aboutsummaryrefslogtreecommitdiffstats
path: root/main/core/parser
diff options
context:
space:
mode:
Diffstat (limited to 'main/core/parser')
-rw-r--r--main/core/parser/Parser.java171
-rw-r--r--main/core/parser/ast/ASTNode.java33
-rw-r--r--main/core/parser/ast/AdditionNode.java34
-rw-r--r--main/core/parser/ast/AssignmentNode.java36
-rw-r--r--main/core/parser/ast/ExpressionNode.java12
-rw-r--r--main/core/parser/ast/IntegerLiteralNode.java30
-rw-r--r--main/core/parser/ast/SymbolNode.java35
-rw-r--r--main/core/parser/datatype/DataContainer.java17
-rw-r--r--main/core/parser/datatype/IntegerDataContainer.java10
9 files changed, 378 insertions, 0 deletions
diff --git a/main/core/parser/Parser.java b/main/core/parser/Parser.java
new file mode 100644
index 0000000..af62f7e
--- /dev/null
+++ b/main/core/parser/Parser.java
@@ -0,0 +1,171 @@
+package com.jantuomi.interpreter.main.core.parser;
+
+import com.jantuomi.interpreter.main.core.parser.ast.*;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.utils.Counter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+public class Parser {
+ private static final Parser instance = new Parser();
+
+ private List<Token> tokens;
+ private List<ASTNode> statementSequence;
+
+ public static Parser getInstance() {
+ return instance;
+ }
+
+ private Parser() {
+
+ }
+
+ public List<ASTNode> parse(List<Token> tokens) {
+ this.tokens = tokens;
+ this.statementSequence = new ArrayList<>();
+
+ Counter c = new Counter();
+ while (c.getValue() < tokens.size()) {
+ AssignmentNode asn = expectAssignmentRoutine(c);
+ if (asn != null) {
+ statementSequence.add(asn);
+ continue;
+ }
+ AdditionNode adn = expectAdditionRoutine(c);
+ if (adn != null) {
+ statementSequence.add(adn);
+ continue;
+ }
+ }
+
+ return statementSequence;
+ }
+
+ public AssignmentNode expectAssignmentRoutine(Counter c) {
+ Counter d = c.clone();
+
+ SymbolNode lhs = expectLHS(d);
+ if (lhs == null) {
+ return null;
+ }
+ boolean isAssign = expectAssignmentAndAdvance(d);
+ if (!isAssign) {
+ return null;
+ }
+ ExpressionNode rhs = expectRHS(d);
+ if (rhs == null) {
+ return null;
+ }
+
+ AssignmentNode an = new AssignmentNode(lhs, rhs);
+ c.setValue(d.getValue());
+ return an;
+ }
+
+ public SymbolNode expectLHS(Counter c) {
+ SymbolNode sn = parseSymbolAndAdvance(c);
+ if (sn != null) {
+ return sn;
+ }
+ return null;
+ }
+
+ public ExpressionNode expectRHS(Counter c) {
+ ExpressionNode en = expectExpression(c);
+ if (en != null) {
+ return en;
+ }
+ return null;
+ }
+
+ private ExpressionNode expectExpression(Counter c) {
+ Counter d = c.clone();
+
+ AdditionNode an = expectAdditionRoutine(d);
+ if (an != null) {
+ c.setValue(d.getValue());
+ return an;
+ }
+ IntegerLiteralNode in = parseIntegerLiteralAndAdvance(d);
+ if (in != null) {
+ c.setValue(d.getValue());
+ return in;
+ }
+ SymbolNode sn = parseSymbolAndAdvance(d);
+ if (sn != null) {
+ c.setValue(d.getValue());
+ return sn;
+ }
+
+ return null;
+ }
+
+ private AdditionNode expectAdditionRoutine(Counter c) {
+ Counter d = c.clone();
+
+ ExpressionNode lhs = expectLHS(d);
+ if (lhs == null) {
+ return null;
+ }
+ boolean isAddition = expectAdditionAndAdvance(d);
+ if (!isAddition) {
+ return null;
+ }
+ ExpressionNode rhs = expectRHS(d);
+ if (rhs == null) {
+ return null;
+ }
+
+ AdditionNode an = new AdditionNode(lhs, rhs);
+ c.setValue(d.getValue());
+ return an;
+ }
+
+ private boolean expectAdditionAndAdvance(Counter c) {
+ if (tokens.get(c.getValue()).is(Token.Type.AdditionToken)) {
+ c.advance();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private IntegerLiteralNode parseIntegerLiteralAndAdvance(Counter c) {
+ if (tokens.get(c.getValue()).is(Token.Type.IntegerLiteralToken)) {
+ IntegerLiteralNode in = new IntegerLiteralNode(tokens.get(c.getValue()));
+ c.advance();
+ return in;
+ } else {
+ return null;
+ }
+ }
+
+ public boolean expectAssignmentAndAdvance(Counter c) {
+ if (tokens.get(c.getValue()).is(Token.Type.AssignmentToken)) {
+ c.advance();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public SymbolNode parseSymbolAndAdvance(Counter c) {
+ if (tokens.get(c.getValue()).is(Token.Type.SymbolToken)) {
+ SymbolNode sn = new SymbolNode(tokens.get(c.getValue()));
+ c.advance();
+ return sn;
+ } else {
+ return null;
+ }
+ }
+
+ public void printTree(ASTNode e) {
+ System.out.println("### Tree begin ###");
+ e.print(0);
+ System.out.println("### Tree end ###");
+ }
+}
diff --git a/main/core/parser/ast/ASTNode.java b/main/core/parser/ast/ASTNode.java
new file mode 100644
index 0000000..106ff75
--- /dev/null
+++ b/main/core/parser/ast/ASTNode.java
@@ -0,0 +1,33 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.List;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+abstract public class ASTNode {
+
+ public abstract DataContainer evaluate();
+
+ protected Token source;
+
+ public ASTNode(Token token) {
+ this.source = token;
+ }
+
+ abstract List<ASTNode> getChildren();
+
+ public void print(int indent) {
+ for (int i = 0; i < indent; i++) {
+ System.out.print("\t");
+ }
+
+ System.out.println(source.toString());
+ for (ASTNode node : getChildren()) {
+ node.print(indent + 1);
+ }
+ }
+}
diff --git a/main/core/parser/ast/AdditionNode.java b/main/core/parser/ast/AdditionNode.java
new file mode 100644
index 0000000..3117e41
--- /dev/null
+++ b/main/core/parser/ast/AdditionNode.java
@@ -0,0 +1,34 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * Created by jan on 13.6.2016.
+ */
+public class AdditionNode extends ExpressionNode {
+
+ private ExpressionNode lhs;
+ private ExpressionNode rhs;
+
+ public AdditionNode(ExpressionNode lhs, ExpressionNode rhs) {
+ super(new Token(Token.Type.AdditionToken));
+
+ this.lhs = lhs;
+ this.rhs = rhs;
+ }
+
+ @Override
+ public List<ASTNode> getChildren() {
+ return Arrays.asList(lhs, rhs);
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ return null;
+ }
+}
diff --git a/main/core/parser/ast/AssignmentNode.java b/main/core/parser/ast/AssignmentNode.java
new file mode 100644
index 0000000..8d8f8bc
--- /dev/null
+++ b/main/core/parser/ast/AssignmentNode.java
@@ -0,0 +1,36 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+import com.jantuomi.interpreter.main.core.runtime.State;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+public class AssignmentNode extends ASTNode {
+
+ private SymbolNode lhs;
+ private ExpressionNode rhs;
+
+ public AssignmentNode(SymbolNode lhs, ExpressionNode rhs) {
+ super(new Token(Token.Type.AssignmentToken));
+
+ this.lhs = lhs;
+ this.rhs = rhs;
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ DataContainer value = rhs.evaluate();
+ State.getInstance().setSymbolValue(lhs.getSymbol(), value);
+ return value;
+ }
+
+ @Override
+ List<ASTNode> getChildren() {
+ return Arrays.asList(lhs, rhs);
+ }
+}
diff --git a/main/core/parser/ast/ExpressionNode.java b/main/core/parser/ast/ExpressionNode.java
new file mode 100644
index 0000000..ac1a190
--- /dev/null
+++ b/main/core/parser/ast/ExpressionNode.java
@@ -0,0 +1,12 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+abstract public class ExpressionNode extends ASTNode {
+ public ExpressionNode(Token token) {
+ super(token);
+ }
+}
diff --git a/main/core/parser/ast/IntegerLiteralNode.java b/main/core/parser/ast/IntegerLiteralNode.java
new file mode 100644
index 0000000..b68adf0
--- /dev/null
+++ b/main/core/parser/ast/IntegerLiteralNode.java
@@ -0,0 +1,30 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 13.6.2016.
+ */
+public class IntegerLiteralNode extends ExpressionNode {
+
+ private int data;
+
+ public IntegerLiteralNode(Token token) {
+ super(token);
+ this.data = Integer.parseInt(token.getText());
+ }
+
+ @Override
+ List<ASTNode> getChildren() {
+ return Arrays.asList();
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ return null;
+ }
+}
diff --git a/main/core/parser/ast/SymbolNode.java b/main/core/parser/ast/SymbolNode.java
new file mode 100644
index 0000000..1457851
--- /dev/null
+++ b/main/core/parser/ast/SymbolNode.java
@@ -0,0 +1,35 @@
+package com.jantuomi.interpreter.main.core.parser.ast;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+import com.jantuomi.interpreter.main.core.runtime.State;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+public class SymbolNode extends ExpressionNode {
+ private String symbol;
+
+ public SymbolNode(Token token) {
+ super(token);
+
+ this.symbol = token.getText();
+ }
+
+ @Override
+ List<ASTNode> getChildren() {
+ return Arrays.asList();
+ }
+
+ public String getSymbol() {
+ return symbol;
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ return State.getInstance().getSymbolValue(symbol);
+ }
+}
diff --git a/main/core/parser/datatype/DataContainer.java b/main/core/parser/datatype/DataContainer.java
new file mode 100644
index 0000000..48e72a3
--- /dev/null
+++ b/main/core/parser/datatype/DataContainer.java
@@ -0,0 +1,17 @@
+package com.jantuomi.interpreter.main.core.parser.datatype;
+
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+abstract public class DataContainer<T> {
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ private T data;
+}
diff --git a/main/core/parser/datatype/IntegerDataContainer.java b/main/core/parser/datatype/IntegerDataContainer.java
new file mode 100644
index 0000000..c5b9fb0
--- /dev/null
+++ b/main/core/parser/datatype/IntegerDataContainer.java
@@ -0,0 +1,10 @@
+package com.jantuomi.interpreter.main.core.parser.datatype;
+
+/**
+ * Created by jan on 11.6.2016.
+ */
+public class IntegerDataContainer extends DataContainer<Integer> {
+ public IntegerDataContainer(Integer data) {
+ this.setData(data);
+ }
+}