finished exercise

This commit is contained in:
2025-11-08 17:16:16 +01:00
parent e854da56aa
commit c1eef57c97
21 changed files with 348 additions and 95 deletions

15
.idea/.gitignore generated vendored
View File

@@ -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

104
.idea/MicroJava.iml generated Normal file
View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/MicroJava Compiler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/MicroJava Tests/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/MicroJava Tests/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/MicroJava VM Tests/test" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/gson-2.10.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/javassist.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/apiguardian-api-1.1.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-jupiter-5.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-jupiter-api-5.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-jupiter-engine-5.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-jupiter-params-5.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-platform-commons-1.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-platform-engine-1.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/opentest4j-1.3.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

10
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="JAVA">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,java.net.http.HttpClient,newHttpClient" />
</inspection_tool>
</profile>
</component>

View File

@@ -1,18 +1,17 @@
<component name="libraryTable">
<library name="lib2">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-engine-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-api-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-engine-1.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/opentest4j-1.3.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-commons-1.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/javassist.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/gson-2.10.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-params-5.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
<component name="libraryTable">
<library name="junit.jupiter" type="repository">
<properties maven-id="org.junit.jupiter:junit-jupiter:5.12.2" />
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-api-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/opentest4j-1.3.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-commons-1.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-params-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-engine-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-engine-1.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,18 +0,0 @@
<component name="libraryTable">
<library name="lib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/out/lib/junit-jupiter-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/javassist.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/junit-jupiter-api-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/junit-jupiter-params-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/junit-jupiter-engine-5.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/gson-2.10.1.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/opentest4j-1.3.0.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/junit-platform-engine-1.12.2.jar!/" />
<root url="jar://$PROJECT_DIR$/out/lib/junit-platform-commons-1.12.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

9
.idea/misc.xml generated
View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

18
.idea/modules.xml generated
View File

@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/MicroJava Compiler/MicroJava Compiler.iml" filepath="$PROJECT_DIR$/MicroJava Compiler/MicroJava Compiler.iml" />
<module fileurl="file://$PROJECT_DIR$/out/MicroJava Compiler/MicroJava Compiler2.iml" filepath="$PROJECT_DIR$/out/MicroJava Compiler/MicroJava Compiler2.iml" />
<module fileurl="file://$PROJECT_DIR$/out/MicroJava Tests/MicroJava Tests.iml" filepath="$PROJECT_DIR$/out/MicroJava Tests/MicroJava Tests.iml" />
<module fileurl="file://$PROJECT_DIR$/MicroJava Tests/MicroJava Tests2.iml" filepath="$PROJECT_DIR$/MicroJava Tests/MicroJava Tests2.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/exercise05.iml" filepath="$PROJECT_DIR$/.idea/exercise05.iml" />
</modules>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/MicroJava.iml" filepath="$PROJECT_DIR$/.idea/MicroJava.iml" />
</modules>
</component>
</project>

19
.idea/runConfigurations/UE_P_1.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-1" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ssw.mj.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="ssw.mj.test" />
<option name="MAIN_CLASS_NAME" value="ssw.mj.test.ScannerTest" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

16
.idea/runConfigurations/UE_P_2.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-2" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<patterns>
<pattern testClass="ssw.mj.test.ScannerTest" />
<pattern testClass="ssw.mj.test.ParserTest" />
</patterns>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

17
.idea/runConfigurations/UE_P_3.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-3" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<patterns>
<pattern testClass="ssw.mj.test.ScannerTest" />
<pattern testClass="ssw.mj.test.ParserTest" />
<pattern testClass="ssw.mj.test.RecoverTest" />
</patterns>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

18
.idea/runConfigurations/UE_P_4.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-4" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<patterns>
<pattern testClass="ssw.mj.test.ScannerTest" />
<pattern testClass="ssw.mj.test.ParserTest" />
<pattern testClass="ssw.mj.test.RecoverTest" />
<pattern testClass="ssw.mj.test.SymbolTableTest" />
</patterns>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

19
.idea/runConfigurations/UE_P_5.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-5" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<patterns>
<pattern testClass="ssw.mj.test.ScannerTest" />
<pattern testClass="ssw.mj.test.ParserTest" />
<pattern testClass="ssw.mj.test.RecoverTest" />
<pattern testClass="ssw.mj.test.SymbolTableTest" />
<pattern testClass="ssw.mj.test.SimpleCodeGenerationTest" />
</patterns>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

13
.idea/runConfigurations/UE_P_6.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="UE-P-6" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="directory" />
<option name="VM_PARAMETERS" value="-ea -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<dir value="$PROJECT_DIR$/MicroJava Tests/tests" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="(for lecturers) Run verbose tracing" type="JUnit" factoryName="JUnit">
<module name="MicroJava" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="directory" />
<option name="VM_PARAMETERS" value="-ea -verbose:class -verbose:dynload -Djava.system.class.loader=ssw.mj.TracingClassLoader" />
<dir value="$PROJECT_DIR$/MicroJava Tests/tests" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib2" level="project" />
<orderEntry type="library" name="lib" level="project" />
</component>
</module>

View File

@@ -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<Token.Kind> firstConstDecl = EnumSet.of(Token.Kind.final_);
static final EnumSet<Token.Kind> firstVarDecl = EnumSet.of(Token.Kind.ident);
static final EnumSet<Token.Kind> firstClassDecl = EnumSet.of(Token.Kind.class_);
static final EnumSet<Token.Kind> breakDecl = EnumSet.of(lbrace, eof);
static final EnumSet<Token.Kind> firstStatement = EnumSet.of(ident, if_, while_, break_, return_, read, print, lbrace, semicolon);
static final EnumSet<Token.Kind> breakStatement = EnumSet.of(rbrace, else_, eof);
static final EnumSet<Token.Kind> firstAsignop = EnumSet.of(assign, plusas, minusas, timesas, slashas, remas);
static final EnumSet<Token.Kind> firstFactor = EnumSet.of(ident, number, charConst, new_, lpar);
static final EnumSet<Token.Kind> firstMulop = EnumSet.of(times, slash, rem);
static final EnumSet<Token.Kind> firstMethodDecl = EnumSet.of(ident, void_);
static final EnumSet<Token.Kind> breakMethodDecl = EnumSet.of(rbrace, eof);
static <T extends Enum<T>> EnumSet<T> enumUnion(EnumSet<T> first, EnumSet<T> ...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;
}
// ====================================
// ====================================
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib2" level="project" />
<orderEntry type="library" name="lib" level="project" />
<orderEntry type="module" module-name="MicroJava Compiler" />
<orderEntry type="module" module-name="MicroJava Compiler2" />
</component>
</module>