用于布尔/条件表达式的 ANTLR v3 语法

est*_*tan 2 grammar antlr3

我首先尝试为表达式创建语法,例如:

(foo = bar or (bar = "bar" and baz = 45.43)) and test = true
Run Code Online (Sandbox Code Playgroud)

到目前为止,我的语法如下所示:

grammar filter;

tokens {
    TRUE = 'true';
    FALSE = 'false';
    AND = 'and';
    OR = 'or';
    LT = '<';
    GT = '>';
    EQ = '=';
    NEQ = '!=';
    PATHSEP = '/';
    LBRACK = '[';
    RBRACK = ']';
    LPAREN = '(';
    RPAREN = ')';
}

expression : or_expression EOF;

or_expression : and_expression (OR or_expression)*;

and_expression : term (AND term)*;

term : atom ( operator atom)? | LPAREN expression RPAREN;

atom : ID | INT | FLOAT | STRING | TRUE | FALSE;

operator : LT | GT | EQ | NEQ;

INT : '0'..'9'+;
FLOAT : ('0'..'9')+ '.' ('0'..'9')*;
STRING : '"' ('a'..'z'|'A'..'Z'|'_'|' ')* '"';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Run Code Online (Sandbox Code Playgroud)

但是在 ANTLRWorks 1.4.3 中,我得到了解析树:

具有上述输入的结果解析树

但对于我的生活,我无法弄清楚我的语法有什么问题。这里缺少什么令牌?

提前谢谢了。

编辑:为了澄清生产中的atom ( operator atom)?替代方案atom,我也许应该提到原子应该能够独立存在而不与另一个原子进行比较。例如a or b是一个有效的表达式。

est*_*tan 5

我在这里回答我自己的问题。我发现我的语法有两个问题。第一个很容易发现;我EOF在顶级规则的末尾加上了:

expression : or_expression EOF;
Run Code Online (Sandbox Code Playgroud)

因此EOF,这是丢失的令牌。我的解决方案是EOFexpression规则中删除,而是在其上方引入规则:

filter: expression EOF;
Run Code Online (Sandbox Code Playgroud)

第二个问题是我的or_expression规则应该是:

or_expression : and_expression (OR and_expression)*;
Run Code Online (Sandbox Code Playgroud)

并不是

or_expression : and_expression (OR or_expression)*;
Run Code Online (Sandbox Code Playgroud)

完整更正的语法是:

grammar filter;

tokens {
    TRUE = 'true';
    FALSE = 'false';
    AND = 'and';
    OR = 'or';
    LT = '<';
    GT = '>';
    EQ = '=';
    NEQ = '!=';
    PATHSEP = '/';
    LBRACK = '[';
    RBRACK = ']';
    LPAREN = '(';
    RPAREN = ')';
}

filter: expression EOF;

expression : or_expression;

or_expression : and_expression (OR and_expression)*;

and_expression : term (AND term)*;

term : atom (operator atom)? | LPAREN expression RPAREN;

atom : ID | INT | FLOAT | STRING | TRUE | FALSE;

operator : LT | GT | EQ | NEQ;

INT : '0'..'9'+;
FLOAT : ('0'..'9')+ '.' ('0'..'9')*;
STRING : '"' ('a'..'z'|'A'..'Z'|'_'|' ')* '"';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Run Code Online (Sandbox Code Playgroud)

生成的解析树是:

正确的解析树