antlr3 - ANTLR3 使用 java.lang.NullPointerException 引发内部错误
问题描述
我尝试使用 ANTLR3 构建一个简单的正则表达式解析器,但它抛出了内部错误
这是 Sample.g
grammar Sample;
options {
memoize=true;
output=AST;
}
tokens {
RegExp;
}
RegExpression:
'/' (a=~('/' | NL))+ '/'
-> ^(RegExp[$RegExpression.start, $RegExpression.text] $a+ )
;
fragment NL: '\n' | '\r';
ANY : . ;
我运行命令:java -jar antlr-3.5.2-complete.jar -print Sample.g
它给出了这个:
error(10): internal error: Sample.g : java.lang.NullPointerException
org.antlr.grammar.v3.DefineGrammarItemsWalker.rewrite_atom(DefineGrammarItemsWalker.java:3896)
……
根据评论更新
grammar Sample{
memoize=true;
output=AST;
}
tokens {
RegExp;
}
regExpression:
'/' (a=~('/' | NL))+ '/'
-> ^(RegExp[$regExpression.start, $regExpression.text] $a+ )
;
NL: '\n' | '\r';
这是运行后的错误java -jar antlr-3.5.2-complete.jar Sample.g
error(10): internal error: Sample.g : java.lang.NullPointerException
org.antlr.grammar.v3.CodeGenTreeWalker.getTokenElementST(CodeGenTreeWalker.java:311)
org.antlr.grammar.v3.CodeGenTreeWalker.notElement(CodeGenTreeWalker.java:2886)
org.antlr.grammar.v3.CodeGenTreeWalker.element(CodeGenTreeWalker.java:2431)
org.antlr.grammar.v3.CodeGenTreeWalker.element(CodeGenTreeWalker.java:2446)
org.antlr.grammar.v3.CodeGenTreeWalker.alternative(CodeGenTreeWalker.java:2250)
org.antlr.grammar.v3.CodeGenTreeWalker.block(CodeGenTreeWalker.java:1798)
org.antlr.grammar.v3.CodeGenTreeWalker.ebnf(CodeGenTreeWalker.java:3014)
org.antlr.grammar.v3.CodeGenTreeWalker.element(CodeGenTreeWalker.java:2495)
org.antlr.grammar.v3.CodeGenTreeWalker.alternative(CodeGenTreeWalker.java:2250)
org.antlr.grammar.v3.CodeGenTreeWalker.block(CodeGenTreeWalker.java:1798)
org.antlr.grammar.v3.CodeGenTreeWalker.rule(CodeGenTreeWalker.java:1321)
org.antlr.grammar.v3.CodeGenTreeWalker.rules(CodeGenTreeWalker.java:955)
org.antlr.grammar.v3.CodeGenTreeWalker.grammarSpec(CodeGenTreeWalker.java:877)
org.antlr.grammar.v3.CodeGenTreeWalker.grammar_(CodeGenTreeWalker.java:518)
org.antlr.codegen.CodeGenerator.genRecognizer(CodeGenerator.java:415)
org.antlr.Tool.generateRecognizer(Tool.java:674)
org.antlr.Tool.process(Tool.java:487)
org.antlr.Tool.main(Tool.java:98)
解决方案
您正在尝试在词法分析器规则上使用重写规则(树构造)。那没有意义。
在 ANTLR 中,所有名称以大写字母开头的规则都是词法分析器规则。树结构用于 AST 节点,而不是标记本身,因此您必须在解析器规则上使用它(以小写字母开头)。
当你这样做时,请记住你NL
现在是一个片段(你不能在解析器规则中使用片段)并确保你的ANY
令牌不会与其他任何东西冲突,即定义所有需要的令牌(/
等NL
)并将它们放在上面ANY
令牌定义。
推荐阅读
- java - CellEditor.java 的 getCellEditorValue() 仅在单击单元格时调用
- java - 使用 @Mock 注入模拟不适用于 Java 13
- azure - 启用了虚拟节点和未启用虚拟节点的 AKS 群集
- python - Firestore 错误:这些文档争用过多,请重试
- javascript - 在 react-native 应用程序中从 TMDB API 翻译 gendre_ids
- spring-boot - 多模块 Spring boot 应用程序 Flyway 迁移脚本
- julia - 如何在稀疏矩阵中找到所有空行的索引,
- javascript - 未捕获(承诺中)错误:reCAPTCHA 占位符元素必须是元素或 id
- java - 如何在用户输入时在 EditText 中添加主题标签
- javascript - 使用自定义方法直接扩展 HTML 元素