2011-05-04 26 views
1

我正在使用ANTLRWorks 1.4.2创建一个简单的语法,用于评估用户提供的表达式作为布尔结果。这最终将成为一个更大的语法的一部分,但我对这个当前片段有一些疑问。我希望用户能够使用表达式,如:带括号表达式的ANTLR语法问题

  1. 2 > 1
  2. 2 > 1 and 3 < 1
  3. (2 > 1 or 1 < 3) and 4 > 1
  4. (2 > 1 or 1 < 3) and (4 > 1 or (2 < 1 and 3 > 1))

前两个表达式都在我的语法合法的,但最后的两个不是,我不知道为什么。此外,ANTLRworks似乎表明,输入如((((1 > 2)与不匹配的括号是合法的,我不知道为什么。所以,我似乎错过了一些关于在文法中处理括号分组的正确方法的见解。

如何更改我的语法以正确处理括号?

我的语法如下:

grammar conditional_test; 

boolean 
    : boolean_value_expression 
     EOF 
    ; 

boolean_value_expression 
    : boolean_term (OR boolean_term)* 
     EOF 
    ; 

boolean_term 
    : boolean_factor (AND boolean_factor)* 
    ; 

boolean_factor 
    : (NOT)? boolean_test 
    ; 

boolean_test 
    : predicate 
    ; 

predicate 
    : expression relational_operator expression 
    | LPAREN boolean_value_expression RPAREN 
    ; 

relational_operator 
    : EQ 
    | LT 
    | GT 
    ; 

expression 
    : NUMBER 
    ; 


LPAREN  : '('; 
RPAREN  : ')'; 
NUMBER  : '0'..'9'+; 

EQ   : '='; 
GT   : '>'; 
LT   : '<'; 

AND   : 'and'; 
OR   : 'or' ; 
NOT   : 'not'; 

回答

4

克里斯农民写道:

前两个表达式都在我的语法合法的,但近两年都没有了,我不知道为什么。 ...

您应该删除EOF令牌:

boolean_value_expression 
    : boolean_term (OR boolean_term)* 
     EOF 
    ; 

你通常只使用EOF你的语法(在你的情况boolean)的进入点之后。注意boolean是Java中的保留字,因此不能用作解析器规则!

所以前两个规则应该是这样的:

bool 
    : boolean_value_expression 
     EOF 
    ; 

boolean_value_expression 
    : boolean_term (OR boolean_term)* 
    ; 

而且你可能也想通过加入以下词法规则忽略文字空间:

SPACE : ' ' {$channel=HIDDEN;}; 

(可以包括标签的行当然)

现在所有的示例输入都正确匹配(也使用ANTLRWorks 1.4.2进行了测试)。

克里斯农民写道:

此外,ANTLRworks似乎表明,输入如((((1> 2)不匹配的括号是合法的,...

无,ANTLRWorks does会产生错误,可能不是很明显的错误。ANTLRWorks生成的分析树有一个NoViableAltException作为叶,并且在“控制台”选项卡上有一些错误。

+0

谢谢!我不确定那里有多少额外的EOF,但它肯定会让一些事情混淆不清。感谢您看看这个。你的建议很好地工作。 – 2011-05-05 01:53:43

+0

@克里斯,不客气。 – 2011-05-05 06:17:51

+0

@Chris,注意你的语法不允许括号括起来,如:1 <(2)'。你可能有意这样做了,但也许不是,在这种情况下,你应该将'LPAREN boolean_value_expression RPAREN'移动到'expression'规则并将'predicate'改为:'predicate:expression(relational_operator expression)? ;' – 2011-05-05 07:23:39