如何解决这种模棱两可的语法?

naf*_*seh 3 antlr antlrworks antlr3

我写过这个语法:

expr        : multExpr ( ('+' | '-') multExpr )*;
multExpr    : atom ( ('*' | '/') atom )*;
atom    : INT | FLOAT | ID | '(' expr ')';
condition   : cond ('or' cond)*;
cond    : c1 ('and' c1)*;
c1      : ('not')? c2;
c2      : '(' condition ')' | boolean;
boolean : expr (relop expr | ²) | 'true' | 'false';
relop   : '<' | '<=' | '>' | '>=' | '==' | '!=';
Run Code Online (Sandbox Code Playgroud)

我已经省略了INT,FLOAT,ID的词法规则,因为很明显.

问题是c2规则,它是模棱两可的,因为'(',我找不到解决方案,你能给我一个解决方案吗?

Bar*_*ers 5

为什么不简单地做:

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 ')';
Run Code Online (Sandbox Code Playgroud)

一元not通常具有比你现在想要做的更高的优先权.

这将允许表达式42 > true,但是当您走过AST /树时,可以检查这样的语义.

编辑

输入"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 ')'!;
Run Code Online (Sandbox Code Playgroud)

你会得到:

在此输入图像描述