ANTLR嵌套表达式问题:解析器未识别相等表达式及成员访问异常
使用ANTLR处理多嵌套表达式的问题及解决方法
问题描述
- 解析器无法识别相等表达式,报错信息:
extraneous input '=' expecting {<EOF>, '~', '(', OPERATOR, IDENTIFIER, NUMBER, STRING},但=已被定义为EQUALITY操作符。 - 解析表达式
context.Previous.Output.previous_value2 = 123时,仅得到2个成员访问表达式,预期结果应为3个成员访问表达式加1个相等表达式。
相关语法规则
grammar xxx; parse: expression+ EOF; expression: expression op=OPERATOR expression #binaryExpression | op=OPERATOR expression #unaryPrefixExpression | expression op=OPERATOR #unarPostfixExpression | member_expression #memberExpression | OPENING_PARENTHESIS expression CLOSING_PARENTHESIS #parenthesisExpression | STRING #stringExpression | NUMBER #numberExpression | NEGATE expression #negationExpression ; member_expression: IDENTIFIER (DOT(IDENTIFIER DOT?))* ; // operators PLUS: '+' ; MINUS: '-' ; BIGGER_THAN: '>' ; LESS_THAN: '<' ; BIGGER_THAN_OR_EQUALS: '>=' ; LESS_THAN_OR_EQUALS: '<=' ; NEGATE: '~' ; EQUALITY: '=' ; OPENING_PARENTHESIS: '(' ; CLOSING_PARENTHESIS: ')' ; fragment LOGICAL_OPERATOR: | EQUALITY | BIGGER_THAN_OR_EQUALS | LESS_THAN_OR_EQUALS | LESS_THAN | BIGGER_THAN ; OPERATOR: PLUS | MINUS | NEGATE | LOGICAL_OPERATOR ; DOT: '.' ; IDENTIFIER: [a-zA-Z]+[a-zA-Z0-9_]* ; // literals NUMBER: [0-9] + ('.' [0-9] +)? ; STRING : '"' .*? '"' ; WS: [ \t\n]+ -> skip ; ANY: . ;
解析树输出
([] ([6] ([16 6] context . Previous .)) ([6] ([16 6] Output . previous_value2)) = ([6] 123) <EOF>)
问题修复
1. 相等表达式识别失败的修复
问题根源:
LOGICAL_OPERATOR片段定义开头多了一个冗余竖线|,导致该片段无法正确匹配EQUALITY操作符。expression规则中同时存在op=OPERATOR expression和NEGATE expression分支,两者优先级冲突,干扰解析器对操作符的识别。
修复措施:
- 修正
LOGICAL_OPERATOR定义,移除开头多余竖线:
fragment LOGICAL_OPERATOR: EQUALITY | BIGGER_THAN_OR_EQUALS | LESS_THAN_OR_EQUALS | LESS_THAN | BIGGER_THAN ;
- 移除
expression中的NEGATE expression分支,因NEGATE已包含在OPERATOR中,避免规则冲突。
2. 成员访问表达式拆分错误的修复
问题根源:member_expression规则中的DOT?会导致解析器错误拆分.Previous.这类结构,无法识别context.Previous.Output这种连续嵌套的成员访问。
修复措施:
修改member_expression为标准连续成员访问格式:
member_expression: IDENTIFIER (DOT IDENTIFIER)* ;
完整修正后的语法
grammar xxx; parse: expression EOF; // 改为单个expression,避免表达式被错误拆分 expression: expression op=LOGICAL_OPERATOR expression #binaryLogicalExpression | expression op=(PLUS | MINUS) expression #binaryArithmeticExpression | op=(PLUS | MINUS | NEGATE) expression #unaryPrefixExpression | member_expression #memberExpression | OPENING_PARENTHESIS expression CLOSING_PARENTHESIS #parenthesisExpression | STRING #stringExpression | NUMBER #numberExpression ; member_expression: IDENTIFIER (DOT IDENTIFIER)* ; // operators PLUS: '+' ; MINUS: '-' ; BIGGER_THAN: '>' ; LESS_THAN: '<' ; BIGGER_THAN_OR_EQUALS: '>=' ; LESS_THAN_OR_EQUALS: '<=' ; NEGATE: '~' ; EQUALITY: '=' ; OPENING_PARENTHESIS: '(' ; CLOSING_PARENTHESIS: ')' ; fragment LOGICAL_OPERATOR: EQUALITY | BIGGER_THAN_OR_EQUALS | LESS_THAN_OR_EQUALS | LESS_THAN | BIGGER_THAN ; DOT: '.' ; IDENTIFIER: [a-zA-Z]+[a-zA-Z0-9_]* ; // literals NUMBER: [0-9]+ ('.' [0-9]+)? ; STRING : '"' .*? '"' ; WS: [ \t\n]+ -> skip ; ANY: . ;
额外说明
- 拆分二元表达式优先级,让逻辑操作符(含
=)优先级低于算术操作符,符合常规语法逻辑。 - 将
parse规则改为expression EOF,确保单个表达式被完整解析,避免被拆分为多个独立表达式。 - 移除冗余的
OPERATOR聚合规则,直接在表达式规则中使用具体操作符或片段,减少歧义。
内容的提问来源于stack exchange,提问作者Xeo
相关产品推荐
相关产品推荐

