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规则,它是模棱两可的,因为'(',我找不到解决方案,你能给我一个解决方案吗?
为什么不简单地做:
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)
你会得到:
归档时间: |
|
查看次数: |
453 次 |
最近记录: |