ANTLR:现场访问和评估

时间:2012-11-21 13:20:48

标签: antlr3 context-free-grammar

我正在尝试编写一段语法来表达层次结构的字段访问,例​​如 abc ,其中 c ab <的字段/ em>和 b a 的字段。

要评估 a.b.c.d.e 的值,我们需要评估 a.b.c.d 的值,然后获取 e 的值。 要评估 abcd 的值,我们需要评估 abc 的值,然后获取 d 的值,依此类推......

如果您有这样的树(箭头表示“lhs是rhs的父母”):

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

评估很简单。使用递归,我们只需要解析子的值,然后访问正确的字段。

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

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来反转树的顺序,或者我需要手动执行它?

1 个答案:

答案 0 :(得分:1)

您只能使用内联树运算符 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


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