2009-09-21 66 views
3

我試圖實現一個表達式處理語法(即處理嵌套括號和東西)。到目前爲止我有以下內容,但它們無法處理某些情況(在下面的代碼塊之後出現成功/失敗的情況)。任何人都知道發生了什麼事?ANTLR用於表達式的語法

注:VARNAME + =VARNAME =東西是XTEXT只是一些額外的AST代幫手東西。現在不要擔心他們。

... 

NilExpression returns Expression: 
    'nil'; 

FalseExpression returns Expression: 
    'false'; 

TrueExpression returns Expression: 
    'true'; 

NumberExpression returns Expression: 
    value=Number; 

StringExpression returns Expression: 
    value=STRING; //EllipsesExpression: '...'; 
//FunctionExpression: function=function; //don't allow random functions 


UnaryExpression: 
    op=unop ('(' expr=Expression ')')|expr=Expression; 

BinaryExpression: 
    'or'? AndOp; //or op 

AndOp: 
    'and'? ComparisonOp; 

ComparisonOp: 
    ('>'|'<'|'>='|'<='|'=='|'~=')? ConcatOp; 

ConcatOp: 
    '..'? AddSubOp; 

AddSubOp: 
    ('+' '-')? MultDivOp; 

MultDivOp: 
    ('*' '/')? ExpOp; 

ExpOp: 
    '^'? (('(' expr=Expression ')')|expr=Expression); 

ExprSideOne : Variable|NilExpression|FalseExpression|TrueExpression| 
    NumberExpression|StringExpression|UnaryExpression; 

Expression: 
    ( 
    '(' 
    expression1=ExprSideOne expression2+=BinaryExpression* 
    ')' 
) 
    | 
    (expression1=ExprSideOne expression2+=BinaryExpression*) 
; 
... 

而這裏的解析列表/失敗:

c = ((b)); //fails 
c = ((a not b)); //fails 
c = b; //parses 
d = (b); //parses 
+0

需要遞歸。 出於好奇,爲什麼你的二元運算符規則寫成一元運算符?是否> = .. + *(1)應該是什麼意思? – 2009-10-10 04:10:21

回答

4

發生了什麼事是你的表達/表達式支持單括號而不是多個括號(如你的結論)。我沒有ANTLR特定的經驗,但我曾與Javacc共享許多相似的概念(我爲Prolog寫了一個語法......不要問)。

爲了處理嵌套的括號,你通常有類似的東西:

ParenthesisExpression: '(' (ParenthesisExpression | Expression) ')'; 

這將意味着,表達式是包裹在括號或者它只是一個原始的表達。至於AST如何處理這個問題,ParenthesisExpression'是'表達式,因此它可以表示爲子類或實現(如果Expression是接口/抽象類的排序)。

+0

作爲補充,您可能還必須處理這種情況: ((a)不是(b或(c))),所以有趣的是確保您的表達式也可以回退到ParenthesisExpression。 – Malaxeur 2009-09-21 03:36:56

+0

會不會強制一個外()?圍繞(括號表達式|表達式),你有一對(...)s。 – jameszhao00 2009-09-21 03:40:42

+0

對不起,我的意思是'('')',而不是():) – jameszhao00 2009-09-21 03:54:29

1

利用^放置令牌/規則名稱對於定義表達式非常有用。

expression : e1 (OR^ e1)* ; 
    e1 : e2 (AND^ e2)*; 
    e2 : e3 (PIPE^ e3)*; 
    e3 : e4 (ANDSYMB^ e4)*; 
    e4 : e5 ((EQUAL^|NOTEQUAL^) e5)*; 
    e5 : e6 ((LESS^|GREATER^) e6)*; 
    e6 : e7 ((PLUS^|MINUS^) e7)* ; 
    e7 : e8 ((STAR^|SLASH^) e8)* ; 
    e8 : e9 (NEW^ ID LPAREN RPAREN)*; 
    e9 : (NOT^)? e10; 
    e10 : e11 | call_def; 
    e11 : constant 
     | '(' expression ')' -> expression; 
+0

該規則後的插入符號^表示什麼?更新:我看到另一個SOF似乎解釋它http://stackoverflow.com/questions/11365781/caret-prefix-instead-of-postfix-in-antlr – javadba 2015-07-17 20:44:04