├── Makefile ├── README ├── inter ├── Access.java ├── And.java ├── Arith.java ├── Break.java ├── Constant.java ├── Do.java ├── Else.java ├── Expr.java ├── Id.java ├── If.java ├── Logical.java ├── Node.java ├── Not.java ├── Op.java ├── Or.java ├── Rel.java ├── Seq.java ├── Set.java ├── SetElem.java ├── Stmt.java ├── Temp.java ├── Unary.java └── While.java ├── lexer ├── Lexer.java ├── Num.java ├── Real.java ├── Tag.java ├── Token.java └── Word.java ├── main └── Main.java ├── parser └── Parser.java ├── symbols ├── Array.java ├── Env.java └── Type.java ├── tests ├── block1.i ├── block1.t ├── expr1.i ├── expr1.t ├── expr2.i ├── expr2.t ├── expr3.i ├── expr3.t ├── expr4.i ├── expr4.t ├── identity.i ├── identity.t ├── identity2.i ├── identity2.t ├── jump1.i ├── jump1.t ├── jump2.i ├── jump2.t ├── jump3.i ├── jump3.t ├── prog0.i ├── prog0.t ├── prog1.i ├── prog1.t ├── prog2.i ├── prog2.t ├── prog3.i ├── prog3.t ├── prog4.i └── prog4.t └── tmp ├── block1.i ├── expr1.i ├── expr2.i ├── expr3.i ├── expr4.i ├── identity.i ├── identity2.i ├── jump1.i ├── jump2.i ├── jump3.i ├── prog0.i ├── prog1.i ├── prog2.i ├── prog3.i └── prog4.i /Makefile: -------------------------------------------------------------------------------- 1 | build: compile test 2 | 3 | compile: 4 | javac lexer/*.java 5 | javac symbols/*.java 6 | javac inter/*.java 7 | javac parser/*.java 8 | javac main/*.java 9 | 10 | test: 11 | @for i in `(cd tests; ls *.t | sed -e 's/.t$$//')`;\ 12 | do echo $$i.t;\ 13 | java main.Main tmp/$$i.i;\ 14 | diff tests/$$i.i tmp/$$i.i;\ 15 | done 16 | 17 | clean: 18 | (cd lexer; rm *.class) 19 | (cd symbols; rm *.class) 20 | (cd inter; rm *.class) 21 | (cd parser; rm *.class) 22 | (cd main; rm *.class) 23 | 24 | yacc: 25 | /usr/ccs/bin/yacc -v doc/front.y 26 | rm y.tab.c 27 | mv y.output doc 28 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Taken from the Dragon Book 2 | 3 | The Language 4 | 5 | The language is based on the fragments in Chapter 6: expressions, arrays, 6 | boolean expressions, statements, declarations, blocks: 7 | 8 | P -> { DD SS } 9 | DD -> e | DD D | D 10 | D -> T id ; 11 | T -> T [ num ] | int | float | char | bool 12 | SS -> e | SS S | S 13 | S -> L = E ; | if ( B ) S | if ( B ) S else S | while ( B ) S 14 | | do S while ( B ) ; | break ; | { DD SS } 15 | B -> B or B | B and B | ! B | ( B ) | E rel E | true | false 16 | E -> E + E | E - E | E * E | E / E | L | ( B ) | num 17 | L -> L [ B ] | id 18 | 19 | 20 | Package lexer 21 | 22 | class Tag. Tags distinguish tokens. 23 | class Token with subclasses Num, Real, and Word 24 | class Lexer, with procedure scan 25 | 26 | 27 | Package symbols 28 | 29 | class Type. Put types here. 30 | class Id. Could have put Id's with expressions; in fact Id extends Expr 31 | clas Env. Linked symbol tables. 32 | 33 | 34 | Package inter for intermediate code 35 | 36 | For simplicity, the front end builds syntax trees. Three-address code is 37 | emitted during a subsequent pass. We generate short-circuit code for 38 | boolean expressions. 39 | 40 | An optimizing compiler would presumably create intermediate-code objects 41 | rather than emitting strings. Further, Chapter 9 has examples with code 42 | that might be produced by backpatching -- that's a variant to be explored 43 | separately. 44 | 45 | Package parser 46 | 47 | At one point, I had the parser and lexer in one package, called syntax. 48 | The parser is kept separate for readability. We can present the lexer 49 | early -- the parser "touches" the other packages, so it's best presented 50 | later. 51 | 52 | Directories tests and tmp 53 | 54 | The makefile automatically runs a compiled front end on tests, presumed 55 | to be in files ending in ".t"; for example, prog0.t is the quicksort 56 | fragment from the running example in Chapter 9. The expected output is 57 | in a file ending in ".i"; for example, prog0.i. 58 | 59 | To distinguish between multiple declarations of the same name, uncomment 60 | the line 61 | 62 | // public String toString() {return "" + op.toString() + offset;} 63 | 64 | in class Id in package inter. The intermediate code will then print the 65 | offset as a suffix to an identifier. 66 | 67 | -------------------------------------------------------------------------------- /inter/Access.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Access extends Op { 5 | 6 | public Id array; 7 | public Expr index; 8 | 9 | public Access(Id a, Expr i, Type p) { // p is element type after 10 | super(new Word("[]", Tag.INDEX), p); // flattening the array 11 | array = a; index = i; 12 | } 13 | 14 | public Expr gen() { return new Access(array, index.reduce(), type); } 15 | 16 | public void jumping(int t,int f) { emitjumps(reduce().toString(),t,f); } 17 | 18 | public String toString() { 19 | return array.toString() + " [ " + index.toString() + " ]"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /inter/And.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class And extends Logical { 5 | 6 | public And(Token tok, Expr x1, Expr x2) { super(tok, x1, x2); } 7 | 8 | public void jumping(int t, int f) { 9 | int label = f != 0 ? f : newlabel(); 10 | expr1.jumping(0, label); 11 | expr2.jumping(t,f); 12 | if( f == 0 ) emitlabel(label); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /inter/Arith.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Arith extends Op { 5 | 6 | public Expr expr1, expr2; 7 | 8 | public Arith(Token tok, Expr x1, Expr x2) { 9 | super(tok, null); expr1 = x1; expr2 = x2; 10 | type = Type.max(expr1.type, expr2.type); 11 | if (type == null ) error("type error"); 12 | } 13 | 14 | public Expr gen() { 15 | return new Arith(op, expr1.reduce(), expr2.reduce()); 16 | } 17 | 18 | public String toString() { 19 | return expr1.toString()+" "+op.toString()+" "+expr2.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /inter/Break.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | 3 | public class Break extends Stmt { 4 | 5 | Stmt stmt; 6 | 7 | public Break() { 8 | if( Stmt.Enclosing == Stmt.Null ) error("unenclosed break"); 9 | stmt = Stmt.Enclosing; 10 | } 11 | 12 | public void gen(int b, int a) { 13 | emit( "goto L" + stmt.after); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /inter/Constant.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Constant extends Expr { 5 | 6 | public Constant(Token tok, Type p) { super(tok, p); } 7 | public Constant(int i) { super(new Num(i), Type.Int); } 8 | 9 | public static final Constant 10 | True = new Constant(Word.True, Type.Bool), 11 | False = new Constant(Word.False, Type.Bool); 12 | 13 | public void jumping(int t, int f) { 14 | if ( this == True && t != 0 ) emit("goto L" + t); 15 | else if ( this == False && f != 0) emit("goto L" + f); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /inter/Do.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import symbols.*; 3 | 4 | public class Do extends Stmt { 5 | 6 | Expr expr; Stmt stmt; 7 | 8 | public Do() { expr = null; stmt = null; } 9 | 10 | public void init(Stmt s, Expr x) { 11 | expr = x; stmt = s; 12 | if( expr.type != Type.Bool ) expr.error("boolean required in do"); 13 | } 14 | 15 | public void gen(int b, int a) { 16 | after = a; 17 | int label = newlabel(); // label for expr 18 | stmt.gen(b,label); 19 | emitlabel(label); 20 | expr.jumping(b,0); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /inter/Else.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import symbols.*; 3 | 4 | public class Else extends Stmt { 5 | 6 | Expr expr; Stmt stmt1, stmt2; 7 | 8 | public Else(Expr x, Stmt s1, Stmt s2) { 9 | expr = x; stmt1 = s1; stmt2 = s2; 10 | if( expr.type != Type.Bool ) expr.error("boolean required in if"); 11 | } 12 | public void gen(int b, int a) { 13 | int label1 = newlabel(); // label1 for stmt1 14 | int label2 = newlabel(); // label2 for stmt2 15 | expr.jumping(0,label2); // fall through to stmt1 on true 16 | emitlabel(label1); stmt1.gen(label1, a); emit("goto L" + a); 17 | emitlabel(label2); stmt2.gen(label2, a); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /inter/Expr.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Expr extends Node { 5 | 6 | public Token op; 7 | public Type type; 8 | 9 | Expr(Token tok, Type p) { op = tok; type = p; } 10 | 11 | public Expr gen() { return this; } 12 | public Expr reduce() { return this; } 13 | 14 | public void jumping(int t, int f) { emitjumps(toString(), t, f); } 15 | 16 | public void emitjumps(String test, int t, int f) { 17 | if( t != 0 && f != 0 ) { 18 | emit("if " + test + " goto L" + t); 19 | emit("goto L" + f); 20 | } 21 | else if( t != 0 ) emit("if " + test + " goto L" + t); 22 | else if( f != 0 ) emit("iffalse " + test + " goto L" + f); 23 | else ; // nothing since both t and f fall through 24 | } 25 | public String toString() { return op.toString(); } 26 | } 27 | -------------------------------------------------------------------------------- /inter/Id.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Id extends Expr { 5 | 6 | public int offset; // relative address 7 | 8 | public Id(Word id, Type p, int b) { super(id, p); offset = b; } 9 | 10 | // public String toString() {return "" + op.toString() + offset;} 11 | } 12 | -------------------------------------------------------------------------------- /inter/If.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import symbols.*; 3 | 4 | public class If extends Stmt { 5 | 6 | Expr expr; Stmt stmt; 7 | 8 | public If(Expr x, Stmt s) { 9 | expr = x; stmt = s; 10 | if( expr.type != Type.Bool ) expr.error("boolean required in if"); 11 | } 12 | 13 | public void gen(int b, int a) { 14 | int label = newlabel(); // label for the code for stmt 15 | expr.jumping(0, a); // fall through on true, goto a on false 16 | emitlabel(label); stmt.gen(label, a); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /inter/Logical.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Logical extends Expr { 5 | 6 | public Expr expr1, expr2; 7 | 8 | Logical(Token tok, Expr x1, Expr x2) { 9 | super(tok, null); // null type to start 10 | expr1 = x1; expr2 = x2; 11 | type = check(expr1.type, expr2.type); 12 | if (type == null ) error("type error"); 13 | } 14 | 15 | public Type check(Type p1, Type p2) { 16 | if ( p1 == Type.Bool && p2 == Type.Bool ) return Type.Bool; 17 | else return null; 18 | } 19 | 20 | public Expr gen() { 21 | int f = newlabel(); int a = newlabel(); 22 | Temp temp = new Temp(type); 23 | this.jumping(0,f); 24 | emit(temp.toString() + " = true"); 25 | emit("goto L" + a); 26 | emitlabel(f); emit(temp.toString() + " = false"); 27 | emitlabel(a); 28 | return temp; 29 | } 30 | 31 | public String toString() { 32 | return expr1.toString()+" "+op.toString()+" "+expr2.toString(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /inter/Node.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; 3 | 4 | public class Node { 5 | 6 | int lexline = 0; 7 | 8 | Node() { lexline = Lexer.line; } 9 | 10 | void error(String s) { throw new Error("near line "+lexline+": "+s); } 11 | 12 | static int labels = 0; 13 | 14 | public int newlabel() { return ++labels; } 15 | 16 | public void emitlabel(int i) { System.out.print("L" + i + ":"); } 17 | 18 | public void emit(String s) { System.out.println("\t" + s); } 19 | } 20 | -------------------------------------------------------------------------------- /inter/Not.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Not extends Logical { 5 | 6 | public Not(Token tok, Expr x2) { super(tok, x2, x2); } 7 | 8 | public void jumping(int t, int f) { expr2.jumping(f, t); } 9 | 10 | public String toString() { return op.toString()+" "+expr2.toString(); } 11 | } 12 | -------------------------------------------------------------------------------- /inter/Op.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Op extends Expr { 5 | 6 | public Op(Token tok, Type p) { super(tok, p); } 7 | 8 | public Expr reduce() { 9 | Expr x = gen(); 10 | Temp t = new Temp(type); 11 | emit( t.toString() + " = " + x.toString() ); 12 | return t; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /inter/Or.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Or extends Logical { 5 | 6 | public Or(Token tok, Expr x1, Expr x2) { super(tok, x1, x2); } 7 | 8 | public void jumping(int t, int f) { 9 | int label = t != 0 ? t : newlabel(); 10 | expr1.jumping(label, 0); 11 | expr2.jumping(t,f); 12 | if( t == 0 ) emitlabel(label); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /inter/Rel.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Rel extends Logical { 5 | 6 | public Rel(Token tok, Expr x1, Expr x2) { super(tok, x1, x2); } 7 | 8 | public Type check(Type p1, Type p2) { 9 | if ( p1 instanceof Array || p2 instanceof Array ) return null; 10 | else if( p1 == p2 ) return Type.Bool; 11 | else return null; 12 | } 13 | 14 | public void jumping(int t, int f) { 15 | Expr a = expr1.reduce(); 16 | Expr b = expr2.reduce(); 17 | String test = a.toString() + " " + op.toString() + " " + b.toString(); 18 | emitjumps(test, t, f); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /inter/Seq.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | 3 | public class Seq extends Stmt { 4 | 5 | Stmt stmt1; Stmt stmt2; 6 | 7 | public Seq(Stmt s1, Stmt s2) { stmt1 = s1; stmt2 = s2; } 8 | 9 | public void gen(int b, int a) { 10 | if ( stmt1 == Stmt.Null ) stmt2.gen(b, a); 11 | else if ( stmt2 == Stmt.Null ) stmt1.gen(b, a); 12 | else { 13 | int label = newlabel(); 14 | stmt1.gen(b,label); 15 | emitlabel(label); 16 | stmt2.gen(label,a); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /inter/Set.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Set extends Stmt { 5 | 6 | public Id id; public Expr expr; 7 | 8 | public Set(Id i, Expr x) { 9 | id = i; expr = x; 10 | if ( check(id.type, expr.type) == null ) error("type error"); 11 | } 12 | 13 | public Type check(Type p1, Type p2) { 14 | if ( Type.numeric(p1) && Type.numeric(p2) ) return p2; 15 | else if ( p1 == Type.Bool && p2 == Type.Bool ) return p2; 16 | else return null; 17 | } 18 | 19 | public void gen(int b, int a) { 20 | emit( id.toString() + " = " + expr.gen().toString() ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /inter/SetElem.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class SetElem extends Stmt { 5 | 6 | public Id array; public Expr index; public Expr expr; 7 | 8 | public SetElem(Access x, Expr y) { 9 | array = x.array; index = x.index; expr = y; 10 | if ( check(x.type, expr.type) == null ) error("type error"); 11 | } 12 | 13 | public Type check(Type p1, Type p2) { 14 | if ( p1 instanceof Array || p2 instanceof Array ) return null; 15 | else if ( p1 == p2 ) return p2; 16 | else if ( Type.numeric(p1) && Type.numeric(p2) ) return p2; 17 | else return null; 18 | } 19 | 20 | public void gen(int b, int a) { 21 | String s1 = index.reduce().toString(); 22 | String s2 = expr.reduce().toString(); 23 | emit(array.toString() + " [ " + s1 + " ] = " + s2); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /inter/Stmt.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | 3 | public class Stmt extends Node { 4 | 5 | public Stmt() { } 6 | 7 | public static Stmt Null = new Stmt(); 8 | 9 | public void gen(int b, int a) {} // called with labels begin and after 10 | 11 | int after = 0; // saves label after 12 | public static Stmt Enclosing = Stmt.Null; // used for break stmts 13 | } 14 | -------------------------------------------------------------------------------- /inter/Temp.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Temp extends Expr { 5 | 6 | static int count = 0; 7 | int number = 0; 8 | 9 | public Temp(Type p) { super(Word.temp, p); number = ++count; } 10 | 11 | public String toString() { return "t" + number; } 12 | } 13 | -------------------------------------------------------------------------------- /inter/Unary.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import lexer.*; import symbols.*; 3 | 4 | public class Unary extends Op { 5 | 6 | public Expr expr; 7 | 8 | public Unary(Token tok, Expr x) { // handles minus, for ! see Not 9 | super(tok, null); expr = x; 10 | type = Type.max(Type.Int, expr.type); 11 | if (type == null ) error("type error"); 12 | } 13 | 14 | public Expr gen() { return new Unary(op, expr.reduce()); } 15 | 16 | public String toString() { return op.toString()+" "+expr.toString(); } 17 | } 18 | -------------------------------------------------------------------------------- /inter/While.java: -------------------------------------------------------------------------------- 1 | package inter; 2 | import symbols.*; 3 | 4 | public class While extends Stmt { 5 | 6 | Expr expr; Stmt stmt; 7 | 8 | public While() { expr = null; stmt = null; } 9 | 10 | public void init(Expr x, Stmt s) { 11 | expr = x; stmt = s; 12 | if( expr.type != Type.Bool ) expr.error("boolean required in while"); 13 | } 14 | public void gen(int b, int a) { 15 | after = a; // save label a 16 | expr.jumping(0, a); 17 | int label = newlabel(); // label for stmt 18 | emitlabel(label); stmt.gen(label, b); 19 | emit("goto L" + b); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lexer/Lexer.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | import java.io.*; 3 | import java.util.*; 4 | import symbols.*; 5 | public class Lexer { 6 | public static int line = 1; 7 | char peek = ' '; 8 | Hashtable words = new Hashtable(); 9 | void reserve(Word w) { words.put(w.lexeme, w); } 10 | 11 | public Lexer() { 12 | 13 | reserve( new Word("if", Tag.IF) ); 14 | reserve( new Word("else", Tag.ELSE) ); 15 | reserve( new Word("while", Tag.WHILE) ); 16 | reserve( new Word("do", Tag.DO) ); 17 | reserve( new Word("break", Tag.BREAK) ); 18 | 19 | reserve( Word.True ); reserve( Word.False ); 20 | 21 | reserve( Type.Int ); reserve( Type.Char ); 22 | reserve( Type.Bool ); reserve( Type.Float ); 23 | } 24 | 25 | void readch() throws IOException { peek = (char)System.in.read(); } 26 | boolean readch(char c) throws IOException { 27 | readch(); 28 | if( peek != c ) return false; 29 | peek = ' '; 30 | return true; 31 | } 32 | public Token scan() throws IOException { 33 | for( ; ; readch() ) { 34 | if( peek == ' ' || peek == '\t' ) continue; 35 | else if( peek == '\n' ) line = line + 1; 36 | else break; 37 | } 38 | switch( peek ) { 39 | case '&': 40 | if( readch('&') ) return Word.and; else return new Token('&'); 41 | case '|': 42 | if( readch('|') ) return Word.or; else return new Token('|'); 43 | case '=': 44 | if( readch('=') ) return Word.eq; else return new Token('='); 45 | case '!': 46 | if( readch('=') ) return Word.ne; else return new Token('!'); 47 | case '<': 48 | if( readch('=') ) return Word.le; else return new Token('<'); 49 | case '>': 50 | if( readch('=') ) return Word.ge; else return new Token('>'); 51 | } 52 | if( Character.isDigit(peek) ) { 53 | int v = 0; 54 | do { 55 | v = 10*v + Character.digit(peek, 10); readch(); 56 | } while( Character.isDigit(peek) ); 57 | if( peek != '.' ) return new Num(v); 58 | float x = v; float d = 10; 59 | for(;;) { 60 | readch(); 61 | if( ! Character.isDigit(peek) ) break; 62 | x = x + Character.digit(peek, 10) / d; d = d*10; 63 | } 64 | return new Real(x); 65 | } 66 | if( Character.isLetter(peek) ) { 67 | StringBuffer b = new StringBuffer(); 68 | do { 69 | b.append(peek); readch(); 70 | } while( Character.isLetterOrDigit(peek) ); 71 | String s = b.toString(); 72 | Word w = (Word)words.get(s); 73 | if( w != null ) return w; 74 | w = new Word(s, Tag.ID); 75 | words.put(s, w); 76 | return w; 77 | } 78 | Token tok = new Token(peek); peek = ' '; 79 | return tok; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lexer/Num.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public class Num extends Token { 4 | 5 | public final int value; 6 | public Num(int v) { super(Tag.NUM); value = v; } 7 | public String toString() { return "" + value; } 8 | } 9 | -------------------------------------------------------------------------------- /lexer/Real.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | public class Real extends Token { 3 | 4 | public final float value; 5 | public Real(float v) { super(Tag.REAL); value = v; } 6 | public String toString() { return "" + value; } 7 | } 8 | -------------------------------------------------------------------------------- /lexer/Tag.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public class Tag { 4 | 5 | public final static int 6 | AND = 256, BASIC = 257, BREAK = 258, DO = 259, ELSE = 260, 7 | EQ = 261, FALSE = 262, GE = 263, ID = 264, IF = 265, 8 | INDEX = 266, LE = 267, MINUS = 268, NE = 269, NUM = 270, 9 | OR = 271, REAL = 272, TEMP = 273, TRUE = 274, WHILE = 275; 10 | } 11 | -------------------------------------------------------------------------------- /lexer/Token.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public class Token { 4 | 5 | public final int tag; 6 | public Token(int t) { tag = t; } 7 | public String toString() {return "" + (char)tag;} 8 | } 9 | -------------------------------------------------------------------------------- /lexer/Word.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | public class Word extends Token { 3 | 4 | public String lexeme = ""; 5 | public Word(String s, int tag) { super(tag); lexeme = s; } 6 | public String toString() { return lexeme; } 7 | 8 | public static final Word 9 | 10 | and = new Word( "&&", Tag.AND ), or = new Word( "||", Tag.OR ), 11 | eq = new Word( "==", Tag.EQ ), ne = new Word( "!=", Tag.NE ), 12 | le = new Word( "<=", Tag.LE ), ge = new Word( ">=", Tag.GE ), 13 | 14 | minus = new Word( "minus", Tag.MINUS ), 15 | True = new Word( "true", Tag.TRUE ), 16 | False = new Word( "false", Tag.FALSE ), 17 | temp = new Word( "t", Tag.TEMP ); 18 | } 19 | -------------------------------------------------------------------------------- /main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | import java.io.*; import lexer.*; import parser.*; 3 | 4 | public class Main { 5 | 6 | public static void main(String[] args) throws IOException { 7 | Lexer lex = new Lexer(); 8 | Parser parse = new Parser(lex); 9 | parse.program(); 10 | System.out.write('\n'); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /parser/Parser.java: -------------------------------------------------------------------------------- 1 | package parser; 2 | import java.io.*; import lexer.*; import symbols.*; import inter.*; 3 | 4 | public class Parser { 5 | 6 | private Lexer lex; // lexical analyzer for this parser 7 | private Token look; // lookahead tagen 8 | Env top = null; // current or top symbol table 9 | int used = 0; // storage used for declarations 10 | 11 | public Parser(Lexer l) throws IOException { lex = l; move(); } 12 | 13 | void move() throws IOException { look = lex.scan(); } 14 | 15 | void error(String s) { throw new Error("near line "+lex.line+": "+s); } 16 | 17 | void match(int t) throws IOException { 18 | if( look.tag == t ) move(); 19 | else error("syntax error"); 20 | } 21 | 22 | public void program() throws IOException { // program -> block 23 | Stmt s = block(); 24 | int begin = s.newlabel(); int after = s.newlabel(); 25 | s.emitlabel(begin); s.gen(begin, after); s.emitlabel(after); 26 | } 27 | 28 | Stmt block() throws IOException { // block -> { decls stmts } 29 | match('{'); Env savedEnv = top; top = new Env(top); 30 | decls(); Stmt s = stmts(); 31 | match('}'); top = savedEnv; 32 | return s; 33 | } 34 | 35 | void decls() throws IOException { 36 | 37 | while( look.tag == Tag.BASIC ) { // D -> type ID ; 38 | Type p = type(); Token tok = look; match(Tag.ID); match(';'); 39 | Id id = new Id((Word)tok, p, used); 40 | top.put( tok, id ); 41 | used = used + p.width; 42 | } 43 | } 44 | 45 | Type type() throws IOException { 46 | 47 | Type p = (Type)look; // expect look.tag == Tag.BASIC 48 | match(Tag.BASIC); 49 | if( look.tag != '[' ) return p; // T -> basic 50 | else return dims(p); // return array type 51 | } 52 | 53 | Type dims(Type p) throws IOException { 54 | match('['); Token tok = look; match(Tag.NUM); match(']'); 55 | if( look.tag == '[' ) 56 | p = dims(p); 57 | return new Array(((Num)tok).value, p); 58 | } 59 | 60 | Stmt stmts() throws IOException { 61 | if ( look.tag == '}' ) return Stmt.Null; 62 | else return new Seq(stmt(), stmts()); 63 | } 64 | 65 | Stmt stmt() throws IOException { 66 | Expr x; Stmt s, s1, s2; 67 | Stmt savedStmt; // save enclosing loop for breaks 68 | 69 | switch( look.tag ) { 70 | 71 | case ';': 72 | move(); 73 | return Stmt.Null; 74 | 75 | case Tag.IF: 76 | match(Tag.IF); match('('); x = bool(); match(')'); 77 | s1 = stmt(); 78 | if( look.tag != Tag.ELSE ) return new If(x, s1); 79 | match(Tag.ELSE); 80 | s2 = stmt(); 81 | return new Else(x, s1, s2); 82 | 83 | case Tag.WHILE: 84 | While whilenode = new While(); 85 | savedStmt = Stmt.Enclosing; Stmt.Enclosing = whilenode; 86 | match(Tag.WHILE); match('('); x = bool(); match(')'); 87 | s1 = stmt(); 88 | whilenode.init(x, s1); 89 | Stmt.Enclosing = savedStmt; // reset Stmt.Enclosing 90 | return whilenode; 91 | 92 | case Tag.DO: 93 | Do donode = new Do(); 94 | savedStmt = Stmt.Enclosing; Stmt.Enclosing = donode; 95 | match(Tag.DO); 96 | s1 = stmt(); 97 | match(Tag.WHILE); match('('); x = bool(); match(')'); match(';'); 98 | donode.init(s1, x); 99 | Stmt.Enclosing = savedStmt; // reset Stmt.Enclosing 100 | return donode; 101 | 102 | case Tag.BREAK: 103 | match(Tag.BREAK); match(';'); 104 | return new Break(); 105 | 106 | case '{': 107 | return block(); 108 | 109 | default: 110 | return assign(); 111 | } 112 | } 113 | 114 | Stmt assign() throws IOException { 115 | Stmt stmt; Token t = look; 116 | match(Tag.ID); 117 | Id id = top.get(t); 118 | if( id == null ) error(t.toString() + " undeclared"); 119 | 120 | if( look.tag == '=' ) { // S -> id = E ; 121 | move(); stmt = new Set(id, bool()); 122 | } 123 | else { // S -> L = E ; 124 | Access x = offset(id); 125 | match('='); stmt = new SetElem(x, bool()); 126 | } 127 | match(';'); 128 | return stmt; 129 | } 130 | 131 | Expr bool() throws IOException { 132 | Expr x = join(); 133 | while( look.tag == Tag.OR ) { 134 | Token tok = look; move(); x = new Or(tok, x, join()); 135 | } 136 | return x; 137 | } 138 | 139 | Expr join() throws IOException { 140 | Expr x = equality(); 141 | while( look.tag == Tag.AND ) { 142 | Token tok = look; move(); x = new And(tok, x, equality()); 143 | } 144 | return x; 145 | } 146 | 147 | Expr equality() throws IOException { 148 | Expr x = rel(); 149 | while( look.tag == Tag.EQ || look.tag == Tag.NE ) { 150 | Token tok = look; move(); x = new Rel(tok, x, rel()); 151 | } 152 | return x; 153 | } 154 | 155 | Expr rel() throws IOException { 156 | Expr x = expr(); 157 | switch( look.tag ) { 158 | case '<': case Tag.LE: case Tag.GE: case '>': 159 | Token tok = look; move(); return new Rel(tok, x, expr()); 160 | default: 161 | return x; 162 | } 163 | } 164 | 165 | Expr expr() throws IOException { 166 | Expr x = term(); 167 | while( look.tag == '+' || look.tag == '-' ) { 168 | Token tok = look; move(); x = new Arith(tok, x, term()); 169 | } 170 | return x; 171 | } 172 | 173 | Expr term() throws IOException { 174 | Expr x = unary(); 175 | while(look.tag == '*' || look.tag == '/' ) { 176 | Token tok = look; move(); x = new Arith(tok, x, unary()); 177 | } 178 | return x; 179 | } 180 | 181 | Expr unary() throws IOException { 182 | if( look.tag == '-' ) { 183 | move(); return new Unary(Word.minus, unary()); 184 | } 185 | else if( look.tag == '!' ) { 186 | Token tok = look; move(); return new Not(tok, unary()); 187 | } 188 | else return factor(); 189 | } 190 | 191 | Expr factor() throws IOException { 192 | Expr x = null; 193 | switch( look.tag ) { 194 | case '(': 195 | move(); x = bool(); match(')'); 196 | return x; 197 | case Tag.NUM: 198 | x = new Constant(look, Type.Int); move(); return x; 199 | case Tag.REAL: 200 | x = new Constant(look, Type.Float); move(); return x; 201 | case Tag.TRUE: 202 | x = Constant.True; move(); return x; 203 | case Tag.FALSE: 204 | x = Constant.False; move(); return x; 205 | default: 206 | error("syntax error"); 207 | return x; 208 | case Tag.ID: 209 | String s = look.toString(); 210 | Id id = top.get(look); 211 | if( id == null ) error(look.toString() + " undeclared"); 212 | move(); 213 | if( look.tag != '[' ) return id; 214 | else return offset(id); 215 | } 216 | } 217 | 218 | Access offset(Id a) throws IOException { // I -> [E] | [E] I 219 | Expr i; Expr w; Expr t1, t2; Expr loc; // inherit id 220 | 221 | Type type = a.type; 222 | match('['); i = bool(); match(']'); // first index, I -> [ E ] 223 | type = ((Array)type).of; 224 | w = new Constant(type.width); 225 | t1 = new Arith(new Token('*'), i, w); 226 | loc = t1; 227 | while( look.tag == '[' ) { // multi-dimensional I -> [ E ] I 228 | match('['); i = bool(); match(']'); 229 | type = ((Array)type).of; 230 | w = new Constant(type.width); 231 | t1 = new Arith(new Token('*'), i, w); 232 | t2 = new Arith(new Token('+'), loc, t1); 233 | loc = t2; 234 | } 235 | 236 | return new Access(a, loc, type); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /symbols/Array.java: -------------------------------------------------------------------------------- 1 | package symbols; 2 | import lexer.*; 3 | public class Array extends Type { 4 | public Type of; // array *of* type 5 | public int size = 1; // number of elements 6 | public Array(int sz, Type p) { 7 | super("[]", Tag.INDEX, sz*p.width); size = sz; of = p; 8 | } 9 | public String toString() { return "[" + size + "] " + of.toString(); } 10 | } 11 | -------------------------------------------------------------------------------- /symbols/Env.java: -------------------------------------------------------------------------------- 1 | package symbols; 2 | import java.util.*; import lexer.*; import inter.*; 3 | 4 | public class Env { 5 | 6 | private Hashtable table; 7 | protected Env prev; 8 | 9 | public Env(Env n) { table = new Hashtable(); prev = n; } 10 | 11 | public void put(Token w, Id i) { table.put(w, i); } 12 | 13 | public Id get(Token w) { 14 | for( Env e = this; e != null; e = e.prev ) { 15 | Id found = (Id)(e.table.get(w)); 16 | if( found != null ) return found; 17 | } 18 | return null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /symbols/Type.java: -------------------------------------------------------------------------------- 1 | package symbols; 2 | import lexer.*; 3 | public class Type extends Word { 4 | 5 | public int width = 0; // width is used for storage allocation 6 | 7 | public Type(String s, int tag, int w) { super(s, tag); width = w; } 8 | 9 | public static final Type 10 | Int = new Type( "int", Tag.BASIC, 4 ), 11 | Float = new Type( "float", Tag.BASIC, 8 ), 12 | Char = new Type( "char", Tag.BASIC, 1 ), 13 | Bool = new Type( "bool", Tag.BASIC, 1 ); 14 | 15 | public static boolean numeric(Type p) { 16 | if (p == Type.Char || p == Type.Int || p == Type.Float) return true; 17 | else return false; 18 | } 19 | 20 | public static Type max(Type p1, Type p2 ) { 21 | if ( ! numeric(p1) || ! numeric(p2) ) return null; 22 | else if ( p1 == Type.Float || p2 == Type.Float ) return Type.Float; 23 | else if ( p1 == Type.Int || p2 == Type.Int ) return Type.Int; 24 | else return Type.Char; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/block1.i: -------------------------------------------------------------------------------- 1 | L1: a = 0 2 | L3: b = 0 3 | L4: b = 1 4 | L6: a = 2 5 | L7: b = 3 6 | L8: a = a + 1 7 | L9: b = b + 1 8 | L5: a = a + 1 9 | L10: b = b + 1 10 | L2: 11 | -------------------------------------------------------------------------------- /tests/block1.t: -------------------------------------------------------------------------------- 1 | { 2 | int a; int b; a = 0; b = 0; 3 | { 4 | int b; b = 1; 5 | { 6 | int a; a = 2; 7 | } 8 | { 9 | int b; b = 3; 10 | } 11 | a = a + 1; b = b + 1; 12 | } 13 | a = a + 1; b = b + 1; 14 | } 15 | -------------------------------------------------------------------------------- /tests/expr1.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: i = 365 3 | L4: x = 0.0 4 | L5: x = 3.1415896 5 | L6: b = true 6 | L7: b = false 7 | L8: i = x 8 | L9: x = i 9 | L2: 10 | -------------------------------------------------------------------------------- /tests/expr1.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; float x; bool b; 3 | i = 0; 4 | i = 365; 5 | x = 0.0; 6 | x = 3.14159; 7 | b = true; 8 | b = false; 9 | i = x; 10 | x = i; 11 | } 12 | -------------------------------------------------------------------------------- /tests/expr2.i: -------------------------------------------------------------------------------- 1 | L1: a = b + c 2 | L3: a = b - c 3 | L4: a = b * c 4 | L5: a = b / c 5 | L6: a = minus b 6 | L7: t1 = a - b 7 | d = t1 - c 8 | L8: t2 = a * b 9 | d = t2 * c 10 | L9: t3 = b * c 11 | d = a + t3 12 | L10: t4 = a * b 13 | d = t4 + c 14 | L11: t5 = a - b 15 | d = t5 - c 16 | L12: t6 = b - c 17 | d = a - t6 18 | L13: t7 = a + b 19 | d = t7 * c 20 | L14: t8 = b + c 21 | d = a * t8 22 | L15: t9 = b * b 23 | t10 = 4.0 * a 24 | t11 = t10 * c 25 | term = t9 - t11 26 | L2: 27 | -------------------------------------------------------------------------------- /tests/expr2.t: -------------------------------------------------------------------------------- 1 | { 2 | int a; int b; int c; int d; float term; 3 | 4 | a = b + c; 5 | a = b - c; 6 | a = b * c; 7 | a = b / c; 8 | a = -b; 9 | 10 | d = a - b - c; 11 | d = a * b * c; 12 | d = a + b * c; 13 | d = a * b + c; 14 | 15 | d = (a - b) - c; 16 | d = a - (b - c); 17 | d = (a + b) * c; 18 | d = a * (b + c); 19 | 20 | term = b*b -4.0*a*c; 21 | } 22 | -------------------------------------------------------------------------------- /tests/expr3.i: -------------------------------------------------------------------------------- 1 | L1: if x < y goto L4 2 | t1 = true 3 | goto L5 4 | L4: t1 = false 5 | L5: r = t1 6 | L3: iffalse x == y goto L7 7 | t2 = true 8 | goto L8 9 | L7: t2 = false 10 | L8: r = t2 11 | L6: if x > y goto L11 12 | L10: r = true 13 | goto L9 14 | L11: r = false 15 | L9: iffalse x != y goto L13 16 | L12: r = true 17 | goto L2 18 | L13: r = false 19 | L2: 20 | -------------------------------------------------------------------------------- /tests/expr3.t: -------------------------------------------------------------------------------- 1 | { 2 | int x; int y; bool r; 3 | 4 | r = !(x < y); 5 | 6 | r = !!(x == y); 7 | 8 | if( !(x > y) ) r = true; 9 | else r = false; 10 | 11 | if( !!(x != y) ) r = true; 12 | else r = false; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /tests/expr4.i: -------------------------------------------------------------------------------- 1 | L1: t1 = i * 12 2 | t2 = j * 4 3 | t3 = t1 + t2 4 | t4 = a [ t3 ] 5 | x = c + t4 6 | L3: t5 = i * 12 7 | t6 = j * 4 8 | t7 = t5 + t6 9 | a [ t7 ] = 0 10 | L4: t8 = i * 100 11 | t9 = j * 10 12 | t10 = t8 + t9 13 | t11 = k * 1 14 | t12 = t10 + t11 15 | b [ t12 ] = true 16 | L5: t13 = i * 100 17 | t14 = j * 10 18 | t15 = t13 + t14 19 | t16 = k * 1 20 | t17 = t15 + t16 21 | d = b [ t17 ] 22 | L2: 23 | -------------------------------------------------------------------------------- /tests/expr4.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; int j; int k; 3 | int[2][3] a; int x; int c; 4 | bool[10][10][10] b; bool d; 5 | 6 | x = c+a[i][j]; 7 | a[i][j] = 0; 8 | 9 | b[i][j][k] = true; 10 | d = b[i][j][k]; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/identity.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: iffalse i < 10 goto L4 3 | L5: j = 0 4 | L6: iffalse j < 10 goto L7 5 | L8: t1 = i * 80 6 | t2 = j * 8 7 | t3 = t1 + t2 8 | a [ t3 ] = 0.0 9 | L9: j = j + 1 10 | goto L6 11 | L7: i = i + 1 12 | goto L3 13 | L4: i = 0 14 | L10: iffalse i < 10 goto L2 15 | L11: t4 = i * 80 16 | t5 = i * 8 17 | t6 = t4 + t5 18 | a [ t6 ] = 1.0 19 | L12: i = i + 1 20 | goto L10 21 | L2: 22 | -------------------------------------------------------------------------------- /tests/identity.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; int j; float[10][10] a; 3 | i = 0; 4 | while ( i < 10 ) { 5 | j = 0; 6 | while ( j < 10 ) { 7 | a[i][j] = 0.0; 8 | j = j + 1; 9 | } 10 | i = i + 1; 11 | } 12 | i = 0; 13 | while ( i < 10 ) { 14 | a[i][i] = 1.0; 15 | i = i + 1; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/identity2.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3:L5: j = 0 3 | L6:L8: t1 = i * 80 4 | t2 = j * 8 5 | t3 = t1 + t2 6 | a [ t3 ] = 0.0 7 | L9: iffalse j >= 10 goto L6 8 | L10: goto L7 9 | goto L6 10 | L7: iffalse i >= 10 goto L3 11 | L11: goto L4 12 | goto L3 13 | L4: i = 0 14 | L12:L13: t4 = i * 80 15 | t5 = i * 8 16 | t6 = t4 + t5 17 | a [ t6 ] = 1.0 18 | L14: iffalse i >= 10 goto L12 19 | L15: goto L2 20 | goto L12 21 | L2: 22 | -------------------------------------------------------------------------------- /tests/identity2.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; int j; float[10][10] a; 3 | i = 0; 4 | while(true) { 5 | j = 0; 6 | while(true) { 7 | a[i][j] = 0.0; 8 | if( j >= 10 ) break; 9 | } 10 | if( i >= 10 ) break; 11 | } 12 | i = 0; 13 | while(true) { 14 | a[i][i] = 1.0; 15 | if( i >= 10 ) break; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/jump1.i: -------------------------------------------------------------------------------- 1 | L1:L4: a = 0 2 | L3: goto L5 3 | L6: x = 0 4 | L5: iffalse a < b goto L7 5 | L8: a = b 6 | L7: iffalse x <= y goto L9 7 | L10: x = y 8 | L9: iffalse a == b goto L11 9 | L12: a = b 10 | L11: iffalse x != y goto L13 11 | L14: x = y 12 | L13: iffalse a >= b goto L15 13 | L16: b = a 14 | L15: iffalse x > y goto L17 15 | L18: y = x 16 | L17: iffalse a == b goto L19 17 | L20:L19: if x < 100 goto L23 18 | iffalse x > 200 goto L21 19 | L23:L22: x = 0 20 | L21: iffalse a < 100 goto L24 21 | iffalse a > 200 goto L24 22 | L25: b = 0 23 | L24: if x < 100 goto L28 24 | iffalse x > 200 goto L26 25 | iffalse x != y goto L26 26 | L28:L27: x = 0 27 | L26: if a < 100 goto L31 28 | iffalse a > 200 goto L32 29 | if a != 150 goto L31 30 | L32: iffalse a != 0 goto L29 31 | L31:L30: a = 0 32 | L29: iffalse x > 200 goto L36 33 | if x != b goto L35 34 | L36: iffalse x < 100 goto L33 35 | L35:L34: x = 0 36 | L33: if a < 100 goto L38 37 | iffalse a > 200 goto L2 38 | iffalse a != b goto L2 39 | L38:L37: a = 0 40 | L2: 41 | -------------------------------------------------------------------------------- /tests/jump1.t: -------------------------------------------------------------------------------- 1 | { 2 | int x; int y; int a; int b; 3 | 4 | if( true ) a = 0; 5 | 6 | if( false ) x = 0; 7 | 8 | if ( a < b ) a = b; 9 | 10 | if ( x <= y ) x = y; 11 | 12 | if ( a == b ) a = b; 13 | 14 | if ( x != y ) x = y; 15 | 16 | if ( a >= b ) b = a; 17 | 18 | if ( x > y ) y = x; 19 | 20 | if ( a == b ) ; 21 | 22 | if( x < 100 || x > 200 ) x = 0; 23 | 24 | if( a < 100 && a > 200 ) b = 0; 25 | 26 | if( x < 100 || (x > 200 && x != y) ) x = 0; 27 | 28 | if( a < 100 || (a > 200 && a != 150) || a != 0 ) a = 0; 29 | 30 | if( x > 200 && x != b || x < 100 ) x = 0; 31 | 32 | if( a < 100 || a > 200 && a != b ) a = 0; 33 | } 34 | -------------------------------------------------------------------------------- /tests/jump2.i: -------------------------------------------------------------------------------- 1 | L1: r = true 2 | L3: r = false 3 | L4: iffalse a < b goto L6 4 | t1 = true 5 | goto L7 6 | L6: t1 = false 7 | L7: r = t1 8 | L5: iffalse x <= y goto L9 9 | t2 = true 10 | goto L10 11 | L9: t2 = false 12 | L10: r = t2 13 | L8: iffalse a == b goto L12 14 | t3 = true 15 | goto L13 16 | L12: t3 = false 17 | L13: r = t3 18 | L11: iffalse x != y goto L15 19 | t4 = true 20 | goto L16 21 | L15: t4 = false 22 | L16: r = t4 23 | L14: iffalse a >= b goto L18 24 | t5 = true 25 | goto L19 26 | L18: t5 = false 27 | L19: r = t5 28 | L17: iffalse x > y goto L21 29 | t6 = true 30 | goto L22 31 | L21: t6 = false 32 | L22: r = t6 33 | L20: if x < 100 goto L26 34 | iffalse x > 200 goto L24 35 | L26: t7 = true 36 | goto L25 37 | L24: t7 = false 38 | L25: r = t7 39 | L23: iffalse a < 100 goto L28 40 | iffalse a > 200 goto L28 41 | t8 = true 42 | goto L29 43 | L28: t8 = false 44 | L29: r = t8 45 | L27: if x < 100 goto L33 46 | iffalse x > 200 goto L31 47 | iffalse x != y goto L31 48 | L33: t9 = true 49 | goto L32 50 | L31: t9 = false 51 | L32: r = t9 52 | L30: if a < 100 goto L37 53 | iffalse a > 200 goto L38 54 | if a != 150 goto L37 55 | L38: iffalse a != 0 goto L35 56 | L37: t10 = true 57 | goto L36 58 | L35: t10 = false 59 | L36: r = t10 60 | L34: iffalse x > 200 goto L43 61 | if x != b goto L42 62 | L43: iffalse x < 100 goto L40 63 | L42: t11 = true 64 | goto L41 65 | L40: t11 = false 66 | L41: r = t11 67 | L39: if a < 100 goto L46 68 | iffalse a > 200 goto L44 69 | iffalse a != b goto L44 70 | L46: t12 = true 71 | goto L45 72 | L44: t12 = false 73 | L45: r = t12 74 | L2: 75 | -------------------------------------------------------------------------------- /tests/jump2.t: -------------------------------------------------------------------------------- 1 | { 2 | int x; int y; int a; int b; bool r; 3 | 4 | r = true; 5 | 6 | r = false; 7 | 8 | r = a < b; 9 | 10 | r = x <= y; 11 | 12 | r = a == b; 13 | 14 | r = x != y; 15 | 16 | r = a >= b; 17 | 18 | r = x > y; 19 | 20 | r = x < 100 || x > 200; 21 | 22 | r = a < 100 && a > 200; 23 | 24 | r = x < 100 || (x > 200 && x != y); 25 | 26 | r = a < 100 || (a > 200 && a != 150) || a != 0; 27 | 28 | r = x > 200 && x != b || x < 100; 29 | 30 | r = a < 100 || a > 200 && a != b; 31 | } 32 | -------------------------------------------------------------------------------- /tests/jump3.i: -------------------------------------------------------------------------------- 1 | L1: r = b 2 | L3: t1 = i * 1 3 | r = a [ t1 ] 4 | L4: t2 = i * 1 5 | a [ t2 ] = b 6 | L5: t3 = i * 1 7 | a [ t3 ] = true 8 | L6: t4 = i * 1 9 | a [ t4 ] = false 10 | L7: iffalse b goto L8 11 | L9: x = y 12 | L8: t5 = i * 1 13 | t6 = a [ t5 ] 14 | iffalse t6 goto L2 15 | L10: x = y 16 | L2: 17 | -------------------------------------------------------------------------------- /tests/jump3.t: -------------------------------------------------------------------------------- 1 | { 2 | bool b; bool r; bool[11] a; int i; int x; int y; 3 | 4 | r = b; 5 | 6 | r = a[i]; 7 | 8 | a[i] = b; 9 | 10 | a[i] = true; 11 | 12 | a[i] = false; 13 | 14 | if( b ) x = y; 15 | 16 | if( a[i] ) x = y; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/prog0.i: -------------------------------------------------------------------------------- 1 | L1:L3: i = i + 1 2 | L5: t1 = i * 8 3 | t2 = a [ t1 ] 4 | if t2 < v goto L3 5 | L4: j = j - 1 6 | L7: t3 = j * 8 7 | t4 = a [ t3 ] 8 | if t4 > v goto L4 9 | L6: iffalse i >= j goto L8 10 | L9: goto L2 11 | L8: t5 = i * 8 12 | x = a [ t5 ] 13 | L10: t6 = i * 8 14 | t7 = j * 8 15 | t8 = a [ t7 ] 16 | a [ t6 ] = t8 17 | L11: t9 = j * 8 18 | a [ t9 ] = x 19 | goto L1 20 | L2: 21 | -------------------------------------------------------------------------------- /tests/prog0.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; int j; float v; float x; float[100] a; 3 | while( true ) { 4 | do i = i+1; while( a[i] < v); 5 | do j = j-1; while( a[j] > v); 6 | if( i >= j ) break; 7 | x = a[i]; a[i] = a[j]; a[j] = x; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/prog1.i: -------------------------------------------------------------------------------- 1 | L1: r = a 2 | L3: dd = d 3 | L4: iffalse dd <= r goto L5 4 | L6: dd = 2 * dd 5 | goto L4 6 | L5: iffalse dd != r goto L2 7 | L7: dd = dd / 2 8 | L8: iffalse dd <= r goto L5 9 | L9: r = r - dd 10 | goto L5 11 | L2: 12 | -------------------------------------------------------------------------------- /tests/prog1.t: -------------------------------------------------------------------------------- 1 | { 2 | int r; int dd; int a; int d; 3 | r = a; dd = d; 4 | while( dd <= r ) dd = 2*dd; 5 | while( dd != r ) { 6 | dd = dd/2; 7 | if (dd <= r) r = r - dd; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/prog2.i: -------------------------------------------------------------------------------- 1 | L1: prod = 0 2 | L3: i = 1 3 | L4: t1 = i * 8 4 | t2 = a [ t1 ] 5 | t3 = i * 8 6 | t4 = b [ t3 ] 7 | t5 = t2 * t4 8 | prod = prod + t5 9 | L6: i = i + 1 10 | L5: if i <= 20 goto L4 11 | L2: 12 | -------------------------------------------------------------------------------- /tests/prog2.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; float prod; float [20] a; float [20] b; 3 | prod = 0; 4 | i = 1; 5 | do { 6 | prod = prod + a[i]*b[i]; 7 | i = i+1; 8 | } while (i <= 20); 9 | } 10 | -------------------------------------------------------------------------------- /tests/prog3.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: iffalse i < 10 goto L4 3 | L5: j = 0 4 | L6: iffalse j < 10 goto L7 5 | L8: t1 = i * 80 6 | t2 = j * 8 7 | t3 = t1 + t2 8 | a [ t3 ] = 0 9 | L9: j = j + 1 10 | goto L6 11 | L7: i = i + 1 12 | goto L3 13 | L4: i = 0 14 | L10: iffalse i < 10 goto L2 15 | L11: t4 = i * 80 16 | t5 = i * 8 17 | t6 = t4 + t5 18 | a [ t6 ] = 1 19 | L12: i = i + 1 20 | goto L10 21 | L2: 22 | -------------------------------------------------------------------------------- /tests/prog3.t: -------------------------------------------------------------------------------- 1 | { 2 | int i; int j; float[10][10] a; 3 | i = 0; 4 | while ( i < 10 ) { 5 | j = 0; 6 | while ( j < 10 ) { 7 | a[i][j] = 0; 8 | j = j+1; 9 | } 10 | i = i+1; 11 | } 12 | i = 0; 13 | while ( i < 10 ) { 14 | a[i][i] = 1; 15 | i = i+1; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/prog4.i: -------------------------------------------------------------------------------- 1 | L1:L3: if peek == BLANK goto L7 2 | iffalse peek == TAB goto L6 3 | L7:L5: goto L4 4 | L6: iffalse peek == NEWLINE goto L9 5 | L8: line = line + 1 6 | goto L4 7 | L9: goto L2 8 | L4: peek = readch 9 | goto L1 10 | L2: 11 | -------------------------------------------------------------------------------- /tests/prog4.t: -------------------------------------------------------------------------------- 1 | { 2 | int BLANK; int TAB; int NEWLINE; int peek; int line; int readch; 3 | 4 | while( true ) { 5 | if( peek == BLANK || peek == TAB ) ; 6 | else if( peek == NEWLINE ) line = line + 1; 7 | else break; 8 | peek = readch; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tmp/block1.i: -------------------------------------------------------------------------------- 1 | L1: a = 0 2 | L3: b = 0 3 | L4: b = 1 4 | L6: a = 2 5 | L7: b = 3 6 | L8: a = a + 1 7 | L9: b = b + 1 8 | L5: a = a + 1 9 | L10: b = b + 1 10 | L2: 11 | -------------------------------------------------------------------------------- /tmp/expr1.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: i = 365 3 | L4: x = 0.0 4 | L5: x = 3.1415896 5 | L6: b = true 6 | L7: b = false 7 | L8: i = x 8 | L9: x = i 9 | L2: 10 | -------------------------------------------------------------------------------- /tmp/expr2.i: -------------------------------------------------------------------------------- 1 | L1: a = b + c 2 | L3: a = b - c 3 | L4: a = b * c 4 | L5: a = b / c 5 | L6: a = minus b 6 | L7: t1 = a - b 7 | d = t1 - c 8 | L8: t2 = a * b 9 | d = t2 * c 10 | L9: t3 = b * c 11 | d = a + t3 12 | L10: t4 = a * b 13 | d = t4 + c 14 | L11: t5 = a - b 15 | d = t5 - c 16 | L12: t6 = b - c 17 | d = a - t6 18 | L13: t7 = a + b 19 | d = t7 * c 20 | L14: t8 = b + c 21 | d = a * t8 22 | L15: t9 = b * b 23 | t10 = 4.0 * a 24 | t11 = t10 * c 25 | term = t9 - t11 26 | L2: 27 | -------------------------------------------------------------------------------- /tmp/expr3.i: -------------------------------------------------------------------------------- 1 | L1: if x < y goto L4 2 | t1 = true 3 | goto L5 4 | L4: t1 = false 5 | L5: r = t1 6 | L3: iffalse x == y goto L7 7 | t2 = true 8 | goto L8 9 | L7: t2 = false 10 | L8: r = t2 11 | L6: if x > y goto L11 12 | L10: r = true 13 | goto L9 14 | L11: r = false 15 | L9: iffalse x != y goto L13 16 | L12: r = true 17 | goto L2 18 | L13: r = false 19 | L2: 20 | -------------------------------------------------------------------------------- /tmp/expr4.i: -------------------------------------------------------------------------------- 1 | L1: t1 = i * 12 2 | t2 = j * 4 3 | t3 = t1 + t2 4 | t4 = a [ t3 ] 5 | x = c + t4 6 | L3: t5 = i * 12 7 | t6 = j * 4 8 | t7 = t5 + t6 9 | a [ t7 ] = 0 10 | L4: t8 = i * 100 11 | t9 = j * 10 12 | t10 = t8 + t9 13 | t11 = k * 1 14 | t12 = t10 + t11 15 | b [ t12 ] = true 16 | L5: t13 = i * 100 17 | t14 = j * 10 18 | t15 = t13 + t14 19 | t16 = k * 1 20 | t17 = t15 + t16 21 | d = b [ t17 ] 22 | L2: 23 | -------------------------------------------------------------------------------- /tmp/identity.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: iffalse i < 10 goto L4 3 | L5: j = 0 4 | L6: iffalse j < 10 goto L7 5 | L8: t1 = i * 80 6 | t2 = j * 8 7 | t3 = t1 + t2 8 | a [ t3 ] = 0.0 9 | L9: j = j + 1 10 | goto L6 11 | L7: i = i + 1 12 | goto L3 13 | L4: i = 0 14 | L10: iffalse i < 10 goto L2 15 | L11: t4 = i * 80 16 | t5 = i * 8 17 | t6 = t4 + t5 18 | a [ t6 ] = 1.0 19 | L12: i = i + 1 20 | goto L10 21 | L2: 22 | -------------------------------------------------------------------------------- /tmp/identity2.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3:L5: j = 0 3 | L6:L8: t1 = i * 80 4 | t2 = j * 8 5 | t3 = t1 + t2 6 | a [ t3 ] = 0.0 7 | L9: iffalse j >= 10 goto L6 8 | L10: goto L7 9 | goto L6 10 | L7: iffalse i >= 10 goto L3 11 | L11: goto L4 12 | goto L3 13 | L4: i = 0 14 | L12:L13: t4 = i * 80 15 | t5 = i * 8 16 | t6 = t4 + t5 17 | a [ t6 ] = 1.0 18 | L14: iffalse i >= 10 goto L12 19 | L15: goto L2 20 | goto L12 21 | L2: 22 | -------------------------------------------------------------------------------- /tmp/jump1.i: -------------------------------------------------------------------------------- 1 | L1:L4: a = 0 2 | L3: goto L5 3 | L6: x = 0 4 | L5: iffalse a < b goto L7 5 | L8: a = b 6 | L7: iffalse x <= y goto L9 7 | L10: x = y 8 | L9: iffalse a == b goto L11 9 | L12: a = b 10 | L11: iffalse x != y goto L13 11 | L14: x = y 12 | L13: iffalse a >= b goto L15 13 | L16: b = a 14 | L15: iffalse x > y goto L17 15 | L18: y = x 16 | L17: iffalse a == b goto L19 17 | L20:L19: if x < 100 goto L23 18 | iffalse x > 200 goto L21 19 | L23:L22: x = 0 20 | L21: iffalse a < 100 goto L24 21 | iffalse a > 200 goto L24 22 | L25: b = 0 23 | L24: if x < 100 goto L28 24 | iffalse x > 200 goto L26 25 | iffalse x != y goto L26 26 | L28:L27: x = 0 27 | L26: if a < 100 goto L31 28 | iffalse a > 200 goto L32 29 | if a != 150 goto L31 30 | L32: iffalse a != 0 goto L29 31 | L31:L30: a = 0 32 | L29: iffalse x > 200 goto L36 33 | if x != b goto L35 34 | L36: iffalse x < 100 goto L33 35 | L35:L34: x = 0 36 | L33: if a < 100 goto L38 37 | iffalse a > 200 goto L2 38 | iffalse a != b goto L2 39 | L38:L37: a = 0 40 | L2: 41 | -------------------------------------------------------------------------------- /tmp/jump2.i: -------------------------------------------------------------------------------- 1 | L1: r = true 2 | L3: r = false 3 | L4: iffalse a < b goto L6 4 | t1 = true 5 | goto L7 6 | L6: t1 = false 7 | L7: r = t1 8 | L5: iffalse x <= y goto L9 9 | t2 = true 10 | goto L10 11 | L9: t2 = false 12 | L10: r = t2 13 | L8: iffalse a == b goto L12 14 | t3 = true 15 | goto L13 16 | L12: t3 = false 17 | L13: r = t3 18 | L11: iffalse x != y goto L15 19 | t4 = true 20 | goto L16 21 | L15: t4 = false 22 | L16: r = t4 23 | L14: iffalse a >= b goto L18 24 | t5 = true 25 | goto L19 26 | L18: t5 = false 27 | L19: r = t5 28 | L17: iffalse x > y goto L21 29 | t6 = true 30 | goto L22 31 | L21: t6 = false 32 | L22: r = t6 33 | L20: if x < 100 goto L26 34 | iffalse x > 200 goto L24 35 | L26: t7 = true 36 | goto L25 37 | L24: t7 = false 38 | L25: r = t7 39 | L23: iffalse a < 100 goto L28 40 | iffalse a > 200 goto L28 41 | t8 = true 42 | goto L29 43 | L28: t8 = false 44 | L29: r = t8 45 | L27: if x < 100 goto L33 46 | iffalse x > 200 goto L31 47 | iffalse x != y goto L31 48 | L33: t9 = true 49 | goto L32 50 | L31: t9 = false 51 | L32: r = t9 52 | L30: if a < 100 goto L37 53 | iffalse a > 200 goto L38 54 | if a != 150 goto L37 55 | L38: iffalse a != 0 goto L35 56 | L37: t10 = true 57 | goto L36 58 | L35: t10 = false 59 | L36: r = t10 60 | L34: iffalse x > 200 goto L43 61 | if x != b goto L42 62 | L43: iffalse x < 100 goto L40 63 | L42: t11 = true 64 | goto L41 65 | L40: t11 = false 66 | L41: r = t11 67 | L39: if a < 100 goto L46 68 | iffalse a > 200 goto L44 69 | iffalse a != b goto L44 70 | L46: t12 = true 71 | goto L45 72 | L44: t12 = false 73 | L45: r = t12 74 | L2: 75 | -------------------------------------------------------------------------------- /tmp/jump3.i: -------------------------------------------------------------------------------- 1 | L1: r = b 2 | L3: t1 = i * 1 3 | r = a [ t1 ] 4 | L4: t2 = i * 1 5 | a [ t2 ] = b 6 | L5: t3 = i * 1 7 | a [ t3 ] = true 8 | L6: t4 = i * 1 9 | a [ t4 ] = false 10 | L7: iffalse b goto L8 11 | L9: x = y 12 | L8: t5 = i * 1 13 | t6 = a [ t5 ] 14 | iffalse t6 goto L2 15 | L10: x = y 16 | L2: 17 | -------------------------------------------------------------------------------- /tmp/prog0.i: -------------------------------------------------------------------------------- 1 | L1:L3: i = i + 1 2 | L5: t1 = i * 8 3 | t2 = a [ t1 ] 4 | if t2 < v goto L3 5 | L4: j = j - 1 6 | L7: t3 = j * 8 7 | t4 = a [ t3 ] 8 | if t4 > v goto L4 9 | L6: iffalse i >= j goto L8 10 | L9: goto L2 11 | L8: t5 = i * 8 12 | x = a [ t5 ] 13 | L10: t6 = i * 8 14 | t7 = j * 8 15 | t8 = a [ t7 ] 16 | a [ t6 ] = t8 17 | L11: t9 = j * 8 18 | a [ t9 ] = x 19 | goto L1 20 | L2: 21 | -------------------------------------------------------------------------------- /tmp/prog1.i: -------------------------------------------------------------------------------- 1 | L1: r = a 2 | L3: dd = d 3 | L4: iffalse dd <= r goto L5 4 | L6: dd = 2 * dd 5 | goto L4 6 | L5: iffalse dd != r goto L2 7 | L7: dd = dd / 2 8 | L8: iffalse dd <= r goto L5 9 | L9: r = r - dd 10 | goto L5 11 | L2: 12 | -------------------------------------------------------------------------------- /tmp/prog2.i: -------------------------------------------------------------------------------- 1 | L1: prod = 0 2 | L3: i = 1 3 | L4: t1 = i * 8 4 | t2 = a [ t1 ] 5 | t3 = i * 8 6 | t4 = b [ t3 ] 7 | t5 = t2 * t4 8 | prod = prod + t5 9 | L6: i = i + 1 10 | L5: if i <= 20 goto L4 11 | L2: 12 | -------------------------------------------------------------------------------- /tmp/prog3.i: -------------------------------------------------------------------------------- 1 | L1: i = 0 2 | L3: iffalse i < 10 goto L4 3 | L5: j = 0 4 | L6: iffalse j < 10 goto L7 5 | L8: t1 = i * 80 6 | t2 = j * 8 7 | t3 = t1 + t2 8 | a [ t3 ] = 0 9 | L9: j = j + 1 10 | goto L6 11 | L7: i = i + 1 12 | goto L3 13 | L4: i = 0 14 | L10: iffalse i < 10 goto L2 15 | L11: t4 = i * 80 16 | t5 = i * 8 17 | t6 = t4 + t5 18 | a [ t6 ] = 1 19 | L12: i = i + 1 20 | goto L10 21 | L2: 22 | -------------------------------------------------------------------------------- /tmp/prog4.i: -------------------------------------------------------------------------------- 1 | L1:L3: if peek == BLANK goto L7 2 | iffalse peek == TAB goto L6 3 | L7:L5: goto L4 4 | L6: iffalse peek == NEWLINE goto L9 5 | L8: line = line + 1 6 | goto L4 7 | L9: goto L2 8 | L4: peek = readch 9 | goto L1 10 | L2: 11 | --------------------------------------------------------------------------------