ANTLR将树节点重写为可变深度树

ANTLR将树节点重写为可变深度树,antlr,Antlr,我尝试将乘法运算符重写为重复加法: (* a t=INT) -> (+ a (+ a (+ a (+ ... + a) ... )) (t times) 有没有一种方法可以使用树重写规则在ANTLR中的单个过程中实现这一点 如果没有,最好的方法是什么 我必须对每次出现的“*”进行多次重写,并解析相应的t。因此,t上没有固定的界限。我成功地多次解决了这个问题。我在解析表达式时计算最大通过次数,并多次应用树重写规则。我甚至不需要回溯来证明这是真的。请参阅下面的代码 Expr.g->lexer

我尝试将乘法运算符重写为重复加法:

(* a t=INT) -> (+ a (+ a (+ a (+ ... + a) ... )) (t times)
有没有一种方法可以使用树重写规则在ANTLR中的单个过程中实现这一点

如果没有,最好的方法是什么


我必须对每次出现的“*”进行多次重写,并解析相应的t。因此,t上没有固定的界限。

我成功地多次解决了这个问题。我在解析表达式时计算最大通过次数,并多次应用树重写规则。我甚至不需要回溯来证明这是真的。请参阅下面的代码

Expr.g->lexer,语法分析器

grammar Expr;
options {
    output=AST;
    ASTLabelType=CommonTree;
}

tokens {
    MULT='*';
    ADD='+';
}

@header{
import java.lang.Math;
}

@members {
public int limit=0;
}

prog :   expr {limit=$expr.value;} ;

expr returns [int value]
    :   a=multExpr {$value=$a.value;} (ADD^ b=multExpr {$value=Math.max($value, $b.value);})* ;

multExpr returns [int value]
    :   primary {$value=$primary.value;} (MULT^ c=INT {$value=Math.max($value, $c.int);})? ;

primary returns[int value]
    :   ID              {$value = 0;}
    |   '('! expr ')'!  {$value = $expr.value;}
    ;

ID  :   'a'..'z'+ ;
INT :   '0'..'9'+ ;
WS  :   (' '|'\r'|'\n')+ {skip();} ;
Eval.g->用主程序重写树语法

    tree grammar Eval;

options {
    tokenVocab=Expr;
    ASTLabelType=CommonTree;
    output=AST;
}

@members {

    public static void main(String[] args) throws Exception {
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        ExprLexer lexer = new ExprLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);

        CommonTree t = null;
        try {
            t = (CommonTree) parser.prog().getTree();
        } catch(RecognitionException re){
            re.printStackTrace();
        }

        System.out.println("Tree: " + t.toStringTree());
        System.out.println();

        int loops = parser.limit;
        System.out.println("Number of loops:" + loops);
        System.out.println();

        for(int i=0; i<loops; i++) {
            System.out.println("Loop:" + (i+1));
            CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
            Eval s = new Eval(nodes);
            t = (CommonTree)s.prog().getTree();
            System.out.println("Simplified tree: "+t.toStringTree());
            System.out.println();
        }
    }
}

prog : expr ;

expr
    : ^(ADD a=expr b=expr)
    | ^(MULT a=expr t=INT) ( {$t.int>1}?=>  -> ^(ADD["+"] $a ^(MULT["*"] $a INT[String.valueOf($t.int - 1)]))
                           | {$t.int==1}?=> -> $a )
    | INT
    | ID
    ;
树语法评估;
选择权{
tokenVocab=Expr;
ASTLabelType=CommonTree;
输出=AST;
}
@成员{
公共静态void main(字符串[]args)引发异常{
AntlInputStream输入=新的AntlInputStream(System.in);
ExprLexer lexer=新的ExprLexer(输入);
CommonTokenStream令牌=新的CommonTokenStream(lexer);
ExprParser parser=新的ExprParser(令牌);
公共树t=null;
试一试{
t=(CommonTree)parser.prog().getTree();
}捕获(识别异常re){
关于printStackTrace();
}
System.out.println(“树:+t.toStringTree());
System.out.println();
int循环=parser.limit;
System.out.println(“循环数:“+循环”);
System.out.println();
对于(int i=0;i1}?=>->^(添加[“+”]$a^(MULT[“*”]$a int[String.valueOf($t.int-1)])
|{$t.int==1}?=>->$a)
|INT
|身份证
;

我成功地在多次传递中解决了这个问题。我在解析表达式时计算了最大传递次数,并多次应用树重写规则。我甚至不需要回溯就可以为真。请参阅下面的代码

Expr.g->lexer,语法分析器

grammar Expr;
options {
    output=AST;
    ASTLabelType=CommonTree;
}

tokens {
    MULT='*';
    ADD='+';
}

@header{
import java.lang.Math;
}

@members {
public int limit=0;
}

prog :   expr {limit=$expr.value;} ;

expr returns [int value]
    :   a=multExpr {$value=$a.value;} (ADD^ b=multExpr {$value=Math.max($value, $b.value);})* ;

multExpr returns [int value]
    :   primary {$value=$primary.value;} (MULT^ c=INT {$value=Math.max($value, $c.int);})? ;

primary returns[int value]
    :   ID              {$value = 0;}
    |   '('! expr ')'!  {$value = $expr.value;}
    ;

ID  :   'a'..'z'+ ;
INT :   '0'..'9'+ ;
WS  :   (' '|'\r'|'\n')+ {skip();} ;
Eval.g->用主程序重写树语法

    tree grammar Eval;

options {
    tokenVocab=Expr;
    ASTLabelType=CommonTree;
    output=AST;
}

@members {

    public static void main(String[] args) throws Exception {
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        ExprLexer lexer = new ExprLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);

        CommonTree t = null;
        try {
            t = (CommonTree) parser.prog().getTree();
        } catch(RecognitionException re){
            re.printStackTrace();
        }

        System.out.println("Tree: " + t.toStringTree());
        System.out.println();

        int loops = parser.limit;
        System.out.println("Number of loops:" + loops);
        System.out.println();

        for(int i=0; i<loops; i++) {
            System.out.println("Loop:" + (i+1));
            CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
            Eval s = new Eval(nodes);
            t = (CommonTree)s.prog().getTree();
            System.out.println("Simplified tree: "+t.toStringTree());
            System.out.println();
        }
    }
}

prog : expr ;

expr
    : ^(ADD a=expr b=expr)
    | ^(MULT a=expr t=INT) ( {$t.int>1}?=>  -> ^(ADD["+"] $a ^(MULT["*"] $a INT[String.valueOf($t.int - 1)]))
                           | {$t.int==1}?=> -> $a )
    | INT
    | ID
    ;
树语法评估;
选择权{
tokenVocab=Expr;
ASTLabelType=CommonTree;
输出=AST;
}
@成员{
公共静态void main(字符串[]args)引发异常{
AntlInputStream输入=新的AntlInputStream(System.in);
ExprLexer lexer=新的ExprLexer(输入);
CommonTokenStream令牌=新的CommonTokenStream(lexer);
ExprParser parser=新的ExprParser(令牌);
公共树t=null;
试一试{
t=(CommonTree)parser.prog().getTree();
}捕获(识别异常re){
关于printStackTrace();
}
System.out.println(“树:+t.toStringTree());
System.out.println();
int循环=parser.limit;
System.out.println(“循环数:“+循环”);
System.out.println();
对于(int i=0;i1}?=>->^(添加[“+”]$a^(MULT[“*”]$a int[String.valueOf($t.int-1)])
|{$t.int==1}?=>->$a)
|INT
|身份证
;