下载 antlrWorks 2.1 和 antlr4.1
从网上找了个例子
grammar LabeledExpr; // prog: stat+ ; stat: expr NEWLINE # printExpr | ID '=' expr NEWLINE # assign | NEWLINE # blank ; expr: expr op=('*'|'/') expr # MulDiv | expr op=('+'|'-') expr # AddSub | INT # int | ID # id | '(' expr ')' # parens ; MUL : '*' ; // assigns token name to '*' used above in grammar DIV : '/' ; ADD : '+' ; SUB : '-' ; ID : [a-zA-Z]+ ; // match identifiers INT : [0-9]+ ; // match integers NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal) WS : [ \t]+ -> skip ; // toss out whitespace
使用antlrworks的 run - 生成识别器 选择生成vistor
派生自己的vistor
1 package LabeledExpr.Imp; 2 3 /** 4 * Created by IntelliJ IDEA. 5 * User: han 6 * Date: 14-1-22 7 * Time: 下午2:12 8 * To change this template use File | Settings | File Templates. 9 */ 10 import LabeledExpr.LabeledExprBaseVisitor; 11 import LabeledExpr.LabeledExprParser; 12 13 import java.util.HashMap; 14 import java.util.LinkedHashMap; 15 import java.util.Map; 16 17 public class EvalVisitor extends LabeledExprBaseVisitor<Integer> { 18 /** "memory" for our calculator; variable/value pairs go here */ 19 Map<String, Integer> memory = new LinkedHashMap<String, Integer>(); 20 21 22 23 /** ID '=' expr NEWLINE */ 24 @Override 25 public Integer visitAssign(LabeledExprParser.AssignContext ctx) { 26 String id = ctx.ID().getText(); // id is left-hand side of '=' 27 int value = visit(ctx.expr()); // compute value of expression on right 28 memory.put(id, value); // store it in our memory 29 int i = new Mem(id).invoke(); 30 System.out.println("mov bx ," + Integer.toHexString(i)); 31 // System.out.println("mov bx ," + (id)); 32 System.out.println("pop ax "); 33 System.out.println("mov [bx]+100," + "ax"); 34 return value; 35 } 36 37 /** expr NEWLINE */ 38 @Override 39 public Integer visitPrintExpr(LabeledExprParser.PrintExprContext ctx) { 40 Integer value = visit(ctx.expr()); // evaluate the expr child 41 System.out.println(value); // print the result 42 return 0; // return dummy value 43 } 44 45 /** INT */ 46 @Override 47 public Integer visitInt(LabeledExprParser.IntContext ctx) { 48 int i= Integer.valueOf(ctx.INT().getText()); 49 System.out.println("mov ax," + i); 50 System.out.println("push ax"); 51 return i; 52 } 53 54 /** ID */ 55 @Override 56 public Integer visitId(LabeledExprParser.IdContext ctx) { 57 String id = ctx.ID().getText(); 58 if ( memory.containsKey(id) ) { 59 int i = new Mem(id).invoke(); 60 System.out.println("mov bx ," + Integer.toHexString(i)); 61 System.out.println("mov ax ,[bx+100]"); 62 System.out.println("push ax"); 63 return memory.get(id); 64 } 65 return 0; 66 } 67 68 /** expr op=('*'|'/') expr */ 69 @Override 70 public Integer visitMulDiv(LabeledExprParser.MulDivContext ctx) { 71 int left = visit(ctx.expr(0)); // get value of left subexpression 72 73 int right = visit(ctx.expr(1)); // get value of right subexpression 74 System.out.println("pop cx"); System.out.println("pop ax"); 75 if ( ctx.op.getType() == LabeledExprParser.MUL ){ 76 System.out.println("mul ax,cx"); 77 System.out.println("push ax "); 78 // System.out.println("push dx "); 79 return left * right; 80 } 81 System.out.println("div ax,cx"); 82 System.out.println("push ax "); 83 // System.out.println("push dx "); 84 return left / right; // must be DIV 85 } 86 87 /** expr op=('+'|'-') expr */ 88 @Override 89 public Integer visitAddSub(LabeledExprParser.AddSubContext ctx) { 90 int left = visit(ctx.expr(0)); // get value of left subexpression 91 92 int right = visit(ctx.expr(1)); // get value of right subexpression 93 System.out.println("pop cx"); System.out.println("pop ax"); 94 if ( ctx.op.getType() == LabeledExprParser.ADD ) 95 { System.out.println("add ax,cx"); 96 System.out.println("push ax "); 97 return left + right; 98 99 } 100 System.out.println("sub ax,cx"); 101 System.out.println("push ax "); 102 return left - right; // must be SUB 103 } 104 105 /** '(' expr ')' */ 106 @Override 107 public Integer visitParens(LabeledExprParser.ParensContext ctx) { 108 return visit(ctx.expr()); // return child expr's value 109 } 110 111 private class Mem { 112 private String id; 113 114 public Mem(String id) { 115 this.id = id; 116 } 117 118 public int invoke() { 119 int i=0; 120 for (String s : memory.keySet()){ 121 122 if (s.equals(id)) { 123 break; 124 } 125 126 i++ ; 127 } 128 return i; 129 } 130 } 131 }
测试
package LabeledExpr.Imp; /** * Created by IntelliJ IDEA. * User: han * Date: 14-1-22 * Time: 下午2:15 * To change this template use File | Settings | File Templates. */ import LabeledExpr.LabeledExprLexer; import LabeledExpr.LabeledExprParser; import org.antlr.runtime.tree.CommonTreeNodeStream; import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; public class Calc { public static void main(String[] args) throws Exception { String inputFile = null; if ( args.length>0 ) inputFile = args[0]; InputStream is = System.in; if ( inputFile!=null ) is = new FileInputStream(inputFile); // InputStreamReader in = new InputStreamReader(is); // BufferedReader read = new BufferedReader(in ); // String s= read.readLine(); ANTLRInputStream input = new ANTLRInputStream( is); LabeledExprLexer lexer = new LabeledExprLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); LabeledExprParser parser = new LabeledExprParser(tokens); LabeledExprParser.ProgContext tree = parser.prog(); // parse tree.inspect(parser) ; EvalVisitor eval = new EvalVisitor(); eval.visit(tree); } }
原来的例子是解释执行
增加了汇编语言,好久没有使用汇编了语句有些不熟练
参数文件内容
a=4
b=2
c=10*(a/b)
1 mov ax,4 2 push ax 3 mov bx ,0 4 pop ax 5 mov [bx]+100,ax 6 mov ax,2 7 push ax 8 mov bx ,1 9 pop ax 10 mov [bx]+100,ax 11 mov ax,10 12 push ax 13 mov bx ,0 14 mov ax ,[bx+100] 15 push ax 16 mov bx ,1 17 mov ax ,[bx+100] 18 push ax 19 pop cx 20 pop ax 21 div ax,cx 22 push ax 23 pop cx 24 pop ax 25 mul ax,cx 26 push ax 27 mov bx ,2 28 pop ax 29 mov [bx]+100,ax
没有优化