ANTLR:乘法省略'*'符号

时间:2010-03-07 21:50:42

标签: antlr

我正在尝试创建一个用于乘法和除数的语法,其中不需要包含'*'符号。我需要它来输出AST。所以对于这样的输入:

1 2/3 4

我希望AST

(*(/(* 1 2)3)4)

我遇到了以下问题,它使用java代码创建适当的节点:

grammar TestProd;

options {
  output = AST;
}

tokens {
  PROD;
}

DIV :   '/';

multExpr: (INTEGER -> INTEGER)
          ( {div = null;}
            div=DIV? b=INTEGER
                ->
                ^({$div == null ? (Object)adaptor.create(PROD, "*") : (Object)adaptor.create(DIV, "/")}
              $multExpr $b))*
    ;

INTEGER: ('0' | '1'..'9' '0'..'9'*);

WHITESPACE: (' ' | '\t')+ { $channel = HIDDEN; };

这很有效。但是有更好/更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

这是一种方式:

grammar Test;

options {
  backtrack=true;
  output=AST;
}

tokens {
  MUL;
  DIV;
}

parse
  : expr* EOF
  ;

expr
  :  (atom -> atom) 
     ( '/' a=atom -> ^(DIV $expr $a)
     | a=atom     -> ^(MUL $expr $a)
     )*
  ;

atom
  :  Number
  |  '(' expr ')' -> expr
  ;

Number
  :  '0'..'9'+
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;

经过测试:

import org.antlr.runtime.*;
import org.antlr.runtime.tree.Tree;

public class Main {
    public static void main(String[] args) throws Exception {
        String source = "1 2 / 3 4";
        ANTLRStringStream in = new ANTLRStringStream(source);
        TestLexer lexer = new TestLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TestParser parser = new TestParser(tokens);
        TestParser.parse_return result = parser.parse();
        Tree tree = (Tree)result.getTree();
        System.out.println(tree.toStringTree());
    }
}

制备:

(MUL (DIV (MUL 1 2) 3) 4)