使用ANTLR4解析键值对时出现语法错误,无法获取对应值
问题排查与解决
问题根源分析
你的ANTLR4语法存在三个核心问题:
- 词法规则优先级倒置:
Char: .会匹配所有字符(包括空格、换行、等号),导致后面定义的Space、LineBreak、EQ等规则完全无法触发——ANTLR4会优先匹配定义在前的词法规则。 - 值匹配逻辑错误:原
value规则依赖valueChar+ EOL,但EOL被Char提前吃掉,导致无法正确识别行尾;同时值中的空格被错误判定为不符合key规则的输入。 - 行内注释未处理:文本中
#!; this is a comment属于行内注释,但原语法仅支持整行注释,未对行内注释做跳过处理。
修正后的语法规则
grammar KEYVALUE; // 优先定义明确的词法符号 EQ: '='; LineBreak: '\r'? '\n' | '\r'; Space: ' ' | '\t' | '\f'; AlphaNum: [a-zA-Z0-9]; // 整行注释:从;开始到行尾或EOF LINE_COMMENT: ';' .*? (LineBreak | EOF) -> skip; // 行内注释:从#开始到行尾或EOF(适配示例中的行内注释格式) INLINE_COMMENT: '#' .*? (LineBreak | EOF) -> skip; file: line* EOF; line: Space* keyValuePair LineBreak?; keyValuePair: key EQ value { String k = $key.text; String v = $value.text.trim(); // 可选:去除值的首尾空格 System.out.println("\nkey : `" + k + "`"); System.out.println("value : `" + v + "`"); }; key: AlphaNum+; // 值匹配:除换行和行内注释起始符外的所有字符,自动终止于行内注释或行尾 value: ( ~('#' | '\r' | '\n') )+;
关键修正说明
- 词法规则顺序调整:将具体符号(EQ、LineBreak等)放在最前面,确保它们被优先匹配,避免被通配符规则覆盖。
- 新增行内注释处理:添加
INLINE_COMMENT规则跳过#开头的行内注释,避免注释内容干扰值的匹配。 - 优化值匹配逻辑:直接用
~('#' | '\r' | '\n')匹配值的内容,允许值包含空格、数字、特殊符号(除#和换行),并自动在遇到行内注释或行尾时停止匹配。 - 行规则适配:
line规则中添加LineBreak?,支持最后一行没有换行符的情况。
测试验证
执行原命令more test.txt |grun parser.KEYVALUE file -gui,现在能正确解析所有键值对,输出如下:
key : `dummykey` value : `dummy string 100` key : `firstname` value : `peter mike` key : `name` value : `mc miller`
且无语法错误提示。
内容的提问来源于stack exchange,提问作者Bafoeg
相关产品推荐
相关产品推荐

