antlr在这种情况下如何获得更小的树

时间:2012-07-06 18:35:12

标签: antlr antlr3

我根据我的语法从AST树打印出类型字段和文本字段,我得到了这个

type=5 text=and
    type=14 text==
        type=4 text=ALIAS
            type=20 text=a
        type=7 text=ATTR_NAME
            type=20 text=column_b
        type=36 text=STR_VAL
            type=35 text="asdfds"
    type=14 text==
        type=4 text=ALIAS
            type=20 text=a
        type=7 text=ATTR_NAME
            type=20 text=yyyy
        type=12 text=DEC_VAL
            type=11 text=564.555

我生成的词法分析器中的有效类型int是

public static final int EOF=-1;
public static final int ALIAS=4;
public static final int AND=5;
public static final int ATTR_NAME=7;
public static final int DECIMAL=11;
public static final int DEC_VAL=12;
public static final int EQ=14;
public static final int ID=20;
public static final int STR_VAL=36;

我非常希望树上永远不会有类型= 20!而是将类型20的节点向上移动一级,因此文本将是信息(不是令牌名称),类型将是4,7,或ALIAS或ATTR_NAME类型。有没有办法做到这一点?

我目前语法的这一部分现在正在使用虚构标记ATTR_NAME和ALIAS(如果我需要更多的语法,请注释,但我认为这足以解决它)

primaryExpr
    :   compExpr
    |   inExpr
    |   parameterExpr
    |   attribute
    ;

parameterExpr
    :   attribute (EQ | NE | GT | LT | GE | LE)^ parameter
    |   aliasdAttribute (EQ | NE | GT | LT | GE | LE)^parameter
    ;

compExpr
    :   attribute (EQ | NE | GT | LT | GE | LE)^ value
    |     aliasdAttribute(EQ | NE | GT | LT | GE | LE)^value
    ;
alias
    :   ID
    ;
inExpr  :   attribute IN^ valueList
    ;

attribute: ID -> ^(ATTR_NAME ID);

aliasdAttribute
    :       alias(DOT)(ID) -> ^(ALIAS alias ) ^(ATTR_NAME ID)
    ;

1 个答案:

答案 0 :(得分:1)

  

有办法做到这一点吗?

不确定

语法alias中的T规则:

grammar T;

options {
  output=AST;
}

tokens {
  ALIAS;
}

alias
 : ID -> ALIAS[$ID.text]
 ;

ID : ('a'..'z' | 'A'..'Z')+;

将始终生成(重写)类型为ALIAS的标记,但内部文本与ID标记相同。