AST File
Grammar File
Printer File
Evaluator
Other Files in the project
Interpreter
Value
Reader
4. (10 pt) (Arithlang interpreter basics) Extend ArithLang to support a new expression greatest-of (>? a b) for positive numbers, e.g., $ >? 3) 3 $ >? 3 4 2) 4 $ (>? 83) 8 $ >? 8-1) error $ (>?-1) error You will need to modify the following files: (2 pt) Grammar file (ArithLang.g) (2 pt) AST file (AST.java) . (1 pt) Printer file (Printer.java) (5 pt) Evaluator (Evaluator.java) + * 1 package arithlang; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * This class hierarchy represents expressions in the abstract syntax tree 8 * manipulated by this interpreter. 9 10 * @author hridesh 11 12 13 @SuppressWarnings ("rawtypes") 14 public interface AST { 15 public static abstract class ASTNode { 16 public abstract Object accept (Visitor visitor); 17 } 18 public static class Program extends ASTNode 19 Exp_e; 20 21 public Program (Expe) { 22 Le = e; 23 } 24 25 public Exp e() { 26 return _e; 27 } 28 29 public Object accept (Visitor visitor) { 30 return visitor.visit(this); 31 } 32 } 33 public static abstract class Exp extends ASTNode { 34 35 } 36 37 public static class NumExp extends Exp { 38 39 double val; 39 40 public NumExp (double v) { 41 _val = v; 42 } 43 44 public double v() { 45 return val; 46 } 47 48 public Object accept (Visitor visitor) { 49 return visitor.visit(this); 50 } 51 } 52 53 public static abstract class CompoundArithExp extends Exp { 54 List
_rep; 55 public CompoundArithExp (List args) { 56 _rep = new ArrayList(); 57 _rep.addAll(args); 58 } 59 public List all() { 60 return _rep; 61 } 62 } 63 64 public static class AddExp extends CompoundArithExp { 65 public AddExp (List args) { 66 super (args); 67 } 68 public Object accept (Visitor visitor) { 69 return visitor.visit(this); 70 } 71 } 74 75 76 77 78 79 80 public static class SubExp extends CompoundArithExp { public SubExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } 81 82 83 84 T - public static class DivExp extends CompoundArithExp { public DivExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } HD - 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 public static class MultExp extends CompoundArithExp{ public MultExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } public interface Visitor { // This interface should contain a signature for each concrete Ast node. public T visit (AST.NumExp e); public T visit (AST.AddExp e); public T visit (AST. SubExpe); public T visit (AST.MultExp e); public T visit (AST. DivExp e); public T visit (AST. Program p); 107 108 109 110 grammar ArithLang; 1/ Grammar of this Programming Language // - grammar rules start with lowercase program returns (Program ast] : e=exp{ $ast = new Program (Se.ast); } ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 exp returns [Exp ast]: n=numexp{ $ast = $n.ast; } | a=addexp { $ast Sa.ast; } | s=subexp { $ast = $s.ast; } | m=multexp { $ast = $m.ast; } | d=divexp { $ast $d.ast;) ; numexp returns [NumExp ast]: n0=Number { $ast = new NumExp (Integer.parseInt($no.text)); } | '-' n0=Number { $ast = new NumExp(-Integer.parseInt($no.text)); } | n0=Number Dot nl=Number { $ast = new NumExp (Double.parseDouble ($no.text+","+$nl.text)); } | '-' n0=Number Dot nl=Number { $ast = new NumExp (Double.parseDouble("-" + $no.text+"."+$nl.text)); } 23 24 25 26 27 28 addexp returns [AddExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : '(''+' e=exp { $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + '' { $ast = new AddExp ($list); } 29 ; subexp returns (SubExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : "('' e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + ' { $ast = new SubExp ($list); } 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 multexp returns (MultExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + ' { $ast = new MultExp (slist); } divexp returns [DivExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + '' { $ast = new DivExp (list); } ; 60 // Lexical Specification of this programming Language lexical specification rules start with uppercase Define : 'define'; Let : 'let'; Dot :'.'; Number : DIGIT+; Identifier : Letter LetterorDigit*; 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 Letter: [a-zA-Z$_] -[\u0000-\u00FF\UD800-\uDBFF] Character.is JavaIdentifierStart_input.LA(-1)) }? [\uD800-\uDBFF] [\UDC00-\UDFFF] {Character.isJavaIdentifierStart (Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))))? ; LetterOrDigit: [a-zA-Z0-9$_] 1 -[\u0000-\u00FF\UD800-\uDBFF) {Character.is JavaIdentifierPart_input.LA(-1)) }? [\UD800-\uDBFF] [\UDC00-\UDFFF] {Character.isJavaIdentifierPart (Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))))?: fragment DIGIT: ('0'..'9'); AT : '@'; ELLIPSIS : WS : [ \t \u000C] + -> skip; Comment : '/' .*? '*/' -> skip; Line_Comment: '//' -[ ]* -> skip; 7 - 1 n 1 package arithlang; 2 3 import static arithlang. AST.*; 4 5 public class Printer { 6 public void print (Value v) { System.out.println(v.toString()); } 10 public static class Formatter implements AST.Visitor { 11 12 public String visit (Program p) { 13 return (String) p.e().accept(this); 14 } 15 16 public String visit (NumExp e) { 17 return "" + e.v(); 18 } 19 20 public String visit (AddExp e) { 21 String result = "(+"; 22 for (AST.Exp exp: e.all()) 23 result += "" + exp.accept(this); 24 return result + ")"; 25 } 26 27 public String visit (SubExp e) { 28 String result = "(-"; 29 for (AST.Exp exp: e.all()) 30 result += " + exp.accept(this); 31 return result + ")"; 32 } 33 34 public String visit (MultExp e) { 35 String result = "(*"; 36 for (AST.Exp exp : e.all()) 37 result += "" + exp.accept(this); 38 return result + "); 39 } 40 41 public String visit (DivExp e) { 42 String result = "/"; 43 for (AST. Exp exp : e.all()) 44 result += " + exp.accept(this); 45 return result + ")"; 46 47 48 49 HITE package arithlang; import static arithlang.AST.*; import static arithlang.Value.*; import java.util.List; public class Evaluator implements Visitor { private Numval record = new Numval(); Printer. Formatter ts = new Printer. Formatter(); Value valueof (Program p) { // Value of a program in this language is the value of the expression return (value) p.accept(this); } 13 14 15 17 18 19 20 @Override public Value visit (AddExp e) { List operands = e.all(); double result = 0; for (Exp exp: operands) { Numval intermediate = (Numval) exp.accept(this); // Dynamic type-checking result += intermediate.v(); //Semantics of AddExp in terms of the target language. } return new NumVal (result); } 22 @Override public Value visit (NumExp e) { return new Numval (e.v()); } 37 38 39 40 41 42 43 @Override public Value visit (DivExp e) { List operands = e.all(); Numval ival = (Numval) operands.get().accept(this); double result = lval.v(); for (int i=1; i operands = e.all(); double result = 1; for (Exp exp: operands) { Numval intermediate = (NumVal) exp.accept(this); // Dynamic type-checking result *= intermediate.v(); //Semantics of MultExp. } return new Numval (result); } @Override public Value visit (Program p) { return (Value) p.e().accept(this); } 63 64 65 66 67 68 69 70 71 72 73 74 @Override public Value visit (SubExp e) { List operands = e.all(); NumVal lVal = (NumVal) operands.get().accept(this); double result = lval.v(); for (int i=1; i? a b) for positive numbers, e.g., $ >? 3) 3 $ >? 3 4 2) 4 $ (>? 83) 8 $ >? 8-1) error $ (>?-1) error You will need to modify the following files: (2 pt) Grammar file (ArithLang.g) (2 pt) AST file (AST.java) . (1 pt) Printer file (Printer.java) (5 pt) Evaluator (Evaluator.java) + * 1 package arithlang; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * This class hierarchy represents expressions in the abstract syntax tree 8 * manipulated by this interpreter. 9 10 * @author hridesh 11 12 13 @SuppressWarnings ("rawtypes") 14 public interface AST { 15 public static abstract class ASTNode { 16 public abstract Object accept (Visitor visitor); 17 } 18 public static class Program extends ASTNode 19 Exp_e; 20 21 public Program (Expe) { 22 Le = e; 23 } 24 25 public Exp e() { 26 return _e; 27 } 28 29 public Object accept (Visitor visitor) { 30 return visitor.visit(this); 31 } 32 } 33 public static abstract class Exp extends ASTNode { 34 35 } 36 37 public static class NumExp extends Exp { 38 39 double val; 39 40 public NumExp (double v) { 41 _val = v; 42 } 43 44 public double v() { 45 return val; 46 } 47 48 public Object accept (Visitor visitor) { 49 return visitor.visit(this); 50 } 51 } 52 53 public static abstract class CompoundArithExp extends Exp { 54 List _rep; 55 public CompoundArithExp (List args) { 56 _rep = new ArrayList(); 57 _rep.addAll(args); 58 } 59 public List all() { 60 return _rep; 61 } 62 } 63 64 public static class AddExp extends CompoundArithExp { 65 public AddExp (List args) { 66 super (args); 67 } 68 public Object accept (Visitor visitor) { 69 return visitor.visit(this); 70 } 71 } 74 75 76 77 78 79 80 public static class SubExp extends CompoundArithExp { public SubExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } 81 82 83 84 T - public static class DivExp extends CompoundArithExp { public DivExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } HD - 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 public static class MultExp extends CompoundArithExp{ public MultExp (List args) { super (args); } public Object accept (Visitor visitor) { return visitor.visit(this); } } public interface Visitor { // This interface should contain a signature for each concrete Ast node. public T visit (AST.NumExp e); public T visit (AST.AddExp e); public T visit (AST. SubExpe); public T visit (AST.MultExp e); public T visit (AST. DivExp e); public T visit (AST. Program p); 107 108 109 110 grammar ArithLang; 1/ Grammar of this Programming Language // - grammar rules start with lowercase program returns (Program ast] : e=exp{ $ast = new Program (Se.ast); } ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 exp returns [Exp ast]: n=numexp{ $ast = $n.ast; } | a=addexp { $ast Sa.ast; } | s=subexp { $ast = $s.ast; } | m=multexp { $ast = $m.ast; } | d=divexp { $ast $d.ast;) ; numexp returns [NumExp ast]: n0=Number { $ast = new NumExp (Integer.parseInt($no.text)); } | '-' n0=Number { $ast = new NumExp(-Integer.parseInt($no.text)); } | n0=Number Dot nl=Number { $ast = new NumExp (Double.parseDouble ($no.text+","+$nl.text)); } | '-' n0=Number Dot nl=Number { $ast = new NumExp (Double.parseDouble("-" + $no.text+"."+$nl.text)); } 23 24 25 26 27 28 addexp returns [AddExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : '(''+' e=exp { $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + '' { $ast = new AddExp ($list); } 29 ; subexp returns (SubExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : "('' e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + ' { $ast = new SubExp ($list); } 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 multexp returns (MultExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } : e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + ' { $ast = new MultExp (slist); } divexp returns [DivExp ast] locals [ArrayList list] @init { $list = new ArrayList(); } e=exp{ $list.add($e.ast); } (e=exp { $list.add($e.ast); } ) + '' { $ast = new DivExp (list); } ; 60 // Lexical Specification of this programming Language lexical specification rules start with uppercase Define : 'define'; Let : 'let'; Dot :'.'; Number : DIGIT+; Identifier : Letter LetterorDigit*; 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 Letter: [a-zA-Z$_] -[\u0000-\u00FF\UD800-\uDBFF] Character.is JavaIdentifierStart_input.LA(-1)) }? [\uD800-\uDBFF] [\UDC00-\UDFFF] {Character.isJavaIdentifierStart (Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))))? ; LetterOrDigit: [a-zA-Z0-9$_] 1 -[\u0000-\u00FF\UD800-\uDBFF) {Character.is JavaIdentifierPart_input.LA(-1)) }? [\UD800-\uDBFF] [\UDC00-\UDFFF] {Character.isJavaIdentifierPart (Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))))?: fragment DIGIT: ('0'..'9'); AT : '@'; ELLIPSIS : WS : [ \t \u000C] + -> skip; Comment : '/' .*? '*/' -> skip; Line_Comment: '//' -[ ]* -> skip; 7 - 1 n 1 package arithlang; 2 3 import static arithlang. AST.*; 4 5 public class Printer { 6 public void print (Value v) { System.out.println(v.toString()); } 10 public static class Formatter implements AST.Visitor { 11 12 public String visit (Program p) { 13 return (String) p.e().accept(this); 14 } 15 16 public String visit (NumExp e) { 17 return "" + e.v(); 18 } 19 20 public String visit (AddExp e) { 21 String result = "(+"; 22 for (AST.Exp exp: e.all()) 23 result += "" + exp.accept(this); 24 return result + ")"; 25 } 26 27 public String visit (SubExp e) { 28 String result = "(-"; 29 for (AST.Exp exp: e.all()) 30 result += " + exp.accept(this); 31 return result + ")"; 32 } 33 34 public String visit (MultExp e) { 35 String result = "(*"; 36 for (AST.Exp exp : e.all()) 37 result += "" + exp.accept(this); 38 return result + "); 39 } 40 41 public String visit (DivExp e) { 42 String result = "/"; 43 for (AST. Exp exp : e.all()) 44 result += " + exp.accept(this); 45 return result + ")"; 46 47 48 49 HITE package arithlang; import static arithlang.AST.*; import static arithlang.Value.*; import java.util.List; public class Evaluator implements Visitor { private Numval record = new Numval(); Printer. Formatter ts = new Printer. Formatter(); Value valueof (Program p) { // Value of a program in this language is the value of the expression return (value) p.accept(this); } 13 14 15 17 18 19 20 @Override public Value visit (AddExp e) { List operands = e.all(); double result = 0; for (Exp exp: operands) { Numval intermediate = (Numval) exp.accept(this); // Dynamic type-checking result += intermediate.v(); //Semantics of AddExp in terms of the target language. } return new NumVal (result); } 22 @Override public Value visit (NumExp e) { return new Numval (e.v()); } 37 38 39 40 41 42 43 @Override public Value visit (DivExp e) { List operands = e.all(); Numval ival = (Numval) operands.get().accept(this); double result = lval.v(); for (int i=1; i operands = e.all(); double result = 1; for (Exp exp: operands) { Numval intermediate = (NumVal) exp.accept(this); // Dynamic type-checking result *= intermediate.v(); //Semantics of MultExp. } return new Numval (result); } @Override public Value visit (Program p) { return (Value) p.e().accept(this); } 63 64 65 66 67 68 69 70 71 72 73 74 @Override public Value visit (SubExp e) { List operands = e.all(); NumVal lVal = (NumVal) operands.get().accept(this); double result = lval.v(); for (int i=1; i