diff options
author | Maël Gassmann <mael.gassmann@students.bfh.ch> | 2021-06-11 20:55:12 +0200 |
---|---|---|
committer | Maël Gassmann <mael.gassmann@students.bfh.ch> | 2021-06-11 20:55:12 +0200 |
commit | fed70f3ac817ed4943a230cb901fcd65dc6fdd0c (patch) | |
tree | aea4de81656c677d33e4af6eb11375303d1dfdda | |
parent | 3baa44f1c8459713a96f4db994ee9905cc4e8df1 (diff) |
[~] First totaly functional Calculator, reorganised the files, verified and added error messages
12 files changed, 67 insertions, 63 deletions
diff --git a/calculator-java/src/main/java/ch/bfh/Main.java b/calculator-java/src/main/java/ch/bfh/Main.java index 5dc8a91..ea01185 100644 --- a/calculator-java/src/main/java/ch/bfh/Main.java +++ b/calculator-java/src/main/java/ch/bfh/Main.java @@ -1,7 +1,8 @@ package ch.bfh; +import ch.bfh.lexer.LexerException; +import ch.bfh.parser.ParserException; import ch.bfh.parser.StatementParser; - import java.util.Scanner; public class Main { @@ -16,8 +17,8 @@ public class Main { try { sp.parseStatement(expression); - System.out.println(sp.getValue()); - } catch (Exception e) { + System.out.println("Result: " + sp.getValue()); + } catch (LexerException | ParserException e) { System.out.println(e.getMessage()); } } diff --git a/calculator-java/src/main/java/ch/bfh/exceptions/ParserException.java b/calculator-java/src/main/java/ch/bfh/exceptions/ParserException.java deleted file mode 100644 index ca6d037..0000000 --- a/calculator-java/src/main/java/ch/bfh/exceptions/ParserException.java +++ /dev/null @@ -1,5 +0,0 @@ -package ch.bfh.exceptions; - -public class ParserException extends RuntimeException { - public ParserException(String s) { super(s); } -}
\ No newline at end of file diff --git a/calculator-java/src/main/java/ch/bfh/CalculatorLexer.java b/calculator-java/src/main/java/ch/bfh/lexer/CalculatorLexer.java index 48d009e..0ba9535 100644 --- a/calculator-java/src/main/java/ch/bfh/CalculatorLexer.java +++ b/calculator-java/src/main/java/ch/bfh/lexer/CalculatorLexer.java @@ -1,5 +1,4 @@ -package ch.bfh; -import ch.bfh.exceptions.LexerException; +package ch.bfh.lexer; // Lexer for classical arithmetic expressions with identifiers and assignments. // Scans a source string char by char. diff --git a/calculator-java/src/main/java/ch/bfh/exceptions/LexerException.java b/calculator-java/src/main/java/ch/bfh/lexer/LexerException.java index 082beee..c5f8671 100644 --- a/calculator-java/src/main/java/ch/bfh/exceptions/LexerException.java +++ b/calculator-java/src/main/java/ch/bfh/lexer/LexerException.java @@ -1,4 +1,4 @@ -package ch.bfh.exceptions; +package ch.bfh.lexer; public class LexerException extends RuntimeException { public LexerException(String s) { super(s); } diff --git a/calculator-java/src/main/java/ch/bfh/Token.java b/calculator-java/src/main/java/ch/bfh/lexer/Token.java index 93d4d02..b021075 100644 --- a/calculator-java/src/main/java/ch/bfh/Token.java +++ b/calculator-java/src/main/java/ch/bfh/lexer/Token.java @@ -1,4 +1,4 @@ -package ch.bfh; +package ch.bfh.lexer; // Various Tokens for arithmetic expressions based on integers // with identifiers and assignments @@ -8,16 +8,16 @@ public class Token { public double value; // numerical value for NUM public String str; // token string - public static final int EOL=0; // End Of Line - public static final int PAL=1; // Left Parenthesis - public static final int PAR=2; // Right Parenthesis - public static final int ADD=3; // operators - public static final int SUB=4; + public static final int EOL=0;// // End Of Line + public static final int PAL=1;// // Left Parenthesis + public static final int PAR=2;// // Right Parenthesis + public static final int ADD=3;// // operators + public static final int SUB=4;// public static final int MUL=5; public static final int DIV=6; - public static final int NUM=7; // number + public static final int NUM=7;// // number public static final int EQU=8; // equal public static final int LET=9; // let - public static final int ID=10; // identifier + public static final int ID=10;// // identifier public static final int END=11; // exit -} +}
\ No newline at end of file diff --git a/calculator-java/src/main/java/ch/bfh/parser/ExpressionParser.java b/calculator-java/src/main/java/ch/bfh/parser/ExpressionParser.java index 3ec0194..e68983b 100644 --- a/calculator-java/src/main/java/ch/bfh/parser/ExpressionParser.java +++ b/calculator-java/src/main/java/ch/bfh/parser/ExpressionParser.java @@ -1,22 +1,15 @@ package ch.bfh.parser; -import ch.bfh.CalculatorLexer; -import ch.bfh.Token; -import ch.bfh.exceptions.ParserException; - +import ch.bfh.lexer.CalculatorLexer; +import ch.bfh.lexer.Token; import java.util.ArrayList; -public class ExpressionParser extends Parser { +class ExpressionParser extends Parser { protected ArrayList<Parser> parsers = new ArrayList<>(); protected ArrayList<Token> ops = new ArrayList<>(); private boolean isParenthesised = false; - public ExpressionParser(CalculatorLexer cl) { - this.cl = cl; - parse(); - } - protected ExpressionParser(CalculatorLexer cl, Token lastToken, boolean isParenthesised) { this.cl = cl; this.lastToken = lastToken; @@ -31,8 +24,8 @@ public class ExpressionParser extends Parser { token = lastToken; else token = cl.nextToken(); - Parser l = null; - Parser r = null; // left and right expressions + TermParser l = null; + TermParser r = null; // left and right Terms Token op = null; // operation of the current l and right expressions loop: @@ -48,9 +41,9 @@ public class ExpressionParser extends Parser { op = token; this.ops.add(op); }else if (l == null) - throw new ParserException("Factor cannot start with '+'."); + throw new ParserException("Redundant use of '+' is forbidden."); else - throw new ParserException("Invalid use of '+' was found in the Expression."); + throw new ParserException(token, "repetition of operator -> a term was expected."); break; case Token.SUB: if (l != null && op == null) { // if the '-' sign is between two term (op) @@ -82,14 +75,19 @@ public class ExpressionParser extends Parser { break loop; } else throw new ParserException("No matching opening parenthesis were found."); - default: - //TODO - Replace default by each individual case - throw new ParserException("Malformed Expression."); + case Token.MUL: + case Token.DIV: + throw new ParserException(token,"a term was expected."); + case Token.EQU: + case Token.LET: + throw new ParserException("The inputted token '"+token.str+"' can only be placed in a variable declaration context (let var = Expression)."); + case Token.END: + throw new ParserException("The keyword 'exit' can only be placed at the beginning of an expression."); } token = cl.nextToken(); } if (op != null && r == null) - throw new ParserException("Missing expression after last operation '"+op.str+"'"); + throw new ParserException("Missing term after the last operator '"+op.str+"'."); } @Override @@ -111,4 +109,4 @@ public class ExpressionParser extends Parser { } return result; } -} +}
\ No newline at end of file diff --git a/calculator-java/src/main/java/ch/bfh/parser/FactorParser.java b/calculator-java/src/main/java/ch/bfh/parser/FactorParser.java index 8bb5ef7..fd54cf4 100644 --- a/calculator-java/src/main/java/ch/bfh/parser/FactorParser.java +++ b/calculator-java/src/main/java/ch/bfh/parser/FactorParser.java @@ -1,8 +1,7 @@ package ch.bfh.parser; -import ch.bfh.CalculatorLexer; -import ch.bfh.Token; -import ch.bfh.exceptions.ParserException; +import ch.bfh.lexer.CalculatorLexer; +import ch.bfh.lexer.Token; class FactorParser extends Parser { @@ -72,9 +71,11 @@ class FactorParser extends Parser { lastToken = token; else throw new ParserException("Missing expression before closing the parenthesis."); break loop; - default: - //TODO - Replace default by each individual case - throw new ParserException("Malformed Expression."); + case Token.EQU: + case Token.LET: + throw new ParserException("The inputted token '"+token.str+"' can only be placed in a variable declaration context (let var = Expression)."); + case Token.END: + throw new ParserException("The keyword 'exit' can only be placed at the beginning of an expression."); } token = cl.nextToken(); } @@ -91,4 +92,4 @@ class FactorParser extends Parser { return value * (-1); return value; } -} +}
\ No newline at end of file diff --git a/calculator-java/src/main/java/ch/bfh/parser/Parser.java b/calculator-java/src/main/java/ch/bfh/parser/Parser.java index 333b942..6a03fe1 100644 --- a/calculator-java/src/main/java/ch/bfh/parser/Parser.java +++ b/calculator-java/src/main/java/ch/bfh/parser/Parser.java @@ -1,14 +1,13 @@ package ch.bfh.parser; -import ch.bfh.CalculatorLexer; -import ch.bfh.Token; - +import ch.bfh.lexer.CalculatorLexer; +import ch.bfh.lexer.Token; import java.util.HashMap; import java.util.Map; abstract class Parser{ - protected static Map<String, ExpressionParser> variables = new HashMap<>(); //'Persisted' Expressions when 'let' token was specified + protected static Map<String, ExpressionParser> variables = new HashMap<>(); //Persisted Expressions aka variables protected CalculatorLexer cl; protected Token lastToken; diff --git a/calculator-java/src/main/java/ch/bfh/parser/ParserException.java b/calculator-java/src/main/java/ch/bfh/parser/ParserException.java new file mode 100644 index 0000000..a85e3b2 --- /dev/null +++ b/calculator-java/src/main/java/ch/bfh/parser/ParserException.java @@ -0,0 +1,8 @@ +package ch.bfh.parser; + +import ch.bfh.lexer.Token; + +public class ParserException extends RuntimeException { + public ParserException(String s) { super(s); } + public ParserException(Token token, String s) { super("Last read token: '"+token.str+"', "+s); } +}
\ No newline at end of file diff --git a/calculator-java/src/main/java/ch/bfh/parser/StatementParser.java b/calculator-java/src/main/java/ch/bfh/parser/StatementParser.java index c85398b..482ef34 100644 --- a/calculator-java/src/main/java/ch/bfh/parser/StatementParser.java +++ b/calculator-java/src/main/java/ch/bfh/parser/StatementParser.java @@ -1,8 +1,7 @@ package ch.bfh.parser; -import ch.bfh.CalculatorLexer; -import ch.bfh.Token; -import ch.bfh.exceptions.ParserException; +import ch.bfh.lexer.CalculatorLexer; +import ch.bfh.lexer.Token; public class StatementParser extends Parser{ @@ -27,15 +26,15 @@ public class StatementParser extends Parser{ switch (token.type) { case Token.LET: if (lastToken != null) - throw new ParserException("The keyword 'let' cannot be placed anywhere else than at the beginning of an expression."); + throw new ParserException("The keyword 'let' can only be placed at the beginning of an expression."); break; case Token.EQU: if (lastToken == null || lastToken.type != Token.LET || variableName == null) - throw new ParserException("The inputted token '=' can only be placed in a variable declaration context (let variable = Expression)."); + throw new ParserException("The token '=' can only be placed in a variable declaration context (let var = Expression)."); break; case Token.END: if (lastToken != null) - throw new ParserException("The keyword 'exit' cannot be placed anywhere else than at the beginning of an expression."); + throw new ParserException("The keyword 'exit' can only be placed at the beginning of an expression."); else System.exit(0); case Token.ID: @@ -58,7 +57,7 @@ public class StatementParser extends Parser{ if (lastToken == null) return; if (lastToken.type == Token.LET || lastToken.type == Token.EQU) - throw new ParserException("Incomplete variable declaration"); + throw new ParserException("Incomplete variable declaration. Expected: let var = Expression."); } @Override diff --git a/calculator-java/src/main/java/ch/bfh/parser/TermParser.java b/calculator-java/src/main/java/ch/bfh/parser/TermParser.java index 9a97659..9e49fa8 100644 --- a/calculator-java/src/main/java/ch/bfh/parser/TermParser.java +++ b/calculator-java/src/main/java/ch/bfh/parser/TermParser.java @@ -1,8 +1,7 @@ package ch.bfh.parser; -import ch.bfh.CalculatorLexer; -import ch.bfh.Token; -import ch.bfh.exceptions.ParserException; +import ch.bfh.lexer.CalculatorLexer; +import ch.bfh.lexer.Token; class TermParser extends ExpressionParser { @@ -61,9 +60,11 @@ class TermParser extends ExpressionParser { case Token.PAR: // Going as high as possible --> possibly the end of an expression created by a Factor :) lastToken = token; break loop; - default: - //TODO - Replace default by each individual case - throw new ParserException("Malformed Expression."); + case Token.EQU: + case Token.LET: + throw new ParserException("The inputted token '"+token.str+"' can only be placed in a variable declaration context (let var = Expression)."); + case Token.END: + throw new ParserException("The keyword 'exit' can only be placed at the beginning of an expression."); } token = cl.nextToken(); } diff --git a/calculator-java/src/test/java/StatementParserTest.java b/calculator-java/src/test/java/StatementParserTest.java index 8c2db59..ee4ab6b 100644 --- a/calculator-java/src/test/java/StatementParserTest.java +++ b/calculator-java/src/test/java/StatementParserTest.java @@ -111,6 +111,9 @@ public class StatementParserTest { sp.parseStatement("b/a"); assertEquals(50.0, sp.getValue(), 0.0); + sp.parseStatement("b--a"); + assertEquals(255.0, sp.getValue(), 0.0); + sp.parseStatement("b+a/2"); assertEquals(252.5, sp.getValue(), 0.0); |