如何解决antlr4:无法按预期识别令牌
我正在尝试使用antlr4构建语法,该语法应该能够将中间解析结果存储为变量,可以访问以供以后使用。我考虑过要使用一个关键字,例如 as (或德语 als ),它将触发此存储功能。除此之外,我还有一个通用令牌 ID ,它将与任何可能的标识符匹配。 存储能力应该是用户的选择。因此,我正在使用?在我的语法定义中。
我的语法如下:
grammar TokenTest;
@header {
package some.package.declaration;
}
AS : 'als' ;
VALUE_ASSIGNMENT : AS ID ;
ID : [a-zA-Z_][a-zA-Z0-9_]+ ;
WS : [ \t\n\r]+ -> skip ;
ANY : . ;
formula : identifier=ID (variable=VALUE_ASSIGNMENT)? #ExpressionIdentifier
;
编译该语法没有失败。但是,当我尝试应用以下TestNG测试时,无法解释其行为:
package some.package.declaration;
import java.util.List;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import some.package.declaration.TokenTestLexer;
public class TokenTest {
private static List<Token> getTokens(final String input) {
final TokenTestLexer lexer = new TokenTestLexer(CharStreams.fromString(input));
final CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.fill();
return tokens.getTokens();
}
@DataProvider (name = "tokenData")
public Object[][] tokenData() {
return new Object [][] {
{"result",new String[] {"result"},new int[] {TokenTestLexer.ID}},{"als",new String[] {"als"},new int[] {TokenTestLexer.AS}},{"result als x",new String[] {"result","als","x"},new int[] {TokenTestLexer.ID,TokenTestLexer.AS,TokenTestLexer.ID}},};
}
@Test (dataProvider = "tokenData")
public void testTokenGeneration(final String input,final String[] expectedTokens,final int[] expectedTypes) {
// System.out.println("test token generation for <" + input + ">");
Assert.assertEquals(expectedTokens.length,expectedTypes.length);
final List<Token> parsedTokens = getTokens(input);
Assert.assertEquals(parsedTokens.size()-1/*EOF is a token*/,expectedTokens.length);
for (int index = 0; index < expectedTokens.length; index++) {
final Token currentToken = parsedTokens.get(index);
Assert.assertEquals(currentToken.getText(),expectedTokens[index]);
Assert.assertEquals(currentToken.getType(),expectedTypes[index]);
}
}
}
第二个测试告诉我 als 一词被解析为 AS 令牌。但是,第三项测试无法正常工作。我认为它是一个 ID 令牌,后跟一个 AS 令牌,最后是一个 ID 令牌。但是,最后一个令牌将被识别为 ANY -令牌。
如果我按以下方式更改 AS -令牌的定义:
fragment AS : 'als' ;
还有另一种奇怪的行为。当然,第二个测试用例不再起作用,因为不再有 AS 令牌。那不足为奇。相反,第三个测试用例中的x将被识别为 ANY 令牌。但是,我认为整个“ als x”序列是一个 VALUE_ASSIGNMENT 令牌。我究竟做错了什么?任何帮助都将非常好。
亲切的问候!
解决方法
但是,第三项测试无法按预期进行。我假设它是一个ID令牌,然后是一个AS令牌,最后是一个ID令牌。但是,最后一个令牌将被识别为ANY令牌
那是因为您定义了:
ID : [a-zA-Z_][a-zA-Z0-9_]+ ;
其中+
表示“一个或多个”。您可能想要的是“零个或多个”:
ID : [a-zA-Z_][a-zA-Z0-9_]* ;
但是,我假设整个“ als x”序列是VALUE_ASSIGNMENT令牌。我在做什么错了?
请注意,解析器规则而不是词法分析器规则会跳过空格。这意味着VALUE_ASSIGNMENT
仅匹配alsFOO
,而不匹配als FOO
。此规则可能应该是解析器规则:
value_assignment : AS ID ;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。