package ch.bfh.parser; import ch.bfh.CalculatorLexer; import ch.bfh.Token; import ch.bfh.exceptions.ParserException; class TermParser extends ExpressionParser { public TermParser(CalculatorLexer cl, Token lastToken) { super(cl, lastToken, false); } @Override protected void parse() { Token token = lastToken; lastToken = null; Parser l = null; Parser r = null; // left and right expressions Token op = null; // operation of the current l and right expressions loop: while (token != null && token.type != Token.EOL) { switch (token.type) { case Token.ADD: if (op != null) { lastToken = token; break loop; // going here on case 'n/+...' or 'n*+...' since '+' would be invalid } case Token.SUB: case Token.NUM: case Token.ID: case Token.PAL: if (l == null) { l = new FactorParser(cl, token); this.parsers.add(l); token = l.lastToken; continue loop; } else if (op != null) { r = new FactorParser(cl, token); this.parsers.add(r); token = r.lastToken; lastToken = token; // in case we finished continue loop; } else { lastToken = token; break loop; // going here on case 'n+...' or 'n-...' since '+' and '-' are part of the parent expression } case Token.MUL: case Token.DIV: if (l != null && op == null) { // if the '*' or '/' signs are between two Factors (op) op = token; this.ops.add(op); } else if (l != null && r != null) { // if we already found a 'l op r' we roll l = r; r = null; op = token; this.ops.add(op); } else throw new ParserException("Two '" + token.str + "' in a row were found."); break; 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."); } token = cl.nextToken(); } if (op != null && r == null) throw new ParserException("Missing expression after last operation '" + op.str + "'"); } @Override public double getValue() { double result = 0.0; if (!this.parsers.isEmpty()) { result = this.parsers.get(0).getValue(); for (int i = 1; i < this.parsers.size(); i++) { switch (this.ops.get(i - 1).type) { case Token.MUL: result *= this.parsers.get(i).getValue(); break; case Token.DIV: result /= this.parsers.get(i).getValue(); break; } } } return result; } }