引用
a=12 b=23 2 + a*b 2 * (a + b)
grammar Expr; prog : stat+ ; stat : expr NEWLINE | ID '=' expr NEWLINE | NEWLINE ; expr : multExpr (('+' | '-') multExpr)* ; multExpr : atom ('*' atom)* ; atom : INT | ID | '(' expr ')' ; ID : ('a'..'z'|'A'..'Z')+; INT :('0'..'9')+; NEWLINE : '\r'?'\n'; WS : (' '|'\t'|'\n'|'\r')+ {skip();};
package impatient; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import org.antlr.runtime.*; public class Test { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/impatient.test"));//impatient.test中包含语言样例 // create a CharStream that reads from standard input // ANTLRInputStream input = new ANTLRInputStream(System.in); ANTLRInputStream input = new ANTLRInputStream(is); // create a lexer that feeds off of input CharStream ExprLexer lexer = new ExprLexer(input); // create a buffer of tokens pulled from the lexer CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens buffer ExprParser parser = new ExprParser(tokens); // begin parsing at rule r parser.prog(); } }
grammar Expr; @header { import java.util.HashMap; } @members { HashMap memory = new HashMap(); } prog : stat+ ; stat : expr NEWLINE {System.out.println($expr.value);} | ID '=' expr NEWLINE {memory.put($ID.text, new Integer($expr.value));} | NEWLINE ; expr returns [int value] : e=multExpr {$value = $e.value;} ('+' e=multExpr {$value += $e.value;} | '-' e=multExpr {$value -= $e.value;} )* ; multExpr returns [int value] : e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})* ; atom returns [int value] : INT {$value = Integer.parseInt($INT.text);} | ID { Integer v = (Integer) memory.get($ID.text); if(v != null) $value = v.intValue(); else System.err.println("undefined variable " + $ID.text); } | '(' expr ')' {$value = $expr.value;} ; ID : ('a'..'z'|'A'..'Z')+; INT :('0'..'9')+; NEWLINE : '\r'?'\n'; WS : (' '|'\t'|'\n'|'\r')+ {skip();};
重新生成parser、lexer和tokens,仍采用test rig Test运行
grammar Expr; options { output = AST; ASTLabelType = CommonTree; } prog : (stat {System.out.println($stat.tree.toStringTree());})+ ; stat : expr NEWLINE -> expr | ID '=' expr NEWLINE -> ^('=' ID expr) | NEWLINE -> ; expr returns [int value] : multExpr (('+'^ | '-'^) multExpr)* ; multExpr : atom ('*'^ atom)* ; atom : INT | ID | '('! expr ')'! ; ID : ('a'..'z'|'A'..'Z')+; INT :('0'..'9')+; NEWLINE : '\r'?'\n'; WS : (' '|'\t'|'\n'|'\r')+ {skip();};
两个后缀符号:!不输入AST、^作为AST的子根节点
tree grammar Eval; options { tokenVocab=Expr; ASTLabelType=CommonTree; } @header { import java.util.HashMap; } @members { HashMap memory = new HashMap(); } prog : stat+; stat : expr {System.out.println($expr.value);} | ^('=' ID expr) {memory.put($ID.text, new Integer($expr.value));} ; expr returns [int value] : ^('+' a=expr b=expr) {$value = a + b;} | ^('-' a=expr b=expr) {$value = a - b;} | ^('*' a=expr b=expr) {$value = a * b;} | ID { Integer v = (Integer)memory.get($ID.text); if(v!=null) $value = v.intValue(); else System.err.println("undefined variable " + $ID.text); } | INT {$value = Integer.parseInt($INT.text);} ;
java -classpath antlr-3.5-complete.jar org.antlr.Tool Eval.g
生成文件Eval.java、Eval.tokens
package impatient; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import org.antlr.runtime.*; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; public class ASTTest { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/impatient.test")); // create a CharStream that reads from standard input // ANTLRInputStream input = new ANTLRInputStream(System.in); ANTLRInputStream input = new ANTLRInputStream(is); // create a lexer that feeds off of input CharStream ExprLexer lexer = new ExprLexer(input); // create a buffer of tokens pulled from the lexer CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens buffer ExprParser parser = new ExprParser(tokens); // get rule prog return value structure ExprParser.prog_return r = parser.prog(); // WALKING RESULTING TREE CommonTree tree = r.getTree(); // one dimensional tree node stream CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree); // tree parser Eval walker = new eval_r(nodes); walker.prog(); } }