private Expression parse (Expression handle, int state) throws SyntaxError
{
Expression hold = null;
while (charPoint < text.length())
{
if (readType() == type.RPARENTHESIS)
{
if (lastRead == type.LPARENTHESIS || lastRead == type.OPERATOR)
{
// error! empty parenthesis or BOP without second parameter
throw new SyntaxError();
}
else if (state == 4)
{
// finalize handle
handle.setExpr(hold, 2);
}
charPoint++;
parenCounter--;
if (handle.getOper() == null)
{
return handle.getExpr(1);
}
return handle;
}
switch (state)
{
case 1:
// parenthesis handling
if (readType() == type.LPARENTHESIS)
{
lastRead = type.LPARENTHESIS;
charPoint++;
// set the first expression to what ever is inside the parenthesis
parenCounter++;
state = 1;
handle.setExpr(parse(new Expression(), 1), 1);
state = 2;
break;
}
// look for a number
if (readType() != type.NUMBER)
{
// not a number
throw new SyntaxError();
}
// read number in
lastRead = type.NUMBER;
handle.setExpr(new Number(Double.parseDouble(numMatcher.group())), 1);
charPoint = numMatcher.end();
state = 2;
break;
case 2:
// look for a binary operator
if (readType() != type.OPERATOR)
{
throw new SyntaxError();
}
lastRead = type.OPERATOR;
handle.setOper(Operator.createBOP(operMatcher.group()));
charPoint = operMatcher.end();
state = 3;
case 3:
// parenthesis handling
if (readType() == type.LPARENTHESIS)
{
lastRead = type.LPARENTHESIS;
parenCounter++;
charPoint++;
// set the second expression to what ever is inside the parenthesis
handle.setExpr(parse(new Expression(), 1), 2);
Expression temp = new Expression();
temp.setExpr(handle, 1);
handle = temp;
state = 2;
break;
}
// look for a number
if (readType() != type.NUMBER)
{
throw new SyntaxError();
}
lastRead = type.NUMBER;
// hold that number
hold = new Number(Double.parseDouble(numMatcher.group()));
charPoint = numMatcher.end();
state = 4;
// break cause we want close parenthesis parsing
break;
case 4:
// perform one look ahead
if (readType() != type.OPERATOR)
{
// error, didn't find an operator
throw new SyntaxError();
}
lastRead = type.OPERATOR;
Operator look = Operator.createBOP(operMatcher.group());
charPoint = operMatcher.end();
if (handle.getOper().hasHigherPrecedence(look))
{
// previous operator has higher or equal precedence, finalize and move handle
Expression temp = new Expression();
handle.setExpr(hold, 2);
temp.setExpr(handle, 1);
temp.setOper(look);
handle = temp;
break;
}
else
{
// previous operator has lower precedence
Expression temp = new Expression();
temp.setExpr(hold, 1);
temp.setOper(look);
handle.setExpr(parse(temp, 3), 2);
temp = new Expression();
temp.setExpr(handle, 1);
state = 3;
break;
}
}
}
if (state == 4)
{
handle.setExpr(hold, 2);
}
return handle;
}