在 gereral 中,我正在尝试创建一个基于 Java 的应用程序,我可以在其中编译支持简单正则表达式的术语字典。然后,字典将用于创建一个简单的实体标记器,其中在文本中标记了识别的术语。以为ANTLR可以提供我需要的一切。尝试创建一个不依赖于编译的语法和词法分析器的 Java 应用程序,因为语法必须每隔几分钟在运行时更新一次。
这是我简单的"Hello World"应用程序:
LexerGrammar lg = new LexerGrammar(
"lexer grammar L;n" +
"A : ('a'|'A');n" +
"B : ('b'|'B');n" +
"C : ('c'|'C');n" +
"D : ('d'|'D');n" +
"FILL_TOKEN : (.);n");
Grammar g = new Grammar(
"parser grammar T;n" +
"t_abc : A FILL_TOKEN? B FILL_TOKEN? C;n" +
"t_abcd : A FILL_TOKEN? B FILL_TOKEN? C FILL_TOKEN? D;n" +
"rule0 : t_abcd|t_abc;n" +
"ws : '.' -> skip ;n",
lg);
LexerInterpreter lexEngine =
lg.createLexerInterpreter(new ANTLRInputStream("Test A BCD"));
CommonTokenStream tokens = new CommonTokenStream(lexEngine);
ParserInterpreter parser = g.createParserInterpreter(tokens);
Rule rule = g.rules.get("rule0");
ParseTree t = parser.parse(rule.index);
System.out.println(t.getText());
当我尝试编译应用程序时,出现以下错误
Exception in thread "main" java.lang.NullPointerException
at org.antlr.v4.runtime.atn.ATNSerializer.serialize(ATNSerializer.java:73)
at org.antlr.v4.runtime.atn.ATNSerializer.getSerialized(ATNSerializer.java:601)
at org.antlr.v4.runtime.atn.ATNSerializer.getSerializedAsChars(ATNSerializer.java:605)
at org.antlr.v4.tool.Grammar.createParserInterpreter(Grammar.java:1337)
at main.OnTheFly.main(OnTheFly.java:98)
当我注释掉语法的"ws : '.' -> skip ;n",
部分时,程序会运行,但它抱怨Test
未知。
我做错了什么还是默认语法不支持skip
参数? 使用 Antlr 4.7.2 和 Java 1.8.0 (131(
找到了答案。只有词法分析器支持skip
参数,此外,我只需要一起使用词法分析器。可以通过查看结果令牌来检索匹配项:
...
// using code from above with grammar part, including SKIP rule.
// In additions, all tokens have to be defined in
// ...
// required to process the input stream
tokens.fill();
for (Token token : tokens.getTokens()) {
int typeId = token.getType();
if (-1 == typeId) {
break;
}
String ruleName = lexEngine.getRuleNames()[token.getType() - 1];
System.out.println("Token: " + token.getText() + " - " + ruleName);
}
有关词法分析和语法词汇的更多信息,请参见此处:
https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md
https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md