diff options
Diffstat (limited to 'main/core')
| -rw-r--r-- | main/core/parser/ASTGenerator.java | 30 | ||||
| -rw-r--r-- | main/core/parser/Parser.java | 245 | ||||
| -rw-r--r-- | main/core/parser/ast/ASTNode.java | 4 | ||||
| -rw-r--r-- | main/core/parser/ast/AdditionNode.java | 30 | ||||
| -rw-r--r-- | main/core/parser/ast/AssignmentNode.java | 36 | ||||
| -rw-r--r-- | main/core/parser/ast/ExpressionNode.java | 12 | ||||
| -rw-r--r-- | main/core/parser/ast/IntegerLiteralNode.java | 17 | ||||
| -rw-r--r-- | main/core/parser/ast/SymbolNode.java | 35 | ||||
| -rw-r--r-- | main/core/parser/datatype/DataContainer.java | 14 | ||||
| -rw-r--r-- | main/core/parser/datatype/IntegerDataContainer.java | 33 | ||||
| -rw-r--r-- | main/core/tokenizer/Tokenizer.java | 4 | ||||
| -rw-r--r-- | main/core/tokenizer/token/ArgumentInfo.java | 28 | ||||
| -rw-r--r-- | main/core/tokenizer/token/Token.java | 57 | ||||
| -rw-r--r-- | main/core/tokenizer/token/types/AdditionToken.java | 22 | ||||
| -rw-r--r-- | main/core/tokenizer/token/types/BinaryOperatorToken.java | 31 | ||||
| -rw-r--r-- | main/core/tokenizer/token/types/IntegerLiteralToken.java | 32 |
16 files changed, 278 insertions, 352 deletions
diff --git a/main/core/parser/ASTGenerator.java b/main/core/parser/ASTGenerator.java new file mode 100644 index 0000000..e0a3146 --- /dev/null +++ b/main/core/parser/ASTGenerator.java @@ -0,0 +1,30 @@ +package com.jantuomi.interpreter.main.core.parser; + +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.tokenizer.token.Token; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by jan on 16.6.2016. + */ +public class ASTGenerator { + private static final ASTGenerator instance = new ASTGenerator(); + + private ASTGenerator() {} + + public static ASTGenerator getInstance() { + return instance; + } + + public List<ASTNode> generate(List<Token> trees) { + List<ASTNode> list = new ArrayList<>(); + + for (Token root : trees) { + list.add(root.generateNode()); + } + + return list; + } +} diff --git a/main/core/parser/Parser.java b/main/core/parser/Parser.java index 416c3f0..e8b8813 100644 --- a/main/core/parser/Parser.java +++ b/main/core/parser/Parser.java @@ -1,14 +1,13 @@ package com.jantuomi.interpreter.main.core.parser; -import com.jantuomi.interpreter.main.core.parser.ast.*; +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.tokenizer.token.ArgumentInfo; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; -import com.jantuomi.interpreter.main.exception.ExceptionManager; -import com.jantuomi.interpreter.main.exception.InterpreterException; -import com.jantuomi.interpreter.main.utils.Counter; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Stack; /** * Created by jan on 11.6.2016. @@ -27,226 +26,42 @@ public class Parser { } - private Token getTokenAt(Counter c) { - if (c.getValue() >= tokens.size()) { - return new Token(Token.Type.NotAToken); - } - - return tokens.get(c.getValue()); - } - - private boolean isTooDeep(Counter c) { - return c.getRecursionDepth() > tokens.size(); - } + private Stack<Token> stack; - public List<ASTNode> parse(List<Token> tokens) { + public List<Token> parse(List<Token> tokens) { this.tokens = tokens; - this.statementSequence = new ArrayList<>(); + this.stack = new Stack<>(); - 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); + List<Token> args = new ArrayList<>(); + List<Token> output = new ArrayList<>(); + for (Token t : tokens) { + if (t.getTokenType() == Token.Type.NewlineToken) { +// if (stack.size() > 0) { +// output.add(stack.pop()); +// } continue; } - Token failed = tokens.get(c.getValue()); - ExceptionManager.raise(InterpreterException.Exception.SyntaxError, failed.getLine(), - Arrays.asList(failed.toString())); - break; - } - - return statementSequence; - } - - public AssignmentNode expectAssignmentRoutine(Counter c) { - Counter d = c.clone(); - d.deeper(); - - if (isTooDeep(d)) { - return null; - } - - SymbolNode lhs = expectAssignmentLHS(d); - if (lhs == null) { - return null; - } - boolean isAssign = expectAssignmentAndAdvance(d); - if (!isAssign) { - return null; - } - ExpressionNode rhs = expectAssignmentRHS(d); - if (rhs == null) { - return null; - } - - AssignmentNode an = new AssignmentNode(lhs, rhs); - d.shallower(); - c.assign(d); - return an; - } - - private AdditionNode expectAdditionRoutine(Counter c) { - Counter d = c.clone(); - d.deeper(); - - if (isTooDeep(d)) { - return null; - } - - ExpressionNode lhs = expectExpression(d); - if (lhs == null) { - return null; - } - boolean isAddition = expectAdditionAndAdvance(d); - if (!isAddition) { - return null; - } - ExpressionNode rhs = expectExpression(d); - if (rhs == null) { - return null; - } - - AdditionNode an = new AdditionNode(lhs, rhs); - d.shallower(); - c.assign(d); - return an; - } - -// private ExpressionNode expectAdditionLHS(Counter c) { -// Counter d = c.clone(); -// d.deeper(); -// -// if (isTooDeep(d)) { -// return null; -// } -// -// IntegerLiteralNode in = parseIntegerLiteralAndAdvance(d); -// if (in != null) { -// d.shallower(); -// c.assign(d); -// return in; -// } -// SymbolNode sn = parseSymbolAndAdvance(d); -// if (sn != null) { -// d.shallower(); -// c.assign(d); -// return sn; -// } -// -// return null; -// } - - - public SymbolNode expectAssignmentLHS(Counter c) { - Counter d = c.clone(); - d.deeper(); - - if (isTooDeep(d)) { - return null; - } - - SymbolNode sn = parseSymbolAndAdvance(d); - if (sn != null) { - d.shallower(); - c.assign(d); - return sn; - } - return null; - } - - public ExpressionNode expectAssignmentRHS(Counter c) { - Counter d = c.clone(); - d.deeper(); - - if (isTooDeep(d)) { - return null; - } - - ExpressionNode en = expectExpression(c); - if (en != null) { - d.shallower(); - c.assign(d); - return en; - } - return null; - } - - private ExpressionNode expectExpression(Counter c) { - Counter d = c.clone(); - d.deeper(); - - if (isTooDeep(d)) { - return null; - } - - AdditionNode an = expectAdditionRoutine(d); - if (an != null) { - d.shallower(); - c.assign(d); - return an; - } - IntegerLiteralNode in = parseIntegerLiteralAndAdvance(d); - if (in != null) { - d.shallower(); - c.assign(d); - return in; - } - SymbolNode sn = parseSymbolAndAdvance(d); - if (sn != null) { - d.shallower(); - c.assign(d); - return sn; - } - - return null; - } - - private boolean expectAdditionAndAdvance(Counter c) { - if (getTokenAt(c).is(Token.Type.AdditionToken)) { - c.advance(); - return true; - } else { - return false; - } - } - - private IntegerLiteralNode parseIntegerLiteralAndAdvance(Counter c) { - if (getTokenAt(c).is(Token.Type.IntegerLiteralToken)) { - IntegerLiteralNode in = new IntegerLiteralNode(getTokenAt(c)); - c.advance(); - return in; - } else { - return null; - } - } - - public boolean expectAssignmentAndAdvance(Counter c) { - if (getTokenAt(c).is(Token.Type.AssignmentToken)) { - c.advance(); - return true; - } else { - return false; + args.clear(); + ArgumentInfo argumentInfo = t.getArgumentInfo(); + if (!argumentInfo.getVarargs()) { + for (int i = 0; i < argumentInfo.getCount(); i++) { + args.add(stack.pop()); + } + } else { + System.err.println("no vararg support yet"); + } + Collections.reverse(args); + Token result = t.setArguments(args); + stack.push(result); } - } - - public SymbolNode parseSymbolAndAdvance(Counter c) { - if (getTokenAt(c).is(Token.Type.SymbolToken)) { - SymbolNode sn = new SymbolNode(getTokenAt(c)); - c.advance(); - return sn; - } else { - return null; + while (stack.size() > 0) { + output.add(stack.pop()); } + return output; } - public void printTree(ASTNode e) { + public void printTree(Token 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 index 106ff75..4f840e3 100644 --- a/main/core/parser/ast/ASTNode.java +++ b/main/core/parser/ast/ASTNode.java @@ -18,6 +18,10 @@ abstract public class ASTNode { this.source = token; } + public Token.Type tokenType() { + return source.getTokenType(); + } + abstract List<ASTNode> getChildren(); public void print(int indent) { diff --git a/main/core/parser/ast/AdditionNode.java b/main/core/parser/ast/AdditionNode.java index f6ebc84..46f67a4 100644 --- a/main/core/parser/ast/AdditionNode.java +++ b/main/core/parser/ast/AdditionNode.java @@ -6,31 +6,31 @@ import com.jantuomi.interpreter.main.core.tokenizer.token.Token; import java.util.Arrays; import java.util.List; - /** - * Created by jan on 13.6.2016. + * Created by jan on 16.6.2016. */ -public class AdditionNode extends ExpressionNode { - - private ExpressionNode lhs; - private ExpressionNode rhs; +public class AdditionNode extends ASTNode { - public AdditionNode(ExpressionNode lhs, ExpressionNode rhs) { - super(new Token(Token.Type.AdditionToken)); + private ASTNode lhs; + private ASTNode rhs; + public AdditionNode(Token token, ASTNode lhs, ASTNode rhs) { + super(token); this.lhs = lhs; this.rhs = rhs; } @Override - public List<ASTNode> getChildren() { - return Arrays.asList(lhs, rhs); - } + public DataContainer evaluate() { + DataContainer operand1 = lhs.evaluate(); + DataContainer operand2 = rhs.evaluate(); + DataContainer result = operand1.add(operand2); + return result; + + } @Override - public DataContainer evaluate() { - DataContainer lhs = this.lhs.evaluate(); - DataContainer rhs = this.rhs.evaluate(); - return lhs.add(rhs); + List<ASTNode> getChildren() { + return Arrays.asList(lhs, rhs); } } diff --git a/main/core/parser/ast/AssignmentNode.java b/main/core/parser/ast/AssignmentNode.java deleted file mode 100644 index 8d8f8bc..0000000 --- a/main/core/parser/ast/AssignmentNode.java +++ /dev/null @@ -1,36 +0,0 @@ -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 deleted file mode 100644 index ac1a190..0000000 --- a/main/core/parser/ast/ExpressionNode.java +++ /dev/null @@ -1,12 +0,0 @@ -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 index d2fceb1..68b57d7 100644 --- a/main/core/parser/ast/IntegerLiteralNode.java +++ b/main/core/parser/ast/IntegerLiteralNode.java @@ -8,24 +8,23 @@ import java.util.Arrays; import java.util.List; /** - * Created by jan on 13.6.2016. + * Created by jan on 16.6.2016. */ -public class IntegerLiteralNode extends ExpressionNode { - - private int data; +public class IntegerLiteralNode extends ASTNode { + private IntegerDataContainer value; public IntegerLiteralNode(Token token) { super(token); - this.data = Integer.parseInt(token.getText()); + value = new IntegerDataContainer(Integer.parseInt(token.getText())); } @Override - List<ASTNode> getChildren() { - return Arrays.asList(); + public DataContainer evaluate() { + return value; } @Override - public DataContainer evaluate() { - return new IntegerDataContainer(data); + List<ASTNode> getChildren() { + return Arrays.asList(); } } diff --git a/main/core/parser/ast/SymbolNode.java b/main/core/parser/ast/SymbolNode.java deleted file mode 100644 index 1457851..0000000 --- a/main/core/parser/ast/SymbolNode.java +++ /dev/null @@ -1,35 +0,0 @@ -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 index 45199e2..593855b 100644 --- a/main/core/parser/datatype/DataContainer.java +++ b/main/core/parser/datatype/DataContainer.java @@ -1,10 +1,18 @@ package com.jantuomi.interpreter.main.core.parser.datatype; - /** * Created by jan on 11.6.2016. */ abstract public class DataContainer<T> { + + public enum Type { + Integer + } + + private Type type; + + private T data; + public T getData() { return data; } @@ -13,10 +21,8 @@ abstract public class DataContainer<T> { this.data = data; } - private T data; - @Override abstract public String toString(); - public abstract DataContainer add(DataContainer rhs); + abstract public DataContainer<T> add(DataContainer<T> other); } diff --git a/main/core/parser/datatype/IntegerDataContainer.java b/main/core/parser/datatype/IntegerDataContainer.java index 8566a1c..b5fdac3 100644 --- a/main/core/parser/datatype/IntegerDataContainer.java +++ b/main/core/parser/datatype/IntegerDataContainer.java @@ -1,36 +1,25 @@ package com.jantuomi.interpreter.main.core.parser.datatype; - -import com.jantuomi.interpreter.main.exception.ExceptionManager; -import com.jantuomi.interpreter.main.exception.InterpreterException; - -import java.util.Arrays; - /** - * Created by jan on 11.6.2016. + * Created by jan on 16.6.2016. */ public class IntegerDataContainer extends DataContainer<Integer> { - public IntegerDataContainer(Integer data) { - this.setData(data); + + private int value; + + public IntegerDataContainer(int value) { + this.value = value; } @Override public String toString() { - return getData().toString(); + return Integer.toString(value); } @Override - public DataContainer add(DataContainer rhs) { - if (rhs instanceof IntegerDataContainer) { - return new IntegerDataContainer( - getData() + ((IntegerDataContainer) rhs).getData() - ); - } - else { - ExceptionManager.raise(InterpreterException.Exception.TypeError, -1, - Arrays.asList(this.getClass().toString(), rhs.getClass().toString())); - - return null; - } + public DataContainer<Integer> add(DataContainer<Integer> other) { + return new IntegerDataContainer( + this.value + ((IntegerDataContainer) other).value + ); } } diff --git a/main/core/tokenizer/Tokenizer.java b/main/core/tokenizer/Tokenizer.java index c04db22..7e88a43 100644 --- a/main/core/tokenizer/Tokenizer.java +++ b/main/core/tokenizer/Tokenizer.java @@ -57,7 +57,7 @@ public class Tokenizer { erroneousTokenTypes.add(Token.Type.NotAToken); } - public List<Token> tokenize(String string) { + public List<Token> tokenize(String string) throws InterpreterException { sourceString = string; tokens.clear(); int line = 1; @@ -79,7 +79,7 @@ public class Tokenizer { } if (erroneousTokenTypes.contains(token.getTokenType())) { - ExceptionManager.raise(InterpreterException.Exception.IllegalTokenError, line, Arrays.asList(token.getText())); + ExceptionManager.raise(InterpreterException.ExceptionType.IllegalTokenError, line, Arrays.asList(token.getText())); } String tokenRawText = token.getRawText(); diff --git a/main/core/tokenizer/token/ArgumentInfo.java b/main/core/tokenizer/token/ArgumentInfo.java new file mode 100644 index 0000000..a9c3d90 --- /dev/null +++ b/main/core/tokenizer/token/ArgumentInfo.java @@ -0,0 +1,28 @@ +package com.jantuomi.interpreter.main.core.tokenizer.token; + +/** + * Created by jan on 15.6.2016. + */ +public class ArgumentInfo { + private int count = 0; + private boolean isVarargs = false; + public ArgumentInfo(int count) { + this.count = count; + } + + public ArgumentInfo() { + + } + + public void setVariable(boolean value) { + this.isVarargs = value; + } + + public boolean getVarargs() { + return isVarargs; + } + + public int getCount() { + return count; + } +} diff --git a/main/core/tokenizer/token/Token.java b/main/core/tokenizer/token/Token.java index 99ae913..0d4395e 100644 --- a/main/core/tokenizer/token/Token.java +++ b/main/core/tokenizer/token/Token.java @@ -1,8 +1,12 @@ package com.jantuomi.interpreter.main.core.tokenizer.token; +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.tokenizer.token.types.AdditionToken; +import com.jantuomi.interpreter.main.core.tokenizer.token.types.IntegerLiteralToken; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -10,7 +14,19 @@ import java.util.regex.Pattern; /** * Created by jan on 10.6.2016. */ -public class Token { +abstract public class Token { + + public void print(int indent) { + for (int i = 0; i < indent; i++) { + System.out.print("\t"); + } + System.out.println(toString()); + for (Token child : getChildren()) { + child.print(indent + 1); + } + } + + abstract public ASTNode generateNode(); /* Token types, ordered by precedence */ public enum Type { @@ -40,6 +56,10 @@ public class Token { NotAToken } + abstract public Token setArguments(List<Token> args); + + abstract public List<Token> getChildren(); + public boolean is(Type type) { return getTokenType() == type; } @@ -120,12 +140,45 @@ public class Token { String text = matcher.group(1); String rawText = matcher.group(0); - return new Token(type, text, rawText); + switch (type) { + case IntegerLiteralToken: + return new IntegerLiteralToken(text); + case AdditionToken: + return new AdditionToken(); + default: + return null; + } } return null; } + public ArgumentInfo getArgumentInfo() { + switch (getTokenType()) { + + case FunctionDefineToken: + ArgumentInfo ai = new ArgumentInfo(); + ai.setVariable(true); + return ai; + case AdditionToken: + case SubtractionToken: + case DivisionToken: + case MultiplicationToken: + case AssignmentToken: + case LessThanToken: + case GreaterThanToken: + case LessOrEqualThanToken: + case GreaterOrEqualThanToken: + case EqualsToken: + case NotEqualsToken: + return new ArgumentInfo(2); + case DeclarationToken: + return new ArgumentInfo(1); + default: + return new ArgumentInfo(0); + } + } + @Override public int hashCode() { return new HashCodeBuilder(17, 37) diff --git a/main/core/tokenizer/token/types/AdditionToken.java b/main/core/tokenizer/token/types/AdditionToken.java new file mode 100644 index 0000000..2d77b46 --- /dev/null +++ b/main/core/tokenizer/token/types/AdditionToken.java @@ -0,0 +1,22 @@ +package com.jantuomi.interpreter.main.core.tokenizer.token.types; + +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.parser.ast.AdditionNode; + +/** + * Created by jan on 15.6.2016. + */ +public class AdditionToken extends BinaryOperatorToken { + public AdditionToken() { + super(Type.AdditionToken); + } + + @Override + public ASTNode generateNode() { + return new AdditionNode(this, + lhs.generateNode(), + rhs.generateNode() + ); + + } +} diff --git a/main/core/tokenizer/token/types/BinaryOperatorToken.java b/main/core/tokenizer/token/types/BinaryOperatorToken.java new file mode 100644 index 0000000..3998bb9 --- /dev/null +++ b/main/core/tokenizer/token/types/BinaryOperatorToken.java @@ -0,0 +1,31 @@ +package com.jantuomi.interpreter.main.core.tokenizer.token.types; + +import com.jantuomi.interpreter.main.core.tokenizer.token.Token; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jan on 15.6.2016. + */ +abstract public class BinaryOperatorToken extends Token { + protected Token lhs; + protected Token rhs; + + public BinaryOperatorToken(Type type) { + super(type); + } + + @Override + public Token setArguments(List<Token> args) { + lhs = args.get(0); + rhs = args.get(1); + return this; + } + + @Override + public List<Token> getChildren() { + return Arrays.asList(lhs, rhs); + + } +} diff --git a/main/core/tokenizer/token/types/IntegerLiteralToken.java b/main/core/tokenizer/token/types/IntegerLiteralToken.java new file mode 100644 index 0000000..cdb4fde --- /dev/null +++ b/main/core/tokenizer/token/types/IntegerLiteralToken.java @@ -0,0 +1,32 @@ +package com.jantuomi.interpreter.main.core.tokenizer.token.types; + +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.parser.ast.IntegerLiteralNode; +import com.jantuomi.interpreter.main.core.tokenizer.token.Token; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jan on 15.6.2016. + */ +public class IntegerLiteralToken extends Token{ + public IntegerLiteralToken(String text) { + super(Type.IntegerLiteralToken, text); + } + + @Override + public ASTNode generateNode() { + return new IntegerLiteralNode(this); + } + + @Override + public Token setArguments(List<Token> args) { + return this; + } + + @Override + public List<Token> getChildren() { + return Arrays.asList(); + } +} |
