使用ANTLR解析时如何避免文本间空格被合并的问题
ANTLR语法问题修复:多空格导致标识符合并与别名覆盖实现
问题根源
- 多空格合并问题:你的语法未定义空白字符处理规则,ANTLR无法识别标识符间的多空格分隔,导致后续标识符被错误合并到前一个
identifier中。 - 别名覆盖缺失:当前语法仅捕获了原名和别名,但未实现别名覆盖原名的逻辑。
修改后的完整语法
grammar YourGrammarName; // 替换为你的语法名称 rule1: Keyword name=identifier (diffName=identifier)? { // 别名覆盖原名逻辑:如果存在别名,用别名替换原名 if ($diffName != null) { $name.str = $diffName.str; } // 示例:输出最终名称 System.out.println("最终生效名称:" + $name.str); } ; identifier: returns [string str] @init{$str="";}: i=Word{$str+=$i.text;} (i=(Number | Word ) {$str+=$i.text;})* ; Keyword: SPACE* START SPACE* 'KEYWORD' SPACE* EQUAL SPACE*; Number: DIGIT+; Word: LETTER+; WS: [ \t]+ -> skip; // 新增:跳过所有空格和制表符 fragment LETTER: 'A'..'Z' | 'a'..'z' | '_'; fragment DIGIT: [0-9]; fragment SPACE: ' ' | '\t'; fragment START: '@@'; fragment EQUAL: '=';
关键修改说明
- 新增WS规则:
WS: [ \t]+ -> skip;让Lexer自动忽略所有空格和制表符,确保MyName和MyAliasName无论间隔多少空格,都会被识别为独立的标识符。 - 简化rule1规则:移除原规则中的
' '*,因为空白字符已被WS规则处理,parser会自动跳过标识符间的空白。 - 添加别名覆盖逻辑:在rule1的动作块中,判断
diffName是否存在,若存在则将name的字符串值替换为diffName的值,实现别名覆盖原名的需求。
测试验证
输入@@ KEYWORD = MyName MyAliasName(含多个空格),规则会正确捕获:
- 原名:
MyName - 别名:
MyAliasName
最终name.str会被替换为MyAliasName,符合需求。
内容的提问来源于stack exchange,提问作者Vignesh G
相关产品推荐
相关产品推荐

