package ch.bfh.parser; import ch.bfh.lexer.CalculatorLexer; import ch.bfh.lexer.Token; class FactorParser extends Parser { ExpressionParser expression; // only used when parenthesis are found boolean isNegative = false; boolean somethingWasParsed = false; public FactorParser(CalculatorLexer cl, Token lastToken) { this.cl = cl; this.lastToken = lastToken; parse(); } @Override protected void parse() { Token token = lastToken; lastToken = null; loop: while (token != null && token.type != Token.EOL) { switch (token.type) { case Token.MUL: case Token.DIV: case Token.ADD: if (somethingWasParsed) { // finished parsing the Factor lastToken = token; // sending the token to the parent break loop; } else throw new ParserException("Empty expression before '" + token.str + "'."); case Token.SUB: if (!somethingWasParsed) if (!isNegative) isNegative = true; else throw new ParserException("A factor cannot contain two '-'."); else { // Meaning we could have parsed '-4' or '4' and '-' is the next digit which is op for the overall expression lastToken = token; break loop; } break; case Token.NUM: if (!somethingWasParsed) { value = token.value; somethingWasParsed = true; } else throw new ParserException("Missing operator between the two Factors."); break; case Token.ID: if (!somethingWasParsed) { expression = variables.get(token.str); if (expression == null) throw new ParserException("'"+token.str+"' is not yet defined."); somethingWasParsed = true; } else throw new ParserException("Missing operator between the two Factors."); break; case Token.PAL: if (!somethingWasParsed) { expression = new ExpressionParser(cl, token, true); if (expression.lastToken.type != Token.PAR) throw new ParserException("No matching closing parenthesis were found."); somethingWasParsed = true; } else throw new ParserException("Missing operator between the two Factors."); break; case Token.PAR: // Going as high as possible --> possibly the end of an expression created by a Factor :) if (somethingWasParsed) lastToken = token; else throw new ParserException("Missing expression before closing the parenthesis."); break loop; 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(); } } @Override public double getValue() { if (expression != null) if (isNegative) return expression.getValue() * (-1); else return expression.getValue(); if (isNegative) return value * (-1); return value; } }