2012-11-21 47 views
1

我试图写一段语法来表达的层次结构字段访问,像ABC其中Ç场ABbaANTLR:现场访问和评估

评价的a.b.c.d.e我们需要评估A.B.C.D的值,然后得到Ë价值的价值。 要evalutate值ABCD,我们需要evalute ABC的值,然后得到d的价值等等...

如果你有一个这样的树(箭头指“ lhs是rhs的父亲“):

Node(e) -> Node(d) -> Node(c) -> Node(b) -> Node(a) 

评价很简单。使用递归,我们只需要解决孩子的价值,然后访问正确的领域。

的问题是:我有这样3条规则,我ANTLR语法文件:

tokens { 
    LBRACE = '{' ; 
    RBRACE = '}' ; 
    LBRACK = '[' ; 
    RBRACK = ']' ; 
    DOT  = '.' ; 
    .... 
} 

reference 
    : DOLLAR LBRACE selector RBRACE -> ^(NODE_VAR_REFERENCE selector) 
; 

selector 
    : IDENT access -> ^(IDENT access) 
; 

access 
    : DOT IDENT access? -> ^(IDENT<node=com.at.cson.ast.FieldAccessTree> access?) 
    | LBRACK IDENT RBRACK access? -> ^(IDENT<node=com.at.cson.ast.FieldAccessTree> access?) 
    | LBRACK INTEGER RBRACK access? -> ^(INTEGER<node=com.at.cson.ast.ArrayAccessTree> access?) 
; 

正如预期的那样,我的树有这种形式:

ReferenceTree 
    IdentTree[a] 
    FieldAccessTree[b] 
     FieldAccessTree[c] 
     FieldAccessTree[d] 
      FieldAccessTree[e] 

的评价不那么容易在另一种情况,因为我需要得到当前节点的值,然后把它给孩子,等等......

有没有什么办法来扭转使用ANTLR的树的顺序或我需要做的它手动?

+0

因此,'a.b.c'应该产生'^(c ^(b a))'。输入'a [1] [2] [3]'的AST应该如何显示? –

+0

正确。与数组访问相同的表单:^(3 ^(2 ^(1 a))) – Antonio

回答

1

您只能使用内嵌树运算符,^而不是重写规则来做到这一点。

的演示:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    ROOT; 
    LBRACK = '[' ; 
    RBRACK = ']' ; 
    DOT = '.' ; 
} 

parse 
: selector+ EOF -> ^(ROOT selector+) 
; 

selector 
: IDENT (access^)* 
; 

access 
: DOT IDENT    -> IDENT 
| LBRACK IDENT RBRACK -> IDENT 
| LBRACK INTEGER RBRACK -> INTEGER 
; 

IDENT : 'a'..'z'+; 
INTEGER : '0'..'9'+; 
SPACE : ' ' {skip();}; 

解析输入:

a.b.c a[1][2][3] 

将产生以下AST:

enter image description here


有关内联树运算符和重写规则的更多信息,请参阅:How to output the AST built using ANTLR?

+0

很好的答案,它的工作原理相当不错。谢谢。 – Antonio

+0

不客气@Antonio。 –