Compare commits
245 Commits
6d36eb109c
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
4c4c06f728 | ||
|
30bd5a0b5c | ||
f673612f54 | |||
|
9760e39a29 | ||
|
93e17e5415 | ||
|
b151edc2fd | ||
|
c0d8ab8399 | ||
|
f50bb7efd7 | ||
|
51a390752b | ||
|
3114064038 | ||
|
745db43b34 | ||
|
e0286e0840 | ||
|
ebef717141 | ||
|
3de54afa93 | ||
|
30d3cfa44a | ||
efa1a21655 | |||
3fb11e5d7e | |||
|
c6e61defce | ||
|
dbde4e8047 | ||
5a12d61623 | |||
f5bccab651 | |||
0de5c3e993 | |||
3628a0a4d8 | |||
36f0683240 | |||
|
97aadb9ba8 | ||
|
e5dcbb8f99 | ||
e96f30fe19 | |||
64b15af6ef | |||
4ff6854094 | |||
0a9cc7655a | |||
7e66b5b8e3 | |||
d835a98e6f | |||
240913d422 | |||
4bee432294 | |||
0cf4715782 | |||
|
3c0f7e857a | ||
|
2b7e0d0d42 | ||
|
bd61a0e595 | ||
|
24407a5c1c | ||
195440e9d9 | |||
6fa57cf319 | |||
1de6add080 | |||
c315966219 | |||
c2c4974c76 | |||
|
85e0cf3807 | ||
|
6f3fb02666 | ||
|
435697053a | ||
8eba420d48 | |||
fbff03c3d7 | |||
721e1caa79 | |||
6d3e1f859e | |||
f6b34bf70b | |||
430d551f7d | |||
8e0d627505 | |||
6b6051cad8 | |||
1f8e045b1e | |||
ceb1231632 | |||
|
31929878b0 | ||
|
ea97f34398 | ||
|
2f7b310254 | ||
|
9b8155ebab | ||
|
4775c3f47e | ||
|
2e3a7850a4 | ||
|
d925a3258c | ||
|
fb5372bc8f | ||
|
f29be4fd8c | ||
|
34bb86c7f4 | ||
|
c0e197e2d0 | ||
|
ae872ed906 | ||
91552ad147 | |||
084808c3ab | |||
d19748766f | |||
|
4bdb65a6ce | ||
|
97e0c228d6 | ||
|
d4be77ceb2 | ||
ca539add98 | |||
1bcf396f95 | |||
8ba58d492b | |||
|
ed25868ff7 | ||
879fa08cdc | |||
|
0e512161a0 | ||
|
ba08c6f6b0 | ||
c5aea85965 | |||
2a1d0a0b8a | |||
f1abe5d5a8 | |||
|
a9d7e841f5 | ||
|
b7863d0684 | ||
|
7ccff3208c | ||
|
3e0e6f8327 | ||
|
ab5a51d3b1 | ||
|
a4c1c502ab | ||
|
7d441116bd | ||
|
8afa3b8461 | ||
|
84ecf316cd | ||
|
7ddea8f18d | ||
46154fbb01 | |||
9aac795c07 | |||
e59f4e7190 | |||
|
e6a2b0fe9d | ||
|
44c2f551de | ||
|
bad034acfd | ||
|
ba73e1bd45 | ||
|
b7affd75ae | ||
|
2ef50f93a9 | ||
|
1cf1aaf837 | ||
|
2bf73385af | ||
|
b072af346b | ||
|
27baa429b4 | ||
bd76135895 | |||
|
6cec17eb45 | ||
87be850a0e | |||
72f82ff863 | |||
7419953510 | |||
449b895d20 | |||
f0dd6d5eb6 | |||
8956362033 | |||
|
ed4aa2d59b | ||
|
6760a17f00 | ||
|
671317f28b | ||
|
e862a7427b | ||
233725778f | |||
3227d69fc1 | |||
4ca6972ccd | |||
0047f6c08e | |||
88ce9e52f0 | |||
|
437de74cc6 | ||
|
ca77307f0c | ||
|
5f46130439 | ||
3e1456351c | |||
d26cd0c13a | |||
|
cfde5219a4 | ||
|
f414e278bb | ||
|
741a56cb99 | ||
|
02e5f3a729 | ||
|
f7338a06b3 | ||
|
3996082fa7 | ||
903e87901e | |||
775beb60fe | |||
|
2537051668 | ||
|
82356ec189 | ||
|
561eafbf4c | ||
b58fa00c9a | |||
|
92990e4042 | ||
|
3500ffd377 | ||
|
771b92bfd7 | ||
c94c7a6477 | |||
c7ad574474 | |||
22c3850062 | |||
|
21da31dee3 | ||
|
294df16e89 | ||
3112660880 | |||
c135819ba0 | |||
e94cd9cc2a | |||
|
dcd20a2394 | ||
|
71ffb8bb83 | ||
|
2d455ba197 | ||
|
77fecfa476 | ||
|
36e56fa66e | ||
|
f3e3158460 | ||
|
7b1e6fced4 | ||
|
4d5c0017b4 | ||
093beb9ef1 | |||
2ae0988986 | |||
|
18fc17b707 | ||
|
bea71838ac | ||
dfded3e592 | |||
0298e2cb76 | |||
|
dccd34db73 | ||
90f91d58d1 | |||
612c967023 | |||
f12e553ffc | |||
f24e279596 | |||
c5fc378eed | |||
|
27f50b9c66 | ||
3e901ea254 | |||
85ae06048c | |||
cd845cd91c | |||
|
4d21d8e94e | ||
|
a34c7ded50 | ||
78d5528733 | |||
|
10eb17497e | ||
|
576146c4fc | ||
|
bf365194be | ||
|
35b3e9ee46 | ||
|
88a25207e9 | ||
|
4e56760dd6 | ||
|
347bdcbd94 | ||
|
d594bacb7d | ||
|
eb313464f0 | ||
|
8163d0b61e | ||
|
92e1daab5b | ||
70a3788030 | |||
b562a789a0 | |||
c05ad761d7 | |||
|
34d17660ef | ||
|
cc6d26e17d | ||
|
f9743efddc | ||
|
b37e065857 | ||
4c5473827e | |||
d631b01c82 | |||
|
8cd22c6e4c | ||
ef0bc99bbf | |||
99948fef07 | |||
66c9481b3e | |||
fd8d451ba7 | |||
f27a7471bc | |||
a15f684c04 | |||
4a78ab62a1 | |||
|
8d3602eda3 | ||
|
fcaeb850ba | ||
|
864ddbaeee | ||
fb3f822160 | |||
fd6da5cad2 | |||
|
c44118c872 | ||
|
0020f582a1 | ||
8b5a0d528e | |||
|
1b91e25d17 | ||
|
9edee73705 | ||
|
5bf9a4fc73 | ||
b9f6014f59 | |||
af64f88198 | |||
837e751094 | |||
|
8cc67080ec | ||
|
cfcb61d49e | ||
|
8f742191bb | ||
|
102961bccc | ||
|
f59d7e9918 | ||
|
0732712e61 | ||
57c2023215 | |||
|
12ab402746 | ||
|
b6cc925e02 | ||
|
6a971345d4 | ||
|
8d6190b130 | ||
09e36a84dc | |||
|
e395c4d96b | ||
|
8a5f307947 | ||
514f7d724a | |||
|
9f40949f5a | ||
|
de5c2a5002 | ||
|
1132ff015c | ||
|
2a20a91d35 | ||
407b03620e | |||
|
b2e1745d51 | ||
|
a0e55d7b27 | ||
|
5a28d88f6a |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -76,4 +76,11 @@ fabric.properties
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
/target
|
||||
/target
|
||||
src/main/resources/logs/miniCompilerLog.log
|
||||
src/test/java/main/CompilerInput.class
|
||||
src/test/resources/output/javac/CompilerInput$Test.class
|
||||
src/test/resources/output/javac/CompilerInput.class
|
||||
src/test/resources/output/miniCompiler/CompilerInput.class
|
||||
src/test/resources/output/miniCompiler/CompilerInput$Test.class
|
||||
.idea/inspectionProfiles/Project_Default.xml
|
||||
|
19
.idea/ANTLRv4ToolGrammarProperties.xml
generated
Normal file
19
.idea/ANTLRv4ToolGrammarProperties.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ANTLRv4ToolGrammarProperties">
|
||||
<option name="perGrammarGenerationSettings">
|
||||
<list>
|
||||
<PerGrammarGenerationSettings>
|
||||
<option name="fileName" value="$PROJECT_DIR$/src/main/java/parser/grammar/SimpleJava.g4" />
|
||||
<option name="autoGen" value="true" />
|
||||
<option name="outputDir" value="C:\Users\janni\Desktop\NichtHaskell2.0\src\main\java" />
|
||||
<option name="libDir" value="" />
|
||||
<option name="encoding" value="" />
|
||||
<option name="pkg" value="parser.generated" />
|
||||
<option name="language" value="" />
|
||||
<option name="generateVisitor" value="true" />
|
||||
</PerGrammarGenerationSettings>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
5
.idea/jarRepositories.xml
generated
5
.idea/jarRepositories.xml
generated
@@ -6,6 +6,11 @@
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven_central" />
|
||||
<option name="name" value="Maven Central" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -6,7 +6,7 @@
|
||||
<PerGrammarGenerationSettings>
|
||||
<option name="fileName" value="$PROJECT_DIR$/src/main/java/parser/SimpleJava.g4" />
|
||||
<option name="autoGen" value="true" />
|
||||
<option name="outputDir" value="C:\Users\Johannes\Documents\Github\JavaCompiler\src\main\java" />
|
||||
<option name="outputDir" value="C:\Users\ARB00075\Documents\DH\Compilerbau\NichtHaskell2.0\src\main\java" />
|
||||
<option name="libDir" value="" />
|
||||
<option name="encoding" value="" />
|
||||
<option name="pkg" value="parser.generated" />
|
||||
|
BIN
JavaCompiler-1.0-jar-with-dependencies.jar
Normal file
BIN
JavaCompiler-1.0-jar-with-dependencies.jar
Normal file
Binary file not shown.
37
Makefile
Normal file
37
Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all
|
||||
### Or run only parts with "make compile-javac", "make clean" etc.
|
||||
|
||||
all: compile-javac compile-miniCompiler
|
||||
|
||||
compile-javac:
|
||||
#javac -d src/test/resources/output/javac src/test/resources/input/CompilerInput.java
|
||||
|
||||
compile-miniCompiler:
|
||||
cd ../.. ; mvn -DskipTests install
|
||||
cd ../.. ; mvn exec:java -DgenJar=true -DgenClass=true -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'"
|
||||
# cp src/main/resources/output/CompilerInput.class src/test/resources/output/miniCompiler
|
||||
|
||||
test-miniCompiler:
|
||||
# move the compiled class to the test/main folder
|
||||
mv src/main/resources/output/CompilerInput.class src/test/java/main/
|
||||
# compile the test class
|
||||
javac src/test/java/main/EndToEndTester.java
|
||||
# run the test class
|
||||
java -cp src/test/java/main EndToEndTester
|
||||
|
||||
clean:
|
||||
# clean main output folders
|
||||
rm -f src/main/resources/output/*.class
|
||||
rm -f src/main/resources/output/*.jar
|
||||
# clean resources output folders
|
||||
rm -f src/test/resources/output/javac/*.class
|
||||
rm -f src/test/resources/output/miniCompiler/*.class
|
||||
rm -f src/test/resources/output/miniCompiler/*.jar
|
||||
# clean logs
|
||||
rm -f src/main/resources/logs/*
|
||||
# clean test/java/main folders from .class files for End-to-End tests
|
||||
rm -f src/test/java/main/*.class
|
||||
# clean javac output from every folder
|
||||
rm -f src/test/resources/input/*/*.class
|
||||
# clean test results from maven surefire plugin
|
||||
rm -f ../../target/surefire-reports/*.txt
|
BIN
Parser_Dokumentation.pdf
Normal file
BIN
Parser_Dokumentation.pdf
Normal file
Binary file not shown.
136
README.md
Normal file
136
README.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# "Nicht Haskel 2.0" Java Compiler
|
||||
|
||||
Realisation of a subset of the Java Standard Compiler in the course Compiler Construction of the 4th semester Computer Science at the Duale Hochschule Stuttgart (Horb).
|
||||
|
||||
This project aims to provide a simplified version of the Java compiler, focusing on key language features and demonstrating the principles of compiler construction.
|
||||
|
||||
## Realised Java syntax
|
||||
|
||||
- **Data types**: `int`, `boolean`, `char`
|
||||
- **Access modifier**: `public`, `protected`, `private`
|
||||
- **Operators**: `=` `+` `-` `*` `%` `/` `>` `<` `>=` `<=` `==` `!=` `!` `&&` `||` `++` `--`
|
||||
- **Keywords**: `class`, `this`, `while`, `do`, `if`, `else`, `for`, `return`, `new`, `switch`, `case`, `break`, `default`, `:`
|
||||
- **Statements**:
|
||||
- `if` ... `if else` ... `else`;
|
||||
- `while` ... ;
|
||||
- `do` ... `while`;
|
||||
- `for`;
|
||||
- **Comments**:
|
||||
- Single line: `// comment`
|
||||
- Multi-line: `/* comment */`
|
||||
- **Further functions**:
|
||||
- All methods are overloadable
|
||||
- High maintainability and expandability through implementation of the visitor pattern
|
||||
- Logging Input and Outputs
|
||||
- Error Handling in the Semantic Check
|
||||
|
||||
## Project Structure
|
||||
|
||||
```plain
|
||||
src/
|
||||
└── main/
|
||||
├── java/
|
||||
│ ├── ast/ -> Defining the structure of the AST
|
||||
│ ├── bytecode/ -> Generate Java bytecode
|
||||
│ ├── main/ -> Running the compiler
|
||||
│ ├── parser/
|
||||
│ │ ├── astBuilder/ -> Builder creating the AST
|
||||
│ │ ├── generated/ -> Antlr generated grammar
|
||||
│ │ └── grammar/ -> Antlr grammar
|
||||
│ ├── semantic/ -> Running the semantic check
|
||||
│ └── visitor/ -> Visitor interface
|
||||
└── resources/
|
||||
test/
|
||||
└── java/
|
||||
│ ├── main/ -> Running E2E tests
|
||||
│ ├── parser/ -> Performs tests on the parser
|
||||
│ ├── semantic/ -> Performs tests on the semantic check
|
||||
└── resources/ -> Ressources for running the Tests
|
||||
```
|
||||
|
||||
## Class-Diagramm AST
|
||||
|
||||

|
||||
|
||||
## Distribution of the realisation
|
||||
|
||||
### i22030 & i22035
|
||||
Ausführliche Beschreibung der Parser Umsetzung:
|
||||
|
||||

|
||||
|
||||
Parser:
|
||||
- Grammar -> (src/main/java/parser/grammar)
|
||||
- Scanner
|
||||
- Parser
|
||||
- Abstract Syntax Tree (AST) -> (src/main/java/ast)
|
||||
- AstBuilder -> (src/main/java/parser/astBuilder)
|
||||
|
||||
Parser tests:
|
||||
- ParserTests -> (src/test/java/parser)
|
||||
- TestCases -> (src/test/resources/input/singeFeatureTests)
|
||||
|
||||
Other:
|
||||
- Documentation -> (README.md)
|
||||
- Ast Class-Diagramm -> (ast.png)
|
||||
- PowerPoint
|
||||
|
||||
### i22005
|
||||
Semantic check:
|
||||
- Set all types and check whether types have been used correctly
|
||||
- Contexts -> (src/main/java/semantic/context)
|
||||
- Exceptions Handling -> (src/main/java/semantic/exceptions)
|
||||
|
||||
Semantic Tests:
|
||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
||||
- Exception and feature test -> (src/test/resources/input/typedAstExceptionsTests)
|
||||
|
||||
### i22007
|
||||
Bytecode generation:
|
||||
- Complete bytecode generation -> (src/mein/java/bytecode)
|
||||
|
||||
### i22011
|
||||
Tests and execution:
|
||||
- Makefile
|
||||
- Running Compiler -> (src/main/main)
|
||||
- Running E2E tests -> (src/test/main)
|
||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
||||
|
||||
|
||||
## Used Tools
|
||||
|
||||
- [Maven 4.0](https://maven.apache.org/index.html)
|
||||
- Used for automating the build process and managing dependencies.
|
||||
- [ANTLR4 v.13.1](https://www.antlr.org/)
|
||||
- Used to parse the input Java code into the Abstract Syntax Tree.
|
||||
|
||||
## How to run the compiler
|
||||
### Possibilities
|
||||
### 1. Start miniCompiler using make:
|
||||
Make needs to be installed
|
||||
```bash
|
||||
cd .\src\test\ ; make clean compile-miniCompiler
|
||||
```
|
||||
|
||||
### 2. Start miniCompiler using jar:
|
||||
If you do not have the .jar, download it [here](https://gitea.hb.dhbw-stuttgart.de/i22005/NichtHaskell2.0/src/branch/main/JavaCompiler-1.0-jar-with-dependencies.jar) or compile it using mvn package or make first
|
||||
```
|
||||
java.exe -DgenJar=bool -DgenClass=bool -jar path_to_jar\jarName.jar 'path_to_input_file.java' 'path_to_output_directory'
|
||||
```
|
||||
|
||||
Example (jar needs to be in the target directory)
|
||||
```bash
|
||||
java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'
|
||||
```
|
||||
|
||||
- set DgenJar true, to generate the jar, false for no jar
|
||||
|
||||
```
|
||||
DgenJar=true
|
||||
```
|
||||
|
||||
- set DgenClass true, to generate class files, false for no class files
|
||||
|
||||
```
|
||||
DgenClass=true
|
||||
```
|
64
pom.xml
64
pom.xml
@@ -4,13 +4,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<groupId>de.dhbw-stuttgart</groupId>
|
||||
<artifactId>JavaCompiler</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<java.version>22</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@@ -19,7 +20,25 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.9.3</version> <!-- Change the version as needed -->
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-suite-engine</artifactId>
|
||||
<version>1.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -52,8 +71,41 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id> <!-- this is used for inheritance merges -->
|
||||
<phase>package</phase> <!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>main.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven_central</id>
|
||||
<name>Maven Central</name>
|
||||
<url>https://repo.maven.apache.org/maven2/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
@@ -1,132 +0,0 @@
|
||||
import ast.ASTNode;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import ast.ProgramNode;
|
||||
//import bytecode.ByteCodeGenerator;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
//import semantic.SemanticAnalyzer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if(args.length > 0) {
|
||||
|
||||
} else {
|
||||
try {
|
||||
CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/CompilerInput.java"));
|
||||
parseFile(codeCharStream);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void parseFile(CharStream codeCharStream) {
|
||||
/* ------------------------- Scanner -> tokens ------------------------- */
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
// Printing the tokens
|
||||
// tokenStream.fill();
|
||||
// List<Token> tokens = tokenStream.getTokens();
|
||||
// System.out.println("-------------------- Scanner -> tokens --------------------");
|
||||
// for (Token token : tokens) {
|
||||
// String tokenType = SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType());
|
||||
// String tokenText = token.getText();
|
||||
// // System.out.println("Token Type: " + tokenType + ", Token Text: " +
|
||||
// // tokenText);
|
||||
// System.out.println(tokenType + " " + tokenText);
|
||||
// }
|
||||
// System.out.println();
|
||||
|
||||
/* ------------------------- Parser -> Parsetree ------------------------- */
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
// Printing the parse tree
|
||||
// System.out.println("-------------------- Parser -> Parsetree --------------------");
|
||||
// System.out.println(parseTree.toStringTree(parser));
|
||||
// printTree(parseTree, parser, 0);
|
||||
// System.out.println();
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
System.out.println(abstractSyntaxTree);
|
||||
// Printing the AST
|
||||
// System.out.println("-------------------- AST builder -> AST --------------------");
|
||||
// // System.out.println("AST: " + ast.toString());
|
||||
// printAST(abstractSyntaxTree, 0);
|
||||
// System.out.println();
|
||||
|
||||
/*
|
||||
* ------------------------- Semantic Analyzer -> Tast -------------------------
|
||||
*/
|
||||
//SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||
//ProgramNode typedAst = (ProgramNode) semanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
// Printing the Tast
|
||||
System.out.println("Tast generated");
|
||||
|
||||
/*
|
||||
* ------------------------- Bytecode Generator -> Bytecode
|
||||
* -------------------------
|
||||
*/
|
||||
//ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator();
|
||||
//byteCodeGenerator.generateByteCode(abstractSyntaxTree);
|
||||
//byteCodeGenerator.visit(typedAst);
|
||||
System.out.println("Bytecode generated");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to print the parse tree in a structured format.
|
||||
* It recursively traverses the tree and prints the rule names and text of the
|
||||
* nodes.
|
||||
*
|
||||
* @param tree The parse tree to be printed.
|
||||
* @param parser The parser used to parse the input. It's used to get the rule
|
||||
* names.
|
||||
* @param indent The current indentation level. It's used to format the output.
|
||||
*/
|
||||
public static void printTree(ParseTree tree, Parser parser, int indent) {
|
||||
// Create an indentation string based on the current indentation level
|
||||
String indentString = " ".repeat(indent * 2);
|
||||
|
||||
// If the tree node is an instance of RuleContext (i.e., it's an internal node),
|
||||
// print the rule name
|
||||
if (tree instanceof RuleContext) {
|
||||
int ruleIndex = ((RuleContext) tree).getRuleIndex();
|
||||
String ruleName = parser.getRuleNames()[ruleIndex];
|
||||
System.out.println(indentString + ruleName);
|
||||
} else {
|
||||
// If the tree node is not an instance of RuleContext (i.e., it's a leaf node),
|
||||
// print the text of the node
|
||||
System.out.println(indentString + tree.getText());
|
||||
}
|
||||
|
||||
// Recursively print the children of the current node, increasing the
|
||||
// indentation level
|
||||
for (int i = 0; i < tree.getChildCount(); i++) {
|
||||
printTree(tree.getChild(i), parser, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void printAST(ASTNode node, int indent) {
|
||||
String indentString = " ".repeat(indent * 2);
|
||||
System.out.println(indentString + node.getClass().toString());
|
||||
|
||||
// for (ASTNode child : node.) {
|
||||
// printAST(child, indent + 1);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package ast;
|
||||
|
||||
public interface ASTNode { }
|
||||
public interface ASTNode {
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package ast;
|
||||
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.members.MemberNode;
|
||||
import ast.members.MethodNode;
|
||||
import bytecode.visitor.ClassVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -15,31 +15,21 @@ public class ClassNode implements ASTNode, Visitable {
|
||||
public AccessModifierNode accessType;
|
||||
public String identifier;
|
||||
public List<MemberNode> members = new ArrayList<>();
|
||||
public boolean hasConstructor;
|
||||
|
||||
public ClassNode() {}
|
||||
public ClassNode() {
|
||||
|
||||
public ClassNode(String accessType, String identifier){
|
||||
}
|
||||
|
||||
public ClassNode(String accessType, String identifier) {
|
||||
this.accessType = new AccessModifierNode(accessType);
|
||||
this.identifier = identifier;
|
||||
hasConstructor = false;
|
||||
}
|
||||
|
||||
public void addMember(MemberNode member) {
|
||||
if (member instanceof ConstructorNode) {
|
||||
this.hasConstructor = true;
|
||||
}
|
||||
members.add(member);
|
||||
}
|
||||
|
||||
public void ensureConstructor(){
|
||||
if(!hasConstructor) {
|
||||
ConstructorNode constructor = new ConstructorNode(new AccessModifierNode("public"), identifier);
|
||||
members.addFirst(constructor);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MethodNode> getMethods(){
|
||||
public List<MethodNode> getMethods() {
|
||||
List<MethodNode> methods = new ArrayList<>();
|
||||
for (MemberNode member : members) {
|
||||
if (member instanceof MethodNode methodNode) {
|
||||
@@ -54,4 +44,9 @@ public class ClassNode implements ASTNode, Visitable {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ClassVisitor classVisitor) {
|
||||
classVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package ast;
|
||||
|
||||
import bytecode.visitor.ProgramVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -18,4 +19,9 @@ public class ProgramNode implements ASTNode, Visitable {
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ProgramVisitor programVisitor) {
|
||||
programVisitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
@@ -1,19 +0,0 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class BinaryExpressionNode implements IExpressionNode {
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.type.type.*;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class CalculationExpressionNode extends BinaryExpressionNode {
|
||||
public CalculationExpressionNode calculationExpression;
|
||||
public EnumLineOperator operator;
|
||||
public DotExpressionNode dotExpression;
|
||||
|
||||
public CalculationExpressionNode(CalculationExpressionNode calculationExpression, String operator, DotExpressionNode dotExpression) {
|
||||
this.calculationExpression = calculationExpression;
|
||||
setOperator(operator);
|
||||
this.dotExpression = dotExpression;
|
||||
}
|
||||
|
||||
public CalculationExpressionNode(DotExpressionNode dotExpression) {
|
||||
this.dotExpression = dotExpression;
|
||||
}
|
||||
|
||||
private void setOperator(String operator) {
|
||||
if(operator.equals("+")) {
|
||||
this.operator = EnumLineOperator.PLUS;
|
||||
} else if(operator.equals("-")) {
|
||||
this.operator = EnumLineOperator.MINUS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.type.type.*;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DotExpressionNode extends BinaryExpressionNode {
|
||||
public DotExpressionNode dotExpression;
|
||||
public EnumDotOperator operator;
|
||||
public DotSubstractionExpressionNode dotSubstractionExpression;
|
||||
|
||||
public DotExpressionNode(DotExpressionNode dotExpression, String operator, DotSubstractionExpressionNode dotSubstractionExpression) {
|
||||
this.dotExpression = dotExpression;
|
||||
setOperator(operator);
|
||||
this.dotSubstractionExpression = dotSubstractionExpression;
|
||||
}
|
||||
|
||||
public DotExpressionNode(DotSubstractionExpressionNode dotSubstractionExpression) {
|
||||
this.dotSubstractionExpression = dotSubstractionExpression;
|
||||
}
|
||||
|
||||
private void setOperator(String operator) {
|
||||
if(operator.equals("*")) {
|
||||
this.operator = EnumDotOperator.MULT;
|
||||
} else if(operator.equals("/")) {
|
||||
this.operator = EnumDotOperator.DIV;
|
||||
} else if(operator.equals("%")) {
|
||||
this.operator = EnumDotOperator.MOD;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import ast.type.ValueNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DotSubstractionExpressionNode extends BinaryExpressionNode {
|
||||
public ValueNode value;
|
||||
public String identifier;
|
||||
public MemberAccessNode memberAccess;
|
||||
public MethodCallStatementExpressionNode methodCall;
|
||||
public CalculationExpressionNode calculationExpression;
|
||||
|
||||
public DotSubstractionExpressionNode(ValueNode value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public DotSubstractionExpressionNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public DotSubstractionExpressionNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
public DotSubstractionExpressionNode(MethodCallStatementExpressionNode methodCall, CalculationExpressionNode calculationExpression) {
|
||||
this.methodCall = methodCall;
|
||||
this.calculationExpression = calculationExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
package ast.expression.binaryexpression;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class NonCalculationExpressionNode extends BinaryExpressionNode {
|
||||
public UnaryExpressionNode unaryExpression;
|
||||
public EnumNonCalculationOperator operator;
|
||||
public IExpressionNode expression;
|
||||
|
||||
public NonCalculationExpressionNode(UnaryExpressionNode unaryExpression, String operator, IExpressionNode expression) {
|
||||
this.unaryExpression = unaryExpression;
|
||||
setOperator(operator);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
private void setOperator(String operator) {
|
||||
if(operator.equals("&&")) {
|
||||
this.operator = EnumNonCalculationOperator.AND;
|
||||
} else if(operator.equals("||")) {
|
||||
this.operator = EnumNonCalculationOperator.OR;
|
||||
} else if(operator.equals(">")) {
|
||||
this.operator = EnumNonCalculationOperator.GREATER;
|
||||
} else if(operator.equals("<")) {
|
||||
this.operator = EnumNonCalculationOperator.LESS;
|
||||
} else if(operator.equals(">=")) {
|
||||
this.operator = EnumNonCalculationOperator.GREATER_EQUAL;
|
||||
} else if(operator.equals("<=")) {
|
||||
this.operator = EnumNonCalculationOperator.LESS_EQUAL;
|
||||
} else if(operator.equals("==")) {
|
||||
this.operator = EnumNonCalculationOperator.EQUAL;
|
||||
} else if(operator.equals("!=")) {
|
||||
this.operator = EnumNonCalculationOperator.NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package ast.expression.unaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MemberAccessNode implements ASTNode {
|
||||
public Boolean thisExpr;
|
||||
public List<String> identifiers = new ArrayList<>();
|
||||
|
||||
public MemberAccessNode(Boolean thisExpr) {
|
||||
this.thisExpr = thisExpr;
|
||||
}
|
||||
|
||||
public void addIdentifier(String identifier) {
|
||||
identifiers.add(identifier);
|
||||
}
|
||||
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package ast.expression.unaryexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
|
||||
public class NotExpressionNode implements ASTNode {
|
||||
public IExpressionNode expression;
|
||||
|
||||
public NotExpressionNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package ast.expression;
|
||||
package ast.expressions;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
@@ -8,4 +8,6 @@ public interface IExpressionNode extends ASTNode, Visitable {
|
||||
|
||||
ITypeNode getType();
|
||||
|
||||
void setType(ITypeNode type);
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class BinaryNode implements IExpressionNode, Visitable {
|
||||
|
||||
public ITypeNode typeNode;
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return typeNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(ITypeNode type) {
|
||||
this.typeNode = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class CalculationNode extends BinaryNode {
|
||||
public CalculationNode calculationExpression;
|
||||
public EnumLineOperator operator;
|
||||
public DotNode dotExpression;
|
||||
|
||||
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
||||
this.calculationExpression = calculationExpression;
|
||||
setOperator(operator);
|
||||
this.dotExpression = dotExpression;
|
||||
}
|
||||
|
||||
public CalculationNode(DotNode dotExpression) {
|
||||
this.dotExpression = dotExpression;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
if (operator != null) {
|
||||
if (operator.equals("+")) {
|
||||
this.operator = EnumLineOperator.PLUS;
|
||||
} else if (operator.equals("-")) {
|
||||
this.operator = EnumLineOperator.MINUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
40
src/main/java/ast/expressions/binaryexpressions/DotNode.java
Normal file
40
src/main/java/ast/expressions/binaryexpressions/DotNode.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class DotNode extends BinaryNode {
|
||||
public DotNode dotExpression;
|
||||
public EnumDotOperator operator;
|
||||
public DotSubtractionNode dotSubtractionExpression;
|
||||
|
||||
public DotNode(DotNode dotExpression, String operator, DotSubtractionNode dotSubtractionExpression) {
|
||||
this.dotExpression = dotExpression;
|
||||
setOperator(operator);
|
||||
this.dotSubtractionExpression = dotSubtractionExpression;
|
||||
}
|
||||
|
||||
public DotNode(DotSubtractionNode dotSubtractionExpression) {
|
||||
this.dotSubtractionExpression = dotSubtractionExpression;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
switch (operator) {
|
||||
case "*" -> this.operator = EnumDotOperator.MULT;
|
||||
case "/" -> this.operator = EnumDotOperator.DIV;
|
||||
case "%" -> this.operator = EnumDotOperator.MOD;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||
import ast.type.ValueNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class DotSubtractionNode extends BinaryNode {
|
||||
public ValueNode value;
|
||||
public String identifier;
|
||||
public MemberAccessNode memberAccess;
|
||||
public MethodCallNode methodCall;
|
||||
public CalculationNode calculationExpression;
|
||||
|
||||
public DotSubtractionNode(ValueNode value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public DotSubtractionNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public DotSubtractionNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
public DotSubtractionNode(MethodCallNode methodCall, CalculationNode calculationExpression) {
|
||||
this.methodCall = methodCall;
|
||||
this.calculationExpression = calculationExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package ast.expression.binaryexpression;
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
public enum EnumDotOperator {
|
||||
MULT, DIV, MOD
|
@@ -1,4 +1,4 @@
|
||||
package ast.expression.binaryexpression;
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
public enum EnumLineOperator {
|
||||
PLUS, MINUS
|
@@ -1,4 +1,4 @@
|
||||
package ast.expression.binaryexpression;
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
public enum EnumNonCalculationOperator {
|
||||
AND, OR, GREATER, LESS, GREATER_EQUAL, LESS_EQUAL, EQUAL, NOT_EQUAL
|
@@ -0,0 +1,43 @@
|
||||
package ast.expressions.binaryexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.expressions.unaryexpressions.UnaryNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class NonCalculationNode extends BinaryNode {
|
||||
public UnaryNode unaryExpression;
|
||||
public EnumNonCalculationOperator operator;
|
||||
public IExpressionNode expression;
|
||||
|
||||
public NonCalculationNode(UnaryNode unaryExpression, String operator, IExpressionNode expression) {
|
||||
this.unaryExpression = unaryExpression;
|
||||
setOperator(operator);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
switch (operator) {
|
||||
case "&&" -> this.operator = EnumNonCalculationOperator.AND;
|
||||
case "||" -> this.operator = EnumNonCalculationOperator.OR;
|
||||
case ">" -> this.operator = EnumNonCalculationOperator.GREATER;
|
||||
case "<" -> this.operator = EnumNonCalculationOperator.LESS;
|
||||
case ">=" -> this.operator = EnumNonCalculationOperator.GREATER_EQUAL;
|
||||
case "<=" -> this.operator = EnumNonCalculationOperator.LESS_EQUAL;
|
||||
case "==" -> this.operator = EnumNonCalculationOperator.EQUAL;
|
||||
case "!=" -> this.operator = EnumNonCalculationOperator.NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package ast.expressions.unaryexpressions;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MemberAccessNode implements ASTNode, Visitable {
|
||||
public Boolean thisExpr;
|
||||
public List<String> identifiers = new ArrayList<>();
|
||||
private ITypeNode typeNode;
|
||||
|
||||
public MemberAccessNode(Boolean thisExpr) {
|
||||
this.thisExpr = thisExpr;
|
||||
}
|
||||
|
||||
public void addIdentifier(String identifier) {
|
||||
identifiers.add(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
public ITypeNode getTypeNode() {
|
||||
return typeNode;
|
||||
}
|
||||
|
||||
public void setTypeNode(ITypeNode typeNode) {
|
||||
this.typeNode = typeNode;
|
||||
}
|
||||
|
||||
|
||||
}
|
35
src/main/java/ast/expressions/unaryexpressions/NotNode.java
Normal file
35
src/main/java/ast/expressions/unaryexpressions/NotNode.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package ast.expressions.unaryexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class NotNode implements IExpressionNode {
|
||||
public IExpressionNode expression;
|
||||
|
||||
public NotNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeNode getType() {
|
||||
return expression.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(ITypeNode type) {
|
||||
this.expression.setType(type);
|
||||
}
|
||||
}
|
@@ -1,49 +1,50 @@
|
||||
package ast.expression.unaryexpression;
|
||||
package ast.expressions.unaryexpressions;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.statements.IStatementNode;
|
||||
import ast.type.type.*;
|
||||
import ast.type.ValueNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class UnaryExpressionNode implements IExpressionNode {
|
||||
public class UnaryNode implements IExpressionNode {
|
||||
public String thisExp;
|
||||
public String identifier;
|
||||
public MemberAccessNode memberAccess;
|
||||
public ValueNode value;
|
||||
public NotExpressionNode notExpression;
|
||||
public NotNode notExpression;
|
||||
public IStatementNode statement;
|
||||
public IExpressionNode expression;
|
||||
private ITypeNode type;
|
||||
public ITypeNode type;
|
||||
|
||||
public UnaryExpressionNode(String value) {
|
||||
if(Objects.equals(value, "this")) {
|
||||
public UnaryNode(String value) {
|
||||
if (Objects.equals(value, "this")) {
|
||||
this.thisExp = "this";
|
||||
} else {
|
||||
this.identifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
public UnaryExpressionNode(MemberAccessNode memberAccess) {
|
||||
public UnaryNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
public UnaryExpressionNode(ValueNode value) {
|
||||
public UnaryNode(ValueNode value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public UnaryExpressionNode(NotExpressionNode notExpression) {
|
||||
public UnaryNode(NotNode notExpression) {
|
||||
this.notExpression = notExpression;
|
||||
}
|
||||
|
||||
public UnaryExpressionNode(IStatementNode statement) {
|
||||
public UnaryNode(IStatementNode statement) {
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
public UnaryExpressionNode(IExpressionNode expression) {
|
||||
public UnaryNode(IExpressionNode expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@@ -61,4 +62,9 @@ public class UnaryExpressionNode implements IExpressionNode {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
package ast.member;
|
||||
|
||||
import ast.block.BlockNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstructorNode extends MethodNode {
|
||||
public AccessModifierNode accessType;
|
||||
public String identifier;
|
||||
public List<ParameterNode> parameters = new ArrayList<>();
|
||||
public BlockNode body;
|
||||
|
||||
public ConstructorNode(AccessModifierNode accessType, String identifier) {
|
||||
this.accessType = accessType;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public ConstructorNode(String accessType, String identifier, BlockNode body) {
|
||||
this.accessType = new AccessModifierNode(accessType);
|
||||
this.identifier = identifier;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void addParameter(ParameterNode parameterNode) {
|
||||
parameters.add(parameterNode);
|
||||
}
|
||||
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
package ast.member;
|
||||
|
||||
import ast.block.BlockNode;
|
||||
|
||||
public class MainMethodNode extends MethodNode {
|
||||
public BlockNode block;
|
||||
|
||||
public MainMethodNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
}
|
41
src/main/java/ast/members/ConstructorNode.java
Normal file
41
src/main/java/ast/members/ConstructorNode.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package ast.members;
|
||||
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.statements.BlockNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConstructorNode extends MethodNode implements Visitable {
|
||||
public ConstructorNode(String accessType, String identifier, BlockNode block) {
|
||||
this.accesModifier = new AccessModifierNode(accessType);
|
||||
this.identifier = identifier;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public void addParameter(ParameterNode parameterNode) {
|
||||
parameters.add(parameterNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
public boolean isSame(MethodNode methodNode) {
|
||||
if (!(Objects.equals(this.identifier, methodNode.getIdentifier())) || getParameters().size() != methodNode.getParameters().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.getParameters().size(); i++) {
|
||||
if (!this.getParameters().get(i).type.equals(methodNode.getParameters().get(i).type)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
package ast.member;
|
||||
package ast.members;
|
||||
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
import bytecode.visitor.ClassVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class FieldNode implements MemberNode, Visitable {
|
||||
@@ -11,7 +12,7 @@ public class FieldNode implements MemberNode, Visitable {
|
||||
public ITypeNode type;
|
||||
public String identifier;
|
||||
|
||||
public FieldNode(AccessModifierNode accessTypeNode, ITypeNode type, String name){
|
||||
public FieldNode(AccessModifierNode accessTypeNode, ITypeNode type, String name) {
|
||||
this.accessTypeNode = accessTypeNode;
|
||||
this.type = type;
|
||||
this.identifier = name;
|
||||
@@ -22,4 +23,9 @@ public class FieldNode implements MemberNode, Visitable {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ClassVisitor classVisitor) {
|
||||
classVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
17
src/main/java/ast/members/MainMethodNode.java
Normal file
17
src/main/java/ast/members/MainMethodNode.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package ast.members;
|
||||
|
||||
import ast.statements.BlockNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class MainMethodNode extends MethodNode implements Visitable {
|
||||
|
||||
public MainMethodNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package ast.member;
|
||||
package ast.members;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
@@ -10,7 +10,8 @@ import ast.ASTNode;
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = MethodNode.class, name = "Method"),
|
||||
|
||||
@JsonSubTypes.Type(value = FieldNode.class, name = "Field") }
|
||||
@JsonSubTypes.Type(value = FieldNode.class, name = "Field")}
|
||||
)
|
||||
|
||||
public interface MemberNode extends ASTNode {}
|
||||
public interface MemberNode extends ASTNode {
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
package ast.member;
|
||||
package ast.members;
|
||||
|
||||
import ast.block.BlockNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.statements.BlockNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.type.*;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -15,15 +15,16 @@ import java.util.Objects;
|
||||
|
||||
public class MethodNode implements MemberNode, Visitable {
|
||||
public AccessModifierNode accesModifier;
|
||||
private ITypeNode type;
|
||||
public ITypeNode type;
|
||||
public Boolean voidType;
|
||||
private String identifier;
|
||||
public String identifier;
|
||||
public List<ParameterNode> parameters = new ArrayList<>();
|
||||
public BlockNode block;
|
||||
|
||||
public MethodNode() {}
|
||||
public MethodNode() {
|
||||
}
|
||||
|
||||
public MethodNode(String accessModifier, ITypeNode type, Boolean voidType, String identifier, BlockNode block){
|
||||
public MethodNode(String accessModifier, ITypeNode type, Boolean voidType, String identifier, BlockNode block) {
|
||||
this.accesModifier = new AccessModifierNode(accessModifier);
|
||||
this.type = type;
|
||||
this.voidType = voidType;
|
||||
@@ -39,14 +40,14 @@ public class MethodNode implements MemberNode, Visitable {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public boolean isSame(MethodNode methodNode){
|
||||
public boolean isSame(MethodNode methodNode) {
|
||||
if (!(Objects.equals(this.identifier, methodNode.getIdentifier())) || type.equals(methodNode.type)
|
||||
|| getParameters().size() != methodNode.getParameters().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.getParameters().size(); i++) {
|
||||
if (this.getParameters().get(i).type.equals(methodNode.getParameters().get(i).type)) {
|
||||
if (!this.getParameters().get(i).type.equals(methodNode.getParameters().get(i).type)) {
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
package ast.parameter;
|
||||
package ast.parameters;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.type.*;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class ParameterNode implements ASTNode, Visitable {
|
@@ -1,31 +0,0 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ForStatementNode implements IStatementNode {
|
||||
public IExpressionNode statementExpressionInit;
|
||||
public IStatementNode localVariableDeclarationInit;
|
||||
public IExpressionNode expression;
|
||||
public IExpressionNode statementExpression;
|
||||
|
||||
public ForStatementNode(IExpressionNode statementExpressionInit, IExpressionNode expression, IExpressionNode statementExpression) {
|
||||
this.statementExpressionInit = statementExpressionInit;
|
||||
this.expression = expression;
|
||||
this.statementExpression = statementExpression;
|
||||
}
|
||||
|
||||
public ForStatementNode(IStatementNode localVariableDeclarationInit, IExpressionNode expression, IExpressionNode statementExpression) {
|
||||
this.localVariableDeclarationInit = localVariableDeclarationInit;
|
||||
this.expression = expression;
|
||||
this.statementExpression = statementExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ReturnStatementNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
public Boolean voidReturn = false;
|
||||
|
||||
public ReturnStatementNode(IExpressionNode expression) {
|
||||
if(expression != null) {
|
||||
this.expression = expression;
|
||||
} else {
|
||||
voidReturn = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package ast.statement.ifstatement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class ElseStatementNode implements IStatementNode {
|
||||
public BlockNode block;
|
||||
|
||||
public ElseStatementNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
package ast.statement.ifstatement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IfElseStatementNode implements IStatementNode {
|
||||
public IfStatementNode ifStatement;
|
||||
public List<ElseStatementNode> elseStatements = new ArrayList<>();
|
||||
|
||||
public IfElseStatementNode(IfStatementNode ifStatement) {
|
||||
this.ifStatement = ifStatement;
|
||||
}
|
||||
|
||||
public void addElseStatement(ElseStatementNode elseStatement) {
|
||||
elseStatements.add(elseStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package ast.statement.ifstatement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class IfStatementNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
public BlockNode block;
|
||||
|
||||
public IfStatementNode(IExpressionNode expression, BlockNode block) {
|
||||
this.expression = expression;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package ast.statement.statementexpression;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class AssignStatementExpressionNode implements IStatementExpressionNode {
|
||||
public AssignableExpressionNode assignable;
|
||||
public IExpressionNode expression;
|
||||
|
||||
public AssignStatementExpressionNode(AssignableExpressionNode assignable, IExpressionNode expression) {
|
||||
this.assignable = assignable;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package ast.statement.statementexpression;
|
||||
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class AssignableExpressionNode implements IStatementExpressionNode {
|
||||
public String identifier;
|
||||
|
||||
public MemberAccessNode memberAccess;
|
||||
|
||||
public AssignableExpressionNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public AssignableExpressionNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
package ast.statement.statementexpression;
|
||||
|
||||
import ast.statement.IStatementNode;
|
||||
|
||||
public interface IStatementExpressionNode extends IStatementNode {}
|
@@ -1,5 +0,0 @@
|
||||
package ast.statement.statementexpression.crementExpression;
|
||||
|
||||
public enum CrementType {
|
||||
PREFIX, SUFFIX
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package ast.statement.statementexpression.crementExpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class DecrementExpressionNode implements IStatementExpressionNode {
|
||||
public CrementType crementType;
|
||||
public AssignableExpressionNode assignableExpression;
|
||||
|
||||
public DecrementExpressionNode(CrementType crementType, AssignableExpressionNode assignableExpression) {
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package ast.statement.statementexpression.crementExpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class IncrementExpressionNode implements IStatementExpressionNode {
|
||||
public CrementType crementType;
|
||||
public AssignableExpressionNode assignableExpression;
|
||||
|
||||
public IncrementExpressionNode(CrementType crementType, AssignableExpressionNode assignableExpression) {
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package ast.statement.statementexpression.methodcallstatementnexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ChainedMethodNode implements ASTNode {
|
||||
public String identifier;
|
||||
public List<IExpressionNode> expressions = new ArrayList<>();
|
||||
|
||||
public ChainedMethodNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public void addExpression(IExpressionNode expression) {
|
||||
expressions.add(expression);
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package ast.statement.statementexpression.methodcallstatementnexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.statement.statementexpression.IStatementExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodCallStatementExpressionNode implements IStatementExpressionNode {
|
||||
public TargetNode target;
|
||||
public List<ChainedMethodNode> chainedMethods = new ArrayList<>();
|
||||
public String identifier;
|
||||
public List<IExpressionNode> expressions = new ArrayList<>();
|
||||
|
||||
public MethodCallStatementExpressionNode(TargetNode target, String identifier) {
|
||||
this.target = target;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public void addChainedMethod(ChainedMethodNode chainedMethode) {
|
||||
chainedMethods.add(chainedMethode);
|
||||
}
|
||||
|
||||
public void addExpression(IExpressionNode expression) {
|
||||
expressions.add(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
package ast.statement.statementexpression.methodcallstatementnexpression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.statement.statementexpression.NewDeclarationStatementExpressionNode;
|
||||
|
||||
public class TargetNode implements ASTNode {
|
||||
public Boolean thisTar;
|
||||
public MemberAccessNode memberAccess;
|
||||
public NewDeclarationStatementExpressionNode newDeclaration;
|
||||
public String identifier;
|
||||
|
||||
public TargetNode(Boolean thisTar) {
|
||||
this.thisTar = thisTar;
|
||||
}
|
||||
|
||||
public TargetNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
public TargetNode(NewDeclarationStatementExpressionNode newDeclaration) {
|
||||
this.newDeclaration = newDeclaration;
|
||||
}
|
||||
|
||||
public TargetNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
}
|
27
src/main/java/ast/statementexpressions/AssignNode.java
Normal file
27
src/main/java/ast/statementexpressions/AssignNode.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package ast.statementexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class AssignNode implements IStatementExpressionNode {
|
||||
public AssignableNode assignable;
|
||||
public IExpressionNode expression;
|
||||
|
||||
public AssignNode(AssignableNode assignable, IExpressionNode expression) {
|
||||
this.assignable = assignable;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
32
src/main/java/ast/statementexpressions/AssignableNode.java
Normal file
32
src/main/java/ast/statementexpressions/AssignableNode.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package ast.statementexpressions;
|
||||
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class AssignableNode implements IStatementExpressionNode {
|
||||
public String identifier;
|
||||
public ITypeNode typeNode;
|
||||
|
||||
public MemberAccessNode memberAccess;
|
||||
|
||||
public AssignableNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public AssignableNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
public void setTypeNode(ITypeNode typeNode) {
|
||||
this.typeNode = typeNode;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
package ast.statementexpressions;
|
||||
|
||||
import ast.statements.IStatementNode;
|
||||
|
||||
public interface IStatementExpressionNode extends IStatementNode {
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package ast.statementexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NewDeclarationNode implements IStatementExpressionNode {
|
||||
public String identifier;
|
||||
public List<IExpressionNode> expressions = new ArrayList<>();
|
||||
|
||||
public NewDeclarationNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public void addExpression(IExpressionNode expression) {
|
||||
expressions.add(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
package ast.statementexpressions.crementexpressions;
|
||||
|
||||
public enum CrementType {
|
||||
PREFIX, SUFFIX
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package ast.statementexpressions.crementexpressions;
|
||||
|
||||
import ast.statementexpressions.AssignableNode;
|
||||
import ast.statementexpressions.IStatementExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class DecrementNode implements IStatementExpressionNode, Visitable {
|
||||
public CrementType crementType;
|
||||
public AssignableNode assignableExpression;
|
||||
|
||||
public DecrementNode(CrementType crementType, AssignableNode assignableExpression) {
|
||||
this.crementType = crementType;
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package ast.statementexpressions.crementexpressions;
|
||||
|
||||
import ast.statementexpressions.AssignableNode;
|
||||
import ast.statementexpressions.IStatementExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import visitor.Visitable;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class IncrementNode implements IStatementExpressionNode, Visitable {
|
||||
public CrementType crementType;
|
||||
public AssignableNode assignableExpression;
|
||||
|
||||
public IncrementNode(CrementType crementType, AssignableNode assignableExpression) {
|
||||
this.crementType = crementType;
|
||||
this.assignableExpression = assignableExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
}
|
@@ -1,18 +1,20 @@
|
||||
package ast.statement.statementexpression;
|
||||
package ast.statementexpressions.methodcallstatementnexpressions;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NewDeclarationStatementExpressionNode implements IStatementExpressionNode {
|
||||
public class ChainedMethodNode implements ASTNode, Visitable {
|
||||
public String identifier;
|
||||
public List<IExpressionNode> expressions = new ArrayList<>();
|
||||
|
||||
public NewDeclarationStatementExpressionNode(String identifier) {
|
||||
public ChainedMethodNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@@ -22,7 +24,6 @@ public class NewDeclarationStatementExpressionNode implements IStatementExpressi
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package ast.statementexpressions.methodcallstatementnexpressions;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.statements.IStatementNode;
|
||||
import ast.type.type.ITypeNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodCallNode implements IStatementNode {
|
||||
public TargetNode target;
|
||||
public ITypeNode type;
|
||||
public List<ChainedMethodNode> chainedMethods = new ArrayList<>();
|
||||
public String identifier;
|
||||
public List<IExpressionNode> parameters = new ArrayList<>();
|
||||
|
||||
public MethodCallNode(TargetNode target, String identifier) {
|
||||
this.target = target;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public void addChainedMethod(ChainedMethodNode chainedMethode) {
|
||||
chainedMethods.add(chainedMethode);
|
||||
}
|
||||
|
||||
public void addExpression(IExpressionNode parameter) {
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package ast.statementexpressions.methodcallstatementnexpressions;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.statementexpressions.NewDeclarationNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class TargetNode implements ASTNode, Visitable {
|
||||
public Boolean thisTar;
|
||||
public MemberAccessNode memberAccess;
|
||||
public NewDeclarationNode newDeclaration;
|
||||
public String identifier;
|
||||
|
||||
public TargetNode(Boolean thisTar) {
|
||||
this.thisTar = thisTar;
|
||||
}
|
||||
|
||||
public TargetNode(MemberAccessNode memberAccess) {
|
||||
this.memberAccess = memberAccess;
|
||||
}
|
||||
|
||||
public TargetNode(NewDeclarationNode newDeclaration) {
|
||||
this.newDeclaration = newDeclaration;
|
||||
}
|
||||
|
||||
public TargetNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,21 +1,18 @@
|
||||
package ast.block;
|
||||
package ast.statements;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.IStatementNode;
|
||||
import ast.statement.ReturnStatementNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
import java.beans.Visibility;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BlockNode implements ASTNode, Visitable {
|
||||
public class BlockNode implements IStatementNode, Visitable {
|
||||
public List<IStatementNode> statements = new ArrayList<>();
|
||||
public Boolean hasReturnStatement = false;
|
||||
|
||||
public BlockNode() {}
|
||||
public BlockNode() {
|
||||
}
|
||||
|
||||
public void addStatement(IStatementNode statement) {
|
||||
statements.add(statement);
|
||||
@@ -26,4 +23,9 @@ public class BlockNode implements ASTNode, Visitable {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
19
src/main/java/ast/statements/ElseNode.java
Normal file
19
src/main/java/ast/statements/ElseNode.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package ast.statements;
|
||||
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class ElseNode implements IStatementNode {
|
||||
public BlockNode block;
|
||||
|
||||
public ElseNode(BlockNode block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package ast.statement;
|
||||
package ast.statements;
|
||||
|
||||
import ast.ASTNode;
|
||||
import visitor.Visitable;
|
33
src/main/java/ast/statements/IfElseNode.java
Normal file
33
src/main/java/ast/statements/IfElseNode.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package ast.statements;
|
||||
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IfElseNode implements IStatementNode {
|
||||
public IfNode ifStatement;
|
||||
public List<IfNode> elseIfStatements = new ArrayList<>();
|
||||
public ElseNode elseStatement;
|
||||
|
||||
public IfElseNode(IfNode ifStatement, ElseNode elseNode) {
|
||||
this.ifStatement = ifStatement;
|
||||
this.elseStatement = elseNode;
|
||||
}
|
||||
|
||||
public void addElseIfStatement(IfNode elseIfStament) {
|
||||
elseIfStatements.add(elseIfStament);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
}
|
@@ -1,16 +1,14 @@
|
||||
package ast.statement;
|
||||
package ast.statements;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class WhileStatementNode implements IStatementNode {
|
||||
public class IfNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
public BlockNode block;
|
||||
|
||||
public WhileStatementNode(IExpressionNode expression, BlockNode block) {
|
||||
public IfNode(IExpressionNode expression, BlockNode block) {
|
||||
this.expression = expression;
|
||||
this.block = block;
|
||||
}
|
||||
@@ -19,5 +17,4 @@ public class WhileStatementNode implements IStatementNode {
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
package ast.statement;
|
||||
package ast.statements;
|
||||
|
||||
import ast.expression.IExpressionNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class LocalVariableDeclarationNode implements IStatementNode {
|
||||
public ITypeNode type;
|
||||
@@ -23,4 +24,9 @@ public class LocalVariableDeclarationNode implements IStatementNode {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
30
src/main/java/ast/statements/ReturnNode.java
Normal file
30
src/main/java/ast/statements/ReturnNode.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package ast.statements;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class ReturnNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
public Boolean voidReturn = false;
|
||||
|
||||
public ReturnNode(IExpressionNode expression) {
|
||||
if (expression != null) {
|
||||
this.expression = expression;
|
||||
} else {
|
||||
voidReturn = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
30
src/main/java/ast/statements/WhileNode.java
Normal file
30
src/main/java/ast/statements/WhileNode.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package ast.statements;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
|
||||
public class WhileNode implements IStatementNode {
|
||||
public IExpressionNode expression;
|
||||
public BlockNode block;
|
||||
|
||||
public WhileNode(IExpressionNode expression, BlockNode block) {
|
||||
this.expression = expression;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public void test() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
}
|
@@ -8,7 +8,7 @@ public class AccessModifierNode {
|
||||
}
|
||||
|
||||
private void setModifier(String accessType) {
|
||||
switch(accessType) {
|
||||
switch (accessType) {
|
||||
case "public":
|
||||
this.accessType = EnumAccessModifierNode.PUBLIC;
|
||||
break;
|
||||
|
@@ -1,8 +1,12 @@
|
||||
package ast.type;
|
||||
|
||||
import ast.ASTNode;
|
||||
import bytecode.visitor.MethodVisitor;
|
||||
import semantic.SemanticVisitor;
|
||||
import semantic.TypeCheckResult;
|
||||
import visitor.Visitable;
|
||||
|
||||
public class ValueNode implements ASTNode {
|
||||
public class ValueNode implements ASTNode, Visitable {
|
||||
public EnumValueNode valueType;
|
||||
public String value;
|
||||
|
||||
@@ -10,4 +14,14 @@ public class ValueNode implements ASTNode {
|
||||
this.valueType = valueType;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MethodVisitor methodVisitor) {
|
||||
methodVisitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package ast.type.type;
|
||||
|
||||
public class BaseType implements ITypeNode {
|
||||
|
||||
private TypeEnum typeEnum;
|
||||
public final TypeEnum typeEnum;
|
||||
|
||||
public BaseType(TypeEnum typeEnum) {
|
||||
this.typeEnum = typeEnum;
|
||||
@@ -21,10 +21,6 @@ public class BaseType implements ITypeNode {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BaseType other = (BaseType) obj;
|
||||
if (typeEnum != other.typeEnum)
|
||||
return false;
|
||||
return true;
|
||||
return typeEnum == other.typeEnum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
package ast.type.type;
|
||||
|
||||
public interface ITypeNode {
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package ast.type.type;
|
||||
|
||||
public class ReferenceType implements ITypeNode{
|
||||
public class ReferenceType implements ITypeNode {
|
||||
|
||||
private String identifier;
|
||||
public final String identifier;
|
||||
|
||||
public ReferenceType(String identifier) {
|
||||
this.identifier = identifier;
|
||||
@@ -22,11 +22,8 @@ public class ReferenceType implements ITypeNode{
|
||||
return false;
|
||||
ReferenceType other = (ReferenceType) obj;
|
||||
if (identifier == null) {
|
||||
if (other.identifier != null)
|
||||
return false;
|
||||
} else if (!identifier.equals(other.identifier))
|
||||
return false;
|
||||
return true;
|
||||
return other.identifier == null;
|
||||
} else return identifier.equals(other.identifier);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,6 +4,6 @@ public enum TypeEnum {
|
||||
VOID,
|
||||
INT,
|
||||
CHAR,
|
||||
BOOL;
|
||||
|
||||
BOOL,
|
||||
NULL
|
||||
}
|
||||
|
@@ -2,15 +2,89 @@ package bytecode;
|
||||
|
||||
import ast.ProgramNode;
|
||||
import ast.ClassNode;
|
||||
import ast.members.MainMethodNode;
|
||||
import ast.members.MemberNode;
|
||||
import bytecode.visitor.ProgramVisitor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class ByteCodeGenerator implements ProgramVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ProgramNode programNode) {
|
||||
for (ClassNode classDeclarationNode : programNode.classes) {
|
||||
ClassCodeGen classCodeGen = new ClassCodeGen();
|
||||
// classDeclarationNode.accept(classCodeGen);
|
||||
private JarOutputStream jarOutputStream;
|
||||
private ByteArrayOutputStream byteArrayOutputStream;
|
||||
private final String outputDirectory;
|
||||
private final boolean generateJar;
|
||||
private final boolean generateClassFiles;
|
||||
|
||||
public ByteCodeGenerator(String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
||||
this.outputDirectory = outputDirectory;
|
||||
this.generateJar = generateJar;
|
||||
this.generateClassFiles = generateClassFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ProgramNode programNode) {
|
||||
if(generateJar) {
|
||||
byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
|
||||
boolean foundMainClass = false;
|
||||
for (ClassNode classNode : programNode.classes) {
|
||||
if (foundMainClass) {
|
||||
break;
|
||||
}
|
||||
for (MemberNode memberNode : classNode.members) {
|
||||
if (memberNode instanceof MainMethodNode) {
|
||||
manifest.getMainAttributes().putValue("Main-Class", classNode.identifier);
|
||||
foundMainClass = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jarOutputStream = new JarOutputStream(byteArrayOutputStream, manifest);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (ClassNode classDeclarationNode : programNode.classes) {
|
||||
ClassCodeGen classCodeGen = new ClassCodeGen(jarOutputStream, outputDirectory, generateJar, generateClassFiles);
|
||||
classDeclarationNode.accept(classCodeGen);
|
||||
}
|
||||
|
||||
try {
|
||||
jarOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
saveJarFile(byteArrayOutputStream.toByteArray(), "output.jar");
|
||||
} else {
|
||||
for (ClassNode classDeclarationNode : programNode.classes) {
|
||||
ClassCodeGen classCodeGen = new ClassCodeGen(jarOutputStream, outputDirectory, generateJar, generateClassFiles);
|
||||
classDeclarationNode.accept(classCodeGen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveJarFile(byte[] jarBytes, String jarFileName) {
|
||||
File directory = new File(outputDirectory);
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs();
|
||||
}
|
||||
|
||||
File jarFile = new File(directory, jarFileName);
|
||||
try (FileOutputStream fos = new FileOutputStream(jarFile)) {
|
||||
fos.write(jarBytes);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,31 +1,44 @@
|
||||
package bytecode;
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.members.FieldNode;
|
||||
import ast.members.MemberNode;
|
||||
import ast.members.MethodNode;
|
||||
import ast.type.type.BaseType;
|
||||
import bytecode.visitor.ClassVisitor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
|
||||
public class ClassCodeGen implements ClassVisitor {
|
||||
private Mapper mapper;
|
||||
private final Mapper mapper;
|
||||
private ClassWriter classWriter;
|
||||
private final JarOutputStream jarOutputStream;
|
||||
private final String outputDirectory;
|
||||
private final boolean generateJar;
|
||||
private final boolean generateClassFiles;
|
||||
|
||||
public ClassCodeGen() {
|
||||
mapper = new Mapper();
|
||||
public ClassCodeGen(JarOutputStream jarOutputStream, String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
||||
this.mapper = new Mapper();
|
||||
this.jarOutputStream = jarOutputStream;
|
||||
this.outputDirectory = outputDirectory;
|
||||
this.generateJar = generateJar;
|
||||
this.generateClassFiles = generateClassFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassNode classNode) {
|
||||
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
// classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
|
||||
// "java/lang/Object", null);
|
||||
classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
|
||||
"java/lang/Object", null);
|
||||
|
||||
for (MemberNode memberNode : classNode.members) {
|
||||
if (memberNode instanceof FieldNode) {
|
||||
@@ -36,28 +49,31 @@ public class ClassCodeGen implements ClassVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
classWriter.visitEnd();
|
||||
printIntoClassFile(classWriter.toByteArray(), classNode.identifier);
|
||||
if (generateJar) {
|
||||
writeToJar(classWriter.toByteArray(), classNode.identifier);
|
||||
}
|
||||
if (generateClassFiles) {
|
||||
printIntoClassFile(classWriter.toByteArray(), classNode.identifier, outputDirectory);
|
||||
}
|
||||
|
||||
classWriter.visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FieldNode fieldNode) {
|
||||
if(fieldNode.type instanceof BaseType baseTypeNode){
|
||||
// classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
|
||||
if (fieldNode.type instanceof BaseType) {
|
||||
classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar((BaseType) fieldNode.type), null, null);
|
||||
}
|
||||
classWriter.visitEnd();
|
||||
}
|
||||
|
||||
private void printIntoClassFile(byte[] byteCode, String name) {
|
||||
String directoryPath = "src/main/java/classFileOutput";
|
||||
File directory = new File(directoryPath);
|
||||
private void printIntoClassFile(byte[] byteCode, String name, String outputDirectory) {
|
||||
File directory = new File(outputDirectory);
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs();
|
||||
}
|
||||
|
||||
String filePath = directoryPath + "/" + name + ".class";
|
||||
String filePath = outputDirectory + "/" + name + ".class";
|
||||
try {
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
|
||||
fileOutputStream.write(byteCode);
|
||||
@@ -66,4 +82,15 @@ public class ClassCodeGen implements ClassVisitor {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeToJar(byte[] byteCode, String className) {
|
||||
try {
|
||||
JarEntry jarEntry = new JarEntry(className + ".class");
|
||||
jarOutputStream.putNextEntry(jarEntry);
|
||||
jarOutputStream.write(byteCode);
|
||||
jarOutputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,41 +1,65 @@
|
||||
package bytecode;
|
||||
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.type.*;
|
||||
import ast.type.type.BaseType;
|
||||
import ast.type.type.ITypeNode;
|
||||
import ast.type.type.ReferenceType;
|
||||
import ast.type.type.TypeEnum;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Mapper {
|
||||
// public int mapAccessTypeToOpcode(AccessModifierNode type) {
|
||||
// switch (type.enumAccessTypeNode) {
|
||||
// case EnumAccessTypeNode.PUBLIC:
|
||||
// return Opcodes.ACC_PUBLIC;
|
||||
// case EnumAccessTypeNode.PRIVATE:
|
||||
// return Opcodes.ACC_PRIVATE;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
public int mapAccessTypeToOpcode(AccessModifierNode accessModifierNode) {
|
||||
switch (accessModifierNode.accessType) {
|
||||
case EnumAccessModifierNode.PUBLIC:
|
||||
return Opcodes.ACC_PUBLIC;
|
||||
case EnumAccessModifierNode.PRIVATE:
|
||||
return Opcodes.ACC_PRIVATE;
|
||||
case EnumAccessModifierNode.PUBLIC_STATIC:
|
||||
return Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
|
||||
case EnumAccessModifierNode.PRIVATE_STATIC:
|
||||
return Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
|
||||
// String descriptor = "(";
|
||||
// for(ParameterNode parameterNode : parameterListNode.parameters) {
|
||||
// descriptor += getTypeChar(EnumTypeNode.INT);
|
||||
// }
|
||||
// descriptor += ")";
|
||||
// descriptor += getTypeChar(baseTypeNode.enumType);
|
||||
// return descriptor;
|
||||
// }
|
||||
public String generateMethodDescriptor(ITypeNode type, List<ParameterNode> parameters) {
|
||||
String descriptor = "(";
|
||||
for (ParameterNode parameterNode : parameters) {
|
||||
if(parameterNode.type instanceof BaseType) {
|
||||
descriptor += getTypeChar((BaseType) parameterNode.type);
|
||||
} else {
|
||||
ReferenceType referenceType = (ReferenceType) parameterNode.type;
|
||||
descriptor += "L" + referenceType.getIdentifier() + ";";
|
||||
}
|
||||
}
|
||||
descriptor += ")";
|
||||
if(type instanceof BaseType) {
|
||||
descriptor += getTypeChar((BaseType) type);
|
||||
} else if(type instanceof ReferenceType) {
|
||||
descriptor += "L" + ((ReferenceType) type).getIdentifier() +";";
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
// public String getTypeChar(TypeEnum enumTypeNode) {
|
||||
// String typeChar = "";
|
||||
// switch (enumTypeNode) {
|
||||
// case TypeEnum.INT:
|
||||
// typeChar = "I";
|
||||
// break;
|
||||
// case TypeEnum.CHAR:
|
||||
// typeChar = "C";
|
||||
// break;
|
||||
// case TypeEnum.BOOLEAN:
|
||||
// typeChar = "Z";
|
||||
// break;
|
||||
// }
|
||||
// return typeChar;
|
||||
// }
|
||||
public String getTypeChar(BaseType type) {
|
||||
String typeChar = "";
|
||||
switch (type.getTypeEnum()) {
|
||||
case TypeEnum.INT:
|
||||
typeChar = "I";
|
||||
break;
|
||||
case TypeEnum.CHAR:
|
||||
typeChar = "C";
|
||||
break;
|
||||
case TypeEnum.BOOL:
|
||||
typeChar = "Z";
|
||||
break;
|
||||
case TypeEnum.VOID:
|
||||
typeChar = "V";
|
||||
break;
|
||||
}
|
||||
return typeChar;
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,32 @@
|
||||
package bytecode;
|
||||
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.expressions.binaryexpressions.*;
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.expressions.unaryexpressions.NotNode;
|
||||
import ast.expressions.unaryexpressions.UnaryNode;
|
||||
import ast.members.ConstructorNode;
|
||||
import ast.members.MainMethodNode;
|
||||
import ast.members.MethodNode;
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.statementexpressions.AssignNode;
|
||||
import ast.statementexpressions.AssignableNode;
|
||||
import ast.statementexpressions.NewDeclarationNode;
|
||||
import ast.statementexpressions.crementexpressions.CrementType;
|
||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||
import ast.statements.*;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.EnumAccessModifierNode;
|
||||
import ast.type.ValueNode;
|
||||
import ast.type.type.BaseType;
|
||||
import ast.type.type.ReferenceType;
|
||||
import ast.type.type.TypeEnum;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -13,82 +36,709 @@ import static org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
||||
|
||||
private ClassWriter classWriter;
|
||||
private Mapper mapper;
|
||||
private final ClassWriter classWriter;
|
||||
private final Mapper mapper;
|
||||
private MethodVisitor methodVisitor;
|
||||
|
||||
private List<String> localVaribales;
|
||||
private final List<String> localVariables;
|
||||
|
||||
public MethodCodeGen(ClassWriter classWriter) {
|
||||
this.classWriter = classWriter;
|
||||
mapper = new Mapper();
|
||||
localVaribales = new ArrayList<>();
|
||||
localVariables = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
// Method nodes
|
||||
|
||||
@Override
|
||||
public void visit(ConstructorNode constructorNode) {
|
||||
// methodVisitor =
|
||||
// classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
|
||||
// "<init>",
|
||||
// "()V",
|
||||
// null,
|
||||
// null);
|
||||
methodVisitor =
|
||||
classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.accesModifier),
|
||||
"<init>",
|
||||
mapper.generateMethodDescriptor(new BaseType(TypeEnum.VOID), constructorNode.parameters),
|
||||
null,
|
||||
null);
|
||||
|
||||
methodVisitor.visitCode();
|
||||
localVariables.add("this");
|
||||
// Add all method parameters to localVariables
|
||||
for (ParameterNode parameterNode : constructorNode.parameters) {
|
||||
localVariables.add(parameterNode.identifier);
|
||||
}
|
||||
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||
methodVisitor.visitInsn(RETURN);
|
||||
methodVisitor.visitMaxs(1, 1);
|
||||
|
||||
// Visit all statements
|
||||
for (IStatementNode statementNode : constructorNode.block.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
|
||||
methodVisitor.visitMaxs(0, 0);
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MainMethodNode mainMethodNode) {
|
||||
AccessModifierNode accessModifierNode = new AccessModifierNode("");
|
||||
accessModifierNode.accessType = EnumAccessModifierNode.PUBLIC_STATIC;
|
||||
methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
"main",
|
||||
"([Ljava/lang/String;)V",
|
||||
null,
|
||||
null);
|
||||
|
||||
methodVisitor.visitCode();
|
||||
localVariables.add("this");
|
||||
localVariables.add("args");
|
||||
|
||||
// Visit all statements
|
||||
for (IStatementNode statementNode : mainMethodNode.block.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
|
||||
methodVisitor.visitMaxs(0, 0);
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodNode methodNode) {
|
||||
// if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
|
||||
// methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
|
||||
// methodNode.identifier,
|
||||
// mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
|
||||
// null,
|
||||
// null);
|
||||
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.accesModifier),
|
||||
methodNode.getIdentifier(),
|
||||
mapper.generateMethodDescriptor(methodNode.getType(), methodNode.parameters),
|
||||
null,
|
||||
null);
|
||||
|
||||
methodVisitor.visitCode();
|
||||
localVaribales.add("this");
|
||||
// for (ParameterNode parameterNode : methodNode.parameters.parameters) {
|
||||
// localVaribales.add(parameterNode.identifier);
|
||||
// }
|
||||
methodVisitor.visitCode();
|
||||
localVariables.add("this");
|
||||
// Add all method parameters to localVariables
|
||||
for (ParameterNode parameterNode : methodNode.parameters) {
|
||||
localVariables.add(parameterNode.identifier);
|
||||
}
|
||||
|
||||
//test();
|
||||
methodVisitor.visitMaxs(1, localVaribales.size());
|
||||
methodVisitor.visitEnd();
|
||||
// }
|
||||
// Visit all statements
|
||||
for (IStatementNode statementNode : methodNode.block.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
|
||||
methodVisitor.visitMaxs(0, 0);
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
|
||||
// public void test() {
|
||||
// Label start = new Label();
|
||||
// Label loop = new Label();
|
||||
// Label end = new Label();
|
||||
// methodVisitor.visitLabel(start);
|
||||
// //methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
|
||||
// //methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
// methodVisitor.visitLdcInsn(99);
|
||||
// // methodVisitor.visitInsn(Opcodes.ICONST_0);
|
||||
// //methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
|
||||
// methodVisitor.visitLabel(loop);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
// methodVisitor.visitInsn(Opcodes.ICONST_5);
|
||||
// methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
|
||||
// methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
// "java/lang/System", "out",
|
||||
// "Ljava/io/PrintStream;");
|
||||
// methodVisitor.visitLdcInsn("Bytecode");
|
||||
// methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
// "java/io/PrintStream", "println",
|
||||
// "(Ljava/lang/String;)V", false);
|
||||
// methodVisitor.visitIincInsn(1, 1);
|
||||
// methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
|
||||
// methodVisitor.visitLabel(end);
|
||||
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
|
||||
// methodVisitor.visitInsn(Opcodes.IRETURN);
|
||||
// methodVisitor.visitEnd();
|
||||
// }
|
||||
|
||||
// Binary expressions
|
||||
|
||||
@Override
|
||||
public void visit(BinaryNode binaryNode) {
|
||||
binaryNode.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CalculationNode calculationNode) {
|
||||
if (calculationNode.calculationExpression != null) {
|
||||
calculationNode.calculationExpression.accept(this);
|
||||
}
|
||||
if (calculationNode.dotExpression != null) {
|
||||
calculationNode.dotExpression.accept(this);
|
||||
}
|
||||
if (calculationNode.operator != null) {
|
||||
switch (calculationNode.operator) {
|
||||
case PLUS:
|
||||
methodVisitor.visitInsn(IADD);
|
||||
break;
|
||||
case MINUS:
|
||||
methodVisitor.visitInsn(ISUB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DotNode dotNode) {
|
||||
if (dotNode.dotExpression != null) {
|
||||
dotNode.dotExpression.accept(this);
|
||||
}
|
||||
if (dotNode.dotSubtractionExpression != null) {
|
||||
dotNode.dotSubtractionExpression.accept(this);
|
||||
}
|
||||
if (dotNode.operator != null) {
|
||||
switch (dotNode.operator) {
|
||||
case DIV:
|
||||
methodVisitor.visitInsn(IDIV);
|
||||
break;
|
||||
case MULT:
|
||||
methodVisitor.visitInsn(IMUL);
|
||||
break;
|
||||
case MOD:
|
||||
methodVisitor.visitInsn(IREM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DotSubtractionNode dotSubtractionNode) {
|
||||
if (dotSubtractionNode.value != null) {
|
||||
dotSubtractionNode.value.accept(this);
|
||||
} else if (dotSubtractionNode.identifier != null) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(dotSubtractionNode.identifier));
|
||||
} else if (dotSubtractionNode.memberAccess != null) {
|
||||
dotSubtractionNode.memberAccess.accept(this);
|
||||
} else if (dotSubtractionNode.methodCall != null) {
|
||||
dotSubtractionNode.methodCall.accept(this);
|
||||
} else if (dotSubtractionNode.calculationExpression != null) {
|
||||
dotSubtractionNode.calculationExpression.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NonCalculationNode nonCalculationNode) {
|
||||
Label labelFalse = new Label();
|
||||
Label labelTrue = new Label();
|
||||
switch (nonCalculationNode.operator) {
|
||||
case AND:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IFEQ, labelFalse); // Value compared to 0 (false)
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IFEQ, labelFalse);
|
||||
break;
|
||||
case OR:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IFNE, labelTrue);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IFEQ, labelFalse);
|
||||
break;
|
||||
case GREATER:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IF_ICMPLE, labelFalse);
|
||||
break;
|
||||
case LESS:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IF_ICMPGE, labelFalse);
|
||||
break;
|
||||
case GREATER_EQUAL:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IF_ICMPLT, labelFalse);
|
||||
break;
|
||||
case LESS_EQUAL:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IF_ICMPGT, labelFalse);
|
||||
break;
|
||||
case EQUAL:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
if (nonCalculationNode.unaryExpression.getType() instanceof BaseType && nonCalculationNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitJumpInsn(IF_ICMPNE, labelFalse);
|
||||
} else {
|
||||
methodVisitor.visitJumpInsn(IF_ACMPNE, labelFalse);
|
||||
}
|
||||
break;
|
||||
case NOT_EQUAL:
|
||||
nonCalculationNode.unaryExpression.accept(this);
|
||||
nonCalculationNode.expression.accept(this);
|
||||
if (nonCalculationNode.unaryExpression.getType() instanceof BaseType && nonCalculationNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitJumpInsn(IF_ICMPEQ, labelFalse);
|
||||
} else {
|
||||
methodVisitor.visitJumpInsn(IF_ACMPEQ, labelFalse);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Label labelEndLogicalExpression = new Label();
|
||||
|
||||
methodVisitor.visitLabel(labelTrue);
|
||||
methodVisitor.visitInsn(ICONST_1); // true
|
||||
methodVisitor.visitJumpInsn(GOTO, labelEndLogicalExpression);
|
||||
|
||||
methodVisitor.visitLabel(labelFalse);
|
||||
methodVisitor.visitInsn(ICONST_0); // false
|
||||
|
||||
methodVisitor.visitLabel(labelEndLogicalExpression);
|
||||
}
|
||||
|
||||
|
||||
// Unary expressions
|
||||
|
||||
@Override
|
||||
public void visit(MemberAccessNode memberAccessNode) {
|
||||
// Only used to get, not to put
|
||||
int localVarIndex = localVariables.indexOf("memberAccessNode.identifier"); // TODO
|
||||
if (localVarIndex >= 0) { // local var object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else { // this field
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
}
|
||||
|
||||
if (memberAccessNode.getTypeNode() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, memberAccessNode.identifiers.get(0), memberAccessNode.identifiers.get(1), mapper.getTypeChar((BaseType) memberAccessNode.getTypeNode()));
|
||||
} else if (memberAccessNode.getTypeNode() instanceof ReferenceType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, memberAccessNode.identifiers.get(0), memberAccessNode.identifiers.get(1), "L" + ((ReferenceType) memberAccessNode.getTypeNode()).getIdentifier() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NotNode notNode) {
|
||||
Label labelFalse = new Label();
|
||||
Label labelTrue = new Label();
|
||||
|
||||
notNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(Opcodes.IFNE, labelFalse); // false if value is true (value != 0)
|
||||
|
||||
Label labelEndLogicalExpression = new Label();
|
||||
|
||||
methodVisitor.visitLabel(labelTrue);
|
||||
methodVisitor.visitInsn(ICONST_1); // true
|
||||
methodVisitor.visitJumpInsn(GOTO, labelEndLogicalExpression);
|
||||
|
||||
methodVisitor.visitLabel(labelFalse);
|
||||
methodVisitor.visitInsn(ICONST_0); // false
|
||||
|
||||
methodVisitor.visitLabel(labelEndLogicalExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnaryNode unaryNode) {
|
||||
if (unaryNode.thisExp != null) {
|
||||
methodVisitor.visitVarInsn(ALOAD, 0); // this
|
||||
} else if (unaryNode.memberAccess != null) {
|
||||
unaryNode.memberAccess.setTypeNode(unaryNode.getType());
|
||||
unaryNode.memberAccess.accept(this);
|
||||
} else if (unaryNode.value != null) {
|
||||
unaryNode.value.accept(this);
|
||||
} else if (unaryNode.notExpression != null) {
|
||||
unaryNode.notExpression.accept(this);
|
||||
} else if (unaryNode.statement != null) {
|
||||
unaryNode.statement.accept(this);
|
||||
} else if (unaryNode.expression != null) {
|
||||
unaryNode.expression.accept(this);
|
||||
} else if (unaryNode.identifier != null) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(unaryNode.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Statements
|
||||
|
||||
@Override
|
||||
public void visit(BlockNode blockNode) {
|
||||
for (IStatementNode statementNode : blockNode.statements) {
|
||||
statementNode.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IfElseNode ifElseNode) {
|
||||
Label elseLabel = new Label();
|
||||
Label endLabel = new Label();
|
||||
|
||||
Label[] elseIfLabels = new Label[ifElseNode.elseIfStatements.size()];
|
||||
for (int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
|
||||
elseIfLabels[i] = new Label();
|
||||
}
|
||||
|
||||
ifElseNode.ifStatement.expression.accept(this);
|
||||
if (ifElseNode.elseIfStatements.isEmpty()) {
|
||||
// No else if
|
||||
methodVisitor.visitJumpInsn(IFEQ, elseLabel);
|
||||
} else {
|
||||
// else if statements
|
||||
methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[0]);
|
||||
}
|
||||
|
||||
ifElseNode.ifStatement.block.accept(this); // accept if block
|
||||
|
||||
methodVisitor.visitJumpInsn(GOTO, endLabel);
|
||||
|
||||
for (int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
|
||||
methodVisitor.visitLabel(elseIfLabels[i]);
|
||||
ifElseNode.elseIfStatements.get(i).expression.accept(this);
|
||||
if (i + 1 < elseIfLabels.length) {
|
||||
// at least one more else if
|
||||
methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[i + 1]);
|
||||
} else {
|
||||
methodVisitor.visitJumpInsn(IFEQ, elseLabel);
|
||||
}
|
||||
ifElseNode.elseIfStatements.get(i).block.accept(this);
|
||||
methodVisitor.visitJumpInsn(GOTO, endLabel);
|
||||
}
|
||||
|
||||
if (ifElseNode.elseStatement != null) {
|
||||
methodVisitor.visitLabel(elseLabel);
|
||||
ifElseNode.elseStatement.block.accept(this);
|
||||
} else {
|
||||
methodVisitor.visitLabel(elseLabel);
|
||||
}
|
||||
|
||||
methodVisitor.visitLabel(endLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LocalVariableDeclarationNode localVariableDeclarationNode) {
|
||||
if (localVariableDeclarationNode.expression != null) {
|
||||
// Process expression
|
||||
localVariableDeclarationNode.expression.accept(this);
|
||||
|
||||
if (localVariableDeclarationNode.expression instanceof UnaryNode) {
|
||||
UnaryNode unaryNode = (UnaryNode) localVariableDeclarationNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode) {
|
||||
IncrementNode incrementNode = (IncrementNode) unaryNode.statement;
|
||||
incrementNode.assignableExpression.typeNode = unaryNode.type;
|
||||
loadIncrement(incrementNode);
|
||||
} else if (unaryNode.statement instanceof DecrementNode) {
|
||||
DecrementNode decrementNode = (DecrementNode) unaryNode.statement;
|
||||
decrementNode.assignableExpression.typeNode = unaryNode.type;
|
||||
loadDecrement(decrementNode);
|
||||
}
|
||||
}
|
||||
|
||||
// add local var to list if not in list
|
||||
if (!localVariables.contains(localVariableDeclarationNode.identifier)) {
|
||||
localVariables.add(localVariableDeclarationNode.identifier);
|
||||
}
|
||||
if (localVariableDeclarationNode.type instanceof BaseType) {
|
||||
methodVisitor.visitVarInsn(ISTORE, localVariables.indexOf(localVariableDeclarationNode.identifier));
|
||||
} else if (localVariableDeclarationNode.type instanceof ReferenceType) {
|
||||
methodVisitor.visitVarInsn(ASTORE, localVariables.indexOf(localVariableDeclarationNode.identifier));
|
||||
}
|
||||
} else {
|
||||
// Local var declaration
|
||||
if (!localVariables.contains(localVariableDeclarationNode.identifier)) {
|
||||
localVariables.add(localVariableDeclarationNode.identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignNode assignNode) {
|
||||
if (assignNode.assignable.memberAccess != null) { // this / object
|
||||
assignNode.assignable.memberAccess.setTypeNode(assignNode.assignable.typeNode);
|
||||
if (assignNode.expression instanceof UnaryNode) {
|
||||
UnaryNode unaryNode = (UnaryNode) assignNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode) {
|
||||
IncrementNode incrementNode = (IncrementNode) unaryNode.statement;
|
||||
if (incrementNode.crementType.equals(CrementType.PREFIX)) { // ++i
|
||||
incrementNode.accept(this); // crement
|
||||
fieldOrObjectVarCrementAssign(assignNode); // assign
|
||||
} else { // i++
|
||||
fieldOrObjectVarCrementAssign(assignNode); // assign
|
||||
incrementNode.accept(this); // crement
|
||||
}
|
||||
} else if (unaryNode.statement instanceof DecrementNode) {
|
||||
DecrementNode decrementNode = (DecrementNode) unaryNode.statement;
|
||||
if (decrementNode.crementType.equals(CrementType.PREFIX)) {
|
||||
decrementNode.accept(this); // crement
|
||||
fieldOrObjectVarCrementAssign(assignNode); // assign
|
||||
} else {
|
||||
fieldOrObjectVarCrementAssign(assignNode); // assign
|
||||
decrementNode.accept(this); // crement
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assignFieldOrObjectVar(assignNode);
|
||||
}
|
||||
} else { // local var
|
||||
if (assignNode.expression instanceof UnaryNode) {
|
||||
UnaryNode unaryNode = (UnaryNode) assignNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode || unaryNode.statement instanceof DecrementNode) {
|
||||
localVarCrementAssign(assignNode);
|
||||
}
|
||||
} else {
|
||||
assignNode.expression.accept(this);
|
||||
assignLocalVar(assignNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadIncrement(IncrementNode incrementNode) {
|
||||
AssignableNode assignableNode = incrementNode.assignableExpression;
|
||||
if (assignableNode.memberAccess != null) {
|
||||
assignableNode.memberAccess.accept(this);
|
||||
} else {
|
||||
if (assignableNode.typeNode instanceof BaseType) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(assignableNode.identifier));
|
||||
} else if (assignableNode.typeNode instanceof ReferenceType) {
|
||||
methodVisitor.visitVarInsn(ALOAD, localVariables.indexOf(assignableNode.identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadDecrement(DecrementNode decrementNode) {
|
||||
AssignableNode assignableNode = decrementNode.assignableExpression;
|
||||
if (assignableNode.memberAccess != null) {
|
||||
assignableNode.memberAccess.accept(this);
|
||||
} else {
|
||||
if (assignableNode.typeNode instanceof BaseType) {
|
||||
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(assignableNode.identifier));
|
||||
} else if (assignableNode.typeNode instanceof ReferenceType) {
|
||||
methodVisitor.visitVarInsn(ALOAD, localVariables.indexOf(assignableNode.identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assignLocalVar(AssignNode assignNode) {
|
||||
if (!localVariables.contains(assignNode.assignable.identifier)) {
|
||||
localVariables.add(assignNode.assignable.identifier);
|
||||
}
|
||||
|
||||
if (assignNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitVarInsn(ISTORE, localVariables.indexOf(assignNode.assignable.identifier));
|
||||
} else if (assignNode.expression.getType() instanceof ReferenceType) {
|
||||
methodVisitor.visitVarInsn(ASTORE, localVariables.indexOf(assignNode.assignable.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
private void assignFieldOrObjectVar(AssignNode assignNode) {
|
||||
int localVarIndex = localVariables.indexOf(assignNode.assignable.identifier);
|
||||
if (localVarIndex >= 0) { // object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else if (assignNode.assignable.memberAccess.thisExpr) { // this
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
} else {
|
||||
localVariables.add(assignNode.assignable.identifier);
|
||||
}
|
||||
|
||||
assignNode.expression.accept(this);
|
||||
|
||||
if (assignNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, assignNode.assignable.memberAccess.identifiers.get(0), assignNode.assignable.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) assignNode.expression.getType()));
|
||||
} else if (assignNode.expression.getType() instanceof ReferenceType) {
|
||||
ReferenceType referenceType = (ReferenceType) assignNode.expression.getType();
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, assignNode.assignable.memberAccess.identifiers.get(0), assignNode.assignable.memberAccess.identifiers.get(1), "L" + referenceType.getIdentifier() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
private void localVarCrementAssign(AssignNode assignNode) {
|
||||
UnaryNode unaryNode = (UnaryNode) assignNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode) {
|
||||
IncrementNode incrementNode = (IncrementNode) unaryNode.statement;
|
||||
if (incrementNode.crementType.equals(CrementType.PREFIX)) { // ++i
|
||||
incrementNode.accept(this);
|
||||
incrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadIncrement(incrementNode);
|
||||
assignLocalVar(assignNode);
|
||||
} else { // i++
|
||||
incrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadIncrement(incrementNode);
|
||||
assignLocalVar(assignNode);
|
||||
incrementNode.accept(this);
|
||||
}
|
||||
} else if (unaryNode.statement instanceof DecrementNode) {
|
||||
DecrementNode decrementNode = (DecrementNode) unaryNode.statement;
|
||||
if (decrementNode.crementType.equals(CrementType.PREFIX)) {
|
||||
decrementNode.accept(this);
|
||||
decrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadDecrement(decrementNode);
|
||||
assignLocalVar(assignNode);
|
||||
} else {
|
||||
decrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadDecrement(decrementNode);
|
||||
assignLocalVar(assignNode);
|
||||
decrementNode.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fieldOrObjectVarCrementAssign(AssignNode assignNode) {
|
||||
int localVarIndex = localVariables.indexOf(assignNode.assignable.identifier);
|
||||
if (localVarIndex >= 0) { // object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else if (assignNode.assignable.memberAccess.thisExpr) { // field
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
} else {
|
||||
localVariables.add(assignNode.assignable.identifier);
|
||||
}
|
||||
|
||||
UnaryNode unaryNode = (UnaryNode) assignNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode) {
|
||||
IncrementNode incrementNode = (IncrementNode) unaryNode.statement;
|
||||
incrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadIncrement((incrementNode));
|
||||
} else if (unaryNode.statement instanceof DecrementNode) {
|
||||
DecrementNode decrementNode = (DecrementNode) unaryNode.statement;
|
||||
decrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadDecrement(decrementNode);
|
||||
}
|
||||
|
||||
if (assignNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, assignNode.assignable.memberAccess.identifiers.get(0), assignNode.assignable.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) assignNode.expression.getType()));
|
||||
} else if (assignNode.expression.getType() instanceof ReferenceType) {
|
||||
ReferenceType referenceType = (ReferenceType) assignNode.expression.getType();
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, assignNode.assignable.memberAccess.identifiers.get(0), assignNode.assignable.memberAccess.identifiers.get(1), "L" + referenceType.getIdentifier() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IncrementNode incrementNode) {
|
||||
if (incrementNode.assignableExpression.memberAccess != null) { // Object var / field
|
||||
int localVarIndex = localVariables.indexOf(incrementNode.assignableExpression.identifier);
|
||||
if (localVarIndex >= 0) { // object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else { // this
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
}
|
||||
if (incrementNode.assignableExpression.memberAccess.getTypeNode() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, incrementNode.assignableExpression.memberAccess.identifiers.get(0), incrementNode.assignableExpression.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) incrementNode.assignableExpression.memberAccess.getTypeNode()));
|
||||
} else if (incrementNode.assignableExpression.memberAccess.getTypeNode() instanceof ReferenceType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, incrementNode.assignableExpression.memberAccess.identifiers.get(0), incrementNode.assignableExpression.memberAccess.identifiers.get(1), "L" + (((ReferenceType) incrementNode.assignableExpression.memberAccess.getTypeNode()).getIdentifier() + ";"));
|
||||
}
|
||||
methodVisitor.visitInsn(ICONST_1);
|
||||
methodVisitor.visitInsn(IADD);
|
||||
if (incrementNode.assignableExpression.memberAccess.getTypeNode() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, incrementNode.assignableExpression.memberAccess.identifiers.get(0), incrementNode.assignableExpression.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) incrementNode.assignableExpression.memberAccess.getTypeNode()));
|
||||
} else if (incrementNode.assignableExpression.memberAccess.getTypeNode() instanceof ReferenceType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, incrementNode.assignableExpression.memberAccess.identifiers.get(0), incrementNode.assignableExpression.memberAccess.identifiers.get(1), "L" + (((ReferenceType) incrementNode.assignableExpression.memberAccess.getTypeNode()).getIdentifier() + ";"));
|
||||
}
|
||||
} else { // local var
|
||||
methodVisitor.visitIincInsn(localVariables.indexOf(incrementNode.assignableExpression.identifier), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DecrementNode decrementNode) {
|
||||
if (decrementNode.assignableExpression.memberAccess != null) { // Object var / field
|
||||
int localVarIndex = localVariables.indexOf(decrementNode.assignableExpression.identifier);
|
||||
if (localVarIndex >= 0) { // object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else { // this
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
}
|
||||
if (decrementNode.assignableExpression.memberAccess.getTypeNode() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, decrementNode.assignableExpression.memberAccess.identifiers.get(0), decrementNode.assignableExpression.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) decrementNode.assignableExpression.memberAccess.getTypeNode()));
|
||||
} else if (decrementNode.assignableExpression.memberAccess.getTypeNode() instanceof ReferenceType) {
|
||||
methodVisitor.visitFieldInsn(GETFIELD, decrementNode.assignableExpression.memberAccess.identifiers.get(0), decrementNode.assignableExpression.memberAccess.identifiers.get(1), "L" + (((ReferenceType) decrementNode.assignableExpression.memberAccess.getTypeNode()).getIdentifier() + ";"));
|
||||
}
|
||||
methodVisitor.visitInsn(ICONST_1);
|
||||
methodVisitor.visitInsn(ISUB);
|
||||
if (decrementNode.assignableExpression.memberAccess.getTypeNode() instanceof BaseType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, decrementNode.assignableExpression.memberAccess.identifiers.get(0), decrementNode.assignableExpression.memberAccess.identifiers.get(1), mapper.getTypeChar((BaseType) decrementNode.assignableExpression.memberAccess.getTypeNode()));
|
||||
} else if (decrementNode.assignableExpression.memberAccess.getTypeNode() instanceof ReferenceType) {
|
||||
methodVisitor.visitFieldInsn(PUTFIELD, decrementNode.assignableExpression.memberAccess.identifiers.get(0), decrementNode.assignableExpression.memberAccess.identifiers.get(1), "L" + (((ReferenceType) decrementNode.assignableExpression.memberAccess.getTypeNode()).getIdentifier() + ";"));
|
||||
}
|
||||
} else { // local var
|
||||
methodVisitor.visitIincInsn(localVariables.indexOf(decrementNode.assignableExpression.identifier), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NewDeclarationNode newDeclarationNode) {
|
||||
methodVisitor.visitTypeInsn(NEW, newDeclarationNode.identifier);
|
||||
methodVisitor.visitInsn(DUP);
|
||||
List<ParameterNode> parameterNodes = new ArrayList<>();
|
||||
for (IExpressionNode expressionNode : newDeclarationNode.expressions) {
|
||||
expressionNode.accept(this);
|
||||
parameterNodes.add(new ParameterNode(expressionNode.getType(), ""));
|
||||
}
|
||||
methodVisitor.visitMethodInsn(INVOKESPECIAL, newDeclarationNode.identifier, "<init>", mapper.generateMethodDescriptor(new BaseType(TypeEnum.VOID), parameterNodes), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ValueNode valueNode) {
|
||||
switch (valueNode.valueType) {
|
||||
case INT_VALUE:
|
||||
int intValue = Integer.parseInt(valueNode.value);
|
||||
if (intValue >= Byte.MIN_VALUE && intValue <= Byte.MAX_VALUE) { // load int as byte
|
||||
methodVisitor.visitIntInsn(BIPUSH, intValue);
|
||||
} else if (intValue >= Short.MIN_VALUE && intValue <= Short.MAX_VALUE) { // load int as short
|
||||
methodVisitor.visitIntInsn(SIPUSH, intValue);
|
||||
} else { // load int as const
|
||||
methodVisitor.visitLdcInsn(intValue);
|
||||
}
|
||||
break;
|
||||
case BOOLEAN_VALUE:
|
||||
if (valueNode.value.equals("true")) {
|
||||
methodVisitor.visitInsn(ICONST_1);
|
||||
} else {
|
||||
methodVisitor.visitInsn(ICONST_0);
|
||||
}
|
||||
break;
|
||||
case CHAR_VALUE:
|
||||
char charValue = valueNode.value.charAt(0);
|
||||
if (charValue <= Byte.MAX_VALUE) { // load char as byte
|
||||
methodVisitor.visitIntInsn(BIPUSH, charValue);
|
||||
} else if (charValue <= Short.MAX_VALUE) { // load char as short
|
||||
methodVisitor.visitIntInsn(SIPUSH, charValue);
|
||||
} else { // load char as const
|
||||
methodVisitor.visitLdcInsn(charValue);
|
||||
}
|
||||
break;
|
||||
case NULL_VALUE:
|
||||
methodVisitor.visitInsn(ACONST_NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ReturnNode returnNode) {
|
||||
if (returnNode.voidReturn) { // Return nothing
|
||||
methodVisitor.visitInsn(RETURN);
|
||||
} else { // Return something
|
||||
// Process expression
|
||||
returnNode.expression.accept(this);
|
||||
|
||||
if (returnNode.expression instanceof UnaryNode) {
|
||||
UnaryNode unaryNode = (UnaryNode) returnNode.expression;
|
||||
if (unaryNode.statement instanceof IncrementNode) {
|
||||
IncrementNode incrementNode = (IncrementNode) unaryNode.statement;
|
||||
incrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadIncrement(incrementNode);
|
||||
}
|
||||
if (unaryNode.statement instanceof DecrementNode) {
|
||||
DecrementNode decrementNode = (DecrementNode) unaryNode.statement;
|
||||
decrementNode.assignableExpression.typeNode = unaryNode.getType();
|
||||
loadDecrement(decrementNode);
|
||||
}
|
||||
}
|
||||
|
||||
// Return result of expression
|
||||
if (returnNode.expression.getType() instanceof BaseType) {
|
||||
methodVisitor.visitInsn(IRETURN);
|
||||
} else if (returnNode.expression.getType() instanceof ReferenceType) {
|
||||
methodVisitor.visitInsn(ARETURN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(WhileNode whileNode) {
|
||||
Label loopLabel = new Label();
|
||||
Label endOfLoopLabel = new Label();
|
||||
|
||||
methodVisitor.visitLabel(loopLabel);
|
||||
// while loop
|
||||
whileNode.expression.accept(this);
|
||||
methodVisitor.visitJumpInsn(IFEQ, endOfLoopLabel); // if condition is false, jump out of loop
|
||||
|
||||
whileNode.block.accept(this);
|
||||
methodVisitor.visitJumpInsn(GOTO, loopLabel);
|
||||
|
||||
methodVisitor.visitLabel(endOfLoopLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodCallNode methodCallNode) {
|
||||
List<ParameterNode> parameterNodes = new ArrayList<>();
|
||||
int localVarIndex = -1;
|
||||
if (methodCallNode.target.memberAccess.identifiers.size() > 1) {
|
||||
localVarIndex = localVariables.indexOf(methodCallNode.target.memberAccess.identifiers.get(1));
|
||||
}
|
||||
if (localVarIndex >= 0) { // local var object
|
||||
methodVisitor.visitVarInsn(ALOAD, localVarIndex);
|
||||
} else { // this field
|
||||
methodVisitor.visitVarInsn(ALOAD, 0);
|
||||
}
|
||||
for (IExpressionNode expressionNode : methodCallNode.parameters) {
|
||||
expressionNode.accept(this);
|
||||
parameterNodes.add(new ParameterNode(expressionNode.getType(), ""));
|
||||
}
|
||||
if(methodCallNode.type == null) {
|
||||
methodCallNode.type = new BaseType(TypeEnum.INT);
|
||||
}
|
||||
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, methodCallNode.target.memberAccess.identifiers.get(0), methodCallNode.identifier, mapper.generateMethodDescriptor(methodCallNode.type, parameterNodes), false);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package bytecode.visitor;
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.members.FieldNode;
|
||||
|
||||
public interface ClassVisitor {
|
||||
void visit(ClassNode classNode);
|
||||
void visit(FieldNode fieldNode);
|
||||
void visit(ClassNode classNode);
|
||||
void visit(FieldNode fieldNode);
|
||||
}
|
||||
|
@@ -1,9 +1,68 @@
|
||||
package bytecode.visitor;
|
||||
|
||||
import ast.member.ConstructorNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.expressions.binaryexpressions.*;
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.expressions.unaryexpressions.NotNode;
|
||||
import ast.expressions.unaryexpressions.UnaryNode;
|
||||
import ast.members.ConstructorNode;
|
||||
import ast.members.MainMethodNode;
|
||||
import ast.members.MethodNode;
|
||||
import ast.statementexpressions.AssignNode;
|
||||
import ast.statementexpressions.NewDeclarationNode;
|
||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||
import ast.statements.*;
|
||||
import ast.type.ValueNode;
|
||||
|
||||
public interface MethodVisitor {
|
||||
// members
|
||||
void visit(ConstructorNode constructorNode);
|
||||
|
||||
void visit(MethodNode methodNode);
|
||||
|
||||
void visit(MainMethodNode mainMethodNode);
|
||||
|
||||
// Binary expressions
|
||||
void visit(BinaryNode binaryNode);
|
||||
|
||||
void visit(CalculationNode calculationNode);
|
||||
|
||||
void visit(DotNode dotNode);
|
||||
|
||||
void visit(DotSubtractionNode dotSubtractionNode);
|
||||
|
||||
void visit(NonCalculationNode nonCalculationNode);
|
||||
|
||||
// Unary expressions
|
||||
void visit(MemberAccessNode memberAccessNode);
|
||||
|
||||
void visit(NotNode notExpressionNode);
|
||||
|
||||
void visit(UnaryNode unaryExpressionNode);
|
||||
|
||||
// statements
|
||||
void visit(BlockNode blockNode);
|
||||
void visit(IfElseNode ifElseNode);
|
||||
|
||||
void visit(IncrementNode incrementNode);
|
||||
void visit(DecrementNode decrementNode);
|
||||
|
||||
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
||||
|
||||
void visit(ReturnNode returnNode);
|
||||
|
||||
void visit(WhileNode whileNode);
|
||||
|
||||
// statement expression
|
||||
void visit(MethodCallNode methodCallNode);
|
||||
|
||||
void visit(AssignNode assignNode);
|
||||
|
||||
void visit(NewDeclarationNode newDeclarationNode);
|
||||
|
||||
// type
|
||||
void visit(ValueNode valueNode);
|
||||
|
||||
}
|
||||
|
@@ -3,5 +3,5 @@ package bytecode.visitor;
|
||||
import ast.ProgramNode;
|
||||
|
||||
public interface ProgramVisitor {
|
||||
void visit(ProgramNode programNode);
|
||||
void visit(ProgramNode programNode);
|
||||
}
|
||||
|
Binary file not shown.
116
src/main/java/main/Main.java
Normal file
116
src/main/java/main/Main.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package main;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ProgramNode;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
import semantic.SemanticAnalyzer;
|
||||
import bytecode.ByteCodeGenerator;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Start miniCompiler using make:
|
||||
* <p> <code> cd .\src\test\ </code>
|
||||
* <p> <code> make clean compile-miniCompiler </code>
|
||||
* <p> Start miniCompiler using jar:
|
||||
* <p> <code> java.exe -DgenJar=true_OR_false -DgenClass=true_OR_false -jar path_to_jar\JavaCompiler-1.0-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' </code>
|
||||
* <p> Example (jar needs to be in the target directory, compile with make or mvn package first):
|
||||
* <code> java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' </code>
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length == 2) {
|
||||
// args[0] is the input file path
|
||||
// args[1] is the output directory path
|
||||
String inputFilePath = args[0];
|
||||
String outputDirectoryPath = args[1];
|
||||
System.out.println("Compiling file: " + inputFilePath);
|
||||
try {
|
||||
CharStream inputCharStream = CharStreams.fromPath(Paths.get(inputFilePath));
|
||||
compileFile(inputCharStream, outputDirectoryPath);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/input/finalTest/Car.java"));
|
||||
compileFile(codeCharStream, "src/test/resources/input/finalTest");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to compile a file from a given CharStream and output the bytecode to a specified directory.
|
||||
* It goes through the following steps:
|
||||
* <p>1. Scanner: It uses the SimpleJavaLexer to tokenize the input CharStream.
|
||||
* <p>2. Parser: It uses the SimpleJavaParser to parse the tokens and generate a ParseTree.
|
||||
* <p>3. AST Builder: It uses the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST).
|
||||
* <p>4. Semantic Analyzer: It uses the SemanticAnalyzer to generate a typed AST.
|
||||
* <p>5. Bytecode Generator: It uses the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory.
|
||||
*
|
||||
* @param inputCharStream The CharStream representing the input file to be compiled.
|
||||
* @param outputDirectoryPath The path of the directory where the output bytecode should be written.
|
||||
*/
|
||||
static void compileFile(CharStream inputCharStream, String outputDirectoryPath) {
|
||||
// Initialize the logger
|
||||
new MiniCompilerLogger();
|
||||
|
||||
/* ------------------------- Scanner -> tokens ------------------------- */
|
||||
// Use the SimpleJavaLexer to tokenize the input CharStream
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
tokenStream.fill();
|
||||
// Log the tokens
|
||||
MiniCompilerLogger.logScanner(tokenStream);
|
||||
|
||||
/*------------------------- Parser -> Parsetree -------------------------*/
|
||||
// Use the SimpleJavaParser to parse the tokens and generate a ParseTree
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
// Log the ParseTree
|
||||
MiniCompilerLogger.logParser(parseTree, parser);
|
||||
|
||||
/*------------------------- AST builder -> AST -------------------------*/
|
||||
// Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST)
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ASTNode abstractSyntaxTree = astBuilder.visit(parseTree);
|
||||
// Log the AST
|
||||
MiniCompilerLogger.logAST(abstractSyntaxTree);
|
||||
|
||||
/*------------------------- Semantic Analyzer -> typed AST -------------------------*/
|
||||
// Use the SemanticAnalyzer to generate a typed AST
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
// Log the typed AST
|
||||
MiniCompilerLogger.logSemanticAnalyzer(typedAst);
|
||||
|
||||
if(SemanticAnalyzer.errors.isEmpty()){
|
||||
/*------------------------- Bytecode Generator -> Bytecode -------------------------*/
|
||||
// Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory
|
||||
|
||||
final boolean genJar = Optional.ofNullable(System.getProperty("genJar")).map(String::toLowerCase).map(Boolean::parseBoolean).orElse(true);
|
||||
final boolean genClass = Optional.ofNullable(System.getProperty("genClass")).map(String::toLowerCase).map(Boolean::parseBoolean).orElse(true);
|
||||
|
||||
ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath, genJar, genClass);
|
||||
assert typedAst != null;
|
||||
byteCodeGenerator.visit((ProgramNode) typedAst);
|
||||
// Log the bytecode generation
|
||||
MiniCompilerLogger.logBytecodeGenerator();
|
||||
} else {
|
||||
for(Exception exception : SemanticAnalyzer.errors){
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
186
src/main/java/main/MiniCompilerLogger.java
Normal file
186
src/main/java/main/MiniCompilerLogger.java
Normal file
@@ -0,0 +1,186 @@
|
||||
package main;
|
||||
|
||||
import ast.ASTNode;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.*;
|
||||
|
||||
/**
|
||||
* Beispiel für Logging-Arten:
|
||||
* <p><code>logger.severe("Schwerwiegender Fehler");</code>
|
||||
* <p><code>logger.warning("Warnung");</code>
|
||||
* <p><code>logger.info("Information");</code>
|
||||
* <p><code>logger.config("Konfigurationshinweis");</code>
|
||||
* <p><code>logger.fine("Fein");</code>
|
||||
* <p><code>logger.finer("Feiner");</code>
|
||||
* <p><code>logger.finest("Am feinsten");</code>
|
||||
* <p>You may toggle the logging level of the console and file handlers by
|
||||
* changing the level ALL/OFF/etc. in the constructor.
|
||||
* <code>consoleHandler.setLevel(Level.OFF);</code>
|
||||
* <code>fileHandler.setLevel(Level.ALL);</code>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
public class MiniCompilerLogger {
|
||||
|
||||
static Logger logger = Logger.getLogger("miniCompilerLogs");
|
||||
|
||||
public MiniCompilerLogger() {
|
||||
// ------------------------- Logging -------------------------
|
||||
logger.setLevel(Level.ALL);
|
||||
logger.getParent().getHandlers()[0].setLevel(Level.ALL);
|
||||
logger.setUseParentHandlers(false);
|
||||
|
||||
// Custom formatter class
|
||||
class CustomFormatter extends Formatter {
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
|
||||
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
return formatMessage(record) + System.lineSeparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHead(Handler h) {
|
||||
Date now = new Date();
|
||||
String dateTime = dateFormat.format(now);
|
||||
return "Log Start Time: " + dateTime + "\n"
|
||||
+ "Logger Name: " + h.getFormatter().getClass().getName() + "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Configure console handler
|
||||
Handler consoleHandler = new ConsoleHandler();
|
||||
// Toggle console logging on/off
|
||||
consoleHandler.setLevel(Level.OFF);
|
||||
consoleHandler.setFormatter(new CustomFormatter());
|
||||
logger.addHandler(consoleHandler);
|
||||
|
||||
// Configure file handler
|
||||
Handler fileHandler = new FileHandler("src/main/resources/logs/miniCompiler.log");
|
||||
// Toggle file logging on/off
|
||||
fileHandler.setLevel(Level.ALL);
|
||||
fileHandler.setFormatter(new CustomFormatter());
|
||||
logger.addHandler(fileHandler);
|
||||
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logScanner(CommonTokenStream tokenStream) {
|
||||
// Printing the tokens
|
||||
logger.info("-------------------- Scanner -> Tokens --------------------");
|
||||
List<Token> tokens = tokenStream.getTokens();
|
||||
for (Token token : tokens) {
|
||||
String tokenType =
|
||||
SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType());
|
||||
String tokenText = token.getText();
|
||||
// logger.info("Token Type: " + tokenType + ", Token Text: " + tokenText);
|
||||
logger.info(tokenType + " " + tokenText);
|
||||
}
|
||||
logger.info("\n");
|
||||
}
|
||||
|
||||
public static void logParser(ParseTree parseTree, SimpleJavaParser parser) {
|
||||
// Printing the parse tree
|
||||
logger.info("-------------------- Parser -> Parsetree --------------------");
|
||||
logger.info(parseTree.toStringTree(parser)); //one line representation
|
||||
logTree(parseTree, parser, 0);
|
||||
logger.info("\n");
|
||||
}
|
||||
|
||||
public static void logAST(ASTNode abstractSyntaxTree) {
|
||||
// Printing the AST
|
||||
logger.info("-------------------- AST builder -> AST --------------------");
|
||||
logger.info("Abstract Syntax Tree generated, Startnode:");
|
||||
logAST(abstractSyntaxTree, 0);
|
||||
logger.info("\n");
|
||||
}
|
||||
|
||||
public static void logSemanticAnalyzer(ASTNode typedAst) {
|
||||
// Printing the typed AST
|
||||
logger.info("-------------------- Semantic Analyzer -> typed AST --------------------");
|
||||
// logAST(typedAst, 0);
|
||||
logger.info("Typed Abstract Syntax Tree generated without errors");
|
||||
logger.info("\n");
|
||||
}
|
||||
|
||||
public static void logBytecodeGenerator() {
|
||||
// Printing the bytecode
|
||||
logger.info("-------------------- Bytecode Generator -> Bytecode --------------------");
|
||||
logger.info("Bytecode generated without errors");
|
||||
logger.info("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------- Printing methods ------------------------- */
|
||||
|
||||
/**
|
||||
* This method is used to print the parse tree in a structured format.
|
||||
* It recursively traverses the tree and prints the rule names and text of the
|
||||
* nodes.
|
||||
*
|
||||
* @param tree The parse tree to be printed.
|
||||
* @param parser The parser used to parse the input. It's used to get the rule
|
||||
* names.
|
||||
* @param indent The current indentation level. It's used to format the output.
|
||||
*/
|
||||
public static void logTree(ParseTree tree, Parser parser, int indent) {
|
||||
// Create an indentation string based on the current indentation level
|
||||
String indentString = " ".repeat(indent * 2);
|
||||
|
||||
// If the tree node is an instance of RuleContext (i.e., it's an internal node),
|
||||
// print the rule name
|
||||
if (tree instanceof RuleContext) {
|
||||
int ruleIndex = ((RuleContext) tree).getRuleIndex();
|
||||
String ruleName = parser.getRuleNames()[ruleIndex];
|
||||
logger.info(indentString + ruleName);
|
||||
} else {
|
||||
// If the tree node is not an instance of RuleContext (i.e., it's a leaf node),
|
||||
// print the text of the node
|
||||
logger.info(indentString + tree.getText());
|
||||
}
|
||||
|
||||
// Recursively print the children of the current node, increasing the
|
||||
// indentation level
|
||||
for (int i = 0; i < tree.getChildCount(); i++) {
|
||||
logTree(tree.getChild(i), parser, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logAST(ASTNode abstractSyntaxTree, int indent) {
|
||||
if (abstractSyntaxTree == null) {
|
||||
logger.severe("AST is null !!!");
|
||||
return;
|
||||
}
|
||||
String indentString = " ".repeat(indent * 2);
|
||||
logger.info(indentString + abstractSyntaxTree.getClass());
|
||||
// for (ASTNode child : abstractSyntaxTree.getChildren()) {
|
||||
// logAST(child, indent + 1);
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
@@ -1,36 +1,47 @@
|
||||
package parser.astBuilder;
|
||||
|
||||
import ast.*;
|
||||
import ast.block.BlockNode;
|
||||
import ast.expression.*;
|
||||
import ast.expression.binaryexpression.CalculationExpressionNode;
|
||||
import ast.expression.binaryexpression.DotExpressionNode;
|
||||
import ast.expression.binaryexpression.DotSubstractionExpressionNode;
|
||||
import ast.expression.binaryexpression.NonCalculationExpressionNode;
|
||||
import ast.expression.unaryexpression.MemberAccessNode;
|
||||
import ast.expression.unaryexpression.NotExpressionNode;
|
||||
import ast.expression.unaryexpression.UnaryExpressionNode;
|
||||
import ast.member.*;
|
||||
import ast.statement.ifstatement.ElseStatementNode;
|
||||
import ast.statement.ifstatement.IfElseStatementNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.*;
|
||||
import ast.statement.ifstatement.IfStatementNode;
|
||||
import ast.statement.statementexpression.AssignStatementExpressionNode;
|
||||
import ast.statement.statementexpression.AssignableExpressionNode;
|
||||
import ast.statement.statementexpression.NewDeclarationStatementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.CrementType;
|
||||
import ast.statement.statementexpression.crementExpression.DecrementExpressionNode;
|
||||
import ast.statement.statementexpression.crementExpression.IncrementExpressionNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.ChainedMethodNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.TargetNode;
|
||||
import ast.type.*;
|
||||
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.expressions.binaryexpressions.*;
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.expressions.unaryexpressions.NotNode;
|
||||
import ast.expressions.unaryexpressions.UnaryNode;
|
||||
import ast.members.*;
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.statementexpressions.AssignNode;
|
||||
import ast.statementexpressions.AssignableNode;
|
||||
import ast.statementexpressions.IStatementExpressionNode;
|
||||
import ast.statementexpressions.NewDeclarationNode;
|
||||
import ast.statementexpressions.crementexpressions.CrementType;
|
||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||
import ast.statements.*;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.type.*;
|
||||
import ast.type.EnumValueNode;
|
||||
import ast.type.ValueNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import parser.generated.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ASTBuilder is a visitor that converts the parse tree into an abstract syntax tree (AST).
|
||||
*/
|
||||
public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
|
||||
/**
|
||||
* Visits a program node and creates a ProgramNode.
|
||||
* It iterates through all class declarations in the context and adds them to the ProgramNode.
|
||||
*
|
||||
* @param ctx the program context
|
||||
* @return the AST node for the program
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitProgram(SimpleJavaParser.ProgramContext ctx) {
|
||||
ProgramNode program = new ProgramNode();
|
||||
@@ -40,132 +51,386 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visits a class declaration and creates a ClassNode.
|
||||
* It checks for an access modifier, processes member declarations, and ensures the class has a constructor.
|
||||
*
|
||||
* @param ctx the class declaration context
|
||||
* @return the AST node for the class
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitClassDeclaration(SimpleJavaParser.ClassDeclarationContext ctx) {
|
||||
ClassNode classNode = new ClassNode(ctx.AccessModifier().getText(), ctx.Identifier().getText());
|
||||
for (SimpleJavaParser.MemberDeclarationContext member : ctx.memberDeclaration()) {
|
||||
classNode.addMember((MemberNode) visit(member));
|
||||
ClassNode classNode;
|
||||
if(ctx.AccessModifier() != null){
|
||||
classNode = new ClassNode(ctx.AccessModifier().getText(), ctx.Identifier().getText());
|
||||
}
|
||||
classNode.ensureConstructor();
|
||||
else{
|
||||
classNode = new ClassNode("public", ctx.Identifier().getText());
|
||||
}
|
||||
|
||||
boolean hasConstructor = false;
|
||||
|
||||
for (SimpleJavaParser.MemberDeclarationContext member : ctx.memberDeclaration()) {
|
||||
MemberNode memberNode = (MemberNode) visit(member);
|
||||
if(memberNode != null) {
|
||||
if(memberNode instanceof ConstructorNode){
|
||||
hasConstructor = true;
|
||||
}
|
||||
classNode.addMember(memberNode);
|
||||
}
|
||||
}
|
||||
|
||||
if(!hasConstructor){
|
||||
BlockNode blockNode = new BlockNode();
|
||||
blockNode.addStatement(new ReturnNode(null));
|
||||
classNode.members.addFirst(new ConstructorNode("public", ctx.Identifier().getText(), blockNode));
|
||||
}
|
||||
|
||||
return classNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a constructor declaration and creates a ConstructorNode.
|
||||
* It processes access modifiers, block statements, and parameters.
|
||||
*
|
||||
* @param ctx the constructor declaration context
|
||||
* @return the AST node for the constructor
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx) {
|
||||
ConstructorNode constructorNode = new ConstructorNode(ctx.AccessModifier().getText(), ctx.Identifier().getText(), (BlockNode) visit(ctx.block()));
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
constructorNode.addParameter((ParameterNode) visit(parameter));
|
||||
ConstructorNode constructorNode;
|
||||
if(ctx.AccessModifier() != null) {
|
||||
constructorNode = new ConstructorNode(ctx.AccessModifier().getText(), ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
} else {
|
||||
constructorNode = new ConstructorNode("public", ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
}
|
||||
if(ctx.parameterList() != null) {
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
constructorNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
}
|
||||
constructorNode.block.addStatement(new ReturnNode(null));
|
||||
return constructorNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a method declaration and creates a MethodNode or MainMethodNode.
|
||||
* It handles method types, access modifiers, block statements, and parameters.
|
||||
*
|
||||
* @param ctx the method declaration context
|
||||
* @return the AST node for the method
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx) {
|
||||
if(ctx.MainMethodDeclaration() != null) {
|
||||
return new MainMethodNode((BlockNode) visit(ctx.block()));
|
||||
MainMethodNode mainMethod = new MainMethodNode((BlockNode) visit(ctx.blockStatement()));
|
||||
mainMethod.block.addStatement(new ReturnNode(null));
|
||||
return mainMethod;
|
||||
} else {
|
||||
if(ctx.type() != null) {
|
||||
MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.block()));
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
if(ctx.AccessModifier() != null) {
|
||||
MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
if(ctx.parameterList() != null) {
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
}
|
||||
return methodNode;
|
||||
} else {
|
||||
MethodNode methodNode = new MethodNode("public", createTypeNode(ctx.type().getText()), false, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
if(ctx.parameterList() != null) {
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
}
|
||||
return methodNode;
|
||||
}
|
||||
return methodNode;
|
||||
} else {
|
||||
MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.block()));
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
if(ctx.AccessModifier() != null) {
|
||||
MethodNode methodNode = new MethodNode(ctx.AccessModifier().getText(), null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
if(ctx.parameterList() != null) {
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
}
|
||||
methodNode.block.addStatement(new ReturnNode(null));
|
||||
return methodNode;
|
||||
} else {
|
||||
MethodNode methodNode = new MethodNode("public", null, true, ctx.Identifier().getText(), (BlockNode) visit(ctx.blockStatement()));
|
||||
if(ctx.parameterList() != null) {
|
||||
for(SimpleJavaParser.ParameterContext parameter : ctx.parameterList().parameter()) {
|
||||
methodNode.addParameter((ParameterNode) visit(parameter));
|
||||
}
|
||||
}
|
||||
methodNode.block.addStatement(new ReturnNode(null));
|
||||
return methodNode;
|
||||
}
|
||||
return methodNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visits a field declaration and creates a FieldNode.
|
||||
* It handles access modifiers and types.
|
||||
*
|
||||
* @param ctx the field declaration context
|
||||
* @return the AST node for the field
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitFieldDeclaration(SimpleJavaParser.FieldDeclarationContext ctx) {
|
||||
return new FieldNode(new AccessModifierNode(ctx.AccessModifier().getText()), createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
if(ctx.AccessModifier() != null) {
|
||||
return new FieldNode(new AccessModifierNode(ctx.AccessModifier().getText()), createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
} else {
|
||||
return new FieldNode(new AccessModifierNode("public"), createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a parameter and creates a ParameterNode.
|
||||
* It handles the type and identifier of the parameter.
|
||||
*
|
||||
* @param ctx the parameter context
|
||||
* @return the AST node for the parameter
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitParameter(SimpleJavaParser.ParameterContext ctx) {
|
||||
return new ParameterNode(createTypeNode(ctx.type().getText()), ctx.Identifier().getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a statement and creates the corresponding AST node.
|
||||
* It determines the specific type of statement and processes it accordingly.
|
||||
*
|
||||
* @param ctx the statement context
|
||||
* @return the AST node for the statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitStatement(SimpleJavaParser.StatementContext ctx) {
|
||||
if(ctx.returnStatement() != null) {
|
||||
return visitReturnStatement(ctx.returnStatement());
|
||||
} else if(ctx.localVariableDeclaration() != null) {
|
||||
return visitLocalVariableDeclaration(ctx.localVariableDeclaration());
|
||||
} else if(ctx.block() != null) {
|
||||
return visitBlock(ctx.block());
|
||||
} else if(ctx.blockStatement() != null) {
|
||||
return visitBlockStatement(ctx.blockStatement());
|
||||
} else if(ctx.whileStatement() != null) {
|
||||
return visitWhileStatement(ctx.whileStatement());
|
||||
} else if(ctx.doWhileStatement() != null) {
|
||||
return visitDoWhileStatement(ctx.doWhileStatement());
|
||||
} else if(ctx.forStatement() != null) {
|
||||
return visitForStatement(ctx.forStatement());
|
||||
} else if(ctx.ifElseStatement() != null) {
|
||||
return visitIfElseStatement(ctx.ifElseStatement());
|
||||
} else if(ctx.switchStatement() != null) {
|
||||
return visitSwitchStatement(ctx.switchStatement());
|
||||
} else if(ctx.statementExpression() != null) {
|
||||
return visitStatementExpression(ctx.statementExpression());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a return statement and creates a ReturnNode.
|
||||
* It processes the expression in the return statement.
|
||||
*
|
||||
* @param ctx the return statement context
|
||||
* @return the AST node for the return statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitReturnStatement(SimpleJavaParser.ReturnStatementContext ctx) {
|
||||
return new ReturnStatementNode((IExpressionNode) visit(ctx.expression()));
|
||||
return new ReturnNode((IExpressionNode) visit(ctx.expression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a return statement and creates a ReturnNode.
|
||||
* It processes the expression in the return statement.
|
||||
*
|
||||
* @param ctx the return statement context
|
||||
* @return the AST node for the return statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitLocalVariableDeclaration(SimpleJavaParser.LocalVariableDeclarationContext ctx) {
|
||||
return new LocalVariableDeclarationNode(createTypeNode(ctx.type().getText()), ctx.Identifier().getText(), ctx.Assign().getText(), (IExpressionNode) visit(ctx.expression()));
|
||||
if(ctx.Assign() != null) {
|
||||
return new LocalVariableDeclarationNode(createTypeNode(ctx.type().getText()), ctx.Identifier().getText(), ctx.Assign().getText(), (IExpressionNode) visit(ctx.expression()));
|
||||
} else {
|
||||
return new LocalVariableDeclarationNode(createTypeNode(ctx.type().getText()), ctx.Identifier().getText(), null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a block statement and creates a BlockNode.
|
||||
* It processes all statements within the block.
|
||||
*
|
||||
* @param ctx the block statement context
|
||||
* @return the AST node for the block statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitBlock(SimpleJavaParser.BlockContext ctx) {
|
||||
public ASTNode visitBlockStatement(SimpleJavaParser.BlockStatementContext ctx) {
|
||||
BlockNode blockNode = new BlockNode();
|
||||
for(SimpleJavaParser.StatementContext statement : ctx.statement()) {
|
||||
blockNode.addStatement((IStatementNode) visit(statement));
|
||||
}
|
||||
if(!blockNode.hasReturnStatement) {
|
||||
blockNode.addStatement(new ReturnStatementNode(null));
|
||||
}
|
||||
return blockNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a while statement and creates a WhileNode.
|
||||
* It processes the condition expression and the block statement.
|
||||
*
|
||||
* @param ctx the while statement context
|
||||
* @return the AST node for the while statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitWhileStatement(SimpleJavaParser.WhileStatementContext ctx) {
|
||||
return new WhileStatementNode((IExpressionNode) visit(ctx.expression()), (BlockNode) visit(ctx.block()));
|
||||
return new WhileNode((IExpressionNode) visit(ctx.expression()), (BlockNode) visit(ctx.blockStatement()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a do-while statement and creates a BlockNode containing a WhileNode.
|
||||
* It processes the condition expression and the block statement.
|
||||
*
|
||||
* @param ctx the do-while statement context
|
||||
* @return the AST node for the do-while statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx) {
|
||||
IExpressionNode condition = (IExpressionNode) visit(ctx.expression());
|
||||
BlockNode doBlock = (BlockNode) visit(ctx.blockStatement());
|
||||
|
||||
WhileNode While = new WhileNode(condition, doBlock);
|
||||
BlockNode resultBlock = new BlockNode();
|
||||
resultBlock.addStatement(doBlock);
|
||||
resultBlock.addStatement(While);
|
||||
|
||||
return resultBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a for statement and creates a BlockNode that contains a WhileNode.
|
||||
* It processes the initialization, condition, and increment parts of the for loop.
|
||||
*
|
||||
* @param ctx the for statement context
|
||||
* @return the AST node for the for statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitForStatement(SimpleJavaParser.ForStatementContext ctx) {
|
||||
if(ctx.statementExpression(0) != null) {
|
||||
return new ForStatementNode((IExpressionNode) visit(ctx.statementExpression(0)), (IExpressionNode) visit(ctx.expression()), (IExpressionNode) visit(ctx.statementExpression(1)));
|
||||
} else if(ctx.localVariableDeclaration() != null) {
|
||||
return new ForStatementNode((IStatementNode) visit(ctx.localVariableDeclaration()), (IExpressionNode) visit(ctx.expression()), (IExpressionNode) visit(ctx.statementExpression(1)));
|
||||
List<IStatementNode> statements = new ArrayList<>();
|
||||
|
||||
// Initialisierung
|
||||
int i = 0;
|
||||
if (ctx.localVariableDeclaration() != null) {
|
||||
statements.add((IStatementNode) visit(ctx.localVariableDeclaration()));
|
||||
} else if (ctx.statementExpression(i) != null) {
|
||||
statements.add((IStatementNode) visit(ctx.statementExpression(i)));
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
// Bedingung
|
||||
IExpressionNode condition = (IExpressionNode) visit(ctx.expression());
|
||||
|
||||
// Inkrement
|
||||
IStatementExpressionNode crement = null;
|
||||
if (ctx.statementExpression(i) != null) {
|
||||
crement = (IStatementExpressionNode) visit(ctx.statementExpression(i));
|
||||
}
|
||||
|
||||
BlockNode forBlock = (BlockNode) visit(ctx.blockStatement());
|
||||
|
||||
// While-Schleife
|
||||
BlockNode whileBody = new BlockNode();
|
||||
|
||||
// Block Statements der For-Schleife in den While-Block kopieren
|
||||
for (IStatementNode statement : forBlock.statements) {
|
||||
whileBody.addStatement(statement);
|
||||
}
|
||||
|
||||
// Post-Inkrement: Das Inkrement kommt nach dem Block
|
||||
if (crement != null) {
|
||||
whileBody.addStatement(crement);
|
||||
}
|
||||
|
||||
// Bedingung der While-Schleife
|
||||
WhileNode whileNode = new WhileNode(condition, whileBody);
|
||||
|
||||
statements.add(whileNode);
|
||||
|
||||
BlockNode resultBlock = new BlockNode();
|
||||
for (IStatementNode statement : statements) {
|
||||
resultBlock.addStatement(statement);
|
||||
}
|
||||
|
||||
return resultBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an if-else statement and creates an IfElseNode.
|
||||
* It processes the if, else-if, and else parts of the statement.
|
||||
*
|
||||
* @param ctx the if-else statement context
|
||||
* @return the AST node for the if-else statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitIfElseStatement(SimpleJavaParser.IfElseStatementContext ctx) {
|
||||
IfElseStatementNode ifElseStatementNode = new IfElseStatementNode((IfStatementNode) visit(ctx.ifStatement()));
|
||||
for(SimpleJavaParser.ElseStatementContext elseStatement : ctx.elseStatement()) {
|
||||
ifElseStatementNode.addElseStatement((ElseStatementNode) visit(elseStatement));
|
||||
IfElseNode ifElseStatementNode;
|
||||
if(ctx.elseStatement() != null) {
|
||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()),
|
||||
(ElseNode) visit(ctx.elseStatement()));
|
||||
} else {
|
||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()), null);
|
||||
}
|
||||
|
||||
for (SimpleJavaParser.ElseIfStatementContext elseIf : ctx.elseIfStatement()){
|
||||
ifElseStatementNode.addElseIfStatement(((IfNode) visit(elseIf)));
|
||||
}
|
||||
|
||||
return ifElseStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an if statement and creates an IfNode.
|
||||
* It processes the condition expression and the block statement.
|
||||
*
|
||||
* @param ctx the if statement context
|
||||
* @return the AST node for the if statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitIfStatement(SimpleJavaParser.IfStatementContext ctx) {
|
||||
return new IfStatementNode((IExpressionNode) visit(ctx.expression()), (BlockNode) visit(ctx.block()));
|
||||
return new IfNode((IExpressionNode) visit(ctx.expression()), (BlockNode) visit(ctx.blockStatement()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an else-if statement and creates an IfNode.
|
||||
* It processes the condition expression and the block statement.
|
||||
*
|
||||
* @param ctx the else-if statement context
|
||||
* @return the AST node for the else-if statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx) {
|
||||
return new IfNode((IExpressionNode) visit(ctx.expression()), (BlockNode) visit(ctx.blockStatement()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an else statement and creates an ElseNode.
|
||||
* It processes the block statement of the else part.
|
||||
*
|
||||
* @param ctx the else statement context
|
||||
* @return the AST node for the else statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitElseStatement(SimpleJavaParser.ElseStatementContext ctx) {
|
||||
return new ElseStatementNode((BlockNode) visit(ctx.block()));
|
||||
return new ElseNode((BlockNode) visit(ctx.blockStatement()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a statement expression and creates the corresponding AST node.
|
||||
* It handles assignments, new declarations, method calls, and increment/decrement expressions.
|
||||
*
|
||||
* @param ctx the statement expression context
|
||||
* @return the AST node for the statement expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitStatementExpression(SimpleJavaParser.StatementExpressionContext ctx) {
|
||||
if(ctx.assign() != null) {
|
||||
@@ -180,23 +445,99 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a switch statement and creates an IfElseNode representing the switch cases.
|
||||
* It processes the switch expression, case statements, and default statement.
|
||||
*
|
||||
* @param ctx the switch statement context
|
||||
* @return the AST node for the switch statement
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx) {
|
||||
UnaryNode switchExpression = (UnaryNode) visit(ctx.expression());
|
||||
|
||||
List<IfNode> ifNodes = new ArrayList<>();
|
||||
|
||||
for (SimpleJavaParser.CaseStatementContext caseCtx : ctx.caseStatement()) {
|
||||
IExpressionNode caseExpression = (IExpressionNode) visit(caseCtx.value());
|
||||
|
||||
// Condition as NonCalculationNode -> Equals Expression
|
||||
NonCalculationNode condition = new NonCalculationNode(switchExpression, "==", caseExpression);
|
||||
|
||||
BlockNode caseBlock = new BlockNode();
|
||||
for (SimpleJavaParser.StatementContext stmtCtx : caseCtx.statement()) {
|
||||
caseBlock.addStatement((IStatementNode) visit(stmtCtx));
|
||||
}
|
||||
|
||||
// Each case as if
|
||||
IfNode ifNode = new IfNode(condition, caseBlock);
|
||||
ifNodes.add(ifNode);
|
||||
}
|
||||
|
||||
// Check if has Default
|
||||
ElseNode defaulElseNode = null;
|
||||
if (ctx.defaultStatement() != null) {
|
||||
BlockNode defaultBlock = new BlockNode();
|
||||
for (SimpleJavaParser.StatementContext stmtCtx : ctx.defaultStatement().statement()) {
|
||||
defaultBlock.addStatement((IStatementNode) visit(stmtCtx));
|
||||
}
|
||||
// Default als letztes Else Statement
|
||||
defaulElseNode = new ElseNode(defaultBlock);
|
||||
}
|
||||
|
||||
IfElseNode ifElseNode = new IfElseNode(ifNodes.getFirst(),defaulElseNode);
|
||||
ifNodes.removeFirst();
|
||||
|
||||
for (IfNode ifNode : ifNodes){
|
||||
ifElseNode.addElseIfStatement(ifNode);
|
||||
}
|
||||
|
||||
return ifElseNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an assignment expression and creates an AssignNode.
|
||||
* It handles the assignable expression and the assigned expression.
|
||||
*
|
||||
* @param ctx the assignment context
|
||||
* @return the AST node for the assignment
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitAssign(SimpleJavaParser.AssignContext ctx) {
|
||||
return new AssignStatementExpressionNode((AssignableExpressionNode) visit(ctx.assignableExpression()), (IExpressionNode) visit(ctx.expression()));
|
||||
return new AssignNode((AssignableNode) visit(ctx.assignableExpression()), (IExpressionNode) visit(ctx.expression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a new declaration and creates a NewDeclarationNode.
|
||||
* It processes the identifier and the argument list.
|
||||
*
|
||||
* @param ctx the new declaration context
|
||||
* @return the AST node for the new declaration
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitNewDeclaration(SimpleJavaParser.NewDeclarationContext ctx) {
|
||||
NewDeclarationStatementExpressionNode newDeclarationStatementExpressionNode = new NewDeclarationStatementExpressionNode(ctx.Identifier().getText());
|
||||
NewDeclarationNode newDeclarationNode = new NewDeclarationNode(ctx.Identifier().getText());
|
||||
for(SimpleJavaParser.ExpressionContext expression : ctx.argumentList().expression()) {
|
||||
newDeclarationStatementExpressionNode.addExpression((IExpressionNode) visit(expression));
|
||||
newDeclarationNode.addExpression((IExpressionNode) visit(expression));
|
||||
}
|
||||
return newDeclarationStatementExpressionNode;
|
||||
return newDeclarationNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a method call and creates a MethodCallNode.
|
||||
* It processes the target, chained methods, and argument list.
|
||||
*
|
||||
* @param ctx the method call context
|
||||
* @return the AST node for the method call
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitMethodCall(SimpleJavaParser.MethodCallContext ctx) {
|
||||
MethodCallStatementExpressionNode methodCallStatementExpressionNode = new MethodCallStatementExpressionNode((TargetNode) visit(ctx.target()), ctx.Identifier().getText());
|
||||
MethodCallNode methodCallStatementExpressionNode;
|
||||
if(ctx.target() != null) {
|
||||
methodCallStatementExpressionNode = new MethodCallNode((TargetNode) visit(ctx.target()), ctx.Identifier().getText());
|
||||
} else {
|
||||
methodCallStatementExpressionNode = new MethodCallNode(null, ctx.Identifier().getText());
|
||||
}
|
||||
for(SimpleJavaParser.ChainedMethodContext chainedMethod : ctx.chainedMethod()) {
|
||||
methodCallStatementExpressionNode.addChainedMethod((ChainedMethodNode) visit(chainedMethod));
|
||||
}
|
||||
@@ -206,6 +547,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return methodCallStatementExpressionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the target of a method call and creates a TargetNode.
|
||||
* It handles various types of targets including 'this', member access, new declarations, and identifiers.
|
||||
*
|
||||
* @param ctx the target context
|
||||
* @return the AST node for the target
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitTarget(SimpleJavaParser.TargetContext ctx) {
|
||||
if(ctx.This() != null) {
|
||||
@@ -213,13 +561,20 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
} else if(ctx.memberAccess() != null) {
|
||||
return new TargetNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||
} else if(ctx.newDeclaration() != null) {
|
||||
return new TargetNode((NewDeclarationStatementExpressionNode) visit(ctx.newDeclaration()));
|
||||
return new TargetNode((NewDeclarationNode) visit(ctx.newDeclaration()));
|
||||
} else if(ctx.Identifier() != null) {
|
||||
return new TargetNode(ctx.Identifier().getText());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a chained method and creates a ChainedMethodNode.
|
||||
* It processes the identifier and the argument list.
|
||||
*
|
||||
* @param ctx the chained method context
|
||||
* @return the AST node for the chained method
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitChainedMethod(SimpleJavaParser.ChainedMethodContext ctx) {
|
||||
ChainedMethodNode chainedMethodNode = new ChainedMethodNode(ctx.Identifier().getText());
|
||||
@@ -229,6 +584,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return chainedMethodNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an increment or decrement expression and creates the corresponding AST node.
|
||||
* It handles both prefix and suffix forms of increment and decrement.
|
||||
*
|
||||
* @param ctx the crement expression context
|
||||
* @return the AST node for the crement expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitCrementExpression(SimpleJavaParser.CrementExpressionContext ctx) {
|
||||
if(ctx.incrementExpression() != null) {
|
||||
@@ -239,6 +601,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an increment expression and creates an IncrementNode.
|
||||
* It handles both prefix and suffix forms.
|
||||
*
|
||||
* @param ctx the increment expression context
|
||||
* @return the AST node for the increment expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitIncrementExpression(SimpleJavaParser.IncrementExpressionContext ctx) {
|
||||
if(ctx.prefixIncrementExpression() != null) {
|
||||
@@ -249,16 +618,35 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a prefix increment expression and creates an IncrementNode.
|
||||
*
|
||||
* @param ctx the prefix increment expression context
|
||||
* @return the AST node for the prefix increment expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitPrefixIncrementExpression(SimpleJavaParser.PrefixIncrementExpressionContext ctx) {
|
||||
return new IncrementExpressionNode(CrementType.PREFIX, (AssignableExpressionNode) visit(ctx.assignableExpression()));
|
||||
return new IncrementNode(CrementType.PREFIX, (AssignableNode) visit(ctx.assignableExpression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a suffix increment expression and creates an IncrementNode.
|
||||
*
|
||||
* @param ctx the suffix increment expression context
|
||||
* @return the AST node for the suffix increment expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitSuffixIncrementExpression(SimpleJavaParser.SuffixIncrementExpressionContext ctx) {
|
||||
return new IncrementExpressionNode(CrementType.SUFFIX, (AssignableExpressionNode) visit(ctx.assignableExpression()));
|
||||
return new IncrementNode(CrementType.SUFFIX, (AssignableNode) visit(ctx.assignableExpression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a decrement expression and creates a DecrementNode.
|
||||
* It handles both prefix and suffix forms.
|
||||
*
|
||||
* @param ctx the decrement expression context
|
||||
* @return the AST node for the decrement expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitDecrementExpression(SimpleJavaParser.DecrementExpressionContext ctx) {
|
||||
if(ctx.prefixDecrementExpression() != null) {
|
||||
@@ -269,16 +657,35 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a prefix decrement expression and creates a DecrementNode.
|
||||
*
|
||||
* @param ctx the prefix decrement expression context
|
||||
* @return the AST node for the prefix decrement expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitPrefixDecrementExpression(SimpleJavaParser.PrefixDecrementExpressionContext ctx) {
|
||||
return new DecrementExpressionNode(CrementType.PREFIX, (AssignableExpressionNode) visit(ctx.assignableExpression()));
|
||||
return new DecrementNode(CrementType.PREFIX, (AssignableNode) visit(ctx.assignableExpression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a suffix decrement expression and creates a DecrementNode.
|
||||
*
|
||||
* @param ctx the suffix decrement expression context
|
||||
* @return the AST node for the suffix decrement expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitSuffixDecrementExpression(SimpleJavaParser.SuffixDecrementExpressionContext ctx) {
|
||||
return new DecrementExpressionNode(CrementType.SUFFIX, (AssignableExpressionNode) visit(ctx.assignableExpression()));
|
||||
return new DecrementNode(CrementType.SUFFIX, (AssignableNode) visit(ctx.assignableExpression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an expression and creates the corresponding AST node.
|
||||
* It handles both unary and binary expressions.
|
||||
*
|
||||
* @param ctx the expression context
|
||||
* @return the AST node for the expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitExpression(SimpleJavaParser.ExpressionContext ctx) {
|
||||
if(ctx.unaryExpression() != null) {
|
||||
@@ -289,26 +696,40 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a unary expression and creates a UnaryNode.
|
||||
* It handles various forms of unary expressions including 'this', identifiers, member access, values, and more.
|
||||
*
|
||||
* @param ctx the unary expression context
|
||||
* @return the AST node for the unary expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitUnaryExpression(SimpleJavaParser.UnaryExpressionContext ctx) {
|
||||
if(ctx.This() != null) {
|
||||
return new UnaryExpressionNode(ctx.This().getText());
|
||||
return new UnaryNode(ctx.This().getText());
|
||||
} else if(ctx.Identifier() != null) {
|
||||
return new UnaryExpressionNode(ctx.Identifier().getText());
|
||||
return new UnaryNode(ctx.Identifier().getText());
|
||||
} else if(ctx.memberAccess() != null) {
|
||||
return new UnaryExpressionNode((MemberAccessNode) visitMemberAccess(ctx.memberAccess()));
|
||||
return new UnaryNode((MemberAccessNode) visitMemberAccess(ctx.memberAccess()));
|
||||
} else if(ctx.value() != null) {
|
||||
return new UnaryExpressionNode((ValueNode) visitValue(ctx.value()));
|
||||
return new UnaryNode((ValueNode) visitValue(ctx.value()));
|
||||
} else if(ctx.notExpression() != null) {
|
||||
return new UnaryExpressionNode((NotExpressionNode) visitNotExpression(ctx.notExpression()));
|
||||
return new UnaryNode((NotNode) visitNotExpression(ctx.notExpression()));
|
||||
} else if(ctx.statementExpression() != null) {
|
||||
return new UnaryExpressionNode((IStatementNode) visitStatementExpression(ctx.statementExpression()));
|
||||
return new UnaryNode((IStatementNode) visitStatementExpression(ctx.statementExpression()));
|
||||
} else if(ctx.expression() != null) {
|
||||
return new UnaryExpressionNode((IExpressionNode) visitExpression(ctx.expression()));
|
||||
return new UnaryNode((IExpressionNode) visitExpression(ctx.expression()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a member access expression and creates a MemberAccessNode.
|
||||
* It processes the 'this' keyword and identifiers for member access.
|
||||
*
|
||||
* @param ctx the member access context
|
||||
* @return the AST node for the member access
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitMemberAccess(SimpleJavaParser.MemberAccessContext ctx) {
|
||||
MemberAccessNode memberAccessNode;
|
||||
@@ -323,6 +744,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return memberAccessNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a value and creates a ValueNode.
|
||||
* It handles integer, boolean, char, and null values.
|
||||
*
|
||||
* @param ctx the value context
|
||||
* @return the AST node for the value
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitValue(SimpleJavaParser.ValueContext ctx) {
|
||||
if(ctx.IntValue() != null) {
|
||||
@@ -337,12 +765,25 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a not expression and creates a NotNode.
|
||||
* It processes the expression to which the 'not' operator is applied.
|
||||
*
|
||||
* @param ctx the not expression context
|
||||
* @return the AST node for the not expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitNotExpression(SimpleJavaParser.NotExpressionContext ctx) {
|
||||
return new NotExpressionNode((IExpressionNode) visitExpression(ctx.expression()));
|
||||
return new NotNode((IExpressionNode) visitExpression(ctx.expression()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visits a binary expression and creates the corresponding AST node.
|
||||
* It handles both calculation and non-calculation expressions.
|
||||
*
|
||||
* @param ctx the binary expression context
|
||||
* @return the AST node for the binary expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitBinaryExpression(SimpleJavaParser.BinaryExpressionContext ctx) {
|
||||
if(ctx.calculationExpression() != null) {
|
||||
@@ -353,55 +794,103 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a calculation expression and creates a CalculationNode.
|
||||
* It handles line operators and dot expressions.
|
||||
*
|
||||
* @param ctx the calculation expression context
|
||||
* @return the AST node for the calculation expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitCalculationExpression(SimpleJavaParser.CalculationExpressionContext ctx) {
|
||||
if(ctx.calculationExpression() != null) {
|
||||
return new CalculationExpressionNode((CalculationExpressionNode) visit(ctx.calculationExpression()), ctx.LineOperator().getText(), (DotExpressionNode) visit(ctx.dotExpression()));
|
||||
return new CalculationNode((CalculationNode) visit(ctx.calculationExpression()), ctx.LineOperator().getText(), (DotNode) visit(ctx.dotExpression()));
|
||||
} else if(ctx.dotExpression() != null) {
|
||||
return new CalculationExpressionNode((DotExpressionNode) visit(ctx.dotExpression()));
|
||||
return new CalculationNode((DotNode) visit(ctx.dotExpression()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a dot expression and creates a DotNode.
|
||||
* It handles dot operators and dot subtraction expressions.
|
||||
*
|
||||
* @param ctx the dot expression context
|
||||
* @return the AST node for the dot expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitDotExpression(SimpleJavaParser.DotExpressionContext ctx) {
|
||||
if(ctx.dotExpression() != null) {
|
||||
return new DotExpressionNode((DotExpressionNode) visit(ctx.dotExpression()), ctx.DotOperator().getText(), (DotSubstractionExpressionNode) visit(ctx.dotSubtractionExpression()));
|
||||
return new DotNode((DotNode) visit(ctx.dotExpression()), ctx.DotOperator().getText(), (DotSubtractionNode) visit(ctx.dotSubtractionExpression()));
|
||||
} else if(ctx.dotSubtractionExpression() != null) {
|
||||
return new DotExpressionNode((DotSubstractionExpressionNode) visit(ctx.dotSubtractionExpression()));
|
||||
return new DotNode((DotSubtractionNode) visit(ctx.dotSubtractionExpression()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a dot subtraction expression and creates a DotSubtractionNode.
|
||||
* It handles integer values, identifiers, member access, and method calls.
|
||||
*
|
||||
* @param ctx the dot subtraction expression context
|
||||
* @return the AST node for the dot subtraction expression
|
||||
*//**
|
||||
* Creates an ITypeNode based on the type identifier.
|
||||
* It handles basic types and reference types.
|
||||
*
|
||||
* @param identifier the type identifier
|
||||
* @return the type node
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitDotSubtractionExpression(SimpleJavaParser.DotSubtractionExpressionContext ctx) {
|
||||
if(ctx.IntValue() != null) {
|
||||
return new DotSubstractionExpressionNode(new ValueNode(EnumValueNode.INT_VALUE, ctx.IntValue().getText()));
|
||||
return new DotSubtractionNode(new ValueNode(EnumValueNode.INT_VALUE, ctx.IntValue().getText()));
|
||||
} else if(ctx.Identifier() != null) {
|
||||
return new DotSubstractionExpressionNode(ctx.Identifier().getText());
|
||||
return new DotSubtractionNode(ctx.Identifier().getText());
|
||||
} else if(ctx.memberAccess() != null) {
|
||||
return new DotSubstractionExpressionNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||
return new DotSubtractionNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||
} else if(ctx.methodCall() != null && ctx.calculationExpression() != null) {
|
||||
return new DotSubstractionExpressionNode((MethodCallStatementExpressionNode) visit(ctx.methodCall()), (CalculationExpressionNode) visit(ctx.calculationExpression()));
|
||||
return new DotSubtractionNode((MethodCallNode) visit(ctx.methodCall()), (CalculationNode) visit(ctx.calculationExpression()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a non-calculation expression and creates a NonCalculationNode.
|
||||
* It handles unary expressions combined with non-calculation operators.
|
||||
*
|
||||
* @param ctx the non-calculation expression context
|
||||
* @return the AST node for the non-calculation expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitNonCalculationExpression(SimpleJavaParser.NonCalculationExpressionContext ctx) {
|
||||
return new NonCalculationExpressionNode((UnaryExpressionNode) visit(ctx.unaryExpression()), ctx.nonCalculationOperator().getText(), (IExpressionNode) visit(ctx.expression()));
|
||||
return new NonCalculationNode((UnaryNode) visit(ctx.unaryExpression()), ctx.nonCalculationOperator().getText(), (IExpressionNode) visit(ctx.expression()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an assignable expression and creates an AssignableNode.
|
||||
* It handles identifiers and member access.
|
||||
*
|
||||
* @param ctx the assignable expression context
|
||||
* @return the AST node for the assignable expression
|
||||
*/
|
||||
@Override
|
||||
public ASTNode visitAssignableExpression(SimpleJavaParser.AssignableExpressionContext ctx) {
|
||||
if(ctx.Identifier() != null) {
|
||||
return new AssignableExpressionNode(ctx.Identifier().getText());
|
||||
return new AssignableNode(ctx.Identifier().getText());
|
||||
} else if(ctx.memberAccess() != null) {
|
||||
return new AssignableExpressionNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||
return new AssignableNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ITypeNode based on the type identifier.
|
||||
* It handles basic types and reference types.
|
||||
*
|
||||
* @param identifier the type identifier
|
||||
* @return the type node
|
||||
*/
|
||||
public ITypeNode createTypeNode(String identifier){
|
||||
return switch (identifier) {
|
||||
case "int" -> new BaseType(TypeEnum.INT);
|
||||
@@ -411,5 +900,4 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
default -> new ReferenceType(identifier);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -35,19 +35,24 @@ Comma=34
|
||||
Class=35
|
||||
This=36
|
||||
While=37
|
||||
If=38
|
||||
Else=39
|
||||
For=40
|
||||
Return=41
|
||||
New=42
|
||||
CharValue=43
|
||||
IntValue=44
|
||||
BooleanValue=45
|
||||
NullValue=46
|
||||
Identifier=47
|
||||
WS=48
|
||||
InlineComment=49
|
||||
MultilineComment=50
|
||||
Do=38
|
||||
If=39
|
||||
Else=40
|
||||
For=41
|
||||
Return=42
|
||||
New=43
|
||||
Switch=44
|
||||
Case=45
|
||||
Default=46
|
||||
Colon=47
|
||||
CharValue=48
|
||||
IntValue=49
|
||||
BooleanValue=50
|
||||
NullValue=51
|
||||
Identifier=52
|
||||
WS=53
|
||||
InlineComment=54
|
||||
MultilineComment=55
|
||||
'++'=1
|
||||
'--'=2
|
||||
'void'=3
|
||||
@@ -80,9 +85,14 @@ MultilineComment=50
|
||||
'class'=35
|
||||
'this'=36
|
||||
'while'=37
|
||||
'if'=38
|
||||
'else'=39
|
||||
'for'=40
|
||||
'return'=41
|
||||
'new'=42
|
||||
'null'=46
|
||||
'do'=38
|
||||
'if'=39
|
||||
'else'=40
|
||||
'for'=41
|
||||
'return'=42
|
||||
'new'=43
|
||||
'switch'=44
|
||||
'case'=45
|
||||
'default'=46
|
||||
':'=47
|
||||
'null'=51
|
||||
|
@@ -137,13 +137,13 @@ public class SimpleJavaBaseListener implements SimpleJavaListener {
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterBlock(SimpleJavaParser.BlockContext ctx) { }
|
||||
@Override public void enterBlockStatement(SimpleJavaParser.BlockStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitBlock(SimpleJavaParser.BlockContext ctx) { }
|
||||
@Override public void exitBlockStatement(SimpleJavaParser.BlockStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -180,6 +180,18 @@ public class SimpleJavaBaseListener implements SimpleJavaListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWhileStatement(SimpleJavaParser.WhileStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -216,6 +228,18 @@ public class SimpleJavaBaseListener implements SimpleJavaListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitIfStatement(SimpleJavaParser.IfStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -228,6 +252,42 @@ public class SimpleJavaBaseListener implements SimpleJavaListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitElseStatement(SimpleJavaParser.ElseStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterCaseStatement(SimpleJavaParser.CaseStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitCaseStatement(SimpleJavaParser.CaseStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDefaultStatement(SimpleJavaParser.DefaultStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDefaultStatement(SimpleJavaParser.DefaultStatementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@@ -88,7 +88,7 @@ public class SimpleJavaBaseVisitor<T> extends AbstractParseTreeVisitor<T> implem
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBlock(SimpleJavaParser.BlockContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitBlockStatement(SimpleJavaParser.BlockStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -110,6 +110,13 @@ public class SimpleJavaBaseVisitor<T> extends AbstractParseTreeVisitor<T> implem
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitWhileStatement(SimpleJavaParser.WhileStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -131,6 +138,13 @@ public class SimpleJavaBaseVisitor<T> extends AbstractParseTreeVisitor<T> implem
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitIfStatement(SimpleJavaParser.IfStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -138,6 +152,27 @@ public class SimpleJavaBaseVisitor<T> extends AbstractParseTreeVisitor<T> implem
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitElseStatement(SimpleJavaParser.ElseStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitCaseStatement(SimpleJavaParser.CaseStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDefaultStatement(SimpleJavaParser.DefaultStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
File diff suppressed because one or more lines are too long
@@ -23,9 +23,9 @@ public class SimpleJavaLexer extends Lexer {
|
||||
Less=20, GreaterEqual=21, LessEqual=22, Equal=23, NotEqual=24, Not=25,
|
||||
And=26, Or=27, Dot=28, OpenRoundBracket=29, ClosedRoundBracket=30, OpenCurlyBracket=31,
|
||||
ClosedCurlyBracket=32, Semicolon=33, Comma=34, Class=35, This=36, While=37,
|
||||
If=38, Else=39, For=40, Return=41, New=42, CharValue=43, IntValue=44,
|
||||
BooleanValue=45, NullValue=46, Identifier=47, WS=48, InlineComment=49,
|
||||
MultilineComment=50;
|
||||
Do=38, If=39, Else=40, For=41, Return=42, New=43, Switch=44, Case=45,
|
||||
Default=46, Colon=47, CharValue=48, IntValue=49, BooleanValue=50, NullValue=51,
|
||||
Identifier=52, WS=53, InlineComment=54, MultilineComment=55;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
@@ -42,9 +42,10 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"GreaterEqual", "LessEqual", "Equal", "NotEqual", "Not", "And", "Or",
|
||||
"Dot", "OpenRoundBracket", "ClosedRoundBracket", "OpenCurlyBracket",
|
||||
"ClosedCurlyBracket", "Semicolon", "Comma", "Class", "This", "While",
|
||||
"If", "Else", "For", "Return", "New", "CharValue", "IntValue", "BooleanValue",
|
||||
"NullValue", "Alphabetic", "Numeric", "ValidIdentSymbols", "Identifier",
|
||||
"WS", "InlineComment", "MultilineComment"
|
||||
"Do", "If", "Else", "For", "Return", "New", "Switch", "Case", "Default",
|
||||
"Colon", "CharValue", "IntValue", "BooleanValue", "NullValue", "Alphabetic",
|
||||
"Numeric", "ValidIdentSymbols", "Identifier", "WS", "InlineComment",
|
||||
"MultilineComment"
|
||||
};
|
||||
}
|
||||
public static final String[] ruleNames = makeRuleNames();
|
||||
@@ -55,8 +56,9 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"'public static void main(String[] args)'", null, null, null, null, "'='",
|
||||
"'+'", "'-'", "'*'", "'%'", "'/'", "'>'", "'<'", "'>='", "'<='", "'=='",
|
||||
"'!='", "'!'", "'&&'", "'||'", "'.'", "'('", "')'", "'{'", "'}'", "';'",
|
||||
"','", "'class'", "'this'", "'while'", "'if'", "'else'", "'for'", "'return'",
|
||||
"'new'", null, null, null, "'null'"
|
||||
"','", "'class'", "'this'", "'while'", "'do'", "'if'", "'else'", "'for'",
|
||||
"'return'", "'new'", "'switch'", "'case'", "'default'", "':'", null,
|
||||
null, null, "'null'"
|
||||
};
|
||||
}
|
||||
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||
@@ -68,8 +70,9 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"Greater", "Less", "GreaterEqual", "LessEqual", "Equal", "NotEqual",
|
||||
"Not", "And", "Or", "Dot", "OpenRoundBracket", "ClosedRoundBracket",
|
||||
"OpenCurlyBracket", "ClosedCurlyBracket", "Semicolon", "Comma", "Class",
|
||||
"This", "While", "If", "Else", "For", "Return", "New", "CharValue", "IntValue",
|
||||
"BooleanValue", "NullValue", "Identifier", "WS", "InlineComment", "MultilineComment"
|
||||
"This", "While", "Do", "If", "Else", "For", "Return", "New", "Switch",
|
||||
"Case", "Default", "Colon", "CharValue", "IntValue", "BooleanValue",
|
||||
"NullValue", "Identifier", "WS", "InlineComment", "MultilineComment"
|
||||
};
|
||||
}
|
||||
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
|
||||
@@ -131,7 +134,7 @@ public class SimpleJavaLexer extends Lexer {
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\u0004\u00002\u0198\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+
|
||||
"\u0004\u00007\u01bb\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+
|
||||
"\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+
|
||||
"\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+
|
||||
"\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+
|
||||
@@ -145,7 +148,8 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+
|
||||
"&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+
|
||||
"+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+
|
||||
"0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0001\u0000"+
|
||||
"0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u00025\u0007"+
|
||||
"5\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0001\u0000"+
|
||||
"\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+
|
||||
"\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003"+
|
||||
"\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
|
||||
@@ -157,16 +161,16 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
|
||||
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
|
||||
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
|
||||
"\u0001\u0006\u0003\u0006\u00b0\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0006\u0003\u0006\u00ba\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
|
||||
"\u0001\b\u0001\b\u0001\b\u0003\b\u00dc\b\b\u0001\t\u0001\t\u0003\t\u00e0"+
|
||||
"\b\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003\n\u00e8\b\n"+
|
||||
"\u0001\u000b\u0001\u000b\u0003\u000b\u00ec\b\u000b\u0001\f\u0001\f\u0001"+
|
||||
"\u0001\b\u0001\b\u0001\b\u0003\b\u00e6\b\b\u0001\t\u0001\t\u0003\t\u00ea"+
|
||||
"\b\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003\n\u00f2\b\n"+
|
||||
"\u0001\u000b\u0001\u000b\u0003\u000b\u00f6\b\u000b\u0001\f\u0001\f\u0001"+
|
||||
"\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u0010"+
|
||||
"\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0013"+
|
||||
"\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015"+
|
||||
@@ -177,212 +181,231 @@ public class SimpleJavaLexer extends Lexer {
|
||||
"\u0001\u001f\u0001 \u0001 \u0001!\u0001!\u0001\"\u0001\"\u0001\"\u0001"+
|
||||
"\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001"+
|
||||
"$\u0001$\u0001$\u0001$\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001"+
|
||||
"&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001"+
|
||||
"(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001)\u0001*\u0001*\u0005*\u014a"+
|
||||
"\b*\n*\f*\u014d\t*\u0001*\u0001*\u0001+\u0003+\u0152\b+\u0001+\u0004+"+
|
||||
"\u0155\b+\u000b+\f+\u0156\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001"+
|
||||
",\u0001,\u0001,\u0003,\u0162\b,\u0001-\u0001-\u0001-\u0001-\u0001-\u0001"+
|
||||
".\u0001.\u0001/\u0001/\u00010\u00010\u00010\u00030\u0170\b0\u00011\u0001"+
|
||||
"1\u00051\u0174\b1\n1\f1\u0177\t1\u00012\u00042\u017a\b2\u000b2\f2\u017b"+
|
||||
"\u00012\u00012\u00013\u00013\u00013\u00013\u00053\u0184\b3\n3\f3\u0187"+
|
||||
"\t3\u00013\u00013\u00014\u00014\u00014\u00014\u00054\u018f\b4\n4\f4\u0192"+
|
||||
"\t4\u00014\u00014\u00014\u00014\u00014\u0001\u0190\u00005\u0001\u0001"+
|
||||
"\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f"+
|
||||
"\b\u0011\t\u0013\n\u0015\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f"+
|
||||
"\u001f\u0010!\u0011#\u0012%\u0013\'\u0014)\u0015+\u0016-\u0017/\u0018"+
|
||||
"1\u00193\u001a5\u001b7\u001c9\u001d;\u001e=\u001f? A!C\"E#G$I%K&M\'O("+
|
||||
"Q)S*U+W,Y-[.]\u0000_\u0000a\u0000c/e0g1i2\u0001\u0000\u0005\u0002\u0000"+
|
||||
"\n\n\r\r\u0002\u0000AZaz\u0001\u000009\u0002\u0000$$__\u0003\u0000\t\n"+
|
||||
"\r\r \u01aa\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000"+
|
||||
"\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000"+
|
||||
"\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000"+
|
||||
"\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000"+
|
||||
"\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000"+
|
||||
"\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000"+
|
||||
"\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%"+
|
||||
"\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001"+
|
||||
"\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000"+
|
||||
"\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u0000"+
|
||||
"3\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001"+
|
||||
"\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000"+
|
||||
"\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000"+
|
||||
"A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001"+
|
||||
"\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000"+
|
||||
"\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000"+
|
||||
"O\u0001\u0000\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001"+
|
||||
"\u0000\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000"+
|
||||
"\u0000\u0000Y\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000"+
|
||||
"c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000\u0000\u0000g\u0001"+
|
||||
"\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0001k\u0001\u0000\u0000"+
|
||||
"\u0000\u0003n\u0001\u0000\u0000\u0000\u0005q\u0001\u0000\u0000\u0000\u0007"+
|
||||
"v\u0001\u0000\u0000\u0000\t~\u0001\u0000\u0000\u0000\u000b\u0083\u0001"+
|
||||
"\u0000\u0000\u0000\r\u00af\u0001\u0000\u0000\u0000\u000f\u00b1\u0001\u0000"+
|
||||
"\u0000\u0000\u0011\u00db\u0001\u0000\u0000\u0000\u0013\u00df\u0001\u0000"+
|
||||
"\u0000\u0000\u0015\u00e7\u0001\u0000\u0000\u0000\u0017\u00eb\u0001\u0000"+
|
||||
"\u0000\u0000\u0019\u00ed\u0001\u0000\u0000\u0000\u001b\u00ef\u0001\u0000"+
|
||||
"\u0000\u0000\u001d\u00f1\u0001\u0000\u0000\u0000\u001f\u00f3\u0001\u0000"+
|
||||
"\u0000\u0000!\u00f5\u0001\u0000\u0000\u0000#\u00f7\u0001\u0000\u0000\u0000"+
|
||||
"%\u00f9\u0001\u0000\u0000\u0000\'\u00fb\u0001\u0000\u0000\u0000)\u00fd"+
|
||||
"\u0001\u0000\u0000\u0000+\u0100\u0001\u0000\u0000\u0000-\u0103\u0001\u0000"+
|
||||
"\u0000\u0000/\u0106\u0001\u0000\u0000\u00001\u0109\u0001\u0000\u0000\u0000"+
|
||||
"3\u010b\u0001\u0000\u0000\u00005\u010e\u0001\u0000\u0000\u00007\u0111"+
|
||||
"\u0001\u0000\u0000\u00009\u0113\u0001\u0000\u0000\u0000;\u0115\u0001\u0000"+
|
||||
"\u0000\u0000=\u0117\u0001\u0000\u0000\u0000?\u0119\u0001\u0000\u0000\u0000"+
|
||||
"A\u011b\u0001\u0000\u0000\u0000C\u011d\u0001\u0000\u0000\u0000E\u011f"+
|
||||
"\u0001\u0000\u0000\u0000G\u0125\u0001\u0000\u0000\u0000I\u012a\u0001\u0000"+
|
||||
"\u0000\u0000K\u0130\u0001\u0000\u0000\u0000M\u0133\u0001\u0000\u0000\u0000"+
|
||||
"O\u0138\u0001\u0000\u0000\u0000Q\u013c\u0001\u0000\u0000\u0000S\u0143"+
|
||||
"\u0001\u0000\u0000\u0000U\u0147\u0001\u0000\u0000\u0000W\u0151\u0001\u0000"+
|
||||
"\u0000\u0000Y\u0161\u0001\u0000\u0000\u0000[\u0163\u0001\u0000\u0000\u0000"+
|
||||
"]\u0168\u0001\u0000\u0000\u0000_\u016a\u0001\u0000\u0000\u0000a\u016f"+
|
||||
"\u0001\u0000\u0000\u0000c\u0171\u0001\u0000\u0000\u0000e\u0179\u0001\u0000"+
|
||||
"\u0000\u0000g\u017f\u0001\u0000\u0000\u0000i\u018a\u0001\u0000\u0000\u0000"+
|
||||
"kl\u0005+\u0000\u0000lm\u0005+\u0000\u0000m\u0002\u0001\u0000\u0000\u0000"+
|
||||
"no\u0005-\u0000\u0000op\u0005-\u0000\u0000p\u0004\u0001\u0000\u0000\u0000"+
|
||||
"qr\u0005v\u0000\u0000rs\u0005o\u0000\u0000st\u0005i\u0000\u0000tu\u0005"+
|
||||
"d\u0000\u0000u\u0006\u0001\u0000\u0000\u0000vw\u0005b\u0000\u0000wx\u0005"+
|
||||
"o\u0000\u0000xy\u0005o\u0000\u0000yz\u0005l\u0000\u0000z{\u0005e\u0000"+
|
||||
"\u0000{|\u0005a\u0000\u0000|}\u0005n\u0000\u0000}\b\u0001\u0000\u0000"+
|
||||
"\u0000~\u007f\u0005c\u0000\u0000\u007f\u0080\u0005h\u0000\u0000\u0080"+
|
||||
"\u0081\u0005a\u0000\u0000\u0081\u0082\u0005r\u0000\u0000\u0082\n\u0001"+
|
||||
"\u0000\u0000\u0000\u0083\u0084\u0005i\u0000\u0000\u0084\u0085\u0005n\u0000"+
|
||||
"\u0000\u0085\u0086\u0005t\u0000\u0000\u0086\f\u0001\u0000\u0000\u0000"+
|
||||
"\u0087\u0088\u0005p\u0000\u0000\u0088\u0089\u0005u\u0000\u0000\u0089\u008a"+
|
||||
"\u0005b\u0000\u0000\u008a\u008b\u0005l\u0000\u0000\u008b\u008c\u0005i"+
|
||||
"\u0000\u0000\u008c\u00b0\u0005c\u0000\u0000\u008d\u008e\u0005p\u0000\u0000"+
|
||||
"\u008e\u008f\u0005r\u0000\u0000\u008f\u0090\u0005i\u0000\u0000\u0090\u0091"+
|
||||
"\u0005v\u0000\u0000\u0091\u0092\u0005a\u0000\u0000\u0092\u0093\u0005t"+
|
||||
"\u0000\u0000\u0093\u00b0\u0005e\u0000\u0000\u0094\u0095\u0005p\u0000\u0000"+
|
||||
"\u0095\u0096\u0005u\u0000\u0000\u0096\u0097\u0005b\u0000\u0000\u0097\u0098"+
|
||||
"\u0005l\u0000\u0000\u0098\u0099\u0005i\u0000\u0000\u0099\u009a\u0005c"+
|
||||
"\u0000\u0000\u009a\u009b\u0005 \u0000\u0000\u009b\u009c\u0005s\u0000\u0000"+
|
||||
"\u009c\u009d\u0005t\u0000\u0000\u009d\u009e\u0005a\u0000\u0000\u009e\u009f"+
|
||||
"\u0005t\u0000\u0000\u009f\u00a0\u0005i\u0000\u0000\u00a0\u00b0\u0005c"+
|
||||
"\u0000\u0000\u00a1\u00a2\u0005p\u0000\u0000\u00a2\u00a3\u0005r\u0000\u0000"+
|
||||
"\u00a3\u00a4\u0005i\u0000\u0000\u00a4\u00a5\u0005v\u0000\u0000\u00a5\u00a6"+
|
||||
"\u0005a\u0000\u0000\u00a6\u00a7\u0005t\u0000\u0000\u00a7\u00a8\u0005e"+
|
||||
"\u0000\u0000\u00a8\u00a9\u0005 \u0000\u0000\u00a9\u00aa\u0005s\u0000\u0000"+
|
||||
"\u00aa\u00ab\u0005t\u0000\u0000\u00ab\u00ac\u0005a\u0000\u0000\u00ac\u00ad"+
|
||||
"\u0005t\u0000\u0000\u00ad\u00ae\u0005i\u0000\u0000\u00ae\u00b0\u0005c"+
|
||||
"\u0000\u0000\u00af\u0087\u0001\u0000\u0000\u0000\u00af\u008d\u0001\u0000"+
|
||||
"\u0000\u0000\u00af\u0094\u0001\u0000\u0000\u0000\u00af\u00a1\u0001\u0000"+
|
||||
"\u0000\u0000\u00b0\u000e\u0001\u0000\u0000\u0000\u00b1\u00b2\u0005p\u0000"+
|
||||
"\u0000\u00b2\u00b3\u0005u\u0000\u0000\u00b3\u00b4\u0005b\u0000\u0000\u00b4"+
|
||||
"\u00b5\u0005l\u0000\u0000\u00b5\u00b6\u0005i\u0000\u0000\u00b6\u00b7\u0005"+
|
||||
"c\u0000\u0000\u00b7\u00b8\u0005 \u0000\u0000\u00b8\u00b9\u0005s\u0000"+
|
||||
"\u0000\u00b9\u00ba\u0005t\u0000\u0000\u00ba\u00bb\u0005a\u0000\u0000\u00bb"+
|
||||
"\u00bc\u0005t\u0000\u0000\u00bc\u00bd\u0005i\u0000\u0000\u00bd\u00be\u0005"+
|
||||
"c\u0000\u0000\u00be\u00bf\u0005 \u0000\u0000\u00bf\u00c0\u0005v\u0000"+
|
||||
"\u0000\u00c0\u00c1\u0005o\u0000\u0000\u00c1\u00c2\u0005i\u0000\u0000\u00c2"+
|
||||
"\u00c3\u0005d\u0000\u0000\u00c3\u00c4\u0005 \u0000\u0000\u00c4\u00c5\u0005"+
|
||||
"m\u0000\u0000\u00c5\u00c6\u0005a\u0000\u0000\u00c6\u00c7\u0005i\u0000"+
|
||||
"\u0000\u00c7\u00c8\u0005n\u0000\u0000\u00c8\u00c9\u0005(\u0000\u0000\u00c9"+
|
||||
"\u00ca\u0005S\u0000\u0000\u00ca\u00cb\u0005t\u0000\u0000\u00cb\u00cc\u0005"+
|
||||
"r\u0000\u0000\u00cc\u00cd\u0005i\u0000\u0000\u00cd\u00ce\u0005n\u0000"+
|
||||
"\u0000\u00ce\u00cf\u0005g\u0000\u0000\u00cf\u00d0\u0005[\u0000\u0000\u00d0"+
|
||||
"\u00d1\u0005]\u0000\u0000\u00d1\u00d2\u0005 \u0000\u0000\u00d2\u00d3\u0005"+
|
||||
"a\u0000\u0000\u00d3\u00d4\u0005r\u0000\u0000\u00d4\u00d5\u0005g\u0000"+
|
||||
"\u0000\u00d5\u00d6\u0005s\u0000\u0000\u00d6\u00d7\u0005)\u0000\u0000\u00d7"+
|
||||
"\u0010\u0001\u0000\u0000\u0000\u00d8\u00dc\u0003\u001f\u000f\u0000\u00d9"+
|
||||
"\u00dc\u0003#\u0011\u0000\u00da\u00dc\u0003!\u0010\u0000\u00db\u00d8\u0001"+
|
||||
"\u0000\u0000\u0000\u00db\u00d9\u0001\u0000\u0000\u0000\u00db\u00da\u0001"+
|
||||
"\u0000\u0000\u0000\u00dc\u0012\u0001\u0000\u0000\u0000\u00dd\u00e0\u0003"+
|
||||
"\u001b\r\u0000\u00de\u00e0\u0003\u001d\u000e\u0000\u00df\u00dd\u0001\u0000"+
|
||||
"\u0000\u0000\u00df\u00de\u0001\u0000\u0000\u0000\u00e0\u0014\u0001\u0000"+
|
||||
"\u0000\u0000\u00e1\u00e8\u0003%\u0012\u0000\u00e2\u00e8\u0003\'\u0013"+
|
||||
"\u0000\u00e3\u00e8\u0003)\u0014\u0000\u00e4\u00e8\u0003+\u0015\u0000\u00e5"+
|
||||
"\u00e8\u0003-\u0016\u0000\u00e6\u00e8\u0003/\u0017\u0000\u00e7\u00e1\u0001"+
|
||||
"\u0000\u0000\u0000\u00e7\u00e2\u0001\u0000\u0000\u0000\u00e7\u00e3\u0001"+
|
||||
"\u0000\u0000\u0000\u00e7\u00e4\u0001\u0000\u0000\u0000\u00e7\u00e5\u0001"+
|
||||
"\u0000\u0000\u0000\u00e7\u00e6\u0001\u0000\u0000\u0000\u00e8\u0016\u0001"+
|
||||
"\u0000\u0000\u0000\u00e9\u00ec\u00033\u0019\u0000\u00ea\u00ec\u00035\u001a"+
|
||||
"\u0000\u00eb\u00e9\u0001\u0000\u0000\u0000\u00eb\u00ea\u0001\u0000\u0000"+
|
||||
"\u0000\u00ec\u0018\u0001\u0000\u0000\u0000\u00ed\u00ee\u0005=\u0000\u0000"+
|
||||
"\u00ee\u001a\u0001\u0000\u0000\u0000\u00ef\u00f0\u0005+\u0000\u0000\u00f0"+
|
||||
"\u001c\u0001\u0000\u0000\u0000\u00f1\u00f2\u0005-\u0000\u0000\u00f2\u001e"+
|
||||
"\u0001\u0000\u0000\u0000\u00f3\u00f4\u0005*\u0000\u0000\u00f4 \u0001\u0000"+
|
||||
"\u0000\u0000\u00f5\u00f6\u0005%\u0000\u0000\u00f6\"\u0001\u0000\u0000"+
|
||||
"\u0000\u00f7\u00f8\u0005/\u0000\u0000\u00f8$\u0001\u0000\u0000\u0000\u00f9"+
|
||||
"\u00fa\u0005>\u0000\u0000\u00fa&\u0001\u0000\u0000\u0000\u00fb\u00fc\u0005"+
|
||||
"<\u0000\u0000\u00fc(\u0001\u0000\u0000\u0000\u00fd\u00fe\u0005>\u0000"+
|
||||
"\u0000\u00fe\u00ff\u0005=\u0000\u0000\u00ff*\u0001\u0000\u0000\u0000\u0100"+
|
||||
"\u0101\u0005<\u0000\u0000\u0101\u0102\u0005=\u0000\u0000\u0102,\u0001"+
|
||||
"\u0000\u0000\u0000\u0103\u0104\u0005=\u0000\u0000\u0104\u0105\u0005=\u0000"+
|
||||
"\u0000\u0105.\u0001\u0000\u0000\u0000\u0106\u0107\u0005!\u0000\u0000\u0107"+
|
||||
"\u0108\u0005=\u0000\u0000\u01080\u0001\u0000\u0000\u0000\u0109\u010a\u0005"+
|
||||
"!\u0000\u0000\u010a2\u0001\u0000\u0000\u0000\u010b\u010c\u0005&\u0000"+
|
||||
"\u0000\u010c\u010d\u0005&\u0000\u0000\u010d4\u0001\u0000\u0000\u0000\u010e"+
|
||||
"\u010f\u0005|\u0000\u0000\u010f\u0110\u0005|\u0000\u0000\u01106\u0001"+
|
||||
"\u0000\u0000\u0000\u0111\u0112\u0005.\u0000\u0000\u01128\u0001\u0000\u0000"+
|
||||
"\u0000\u0113\u0114\u0005(\u0000\u0000\u0114:\u0001\u0000\u0000\u0000\u0115"+
|
||||
"\u0116\u0005)\u0000\u0000\u0116<\u0001\u0000\u0000\u0000\u0117\u0118\u0005"+
|
||||
"{\u0000\u0000\u0118>\u0001\u0000\u0000\u0000\u0119\u011a\u0005}\u0000"+
|
||||
"\u0000\u011a@\u0001\u0000\u0000\u0000\u011b\u011c\u0005;\u0000\u0000\u011c"+
|
||||
"B\u0001\u0000\u0000\u0000\u011d\u011e\u0005,\u0000\u0000\u011eD\u0001"+
|
||||
"\u0000\u0000\u0000\u011f\u0120\u0005c\u0000\u0000\u0120\u0121\u0005l\u0000"+
|
||||
"\u0000\u0121\u0122\u0005a\u0000\u0000\u0122\u0123\u0005s\u0000\u0000\u0123"+
|
||||
"\u0124\u0005s\u0000\u0000\u0124F\u0001\u0000\u0000\u0000\u0125\u0126\u0005"+
|
||||
"t\u0000\u0000\u0126\u0127\u0005h\u0000\u0000\u0127\u0128\u0005i\u0000"+
|
||||
"\u0000\u0128\u0129\u0005s\u0000\u0000\u0129H\u0001\u0000\u0000\u0000\u012a"+
|
||||
"\u012b\u0005w\u0000\u0000\u012b\u012c\u0005h\u0000\u0000\u012c\u012d\u0005"+
|
||||
"i\u0000\u0000\u012d\u012e\u0005l\u0000\u0000\u012e\u012f\u0005e\u0000"+
|
||||
"\u0000\u012fJ\u0001\u0000\u0000\u0000\u0130\u0131\u0005i\u0000\u0000\u0131"+
|
||||
"\u0132\u0005f\u0000\u0000\u0132L\u0001\u0000\u0000\u0000\u0133\u0134\u0005"+
|
||||
"e\u0000\u0000\u0134\u0135\u0005l\u0000\u0000\u0135\u0136\u0005s\u0000"+
|
||||
"\u0000\u0136\u0137\u0005e\u0000\u0000\u0137N\u0001\u0000\u0000\u0000\u0138"+
|
||||
"\u0139\u0005f\u0000\u0000\u0139\u013a\u0005o\u0000\u0000\u013a\u013b\u0005"+
|
||||
"r\u0000\u0000\u013bP\u0001\u0000\u0000\u0000\u013c\u013d\u0005r\u0000"+
|
||||
"\u0000\u013d\u013e\u0005e\u0000\u0000\u013e\u013f\u0005t\u0000\u0000\u013f"+
|
||||
"\u0140\u0005u\u0000\u0000\u0140\u0141\u0005r\u0000\u0000\u0141\u0142\u0005"+
|
||||
"n\u0000\u0000\u0142R\u0001\u0000\u0000\u0000\u0143\u0144\u0005n\u0000"+
|
||||
"\u0000\u0144\u0145\u0005e\u0000\u0000\u0145\u0146\u0005w\u0000\u0000\u0146"+
|
||||
"T\u0001\u0000\u0000\u0000\u0147\u014b\u0005\'\u0000\u0000\u0148\u014a"+
|
||||
"\b\u0000\u0000\u0000\u0149\u0148\u0001\u0000\u0000\u0000\u014a\u014d\u0001"+
|
||||
"\u0000\u0000\u0000\u014b\u0149\u0001\u0000\u0000\u0000\u014b\u014c\u0001"+
|
||||
"\u0000\u0000\u0000\u014c\u014e\u0001\u0000\u0000\u0000\u014d\u014b\u0001"+
|
||||
"\u0000\u0000\u0000\u014e\u014f\u0005\'\u0000\u0000\u014fV\u0001\u0000"+
|
||||
"\u0000\u0000\u0150\u0152\u0003\u001d\u000e\u0000\u0151\u0150\u0001\u0000"+
|
||||
"\u0000\u0000\u0151\u0152\u0001\u0000\u0000\u0000\u0152\u0154\u0001\u0000"+
|
||||
"\u0000\u0000\u0153\u0155\u0003_/\u0000\u0154\u0153\u0001\u0000\u0000\u0000"+
|
||||
"\u0155\u0156\u0001\u0000\u0000\u0000\u0156\u0154\u0001\u0000\u0000\u0000"+
|
||||
"\u0156\u0157\u0001\u0000\u0000\u0000\u0157X\u0001\u0000\u0000\u0000\u0158"+
|
||||
"\u0159\u0005t\u0000\u0000\u0159\u015a\u0005r\u0000\u0000\u015a\u015b\u0005"+
|
||||
"u\u0000\u0000\u015b\u0162\u0005e\u0000\u0000\u015c\u015d\u0005f\u0000"+
|
||||
"\u0000\u015d\u015e\u0005a\u0000\u0000\u015e\u015f\u0005l\u0000\u0000\u015f"+
|
||||
"\u0160\u0005s\u0000\u0000\u0160\u0162\u0005e\u0000\u0000\u0161\u0158\u0001"+
|
||||
"\u0000\u0000\u0000\u0161\u015c\u0001\u0000\u0000\u0000\u0162Z\u0001\u0000"+
|
||||
"\u0000\u0000\u0163\u0164\u0005n\u0000\u0000\u0164\u0165\u0005u\u0000\u0000"+
|
||||
"\u0165\u0166\u0005l\u0000\u0000\u0166\u0167\u0005l\u0000\u0000\u0167\\"+
|
||||
"\u0001\u0000\u0000\u0000\u0168\u0169\u0007\u0001\u0000\u0000\u0169^\u0001"+
|
||||
"\u0000\u0000\u0000\u016a\u016b\u0007\u0002\u0000\u0000\u016b`\u0001\u0000"+
|
||||
"\u0000\u0000\u016c\u0170\u0003].\u0000\u016d\u0170\u0003_/\u0000\u016e"+
|
||||
"\u0170\u0007\u0003\u0000\u0000\u016f\u016c\u0001\u0000\u0000\u0000\u016f"+
|
||||
"\u016d\u0001\u0000\u0000\u0000\u016f\u016e\u0001\u0000\u0000\u0000\u0170"+
|
||||
"b\u0001\u0000\u0000\u0000\u0171\u0175\u0003].\u0000\u0172\u0174\u0003"+
|
||||
"a0\u0000\u0173\u0172\u0001\u0000\u0000\u0000\u0174\u0177\u0001\u0000\u0000"+
|
||||
"\u0000\u0175\u0173\u0001\u0000\u0000\u0000\u0175\u0176\u0001\u0000\u0000"+
|
||||
"\u0000\u0176d\u0001\u0000\u0000\u0000\u0177\u0175\u0001\u0000\u0000\u0000"+
|
||||
"\u0178\u017a\u0007\u0004\u0000\u0000\u0179\u0178\u0001\u0000\u0000\u0000"+
|
||||
"\u017a\u017b\u0001\u0000\u0000\u0000\u017b\u0179\u0001\u0000\u0000\u0000"+
|
||||
"\u017b\u017c\u0001\u0000\u0000\u0000\u017c\u017d\u0001\u0000\u0000\u0000"+
|
||||
"\u017d\u017e\u00062\u0000\u0000\u017ef\u0001\u0000\u0000\u0000\u017f\u0180"+
|
||||
"\u0005/\u0000\u0000\u0180\u0181\u0005/\u0000\u0000\u0181\u0185\u0001\u0000"+
|
||||
"\u0000\u0000\u0182\u0184\b\u0000\u0000\u0000\u0183\u0182\u0001\u0000\u0000"+
|
||||
"\u0000\u0184\u0187\u0001\u0000\u0000\u0000\u0185\u0183\u0001\u0000\u0000"+
|
||||
"\u0000\u0185\u0186\u0001\u0000\u0000\u0000\u0186\u0188\u0001\u0000\u0000"+
|
||||
"\u0000\u0187\u0185\u0001\u0000\u0000\u0000\u0188\u0189\u00063\u0000\u0000"+
|
||||
"\u0189h\u0001\u0000\u0000\u0000\u018a\u018b\u0005/\u0000\u0000\u018b\u018c"+
|
||||
"\u0005*\u0000\u0000\u018c\u0190\u0001\u0000\u0000\u0000\u018d\u018f\t"+
|
||||
"\u0000\u0000\u0000\u018e\u018d\u0001\u0000\u0000\u0000\u018f\u0192\u0001"+
|
||||
"\u0000\u0000\u0000\u0190\u0191\u0001\u0000\u0000\u0000\u0190\u018e\u0001"+
|
||||
"\u0000\u0000\u0000\u0191\u0193\u0001\u0000\u0000\u0000\u0192\u0190\u0001"+
|
||||
"\u0000\u0000\u0000\u0193\u0194\u0005*\u0000\u0000\u0194\u0195\u0005/\u0000"+
|
||||
"\u0000\u0195\u0196\u0001\u0000\u0000\u0000\u0196\u0197\u00064\u0000\u0000"+
|
||||
"\u0197j\u0001\u0000\u0000\u0000\u000f\u0000\u00af\u00db\u00df\u00e7\u00eb"+
|
||||
"\u014b\u0151\u0156\u0161\u016f\u0175\u017b\u0185\u0190\u0001\u0006\u0000"+
|
||||
"\u0000";
|
||||
"\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001)"+
|
||||
"\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001"+
|
||||
"*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001"+
|
||||
",\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001"+
|
||||
"-\u0001.\u0001.\u0001/\u0001/\u0005/\u016d\b/\n/\f/\u0170\t/\u0001/\u0001"+
|
||||
"/\u00010\u00030\u0175\b0\u00010\u00040\u0178\b0\u000b0\f0\u0179\u0001"+
|
||||
"1\u00011\u00011\u00011\u00011\u00011\u00011\u00011\u00011\u00031\u0185"+
|
||||
"\b1\u00012\u00012\u00012\u00012\u00012\u00013\u00013\u00014\u00014\u0001"+
|
||||
"5\u00015\u00015\u00035\u0193\b5\u00016\u00016\u00056\u0197\b6\n6\f6\u019a"+
|
||||
"\t6\u00017\u00047\u019d\b7\u000b7\f7\u019e\u00017\u00017\u00018\u0001"+
|
||||
"8\u00018\u00018\u00058\u01a7\b8\n8\f8\u01aa\t8\u00018\u00018\u00019\u0001"+
|
||||
"9\u00019\u00019\u00059\u01b2\b9\n9\f9\u01b5\t9\u00019\u00019\u00019\u0001"+
|
||||
"9\u00019\u0001\u01b3\u0000:\u0001\u0001\u0003\u0002\u0005\u0003\u0007"+
|
||||
"\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b"+
|
||||
"\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013"+
|
||||
"\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d"+
|
||||
";\u001e=\u001f? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e3g\u0000i\u0000"+
|
||||
"k\u0000m4o5q6s7\u0001\u0000\u0005\u0002\u0000\n\n\r\r\u0002\u0000AZaz"+
|
||||
"\u0001\u000009\u0002\u0000$$__\u0003\u0000\t\n\r\r \u01cd\u0000\u0001"+
|
||||
"\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000\u0005"+
|
||||
"\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001"+
|
||||
"\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000"+
|
||||
"\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001\u0000\u0000"+
|
||||
"\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000\u0000\u0000"+
|
||||
"\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001"+
|
||||
"\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000"+
|
||||
"\u0000\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u0000"+
|
||||
"5\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000\u00009\u0001"+
|
||||
"\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000"+
|
||||
"\u0000\u0000?\u0001\u0000\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000"+
|
||||
"C\u0001\u0000\u0000\u0000\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001"+
|
||||
"\u0000\u0000\u0000\u0000I\u0001\u0000\u0000\u0000\u0000K\u0001\u0000\u0000"+
|
||||
"\u0000\u0000M\u0001\u0000\u0000\u0000\u0000O\u0001\u0000\u0000\u0000\u0000"+
|
||||
"Q\u0001\u0000\u0000\u0000\u0000S\u0001\u0000\u0000\u0000\u0000U\u0001"+
|
||||
"\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000\u0000Y\u0001\u0000\u0000"+
|
||||
"\u0000\u0000[\u0001\u0000\u0000\u0000\u0000]\u0001\u0000\u0000\u0000\u0000"+
|
||||
"_\u0001\u0000\u0000\u0000\u0000a\u0001\u0000\u0000\u0000\u0000c\u0001"+
|
||||
"\u0000\u0000\u0000\u0000e\u0001\u0000\u0000\u0000\u0000m\u0001\u0000\u0000"+
|
||||
"\u0000\u0000o\u0001\u0000\u0000\u0000\u0000q\u0001\u0000\u0000\u0000\u0000"+
|
||||
"s\u0001\u0000\u0000\u0000\u0001u\u0001\u0000\u0000\u0000\u0003x\u0001"+
|
||||
"\u0000\u0000\u0000\u0005{\u0001\u0000\u0000\u0000\u0007\u0080\u0001\u0000"+
|
||||
"\u0000\u0000\t\u0088\u0001\u0000\u0000\u0000\u000b\u008d\u0001\u0000\u0000"+
|
||||
"\u0000\r\u00b9\u0001\u0000\u0000\u0000\u000f\u00bb\u0001\u0000\u0000\u0000"+
|
||||
"\u0011\u00e5\u0001\u0000\u0000\u0000\u0013\u00e9\u0001\u0000\u0000\u0000"+
|
||||
"\u0015\u00f1\u0001\u0000\u0000\u0000\u0017\u00f5\u0001\u0000\u0000\u0000"+
|
||||
"\u0019\u00f7\u0001\u0000\u0000\u0000\u001b\u00f9\u0001\u0000\u0000\u0000"+
|
||||
"\u001d\u00fb\u0001\u0000\u0000\u0000\u001f\u00fd\u0001\u0000\u0000\u0000"+
|
||||
"!\u00ff\u0001\u0000\u0000\u0000#\u0101\u0001\u0000\u0000\u0000%\u0103"+
|
||||
"\u0001\u0000\u0000\u0000\'\u0105\u0001\u0000\u0000\u0000)\u0107\u0001"+
|
||||
"\u0000\u0000\u0000+\u010a\u0001\u0000\u0000\u0000-\u010d\u0001\u0000\u0000"+
|
||||
"\u0000/\u0110\u0001\u0000\u0000\u00001\u0113\u0001\u0000\u0000\u00003"+
|
||||
"\u0115\u0001\u0000\u0000\u00005\u0118\u0001\u0000\u0000\u00007\u011b\u0001"+
|
||||
"\u0000\u0000\u00009\u011d\u0001\u0000\u0000\u0000;\u011f\u0001\u0000\u0000"+
|
||||
"\u0000=\u0121\u0001\u0000\u0000\u0000?\u0123\u0001\u0000\u0000\u0000A"+
|
||||
"\u0125\u0001\u0000\u0000\u0000C\u0127\u0001\u0000\u0000\u0000E\u0129\u0001"+
|
||||
"\u0000\u0000\u0000G\u012f\u0001\u0000\u0000\u0000I\u0134\u0001\u0000\u0000"+
|
||||
"\u0000K\u013a\u0001\u0000\u0000\u0000M\u013d\u0001\u0000\u0000\u0000O"+
|
||||
"\u0140\u0001\u0000\u0000\u0000Q\u0145\u0001\u0000\u0000\u0000S\u0149\u0001"+
|
||||
"\u0000\u0000\u0000U\u0150\u0001\u0000\u0000\u0000W\u0154\u0001\u0000\u0000"+
|
||||
"\u0000Y\u015b\u0001\u0000\u0000\u0000[\u0160\u0001\u0000\u0000\u0000]"+
|
||||
"\u0168\u0001\u0000\u0000\u0000_\u016a\u0001\u0000\u0000\u0000a\u0174\u0001"+
|
||||
"\u0000\u0000\u0000c\u0184\u0001\u0000\u0000\u0000e\u0186\u0001\u0000\u0000"+
|
||||
"\u0000g\u018b\u0001\u0000\u0000\u0000i\u018d\u0001\u0000\u0000\u0000k"+
|
||||
"\u0192\u0001\u0000\u0000\u0000m\u0194\u0001\u0000\u0000\u0000o\u019c\u0001"+
|
||||
"\u0000\u0000\u0000q\u01a2\u0001\u0000\u0000\u0000s\u01ad\u0001\u0000\u0000"+
|
||||
"\u0000uv\u0005+\u0000\u0000vw\u0005+\u0000\u0000w\u0002\u0001\u0000\u0000"+
|
||||
"\u0000xy\u0005-\u0000\u0000yz\u0005-\u0000\u0000z\u0004\u0001\u0000\u0000"+
|
||||
"\u0000{|\u0005v\u0000\u0000|}\u0005o\u0000\u0000}~\u0005i\u0000\u0000"+
|
||||
"~\u007f\u0005d\u0000\u0000\u007f\u0006\u0001\u0000\u0000\u0000\u0080\u0081"+
|
||||
"\u0005b\u0000\u0000\u0081\u0082\u0005o\u0000\u0000\u0082\u0083\u0005o"+
|
||||
"\u0000\u0000\u0083\u0084\u0005l\u0000\u0000\u0084\u0085\u0005e\u0000\u0000"+
|
||||
"\u0085\u0086\u0005a\u0000\u0000\u0086\u0087\u0005n\u0000\u0000\u0087\b"+
|
||||
"\u0001\u0000\u0000\u0000\u0088\u0089\u0005c\u0000\u0000\u0089\u008a\u0005"+
|
||||
"h\u0000\u0000\u008a\u008b\u0005a\u0000\u0000\u008b\u008c\u0005r\u0000"+
|
||||
"\u0000\u008c\n\u0001\u0000\u0000\u0000\u008d\u008e\u0005i\u0000\u0000"+
|
||||
"\u008e\u008f\u0005n\u0000\u0000\u008f\u0090\u0005t\u0000\u0000\u0090\f"+
|
||||
"\u0001\u0000\u0000\u0000\u0091\u0092\u0005p\u0000\u0000\u0092\u0093\u0005"+
|
||||
"u\u0000\u0000\u0093\u0094\u0005b\u0000\u0000\u0094\u0095\u0005l\u0000"+
|
||||
"\u0000\u0095\u0096\u0005i\u0000\u0000\u0096\u00ba\u0005c\u0000\u0000\u0097"+
|
||||
"\u0098\u0005p\u0000\u0000\u0098\u0099\u0005r\u0000\u0000\u0099\u009a\u0005"+
|
||||
"i\u0000\u0000\u009a\u009b\u0005v\u0000\u0000\u009b\u009c\u0005a\u0000"+
|
||||
"\u0000\u009c\u009d\u0005t\u0000\u0000\u009d\u00ba\u0005e\u0000\u0000\u009e"+
|
||||
"\u009f\u0005p\u0000\u0000\u009f\u00a0\u0005u\u0000\u0000\u00a0\u00a1\u0005"+
|
||||
"b\u0000\u0000\u00a1\u00a2\u0005l\u0000\u0000\u00a2\u00a3\u0005i\u0000"+
|
||||
"\u0000\u00a3\u00a4\u0005c\u0000\u0000\u00a4\u00a5\u0005 \u0000\u0000\u00a5"+
|
||||
"\u00a6\u0005s\u0000\u0000\u00a6\u00a7\u0005t\u0000\u0000\u00a7\u00a8\u0005"+
|
||||
"a\u0000\u0000\u00a8\u00a9\u0005t\u0000\u0000\u00a9\u00aa\u0005i\u0000"+
|
||||
"\u0000\u00aa\u00ba\u0005c\u0000\u0000\u00ab\u00ac\u0005p\u0000\u0000\u00ac"+
|
||||
"\u00ad\u0005r\u0000\u0000\u00ad\u00ae\u0005i\u0000\u0000\u00ae\u00af\u0005"+
|
||||
"v\u0000\u0000\u00af\u00b0\u0005a\u0000\u0000\u00b0\u00b1\u0005t\u0000"+
|
||||
"\u0000\u00b1\u00b2\u0005e\u0000\u0000\u00b2\u00b3\u0005 \u0000\u0000\u00b3"+
|
||||
"\u00b4\u0005s\u0000\u0000\u00b4\u00b5\u0005t\u0000\u0000\u00b5\u00b6\u0005"+
|
||||
"a\u0000\u0000\u00b6\u00b7\u0005t\u0000\u0000\u00b7\u00b8\u0005i\u0000"+
|
||||
"\u0000\u00b8\u00ba\u0005c\u0000\u0000\u00b9\u0091\u0001\u0000\u0000\u0000"+
|
||||
"\u00b9\u0097\u0001\u0000\u0000\u0000\u00b9\u009e\u0001\u0000\u0000\u0000"+
|
||||
"\u00b9\u00ab\u0001\u0000\u0000\u0000\u00ba\u000e\u0001\u0000\u0000\u0000"+
|
||||
"\u00bb\u00bc\u0005p\u0000\u0000\u00bc\u00bd\u0005u\u0000\u0000\u00bd\u00be"+
|
||||
"\u0005b\u0000\u0000\u00be\u00bf\u0005l\u0000\u0000\u00bf\u00c0\u0005i"+
|
||||
"\u0000\u0000\u00c0\u00c1\u0005c\u0000\u0000\u00c1\u00c2\u0005 \u0000\u0000"+
|
||||
"\u00c2\u00c3\u0005s\u0000\u0000\u00c3\u00c4\u0005t\u0000\u0000\u00c4\u00c5"+
|
||||
"\u0005a\u0000\u0000\u00c5\u00c6\u0005t\u0000\u0000\u00c6\u00c7\u0005i"+
|
||||
"\u0000\u0000\u00c7\u00c8\u0005c\u0000\u0000\u00c8\u00c9\u0005 \u0000\u0000"+
|
||||
"\u00c9\u00ca\u0005v\u0000\u0000\u00ca\u00cb\u0005o\u0000\u0000\u00cb\u00cc"+
|
||||
"\u0005i\u0000\u0000\u00cc\u00cd\u0005d\u0000\u0000\u00cd\u00ce\u0005 "+
|
||||
"\u0000\u0000\u00ce\u00cf\u0005m\u0000\u0000\u00cf\u00d0\u0005a\u0000\u0000"+
|
||||
"\u00d0\u00d1\u0005i\u0000\u0000\u00d1\u00d2\u0005n\u0000\u0000\u00d2\u00d3"+
|
||||
"\u0005(\u0000\u0000\u00d3\u00d4\u0005S\u0000\u0000\u00d4\u00d5\u0005t"+
|
||||
"\u0000\u0000\u00d5\u00d6\u0005r\u0000\u0000\u00d6\u00d7\u0005i\u0000\u0000"+
|
||||
"\u00d7\u00d8\u0005n\u0000\u0000\u00d8\u00d9\u0005g\u0000\u0000\u00d9\u00da"+
|
||||
"\u0005[\u0000\u0000\u00da\u00db\u0005]\u0000\u0000\u00db\u00dc\u0005 "+
|
||||
"\u0000\u0000\u00dc\u00dd\u0005a\u0000\u0000\u00dd\u00de\u0005r\u0000\u0000"+
|
||||
"\u00de\u00df\u0005g\u0000\u0000\u00df\u00e0\u0005s\u0000\u0000\u00e0\u00e1"+
|
||||
"\u0005)\u0000\u0000\u00e1\u0010\u0001\u0000\u0000\u0000\u00e2\u00e6\u0003"+
|
||||
"\u001f\u000f\u0000\u00e3\u00e6\u0003#\u0011\u0000\u00e4\u00e6\u0003!\u0010"+
|
||||
"\u0000\u00e5\u00e2\u0001\u0000\u0000\u0000\u00e5\u00e3\u0001\u0000\u0000"+
|
||||
"\u0000\u00e5\u00e4\u0001\u0000\u0000\u0000\u00e6\u0012\u0001\u0000\u0000"+
|
||||
"\u0000\u00e7\u00ea\u0003\u001b\r\u0000\u00e8\u00ea\u0003\u001d\u000e\u0000"+
|
||||
"\u00e9\u00e7\u0001\u0000\u0000\u0000\u00e9\u00e8\u0001\u0000\u0000\u0000"+
|
||||
"\u00ea\u0014\u0001\u0000\u0000\u0000\u00eb\u00f2\u0003%\u0012\u0000\u00ec"+
|
||||
"\u00f2\u0003\'\u0013\u0000\u00ed\u00f2\u0003)\u0014\u0000\u00ee\u00f2"+
|
||||
"\u0003+\u0015\u0000\u00ef\u00f2\u0003-\u0016\u0000\u00f0\u00f2\u0003/"+
|
||||
"\u0017\u0000\u00f1\u00eb\u0001\u0000\u0000\u0000\u00f1\u00ec\u0001\u0000"+
|
||||
"\u0000\u0000\u00f1\u00ed\u0001\u0000\u0000\u0000\u00f1\u00ee\u0001\u0000"+
|
||||
"\u0000\u0000\u00f1\u00ef\u0001\u0000\u0000\u0000\u00f1\u00f0\u0001\u0000"+
|
||||
"\u0000\u0000\u00f2\u0016\u0001\u0000\u0000\u0000\u00f3\u00f6\u00033\u0019"+
|
||||
"\u0000\u00f4\u00f6\u00035\u001a\u0000\u00f5\u00f3\u0001\u0000\u0000\u0000"+
|
||||
"\u00f5\u00f4\u0001\u0000\u0000\u0000\u00f6\u0018\u0001\u0000\u0000\u0000"+
|
||||
"\u00f7\u00f8\u0005=\u0000\u0000\u00f8\u001a\u0001\u0000\u0000\u0000\u00f9"+
|
||||
"\u00fa\u0005+\u0000\u0000\u00fa\u001c\u0001\u0000\u0000\u0000\u00fb\u00fc"+
|
||||
"\u0005-\u0000\u0000\u00fc\u001e\u0001\u0000\u0000\u0000\u00fd\u00fe\u0005"+
|
||||
"*\u0000\u0000\u00fe \u0001\u0000\u0000\u0000\u00ff\u0100\u0005%\u0000"+
|
||||
"\u0000\u0100\"\u0001\u0000\u0000\u0000\u0101\u0102\u0005/\u0000\u0000"+
|
||||
"\u0102$\u0001\u0000\u0000\u0000\u0103\u0104\u0005>\u0000\u0000\u0104&"+
|
||||
"\u0001\u0000\u0000\u0000\u0105\u0106\u0005<\u0000\u0000\u0106(\u0001\u0000"+
|
||||
"\u0000\u0000\u0107\u0108\u0005>\u0000\u0000\u0108\u0109\u0005=\u0000\u0000"+
|
||||
"\u0109*\u0001\u0000\u0000\u0000\u010a\u010b\u0005<\u0000\u0000\u010b\u010c"+
|
||||
"\u0005=\u0000\u0000\u010c,\u0001\u0000\u0000\u0000\u010d\u010e\u0005="+
|
||||
"\u0000\u0000\u010e\u010f\u0005=\u0000\u0000\u010f.\u0001\u0000\u0000\u0000"+
|
||||
"\u0110\u0111\u0005!\u0000\u0000\u0111\u0112\u0005=\u0000\u0000\u01120"+
|
||||
"\u0001\u0000\u0000\u0000\u0113\u0114\u0005!\u0000\u0000\u01142\u0001\u0000"+
|
||||
"\u0000\u0000\u0115\u0116\u0005&\u0000\u0000\u0116\u0117\u0005&\u0000\u0000"+
|
||||
"\u01174\u0001\u0000\u0000\u0000\u0118\u0119\u0005|\u0000\u0000\u0119\u011a"+
|
||||
"\u0005|\u0000\u0000\u011a6\u0001\u0000\u0000\u0000\u011b\u011c\u0005."+
|
||||
"\u0000\u0000\u011c8\u0001\u0000\u0000\u0000\u011d\u011e\u0005(\u0000\u0000"+
|
||||
"\u011e:\u0001\u0000\u0000\u0000\u011f\u0120\u0005)\u0000\u0000\u0120<"+
|
||||
"\u0001\u0000\u0000\u0000\u0121\u0122\u0005{\u0000\u0000\u0122>\u0001\u0000"+
|
||||
"\u0000\u0000\u0123\u0124\u0005}\u0000\u0000\u0124@\u0001\u0000\u0000\u0000"+
|
||||
"\u0125\u0126\u0005;\u0000\u0000\u0126B\u0001\u0000\u0000\u0000\u0127\u0128"+
|
||||
"\u0005,\u0000\u0000\u0128D\u0001\u0000\u0000\u0000\u0129\u012a\u0005c"+
|
||||
"\u0000\u0000\u012a\u012b\u0005l\u0000\u0000\u012b\u012c\u0005a\u0000\u0000"+
|
||||
"\u012c\u012d\u0005s\u0000\u0000\u012d\u012e\u0005s\u0000\u0000\u012eF"+
|
||||
"\u0001\u0000\u0000\u0000\u012f\u0130\u0005t\u0000\u0000\u0130\u0131\u0005"+
|
||||
"h\u0000\u0000\u0131\u0132\u0005i\u0000\u0000\u0132\u0133\u0005s\u0000"+
|
||||
"\u0000\u0133H\u0001\u0000\u0000\u0000\u0134\u0135\u0005w\u0000\u0000\u0135"+
|
||||
"\u0136\u0005h\u0000\u0000\u0136\u0137\u0005i\u0000\u0000\u0137\u0138\u0005"+
|
||||
"l\u0000\u0000\u0138\u0139\u0005e\u0000\u0000\u0139J\u0001\u0000\u0000"+
|
||||
"\u0000\u013a\u013b\u0005d\u0000\u0000\u013b\u013c\u0005o\u0000\u0000\u013c"+
|
||||
"L\u0001\u0000\u0000\u0000\u013d\u013e\u0005i\u0000\u0000\u013e\u013f\u0005"+
|
||||
"f\u0000\u0000\u013fN\u0001\u0000\u0000\u0000\u0140\u0141\u0005e\u0000"+
|
||||
"\u0000\u0141\u0142\u0005l\u0000\u0000\u0142\u0143\u0005s\u0000\u0000\u0143"+
|
||||
"\u0144\u0005e\u0000\u0000\u0144P\u0001\u0000\u0000\u0000\u0145\u0146\u0005"+
|
||||
"f\u0000\u0000\u0146\u0147\u0005o\u0000\u0000\u0147\u0148\u0005r\u0000"+
|
||||
"\u0000\u0148R\u0001\u0000\u0000\u0000\u0149\u014a\u0005r\u0000\u0000\u014a"+
|
||||
"\u014b\u0005e\u0000\u0000\u014b\u014c\u0005t\u0000\u0000\u014c\u014d\u0005"+
|
||||
"u\u0000\u0000\u014d\u014e\u0005r\u0000\u0000\u014e\u014f\u0005n\u0000"+
|
||||
"\u0000\u014fT\u0001\u0000\u0000\u0000\u0150\u0151\u0005n\u0000\u0000\u0151"+
|
||||
"\u0152\u0005e\u0000\u0000\u0152\u0153\u0005w\u0000\u0000\u0153V\u0001"+
|
||||
"\u0000\u0000\u0000\u0154\u0155\u0005s\u0000\u0000\u0155\u0156\u0005w\u0000"+
|
||||
"\u0000\u0156\u0157\u0005i\u0000\u0000\u0157\u0158\u0005t\u0000\u0000\u0158"+
|
||||
"\u0159\u0005c\u0000\u0000\u0159\u015a\u0005h\u0000\u0000\u015aX\u0001"+
|
||||
"\u0000\u0000\u0000\u015b\u015c\u0005c\u0000\u0000\u015c\u015d\u0005a\u0000"+
|
||||
"\u0000\u015d\u015e\u0005s\u0000\u0000\u015e\u015f\u0005e\u0000\u0000\u015f"+
|
||||
"Z\u0001\u0000\u0000\u0000\u0160\u0161\u0005d\u0000\u0000\u0161\u0162\u0005"+
|
||||
"e\u0000\u0000\u0162\u0163\u0005f\u0000\u0000\u0163\u0164\u0005a\u0000"+
|
||||
"\u0000\u0164\u0165\u0005u\u0000\u0000\u0165\u0166\u0005l\u0000\u0000\u0166"+
|
||||
"\u0167\u0005t\u0000\u0000\u0167\\\u0001\u0000\u0000\u0000\u0168\u0169"+
|
||||
"\u0005:\u0000\u0000\u0169^\u0001\u0000\u0000\u0000\u016a\u016e\u0005\'"+
|
||||
"\u0000\u0000\u016b\u016d\b\u0000\u0000\u0000\u016c\u016b\u0001\u0000\u0000"+
|
||||
"\u0000\u016d\u0170\u0001\u0000\u0000\u0000\u016e\u016c\u0001\u0000\u0000"+
|
||||
"\u0000\u016e\u016f\u0001\u0000\u0000\u0000\u016f\u0171\u0001\u0000\u0000"+
|
||||
"\u0000\u0170\u016e\u0001\u0000\u0000\u0000\u0171\u0172\u0005\'\u0000\u0000"+
|
||||
"\u0172`\u0001\u0000\u0000\u0000\u0173\u0175\u0003\u001d\u000e\u0000\u0174"+
|
||||
"\u0173\u0001\u0000\u0000\u0000\u0174\u0175\u0001\u0000\u0000\u0000\u0175"+
|
||||
"\u0177\u0001\u0000\u0000\u0000\u0176\u0178\u0003i4\u0000\u0177\u0176\u0001"+
|
||||
"\u0000\u0000\u0000\u0178\u0179\u0001\u0000\u0000\u0000\u0179\u0177\u0001"+
|
||||
"\u0000\u0000\u0000\u0179\u017a\u0001\u0000\u0000\u0000\u017ab\u0001\u0000"+
|
||||
"\u0000\u0000\u017b\u017c\u0005t\u0000\u0000\u017c\u017d\u0005r\u0000\u0000"+
|
||||
"\u017d\u017e\u0005u\u0000\u0000\u017e\u0185\u0005e\u0000\u0000\u017f\u0180"+
|
||||
"\u0005f\u0000\u0000\u0180\u0181\u0005a\u0000\u0000\u0181\u0182\u0005l"+
|
||||
"\u0000\u0000\u0182\u0183\u0005s\u0000\u0000\u0183\u0185\u0005e\u0000\u0000"+
|
||||
"\u0184\u017b\u0001\u0000\u0000\u0000\u0184\u017f\u0001\u0000\u0000\u0000"+
|
||||
"\u0185d\u0001\u0000\u0000\u0000\u0186\u0187\u0005n\u0000\u0000\u0187\u0188"+
|
||||
"\u0005u\u0000\u0000\u0188\u0189\u0005l\u0000\u0000\u0189\u018a\u0005l"+
|
||||
"\u0000\u0000\u018af\u0001\u0000\u0000\u0000\u018b\u018c\u0007\u0001\u0000"+
|
||||
"\u0000\u018ch\u0001\u0000\u0000\u0000\u018d\u018e\u0007\u0002\u0000\u0000"+
|
||||
"\u018ej\u0001\u0000\u0000\u0000\u018f\u0193\u0003g3\u0000\u0190\u0193"+
|
||||
"\u0003i4\u0000\u0191\u0193\u0007\u0003\u0000\u0000\u0192\u018f\u0001\u0000"+
|
||||
"\u0000\u0000\u0192\u0190\u0001\u0000\u0000\u0000\u0192\u0191\u0001\u0000"+
|
||||
"\u0000\u0000\u0193l\u0001\u0000\u0000\u0000\u0194\u0198\u0003g3\u0000"+
|
||||
"\u0195\u0197\u0003k5\u0000\u0196\u0195\u0001\u0000\u0000\u0000\u0197\u019a"+
|
||||
"\u0001\u0000\u0000\u0000\u0198\u0196\u0001\u0000\u0000\u0000\u0198\u0199"+
|
||||
"\u0001\u0000\u0000\u0000\u0199n\u0001\u0000\u0000\u0000\u019a\u0198\u0001"+
|
||||
"\u0000\u0000\u0000\u019b\u019d\u0007\u0004\u0000\u0000\u019c\u019b\u0001"+
|
||||
"\u0000\u0000\u0000\u019d\u019e\u0001\u0000\u0000\u0000\u019e\u019c\u0001"+
|
||||
"\u0000\u0000\u0000\u019e\u019f\u0001\u0000\u0000\u0000\u019f\u01a0\u0001"+
|
||||
"\u0000\u0000\u0000\u01a0\u01a1\u00067\u0000\u0000\u01a1p\u0001\u0000\u0000"+
|
||||
"\u0000\u01a2\u01a3\u0005/\u0000\u0000\u01a3\u01a4\u0005/\u0000\u0000\u01a4"+
|
||||
"\u01a8\u0001\u0000\u0000\u0000\u01a5\u01a7\b\u0000\u0000\u0000\u01a6\u01a5"+
|
||||
"\u0001\u0000\u0000\u0000\u01a7\u01aa\u0001\u0000\u0000\u0000\u01a8\u01a6"+
|
||||
"\u0001\u0000\u0000\u0000\u01a8\u01a9\u0001\u0000\u0000\u0000\u01a9\u01ab"+
|
||||
"\u0001\u0000\u0000\u0000\u01aa\u01a8\u0001\u0000\u0000\u0000\u01ab\u01ac"+
|
||||
"\u00068\u0000\u0000\u01acr\u0001\u0000\u0000\u0000\u01ad\u01ae\u0005/"+
|
||||
"\u0000\u0000\u01ae\u01af\u0005*\u0000\u0000\u01af\u01b3\u0001\u0000\u0000"+
|
||||
"\u0000\u01b0\u01b2\t\u0000\u0000\u0000\u01b1\u01b0\u0001\u0000\u0000\u0000"+
|
||||
"\u01b2\u01b5\u0001\u0000\u0000\u0000\u01b3\u01b4\u0001\u0000\u0000\u0000"+
|
||||
"\u01b3\u01b1\u0001\u0000\u0000\u0000\u01b4\u01b6\u0001\u0000\u0000\u0000"+
|
||||
"\u01b5\u01b3\u0001\u0000\u0000\u0000\u01b6\u01b7\u0005*\u0000\u0000\u01b7"+
|
||||
"\u01b8\u0005/\u0000\u0000\u01b8\u01b9\u0001\u0000\u0000\u0000\u01b9\u01ba"+
|
||||
"\u00069\u0000\u0000\u01bat\u0001\u0000\u0000\u0000\u000f\u0000\u00b9\u00e5"+
|
||||
"\u00e9\u00f1\u00f5\u016e\u0174\u0179\u0184\u0192\u0198\u019e\u01a8\u01b3"+
|
||||
"\u0001\u0006\u0000\u0000";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@@ -35,19 +35,24 @@ Comma=34
|
||||
Class=35
|
||||
This=36
|
||||
While=37
|
||||
If=38
|
||||
Else=39
|
||||
For=40
|
||||
Return=41
|
||||
New=42
|
||||
CharValue=43
|
||||
IntValue=44
|
||||
BooleanValue=45
|
||||
NullValue=46
|
||||
Identifier=47
|
||||
WS=48
|
||||
InlineComment=49
|
||||
MultilineComment=50
|
||||
Do=38
|
||||
If=39
|
||||
Else=40
|
||||
For=41
|
||||
Return=42
|
||||
New=43
|
||||
Switch=44
|
||||
Case=45
|
||||
Default=46
|
||||
Colon=47
|
||||
CharValue=48
|
||||
IntValue=49
|
||||
BooleanValue=50
|
||||
NullValue=51
|
||||
Identifier=52
|
||||
WS=53
|
||||
InlineComment=54
|
||||
MultilineComment=55
|
||||
'++'=1
|
||||
'--'=2
|
||||
'void'=3
|
||||
@@ -80,9 +85,14 @@ MultilineComment=50
|
||||
'class'=35
|
||||
'this'=36
|
||||
'while'=37
|
||||
'if'=38
|
||||
'else'=39
|
||||
'for'=40
|
||||
'return'=41
|
||||
'new'=42
|
||||
'null'=46
|
||||
'do'=38
|
||||
'if'=39
|
||||
'else'=40
|
||||
'for'=41
|
||||
'return'=42
|
||||
'new'=43
|
||||
'switch'=44
|
||||
'case'=45
|
||||
'default'=46
|
||||
':'=47
|
||||
'null'=51
|
||||
|
@@ -108,15 +108,15 @@ public interface SimpleJavaListener extends ParseTreeListener {
|
||||
*/
|
||||
void exitStatement(SimpleJavaParser.StatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#block}.
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#blockStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterBlock(SimpleJavaParser.BlockContext ctx);
|
||||
void enterBlockStatement(SimpleJavaParser.BlockStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#block}.
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#blockStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitBlock(SimpleJavaParser.BlockContext ctx);
|
||||
void exitBlockStatement(SimpleJavaParser.BlockStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#returnStatement}.
|
||||
* @param ctx the parse tree
|
||||
@@ -147,6 +147,16 @@ public interface SimpleJavaListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWhileStatement(SimpleJavaParser.WhileStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#doWhileStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#doWhileStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDoWhileStatement(SimpleJavaParser.DoWhileStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#forStatement}.
|
||||
* @param ctx the parse tree
|
||||
@@ -177,6 +187,16 @@ public interface SimpleJavaListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitIfStatement(SimpleJavaParser.IfStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#elseIfStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#elseIfStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitElseIfStatement(SimpleJavaParser.ElseIfStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#elseStatement}.
|
||||
* @param ctx the parse tree
|
||||
@@ -187,6 +207,36 @@ public interface SimpleJavaListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitElseStatement(SimpleJavaParser.ElseStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#switchStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#switchStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSwitchStatement(SimpleJavaParser.SwitchStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#caseStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCaseStatement(SimpleJavaParser.CaseStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#caseStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCaseStatement(SimpleJavaParser.CaseStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#defaultStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDefaultStatement(SimpleJavaParser.DefaultStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SimpleJavaParser#defaultStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDefaultStatement(SimpleJavaParser.DefaultStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SimpleJavaParser#statementExpression}.
|
||||
* @param ctx the parse tree
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user