diff --git a/.classpath b/.classpath index 646ce8c..98e4377 100644 --- a/.classpath +++ b/.classpath @@ -2,10 +2,9 @@ - - - + + diff --git a/.project b/.project index 1f75518..18eecfe 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - Javali-HW1 + Javali-HW2 diff --git a/.settings/com.github.jknack.antlr4ide.Antlr4.prefs b/.settings/com.github.jknack.antlr4ide.Antlr4.prefs new file mode 100644 index 0000000..67ef6b9 --- /dev/null +++ b/.settings/com.github.jknack.antlr4ide.Antlr4.prefs @@ -0,0 +1,13 @@ +antlr4.antlrRegisteredTools=4.4@/tmp/antlr-4.4-complete.jar\:4.7.1@/home/carlos/eth/cd/nop90/HW2/lib/antlr-4.7.1-complete.jar +antlr4.antlrToolPath=/home/carlos/eth/cd/nop90/HW2/lib/antlr-4.7.1-complete.jar +antlr4.encoding=UTF-8 +antlr4.listener=true +antlr4.visitor=false +antlr4.vmArgs= +antlr4ide.is_project_specific=true +autobuilding=true +eclipse.preferences.version=1 +is_project_specific= +outlet.DEFAULT_OUTPUT.cleanupDerived=true +outlet.DEFAULT_OUTPUT.derived=true +outlet.DEFAULT_OUTPUT.directory=./target/generated-sources/antlr4 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index a698e59..0c68a61 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.8 diff --git a/Grade.txt b/Grade.txt index ede9e61..9d05b6d 100644 --- a/Grade.txt +++ b/Grade.txt @@ -1,5 +1,5 @@ -Grade: 24/25 +Grade: 29/30 -31/31 tests passed [20/20] +251/251 tests passed [25/25] -Submitted test cases [4/5] \ No newline at end of file +Submitted test cases: [4/5] \ No newline at end of file diff --git a/build.xml b/build.xml index c0b6cee..ea0e895 100644 --- a/build.xml +++ b/build.xml @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + - - - + + @@ -40,7 +66,6 @@ - @@ -83,5 +108,4 @@ - diff --git a/javali_tests/HW1/Multiplication.javali b/javali_tests/HW1/Multiplication.javali new file mode 100644 index 0000000..0bba7fc --- /dev/null +++ b/javali_tests/HW1/Multiplication.javali @@ -0,0 +1,18 @@ +class Main { + void main() { + int r1; + int i0, i1; + + i0 = 5; + i1 = 2; + + r1 = i1 * 3; + write(r1); writeln(); + + r1 = i0 * i1; + write(r1); writeln(); + + r1 = r1 * i0 * i1 * 3; + write(r1); writeln(); + } +} diff --git a/javali_tests/HW1/ReadWrite.javali b/javali_tests/HW1/ReadWrite.javali new file mode 100644 index 0000000..5d3dda4 --- /dev/null +++ b/javali_tests/HW1/ReadWrite.javali @@ -0,0 +1,15 @@ +/* Test read/write native functions */ +class Main { + void main() { + int r1, r2; + int i0, i1, i2; + + i0 = 5; + i1 = read(); + + r1 = i0 + i1; + write(r1); writeln(); + + write(r1 - 3); writeln(); + } +} diff --git a/javali_tests/HW1/ReadWrite.javali.in b/javali_tests/HW1/ReadWrite.javali.in new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/javali_tests/HW1/ReadWrite.javali.in @@ -0,0 +1 @@ +22 diff --git a/javali_tests/HW1_nop90/EightVariablesWrite.javali b/javali_tests/HW1_nop90/EightVariablesWrite.javali old mode 100644 new mode 100755 diff --git a/javali_tests/HW1_nop90/Overflow.javali b/javali_tests/HW1_nop90/Overflow.javali index 5216592..97725ac 100755 --- a/javali_tests/HW1_nop90/Overflow.javali +++ b/javali_tests/HW1_nop90/Overflow.javali @@ -14,7 +14,7 @@ class Main { write(x); writeln(); /* performe some operation that should generate an int overflow */ - x = 2147483640; + x = 21474836400; y = 60000; write( x + y); writeln(); z = 20000000; diff --git a/javali_tests/HW2/ErrWhileMissingBrace.javali b/javali_tests/HW2/ErrWhileMissingBrace.javali new file mode 100644 index 0000000..53405a9 --- /dev/null +++ b/javali_tests/HW2/ErrWhileMissingBrace.javali @@ -0,0 +1,10 @@ +class Main { + void main() { + int i; + + // Note: In Javali, while() loops must have braces ({}) after them, + // so this is an expected syntax error. + while(true) + i = 1; + } +} diff --git a/javali_tests/HW2/OkInheritance.javali b/javali_tests/HW2/OkInheritance.javali new file mode 100644 index 0000000..b7fc8c3 --- /dev/null +++ b/javali_tests/HW2/OkInheritance.javali @@ -0,0 +1,12 @@ +class Base { +} + +class Extends extends Base { +} + +class Main { + void main() { + write(0); + writeln(); + } +} diff --git a/javali_tests/HW2/OkSimpleObject.javali b/javali_tests/HW2/OkSimpleObject.javali new file mode 100644 index 0000000..873174e --- /dev/null +++ b/javali_tests/HW2/OkSimpleObject.javali @@ -0,0 +1,22 @@ +class Main { + + int field; + + void method() { + write(this.field); + writeln(); + } + + void method(int withArg) { + write(withArg); + writeln(); + } + + void main() { + this.field = 3; + method(field); + method(3); + method(this.field); + method(); + } +} diff --git a/javali_tests/HW2/OkSimpleReturn.javali b/javali_tests/HW2/OkSimpleReturn.javali new file mode 100644 index 0000000..fa1a0cb --- /dev/null +++ b/javali_tests/HW2/OkSimpleReturn.javali @@ -0,0 +1,22 @@ +class Main { + + int m() { + return 0; + } + + void main() { + + int res; + res = -1; + + res = m(); + write(res); + writeln(); + + res = this.m(); + write(res); + writeln(); + + } + +} diff --git a/javali_tests/HW2/OkSimpleReturnWithExpression.javali b/javali_tests/HW2/OkSimpleReturnWithExpression.javali new file mode 100644 index 0000000..6f24a91 --- /dev/null +++ b/javali_tests/HW2/OkSimpleReturnWithExpression.javali @@ -0,0 +1,27 @@ +class Main { + + int m(int a, int b) { + return a + b + 1; + } + + void main() { + + int res; + res = -1; + + res = m(1, 2); + write(res); + writeln(); + + res = this.m(1, 2); + write(res); + writeln(); + + write(m(1, 2)); + writeln(); + + write(this.m(1, 2)); + writeln(); + + } +} diff --git a/javali_tests/HW2_nop90/Arrays.javali b/javali_tests/HW2_nop90/Arrays.javali new file mode 100644 index 0000000..2638373 --- /dev/null +++ b/javali_tests/HW2_nop90/Arrays.javali @@ -0,0 +1,24 @@ +/* testing arrays with primitive types as well as new objects +the if/else statements shows that the array is boolean array is initialized with false + */ +class Main { + void main() { + int [] testArray; + boolean [] boolarray; + + boolarray = new boolean [3]; + testArray = new int [10]; + + testArray[5] = 3; + boolarray[1] = true; + + if (boolarray[0]){ + write(1);} + else{ + write(5);} + writeln(); + if (boolarray[1]){ + write(1);} + + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/Assignments.javali b/javali_tests/HW2_nop90/Assignments.javali new file mode 100644 index 0000000..d239f5f --- /dev/null +++ b/javali_tests/HW2_nop90/Assignments.javali @@ -0,0 +1,12 @@ +/* testing assign statements*/ +class Main { + void main() { + a = read(); + b = methodCall(); + c = methodCall(param1, param2); + d = object.access; + e = new Ast(); + d = new int[size]; + f = new Object[size]; + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/Casts.javali b/javali_tests/HW2_nop90/Casts.javali new file mode 100755 index 0000000..a33c216 --- /dev/null +++ b/javali_tests/HW2_nop90/Casts.javali @@ -0,0 +1,16 @@ +/* testing casting as well as creating new Objects*/ +class Main +{ + void main() + { + int a; + int b; + Object c; + Object d; + + c = null; + d = new Object(); + a = 10; + c = (Object) d; + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/Division.javali b/javali_tests/HW2_nop90/Division.javali new file mode 100755 index 0000000..13358d3 --- /dev/null +++ b/javali_tests/HW2_nop90/Division.javali @@ -0,0 +1,21 @@ +class Main { + void main() { + int a, b, c, d, e; + + a = 10; + b = -1; + c = 0; + d = 100; + e = 2; + + write(a / b); writeln(); + write(d / e); writeln(); + write(c / d); writeln(); + write(b / a + c); writeln(); + write(d / e * a / b * c); writeln(); + write(d / e * a / b); writeln(); + write(d / e + a / b); writeln(); + write(d / e * a * b * c); writeln(); + write(d / e * a - b + c); writeln(); + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/DoubleInheritance.javali b/javali_tests/HW2_nop90/DoubleInheritance.javali new file mode 100644 index 0000000..14cf167 --- /dev/null +++ b/javali_tests/HW2_nop90/DoubleInheritance.javali @@ -0,0 +1,6 @@ +/* testing basic inheritance*/ +class C1 {} +class C2 extends C1 {} +class C3 extends C2 {} +class C4 extends C2 {} +class C5 extends C3 {} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/EightVariablesWrite.javali b/javali_tests/HW2_nop90/EightVariablesWrite.javali new file mode 100755 index 0000000..e9391ca --- /dev/null +++ b/javali_tests/HW2_nop90/EightVariablesWrite.javali @@ -0,0 +1,20 @@ +/* Test expression evaluation with 8 variables */ +class Main { + void main() { + int r1, r2, r3; + int i0, i1, i2, i3, i4, i5, i6, i7; + + i0 = 0; + i1 = 1; + i2 = 2; + i3 = 3; + i4 = 4; + i5 = 5; + i6 = 6; + i7 = 7; + + write(i0 + (i1 + ( i2 + ( i3 + ( i4 + (i5 + (i6 + i7))))))); writeln(); + write(((((((i0 + i1) + i2) + i3) + i4) + i5) + i6) + i7); writeln(); + write(((i0 + i1) + (i2 + i3)) + ((i4 + i5) + (i6 + i7))); writeln(); + } +} diff --git a/javali_tests/HW2_nop90/Expressions.javali b/javali_tests/HW2_nop90/Expressions.javali new file mode 100644 index 0000000..54830ce --- /dev/null +++ b/javali_tests/HW2_nop90/Expressions.javali @@ -0,0 +1,22 @@ +/* testing different expressions +compiler should recognize Type error: Return statement of method with void return type should not have arguments + */ +class Main { + void main() { + return; + return true; + return false; + return 0x10; + return 10; + return variable; + return array[index]; + return methodAccess(); + return object.field; + return object.call(); + return op + op2; + return op / asd * asd && a == true; + return this.run(); + return this; + return this.field; + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/Multiplication.javali b/javali_tests/HW2_nop90/Multiplication.javali new file mode 100755 index 0000000..0c092a6 --- /dev/null +++ b/javali_tests/HW2_nop90/Multiplication.javali @@ -0,0 +1,31 @@ +class Main { + void main() { + int r1; + int i0, i1; + int x,y,z; + + i0 = 5; + i1 = 2; + + r1 = i1 * 3; + write(r1); writeln(); + + r1 = i0 * i1; + write(r1); writeln(); + + r1 = r1 * i0 * i1 * 3; + write(r1); writeln(); + + y = 5; + z = 10; + x = (-y * z); + write(x); writeln(); + + y = 0; + z = - 10; + x = (y * z); + write(x); writeln(); + write(y * z); writeln(); + write(0 * -10); writeln(); + } +} diff --git a/javali_tests/HW2_nop90/NULLTest.javali b/javali_tests/HW2_nop90/NULLTest.javali new file mode 100755 index 0000000..206f3cb --- /dev/null +++ b/javali_tests/HW2_nop90/NULLTest.javali @@ -0,0 +1,20 @@ +/* testing null references: +assigning null to an int or a boolean results in an error +write(null) results in a parser failure + */ +class Main { + void main() { + int a; + boolean b; + Object c; + + a = null; + b = null; + c = null; + + write(a); + writeln(); + //write(null) + + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/OrderOfDeclarations.javali b/javali_tests/HW2_nop90/OrderOfDeclarations.javali new file mode 100644 index 0000000..ea555ab --- /dev/null +++ b/javali_tests/HW2_nop90/OrderOfDeclarations.javali @@ -0,0 +1,8 @@ +/*Check the order of the declarations in the generated parser +* Do the variables come always first or in their place? */ +class ClassName { + void a() {} + int a; + void a() {} + void tests(boolean d, nulle a) {} +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/Overflow.javali b/javali_tests/HW2_nop90/Overflow.javali new file mode 100755 index 0000000..97725ac --- /dev/null +++ b/javali_tests/HW2_nop90/Overflow.javali @@ -0,0 +1,25 @@ +/* Test what happens for Integers that are to big for 32bits +2147483647 (=0x7FFFFFFF) is the biggest integer in 32bits (IntMAX) +*/ +class Main { + void main() { + int x,y,z; + x = 2147483647; + write( x ); writeln(); + /* add 1 to IntMax and output it */ + write( x + 1); writeln(); + + /* read an int bigger than IntMAX */ + x = read(); + write(x); writeln(); + + /* performe some operation that should generate an int overflow */ + x = 21474836400; + y = 60000; + write( x + y); writeln(); + z = 20000000; + write( y * z); writeln(); + write( (y * z) ); writeln(); + + } +} diff --git a/javali_tests/HW2_nop90/Overflow.javali.in b/javali_tests/HW2_nop90/Overflow.javali.in new file mode 100755 index 0000000..a51fa7d --- /dev/null +++ b/javali_tests/HW2_nop90/Overflow.javali.in @@ -0,0 +1 @@ +2147483647 diff --git a/javali_tests/HW2_nop90/ParamLists.javali b/javali_tests/HW2_nop90/ParamLists.javali new file mode 100644 index 0000000..ac19360 --- /dev/null +++ b/javali_tests/HW2_nop90/ParamLists.javali @@ -0,0 +1,15 @@ +/*Testing all related to methods (declaration and execution)*/ +class Main { + void main() { + callWithParams(a, b, c, 0, false); + object.call(a, b, d); + } + + int method(int a, String b, int[] c) { + + } + + int[] method2() {} + Object method3() {} + Model[] method4() {} +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/ReadWrite.javali b/javali_tests/HW2_nop90/ReadWrite.javali new file mode 100755 index 0000000..e9f3944 --- /dev/null +++ b/javali_tests/HW2_nop90/ReadWrite.javali @@ -0,0 +1,26 @@ +/* Test read/write native functions */ +class Main { + void main() { + int r1, r2, readvar, a1; + + r1 = 6; + /* r2 = 22 */ + r2 = read(); + + write(r1); writeln(); // 6 + + /* test expressions inside write() */ + write(r1 - 3); writeln(); // 3 + write(r1 - 6); writeln(); // 0 + write(r1 - 7); writeln(); // -1 + /* should output 111 */ + readvar = read(); // 1 + write( (r1 + (r2 * 5)) + readvar); // 117 + write(- r1); // -6 + writeln(); + /* should output 15 */ + a1 = read(); // -15 + write(- a1); // 15 + + } +} diff --git a/javali_tests/HW2_nop90/ReadWrite.javali.in b/javali_tests/HW2_nop90/ReadWrite.javali.in new file mode 100755 index 0000000..fff4c89 --- /dev/null +++ b/javali_tests/HW2_nop90/ReadWrite.javali.in @@ -0,0 +1,6 @@ + 22 + + + 1 + +-15 diff --git a/javali_tests/HW2_nop90/Statements.javali b/javali_tests/HW2_nop90/Statements.javali new file mode 100644 index 0000000..f5f2279 --- /dev/null +++ b/javali_tests/HW2_nop90/Statements.javali @@ -0,0 +1,34 @@ +/* testing different statements +'condition' is not initialized + */ +class Main { + void main() { + if (condition) { + instructions(); + asd.b = c; + if (cond2) { + + } else { + nonEmptyBlock = a; + } + } else { + + } + // Whiles + while (condition) { + while (anotherLoop == false) { + nestedLoops(); + } + } + while (false) {} // emptyloop + // Returns + return; // empty + return expr; // with expressions (expressions already tested) + return array[index]; + // Writes + write(a); + write(9 + 10); + writeln(); + write(call()); + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/UnaryOperators.javali b/javali_tests/HW2_nop90/UnaryOperators.javali new file mode 100755 index 0000000..4a5485b --- /dev/null +++ b/javali_tests/HW2_nop90/UnaryOperators.javali @@ -0,0 +1,15 @@ +class Main { + void main() { + int a, b; + + a = 1; + b = 2; + + write(+a); writeln(); + write(-a); writeln(); + write(+a --b); writeln(); + write(-a--b); writeln(); + write(-----a-----5--b); writeln(); + write(-----a*---------b);writeln(); + } +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/conditionExpressions.javali b/javali_tests/HW2_nop90/conditionExpressions.javali new file mode 100755 index 0000000..5257a61 --- /dev/null +++ b/javali_tests/HW2_nop90/conditionExpressions.javali @@ -0,0 +1,24 @@ +/* testing conditions*/ +class Main { + void main() { + boolean a; + int b,c, d, e; + b = 10; + c = 3; + d = 40; + e = 1; + + while ( b > c ) { + write(b); + b = b-1; + } + a = c < (b+4-5/2); + if (a){ + write(13);} + if (100/2>d*e){ + while(e0 ) { + a = a-1; + } + + + +} \ No newline at end of file diff --git a/javali_tests/HW2_nop90/noParentheses.javali b/javali_tests/HW2_nop90/noParentheses.javali new file mode 100755 index 0000000..0413586 --- /dev/null +++ b/javali_tests/HW2_nop90/noParentheses.javali @@ -0,0 +1,24 @@ +/* test what happens if there are no parentheses */ + +class Main { + void main() { + int x; + int y; + int z; + + x = 5; + y = 10; + z = 100; + + write( x + y + z); writeln(); + /* */ + write( - x + y - z); writeln(); + + /* should output 205 */ + write( x + 2 * z); writeln(); + + write( x + 2 * z / x + 1); writeln(); + write(+x); writeln(); + + } +} diff --git a/src/cd/Config.java b/src/cd/Config.java index 6c7403a..db99934 100644 --- a/src/cd/Config.java +++ b/src/cd/Config.java @@ -10,11 +10,6 @@ public class Config { MACOSX } - /** - * What kind of system we are on - */ - public static final SystemKind systemKind; - /** * Defines the extension used for assembler files on this platform. * Currently always {@code .s}. @@ -84,11 +79,9 @@ public class Config { public static final String JAVA_EXE; static { - final String os = System.getProperty("os.name").toLowerCase(); if(os.contains("windows") || os.contains("nt")) { - systemKind = SystemKind.WINDOWS; BINARYEXT = ".exe"; MAIN = "_main"; PRINTF = "_printf"; @@ -96,7 +89,7 @@ public class Config { CALLOC = "_calloc"; EXIT = "_exit"; // These are set up for a Cygwin installation on C:, - // you can change as registersNeeded. + // you can change as needed. ASM = new String[]{"gcc", "-o", "$0", "$1"}; ASM_DIR = new File("C:\\CYGWIN\\BIN"); JAVA_EXE = "javaw.exe"; @@ -108,7 +101,6 @@ public class Config { COMMENT_SEP = "#"; } else if(os.contains("mac os x") || os.contains("darwin")) { - systemKind = SystemKind.MACOSX; BINARYEXT = ".bin"; MAIN = "_main"; PRINTF = "_printf"; @@ -126,7 +118,6 @@ public class Config { COMMENT_SEP = "#"; } else { - systemKind = SystemKind.LINUX; BINARYEXT = ".bin"; MAIN = "main"; PRINTF = "printf"; diff --git a/src/cd/Main.java b/src/cd/Main.java index b0413b7..e4a1335 100644 --- a/src/cd/Main.java +++ b/src/cd/Main.java @@ -2,7 +2,6 @@ package cd; import java.io.File; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Reader; @@ -15,7 +14,6 @@ import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.misc.ParseCancellationException; -import cd.backend.codegen.AstCodeGenerator; import cd.frontend.parser.JavaliAstVisitor; import cd.frontend.parser.JavaliLexer; import cd.frontend.parser.JavaliParser; @@ -36,7 +34,7 @@ public class Main { // Set to non-null to write debug info out public Writer debug = null; - // Set to non-null to write dump of control flow graph (Advanced Compiler Design) + // Set to non-null to write dump of control flow graph public File cfgdumpbase; public void debug(String format, Object... args) { @@ -64,15 +62,6 @@ public class Main { // Parse: List astRoots = m.parse(fin); - - // Run the semantic check: - m.semanticCheck(astRoots); - - // Generate code: - String sFile = arg + Config.ASMEXT; - try (FileWriter fout = new FileWriter(sFile)) { - m.generateCode(astRoots, fout); - } } } } @@ -105,18 +94,7 @@ public class Main { } - public void semanticCheck(List astRoots) { - { - // Not registersNeeded until later. Ignore. - } - } - public void generateCode(List astRoots, Writer out) { - { - AstCodeGenerator cg = AstCodeGenerator.createCodeGenerator(this, out); - cg.go(astRoots); - } - } /** Dumps the AST to the debug stream */ private void dumpAst(List astRoots) throws IOException { diff --git a/src/cd/backend/codegen/AssemblyEmitter.java b/src/cd/backend/codegen/AssemblyEmitter.java deleted file mode 100644 index f9c8c01..0000000 --- a/src/cd/backend/codegen/AssemblyEmitter.java +++ /dev/null @@ -1,164 +0,0 @@ -package cd.backend.codegen; - -import java.io.IOException; -import java.io.Writer; - -import cd.Config; -import cd.backend.codegen.RegisterManager.Register; - -public class AssemblyEmitter { - public Writer out; - public StringBuilder indent = new StringBuilder(); - public int counter = 0; - - public AssemblyEmitter(Writer out) { - this.out = out; - } - - /** Creates an constant operand. */ - static String constant(int i) { - return "$" + i; - } - - /** Creates an constant operand with the address of a label. */ - static String labelAddress(String lbl) { - return "$" + lbl; - } - - /** Creates an operand relative to another operand. */ - static String registerOffset(int offset, Register reg) { - return String.format("%d(%s)", offset, reg); - } - - /** Creates an operand addressing an item in an array */ - static String arrayAddress(Register arrReg, Register idxReg) { - final int offset = Config.SIZEOF_PTR * 2; // one word each in front for - // vptr and length - final int mul = Config.SIZEOF_PTR; // assume all arrays of 4-byte elem - return String.format("%d(%s,%s,%d)", offset, arrReg, idxReg, mul); - } - - void increaseIndent(String comment) { - indent.append(" "); - if (comment != null) - emitComment(comment); - } - - void decreaseIndent() { - indent.setLength(indent.length() - 2); - } - - void emitCommentSection(String name) { - int indentLen = indent.length(); - int breakLen = 68 - indentLen - name.length(); - StringBuffer sb = new StringBuffer(); - sb.append(Config.COMMENT_SEP).append(" "); - for (int i = 0; i < indentLen; i++) - sb.append("_"); - sb.append(name); - for (int i = 0; i < breakLen; i++) - sb.append("_"); - - try { - out.write(sb.toString()); - out.write("\n"); - } catch (IOException e) { - } - } - - void emitComment(String comment) { - emitRaw(Config.COMMENT_SEP + " " + comment); - } - - void emit(String op, Register src, String dest) { - emit(op, src.repr, dest); - } - - void emit(String op, String src, Register dest) { - emit(op, src, dest.repr); - } - - void emit(String op, Register src, Register dest) { - emit(op, src.repr, dest.repr); - } - - void emit(String op, String src, String dest) { - emitRaw(String.format("%s %s, %s", op, src, dest)); - } - - void emit(String op, int src, Register dest) { - emit(op, constant(src), dest); - } - - void emit(String op, String dest) { - emitRaw(op + " " + dest); - } - - void emit(String op) { - emitRaw(op); - } - - void emit(String op, Register reg) { - emit(op, reg.repr); - } - - void emit(String op, int dest) { - emit(op, constant(dest)); - } - - void emitMove(Register src, String dest) { - emitMove(src.repr, dest); - } - - void emitMove(Register src, Register dest) { - emitMove(src.repr, dest.repr); - } - - void emitMove(String src, Register dest) { - emitMove(src, dest.repr); - } - - void emitMove(String src, String dest) { - if (!src.equals(dest)) - emit("movl", src, dest); - } - - void emitLoad(int srcOffset, Register src, Register dest) { - emitMove(registerOffset(srcOffset, src), dest.repr); - } - - void emitStore(Register src, int destOffset, Register dest) { - emitStore(src.repr, destOffset, dest); - } - - void emitStore(String src, int destOffset, Register dest) { - emitMove(src, registerOffset(destOffset, dest)); - } - - void emitConstantData(String data) { - emitRaw(String.format("%s %s", Config.DOT_INT, data)); - } - - String uniqueLabel() { - String labelName = "label" + counter++; - return labelName; - } - - void emitLabel(String label) { - try { - out.write(label + ":" + "\n"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - void emitRaw(String op) { - try { - out.write(indent.toString()); - out.write(op); - out.write("\n"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/src/cd/backend/codegen/AssemblyFailedException.java b/src/cd/backend/codegen/AssemblyFailedException.java deleted file mode 100644 index 112fee9..0000000 --- a/src/cd/backend/codegen/AssemblyFailedException.java +++ /dev/null @@ -1,14 +0,0 @@ -package cd.backend.codegen; - -public class AssemblyFailedException extends RuntimeException { - private static final long serialVersionUID = -5658502514441032016L; - - public final String assemblerOutput; - public AssemblyFailedException( - String assemblerOutput) { - super("Executing assembler failed.\n" - + "Output:\n" - + assemblerOutput); - this.assemblerOutput = assemblerOutput; - } -} diff --git a/src/cd/backend/codegen/AstCodeGenerator.java b/src/cd/backend/codegen/AstCodeGenerator.java deleted file mode 100644 index cdbb510..0000000 --- a/src/cd/backend/codegen/AstCodeGenerator.java +++ /dev/null @@ -1,58 +0,0 @@ -package cd.backend.codegen; - -import cd.Main; -import cd.ir.Ast.ClassDecl; - -import java.io.Writer; -import java.util.List; - -public class AstCodeGenerator { - - protected ExprGenerator eg; - protected StmtGenerator sg; - - protected final Main main; - - protected final AssemblyEmitter emit; - protected final RegisterManager rm = new RegisterManager(); - - AstCodeGenerator(Main main, Writer out) { - this.emit = new AssemblyEmitter(out); - this.main = main; - this.eg = new ExprGenerator(this); - this.sg = new StmtGenerator(this); - } - - protected void debug(String format, Object... args) { - this.main.debug(format, args); - } - - public static AstCodeGenerator createCodeGenerator(Main main, Writer out) { - return new AstCodeGenerator(main, out); - } - - - /** - * Main method. Causes us to emit x86 assembly corresponding to {@code ast} - * into {@code file}. Throws a {@link RuntimeException} should any I/O error - * occur. - * - *

- * The generated file will be divided into two sections: - *

    - *
  1. Prologue: Generated by {@link #emitPrefix()}. This contains any - * introductory declarations and the like. - *
  2. Body: Generated by {@link ExprGenerator}. This contains the main - * method definitions. - *
- */ - public void go(List astRoots) { - for (ClassDecl ast : astRoots) { - sg.gen(ast); - } - } - - - protected void initMethodData() { - } -} \ No newline at end of file diff --git a/src/cd/backend/codegen/ExprGenerator.java b/src/cd/backend/codegen/ExprGenerator.java deleted file mode 100644 index 7632727..0000000 --- a/src/cd/backend/codegen/ExprGenerator.java +++ /dev/null @@ -1,307 +0,0 @@ -package cd.backend.codegen; - -import cd.backend.codegen.RegisterManager.Register; -import cd.ir.Ast.*; -import cd.ir.Ast.BinaryOp.BOp; -import cd.ir.ExprVisitor; -import cd.util.debug.AstOneLine; - -/** - * Generates code to evaluate expressions. After emitting the code, returns a - * String which indicates the register where the result can be found. - */ -class ExprGenerator extends ExprVisitor { - protected final AstCodeGenerator cg; - - ExprGenerator(AstCodeGenerator astCodeGenerator) { - cg = astCodeGenerator; - } - - public Register gen(Expr ast) { - return visit(ast, null); - } - - @Override - public Register visit(Expr ast, Void arg) { - try { - cg.emit.increaseIndent("Emitting " + AstOneLine.toString(ast)); - return super.visit(ast, null); - } finally { - cg.emit.decreaseIndent(); - } - - } - - @Override - public Register binaryOp(BinaryOp ast, Void arg) { - String op; - if (ast.operator == BOp.B_TIMES) - op = "imul"; - else if (ast.operator == BOp.B_PLUS) - op = "add"; - else if (ast.operator == BOp.B_MINUS) - op = "sub"; - else if (ast.operator == BOp.B_DIV) - op = "div"; - else - throw new RuntimeException("Not required (optional)"); - op += "l"; // long = 4B = 32b - - Register left, right; - int leftNeeded = ast.left().registersNeeded(); - int rightNeeded = ast.right().registersNeeded(); - if (leftNeeded > rightNeeded) { - left = cg.eg.visit(ast.left(), arg); - right = cg.eg.visit(ast.right(), arg); - } else { - right = cg.eg.visit(ast.right(), arg); - left = cg.eg.visit(ast.left(), arg); - } - - if (ast.operator == BOp.B_DIV) { - // The dividend (left) will be replaced with the quotient - // So free the divisor register (right) and return the quotient (left) - division(left, right); - cg.rm.releaseRegister(right); - return left; - } else { - // All operators take the form OP A, B --> B = B OP A --> B is left, A is right - // Therefore the result is stored in B (left) and A (right) can be freed - cg.emit.emit(op, right, left); - cg.rm.releaseRegister(right); - return left; - } - } - - /** - * Division with divide by zero check incorporated - */ - private void division(Register dividend, Register divisor) { - division(dividend, divisor, true); - } - - /** - * Special implementation for divisions, as it requires specific registers to be used - * @param dividend Maximum 32bit (even though the division is implemented as 64bit) - * @param divisor Maximum 32bit - * @param checkZero Whether to generate code that checks for division by zero or not - * @return The quotient will be in place of the dividend and the remainder in the divisor - */ - protected void division(Register dividend, Register divisor, boolean checkZero) { - if (checkZero) { - String beginDivision = cg.emit.uniqueLabel(); - cg.emit.emit("cmp", 0, divisor); - cg.emit.emit("jne", beginDivision); - // Exit with error code in case of div/0 - Interrupts.exit(cg, Interrupts.EXIT_DIV_0); - cg.emit.emitLabel(beginDivision); - } - - // D = d * q + r (dividend, divisor, quotient, remainder) - // EDX:EAX = d * EAX + EDX (before and after the div operation) - - // Take care of register use: move EAX to memory if necessary - // The stack is not needed because the division operator is not recursive - // After the division is performed, move the data back to dividend and divisor - Register d, D = Register.EAX; - if (divisor.equals(D)) { - d = cg.rm.getRegister(); - cg.emit.emitMove(divisor, d); - cg.emit.emitMove(dividend, Register.EAX); - } else { - if (!dividend.equals(D) && cg.rm.isInUse(D)) - cg.emit.emitMove(D, "(" + Interrupts.Mem.EAX.pos + ")"); - cg.emit.emitMove(dividend, D); - if (divisor.equals(Register.EDX)) { - d = cg.rm.getRegister(); - cg.emit.emitMove(divisor, d); - } - } - - // Division - cg.emit.emit("cdq"); - cg.emit.emit("idiv", divisor); - cg.emit.emitMove(Register.EAX, dividend); - cg.emit.emitMove(Register.EDX, divisor); - - Register q = Register.EAX, r = Register.EDX; - if (divisor.equals(D)) { - cg.emit.emitMove(q, dividend); - cg.emit.emitMove(r, divisor); - } else { - if (!dividend.equals(D) && cg.rm.isInUse(D)) - cg.emit.emitMove(Interrupts.Mem.EAX.pos, D); - cg.emit.emitMove(dividend, D); - if (!divisor.equals(r)) { - cg.emit.emitMove(r, divisor); - } - } - } - - @Override - public Register booleanConst(BooleanConst ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register builtInRead(BuiltInRead ast, Void arg) { - // Holds the first digit and then is used to accumulate the total value - Register value = cg.rm.getRegister(); - // Used to mark for positive (0) or negative (1) value - Register negative = cg.rm.getRegister(); - // Holds the next digit read, once the first has been read - Register nextDigit = cg.rm.getRegister(); - - // Labels for the read structure - String removeWhitespace = cg.emit.uniqueLabel(); - String negativeFirstDigit = cg.emit.uniqueLabel(); - String inputError = cg.emit.uniqueLabel(); - String moreDigits = cg.emit.uniqueLabel(); - String endRead = cg.emit.uniqueLabel(); - String checkSign = cg.emit.uniqueLabel(); - - // By default, variable is positive (negative == 0) - cg.emit.emitMove(AssemblyEmitter.constant(0), negative); - - // Skip whitespace ( \t\n\r) at the beginning - cg.emit.emitLabel(removeWhitespace); - Interrupts.readChar(cg, value); - cg.emit.emit("cmp", '\n', value); - cg.emit.emit("je", removeWhitespace); - cg.emit.emit("cmp", ' ', value); - cg.emit.emit("je", removeWhitespace); - cg.emit.emit("cmp", '\t', value); - cg.emit.emit("je", removeWhitespace); - cg.emit.emit("cmp", '\r', value); - cg.emit.emit("je", removeWhitespace); - - // Recognize first digit, if negative read another digit to place at value - cg.emit.emit("cmp", '-', value); - cg.emit.emit("je", negativeFirstDigit); - charToIntOrJump(value, inputError); - cg.emit.emit("jmp", moreDigits); - - // Negative first digit - cg.emit.emitLabel(negativeFirstDigit); - Interrupts.readChar(cg, value); - cg.emit.emitMove(AssemblyEmitter.constant(1), negative); - charToIntOrJump(value, inputError); - - // All other digits: - // while ( (nextDigit = read()).isDigit()) - // value = value * 10 + nextDigit - cg.emit.emitLabel(moreDigits); - Interrupts.readChar(cg, nextDigit); - charToIntOrJump(nextDigit, checkSign); - cg.emit.emit("imul", 10, value); - cg.emit.emit("add", nextDigit, value); - cg.emit.emit("jmp", moreDigits); - - // No number can be read (non-digit first or following the '-') - cg.emit.emitLabel(inputError); - Interrupts.exit(cg, Interrupts.EXIT_INPUT_MISMATCH); - - // Sign check and end - cg.emit.emitLabel(checkSign); - cg.emit.emit("cmp", 0, negative); - cg.emit.emit("je", endRead); - cg.emit.emit("negl", value); - cg.emit.emitLabel(endRead); - - // Register bookkeeping and return read value - cg.rm.releaseRegister(negative); - cg.rm.releaseRegister(nextDigit); - return value; - } - - private void charToIntOrJump(Register reg, String jumpLabel) { - cg.emit.emit("cmp", '0', reg); - cg.emit.emit("jl", jumpLabel); - cg.emit.emit("cmp", '9', reg); - cg.emit.emit("jg", jumpLabel); - cg.emit.emit("sub", '0', reg); - } - - @Override - public Register cast(Cast ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register index(Index ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register intConst(IntConst ast, Void arg) { - Register r = cg.rm.getRegister(); - cg.emit.emitMove(AssemblyEmitter.constant(ast.value), r); - return r; - } - - @Override - public Register field(Field ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register newArray(NewArray ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register newObject(NewObject ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register nullConst(NullConst ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register thisRef(ThisRef ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register unaryOp(UnaryOp ast, Void arg) { - Register aux = cg.eg.visit(ast.arg(), arg); - switch (ast.operator) { - case U_PLUS: - return aux; - case U_MINUS: - cg.emit.emit("negl", aux); - return aux; - case U_BOOL_NOT: - cg.emit.emit("notl", aux); - return aux; - default: - throw new RuntimeException("Not implemented"); - } - } - - @Override - public Register var(Var ast, Void arg) { - Register r = cg.rm.getRegister(); - cg.emit.emitMove(ast.getLabel(), r); - return r; - } - -} diff --git a/src/cd/backend/codegen/Interrupts.java b/src/cd/backend/codegen/Interrupts.java deleted file mode 100644 index c1c2992..0000000 --- a/src/cd/backend/codegen/Interrupts.java +++ /dev/null @@ -1,97 +0,0 @@ -package cd.backend.codegen; - -import cd.backend.codegen.RegisterManager.Register; - -import static cd.backend.codegen.Interrupts.Mem.BUFFER; - -public class Interrupts { - - protected static final int EXIT_OK = 0, EXIT_DIV_0 = 7, EXIT_INPUT_MISMATCH = 8; - protected static final int STDIN = 0, STDOUT = 1, STDERR = 2; - protected static final int I_EXIT = 1, I_READ = 3, I_WRITE = 4; - - protected enum Mem { - BUFFER("io_buffer"), EAX("eax"); - - String pos; - Mem(String pos) { - this.pos = pos; - } - - @Override - public String toString() { - return pos; - } - } - - /** - * Write auxiliary data variables needed for I/O and division - * @param cg AstCodeGenerator to print instructions - */ - protected static void reserveMemory(AstCodeGenerator cg) { - for (Mem m : Mem.values()) { - cg.emit.emitLabel(m.pos); - cg.emit.emitConstantData("0"); - } - } - - /** - * Writes a single character passed as parameter - * @param cg AstCodeGenerator to print instructions - * @param i Character code in ASCII (or single casted character) - */ - protected static void printChar(AstCodeGenerator cg, int i) { - cg.emit.emitMove(AssemblyEmitter.constant(i), BUFFER.pos); - printChar(cg); - } - - /** - * Writes a single character from the BUFFER memory pos to stdout - * @param cg AstCodeGenerator to print instructions - */ - protected static void printChar(AstCodeGenerator cg) { - Register[] needed = {Register.EAX, Register.EBX, Register.ECX, Register.EDX}; - for (int i = 0; i < needed.length; i++) - if (cg.rm.isInUse(needed[i])) - cg.emit.emit("push", needed[i]); - cg.emit.emitMove(AssemblyEmitter.constant(I_WRITE), Register.EAX); - cg.emit.emitMove(AssemblyEmitter.constant(STDOUT), Register.EBX); - cg.emit.emitMove("$" + BUFFER.pos, Register.ECX); - cg.emit.emitMove(AssemblyEmitter.constant(1), Register.EDX); - cg.emit.emit("int", 0x80); - for (int i = needed.length - 1; i >= 0; i--) - if (cg.rm.isInUse(needed[i])) - cg.emit.emit("pop", needed[i]); - } - - /** - * Reads a single character from stdin and places it in the - * memory pos BUFFER - */ - protected static void readChar(AstCodeGenerator cg, Register destination) { - Register[] needed = {Register.EAX, Register.EBX, Register.ECX, Register.EDX}; - for (int i = 0; i < needed.length; i++) - if (cg.rm.isInUse(needed[i])) - cg.emit.emit("push", needed[i]); - cg.emit.emitMove(AssemblyEmitter.constant(I_READ), Register.EAX); - cg.emit.emitMove(AssemblyEmitter.constant(STDIN), Register.EBX); - cg.emit.emitMove("$" + BUFFER.pos, Register.ECX); - cg.emit.emitMove(AssemblyEmitter.constant(1), Register.EDX); - cg.emit.emit("int", 0x80); - for (int i = needed.length - 1; i >= 0; i--) - if (cg.rm.isInUse(needed[i])) - cg.emit.emit("pop", needed[i]); - cg.emit.emitMove(BUFFER.pos, destination); - } - - /** - * Generates a exit interrupt with the code provided - * @param cg AstCodeGenerator to print instructions - * @param exitCode Number to use as exit code (can use constants in this class) - */ - protected static void exit(AstCodeGenerator cg, int exitCode) { - cg.emit.emitMove(AssemblyEmitter.constant(I_EXIT), Register.EAX); - cg.emit.emitMove(AssemblyEmitter.constant(exitCode), Register.EBX); - cg.emit.emit("int", 0x80); - } -} diff --git a/src/cd/backend/codegen/RegisterManager.java b/src/cd/backend/codegen/RegisterManager.java deleted file mode 100644 index 02c96b9..0000000 --- a/src/cd/backend/codegen/RegisterManager.java +++ /dev/null @@ -1,123 +0,0 @@ -package cd.backend.codegen; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Simple class that manages the set of currently used - * and unused registers - */ -public class RegisterManager { - private List registers = new ArrayList(); - - // lists of register to save by the callee and the caller - public static final Register CALLEE_SAVE[] = new Register[]{Register.ESI, - Register.EDI, Register.EBX}; - public static final Register CALLER_SAVE[] = new Register[]{Register.EAX, - Register.ECX, Register.EDX}; - - // list of general purpose registers - public static final Register GPR[] = new Register[]{Register.EAX, Register.EBX, - Register.ECX, Register.EDX, Register.ESI, Register.EDI}; - - // special purpose registers - public static final Register BASE_REG = Register.EBP; - public static final Register STACK_REG = Register.ESP; - - public static final int SIZEOF_REG = 4; - - - public enum Register { - EAX("%eax", ByteRegister.EAX), EBX("%ebx", ByteRegister.EBX), ECX( - "%ecx", ByteRegister.ECX), EDX("%edx", ByteRegister.EDX), ESI( - "%esi", null), EDI("%edi", null), EBP("%ebp", null), ESP( - "%esp", null); - - public final String repr; - private final ByteRegister lowByteVersion; - - private Register(String repr, ByteRegister bv) { - this.repr = repr; - this.lowByteVersion = bv; - } - - @Override - public String toString() { - return repr; - } - - /** - * determines if this register has an 8bit version - */ - public boolean hasLowByteVersion() { - return lowByteVersion != null; - } - - /** - * Given a register like {@code %eax} returns {@code %al}, but doesn't - * work for {@code %esi} and {@code %edi}! - */ - public ByteRegister lowByteVersion() { - assert hasLowByteVersion(); - return lowByteVersion; - } - } - - public enum ByteRegister { - EAX("%al"), EBX("%bl"), ECX("%cl"), EDX("%dl"); - - public final String repr; - - private ByteRegister(String repr) { - this.repr = repr; - } - - @Override - public String toString() { - return repr; - } - } - - /** - * Reset all general purpose registers to free - */ - public void initRegisters() { - registers.clear(); - registers.addAll(Arrays.asList(GPR)); - } - - /** - * returns a free register and marks it as used - */ - public Register getRegister() { - int last = registers.size() - 1; - if (last < 0) - throw new AssemblyFailedException( - "Program requires too many registers"); - - return registers.remove(last); - } - - /** - * marks a currently used register as free - */ - public void releaseRegister(Register reg) { - assert !registers.contains(reg); - registers.add(reg); - } - - /** - * Returns whether the register is currently non-free - */ - public boolean isInUse(Register reg) { - return !registers.contains(reg); - } - - /** - * returns the number of free registers - */ - public int availableRegisters() { - return registers.size(); - } -} \ No newline at end of file diff --git a/src/cd/backend/codegen/StmtGenerator.java b/src/cd/backend/codegen/StmtGenerator.java deleted file mode 100644 index acfa300..0000000 --- a/src/cd/backend/codegen/StmtGenerator.java +++ /dev/null @@ -1,206 +0,0 @@ -package cd.backend.codegen; - -import cd.backend.codegen.RegisterManager.Register; -import cd.ir.Ast; -import cd.ir.Ast.*; -import cd.ir.AstVisitor; -import cd.util.debug.AstOneLine; - -import java.util.*; - -/** - * Generates code to process statements and declarations. - */ -class StmtGenerator extends AstVisitor { - protected final AstCodeGenerator cg; - - StmtGenerator(AstCodeGenerator astCodeGenerator) { - cg = astCodeGenerator; - } - - public void gen(Ast ast) { - visit(ast, null); - } - - @Override - public Register visit(Ast ast, Void arg) { - try { - cg.emit.increaseIndent("Emitting " + AstOneLine.toString(ast)); - return super.visit(ast, arg); - } finally { - cg.emit.decreaseIndent(); - } - } - - /** - * Declares a variable in the data segment. This method was implemented because it was necessary - * to create the data segment - * @param ast Variable declaration node - * @param arg Extra arguments - * @return null - */ - @Override - public Register varDecl(Ast.VarDecl ast, Void arg) { - cg.emit.emitLabel(ast.getLabel()); - cg.emit.emitConstantData("0"); - return null; - } - - @Override - public Register methodCall(MethodCall ast, Void dummy) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register methodDecl(MethodDecl ast, Void arg) { - // Prologue: in future version a more complex prologue that - // takes care of parameters and return values is necessary - // Method code - cg.rm.initRegisters(); - cg.emit.emitRaw(".section .data"); - Interrupts.reserveMemory(cg); - // Variables - cg.sg.visit(ast.decls(), arg); - cg.emit.emitRaw(".section .text"); - cg.emit.emitRaw(".globl " + ast.name); - cg.emit.emitLabel(ast.name); - Register result = cg.sg.visit(ast.body(), arg); - // Epilogue: not needed in the simple HW1 - return null; - } - - @Override - public Register ifElse(IfElse ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register whileLoop(WhileLoop ast, Void arg) { - { - throw new RuntimeException("Not required"); - } - } - - @Override - public Register assign(Assign ast, Void arg) { - // Because we only handle very simple programs in HW1, - // you can just emit the prologue here! - Register value = cg.eg.visit(ast.right(), arg); - Ast.Var variable = (Var) ast.left(); - cg.emit.emitMove(value, variable.getLabel()); - cg.rm.releaseRegister(value); - return null; - } - - @Override - public Register builtInWrite(BuiltInWrite ast, Void arg) { - String printNonZero = cg.emit.uniqueLabel(); - String end = cg.emit.uniqueLabel(); - String printPositive = cg.emit.uniqueLabel(); - String stackLoop = cg.emit.uniqueLabel(); - String printLoop = cg.emit.uniqueLabel(); - - Register value = cg.eg.visit(ast.arg(), arg); - // Begin: decide if print 0 or print number - cg.emit.emit("cmp", 0, value); - cg.emit.emit("jne", printNonZero); // value != 0 - - // Print 0 - Interrupts.printChar(cg, '0'); // print 0 - cg.emit.emit("jmp", end); - - // Not 0: positive or negative? - cg.emit.emitLabel(printNonZero); - cg.emit.emit("jg", printPositive); // value > 0 - - // Number is negative, print '-' then number (with sign changed) - Interrupts.printChar(cg, '-'); - cg.emit.emit("negl", value); - - // Print number: extract and print all digits of number - cg.emit.emitLabel(printPositive); - - // In order to avoid using EAX and EDX, we are going to guarantee - // that there will be at least 2 other registers available - List auxRegs = Arrays.asList(Register.EDI, Register.ESI); - List divRegs = Arrays.asList(Register.EAX, Register.EDX); - Map isPushed = new HashMap<>(); - boolean usingAuxRegs = cg.rm.availableRegisters() < 4; - if (usingAuxRegs) - for (int i = 0; i < auxRegs.size(); i++) - isPushed.put(auxRegs.get(i), cg.rm.isInUse(auxRegs.get(i))); - - // Free EAX and EDX for div operand use - isPushed.put(Register.EAX, cg.rm.isInUse(Register.EAX) && !value.equals(Register.EAX)); - isPushed.put(Register.EDX, cg.rm.isInUse(Register.EDX)); - - // Push all elements - for (Register r : isPushed.keySet()) - if (isPushed.get(r)) - cg.emit.emit("push", r); - - // Force counter and divisor to not be EDX/EAX, as they need to coexist - Register counter = cg.rm.getRegister(); - Register divisor = cg.rm.getRegister(); - while (divRegs.contains(counter)) { - Register aux = cg.rm.getRegister(); - cg.rm.releaseRegister(counter); - counter = aux; - } - while (divRegs.contains(divisor)) { - Register aux = cg.rm.getRegister(); - cg.rm.releaseRegister(divisor); - divisor = aux; - } - - // Divide by 10 to extract the remainders and push them to the stack - // Registers used: EAX is the remaining digits (initially the value) - // in div it is used for the lower half of the dividend and for quotient - // divisor - // EDX is used as the high half of the dividend and as remainder - cg.emit.emitMove(value, Register.EAX); - cg.rm.releaseRegister(value); - cg.emit.emitMove(AssemblyEmitter.constant(0), counter); - - cg.emit.emitLabel(stackLoop); - cg.emit.emitMove(AssemblyEmitter.constant(0), Register.EDX); - cg.emit.emitMove(AssemblyEmitter.constant(10), divisor); - cg.emit.emit("div", divisor); - cg.emit.emit("add", '0', Register.EDX); - cg.emit.emit("push", Register.EDX); - cg.emit.emit("inc", counter); - cg.emit.emit("cmp", 0, Register.EAX); - cg.emit.emit("je", printLoop); - cg.emit.emit("jmp", stackLoop); - // Release divisor register - cg.rm.releaseRegister(divisor); - - // Print digits from the stack - cg.emit.emitLabel(printLoop); - cg.emit.emit("cmp", 0, counter); - cg.emit.emit("jz", end); - cg.emit.emit("dec", counter); - cg.emit.emit("pop", Interrupts.Mem.BUFFER.pos); - Interrupts.printChar(cg); - cg.emit.emit("jmp", printLoop); - cg.emit.emitLabel(end); - - cg.rm.releaseRegister(counter); - - // Restore original registers - for (Register r : isPushed.keySet()) - if (isPushed.get(r)) - cg.emit.emit("pop", r); - return null; - } - - @Override - public Register builtInWriteln(BuiltInWriteln ast, Void arg) { - Interrupts.printChar(cg, '\n'); - return null; - } -} diff --git a/src/cd/frontend/parser/.gitignore b/src/cd/frontend/parser/.gitignore deleted file mode 100644 index 3713151..0000000 --- a/src/cd/frontend/parser/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/Javali.tokens -/JavaliBaseVisitor.java -/JavaliLexer.java -/JavaliLexer.tokens -/JavaliParser.java -/JavaliVisitor.java diff --git a/src/cd/frontend/parser/Javali.g4 b/src/cd/frontend/parser/Javali.g4 new file mode 100644 index 0000000..4ea3d4f --- /dev/null +++ b/src/cd/frontend/parser/Javali.g4 @@ -0,0 +1,203 @@ +grammar Javali; // parser grammar, parses streams of tokens + +@header { + // Java header + package cd.frontend.parser; +} + + + +// PARSER RULES +literal + : 'null' # NullLiteral + | Boolean # BoolLiteral + | Integer # IntLiteral + ; + +// Types +type + : primitiveType + | referenceType + ; + +referenceType + : Ident + | arrayType + ; + +arrayType + : Ident '[' ']' + | primitiveType '[' ']' + ; + +primitiveType + : 'boolean' + | 'int' + ; + +// Program structure +unit + : classDecl+ EOF + ; + +classDecl + : 'class' Ident ('extends' Ident)? '{' memberList '}' + ; + +memberList + : (varDecl | methodDecl)* + ; + +varDecl + : type Ident (',' Ident)* ';' + ; + +methodDecl + : (type | 'void') Ident '(' formalParamList? ')' '{' varDecl* stmt* '}' + ; + +formalParamList + : type Ident (',' type Ident)* + ; + +// Statements +stmt + : assignmentStmt + | methodCallStmt + | ifStmt + | whileStmt + | returnStmt + | writeStmt + ; + +stmtBlock + : '{' stmt* '}' + ; + +methodCallStmt + : Ident '(' actualParamList? ')' ';' # LocalMethodCallStmt + | identAccess '.' Ident '(' actualParamList? ')' ';' # ObjectMethodCallStmt + ; + +assignmentStmt + : identAccess '=' (expr | newExpr | readExpr) ';' + ; + +writeStmt + : 'write' '(' expr ')' ';' # Write + | 'writeln' '(' ')' ';' # WriteLn + ; + +ifStmt + : 'if' '(' expr ')' stmtBlock ('else' stmtBlock)? + ; + +whileStmt + : 'while' '(' expr ')' stmtBlock + ; + +returnStmt + : 'return' expr? ';' + ; + +// Expressions +newExpr + : 'new' Ident '(' ')' # NewObject + | 'new' Ident '[' expr ']' # NewObjectArray + | 'new' primitiveType '[' expr ']' # NewPrimitiveArray + ; + +readExpr + : 'read' '(' ')' + ; + +actualParamList + : expr (',' expr)* + ; + +identAccess + : Ident # AccessLocalField + | 'this' # AccessThis + | identAccess '.' Ident # AccessObjectField + | identAccess '[' expr ']' # AccessArray + | Ident '(' actualParamList? ')' # AccessLocalMethod + | identAccess '.' Ident '(' actualParamList? ')'# AccessObjectMethod + ; + +expr + : literal # ExprConstant + | identAccess # ExprIdentAccess + | '(' expr ')' # ExprParentheses + | ('+'|'-'|'!') expr # ExprUnary + | '(' referenceType ')' expr # ExprCast + | expr ('*'|'/'|'%') expr # ExprBinary + | expr ('+'|'-') expr # ExprBinary + | expr ('<'|'>'|'<='|'>=') expr # ExprBinary + | expr ('=='|'!=') expr # ExprBinary + | expr '&&' expr # ExprBinary + | expr '||' expr # ExprBinary + ; + + +// LEXER RULES +fragment +Letter + : 'A'..'Z' + | 'a'..'z' + ; + +fragment +Digit + : '0'..'9' + ; + +fragment +HexDigit + : Digit + | 'a'..'f' + | 'A'..'F' + ; + +fragment +Decimal + : '0' + | '1'..'9' Digit* + ; + +fragment +Hexadecimal + : ('0x'|'0X') HexDigit+ + ; + +Integer + : Decimal + | Hexadecimal + ; + +Boolean + : 'false' + | 'true' + ; + +Ident + : Letter (Letter|Digit)* + ; + + + +// comments and white space does not produce tokens: +COMMENT + : '/*' .*? '*/' -> skip + ; + +LINE_COMMENT + : '//' ~('\n'|'\r')* -> skip + ; + +WS + : (' '|'\r'|'\t'|'\n') -> skip + ; + + +// handle characters which failed to match any other token +ErrorCharacter : . ; diff --git a/src/cd/frontend/parser/Javali.interp b/src/cd/frontend/parser/Javali.interp new file mode 100644 index 0000000..639ff83 --- /dev/null +++ b/src/cd/frontend/parser/Javali.interp @@ -0,0 +1,127 @@ +token literal names: +null +'null' +'[' +']' +'boolean' +'int' +'class' +'extends' +'{' +'}' +',' +';' +'void' +'(' +')' +'.' +'=' +'write' +'writeln' +'if' +'else' +'while' +'return' +'new' +'read' +'this' +'+' +'-' +'!' +'*' +'/' +'%' +'<' +'>' +'<=' +'>=' +'==' +'!=' +'&&' +'||' +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +Integer +Boolean +Ident +COMMENT +LINE_COMMENT +WS +ErrorCharacter + +rule names: +literal +type +referenceType +arrayType +primitiveType +unit +classDecl +memberList +varDecl +methodDecl +formalParamList +stmt +stmtBlock +methodCallStmt +assignmentStmt +writeStmt +ifStmt +whileStmt +returnStmt +newExpr +readExpr +actualParamList +identAccess +expr + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 48, 325, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 3, 2, 3, 2, 3, 2, 5, 2, 54, 10, 2, 3, 3, 3, 3, 5, 3, 58, 10, 3, 3, 4, 3, 4, 5, 4, 62, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 71, 10, 5, 3, 6, 3, 6, 3, 7, 6, 7, 76, 10, 7, 13, 7, 14, 7, 77, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 86, 10, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 7, 9, 94, 10, 9, 12, 9, 14, 9, 97, 11, 9, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 103, 10, 10, 12, 10, 14, 10, 106, 11, 10, 3, 10, 3, 10, 3, 11, 3, 11, 5, 11, 112, 10, 11, 3, 11, 3, 11, 3, 11, 5, 11, 117, 10, 11, 3, 11, 3, 11, 3, 11, 7, 11, 122, 10, 11, 12, 11, 14, 11, 125, 11, 11, 3, 11, 7, 11, 128, 10, 11, 12, 11, 14, 11, 131, 11, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 141, 10, 12, 12, 12, 14, 12, 144, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 152, 10, 13, 3, 14, 3, 14, 7, 14, 156, 10, 14, 12, 14, 14, 14, 159, 11, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 5, 15, 166, 10, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 175, 10, 15, 3, 15, 3, 15, 3, 15, 5, 15, 180, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 187, 10, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 201, 10, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 210, 10, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 5, 20, 220, 10, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 240, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 7, 23, 249, 10, 23, 12, 23, 14, 23, 252, 11, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 260, 10, 24, 3, 24, 5, 24, 263, 10, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 278, 10, 24, 3, 24, 7, 24, 281, 10, 24, 12, 24, 14, 24, 284, 11, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 5, 25, 300, 10, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 320, 10, 25, 12, 25, 14, 25, 323, 11, 25, 3, 25, 2, 4, 46, 48, 26, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 2, 8, 3, 2, 6, 7, 3, 2, 28, 30, 3, 2, 31, 33, 3, 2, 28, 29, 3, 2, 34, 37, 3, 2, 38, 39, 2, 349, 2, 53, 3, 2, 2, 2, 4, 57, 3, 2, 2, 2, 6, 61, 3, 2, 2, 2, 8, 70, 3, 2, 2, 2, 10, 72, 3, 2, 2, 2, 12, 75, 3, 2, 2, 2, 14, 81, 3, 2, 2, 2, 16, 95, 3, 2, 2, 2, 18, 98, 3, 2, 2, 2, 20, 111, 3, 2, 2, 2, 22, 134, 3, 2, 2, 2, 24, 151, 3, 2, 2, 2, 26, 153, 3, 2, 2, 2, 28, 179, 3, 2, 2, 2, 30, 181, 3, 2, 2, 2, 32, 200, 3, 2, 2, 2, 34, 202, 3, 2, 2, 2, 36, 211, 3, 2, 2, 2, 38, 217, 3, 2, 2, 2, 40, 239, 3, 2, 2, 2, 42, 241, 3, 2, 2, 2, 44, 245, 3, 2, 2, 2, 46, 262, 3, 2, 2, 2, 48, 299, 3, 2, 2, 2, 50, 54, 7, 3, 2, 2, 51, 54, 7, 43, 2, 2, 52, 54, 7, 42, 2, 2, 53, 50, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 52, 3, 2, 2, 2, 54, 3, 3, 2, 2, 2, 55, 58, 5, 10, 6, 2, 56, 58, 5, 6, 4, 2, 57, 55, 3, 2, 2, 2, 57, 56, 3, 2, 2, 2, 58, 5, 3, 2, 2, 2, 59, 62, 7, 44, 2, 2, 60, 62, 5, 8, 5, 2, 61, 59, 3, 2, 2, 2, 61, 60, 3, 2, 2, 2, 62, 7, 3, 2, 2, 2, 63, 64, 7, 44, 2, 2, 64, 65, 7, 4, 2, 2, 65, 71, 7, 5, 2, 2, 66, 67, 5, 10, 6, 2, 67, 68, 7, 4, 2, 2, 68, 69, 7, 5, 2, 2, 69, 71, 3, 2, 2, 2, 70, 63, 3, 2, 2, 2, 70, 66, 3, 2, 2, 2, 71, 9, 3, 2, 2, 2, 72, 73, 9, 2, 2, 2, 73, 11, 3, 2, 2, 2, 74, 76, 5, 14, 8, 2, 75, 74, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 80, 7, 2, 2, 3, 80, 13, 3, 2, 2, 2, 81, 82, 7, 8, 2, 2, 82, 85, 7, 44, 2, 2, 83, 84, 7, 9, 2, 2, 84, 86, 7, 44, 2, 2, 85, 83, 3, 2, 2, 2, 85, 86, 3, 2, 2, 2, 86, 87, 3, 2, 2, 2, 87, 88, 7, 10, 2, 2, 88, 89, 5, 16, 9, 2, 89, 90, 7, 11, 2, 2, 90, 15, 3, 2, 2, 2, 91, 94, 5, 18, 10, 2, 92, 94, 5, 20, 11, 2, 93, 91, 3, 2, 2, 2, 93, 92, 3, 2, 2, 2, 94, 97, 3, 2, 2, 2, 95, 93, 3, 2, 2, 2, 95, 96, 3, 2, 2, 2, 96, 17, 3, 2, 2, 2, 97, 95, 3, 2, 2, 2, 98, 99, 5, 4, 3, 2, 99, 104, 7, 44, 2, 2, 100, 101, 7, 12, 2, 2, 101, 103, 7, 44, 2, 2, 102, 100, 3, 2, 2, 2, 103, 106, 3, 2, 2, 2, 104, 102, 3, 2, 2, 2, 104, 105, 3, 2, 2, 2, 105, 107, 3, 2, 2, 2, 106, 104, 3, 2, 2, 2, 107, 108, 7, 13, 2, 2, 108, 19, 3, 2, 2, 2, 109, 112, 5, 4, 3, 2, 110, 112, 7, 14, 2, 2, 111, 109, 3, 2, 2, 2, 111, 110, 3, 2, 2, 2, 112, 113, 3, 2, 2, 2, 113, 114, 7, 44, 2, 2, 114, 116, 7, 15, 2, 2, 115, 117, 5, 22, 12, 2, 116, 115, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 119, 7, 16, 2, 2, 119, 123, 7, 10, 2, 2, 120, 122, 5, 18, 10, 2, 121, 120, 3, 2, 2, 2, 122, 125, 3, 2, 2, 2, 123, 121, 3, 2, 2, 2, 123, 124, 3, 2, 2, 2, 124, 129, 3, 2, 2, 2, 125, 123, 3, 2, 2, 2, 126, 128, 5, 24, 13, 2, 127, 126, 3, 2, 2, 2, 128, 131, 3, 2, 2, 2, 129, 127, 3, 2, 2, 2, 129, 130, 3, 2, 2, 2, 130, 132, 3, 2, 2, 2, 131, 129, 3, 2, 2, 2, 132, 133, 7, 11, 2, 2, 133, 21, 3, 2, 2, 2, 134, 135, 5, 4, 3, 2, 135, 142, 7, 44, 2, 2, 136, 137, 7, 12, 2, 2, 137, 138, 5, 4, 3, 2, 138, 139, 7, 44, 2, 2, 139, 141, 3, 2, 2, 2, 140, 136, 3, 2, 2, 2, 141, 144, 3, 2, 2, 2, 142, 140, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 23, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 145, 152, 5, 30, 16, 2, 146, 152, 5, 28, 15, 2, 147, 152, 5, 34, 18, 2, 148, 152, 5, 36, 19, 2, 149, 152, 5, 38, 20, 2, 150, 152, 5, 32, 17, 2, 151, 145, 3, 2, 2, 2, 151, 146, 3, 2, 2, 2, 151, 147, 3, 2, 2, 2, 151, 148, 3, 2, 2, 2, 151, 149, 3, 2, 2, 2, 151, 150, 3, 2, 2, 2, 152, 25, 3, 2, 2, 2, 153, 157, 7, 10, 2, 2, 154, 156, 5, 24, 13, 2, 155, 154, 3, 2, 2, 2, 156, 159, 3, 2, 2, 2, 157, 155, 3, 2, 2, 2, 157, 158, 3, 2, 2, 2, 158, 160, 3, 2, 2, 2, 159, 157, 3, 2, 2, 2, 160, 161, 7, 11, 2, 2, 161, 27, 3, 2, 2, 2, 162, 163, 7, 44, 2, 2, 163, 165, 7, 15, 2, 2, 164, 166, 5, 44, 23, 2, 165, 164, 3, 2, 2, 2, 165, 166, 3, 2, 2, 2, 166, 167, 3, 2, 2, 2, 167, 168, 7, 16, 2, 2, 168, 180, 7, 13, 2, 2, 169, 170, 5, 46, 24, 2, 170, 171, 7, 17, 2, 2, 171, 172, 7, 44, 2, 2, 172, 174, 7, 15, 2, 2, 173, 175, 5, 44, 23, 2, 174, 173, 3, 2, 2, 2, 174, 175, 3, 2, 2, 2, 175, 176, 3, 2, 2, 2, 176, 177, 7, 16, 2, 2, 177, 178, 7, 13, 2, 2, 178, 180, 3, 2, 2, 2, 179, 162, 3, 2, 2, 2, 179, 169, 3, 2, 2, 2, 180, 29, 3, 2, 2, 2, 181, 182, 5, 46, 24, 2, 182, 186, 7, 18, 2, 2, 183, 187, 5, 48, 25, 2, 184, 187, 5, 40, 21, 2, 185, 187, 5, 42, 22, 2, 186, 183, 3, 2, 2, 2, 186, 184, 3, 2, 2, 2, 186, 185, 3, 2, 2, 2, 187, 188, 3, 2, 2, 2, 188, 189, 7, 13, 2, 2, 189, 31, 3, 2, 2, 2, 190, 191, 7, 19, 2, 2, 191, 192, 7, 15, 2, 2, 192, 193, 5, 48, 25, 2, 193, 194, 7, 16, 2, 2, 194, 195, 7, 13, 2, 2, 195, 201, 3, 2, 2, 2, 196, 197, 7, 20, 2, 2, 197, 198, 7, 15, 2, 2, 198, 199, 7, 16, 2, 2, 199, 201, 7, 13, 2, 2, 200, 190, 3, 2, 2, 2, 200, 196, 3, 2, 2, 2, 201, 33, 3, 2, 2, 2, 202, 203, 7, 21, 2, 2, 203, 204, 7, 15, 2, 2, 204, 205, 5, 48, 25, 2, 205, 206, 7, 16, 2, 2, 206, 209, 5, 26, 14, 2, 207, 208, 7, 22, 2, 2, 208, 210, 5, 26, 14, 2, 209, 207, 3, 2, 2, 2, 209, 210, 3, 2, 2, 2, 210, 35, 3, 2, 2, 2, 211, 212, 7, 23, 2, 2, 212, 213, 7, 15, 2, 2, 213, 214, 5, 48, 25, 2, 214, 215, 7, 16, 2, 2, 215, 216, 5, 26, 14, 2, 216, 37, 3, 2, 2, 2, 217, 219, 7, 24, 2, 2, 218, 220, 5, 48, 25, 2, 219, 218, 3, 2, 2, 2, 219, 220, 3, 2, 2, 2, 220, 221, 3, 2, 2, 2, 221, 222, 7, 13, 2, 2, 222, 39, 3, 2, 2, 2, 223, 224, 7, 25, 2, 2, 224, 225, 7, 44, 2, 2, 225, 226, 7, 15, 2, 2, 226, 240, 7, 16, 2, 2, 227, 228, 7, 25, 2, 2, 228, 229, 7, 44, 2, 2, 229, 230, 7, 4, 2, 2, 230, 231, 5, 48, 25, 2, 231, 232, 7, 5, 2, 2, 232, 240, 3, 2, 2, 2, 233, 234, 7, 25, 2, 2, 234, 235, 5, 10, 6, 2, 235, 236, 7, 4, 2, 2, 236, 237, 5, 48, 25, 2, 237, 238, 7, 5, 2, 2, 238, 240, 3, 2, 2, 2, 239, 223, 3, 2, 2, 2, 239, 227, 3, 2, 2, 2, 239, 233, 3, 2, 2, 2, 240, 41, 3, 2, 2, 2, 241, 242, 7, 26, 2, 2, 242, 243, 7, 15, 2, 2, 243, 244, 7, 16, 2, 2, 244, 43, 3, 2, 2, 2, 245, 250, 5, 48, 25, 2, 246, 247, 7, 12, 2, 2, 247, 249, 5, 48, 25, 2, 248, 246, 3, 2, 2, 2, 249, 252, 3, 2, 2, 2, 250, 248, 3, 2, 2, 2, 250, 251, 3, 2, 2, 2, 251, 45, 3, 2, 2, 2, 252, 250, 3, 2, 2, 2, 253, 254, 8, 24, 1, 2, 254, 263, 7, 44, 2, 2, 255, 263, 7, 27, 2, 2, 256, 257, 7, 44, 2, 2, 257, 259, 7, 15, 2, 2, 258, 260, 5, 44, 23, 2, 259, 258, 3, 2, 2, 2, 259, 260, 3, 2, 2, 2, 260, 261, 3, 2, 2, 2, 261, 263, 7, 16, 2, 2, 262, 253, 3, 2, 2, 2, 262, 255, 3, 2, 2, 2, 262, 256, 3, 2, 2, 2, 263, 282, 3, 2, 2, 2, 264, 265, 12, 6, 2, 2, 265, 266, 7, 17, 2, 2, 266, 281, 7, 44, 2, 2, 267, 268, 12, 5, 2, 2, 268, 269, 7, 4, 2, 2, 269, 270, 5, 48, 25, 2, 270, 271, 7, 5, 2, 2, 271, 281, 3, 2, 2, 2, 272, 273, 12, 3, 2, 2, 273, 274, 7, 17, 2, 2, 274, 275, 7, 44, 2, 2, 275, 277, 7, 15, 2, 2, 276, 278, 5, 44, 23, 2, 277, 276, 3, 2, 2, 2, 277, 278, 3, 2, 2, 2, 278, 279, 3, 2, 2, 2, 279, 281, 7, 16, 2, 2, 280, 264, 3, 2, 2, 2, 280, 267, 3, 2, 2, 2, 280, 272, 3, 2, 2, 2, 281, 284, 3, 2, 2, 2, 282, 280, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 47, 3, 2, 2, 2, 284, 282, 3, 2, 2, 2, 285, 286, 8, 25, 1, 2, 286, 300, 5, 2, 2, 2, 287, 300, 5, 46, 24, 2, 288, 289, 7, 15, 2, 2, 289, 290, 5, 48, 25, 2, 290, 291, 7, 16, 2, 2, 291, 300, 3, 2, 2, 2, 292, 293, 9, 3, 2, 2, 293, 300, 5, 48, 25, 10, 294, 295, 7, 15, 2, 2, 295, 296, 5, 6, 4, 2, 296, 297, 7, 16, 2, 2, 297, 298, 5, 48, 25, 9, 298, 300, 3, 2, 2, 2, 299, 285, 3, 2, 2, 2, 299, 287, 3, 2, 2, 2, 299, 288, 3, 2, 2, 2, 299, 292, 3, 2, 2, 2, 299, 294, 3, 2, 2, 2, 300, 321, 3, 2, 2, 2, 301, 302, 12, 8, 2, 2, 302, 303, 9, 4, 2, 2, 303, 320, 5, 48, 25, 9, 304, 305, 12, 7, 2, 2, 305, 306, 9, 5, 2, 2, 306, 320, 5, 48, 25, 8, 307, 308, 12, 6, 2, 2, 308, 309, 9, 6, 2, 2, 309, 320, 5, 48, 25, 7, 310, 311, 12, 5, 2, 2, 311, 312, 9, 7, 2, 2, 312, 320, 5, 48, 25, 6, 313, 314, 12, 4, 2, 2, 314, 315, 7, 40, 2, 2, 315, 320, 5, 48, 25, 5, 316, 317, 12, 3, 2, 2, 317, 318, 7, 41, 2, 2, 318, 320, 5, 48, 25, 4, 319, 301, 3, 2, 2, 2, 319, 304, 3, 2, 2, 2, 319, 307, 3, 2, 2, 2, 319, 310, 3, 2, 2, 2, 319, 313, 3, 2, 2, 2, 319, 316, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 49, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 35, 53, 57, 61, 70, 77, 85, 93, 95, 104, 111, 116, 123, 129, 142, 151, 157, 165, 174, 179, 186, 200, 209, 219, 239, 250, 259, 262, 277, 280, 282, 299, 319, 321] \ No newline at end of file diff --git a/src/cd/frontend/parser/Javali.tokens b/src/cd/frontend/parser/Javali.tokens new file mode 100644 index 0000000..0bd9b31 --- /dev/null +++ b/src/cd/frontend/parser/Javali.tokens @@ -0,0 +1,85 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +T__38=39 +Integer=40 +Boolean=41 +Ident=42 +COMMENT=43 +LINE_COMMENT=44 +WS=45 +ErrorCharacter=46 +'null'=1 +'['=2 +']'=3 +'boolean'=4 +'int'=5 +'class'=6 +'extends'=7 +'{'=8 +'}'=9 +','=10 +';'=11 +'void'=12 +'('=13 +')'=14 +'.'=15 +'='=16 +'write'=17 +'writeln'=18 +'if'=19 +'else'=20 +'while'=21 +'return'=22 +'new'=23 +'read'=24 +'this'=25 +'+'=26 +'-'=27 +'!'=28 +'*'=29 +'/'=30 +'%'=31 +'<'=32 +'>'=33 +'<='=34 +'>='=35 +'=='=36 +'!='=37 +'&&'=38 +'||'=39 diff --git a/src/cd/frontend/parser/JavaliAstVisitor.java b/src/cd/frontend/parser/JavaliAstVisitor.java new file mode 100644 index 0000000..f9b3559 --- /dev/null +++ b/src/cd/frontend/parser/JavaliAstVisitor.java @@ -0,0 +1,329 @@ +package cd.frontend.parser; + +import cd.frontend.parser.JavaliParser.*; +import cd.ir.Ast; +import cd.ir.Ast.*; +import cd.ir.Ast.BinaryOp.BOp; +import cd.ir.Ast.UnaryOp.UOp; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.util.ArrayList; +import java.util.List; + +public final class JavaliAstVisitor extends JavaliBaseVisitor { + + public List classDecls = new ArrayList<>(); + + @Override + public Ast visitUnit(UnitContext ctx) { + for (ClassDeclContext classDeclContext : ctx.classDecl()) + classDecls.add((ClassDecl) visit(classDeclContext)); + return new Seq(new ArrayList<>(classDecls)); + } + + @Override + public Ast visitClassDecl(ClassDeclContext ctx) { + String name = ctx.Ident(0).getText(); + String superClass = "Object"; // Common superclass + if (ctx.Ident().size() == 2) + superClass = ctx.Ident(1).getText(); + Seq members = (Seq) visit(ctx.memberList()); + return new ClassDecl(name, superClass, members.children()); + } + + @Override + public Ast visitMemberList(MemberListContext ctx) { + if (ctx.children == null) { + return new Seq(new ArrayList<>()); + } + List list = new ArrayList<>(ctx.children.size()); + for (ParseTree parseTree : ctx.children) { + if (parseTree instanceof VarDeclContext) { + Seq seqVars = (Seq) visit(parseTree); + list.addAll(seqVars.children()); + } else { + assert parseTree instanceof MethodDeclContext; + list.add(visit(parseTree)); + } + } + return new Seq(list); + } + + @Override + public Ast visitVarDecl(VarDeclContext ctx) { + List list = new ArrayList<>(ctx.Ident().size()); + String type = ctx.type().getText(); + for (TerminalNode n : ctx.Ident()) + list.add(new VarDecl(type, n.getText())); + return new Seq(list); + } + + @Override + public Ast visitMethodDecl(MethodDeclContext ctx) { + List argumentTypes = new ArrayList<>(); + List argumentNames = new ArrayList<>(); + if (ctx.formalParamList() != null) { + Seq paramList = (Seq) visit(ctx.formalParamList()); + for (Ast ast : paramList.children()) { + VarDecl var = (VarDecl) ast; + argumentNames.add(var.name); + argumentTypes.add(var.type); + } + } + + List decls = new ArrayList<>(ctx.varDecl().size()); + for (VarDeclContext varDecl : ctx.varDecl()) { + Seq declarationSeq = (Seq) visit(varDecl); + decls.addAll(declarationSeq.children()); + } + + List stmts = new ArrayList<>(ctx.stmt().size()); + for (StmtContext s : ctx.stmt()) + stmts.add(visit(s)); + + return new MethodDecl( + ctx.type() == null ? "void" : ctx.type().getText(), + ctx.Ident().getText(), + argumentTypes, + argumentNames, + new Seq(decls), + new Seq(stmts) + ); + } + + @Override + public Ast visitFormalParamList(FormalParamListContext ctx) { + List list = new ArrayList<>(ctx.type().size()); + for (int i = 0; i < ctx.type().size(); i++) { + String type = ctx.type(i).getText(); + String name = ctx.Ident(i).getText(); + list.add(new VarDecl(type, name)); + } + return new Seq(list); + } + + @Override + public Ast visitStmt(StmtContext ctx) { + return visit(ctx.children.get(0)); + } + + @Override + public Ast visitStmtBlock(StmtBlockContext ctx) { + List list = new ArrayList<>(ctx.stmt().size()); + for (StmtContext stmtContext : ctx.stmt()) + list.add(visit(stmtContext)); + return new Seq(list); + } + + @Override + public Ast visitLocalMethodCallStmt(LocalMethodCallStmtContext ctx) { + return new MethodCall(new MethodCallExpr( + new ThisRef(), + ctx.Ident().getText(), + getParams(ctx.actualParamList()) + )); + } + + @Override + public Ast visitObjectMethodCallStmt(ObjectMethodCallStmtContext ctx) { + return new MethodCall(new MethodCallExpr( + (Expr) visit(ctx.identAccess()), + ctx.Ident().getText(), + getParams(ctx.actualParamList()) + )); + } + + @Override + public Ast visitAssignmentStmt(AssignmentStmtContext ctx) { + Expr left = (Expr) visit(ctx.children.get(0)); + Expr right = (Expr) visit(ctx.children.get(2)); + return new Assign(left, right); + } + + @Override + public Ast visitWrite(WriteContext ctx) { + return new BuiltInWrite((Expr) visit(ctx.expr())); + } + + @Override + public Ast visitWriteLn(WriteLnContext ctx) { + return new BuiltInWriteln(); + } + + @Override + public Ast visitIfStmt(IfStmtContext ctx) { + Expr condition = (Expr) visit(ctx.expr()); + Ast then = visit(ctx.stmtBlock(0)); + Ast otherwise = new Nop(); + if (ctx.stmtBlock().size() == 2) + otherwise = visit(ctx.stmtBlock(1)); + return new IfElse(condition, then, otherwise); + } + + @Override + public Ast visitWhileStmt(WhileStmtContext ctx) { + Expr condition = (Expr) visit(ctx.expr()); + Ast body = visit(ctx.stmtBlock()); + return new WhileLoop(condition, body); + } + + @Override + public Ast visitReturnStmt(ReturnStmtContext ctx) { + if (ctx.expr() != null) + return new ReturnStmt((Expr) visit(ctx.expr())); + else + return new ReturnStmt(null); + } + + @Override + public Ast visitNewObject(NewObjectContext ctx) { + return new NewObject(ctx.Ident().getText()); + } + + @Override + public Ast visitNewObjectArray(NewObjectArrayContext ctx) { + String type = ctx.Ident().getText(); + Expr size = (Expr) visit(ctx.expr()); + return new NewArray(type + "[]", size); + } + + @Override + public Ast visitNewPrimitiveArray(NewPrimitiveArrayContext ctx) { + String type = ctx.primitiveType().getText(); + Expr size = (Expr) visit(ctx.expr()); + return new NewArray(type + "[]", size); + } + + @Override + public Ast visitReadExpr(ReadExprContext ctx) { + return new BuiltInRead(); + } + + @Override + public Ast visitActualParamList(ActualParamListContext ctx) { + List list = new ArrayList<>(ctx.expr().size()); + for (ExprContext exprContext : ctx.expr()) + list.add(visit(exprContext)); + return new Seq(list); + } + + @Override + public Ast visitAccessThis(AccessThisContext ctx) { + return new ThisRef(); + } + + @Override + public Ast visitAccessLocalField(AccessLocalFieldContext ctx) { + return new Var(ctx.Ident().getText()); + } + + @Override + public Ast visitAccessObjectField(AccessObjectFieldContext ctx) { + Expr arg = (Expr) visit(ctx.identAccess()); + String fieldName = ctx.Ident().getText(); + return new Field(arg, fieldName); + } + + @Override + public Ast visitAccessLocalMethod(AccessLocalMethodContext ctx) { + return new MethodCallExpr( + new ThisRef(), + ctx.Ident().getText(), + getParams(ctx.actualParamList()) + ); + } + + @Override + public Ast visitAccessArray(AccessArrayContext ctx) { + Expr array = (Expr) visit(ctx.identAccess()); + Expr index = (Expr) visit(ctx.expr()); + return new Index(array, index); + } + + @Override + public Ast visitAccessObjectMethod(AccessObjectMethodContext ctx) { + return new MethodCallExpr( + (Expr) visit(ctx.identAccess()), + ctx.Ident().getText(), + getParams(ctx.actualParamList()) + ); + } + + @Override + public Ast visitExprBinary(ExprBinaryContext ctx) { + Expr left = (Expr) visit(ctx.expr(0)); + Expr right = (Expr) visit(ctx.expr(1)); + String op = ctx.getChild(1).getText(); + for (BOp bop : BOp.values()) + if (bop.repr.equals(op)) + return new BinaryOp(left, bop, right); + throw new RuntimeException("BOp enum is inconsistent with grammar"); + } + + @Override + public Ast visitExprCast(ExprCastContext ctx) { + Expr arg = (Expr) visit(ctx.expr()); + String typeName = ctx.referenceType().getText(); + return new Cast(arg, typeName); + } + + @Override + public Ast visitExprParentheses(ExprParenthesesContext ctx) { + return visit(ctx.expr()); + } + + @Override + public Ast visitExprUnary(ExprUnaryContext ctx) { + Expr expr = (Expr) visit(ctx.expr()); + String op = ctx.getChild(0).getText(); + for (UOp uop : UOp.values()) + if (uop.repr.equals(op)) + return new UnaryOp(uop, expr); + throw new RuntimeException("UOp enum is inconsistent with grammar"); + } + + @Override + public Ast visitExprConstant(ExprConstantContext ctx) { + return visit(ctx.literal()); + } + + @Override + public Ast visitNullLiteral(NullLiteralContext ctx) { + return new NullConst(); + } + + @Override + public Ast visitBoolLiteral(BoolLiteralContext ctx) { + return new BooleanConst(ctx.Boolean().getText().equals("true")); + } + + @Override + public Ast visitIntLiteral(IntLiteralContext ctx) { + try { + return new IntConst(Integer.decode(ctx.Integer().getText())); + } catch (NumberFormatException exception) { + throw new ParseFailure(ctx.start.getLine(), "Value not in 32bit signed int range"); + } + } + + @Override + public Ast visitExprIdentAccess(ExprIdentAccessContext ctx) { + return visit(ctx.identAccess()); + } + + /** + * Obtain the parameters for a method call + * @param paramListContext Formal parameter list from the ANTRL tree + * @return List of parameters for the method call + */ + private List getParams(ActualParamListContext paramListContext) { + List paramList = new ArrayList<>(); + if (paramListContext != null) { + Seq paramSeq = (Seq) visit(paramListContext); + for (Ast ast : paramSeq.children()) + paramList.add((Expr) ast); + } + return paramList; + } +} diff --git a/src/cd/frontend/parser/JavaliBaseVisitor.java b/src/cd/frontend/parser/JavaliBaseVisitor.java new file mode 100644 index 0000000..a3a15ac --- /dev/null +++ b/src/cd/frontend/parser/JavaliBaseVisitor.java @@ -0,0 +1,297 @@ +// Generated from /home/carlos/eth/cd/nop90/HW2/src/cd/frontend/parser/Javali.g4 by ANTLR 4.7.1 + + // Java header + package cd.frontend.parser; + +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link JavaliVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public class JavaliBaseVisitor extends AbstractParseTreeVisitor implements JavaliVisitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNullLiteral(JavaliParser.NullLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitBoolLiteral(JavaliParser.BoolLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitIntLiteral(JavaliParser.IntLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitType(JavaliParser.TypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitReferenceType(JavaliParser.ReferenceTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitArrayType(JavaliParser.ArrayTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPrimitiveType(JavaliParser.PrimitiveTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitUnit(JavaliParser.UnitContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitClassDecl(JavaliParser.ClassDeclContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitMemberList(JavaliParser.MemberListContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitVarDecl(JavaliParser.VarDeclContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitMethodDecl(JavaliParser.MethodDeclContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitFormalParamList(JavaliParser.FormalParamListContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStmt(JavaliParser.StmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStmtBlock(JavaliParser.StmtBlockContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLocalMethodCallStmt(JavaliParser.LocalMethodCallStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitObjectMethodCallStmt(JavaliParser.ObjectMethodCallStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAssignmentStmt(JavaliParser.AssignmentStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitWrite(JavaliParser.WriteContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitWriteLn(JavaliParser.WriteLnContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitIfStmt(JavaliParser.IfStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitWhileStmt(JavaliParser.WhileStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitReturnStmt(JavaliParser.ReturnStmtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNewObject(JavaliParser.NewObjectContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNewObjectArray(JavaliParser.NewObjectArrayContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNewPrimitiveArray(JavaliParser.NewPrimitiveArrayContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitReadExpr(JavaliParser.ReadExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitActualParamList(JavaliParser.ActualParamListContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessThis(JavaliParser.AccessThisContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessLocalField(JavaliParser.AccessLocalFieldContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessObjectField(JavaliParser.AccessObjectFieldContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessLocalMethod(JavaliParser.AccessLocalMethodContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessArray(JavaliParser.AccessArrayContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAccessObjectMethod(JavaliParser.AccessObjectMethodContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprBinary(JavaliParser.ExprBinaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprCast(JavaliParser.ExprCastContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprParentheses(JavaliParser.ExprParenthesesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprUnary(JavaliParser.ExprUnaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprConstant(JavaliParser.ExprConstantContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprIdentAccess(JavaliParser.ExprIdentAccessContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/src/cd/frontend/parser/JavaliLexer.interp b/src/cd/frontend/parser/JavaliLexer.interp new file mode 100644 index 0000000..6244602 --- /dev/null +++ b/src/cd/frontend/parser/JavaliLexer.interp @@ -0,0 +1,160 @@ +token literal names: +null +'null' +'[' +']' +'boolean' +'int' +'class' +'extends' +'{' +'}' +',' +';' +'void' +'(' +')' +'.' +'=' +'write' +'writeln' +'if' +'else' +'while' +'return' +'new' +'read' +'this' +'+' +'-' +'!' +'*' +'/' +'%' +'<' +'>' +'<=' +'>=' +'==' +'!=' +'&&' +'||' +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +Integer +Boolean +Ident +COMMENT +LINE_COMMENT +WS +ErrorCharacter + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +T__13 +T__14 +T__15 +T__16 +T__17 +T__18 +T__19 +T__20 +T__21 +T__22 +T__23 +T__24 +T__25 +T__26 +T__27 +T__28 +T__29 +T__30 +T__31 +T__32 +T__33 +T__34 +T__35 +T__36 +T__37 +T__38 +Letter +Digit +HexDigit +Decimal +Hexadecimal +Integer +Boolean +Ident +COMMENT +LINE_COMMENT +WS +ErrorCharacter + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 48, 327, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 43, 3, 43, 5, 43, 251, 10, 43, 3, 44, 3, 44, 3, 44, 7, 44, 256, 10, 44, 12, 44, 14, 44, 259, 11, 44, 5, 44, 261, 10, 44, 3, 45, 3, 45, 3, 45, 3, 45, 5, 45, 267, 10, 45, 3, 45, 6, 45, 270, 10, 45, 13, 45, 14, 45, 271, 3, 46, 3, 46, 5, 46, 276, 10, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 5, 47, 287, 10, 47, 3, 48, 3, 48, 3, 48, 7, 48, 292, 10, 48, 12, 48, 14, 48, 295, 11, 48, 3, 49, 3, 49, 3, 49, 3, 49, 7, 49, 301, 10, 49, 12, 49, 14, 49, 304, 11, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 7, 50, 315, 10, 50, 12, 50, 14, 50, 318, 11, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 302, 2, 53, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 2, 83, 2, 85, 2, 87, 2, 89, 2, 91, 42, 93, 43, 95, 44, 97, 45, 99, 46, 101, 47, 103, 48, 3, 2, 6, 4, 2, 67, 92, 99, 124, 4, 2, 67, 72, 99, 104, 4, 2, 12, 12, 15, 15, 5, 2, 11, 12, 15, 15, 34, 34, 2, 332, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 3, 105, 3, 2, 2, 2, 5, 110, 3, 2, 2, 2, 7, 112, 3, 2, 2, 2, 9, 114, 3, 2, 2, 2, 11, 122, 3, 2, 2, 2, 13, 126, 3, 2, 2, 2, 15, 132, 3, 2, 2, 2, 17, 140, 3, 2, 2, 2, 19, 142, 3, 2, 2, 2, 21, 144, 3, 2, 2, 2, 23, 146, 3, 2, 2, 2, 25, 148, 3, 2, 2, 2, 27, 153, 3, 2, 2, 2, 29, 155, 3, 2, 2, 2, 31, 157, 3, 2, 2, 2, 33, 159, 3, 2, 2, 2, 35, 161, 3, 2, 2, 2, 37, 167, 3, 2, 2, 2, 39, 175, 3, 2, 2, 2, 41, 178, 3, 2, 2, 2, 43, 183, 3, 2, 2, 2, 45, 189, 3, 2, 2, 2, 47, 196, 3, 2, 2, 2, 49, 200, 3, 2, 2, 2, 51, 205, 3, 2, 2, 2, 53, 210, 3, 2, 2, 2, 55, 212, 3, 2, 2, 2, 57, 214, 3, 2, 2, 2, 59, 216, 3, 2, 2, 2, 61, 218, 3, 2, 2, 2, 63, 220, 3, 2, 2, 2, 65, 222, 3, 2, 2, 2, 67, 224, 3, 2, 2, 2, 69, 226, 3, 2, 2, 2, 71, 229, 3, 2, 2, 2, 73, 232, 3, 2, 2, 2, 75, 235, 3, 2, 2, 2, 77, 238, 3, 2, 2, 2, 79, 241, 3, 2, 2, 2, 81, 244, 3, 2, 2, 2, 83, 246, 3, 2, 2, 2, 85, 250, 3, 2, 2, 2, 87, 260, 3, 2, 2, 2, 89, 266, 3, 2, 2, 2, 91, 275, 3, 2, 2, 2, 93, 286, 3, 2, 2, 2, 95, 288, 3, 2, 2, 2, 97, 296, 3, 2, 2, 2, 99, 310, 3, 2, 2, 2, 101, 321, 3, 2, 2, 2, 103, 325, 3, 2, 2, 2, 105, 106, 7, 112, 2, 2, 106, 107, 7, 119, 2, 2, 107, 108, 7, 110, 2, 2, 108, 109, 7, 110, 2, 2, 109, 4, 3, 2, 2, 2, 110, 111, 7, 93, 2, 2, 111, 6, 3, 2, 2, 2, 112, 113, 7, 95, 2, 2, 113, 8, 3, 2, 2, 2, 114, 115, 7, 100, 2, 2, 115, 116, 7, 113, 2, 2, 116, 117, 7, 113, 2, 2, 117, 118, 7, 110, 2, 2, 118, 119, 7, 103, 2, 2, 119, 120, 7, 99, 2, 2, 120, 121, 7, 112, 2, 2, 121, 10, 3, 2, 2, 2, 122, 123, 7, 107, 2, 2, 123, 124, 7, 112, 2, 2, 124, 125, 7, 118, 2, 2, 125, 12, 3, 2, 2, 2, 126, 127, 7, 101, 2, 2, 127, 128, 7, 110, 2, 2, 128, 129, 7, 99, 2, 2, 129, 130, 7, 117, 2, 2, 130, 131, 7, 117, 2, 2, 131, 14, 3, 2, 2, 2, 132, 133, 7, 103, 2, 2, 133, 134, 7, 122, 2, 2, 134, 135, 7, 118, 2, 2, 135, 136, 7, 103, 2, 2, 136, 137, 7, 112, 2, 2, 137, 138, 7, 102, 2, 2, 138, 139, 7, 117, 2, 2, 139, 16, 3, 2, 2, 2, 140, 141, 7, 125, 2, 2, 141, 18, 3, 2, 2, 2, 142, 143, 7, 127, 2, 2, 143, 20, 3, 2, 2, 2, 144, 145, 7, 46, 2, 2, 145, 22, 3, 2, 2, 2, 146, 147, 7, 61, 2, 2, 147, 24, 3, 2, 2, 2, 148, 149, 7, 120, 2, 2, 149, 150, 7, 113, 2, 2, 150, 151, 7, 107, 2, 2, 151, 152, 7, 102, 2, 2, 152, 26, 3, 2, 2, 2, 153, 154, 7, 42, 2, 2, 154, 28, 3, 2, 2, 2, 155, 156, 7, 43, 2, 2, 156, 30, 3, 2, 2, 2, 157, 158, 7, 48, 2, 2, 158, 32, 3, 2, 2, 2, 159, 160, 7, 63, 2, 2, 160, 34, 3, 2, 2, 2, 161, 162, 7, 121, 2, 2, 162, 163, 7, 116, 2, 2, 163, 164, 7, 107, 2, 2, 164, 165, 7, 118, 2, 2, 165, 166, 7, 103, 2, 2, 166, 36, 3, 2, 2, 2, 167, 168, 7, 121, 2, 2, 168, 169, 7, 116, 2, 2, 169, 170, 7, 107, 2, 2, 170, 171, 7, 118, 2, 2, 171, 172, 7, 103, 2, 2, 172, 173, 7, 110, 2, 2, 173, 174, 7, 112, 2, 2, 174, 38, 3, 2, 2, 2, 175, 176, 7, 107, 2, 2, 176, 177, 7, 104, 2, 2, 177, 40, 3, 2, 2, 2, 178, 179, 7, 103, 2, 2, 179, 180, 7, 110, 2, 2, 180, 181, 7, 117, 2, 2, 181, 182, 7, 103, 2, 2, 182, 42, 3, 2, 2, 2, 183, 184, 7, 121, 2, 2, 184, 185, 7, 106, 2, 2, 185, 186, 7, 107, 2, 2, 186, 187, 7, 110, 2, 2, 187, 188, 7, 103, 2, 2, 188, 44, 3, 2, 2, 2, 189, 190, 7, 116, 2, 2, 190, 191, 7, 103, 2, 2, 191, 192, 7, 118, 2, 2, 192, 193, 7, 119, 2, 2, 193, 194, 7, 116, 2, 2, 194, 195, 7, 112, 2, 2, 195, 46, 3, 2, 2, 2, 196, 197, 7, 112, 2, 2, 197, 198, 7, 103, 2, 2, 198, 199, 7, 121, 2, 2, 199, 48, 3, 2, 2, 2, 200, 201, 7, 116, 2, 2, 201, 202, 7, 103, 2, 2, 202, 203, 7, 99, 2, 2, 203, 204, 7, 102, 2, 2, 204, 50, 3, 2, 2, 2, 205, 206, 7, 118, 2, 2, 206, 207, 7, 106, 2, 2, 207, 208, 7, 107, 2, 2, 208, 209, 7, 117, 2, 2, 209, 52, 3, 2, 2, 2, 210, 211, 7, 45, 2, 2, 211, 54, 3, 2, 2, 2, 212, 213, 7, 47, 2, 2, 213, 56, 3, 2, 2, 2, 214, 215, 7, 35, 2, 2, 215, 58, 3, 2, 2, 2, 216, 217, 7, 44, 2, 2, 217, 60, 3, 2, 2, 2, 218, 219, 7, 49, 2, 2, 219, 62, 3, 2, 2, 2, 220, 221, 7, 39, 2, 2, 221, 64, 3, 2, 2, 2, 222, 223, 7, 62, 2, 2, 223, 66, 3, 2, 2, 2, 224, 225, 7, 64, 2, 2, 225, 68, 3, 2, 2, 2, 226, 227, 7, 62, 2, 2, 227, 228, 7, 63, 2, 2, 228, 70, 3, 2, 2, 2, 229, 230, 7, 64, 2, 2, 230, 231, 7, 63, 2, 2, 231, 72, 3, 2, 2, 2, 232, 233, 7, 63, 2, 2, 233, 234, 7, 63, 2, 2, 234, 74, 3, 2, 2, 2, 235, 236, 7, 35, 2, 2, 236, 237, 7, 63, 2, 2, 237, 76, 3, 2, 2, 2, 238, 239, 7, 40, 2, 2, 239, 240, 7, 40, 2, 2, 240, 78, 3, 2, 2, 2, 241, 242, 7, 126, 2, 2, 242, 243, 7, 126, 2, 2, 243, 80, 3, 2, 2, 2, 244, 245, 9, 2, 2, 2, 245, 82, 3, 2, 2, 2, 246, 247, 4, 50, 59, 2, 247, 84, 3, 2, 2, 2, 248, 251, 5, 83, 42, 2, 249, 251, 9, 3, 2, 2, 250, 248, 3, 2, 2, 2, 250, 249, 3, 2, 2, 2, 251, 86, 3, 2, 2, 2, 252, 261, 7, 50, 2, 2, 253, 257, 4, 51, 59, 2, 254, 256, 5, 83, 42, 2, 255, 254, 3, 2, 2, 2, 256, 259, 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 257, 258, 3, 2, 2, 2, 258, 261, 3, 2, 2, 2, 259, 257, 3, 2, 2, 2, 260, 252, 3, 2, 2, 2, 260, 253, 3, 2, 2, 2, 261, 88, 3, 2, 2, 2, 262, 263, 7, 50, 2, 2, 263, 267, 7, 122, 2, 2, 264, 265, 7, 50, 2, 2, 265, 267, 7, 90, 2, 2, 266, 262, 3, 2, 2, 2, 266, 264, 3, 2, 2, 2, 267, 269, 3, 2, 2, 2, 268, 270, 5, 85, 43, 2, 269, 268, 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 90, 3, 2, 2, 2, 273, 276, 5, 87, 44, 2, 274, 276, 5, 89, 45, 2, 275, 273, 3, 2, 2, 2, 275, 274, 3, 2, 2, 2, 276, 92, 3, 2, 2, 2, 277, 278, 7, 104, 2, 2, 278, 279, 7, 99, 2, 2, 279, 280, 7, 110, 2, 2, 280, 281, 7, 117, 2, 2, 281, 287, 7, 103, 2, 2, 282, 283, 7, 118, 2, 2, 283, 284, 7, 116, 2, 2, 284, 285, 7, 119, 2, 2, 285, 287, 7, 103, 2, 2, 286, 277, 3, 2, 2, 2, 286, 282, 3, 2, 2, 2, 287, 94, 3, 2, 2, 2, 288, 293, 5, 81, 41, 2, 289, 292, 5, 81, 41, 2, 290, 292, 5, 83, 42, 2, 291, 289, 3, 2, 2, 2, 291, 290, 3, 2, 2, 2, 292, 295, 3, 2, 2, 2, 293, 291, 3, 2, 2, 2, 293, 294, 3, 2, 2, 2, 294, 96, 3, 2, 2, 2, 295, 293, 3, 2, 2, 2, 296, 297, 7, 49, 2, 2, 297, 298, 7, 44, 2, 2, 298, 302, 3, 2, 2, 2, 299, 301, 11, 2, 2, 2, 300, 299, 3, 2, 2, 2, 301, 304, 3, 2, 2, 2, 302, 303, 3, 2, 2, 2, 302, 300, 3, 2, 2, 2, 303, 305, 3, 2, 2, 2, 304, 302, 3, 2, 2, 2, 305, 306, 7, 44, 2, 2, 306, 307, 7, 49, 2, 2, 307, 308, 3, 2, 2, 2, 308, 309, 8, 49, 2, 2, 309, 98, 3, 2, 2, 2, 310, 311, 7, 49, 2, 2, 311, 312, 7, 49, 2, 2, 312, 316, 3, 2, 2, 2, 313, 315, 10, 4, 2, 2, 314, 313, 3, 2, 2, 2, 315, 318, 3, 2, 2, 2, 316, 314, 3, 2, 2, 2, 316, 317, 3, 2, 2, 2, 317, 319, 3, 2, 2, 2, 318, 316, 3, 2, 2, 2, 319, 320, 8, 50, 2, 2, 320, 100, 3, 2, 2, 2, 321, 322, 9, 5, 2, 2, 322, 323, 3, 2, 2, 2, 323, 324, 8, 51, 2, 2, 324, 102, 3, 2, 2, 2, 325, 326, 11, 2, 2, 2, 326, 104, 3, 2, 2, 2, 14, 2, 250, 257, 260, 266, 271, 275, 286, 291, 293, 302, 316, 3, 8, 2, 2] \ No newline at end of file diff --git a/src/cd/frontend/parser/JavaliLexer.java b/src/cd/frontend/parser/JavaliLexer.java new file mode 100644 index 0000000..50aec9c --- /dev/null +++ b/src/cd/frontend/parser/JavaliLexer.java @@ -0,0 +1,232 @@ +// Generated from /home/carlos/eth/cd/nop90/HW2/src/cd/frontend/parser/Javali.g4 by ANTLR 4.7.1 + + // Java header + package cd.frontend.parser; + +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class JavaliLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, + T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, + T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, + T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, + T__38=39, Integer=40, Boolean=41, Ident=42, COMMENT=43, LINE_COMMENT=44, + WS=45, ErrorCharacter=46; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + public static final String[] ruleNames = { + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", + "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", + "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", + "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "Letter", "Digit", + "HexDigit", "Decimal", "Hexadecimal", "Integer", "Boolean", "Ident", "COMMENT", + "LINE_COMMENT", "WS", "ErrorCharacter" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'null'", "'['", "']'", "'boolean'", "'int'", "'class'", "'extends'", + "'{'", "'}'", "','", "';'", "'void'", "'('", "')'", "'.'", "'='", "'write'", + "'writeln'", "'if'", "'else'", "'while'", "'return'", "'new'", "'read'", + "'this'", "'+'", "'-'", "'!'", "'*'", "'/'", "'%'", "'<'", "'>'", "'<='", + "'>='", "'=='", "'!='", "'&&'", "'||'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, "Integer", "Boolean", "Ident", "COMMENT", "LINE_COMMENT", + "WS", "ErrorCharacter" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public JavaliLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "Javali.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\60\u0147\b\1\4\2"+ + "\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+ + "\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ + "\t\64\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ + "\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3"+ + "\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16"+ + "\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25"+ + "\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30"+ + "\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33"+ + "\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\3"+ + "#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3+\3"+ + "+\5+\u00fb\n+\3,\3,\3,\7,\u0100\n,\f,\16,\u0103\13,\5,\u0105\n,\3-\3-"+ + "\3-\3-\5-\u010b\n-\3-\6-\u010e\n-\r-\16-\u010f\3.\3.\5.\u0114\n.\3/\3"+ + "/\3/\3/\3/\3/\3/\3/\3/\5/\u011f\n/\3\60\3\60\3\60\7\60\u0124\n\60\f\60"+ + "\16\60\u0127\13\60\3\61\3\61\3\61\3\61\7\61\u012d\n\61\f\61\16\61\u0130"+ + "\13\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\7\62\u013b\n\62\f"+ + "\62\16\62\u013e\13\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\u012e"+ + "\2\65\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35"+ + "\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36"+ + ";\37= ?!A\"C#E$G%I&K\'M(O)Q\2S\2U\2W\2Y\2[*]+_,a-c.e/g\60\3\2\6\4\2C\\"+ + "c|\4\2CHch\4\2\f\f\17\17\5\2\13\f\17\17\"\"\2\u014c\2\3\3\2\2\2\2\5\3"+ + "\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2"+ + "\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3"+ + "\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'"+ + "\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63"+ + "\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2"+ + "?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3"+ + "\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2"+ + "\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\3i\3\2\2\2\5n\3\2\2\2\7p\3\2\2\2\t"+ + "r\3\2\2\2\13z\3\2\2\2\r~\3\2\2\2\17\u0084\3\2\2\2\21\u008c\3\2\2\2\23"+ + "\u008e\3\2\2\2\25\u0090\3\2\2\2\27\u0092\3\2\2\2\31\u0094\3\2\2\2\33\u0099"+ + "\3\2\2\2\35\u009b\3\2\2\2\37\u009d\3\2\2\2!\u009f\3\2\2\2#\u00a1\3\2\2"+ + "\2%\u00a7\3\2\2\2\'\u00af\3\2\2\2)\u00b2\3\2\2\2+\u00b7\3\2\2\2-\u00bd"+ + "\3\2\2\2/\u00c4\3\2\2\2\61\u00c8\3\2\2\2\63\u00cd\3\2\2\2\65\u00d2\3\2"+ + "\2\2\67\u00d4\3\2\2\29\u00d6\3\2\2\2;\u00d8\3\2\2\2=\u00da\3\2\2\2?\u00dc"+ + "\3\2\2\2A\u00de\3\2\2\2C\u00e0\3\2\2\2E\u00e2\3\2\2\2G\u00e5\3\2\2\2I"+ + "\u00e8\3\2\2\2K\u00eb\3\2\2\2M\u00ee\3\2\2\2O\u00f1\3\2\2\2Q\u00f4\3\2"+ + "\2\2S\u00f6\3\2\2\2U\u00fa\3\2\2\2W\u0104\3\2\2\2Y\u010a\3\2\2\2[\u0113"+ + "\3\2\2\2]\u011e\3\2\2\2_\u0120\3\2\2\2a\u0128\3\2\2\2c\u0136\3\2\2\2e"+ + "\u0141\3\2\2\2g\u0145\3\2\2\2ij\7p\2\2jk\7w\2\2kl\7n\2\2lm\7n\2\2m\4\3"+ + "\2\2\2no\7]\2\2o\6\3\2\2\2pq\7_\2\2q\b\3\2\2\2rs\7d\2\2st\7q\2\2tu\7q"+ + "\2\2uv\7n\2\2vw\7g\2\2wx\7c\2\2xy\7p\2\2y\n\3\2\2\2z{\7k\2\2{|\7p\2\2"+ + "|}\7v\2\2}\f\3\2\2\2~\177\7e\2\2\177\u0080\7n\2\2\u0080\u0081\7c\2\2\u0081"+ + "\u0082\7u\2\2\u0082\u0083\7u\2\2\u0083\16\3\2\2\2\u0084\u0085\7g\2\2\u0085"+ + "\u0086\7z\2\2\u0086\u0087\7v\2\2\u0087\u0088\7g\2\2\u0088\u0089\7p\2\2"+ + "\u0089\u008a\7f\2\2\u008a\u008b\7u\2\2\u008b\20\3\2\2\2\u008c\u008d\7"+ + "}\2\2\u008d\22\3\2\2\2\u008e\u008f\7\177\2\2\u008f\24\3\2\2\2\u0090\u0091"+ + "\7.\2\2\u0091\26\3\2\2\2\u0092\u0093\7=\2\2\u0093\30\3\2\2\2\u0094\u0095"+ + "\7x\2\2\u0095\u0096\7q\2\2\u0096\u0097\7k\2\2\u0097\u0098\7f\2\2\u0098"+ + "\32\3\2\2\2\u0099\u009a\7*\2\2\u009a\34\3\2\2\2\u009b\u009c\7+\2\2\u009c"+ + "\36\3\2\2\2\u009d\u009e\7\60\2\2\u009e \3\2\2\2\u009f\u00a0\7?\2\2\u00a0"+ + "\"\3\2\2\2\u00a1\u00a2\7y\2\2\u00a2\u00a3\7t\2\2\u00a3\u00a4\7k\2\2\u00a4"+ + "\u00a5\7v\2\2\u00a5\u00a6\7g\2\2\u00a6$\3\2\2\2\u00a7\u00a8\7y\2\2\u00a8"+ + "\u00a9\7t\2\2\u00a9\u00aa\7k\2\2\u00aa\u00ab\7v\2\2\u00ab\u00ac\7g\2\2"+ + "\u00ac\u00ad\7n\2\2\u00ad\u00ae\7p\2\2\u00ae&\3\2\2\2\u00af\u00b0\7k\2"+ + "\2\u00b0\u00b1\7h\2\2\u00b1(\3\2\2\2\u00b2\u00b3\7g\2\2\u00b3\u00b4\7"+ + "n\2\2\u00b4\u00b5\7u\2\2\u00b5\u00b6\7g\2\2\u00b6*\3\2\2\2\u00b7\u00b8"+ + "\7y\2\2\u00b8\u00b9\7j\2\2\u00b9\u00ba\7k\2\2\u00ba\u00bb\7n\2\2\u00bb"+ + "\u00bc\7g\2\2\u00bc,\3\2\2\2\u00bd\u00be\7t\2\2\u00be\u00bf\7g\2\2\u00bf"+ + "\u00c0\7v\2\2\u00c0\u00c1\7w\2\2\u00c1\u00c2\7t\2\2\u00c2\u00c3\7p\2\2"+ + "\u00c3.\3\2\2\2\u00c4\u00c5\7p\2\2\u00c5\u00c6\7g\2\2\u00c6\u00c7\7y\2"+ + "\2\u00c7\60\3\2\2\2\u00c8\u00c9\7t\2\2\u00c9\u00ca\7g\2\2\u00ca\u00cb"+ + "\7c\2\2\u00cb\u00cc\7f\2\2\u00cc\62\3\2\2\2\u00cd\u00ce\7v\2\2\u00ce\u00cf"+ + "\7j\2\2\u00cf\u00d0\7k\2\2\u00d0\u00d1\7u\2\2\u00d1\64\3\2\2\2\u00d2\u00d3"+ + "\7-\2\2\u00d3\66\3\2\2\2\u00d4\u00d5\7/\2\2\u00d58\3\2\2\2\u00d6\u00d7"+ + "\7#\2\2\u00d7:\3\2\2\2\u00d8\u00d9\7,\2\2\u00d9<\3\2\2\2\u00da\u00db\7"+ + "\61\2\2\u00db>\3\2\2\2\u00dc\u00dd\7\'\2\2\u00dd@\3\2\2\2\u00de\u00df"+ + "\7>\2\2\u00dfB\3\2\2\2\u00e0\u00e1\7@\2\2\u00e1D\3\2\2\2\u00e2\u00e3\7"+ + ">\2\2\u00e3\u00e4\7?\2\2\u00e4F\3\2\2\2\u00e5\u00e6\7@\2\2\u00e6\u00e7"+ + "\7?\2\2\u00e7H\3\2\2\2\u00e8\u00e9\7?\2\2\u00e9\u00ea\7?\2\2\u00eaJ\3"+ + "\2\2\2\u00eb\u00ec\7#\2\2\u00ec\u00ed\7?\2\2\u00edL\3\2\2\2\u00ee\u00ef"+ + "\7(\2\2\u00ef\u00f0\7(\2\2\u00f0N\3\2\2\2\u00f1\u00f2\7~\2\2\u00f2\u00f3"+ + "\7~\2\2\u00f3P\3\2\2\2\u00f4\u00f5\t\2\2\2\u00f5R\3\2\2\2\u00f6\u00f7"+ + "\4\62;\2\u00f7T\3\2\2\2\u00f8\u00fb\5S*\2\u00f9\u00fb\t\3\2\2\u00fa\u00f8"+ + "\3\2\2\2\u00fa\u00f9\3\2\2\2\u00fbV\3\2\2\2\u00fc\u0105\7\62\2\2\u00fd"+ + "\u0101\4\63;\2\u00fe\u0100\5S*\2\u00ff\u00fe\3\2\2\2\u0100\u0103\3\2\2"+ + "\2\u0101\u00ff\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0105\3\2\2\2\u0103\u0101"+ + "\3\2\2\2\u0104\u00fc\3\2\2\2\u0104\u00fd\3\2\2\2\u0105X\3\2\2\2\u0106"+ + "\u0107\7\62\2\2\u0107\u010b\7z\2\2\u0108\u0109\7\62\2\2\u0109\u010b\7"+ + "Z\2\2\u010a\u0106\3\2\2\2\u010a\u0108\3\2\2\2\u010b\u010d\3\2\2\2\u010c"+ + "\u010e\5U+\2\u010d\u010c\3\2\2\2\u010e\u010f\3\2\2\2\u010f\u010d\3\2\2"+ + "\2\u010f\u0110\3\2\2\2\u0110Z\3\2\2\2\u0111\u0114\5W,\2\u0112\u0114\5"+ + "Y-\2\u0113\u0111\3\2\2\2\u0113\u0112\3\2\2\2\u0114\\\3\2\2\2\u0115\u0116"+ + "\7h\2\2\u0116\u0117\7c\2\2\u0117\u0118\7n\2\2\u0118\u0119\7u\2\2\u0119"+ + "\u011f\7g\2\2\u011a\u011b\7v\2\2\u011b\u011c\7t\2\2\u011c\u011d\7w\2\2"+ + "\u011d\u011f\7g\2\2\u011e\u0115\3\2\2\2\u011e\u011a\3\2\2\2\u011f^\3\2"+ + "\2\2\u0120\u0125\5Q)\2\u0121\u0124\5Q)\2\u0122\u0124\5S*\2\u0123\u0121"+ + "\3\2\2\2\u0123\u0122\3\2\2\2\u0124\u0127\3\2\2\2\u0125\u0123\3\2\2\2\u0125"+ + "\u0126\3\2\2\2\u0126`\3\2\2\2\u0127\u0125\3\2\2\2\u0128\u0129\7\61\2\2"+ + "\u0129\u012a\7,\2\2\u012a\u012e\3\2\2\2\u012b\u012d\13\2\2\2\u012c\u012b"+ + "\3\2\2\2\u012d\u0130\3\2\2\2\u012e\u012f\3\2\2\2\u012e\u012c\3\2\2\2\u012f"+ + "\u0131\3\2\2\2\u0130\u012e\3\2\2\2\u0131\u0132\7,\2\2\u0132\u0133\7\61"+ + "\2\2\u0133\u0134\3\2\2\2\u0134\u0135\b\61\2\2\u0135b\3\2\2\2\u0136\u0137"+ + "\7\61\2\2\u0137\u0138\7\61\2\2\u0138\u013c\3\2\2\2\u0139\u013b\n\4\2\2"+ + "\u013a\u0139\3\2\2\2\u013b\u013e\3\2\2\2\u013c\u013a\3\2\2\2\u013c\u013d"+ + "\3\2\2\2\u013d\u013f\3\2\2\2\u013e\u013c\3\2\2\2\u013f\u0140\b\62\2\2"+ + "\u0140d\3\2\2\2\u0141\u0142\t\5\2\2\u0142\u0143\3\2\2\2\u0143\u0144\b"+ + "\63\2\2\u0144f\3\2\2\2\u0145\u0146\13\2\2\2\u0146h\3\2\2\2\16\2\u00fa"+ + "\u0101\u0104\u010a\u010f\u0113\u011e\u0123\u0125\u012e\u013c\3\b\2\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/src/cd/frontend/parser/JavaliLexer.tokens b/src/cd/frontend/parser/JavaliLexer.tokens new file mode 100644 index 0000000..0bd9b31 --- /dev/null +++ b/src/cd/frontend/parser/JavaliLexer.tokens @@ -0,0 +1,85 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +T__38=39 +Integer=40 +Boolean=41 +Ident=42 +COMMENT=43 +LINE_COMMENT=44 +WS=45 +ErrorCharacter=46 +'null'=1 +'['=2 +']'=3 +'boolean'=4 +'int'=5 +'class'=6 +'extends'=7 +'{'=8 +'}'=9 +','=10 +';'=11 +'void'=12 +'('=13 +')'=14 +'.'=15 +'='=16 +'write'=17 +'writeln'=18 +'if'=19 +'else'=20 +'while'=21 +'return'=22 +'new'=23 +'read'=24 +'this'=25 +'+'=26 +'-'=27 +'!'=28 +'*'=29 +'/'=30 +'%'=31 +'<'=32 +'>'=33 +'<='=34 +'>='=35 +'=='=36 +'!='=37 +'&&'=38 +'||'=39 diff --git a/src/cd/frontend/parser/JavaliParser.java b/src/cd/frontend/parser/JavaliParser.java new file mode 100644 index 0000000..a79d41b --- /dev/null +++ b/src/cd/frontend/parser/JavaliParser.java @@ -0,0 +1,2315 @@ +// Generated from /home/carlos/eth/cd/nop90/HW2/src/cd/frontend/parser/Javali.g4 by ANTLR 4.7.1 + + // Java header + package cd.frontend.parser; + +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class JavaliParser extends Parser { + static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, + T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, + T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, + T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, + T__38=39, Integer=40, Boolean=41, Ident=42, COMMENT=43, LINE_COMMENT=44, + WS=45, ErrorCharacter=46; + public static final int + RULE_literal = 0, RULE_type = 1, RULE_referenceType = 2, RULE_arrayType = 3, + RULE_primitiveType = 4, RULE_unit = 5, RULE_classDecl = 6, RULE_memberList = 7, + RULE_varDecl = 8, RULE_methodDecl = 9, RULE_formalParamList = 10, RULE_stmt = 11, + RULE_stmtBlock = 12, RULE_methodCallStmt = 13, RULE_assignmentStmt = 14, + RULE_writeStmt = 15, RULE_ifStmt = 16, RULE_whileStmt = 17, RULE_returnStmt = 18, + RULE_newExpr = 19, RULE_readExpr = 20, RULE_actualParamList = 21, RULE_identAccess = 22, + RULE_expr = 23; + public static final String[] ruleNames = { + "literal", "type", "referenceType", "arrayType", "primitiveType", "unit", + "classDecl", "memberList", "varDecl", "methodDecl", "formalParamList", + "stmt", "stmtBlock", "methodCallStmt", "assignmentStmt", "writeStmt", + "ifStmt", "whileStmt", "returnStmt", "newExpr", "readExpr", "actualParamList", + "identAccess", "expr" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'null'", "'['", "']'", "'boolean'", "'int'", "'class'", "'extends'", + "'{'", "'}'", "','", "';'", "'void'", "'('", "')'", "'.'", "'='", "'write'", + "'writeln'", "'if'", "'else'", "'while'", "'return'", "'new'", "'read'", + "'this'", "'+'", "'-'", "'!'", "'*'", "'/'", "'%'", "'<'", "'>'", "'<='", + "'>='", "'=='", "'!='", "'&&'", "'||'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, "Integer", "Boolean", "Ident", "COMMENT", "LINE_COMMENT", + "WS", "ErrorCharacter" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "Javali.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public JavaliParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + public static class LiteralContext extends ParserRuleContext { + public LiteralContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_literal; } + + public LiteralContext() { } + public void copyFrom(LiteralContext ctx) { + super.copyFrom(ctx); + } + } + public static class BoolLiteralContext extends LiteralContext { + public TerminalNode Boolean() { return getToken(JavaliParser.Boolean, 0); } + public BoolLiteralContext(LiteralContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitBoolLiteral(this); + else return visitor.visitChildren(this); + } + } + public static class IntLiteralContext extends LiteralContext { + public TerminalNode Integer() { return getToken(JavaliParser.Integer, 0); } + public IntLiteralContext(LiteralContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitIntLiteral(this); + else return visitor.visitChildren(this); + } + } + public static class NullLiteralContext extends LiteralContext { + public NullLiteralContext(LiteralContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitNullLiteral(this); + else return visitor.visitChildren(this); + } + } + + public final LiteralContext literal() throws RecognitionException { + LiteralContext _localctx = new LiteralContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_literal); + try { + setState(51); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__0: + _localctx = new NullLiteralContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(48); + match(T__0); + } + break; + case Boolean: + _localctx = new BoolLiteralContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(49); + match(Boolean); + } + break; + case Integer: + _localctx = new IntLiteralContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(50); + match(Integer); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeContext extends ParserRuleContext { + public PrimitiveTypeContext primitiveType() { + return getRuleContext(PrimitiveTypeContext.class,0); + } + public ReferenceTypeContext referenceType() { + return getRuleContext(ReferenceTypeContext.class,0); + } + public TypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_type; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitType(this); + else return visitor.visitChildren(this); + } + } + + public final TypeContext type() throws RecognitionException { + TypeContext _localctx = new TypeContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_type); + try { + setState(55); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(53); + primitiveType(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(54); + referenceType(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReferenceTypeContext extends ParserRuleContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ArrayTypeContext arrayType() { + return getRuleContext(ArrayTypeContext.class,0); + } + public ReferenceTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_referenceType; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitReferenceType(this); + else return visitor.visitChildren(this); + } + } + + public final ReferenceTypeContext referenceType() throws RecognitionException { + ReferenceTypeContext _localctx = new ReferenceTypeContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_referenceType); + try { + setState(59); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(57); + match(Ident); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(58); + arrayType(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ArrayTypeContext extends ParserRuleContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public PrimitiveTypeContext primitiveType() { + return getRuleContext(PrimitiveTypeContext.class,0); + } + public ArrayTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_arrayType; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitArrayType(this); + else return visitor.visitChildren(this); + } + } + + public final ArrayTypeContext arrayType() throws RecognitionException { + ArrayTypeContext _localctx = new ArrayTypeContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_arrayType); + try { + setState(68); + _errHandler.sync(this); + switch (_input.LA(1)) { + case Ident: + enterOuterAlt(_localctx, 1); + { + setState(61); + match(Ident); + setState(62); + match(T__1); + setState(63); + match(T__2); + } + break; + case T__3: + case T__4: + enterOuterAlt(_localctx, 2); + { + setState(64); + primitiveType(); + setState(65); + match(T__1); + setState(66); + match(T__2); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class PrimitiveTypeContext extends ParserRuleContext { + public PrimitiveTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_primitiveType; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitPrimitiveType(this); + else return visitor.visitChildren(this); + } + } + + public final PrimitiveTypeContext primitiveType() throws RecognitionException { + PrimitiveTypeContext _localctx = new PrimitiveTypeContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_primitiveType); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(70); + _la = _input.LA(1); + if ( !(_la==T__3 || _la==T__4) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class UnitContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(JavaliParser.EOF, 0); } + public List classDecl() { + return getRuleContexts(ClassDeclContext.class); + } + public ClassDeclContext classDecl(int i) { + return getRuleContext(ClassDeclContext.class,i); + } + public UnitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_unit; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitUnit(this); + else return visitor.visitChildren(this); + } + } + + public final UnitContext unit() throws RecognitionException { + UnitContext _localctx = new UnitContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_unit); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(73); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(72); + classDecl(); + } + } + setState(75); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==T__5 ); + setState(77); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ClassDeclContext extends ParserRuleContext { + public List Ident() { return getTokens(JavaliParser.Ident); } + public TerminalNode Ident(int i) { + return getToken(JavaliParser.Ident, i); + } + public MemberListContext memberList() { + return getRuleContext(MemberListContext.class,0); + } + public ClassDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_classDecl; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitClassDecl(this); + else return visitor.visitChildren(this); + } + } + + public final ClassDeclContext classDecl() throws RecognitionException { + ClassDeclContext _localctx = new ClassDeclContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_classDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(79); + match(T__5); + setState(80); + match(Ident); + setState(83); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__6) { + { + setState(81); + match(T__6); + setState(82); + match(Ident); + } + } + + setState(85); + match(T__7); + setState(86); + memberList(); + setState(87); + match(T__8); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MemberListContext extends ParserRuleContext { + public List varDecl() { + return getRuleContexts(VarDeclContext.class); + } + public VarDeclContext varDecl(int i) { + return getRuleContext(VarDeclContext.class,i); + } + public List methodDecl() { + return getRuleContexts(MethodDeclContext.class); + } + public MethodDeclContext methodDecl(int i) { + return getRuleContext(MethodDeclContext.class,i); + } + public MemberListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_memberList; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitMemberList(this); + else return visitor.visitChildren(this); + } + } + + public final MemberListContext memberList() throws RecognitionException { + MemberListContext _localctx = new MemberListContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_memberList); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(93); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__4) | (1L << T__11) | (1L << Ident))) != 0)) { + { + setState(91); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + { + setState(89); + varDecl(); + } + break; + case 2: + { + setState(90); + methodDecl(); + } + break; + } + } + setState(95); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class VarDeclContext extends ParserRuleContext { + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public List Ident() { return getTokens(JavaliParser.Ident); } + public TerminalNode Ident(int i) { + return getToken(JavaliParser.Ident, i); + } + public VarDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_varDecl; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitVarDecl(this); + else return visitor.visitChildren(this); + } + } + + public final VarDeclContext varDecl() throws RecognitionException { + VarDeclContext _localctx = new VarDeclContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_varDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(96); + type(); + setState(97); + match(Ident); + setState(102); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__9) { + { + { + setState(98); + match(T__9); + setState(99); + match(Ident); + } + } + setState(104); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(105); + match(T__10); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MethodDeclContext extends ParserRuleContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public FormalParamListContext formalParamList() { + return getRuleContext(FormalParamListContext.class,0); + } + public List varDecl() { + return getRuleContexts(VarDeclContext.class); + } + public VarDeclContext varDecl(int i) { + return getRuleContext(VarDeclContext.class,i); + } + public List stmt() { + return getRuleContexts(StmtContext.class); + } + public StmtContext stmt(int i) { + return getRuleContext(StmtContext.class,i); + } + public MethodDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_methodDecl; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitMethodDecl(this); + else return visitor.visitChildren(this); + } + } + + public final MethodDeclContext methodDecl() throws RecognitionException { + MethodDeclContext _localctx = new MethodDeclContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_methodDecl); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(109); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__3: + case T__4: + case Ident: + { + setState(107); + type(); + } + break; + case T__11: + { + setState(108); + match(T__11); + } + break; + default: + throw new NoViableAltException(this); + } + setState(111); + match(Ident); + setState(112); + match(T__12); + setState(114); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__4) | (1L << Ident))) != 0)) { + { + setState(113); + formalParamList(); + } + } + + setState(116); + match(T__13); + setState(117); + match(T__7); + setState(121); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(118); + varDecl(); + } + } + } + setState(123); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + } + setState(127); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__20) | (1L << T__21) | (1L << T__24) | (1L << Ident))) != 0)) { + { + { + setState(124); + stmt(); + } + } + setState(129); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(130); + match(T__8); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FormalParamListContext extends ParserRuleContext { + public List type() { + return getRuleContexts(TypeContext.class); + } + public TypeContext type(int i) { + return getRuleContext(TypeContext.class,i); + } + public List Ident() { return getTokens(JavaliParser.Ident); } + public TerminalNode Ident(int i) { + return getToken(JavaliParser.Ident, i); + } + public FormalParamListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_formalParamList; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitFormalParamList(this); + else return visitor.visitChildren(this); + } + } + + public final FormalParamListContext formalParamList() throws RecognitionException { + FormalParamListContext _localctx = new FormalParamListContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_formalParamList); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(132); + type(); + setState(133); + match(Ident); + setState(140); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__9) { + { + { + setState(134); + match(T__9); + setState(135); + type(); + setState(136); + match(Ident); + } + } + setState(142); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StmtContext extends ParserRuleContext { + public AssignmentStmtContext assignmentStmt() { + return getRuleContext(AssignmentStmtContext.class,0); + } + public MethodCallStmtContext methodCallStmt() { + return getRuleContext(MethodCallStmtContext.class,0); + } + public IfStmtContext ifStmt() { + return getRuleContext(IfStmtContext.class,0); + } + public WhileStmtContext whileStmt() { + return getRuleContext(WhileStmtContext.class,0); + } + public ReturnStmtContext returnStmt() { + return getRuleContext(ReturnStmtContext.class,0); + } + public WriteStmtContext writeStmt() { + return getRuleContext(WriteStmtContext.class,0); + } + public StmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stmt; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitStmt(this); + else return visitor.visitChildren(this); + } + } + + public final StmtContext stmt() throws RecognitionException { + StmtContext _localctx = new StmtContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_stmt); + try { + setState(149); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(143); + assignmentStmt(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(144); + methodCallStmt(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(145); + ifStmt(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(146); + whileStmt(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(147); + returnStmt(); + } + break; + case 6: + enterOuterAlt(_localctx, 6); + { + setState(148); + writeStmt(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StmtBlockContext extends ParserRuleContext { + public List stmt() { + return getRuleContexts(StmtContext.class); + } + public StmtContext stmt(int i) { + return getRuleContext(StmtContext.class,i); + } + public StmtBlockContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stmtBlock; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitStmtBlock(this); + else return visitor.visitChildren(this); + } + } + + public final StmtBlockContext stmtBlock() throws RecognitionException { + StmtBlockContext _localctx = new StmtBlockContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_stmtBlock); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(151); + match(T__7); + setState(155); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__20) | (1L << T__21) | (1L << T__24) | (1L << Ident))) != 0)) { + { + { + setState(152); + stmt(); + } + } + setState(157); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(158); + match(T__8); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MethodCallStmtContext extends ParserRuleContext { + public MethodCallStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_methodCallStmt; } + + public MethodCallStmtContext() { } + public void copyFrom(MethodCallStmtContext ctx) { + super.copyFrom(ctx); + } + } + public static class ObjectMethodCallStmtContext extends MethodCallStmtContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ActualParamListContext actualParamList() { + return getRuleContext(ActualParamListContext.class,0); + } + public ObjectMethodCallStmtContext(MethodCallStmtContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitObjectMethodCallStmt(this); + else return visitor.visitChildren(this); + } + } + public static class LocalMethodCallStmtContext extends MethodCallStmtContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ActualParamListContext actualParamList() { + return getRuleContext(ActualParamListContext.class,0); + } + public LocalMethodCallStmtContext(MethodCallStmtContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitLocalMethodCallStmt(this); + else return visitor.visitChildren(this); + } + } + + public final MethodCallStmtContext methodCallStmt() throws RecognitionException { + MethodCallStmtContext _localctx = new MethodCallStmtContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_methodCallStmt); + int _la; + try { + setState(177); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { + case 1: + _localctx = new LocalMethodCallStmtContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(160); + match(Ident); + setState(161); + match(T__12); + setState(163); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__12) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << Integer) | (1L << Boolean) | (1L << Ident))) != 0)) { + { + setState(162); + actualParamList(); + } + } + + setState(165); + match(T__13); + setState(166); + match(T__10); + } + break; + case 2: + _localctx = new ObjectMethodCallStmtContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(167); + identAccess(0); + setState(168); + match(T__14); + setState(169); + match(Ident); + setState(170); + match(T__12); + setState(172); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__12) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << Integer) | (1L << Boolean) | (1L << Ident))) != 0)) { + { + setState(171); + actualParamList(); + } + } + + setState(174); + match(T__13); + setState(175); + match(T__10); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AssignmentStmtContext extends ParserRuleContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public NewExprContext newExpr() { + return getRuleContext(NewExprContext.class,0); + } + public ReadExprContext readExpr() { + return getRuleContext(ReadExprContext.class,0); + } + public AssignmentStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_assignmentStmt; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAssignmentStmt(this); + else return visitor.visitChildren(this); + } + } + + public final AssignmentStmtContext assignmentStmt() throws RecognitionException { + AssignmentStmtContext _localctx = new AssignmentStmtContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_assignmentStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(179); + identAccess(0); + setState(180); + match(T__15); + setState(184); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__0: + case T__12: + case T__24: + case T__25: + case T__26: + case T__27: + case Integer: + case Boolean: + case Ident: + { + setState(181); + expr(0); + } + break; + case T__22: + { + setState(182); + newExpr(); + } + break; + case T__23: + { + setState(183); + readExpr(); + } + break; + default: + throw new NoViableAltException(this); + } + setState(186); + match(T__10); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class WriteStmtContext extends ParserRuleContext { + public WriteStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_writeStmt; } + + public WriteStmtContext() { } + public void copyFrom(WriteStmtContext ctx) { + super.copyFrom(ctx); + } + } + public static class WriteContext extends WriteStmtContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public WriteContext(WriteStmtContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitWrite(this); + else return visitor.visitChildren(this); + } + } + public static class WriteLnContext extends WriteStmtContext { + public WriteLnContext(WriteStmtContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitWriteLn(this); + else return visitor.visitChildren(this); + } + } + + public final WriteStmtContext writeStmt() throws RecognitionException { + WriteStmtContext _localctx = new WriteStmtContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_writeStmt); + try { + setState(198); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__16: + _localctx = new WriteContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(188); + match(T__16); + setState(189); + match(T__12); + setState(190); + expr(0); + setState(191); + match(T__13); + setState(192); + match(T__10); + } + break; + case T__17: + _localctx = new WriteLnContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(194); + match(T__17); + setState(195); + match(T__12); + setState(196); + match(T__13); + setState(197); + match(T__10); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IfStmtContext extends ParserRuleContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public List stmtBlock() { + return getRuleContexts(StmtBlockContext.class); + } + public StmtBlockContext stmtBlock(int i) { + return getRuleContext(StmtBlockContext.class,i); + } + public IfStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ifStmt; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitIfStmt(this); + else return visitor.visitChildren(this); + } + } + + public final IfStmtContext ifStmt() throws RecognitionException { + IfStmtContext _localctx = new IfStmtContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_ifStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(200); + match(T__18); + setState(201); + match(T__12); + setState(202); + expr(0); + setState(203); + match(T__13); + setState(204); + stmtBlock(); + setState(207); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__19) { + { + setState(205); + match(T__19); + setState(206); + stmtBlock(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class WhileStmtContext extends ParserRuleContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public StmtBlockContext stmtBlock() { + return getRuleContext(StmtBlockContext.class,0); + } + public WhileStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whileStmt; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitWhileStmt(this); + else return visitor.visitChildren(this); + } + } + + public final WhileStmtContext whileStmt() throws RecognitionException { + WhileStmtContext _localctx = new WhileStmtContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_whileStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(209); + match(T__20); + setState(210); + match(T__12); + setState(211); + expr(0); + setState(212); + match(T__13); + setState(213); + stmtBlock(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReturnStmtContext extends ParserRuleContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public ReturnStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_returnStmt; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitReturnStmt(this); + else return visitor.visitChildren(this); + } + } + + public final ReturnStmtContext returnStmt() throws RecognitionException { + ReturnStmtContext _localctx = new ReturnStmtContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_returnStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(215); + match(T__21); + setState(217); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__12) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << Integer) | (1L << Boolean) | (1L << Ident))) != 0)) { + { + setState(216); + expr(0); + } + } + + setState(219); + match(T__10); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class NewExprContext extends ParserRuleContext { + public NewExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_newExpr; } + + public NewExprContext() { } + public void copyFrom(NewExprContext ctx) { + super.copyFrom(ctx); + } + } + public static class NewObjectArrayContext extends NewExprContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public NewObjectArrayContext(NewExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitNewObjectArray(this); + else return visitor.visitChildren(this); + } + } + public static class NewPrimitiveArrayContext extends NewExprContext { + public PrimitiveTypeContext primitiveType() { + return getRuleContext(PrimitiveTypeContext.class,0); + } + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public NewPrimitiveArrayContext(NewExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitNewPrimitiveArray(this); + else return visitor.visitChildren(this); + } + } + public static class NewObjectContext extends NewExprContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public NewObjectContext(NewExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitNewObject(this); + else return visitor.visitChildren(this); + } + } + + public final NewExprContext newExpr() throws RecognitionException { + NewExprContext _localctx = new NewExprContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_newExpr); + try { + setState(237); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) { + case 1: + _localctx = new NewObjectContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(221); + match(T__22); + setState(222); + match(Ident); + setState(223); + match(T__12); + setState(224); + match(T__13); + } + break; + case 2: + _localctx = new NewObjectArrayContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(225); + match(T__22); + setState(226); + match(Ident); + setState(227); + match(T__1); + setState(228); + expr(0); + setState(229); + match(T__2); + } + break; + case 3: + _localctx = new NewPrimitiveArrayContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(231); + match(T__22); + setState(232); + primitiveType(); + setState(233); + match(T__1); + setState(234); + expr(0); + setState(235); + match(T__2); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReadExprContext extends ParserRuleContext { + public ReadExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_readExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitReadExpr(this); + else return visitor.visitChildren(this); + } + } + + public final ReadExprContext readExpr() throws RecognitionException { + ReadExprContext _localctx = new ReadExprContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_readExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(239); + match(T__23); + setState(240); + match(T__12); + setState(241); + match(T__13); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ActualParamListContext extends ParserRuleContext { + public List expr() { + return getRuleContexts(ExprContext.class); + } + public ExprContext expr(int i) { + return getRuleContext(ExprContext.class,i); + } + public ActualParamListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_actualParamList; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitActualParamList(this); + else return visitor.visitChildren(this); + } + } + + public final ActualParamListContext actualParamList() throws RecognitionException { + ActualParamListContext _localctx = new ActualParamListContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_actualParamList); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(243); + expr(0); + setState(248); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__9) { + { + { + setState(244); + match(T__9); + setState(245); + expr(0); + } + } + setState(250); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IdentAccessContext extends ParserRuleContext { + public IdentAccessContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_identAccess; } + + public IdentAccessContext() { } + public void copyFrom(IdentAccessContext ctx) { + super.copyFrom(ctx); + } + } + public static class AccessThisContext extends IdentAccessContext { + public AccessThisContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessThis(this); + else return visitor.visitChildren(this); + } + } + public static class AccessLocalFieldContext extends IdentAccessContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public AccessLocalFieldContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessLocalField(this); + else return visitor.visitChildren(this); + } + } + public static class AccessObjectFieldContext extends IdentAccessContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public AccessObjectFieldContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessObjectField(this); + else return visitor.visitChildren(this); + } + } + public static class AccessLocalMethodContext extends IdentAccessContext { + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ActualParamListContext actualParamList() { + return getRuleContext(ActualParamListContext.class,0); + } + public AccessLocalMethodContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessLocalMethod(this); + else return visitor.visitChildren(this); + } + } + public static class AccessArrayContext extends IdentAccessContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public AccessArrayContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessArray(this); + else return visitor.visitChildren(this); + } + } + public static class AccessObjectMethodContext extends IdentAccessContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public TerminalNode Ident() { return getToken(JavaliParser.Ident, 0); } + public ActualParamListContext actualParamList() { + return getRuleContext(ActualParamListContext.class,0); + } + public AccessObjectMethodContext(IdentAccessContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitAccessObjectMethod(this); + else return visitor.visitChildren(this); + } + } + + public final IdentAccessContext identAccess() throws RecognitionException { + return identAccess(0); + } + + private IdentAccessContext identAccess(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + IdentAccessContext _localctx = new IdentAccessContext(_ctx, _parentState); + IdentAccessContext _prevctx = _localctx; + int _startState = 44; + enterRecursionRule(_localctx, 44, RULE_identAccess, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(260); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { + case 1: + { + _localctx = new AccessLocalFieldContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(252); + match(Ident); + } + break; + case 2: + { + _localctx = new AccessThisContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(253); + match(T__24); + } + break; + case 3: + { + _localctx = new AccessLocalMethodContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(254); + match(Ident); + setState(255); + match(T__12); + setState(257); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__12) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << Integer) | (1L << Boolean) | (1L << Ident))) != 0)) { + { + setState(256); + actualParamList(); + } + } + + setState(259); + match(T__13); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(280); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,29,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(278); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { + case 1: + { + _localctx = new AccessObjectFieldContext(new IdentAccessContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_identAccess); + setState(262); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(263); + match(T__14); + setState(264); + match(Ident); + } + break; + case 2: + { + _localctx = new AccessArrayContext(new IdentAccessContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_identAccess); + setState(265); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(266); + match(T__1); + setState(267); + expr(0); + setState(268); + match(T__2); + } + break; + case 3: + { + _localctx = new AccessObjectMethodContext(new IdentAccessContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_identAccess); + setState(270); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(271); + match(T__14); + setState(272); + match(Ident); + setState(273); + match(T__12); + setState(275); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__12) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << Integer) | (1L << Boolean) | (1L << Ident))) != 0)) { + { + setState(274); + actualParamList(); + } + } + + setState(277); + match(T__13); + } + break; + } + } + } + setState(282); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,29,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public static class ExprContext extends ParserRuleContext { + public ExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expr; } + + public ExprContext() { } + public void copyFrom(ExprContext ctx) { + super.copyFrom(ctx); + } + } + public static class ExprBinaryContext extends ExprContext { + public List expr() { + return getRuleContexts(ExprContext.class); + } + public ExprContext expr(int i) { + return getRuleContext(ExprContext.class,i); + } + public ExprBinaryContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprBinary(this); + else return visitor.visitChildren(this); + } + } + public static class ExprCastContext extends ExprContext { + public ReferenceTypeContext referenceType() { + return getRuleContext(ReferenceTypeContext.class,0); + } + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public ExprCastContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprCast(this); + else return visitor.visitChildren(this); + } + } + public static class ExprParenthesesContext extends ExprContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public ExprParenthesesContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprParentheses(this); + else return visitor.visitChildren(this); + } + } + public static class ExprUnaryContext extends ExprContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public ExprUnaryContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprUnary(this); + else return visitor.visitChildren(this); + } + } + public static class ExprConstantContext extends ExprContext { + public LiteralContext literal() { + return getRuleContext(LiteralContext.class,0); + } + public ExprConstantContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprConstant(this); + else return visitor.visitChildren(this); + } + } + public static class ExprIdentAccessContext extends ExprContext { + public IdentAccessContext identAccess() { + return getRuleContext(IdentAccessContext.class,0); + } + public ExprIdentAccessContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JavaliVisitor ) return ((JavaliVisitor)visitor).visitExprIdentAccess(this); + else return visitor.visitChildren(this); + } + } + + public final ExprContext expr() throws RecognitionException { + return expr(0); + } + + private ExprContext expr(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + ExprContext _localctx = new ExprContext(_ctx, _parentState); + ExprContext _prevctx = _localctx; + int _startState = 46; + enterRecursionRule(_localctx, 46, RULE_expr, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(297); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) { + case 1: + { + _localctx = new ExprConstantContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(284); + literal(); + } + break; + case 2: + { + _localctx = new ExprIdentAccessContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(285); + identAccess(0); + } + break; + case 3: + { + _localctx = new ExprParenthesesContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(286); + match(T__12); + setState(287); + expr(0); + setState(288); + match(T__13); + } + break; + case 4: + { + _localctx = new ExprUnaryContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(290); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__25) | (1L << T__26) | (1L << T__27))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(291); + expr(8); + } + break; + case 5: + { + _localctx = new ExprCastContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(292); + match(T__12); + setState(293); + referenceType(); + setState(294); + match(T__13); + setState(295); + expr(7); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(319); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,32,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(317); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { + case 1: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(299); + if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); + setState(300); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__28) | (1L << T__29) | (1L << T__30))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(301); + expr(7); + } + break; + case 2: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(302); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(303); + _la = _input.LA(1); + if ( !(_la==T__25 || _la==T__26) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(304); + expr(6); + } + break; + case 3: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(305); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(306); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__31) | (1L << T__32) | (1L << T__33) | (1L << T__34))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(307); + expr(5); + } + break; + case 4: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(308); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(309); + _la = _input.LA(1); + if ( !(_la==T__35 || _la==T__36) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(310); + expr(4); + } + break; + case 5: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(311); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(312); + match(T__37); + setState(313); + expr(3); + } + break; + case 6: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(314); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(315); + match(T__38); + setState(316); + expr(2); + } + break; + } + } + } + setState(321); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,32,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 22: + return identAccess_sempred((IdentAccessContext)_localctx, predIndex); + case 23: + return expr_sempred((ExprContext)_localctx, predIndex); + } + return true; + } + private boolean identAccess_sempred(IdentAccessContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 4); + case 1: + return precpred(_ctx, 3); + case 2: + return precpred(_ctx, 1); + } + return true; + } + private boolean expr_sempred(ExprContext _localctx, int predIndex) { + switch (predIndex) { + case 3: + return precpred(_ctx, 6); + case 4: + return precpred(_ctx, 5); + case 5: + return precpred(_ctx, 4); + case 6: + return precpred(_ctx, 3); + case 7: + return precpred(_ctx, 2); + case 8: + return precpred(_ctx, 1); + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\60\u0145\4\2\t\2"+ + "\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\3\2\3\2\3\2\5\2\66\n\2\3\3\3\3\5\3:\n\3\3\4\3\4\5\4>\n\4\3\5\3\5\3\5"+ + "\3\5\3\5\3\5\3\5\5\5G\n\5\3\6\3\6\3\7\6\7L\n\7\r\7\16\7M\3\7\3\7\3\b\3"+ + "\b\3\b\3\b\5\bV\n\b\3\b\3\b\3\b\3\b\3\t\3\t\7\t^\n\t\f\t\16\ta\13\t\3"+ + "\n\3\n\3\n\3\n\7\ng\n\n\f\n\16\nj\13\n\3\n\3\n\3\13\3\13\5\13p\n\13\3"+ + "\13\3\13\3\13\5\13u\n\13\3\13\3\13\3\13\7\13z\n\13\f\13\16\13}\13\13\3"+ + "\13\7\13\u0080\n\13\f\13\16\13\u0083\13\13\3\13\3\13\3\f\3\f\3\f\3\f\3"+ + "\f\3\f\7\f\u008d\n\f\f\f\16\f\u0090\13\f\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u0098"+ + "\n\r\3\16\3\16\7\16\u009c\n\16\f\16\16\16\u009f\13\16\3\16\3\16\3\17\3"+ + "\17\3\17\5\17\u00a6\n\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u00af"+ + "\n\17\3\17\3\17\3\17\5\17\u00b4\n\17\3\20\3\20\3\20\3\20\3\20\5\20\u00bb"+ + "\n\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21"+ + "\u00c9\n\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\5\22\u00d2\n\22\3\23\3"+ + "\23\3\23\3\23\3\23\3\23\3\24\3\24\5\24\u00dc\n\24\3\24\3\24\3\25\3\25"+ + "\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25"+ + "\5\25\u00f0\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\7\27\u00f9\n\27\f"+ + "\27\16\27\u00fc\13\27\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u0104\n\30\3"+ + "\30\5\30\u0107\n\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ + "\3\30\3\30\3\30\5\30\u0116\n\30\3\30\7\30\u0119\n\30\f\30\16\30\u011c"+ + "\13\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\5\31\u012c\n\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\7\31\u0140\n\31\f\31\16\31\u0143"+ + "\13\31\3\31\2\4.\60\32\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,"+ + ".\60\2\b\3\2\6\7\3\2\34\36\3\2\37!\3\2\34\35\3\2\"%\3\2&\'\2\u015d\2\65"+ + "\3\2\2\2\49\3\2\2\2\6=\3\2\2\2\bF\3\2\2\2\nH\3\2\2\2\fK\3\2\2\2\16Q\3"+ + "\2\2\2\20_\3\2\2\2\22b\3\2\2\2\24o\3\2\2\2\26\u0086\3\2\2\2\30\u0097\3"+ + "\2\2\2\32\u0099\3\2\2\2\34\u00b3\3\2\2\2\36\u00b5\3\2\2\2 \u00c8\3\2\2"+ + "\2\"\u00ca\3\2\2\2$\u00d3\3\2\2\2&\u00d9\3\2\2\2(\u00ef\3\2\2\2*\u00f1"+ + "\3\2\2\2,\u00f5\3\2\2\2.\u0106\3\2\2\2\60\u012b\3\2\2\2\62\66\7\3\2\2"+ + "\63\66\7+\2\2\64\66\7*\2\2\65\62\3\2\2\2\65\63\3\2\2\2\65\64\3\2\2\2\66"+ + "\3\3\2\2\2\67:\5\n\6\28:\5\6\4\29\67\3\2\2\298\3\2\2\2:\5\3\2\2\2;>\7"+ + ",\2\2<>\5\b\5\2=;\3\2\2\2=<\3\2\2\2>\7\3\2\2\2?@\7,\2\2@A\7\4\2\2AG\7"+ + "\5\2\2BC\5\n\6\2CD\7\4\2\2DE\7\5\2\2EG\3\2\2\2F?\3\2\2\2FB\3\2\2\2G\t"+ + "\3\2\2\2HI\t\2\2\2I\13\3\2\2\2JL\5\16\b\2KJ\3\2\2\2LM\3\2\2\2MK\3\2\2"+ + "\2MN\3\2\2\2NO\3\2\2\2OP\7\2\2\3P\r\3\2\2\2QR\7\b\2\2RU\7,\2\2ST\7\t\2"+ + "\2TV\7,\2\2US\3\2\2\2UV\3\2\2\2VW\3\2\2\2WX\7\n\2\2XY\5\20\t\2YZ\7\13"+ + "\2\2Z\17\3\2\2\2[^\5\22\n\2\\^\5\24\13\2][\3\2\2\2]\\\3\2\2\2^a\3\2\2"+ + "\2_]\3\2\2\2_`\3\2\2\2`\21\3\2\2\2a_\3\2\2\2bc\5\4\3\2ch\7,\2\2de\7\f"+ + "\2\2eg\7,\2\2fd\3\2\2\2gj\3\2\2\2hf\3\2\2\2hi\3\2\2\2ik\3\2\2\2jh\3\2"+ + "\2\2kl\7\r\2\2l\23\3\2\2\2mp\5\4\3\2np\7\16\2\2om\3\2\2\2on\3\2\2\2pq"+ + "\3\2\2\2qr\7,\2\2rt\7\17\2\2su\5\26\f\2ts\3\2\2\2tu\3\2\2\2uv\3\2\2\2"+ + "vw\7\20\2\2w{\7\n\2\2xz\5\22\n\2yx\3\2\2\2z}\3\2\2\2{y\3\2\2\2{|\3\2\2"+ + "\2|\u0081\3\2\2\2}{\3\2\2\2~\u0080\5\30\r\2\177~\3\2\2\2\u0080\u0083\3"+ + "\2\2\2\u0081\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0084\3\2\2\2\u0083"+ + "\u0081\3\2\2\2\u0084\u0085\7\13\2\2\u0085\25\3\2\2\2\u0086\u0087\5\4\3"+ + "\2\u0087\u008e\7,\2\2\u0088\u0089\7\f\2\2\u0089\u008a\5\4\3\2\u008a\u008b"+ + "\7,\2\2\u008b\u008d\3\2\2\2\u008c\u0088\3\2\2\2\u008d\u0090\3\2\2\2\u008e"+ + "\u008c\3\2\2\2\u008e\u008f\3\2\2\2\u008f\27\3\2\2\2\u0090\u008e\3\2\2"+ + "\2\u0091\u0098\5\36\20\2\u0092\u0098\5\34\17\2\u0093\u0098\5\"\22\2\u0094"+ + "\u0098\5$\23\2\u0095\u0098\5&\24\2\u0096\u0098\5 \21\2\u0097\u0091\3\2"+ + "\2\2\u0097\u0092\3\2\2\2\u0097\u0093\3\2\2\2\u0097\u0094\3\2\2\2\u0097"+ + "\u0095\3\2\2\2\u0097\u0096\3\2\2\2\u0098\31\3\2\2\2\u0099\u009d\7\n\2"+ + "\2\u009a\u009c\5\30\r\2\u009b\u009a\3\2\2\2\u009c\u009f\3\2\2\2\u009d"+ + "\u009b\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u00a0\3\2\2\2\u009f\u009d\3\2"+ + "\2\2\u00a0\u00a1\7\13\2\2\u00a1\33\3\2\2\2\u00a2\u00a3\7,\2\2\u00a3\u00a5"+ + "\7\17\2\2\u00a4\u00a6\5,\27\2\u00a5\u00a4\3\2\2\2\u00a5\u00a6\3\2\2\2"+ + "\u00a6\u00a7\3\2\2\2\u00a7\u00a8\7\20\2\2\u00a8\u00b4\7\r\2\2\u00a9\u00aa"+ + "\5.\30\2\u00aa\u00ab\7\21\2\2\u00ab\u00ac\7,\2\2\u00ac\u00ae\7\17\2\2"+ + "\u00ad\u00af\5,\27\2\u00ae\u00ad\3\2\2\2\u00ae\u00af\3\2\2\2\u00af\u00b0"+ + "\3\2\2\2\u00b0\u00b1\7\20\2\2\u00b1\u00b2\7\r\2\2\u00b2\u00b4\3\2\2\2"+ + "\u00b3\u00a2\3\2\2\2\u00b3\u00a9\3\2\2\2\u00b4\35\3\2\2\2\u00b5\u00b6"+ + "\5.\30\2\u00b6\u00ba\7\22\2\2\u00b7\u00bb\5\60\31\2\u00b8\u00bb\5(\25"+ + "\2\u00b9\u00bb\5*\26\2\u00ba\u00b7\3\2\2\2\u00ba\u00b8\3\2\2\2\u00ba\u00b9"+ + "\3\2\2\2\u00bb\u00bc\3\2\2\2\u00bc\u00bd\7\r\2\2\u00bd\37\3\2\2\2\u00be"+ + "\u00bf\7\23\2\2\u00bf\u00c0\7\17\2\2\u00c0\u00c1\5\60\31\2\u00c1\u00c2"+ + "\7\20\2\2\u00c2\u00c3\7\r\2\2\u00c3\u00c9\3\2\2\2\u00c4\u00c5\7\24\2\2"+ + "\u00c5\u00c6\7\17\2\2\u00c6\u00c7\7\20\2\2\u00c7\u00c9\7\r\2\2\u00c8\u00be"+ + "\3\2\2\2\u00c8\u00c4\3\2\2\2\u00c9!\3\2\2\2\u00ca\u00cb\7\25\2\2\u00cb"+ + "\u00cc\7\17\2\2\u00cc\u00cd\5\60\31\2\u00cd\u00ce\7\20\2\2\u00ce\u00d1"+ + "\5\32\16\2\u00cf\u00d0\7\26\2\2\u00d0\u00d2\5\32\16\2\u00d1\u00cf\3\2"+ + "\2\2\u00d1\u00d2\3\2\2\2\u00d2#\3\2\2\2\u00d3\u00d4\7\27\2\2\u00d4\u00d5"+ + "\7\17\2\2\u00d5\u00d6\5\60\31\2\u00d6\u00d7\7\20\2\2\u00d7\u00d8\5\32"+ + "\16\2\u00d8%\3\2\2\2\u00d9\u00db\7\30\2\2\u00da\u00dc\5\60\31\2\u00db"+ + "\u00da\3\2\2\2\u00db\u00dc\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\u00de\7\r"+ + "\2\2\u00de\'\3\2\2\2\u00df\u00e0\7\31\2\2\u00e0\u00e1\7,\2\2\u00e1\u00e2"+ + "\7\17\2\2\u00e2\u00f0\7\20\2\2\u00e3\u00e4\7\31\2\2\u00e4\u00e5\7,\2\2"+ + "\u00e5\u00e6\7\4\2\2\u00e6\u00e7\5\60\31\2\u00e7\u00e8\7\5\2\2\u00e8\u00f0"+ + "\3\2\2\2\u00e9\u00ea\7\31\2\2\u00ea\u00eb\5\n\6\2\u00eb\u00ec\7\4\2\2"+ + "\u00ec\u00ed\5\60\31\2\u00ed\u00ee\7\5\2\2\u00ee\u00f0\3\2\2\2\u00ef\u00df"+ + "\3\2\2\2\u00ef\u00e3\3\2\2\2\u00ef\u00e9\3\2\2\2\u00f0)\3\2\2\2\u00f1"+ + "\u00f2\7\32\2\2\u00f2\u00f3\7\17\2\2\u00f3\u00f4\7\20\2\2\u00f4+\3\2\2"+ + "\2\u00f5\u00fa\5\60\31\2\u00f6\u00f7\7\f\2\2\u00f7\u00f9\5\60\31\2\u00f8"+ + "\u00f6\3\2\2\2\u00f9\u00fc\3\2\2\2\u00fa\u00f8\3\2\2\2\u00fa\u00fb\3\2"+ + "\2\2\u00fb-\3\2\2\2\u00fc\u00fa\3\2\2\2\u00fd\u00fe\b\30\1\2\u00fe\u0107"+ + "\7,\2\2\u00ff\u0107\7\33\2\2\u0100\u0101\7,\2\2\u0101\u0103\7\17\2\2\u0102"+ + "\u0104\5,\27\2\u0103\u0102\3\2\2\2\u0103\u0104\3\2\2\2\u0104\u0105\3\2"+ + "\2\2\u0105\u0107\7\20\2\2\u0106\u00fd\3\2\2\2\u0106\u00ff\3\2\2\2\u0106"+ + "\u0100\3\2\2\2\u0107\u011a\3\2\2\2\u0108\u0109\f\6\2\2\u0109\u010a\7\21"+ + "\2\2\u010a\u0119\7,\2\2\u010b\u010c\f\5\2\2\u010c\u010d\7\4\2\2\u010d"+ + "\u010e\5\60\31\2\u010e\u010f\7\5\2\2\u010f\u0119\3\2\2\2\u0110\u0111\f"+ + "\3\2\2\u0111\u0112\7\21\2\2\u0112\u0113\7,\2\2\u0113\u0115\7\17\2\2\u0114"+ + "\u0116\5,\27\2\u0115\u0114\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0117\3\2"+ + "\2\2\u0117\u0119\7\20\2\2\u0118\u0108\3\2\2\2\u0118\u010b\3\2\2\2\u0118"+ + "\u0110\3\2\2\2\u0119\u011c\3\2\2\2\u011a\u0118\3\2\2\2\u011a\u011b\3\2"+ + "\2\2\u011b/\3\2\2\2\u011c\u011a\3\2\2\2\u011d\u011e\b\31\1\2\u011e\u012c"+ + "\5\2\2\2\u011f\u012c\5.\30\2\u0120\u0121\7\17\2\2\u0121\u0122\5\60\31"+ + "\2\u0122\u0123\7\20\2\2\u0123\u012c\3\2\2\2\u0124\u0125\t\3\2\2\u0125"+ + "\u012c\5\60\31\n\u0126\u0127\7\17\2\2\u0127\u0128\5\6\4\2\u0128\u0129"+ + "\7\20\2\2\u0129\u012a\5\60\31\t\u012a\u012c\3\2\2\2\u012b\u011d\3\2\2"+ + "\2\u012b\u011f\3\2\2\2\u012b\u0120\3\2\2\2\u012b\u0124\3\2\2\2\u012b\u0126"+ + "\3\2\2\2\u012c\u0141\3\2\2\2\u012d\u012e\f\b\2\2\u012e\u012f\t\4\2\2\u012f"+ + "\u0140\5\60\31\t\u0130\u0131\f\7\2\2\u0131\u0132\t\5\2\2\u0132\u0140\5"+ + "\60\31\b\u0133\u0134\f\6\2\2\u0134\u0135\t\6\2\2\u0135\u0140\5\60\31\7"+ + "\u0136\u0137\f\5\2\2\u0137\u0138\t\7\2\2\u0138\u0140\5\60\31\6\u0139\u013a"+ + "\f\4\2\2\u013a\u013b\7(\2\2\u013b\u0140\5\60\31\5\u013c\u013d\f\3\2\2"+ + "\u013d\u013e\7)\2\2\u013e\u0140\5\60\31\4\u013f\u012d\3\2\2\2\u013f\u0130"+ + "\3\2\2\2\u013f\u0133\3\2\2\2\u013f\u0136\3\2\2\2\u013f\u0139\3\2\2\2\u013f"+ + "\u013c\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2"+ + "\2\2\u0142\61\3\2\2\2\u0143\u0141\3\2\2\2#\659=FMU]_hot{\u0081\u008e\u0097"+ + "\u009d\u00a5\u00ae\u00b3\u00ba\u00c8\u00d1\u00db\u00ef\u00fa\u0103\u0106"+ + "\u0115\u0118\u011a\u012b\u013f\u0141"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/src/cd/frontend/parser/JavaliVisitor.java b/src/cd/frontend/parser/JavaliVisitor.java new file mode 100644 index 0000000..fca4db5 --- /dev/null +++ b/src/cd/frontend/parser/JavaliVisitor.java @@ -0,0 +1,278 @@ +// Generated from /home/carlos/eth/cd/nop90/HW2/src/cd/frontend/parser/Javali.g4 by ANTLR 4.7.1 + + // Java header + package cd.frontend.parser; + +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link JavaliParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface JavaliVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by the {@code NullLiteral} + * labeled alternative in {@link JavaliParser#literal}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNullLiteral(JavaliParser.NullLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code BoolLiteral} + * labeled alternative in {@link JavaliParser#literal}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBoolLiteral(JavaliParser.BoolLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code IntLiteral} + * labeled alternative in {@link JavaliParser#literal}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIntLiteral(JavaliParser.IntLiteralContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitType(JavaliParser.TypeContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#referenceType}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReferenceType(JavaliParser.ReferenceTypeContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#arrayType}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArrayType(JavaliParser.ArrayTypeContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#primitiveType}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPrimitiveType(JavaliParser.PrimitiveTypeContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#unit}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitUnit(JavaliParser.UnitContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#classDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitClassDecl(JavaliParser.ClassDeclContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#memberList}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMemberList(JavaliParser.MemberListContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#varDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitVarDecl(JavaliParser.VarDeclContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#methodDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMethodDecl(JavaliParser.MethodDeclContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#formalParamList}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFormalParamList(JavaliParser.FormalParamListContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#stmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStmt(JavaliParser.StmtContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#stmtBlock}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStmtBlock(JavaliParser.StmtBlockContext ctx); + /** + * Visit a parse tree produced by the {@code LocalMethodCallStmt} + * labeled alternative in {@link JavaliParser#methodCallStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLocalMethodCallStmt(JavaliParser.LocalMethodCallStmtContext ctx); + /** + * Visit a parse tree produced by the {@code ObjectMethodCallStmt} + * labeled alternative in {@link JavaliParser#methodCallStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitObjectMethodCallStmt(JavaliParser.ObjectMethodCallStmtContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#assignmentStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAssignmentStmt(JavaliParser.AssignmentStmtContext ctx); + /** + * Visit a parse tree produced by the {@code Write} + * labeled alternative in {@link JavaliParser#writeStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWrite(JavaliParser.WriteContext ctx); + /** + * Visit a parse tree produced by the {@code WriteLn} + * labeled alternative in {@link JavaliParser#writeStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWriteLn(JavaliParser.WriteLnContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#ifStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIfStmt(JavaliParser.IfStmtContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#whileStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhileStmt(JavaliParser.WhileStmtContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#returnStmt}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReturnStmt(JavaliParser.ReturnStmtContext ctx); + /** + * Visit a parse tree produced by the {@code NewObject} + * labeled alternative in {@link JavaliParser#newExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNewObject(JavaliParser.NewObjectContext ctx); + /** + * Visit a parse tree produced by the {@code NewObjectArray} + * labeled alternative in {@link JavaliParser#newExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNewObjectArray(JavaliParser.NewObjectArrayContext ctx); + /** + * Visit a parse tree produced by the {@code NewPrimitiveArray} + * labeled alternative in {@link JavaliParser#newExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNewPrimitiveArray(JavaliParser.NewPrimitiveArrayContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#readExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReadExpr(JavaliParser.ReadExprContext ctx); + /** + * Visit a parse tree produced by {@link JavaliParser#actualParamList}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitActualParamList(JavaliParser.ActualParamListContext ctx); + /** + * Visit a parse tree produced by the {@code AccessThis} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessThis(JavaliParser.AccessThisContext ctx); + /** + * Visit a parse tree produced by the {@code AccessLocalField} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessLocalField(JavaliParser.AccessLocalFieldContext ctx); + /** + * Visit a parse tree produced by the {@code AccessObjectField} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessObjectField(JavaliParser.AccessObjectFieldContext ctx); + /** + * Visit a parse tree produced by the {@code AccessLocalMethod} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessLocalMethod(JavaliParser.AccessLocalMethodContext ctx); + /** + * Visit a parse tree produced by the {@code AccessArray} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessArray(JavaliParser.AccessArrayContext ctx); + /** + * Visit a parse tree produced by the {@code AccessObjectMethod} + * labeled alternative in {@link JavaliParser#identAccess}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAccessObjectMethod(JavaliParser.AccessObjectMethodContext ctx); + /** + * Visit a parse tree produced by the {@code ExprBinary} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprBinary(JavaliParser.ExprBinaryContext ctx); + /** + * Visit a parse tree produced by the {@code ExprCast} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprCast(JavaliParser.ExprCastContext ctx); + /** + * Visit a parse tree produced by the {@code ExprParentheses} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprParentheses(JavaliParser.ExprParenthesesContext ctx); + /** + * Visit a parse tree produced by the {@code ExprUnary} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprUnary(JavaliParser.ExprUnaryContext ctx); + /** + * Visit a parse tree produced by the {@code ExprConstant} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprConstant(JavaliParser.ExprConstantContext ctx); + /** + * Visit a parse tree produced by the {@code ExprIdentAccess} + * labeled alternative in {@link JavaliParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprIdentAccess(JavaliParser.ExprIdentAccessContext ctx); +} \ No newline at end of file diff --git a/src/cd/ir/Ast.java b/src/cd/ir/Ast.java index 300fb97..5bf1a26 100644 --- a/src/cd/ir/Ast.java +++ b/src/cd/ir/Ast.java @@ -1,13 +1,13 @@ package cd.ir; -import cd.util.Pair; -import cd.util.debug.AstOneLine; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import cd.util.Pair; +import cd.util.debug.AstOneLine; + public abstract class Ast { /** @@ -17,7 +17,6 @@ public abstract class Ast { *

Note: this list may contain null pointers! */ public final List rwChildren; - final String VAR_LABEL_FORMAT = "var_%s"; protected Ast(int fixedCount) { if (fixedCount == -1) @@ -69,27 +68,17 @@ public abstract class Ast { /** Base class for all expressions */ public static abstract class Expr extends Ast { - - int needed = -1; - + protected Expr(int fixedCount) { super(fixedCount); } - + @Override - public R accept(AstVisitor visitor, A arg) { - return this.accept((ExprVisitor) visitor, arg); + public R accept(AstVisitor visitor, A arg) { + return this.accept((ExprVisitor)visitor, arg); } - - public abstract R accept(ExprVisitor visitor, A arg); - - /** - * Registers needed to perform the operation represented by this Expr node - * If not already run, the cost is visiting all subnodes, else the cost is constant - * @return Minimum number of registers needed - */ - public abstract int registersNeeded(); - + public abstract R accept(ExprVisitor visitor, A arg); + /** Copies any non-AST fields. */ protected E postCopy(E item) { return item; @@ -108,21 +97,7 @@ public abstract class Ast { setLeft(left); setRight(right); } - - @Override - public int registersNeeded() { - if (needed != -1) - return needed; - int leftNeed = left().registersNeeded(); - int rightNeed = right().registersNeeded(); - if (leftNeed > rightNeed) - return needed = leftNeed; - else if (leftNeed < rightNeed) - return needed = rightNeed; - else - return needed = ++rightNeed; - } - + public Expr left() { return (Expr) this.rwChildren.get(0); } public void setLeft(Expr node) { this.rwChildren.set(0, node); } @@ -138,12 +113,7 @@ public abstract class Ast { assert arg != null; setArg(arg); } - - @Override - public int registersNeeded() { - return arg().registersNeeded(); - } - + public Expr arg() { return (Expr) this.rwChildren.get(0); } public void setArg(Expr node) { this.rwChildren.set(0, node); } @@ -154,11 +124,6 @@ public abstract class Ast { public LeafExpr() { super(0); } - - @Override - public int registersNeeded() { - return 1; - } } /** Represents {@code this}, the current object */ @@ -374,7 +339,7 @@ public abstract class Ast { public static class Var extends LeafExpr { public String name; - + /** * Use this constructor to build an instance of this AST * in the parser. @@ -382,11 +347,6 @@ public abstract class Ast { public Var(String name) { this.name = name; } - - public String getLabel() { - return String.format(VAR_LABEL_FORMAT, name); - } - @Override public R accept(ExprVisitor visitor, A arg) { return visitor.var(this, arg); @@ -448,12 +408,7 @@ public abstract class Ast { public R accept(ExprVisitor visitor, A arg) { return visitor.methodCall(this, arg); } - - @Override - public int registersNeeded() { - throw new RuntimeException("Not implemented"); - } - + } // _________________________________________________________________ @@ -643,10 +598,6 @@ public abstract class Ast { this.name = name; } - public String getLabel() { - return String.format(VAR_LABEL_FORMAT, name); - } - @Override public R accept(AstVisitor visitor, A arg) { return visitor.varDecl(this, arg); diff --git a/src/cd/ir/AstVisitor.java b/src/cd/ir/AstVisitor.java index 0576c24..8d334d6 100644 --- a/src/cd/ir/AstVisitor.java +++ b/src/cd/ir/AstVisitor.java @@ -16,6 +16,17 @@ public class AstVisitor extends ExprVisitor { return ast.accept(this, arg); } + /** + * Overrides {@link ExprVisitor#visitChildren(Expr, Object)} and + * delegates to the more general {@link #visitChildren(Ast, Object)} + * with {@link Ast} parameter. This method is final to prevent + * overriding only one of the two versions. + */ + @Override + public final R visitChildren(Expr ast, A arg) { + return visitChildren((Ast) ast, arg); + } + /** * A handy function which visits the children of {@code ast}, * providing "arg" to each of them. It returns the result of @@ -45,6 +56,7 @@ public class AstVisitor extends ExprVisitor { /** * The default action for expressions is to call this */ + @Override protected R dfltExpr(Expr ast, A arg) { return dflt(ast, arg); } diff --git a/src/cd/util/debug/AstOneLine.java b/src/cd/util/debug/AstOneLine.java index 135990f..1557010 100644 --- a/src/cd/util/debug/AstOneLine.java +++ b/src/cd/util/debug/AstOneLine.java @@ -13,11 +13,14 @@ import cd.ir.Ast.Field; import cd.ir.Ast.IfElse; import cd.ir.Ast.Index; import cd.ir.Ast.IntConst; +import cd.ir.Ast.MethodCall; +import cd.ir.Ast.MethodCallExpr; import cd.ir.Ast.MethodDecl; import cd.ir.Ast.NewArray; import cd.ir.Ast.NewObject; import cd.ir.Ast.Nop; import cd.ir.Ast.NullConst; +import cd.ir.Ast.ReturnStmt; import cd.ir.Ast.Seq; import cd.ir.Ast.ThisRef; import cd.ir.Ast.UnaryOp; @@ -99,6 +102,16 @@ public class AstOneLine { return Integer.toString(ast.value); } + @Override + public String methodCall(MethodCall ast, Void arg) { + return str(ast.getMethodCallExpr()); + } + + @Override + public String methodCall(MethodCallExpr ast, Void arg) { + return String.format("%s.%s(...)", str(ast.receiver()), ast.methodName); + } + @Override public String methodDecl(MethodDecl ast, Void arg) { return String.format("%s %s(...) {...}", ast.returnType, ast.name); @@ -134,6 +147,11 @@ public class AstOneLine { return "this"; } + @Override + public String returnStmt(ReturnStmt ast, Void arg) { + return ast.arg() != null ? String.format("return %s", str(ast.arg())) : "return"; + } + @Override public String unaryOp(UnaryOp ast, Void arg) { return String.format("%s(%s)", ast.operator.repr, str(ast.arg())); diff --git a/src/cd/util/debug/DumpUtils.java b/src/cd/util/debug/DumpUtils.java new file mode 100644 index 0000000..52a2c48 --- /dev/null +++ b/src/cd/util/debug/DumpUtils.java @@ -0,0 +1,34 @@ +package cd.util.debug; + +import static java.util.Collections.sort; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import cd.ir.Ast.ClassDecl; +import cd.ir.Ast.MethodDecl; + +class DumpUtils { + + static final Comparator classComparator = new Comparator() { + public int compare(ClassDecl left, ClassDecl right) { + return left.name.compareTo(right.name); + } + }; + + static final Comparator methodComparator = new Comparator() { + public int compare(MethodDecl left, MethodDecl right) { + return left.name.compareTo(right.name); + } + }; + + static List sortedStrings(Set set) { + List strings = new ArrayList(); + for(Object element : set) + strings.add(element.toString()); + sort(strings); + return strings; + } +} diff --git a/test/cd/test/AbstractTestAgainstFrozenReference.java b/test/cd/AbstractTestAgainstFrozenReference.java similarity index 59% rename from test/cd/test/AbstractTestAgainstFrozenReference.java rename to test/cd/AbstractTestAgainstFrozenReference.java index 9a966eb..ef9eea1 100644 --- a/test/cd/test/AbstractTestAgainstFrozenReference.java +++ b/test/cd/AbstractTestAgainstFrozenReference.java @@ -1,20 +1,21 @@ -package cd.test; +package cd; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; -import cd.Config; -import cd.Main; -import cd.backend.codegen.AssemblyFailedException; import cd.frontend.parser.ParseFailure; import cd.ir.Ast.ClassDecl; import cd.util.FileUtil; @@ -26,13 +27,17 @@ abstract public class AbstractTestAgainstFrozenReference { public static final String PARSE_FAILURE = "ParseFailure"; public File file, sfile, binfile, infile; - public File parserreffile, semanticreffile, execreffile, cfgreffile, optreffile; + public File parserreffile, semanticreffile, execreffile, cfgreffile, rdreffile, + nnreffile, optreffile; public File errfile; public Main main; public static int counter = 0; - @Test(timeout=10000) + @Rule + public TestRule timeout = new DisableOnDebug(new Timeout(15, TimeUnit.SECONDS)); + + @Test public void test() throws Throwable { System.err.println("[" + counter++ + " = " + file + "]"); @@ -47,9 +52,6 @@ abstract public class AbstractTestAgainstFrozenReference { List astRoots = testParser(); if (astRoots != null) { - { - testCodeGenerator(astRoots); - } } } catch (org.junit.ComparisonFailure cf) { throw cf; @@ -78,7 +80,7 @@ abstract public class AbstractTestAgainstFrozenReference { ProcessBuilder pb = new ProcessBuilder( javaExe, "-Dcd.meta_hidden.Version=" + referenceVersion(), - "-cp", "lib/frozenReferenceObf.jar" + colon + " lib/junit-4.12.jar" + colon + "lib/antlr-4.4-complete.jar", + "-cp", "lib/frozenReferenceObf.jar" + colon + " lib/junit-4.12.jar" + colon + "lib/antlr-4.7.1-complete.jar", "cd.FrozenReferenceMain", file.getAbsolutePath()); Process proc = pb.start(); @@ -94,13 +96,24 @@ abstract public class AbstractTestAgainstFrozenReference { private static String referenceVersion() { { - return "CD_HW_CODEGEN_SIMPLE_SOL"; + return "CD_HW_PARSER_SOL"; } } + private String tryReadRefFile(File fileToFind) { + if (fileToFind.exists() && fileToFind.lastModified() >= file.lastModified()) { + try { + return FileUtil.read(fileToFind); + } catch (IOException e) { + throw new RuntimeException("ERROR: could not read file " + fileToFind.getPath()); + } + } + throw new RuntimeException("ERROR: could not find file " + fileToFind.getPath()); + } + /** Run the parser and compare the output against the reference results */ private List testParser() throws Exception { - String parserRef = findParserRef(); + String parserRef = tryReadRefFile(parserreffile); List astRoots = null; String parserOut; @@ -110,8 +123,11 @@ abstract public class AbstractTestAgainstFrozenReference { parserOut = AstDump.toString(astRoots); } catch (ParseFailure pf) { { - // For this assignment, we expect all tests to parse! - throw pf; + // Parse errors are ok too. + main.debug(""); + main.debug(""); + main.debug("%s", pf.toString()); + parserOut = PARSE_FAILURE; } } @@ -121,64 +137,6 @@ abstract public class AbstractTestAgainstFrozenReference { return astRoots; } - private String findParserRef() throws IOException { - // Check for a .ref file - if (parserreffile.exists() && parserreffile.lastModified() >= file.lastModified()) { - return FileUtil.read(parserreffile); - } - throw new RuntimeException("ERROR: could not find parser .ref"); - } - - /** - * Run the code generator, assemble the resulting .s file, and (if the output - * is well-defined) compare against the expected output. - */ - private void testCodeGenerator(List astRoots) - throws IOException { - // Determine the input and expected output. - String inFile = (infile.exists() ? FileUtil.read(infile) : ""); - String execRef = findExecRef(); - - // Run the code generator: - try (FileWriter fw = new FileWriter(this.sfile)) { - main.generateCode(astRoots, fw); - } - - // At this point, we have generated a .s file and we have to compile - // it to a binary file. We need to call out to GCC or something - // to do this. - String asmOutput = FileUtil.runCommand( - Config.ASM_DIR, - Config.ASM, - new String[] { binfile.getAbsolutePath(), - sfile.getAbsolutePath() }, null, false); - - // To check if gcc succeeded, check if the binary file exists. - // We could use the return code instead, but this seems more - // portable to other compilers / make systems. - if (!binfile.exists()) - throw new AssemblyFailedException(asmOutput); - - // Execute the binary file, providing input if relevant, and - // capturing the output. Check the error code so see if the - // code signaled dynamic errors. - String execOut = FileUtil.runCommand(new File("."), - new String[] { binfile.getAbsolutePath() }, new String[] {}, - inFile, true); - - // Compute the output to what we expected to see. - if (!execRef.equals(execOut)) - assertEqualOutput("exec", execRef, execOut); - } - - private String findExecRef() throws IOException { - // Check for a .ref file - if (execreffile.exists() && execreffile.lastModified() > file.lastModified()) { - return FileUtil.read(execreffile); - } - - throw new RuntimeException("ERROR: could not find execution .ref"); - } private void assertEquals(String phase, String exp, String act_) { String act = act_.replace("\r\n", "\n"); // for windows machines @@ -186,16 +144,6 @@ abstract public class AbstractTestAgainstFrozenReference { warnAboutDiff(phase, exp, act); } } - - /** - * Compare the output of two executions - */ - private void assertEqualOutput(String phase, String exp, String act_) { - String act = act_.replace("\r\n", "\n"); // for windows machines - if (!exp.equals(act)) { - warnAboutDiff(phase, exp, act); - } - } private void warnAboutDiff(String phase, String exp, String act) { try { diff --git a/test/cd/test/Diff.java b/test/cd/Diff.java similarity index 99% rename from test/cd/test/Diff.java rename to test/cd/Diff.java index a86b5ee..148c1bd 100644 --- a/test/cd/test/Diff.java +++ b/test/cd/Diff.java @@ -1,4 +1,4 @@ -package cd.test; +package cd; // NOTE: This code was adapted from the code found at // http://www.cs.princeton.edu/introcs/96optimization/Diff.java.html diff --git a/test/cd/test/TestSamplePrograms.java b/test/cd/TestSamplePrograms.java similarity index 89% rename from test/cd/test/TestSamplePrograms.java rename to test/cd/TestSamplePrograms.java index 654c6d4..4448587 100644 --- a/test/cd/test/TestSamplePrograms.java +++ b/test/cd/TestSamplePrograms.java @@ -1,4 +1,9 @@ -package cd.test; +package cd; + +import cd.util.FileUtil; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; import java.io.File; import java.io.StringWriter; @@ -6,14 +11,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import cd.Config; -import cd.Main; -import cd.util.FileUtil; - @RunWith(Parameterized.class) public class TestSamplePrograms extends AbstractTestAgainstFrozenReference { @@ -31,8 +28,8 @@ public class TestSamplePrograms extends AbstractTestAgainstFrozenReference { * particular directory, use sth. like: * {@code testDir = new File("javali_tests/HW2/")}. */ -// public static final File testDir = new File("javali_tests/HW1"); - public static final File testDir = new File("javali_tests"); + public static final File testDir = new File("javali_tests/HW2_nop90"); +// public static final File testDir = new File("javali_tests"); @Parameters(name="{index}:{0}") public static Collection testFiles() { @@ -64,6 +61,8 @@ public class TestSamplePrograms extends AbstractTestAgainstFrozenReference { this.semanticreffile = new File(file.getPath() + ".semantic.ref"); this.execreffile = new File(file.getPath() + ".exec.ref"); this.cfgreffile = new File(file.getPath() + ".cfg.dot.ref"); + this.rdreffile = new File(file.getPath() + ".rd.ref"); + this.nnreffile = new File(file.getPath() + ".nn.ref"); this.optreffile = new File(file.getPath() + ".opt.ref"); this.errfile = new File(String.format("%s.err", file.getPath())); this.main = new Main();