ANTLR(语言识别的另一工具)的简介之三[翻译]

    技术2022-05-11  129

    表达式求值

    实际中需要当记号进来时直接对表达式求值,这可以在parser中添加行为:

    class ExprParser extends Parser;

     

    expr returns [int value=0]

    {int x;}

        :   value=mexpr

            ( PLUS x=mexpr  {value += x;}

            | MINUS x=mexpr {value -= x;}

           )*

        ;

     

    mexpr returns [int value=0]

    {int x;}

        :   value=atom ( STAR x=atom {value *= x;} )*

        ;

     

    atom returns [int value=0]

        :   i:INT {value=Integer.parseInt(i.getText());}

        |   LPAREN value=expr RPAREN

        ;

    Lexer仍然一样,但需要在main程序中添加一个打印语句:

    import antlr.*;

     

    public class Main {

            public static void main(String[] args) throws Exception {

                    ExprLexer lexer = new ExprLexer(System.in);

                    ExprParser parser = new ExprParser(lexer);

                    int x = parser.expr();

                    System.out.println(x);

            }

    }

    现在,一旦你运行这个程序,你就可以得到计算的结果:

    $ java Main

    3+4*5

    23

    $ java Main

    (3+4)*5

    35

    $

    ANTLR怎样翻译动作

    动作通常被逐字地放置在生成parser里面,地点与语法中的位置相对应。

    返回规则的说明如下:

    mexpr returns [int value=0]

      : ...

      ;

    被翻译成

    public int mexpr() {

      int value=0;

      ...

      return value;

    }

    如果你添加了一个穿入参数的说明,则这些参数也会被拷贝到方法声明中:

    mexpr[int x] returns [int value=0]

      : ... {value = x;}

      ;

    生成

    public int mexpr(int x) {

      int value=0;

      ...

      value = x;

      return value;

    }

    因此,mexpr和atom规则的完整翻译看似如下所示:

    public int mexpr() {

      int value=0;

      int x; // local variable def from rule mexpr

      value = atom();

      while ( LA(1)==STAR ) {

        match(STAR);

        x = atom();

        value *= x;

      }

      return value;

    }

     

    public int atom() {

      int value=0;

      switch ( LA(1) ) { // switch on lookahead token type

        case INT :

          Token i = LT(1); // make label i point to next lookahead token object

          match(INT);

          value=Integer.parseInt(i.getText()); // compute int value of token

          break;

        case LPAREN :

          match(LPAREN);

          value = expr(); // return whatever expr() computes

          match(RPAREN);

          break;

        default :

          // error

      }

      return value;

    }


    最新回复(0)