我正在尝试使用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 令牌。我究竟做错了什么?任何帮助都将非常好。
亲切的问候!
答案 0 :(得分:0)
但是,第三项测试无法按预期进行。我假设它是一个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 ;