ANTLR解析骰子表达式异常求助:无法解析3D6+2D10类表达式
解决ANTLR骰子表达式语法的解析问题
我来帮你搞定这个问题!你的ANTLR语法没法解析3D6+2D10这类表达式,核心问题出在语法结构设计和起始规则的匹配逻辑上。
问题根源分析
你原来的语法里,function作为起始规则,它的可选匹配项是单个骰子表达式、单个二元运算或者单个数字。当解析3D6+2D10时,解析器会优先把3D6匹配成function(因为dice是function的第一个选项),剩下的+2D10就找不到对应的规则来匹配了——毕竟起始规则已经“用完”了,自然会抛出no viable alternative at input错误。
另外,原来的右递归结构(binaryOp引用function,而function又可以是binaryOp)虽然理论上能处理单个二元运算,但无法自然扩展到多个连续运算,也容易让解析器的匹配逻辑混乱。
修正后的语法
我重新设计了语法结构,用更清晰的层级和左递归表达式来解决问题:
grammar Dice; // 起始规则:匹配整个表达式,支持任意数量的+/-运算 expr : expr OPERATOR term | term; // 原子项:单个骰子表达式或数字 term : dice | DIGIT; // 骰子表达式定义,支持爆炸骰子(*后缀) dice : DIGIT DSEPERATOR DIGIT EXPLODING?; // 词法规则简化写法 DSEPERATOR : [dDwW]; // 支持大小写d/w作为分隔符 EXPLODING : '*'; // 爆炸骰子标记 OPERATOR : '+' | '-'; // 加减运算符 DIGIT : [0-9]+; // 数字 WS : [ \t\r\n]+ -> skip; // 跳过空白字符
语法说明
- 起始规则
expr:用左递归定义,支持连续的加减运算(比如3D6+2D10-5),ANTLR4原生支持左递归,解析效率和逻辑都更清晰。 term规则:明确表示单个不可拆分的“原子”元素,要么是骰子表达式,要么是数字,这样能保证运算的左结合性(和常规数学运算一致)。- 词法规则简化:用字符集
[dDwW]代替多个单独的选项,写法更简洁,功能完全一致。
这个修正后的语法可以正确解析你提到的3D6+2D10,还支持更复杂的表达式比如5-2W10*+3D6这类带爆炸骰子的组合运算。
内容的提问来源于stack exchange,提问作者Olav Müller
相关产品推荐
相关产品推荐

