tags:

views:

421

answers:

1

I'm trying to parse an expression like a IN [3 .. 5[, where the direction of the angle brackets determine whether the interval is inclusive or exclusive. I want this to be rewritten to an AST like

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

where NODE-TYPE is one of BTW_INCLUSIVE, BTW_EXCL_LOWER, BTW_EXCL_UPPER or BTW_EXCL_BOTH, depending on the direction of the angle brackets.

I have the following parse rule:

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

This works, except that it does not create the correct tree node type. How can I choose which node type to create based on what was matched?

+4  A: 

I think you have to solve this by writing one rule for each of the bracket combinations, adding the node type manually. As far as I know, it's not possible to rewrite two (non-adjacent) matching tokens into one other.

So you'd get this:

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);
Jorn