为什么不简单地做:
expr : orExpr;
orExpr : andExpr ('or' andExpr)*;
andExpr : relExpr ('and' relExpr)*;
relExpr : addExpr (relop addExpr)?;
relop : '<' | '<=' | '>' | '>=' | '==' | '!=';
addExpr : multExpr (('+' | '-') multExpr)*;
multExpr : unaryExpr (('*' | '/') unaryExpr)*;
unaryExpr : 'not'? atom;
atom : INT | FLOAT | ID | 'true' | 'false' | '(' expr ')';
一元not
的优先级通常比您现在尝试的要高。
这将允许像这样的表达式42 > true
,但是当您在 AST/tree 中行走时,可能会检查此类语义。
编辑
"not(a+b >= 2 * foo/3.14159) == false"
现在将像这样解析输入(忽略空格):

如果您将输出设置为 AST 并混合一些树重写运算符(^
和!
):
options {
output=AST;
}
// ...
expr : orExpr;
orExpr : andExpr ('or'^ andExpr)*;
andExpr : relExpr ('and'^ relExpr)*;
relExpr : addExpr (relop^ addExpr)?;
relop : '<' | '<=' | '>' | '>=' | '==' | '!=';
addExpr : multExpr (('+' | '-')^ multExpr)*;
multExpr : unaryExpr (('*' | '/')^ unaryExpr)*;
unaryExpr : 'not'^ atom | atom;
atom : INT | FLOAT | ID | 'true' | 'false' | '('! expr ')'!;
你会得到:
