diff --git a/.idea/.gitignore b/.idea/.gitignore
index b58b603..052f916 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -1,5 +1,10 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# GitHub Copilot persisted chat sessions
+/copilot/chatSessions
diff --git a/.idea/MicroJava.iml b/.idea/MicroJava.iml
new file mode 100644
index 0000000..275245e
--- /dev/null
+++ b/.idea/MicroJava.iml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..7c86e17
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..307554b
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/exercise05.iml b/.idea/exercise02.iml
similarity index 100%
rename from .idea/exercise05.iml
rename to .idea/exercise02.iml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..e8079f7
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/lib2.xml b/.idea/libraries/junit_jupiter.xml
similarity index 83%
rename from .idea/libraries/lib2.xml
rename to .idea/libraries/junit_jupiter.xml
index 48a1569..631884c 100644
--- a/.idea/libraries/lib2.xml
+++ b/.idea/libraries/junit_jupiter.xml
@@ -1,18 +1,17 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
deleted file mode 100644
index 0277ad2..0000000
--- a/.idea/libraries/lib.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6f29fee..357a5d4 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,5 @@
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index bec10bb..4cd36c0 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -1,12 +1,8 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_1.xml b/.idea/runConfigurations/UE_P_1.xml
new file mode 100644
index 0000000..6da5284
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_1.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_2.xml b/.idea/runConfigurations/UE_P_2.xml
new file mode 100644
index 0000000..32e7d97
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_2.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_3.xml b/.idea/runConfigurations/UE_P_3.xml
new file mode 100644
index 0000000..18d61ee
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_3.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_4.xml b/.idea/runConfigurations/UE_P_4.xml
new file mode 100644
index 0000000..a137536
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_4.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_5.xml b/.idea/runConfigurations/UE_P_5.xml
new file mode 100644
index 0000000..ff69013
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_5.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/UE_P_6.xml b/.idea/runConfigurations/UE_P_6.xml
new file mode 100644
index 0000000..60a4a5f
--- /dev/null
+++ b/.idea/runConfigurations/UE_P_6.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/_for_lecturers__Run_verbose_tracing.xml b/.idea/runConfigurations/_for_lecturers__Run_verbose_tracing.xml
new file mode 100644
index 0000000..578f3e0
--- /dev/null
+++ b/.idea/runConfigurations/_for_lecturers__Run_verbose_tracing.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MicroJava Compiler/MicroJava Compiler.iml b/MicroJava Compiler/MicroJava Compiler.iml
deleted file mode 100644
index 228f0a9..0000000
--- a/MicroJava Compiler/MicroJava Compiler.iml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/MicroJava Compiler/src/ssw/mj/impl/Parser.java b/MicroJava Compiler/src/ssw/mj/impl/Parser.java
index 4bf19b9..f260f0e 100644
--- a/MicroJava Compiler/src/ssw/mj/impl/Parser.java
+++ b/MicroJava Compiler/src/ssw/mj/impl/Parser.java
@@ -9,8 +9,7 @@ import ssw.mj.scanner.Token;
import javax.xml.stream.FactoryConfigurationError;
import java.util.EnumSet;
-import static ssw.mj.Errors.Message.TOKEN_EXPECTED;
-import static ssw.mj.Errors.Message.UNDEFINED_ESCAPE;
+import static ssw.mj.Errors.Message.*;
import static ssw.mj.scanner.Token.Kind.*;
public final class Parser {
@@ -60,6 +59,10 @@ public final class Parser {
*/
public final Tab tab;
+ private static int MIN_ERROR_DIST = 3;
+
+ private int errorDist = MIN_ERROR_DIST;
+
public Parser(Scanner scanner) {
this.scanner = scanner;
tab = new Tab(this);
@@ -76,6 +79,7 @@ public final class Parser {
t = la;
la = scanner.next();
sym = la.kind;
+ errorDist++;
}
/**
@@ -95,8 +99,12 @@ public final class Parser {
public void error(Message msg, Object... msgParams) {
// TODO Exercise UE-P-3: Replace panic mode with error recovery (i.e., keep track of error distance)
// TODO Exercise UE-P-3: Hint: Replacing panic mode also affects scan() method
- scanner.errors.error(la.line, la.col, msg, msgParams);
- throw new Errors.PanicMode();
+
+ if (errorDist >= MIN_ERROR_DIST) {
+ scanner.errors.error(la.line, la.col, msg, msgParams);
+ }
+
+ errorDist = 0;
}
/**
@@ -124,10 +132,15 @@ public final class Parser {
static final EnumSet firstConstDecl = EnumSet.of(Token.Kind.final_);
static final EnumSet firstVarDecl = EnumSet.of(Token.Kind.ident);
static final EnumSet firstClassDecl = EnumSet.of(Token.Kind.class_);
+ static final EnumSet breakDecl = EnumSet.of(lbrace, eof);
static final EnumSet firstStatement = EnumSet.of(ident, if_, while_, break_, return_, read, print, lbrace, semicolon);
+ static final EnumSet breakStatement = EnumSet.of(rbrace, else_, eof);
static final EnumSet firstAsignop = EnumSet.of(assign, plusas, minusas, timesas, slashas, remas);
static final EnumSet firstFactor = EnumSet.of(ident, number, charConst, new_, lpar);
static final EnumSet firstMulop = EnumSet.of(times, slash, rem);
+ static final EnumSet firstMethodDecl = EnumSet.of(ident, void_);
+ static final EnumSet breakMethodDecl = EnumSet.of(rbrace, eof);
+
static > EnumSet enumUnion(EnumSet first, EnumSet ...sets) {
final var copy = EnumSet.copyOf(first);
@@ -154,22 +167,26 @@ public final class Parser {
check(Token.Kind.program);
check(Token.Kind.ident);
- final var firstDeclarationUnion = enumUnion(firstConstDecl, firstVarDecl, firstClassDecl);
-
- while (firstDeclarationUnion.contains(sym)) {
+ while (!breakDecl.contains(sym)) {
if (firstVarDecl.contains(sym)) {
VarDecl();
} else if (firstClassDecl.contains(sym)) {
ClassDecl();
- } else {
+ } else if (firstConstDecl.contains(sym)){
ConstDecl();
+ } else {
+ recoverDecl();
}
}
check(lbrace);
- while (sym == ident || sym == void_) {
- MethodDecl();
+ while (!breakMethodDecl.contains(sym)) {
+ if (firstMethodDecl.contains(sym)) {
+ MethodDecl();
+ } else {
+ recoverMethodDecl();
+ }
}
check(rbrace);
@@ -266,7 +283,7 @@ public final class Parser {
}
private void Statement() {
- while (firstStatement.contains(sym)) {
+ while (!breakStatement.contains(sym)) {
switch (sym) {
case ident -> {
Designator();
@@ -340,6 +357,7 @@ public final class Parser {
}
case lbrace -> Block();
case semicolon -> scan();
+ default -> recoverStatement();
};
}
}
@@ -504,6 +522,40 @@ public final class Parser {
// TODO Exercise UE-P-3: Error recovery methods: recoverDecl, recoverMethodDecl and recoverStat (+ TODO Exercise UE-P-5: Check idents for Type kind)
+ private void recoverDecl() {
+ final var firstDeclarationUnion = enumUnion(firstConstDecl, firstVarDecl, firstClassDecl);
+ final var recoverDeclSet = enumUnion(breakDecl, firstDeclarationUnion);
+ error(DECLARATION_RECOVERY);
+
+ do {
+ scan();
+ } while (!recoverDeclSet.contains(sym));
+ errorDist = 0;
+ }
+
+ private void recoverMethodDecl() {
+ error(METHOD_DECL_RECOVERY);
+
+ final var recoveryMethoDeclSet = enumUnion(breakMethodDecl, firstMethodDecl);
+ do {
+ scan();
+ } while (!recoveryMethoDeclSet.contains(sym));
+ errorDist = 0;
+ }
+
+ private void recoverStatement() {
+ error(STATEMENT_RECOVERY);
+
+ var recoveryStatementSet = enumUnion(breakStatement, firstStatement);
+ recoveryStatementSet.remove(ident);
+ recoveryStatementSet.remove(lbrace);
+
+ do {
+ scan();
+ } while (!recoveryStatementSet.contains(sym));
+ errorDist = 0;
+ }
+
// ====================================
// ====================================
}
diff --git a/MicroJava Tests/MicroJava Tests2.iml b/MicroJava Tests/MicroJava Tests2.iml
deleted file mode 100644
index 9d2e8a7..0000000
--- a/MicroJava Tests/MicroJava Tests2.iml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file