ANTLR4语法解析顺序异常,求优雅的解析器控制方案
ANTLR4解析优先级调整求助
简化语法示例
grammar Expr; a: a binop a | unop a; binop: '&'; unop: '~';
待解析代码
~A & ~B & C
当前解析结果
unop (A binop ((unop B) binop C))
期望解析结果
(unop A) binop ((unop B) binop C)
我本来打算在生成的代码里修正解析结果,但觉得应该有更优雅的方式直接控制解析器。试过一些文章里的技巧,但都不匹配这个场景,没成功,求可行建议。
解决方案
问题根源是运算符的优先级和结合性没明确定义。你当前的语法里,一元运算符~和二元运算符&的优先级没有区分,导致解析器把~A & ...错误解析成~(A & ...),而非(~A) & ...。
在ANTLR4里,通过拆分规则分层就能解决这个问题,规则的顺序直接决定优先级:越靠后的规则优先级越高。
推荐写法:
grammar Expr; // 最低优先级:二元&运算,左结合 expr: expr '&' unop_expr | unop_expr; // 高优先级:一元~运算 unop_expr: '~' atom | atom; // 最基础的语法单元 atom: ID; // 标识符定义 ID: [A-Z];
这样解析~A & ~B & C时,会先将~A、~B分别解析为unop_expr,再按左结合处理&,最终得到结构为((~A) & (~B)) & C的语法树,和你期望的(unop A) binop ((unop B) binop C)完全一致。
如果需要右结合的二元运算,只需把expr改成右递归形式expr: unop_expr '&' expr即可,但&通常是左结合,所以左递归写法更合适。
内容的提问来源于stack exchange,提问作者Nils Kronqvist
相关产品推荐
相关产品推荐

