2009-08-12 72 views
1

我想解析一个像a IN [3 .. 5[这样的表达式,其中尖括号的方向决定间隔是包含还是独占。我想这被重写到AST等Antlr树重写规则

   NODE-TYPE 
       | 
    +------------+-----------+ 
    |   |   | 
variable lower-bound upper-bound 

其中节点型是BTW_INCLUSIVE,BTW_EXCL_LOWER,BTW_EXCL_UPPER或BTW_EXCL_BOTH之一,这取决于角括号的方向。

我有以下解析规则:

interval_expr : expr1=variable IN 
       (LBRACKET|RBRACKET) 
       expr2=expression DOTDOT expr3=expression 
       (LBRACKET|RBRACKET) 
       -> ^(BETWEEN $expr1 $expr2 $expr3) 

这工作,但它不会创建正确的树节点类型。如何根据匹配的内容选择要创建的节点类型?

回答

5

我认为你必须通过为每个括号组合编写一个规则来解决这个问题,手动添加节点类型。据我所知,不可能将两个(不相邻的)匹配的标记重写为另一个。

所以,你会得到这样的:

interval_expr: 
    inclusive_expr | 
    excl_lower_expr | 
    excl_upper_expr | 
    excl_both_expr; 

inclusive_expr: 
    expr1=variable IN LBRACKET expr2=expression DOTDOT expr3=expression RBRACKET 
    -> ^(BTW_INCLUSIVE $expr1 $expr2 $expr3); 

excl_lower_expr: 
    expr1=variable IN RBRACKET expr2=expression DOTDOT expr3=expression RBRACKET 
    -> ^(BTW_EXCL_LOWER $expr1 $expr2 $expr3); 

excl_upper_expr: 
    expr1=variable IN LBRACKET expr2=expression DOTDOT expr3=expression LBRACKET 
    -> ^(BTW_EXCL_UPPER $expr1 $expr2 $expr3); 

excl_both_expr: 
    expr1=variable IN RBRACKET expr2=expression DOTDOT expr3=expression LBRACKET 
    -> ^(BTW_EXCL_BOTH $expr1 $expr2 $expr3);