Antlr4无法识别关键字并归类为ID,寻求技术解决方案
问题核心
AND、OR关键字被错误识别为IDif语句的else分支未出现在解析树中,同时报错提示预期then或<符号
问题原因
1. 词法规则优先级错误
ANTLR词法分析器按定义顺序匹配最长字符串,你的ID规则定义在所有关键字(包括AND、OR)之前,导致"and"、"or"这类字符串会先被匹配为ID,而非对应的关键字token。
2. 语法规则存在多处关键错误
set_statement分支逻辑错误:原规则(SET ID | ID) TO expression | value | comparison会被拆分为三个独立分支,不符合赋值语句语义,同时导致comparison规则未被整合到表达式层级。- 表达式层级缺失比较运算:原
expression解析路径未包含comparison规则,导致<、>=等比较运算符无法被正确识别,进而引发if条件解析错误。 - 语句块定义不严谨:原
statement_list仅支持单个语句加分隔符,无法识别多语句组成的代码块,导致else后的语句未被解析。 - WS规则覆盖NEWLINE:原
WS包含换行符,导致NEWLINEtoken无法被匹配,语句分隔逻辑失效。
解决方案
- 调整词法规则顺序:将所有关键字规则移至
ID规则之前,确保关键字优先匹配。 - 修正
set_statement规则:将value和comparison整合到expression中,赋值语句仅保留(SET ID | ID) TO expression分支。 - 重构表达式层级:将
comparison纳入表达式解析路径,确保比较、逻辑运算优先级符合常规语法。 - 修正语句块和WS规则:调整
statement_list支持多语句块,从WS中移除换行符,让NEWLINE作为语句分隔符生效。 - 补充括号支持:在
value规则中添加括号表达式,完善语法逻辑。
修正后的EasyBite语法
grammar EasyBite; // 关键字规则:必须放在ID之前 IF : 'if'; THEN : 'then'; ELSE : 'else'; ELSE_IF : 'else if'; END_IF : 'end if'; DECLARE : 'declare'; SET : 'set'; TO : 'to'; SHOW : 'show'; INPUT : 'input'; AND : 'and'; OR : 'or'; NOT : 'not'; MODULO : 'remind'; // 运算符与符号 MUL : '*'; DIV : '/'; POW : '^'; PLUS : '+'; MINUS : '-'; SEMICOLON : ';'; LPAREN : '('; RPAREN : ')'; LESS_THAN : '<'; LESS_THAN_EQUAL : '<='; GREATER_THAN : '>'; GREATER_THAN_EQUAL: '>='; EQUAL : '=='; NOT_EQUAL : '!='; // 字面量 NUMBER : ('+' | '-')? [0-9]+ ('.' [0-9]+)?; STRING : '"' ( '\\' . | ~["\\] )* '"' | '\'' ( '\\' . | ~['\\] )* '\'' ; // 标识符:必须放在所有关键字之后 ID : [a-zA-Z] [a-zA-Z0-9_]*; // 空白与换行 NEWLINE : '\r'? '\n'; WS : [ \t]+ -> skip; // 仅匹配空格和制表符,不包含换行 // Parser规则 program : statement_list* EOF; // 支持多语句组成的块 statement_list : statement ( (NEWLINE|SEMICOLON) statement )*; statement : if_statement | declare_statement | set_statement | input_statement | print_statement ; if_statement : IF expression THEN statement_list (elseif_statement)* (ELSE statement_list)? END_IF; elseif_statement : ELSE_IF expression THEN statement_list; declare_statement : DECLARE ID; set_statement : (SET ID | ID) TO expression; input_statement : (SET ID | ID) TO INPUT LPAREN expression RPAREN; print_statement : SHOW (LPAREN expression RPAREN | STRING); // 表达式层级:严格遵循优先级从低到高 expression : logicalOr; logicalOr : logicalAnd (OR logicalAnd)*; logicalAnd : comparison (AND comparison)*; comparison : equality ((GREATER_THAN | LESS_THAN | GREATER_THAN_EQUAL | LESS_THAN_EQUAL) equality)*; equality : term ((EQUAL | NOT_EQUAL) term)*; term : factor ((PLUS | MINUS) factor)*; factor : power ((MUL | DIV | MODULO) power)*; power : value ('^' value)*; value : NUMBER | STRING | ID | LPAREN expression RPAREN; // 支持括号表达式
验证说明
修正后的语法可正确处理测试代码:
AND、OR会被识别为关键字而非IDif语句的else分支会被正确解析到树中- 表达式中的比较、逻辑运算优先级符合预期
内容的提问来源于stack exchange,提问作者Muhammad Baba Goni
相关产品推荐
相关产品推荐

