表达式求值
实际中需要当记号进来时直接对表达式求值,这可以在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;
}