Antlr语法报错:missing 'hello' at 'hello',新手求解析与使用指导
错误原因解析
你碰到的1:0 missing 'hello' at 'hello'错误,核心问题出在运行解析器时没指定正确的起始规则:
你的语法里定义的入口规则是r,但如果运行时没明确指定这个规则(比如用grun测试时漏写了规则名),ANTLR会默认去找和语法文件同名的规则(也就是Hello),可你的语法里根本没定义Hello规则,导致解析逻辑混乱,才出现这个奇怪的错误。
ANTLR开发解析器完整流程(以你的Hello语法为例)
1. 确认语法文件
你的Hello.g4写法没问题,保留即可:
grammar Hello; r : 'hello' ID ; ID : [a-z]+ ; WS : [ \t\r\n]+ -> skip ;
2. 生成词法/解析器代码
用ANTLR命令生成目标语言代码(这里以Java为例):
antlr4 Hello.g4
执行后会生成HelloLexer.java、HelloParser.java等一系列文件。
3. 编译生成的代码
编译时要把ANTLR的jar包加入classpath(替换成你实际用的ANTLR版本jar):
javac -cp "antlr-4.x.x-complete.jar:." Hello*.java
4. 测试解析器
用grun工具测试(最快捷)
必须指定起始规则r,命令如下:
grun Hello r -tokens
输入hello world后,按Ctrl+D(Linux/macOS)或Ctrl+Z(Windows)结束输入,就能看到正常的token输出,不会再报错。
自己写代码调用解析器(Java示例)
如果要集成到自己的程序里,代码要明确调用起始规则r:
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*; public class TestHello { public static void main(String[] args) throws Exception { String input = "hello world"; HelloLexer lexer = new HelloLexer(CharStreams.fromString(input)); CommonTokenStream tokens = new CommonTokenStream(lexer); HelloParser parser = new HelloParser(tokens); // 关键:调用起始规则r ParseTree tree = parser.r(); System.out.println(tree.toStringTree(parser)); } }
编译运行时同样要带上ANTLR jar:
javac -cp "antlr-4.x.x-complete.jar:." TestHello.java java -cp "antlr-4.x.x-complete.jar:." TestHello
核心注意事项
- 起始规则可以自定义,但运行时必须明确指定,否则ANTLR会默认匹配与语法名同名的规则,找不到就会出错。
- 词法规则必须大写开头(比如
ID、WS),语法规则小写开头(比如r),ANTLR靠这个区分两者。 - 确保使用的ANTLR版本和生成代码时的版本一致,避免版本兼容问题。
内容的提问来源于stack exchange,提问作者louq1
相关产品推荐
相关产品推荐

