ANTLR4:遵循什么设计模式?
我有一个规则“表达式”,可以是“数学”或“比较”,但“比较”可以包含“数学”。这里有一个具体的代码:ANTLR4:遵循什么设计模式?,antlr4,Antlr4,我有一个规则“表达式”,可以是“数学”或“比较”,但“比较”可以包含“数学”。这里有一个具体的代码: expression : ID | maths | comparison ; maths : maths_atom ((PLUS | MINUS) maths_atom) ? // "?" because in fact there is first multiplication then pow and I don't want t
expression
: ID
| maths
| comparison
;
maths
: maths_atom ((PLUS | MINUS) maths_atom) ? // "?" because in fact there is first multiplication then pow and I don't want to force a multiplication to make an addition
;
maths_atom
: NUMBER
| ID
| OPEN_PAR expression CLOSE_PAR
;
comparison
: comp_atom ((EQUALS | NOT_EQUALS) comp_atom) ?
;
comp_atom
: ID
| maths // here is the expression of interest
| OPEN_PAR expression CLOSE_PAR
;
例如,如果我将
6
作为输入,这对于解析树来说很好,因为它检测mathematics
。但是在Intellij Idea的ANTLR4插件中,它将我的表达式规则标记为红色模糊。我是否应该告别一个简短的解析树,只允许在表达式中通过比较,这样它就不再那么模棱两可了?问题是,当解析器看到6
,这是一个数字时,它有两条路径可以通过语法到达它:
expression - maths - maths_atom - NUMBER
或
这种模糊性会触发您看到的错误
您可以通过展平解析器语法来解决此问题:
开始
:expr|
;
expr
:expr(加|减)expr#ADDGRP
|expr(等于|不等于)expr#COMPGRP
|开放式PAR表达式闭合式PAR PARENGRP
|数字#NUM
|识别号
;
很抱歉,这是一个错误,比较中没有“数字”。我编辑了这个问题。顺便说一句,我的语法太复杂了,不能像这样扁平化。阅读我的第一条命令code@bananasmoothii那么ID
就是问题所在:您可以直接或通过一系列规则访问它。无论哪种方式,扁平化语法都可以识别您的原始语法,也就是说,它可以让您自己放置一个ID
。是的,这就是问题所在。我应该只通过一系列规则来允许它,但这会生成一些外观怪异的解析树,还是生成好的解析树并允许它directly@Bananasmoothii周围没有干净的路,因为文本中没有标记,因此无法区分由单个ID
组成的数学表达式和单独表示单个ID
的表达式。通常这并不重要,因为访问者可以忽略所有中间的单子节点。
expression - comparison - comp_atom - NUMBER
start
: expr | <EOF>
;
expr
: expr (PLUS | MINUS) expr # ADDGRP
| expr (EQUALS | NOT_EQUALS) expr # COMPGRP
| OPEN_PAR expression CLOSE_PAR # PARENGRP
| NUMBER # NUM
| ID # IDENT
;