Antlr树重写规则

eri*_*len 1 parsing antlr

我正在尝试解析一个表达式a IN [3 .. 5[,其中尖括号的方向决定了区间是包含还是排除.我希望将其重写为AST

             NODE-TYPE
                 |
    +------------+-----------+
    |            |           |
 variable  lower-bound  upper-bound
Run Code Online (Sandbox Code Playgroud)

其中NODE-TYPE是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)
Run Code Online (Sandbox Code Playgroud)

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

Jor*_*orn 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);
Run Code Online (Sandbox Code Playgroud)