正如Kaby76在评论中提到的,这个替代方案:
我在.g4文件中编写如下语法:
expr
:function=expr'('((arg',')*arg)?')' #callFun
|object=expr'.'SYMBOL #objCall
|coll=expr'['arg']' #collage
|varId=SYMBOL #varValue
|(expr) #brackets
|expr ADD ADD #lastInc
|expr SUB SUB #lastDec
//2
|ADD ADD <assoc=right> expr #postInc
|SUB SUB <assoc=right> expr #postDec
|NOT <assoc=right> expr #not
|SUB <assoc=right> expr #negative
|'new' expr #createObj
//3
|expr MUL expr #mul
|expr DIV expr #div
|expr MOD expr #mod
//4
|expr ADD expr #add
|expr SUB expr #sub
//5
|expr LMOVE expr #lMove
|expr RMOVE expr #rMove
//6
|expr LESS expr #less
|expr LESS EQUAL expr #lessEqual
|expr GREATER expr #greater
|expr GREATER EQUAL expr #greaterEqual
//7
|expr EQUAL EQUAL expr #equal
|expr NOT EQUAL expr #notEqual
//8
|expr AND ADD expr #and
//9
|expr OR OR expr #or
//10
|expr '?' <assoc=right> exprA = expr':'exprB = expr #trueAfalseB
//11
|expr EQUAL <assoc=right> expr #putIn
|expr ADD EQUAL <assoc=right> expr #addPutIn
|expr SUB EQUAL <assoc=right> expr #subPutIn
|expr MUL EQUAL <assoc=right> expr #mulPutIn
|expr DIV EQUAL <assoc=right> expr #divPutIn
|expr MOD EQUAL <assoc=right> expr #modPutIn
|expr LMOVE EQUAL <assoc=right> expr #lMovePutIn
|expr RMOVE EQUAL <assoc=right> expr #rMovePutIn
//12
|THROW <assoc=right> expr #throw
//13
|expr','expr #comma
;
如果我没有记错的话,这个语法中只有立即左递归。但是有一个错误消息:;以下规则集是相互左递归的[expr]";。为什么?
expr
: ...
| (expr)
| ...
;
是原因。你可能想这么做:
expr
: ...
| '(' expr ')'
| ...
;