private static void ConsumeToken(Stack <TOKEN> stack, TOKEN.Ttype ttype, string errmsg) { if (stack.Count == 0 || stack.Peek().ttype != ttype) { throw new ParseException(errmsg); } stack.Pop(); }
private static BigInteger Parse(Stack <TOKEN> stack, Priority priority) { BigInteger v = 0; if (stack.Count == 0) { throw new ParseException("empty stack"); } TOKEN t = stack.Pop(); // Parse prefix operators switch (t.ttype) { case TOKEN.Ttype.MINUS: v = -Parse(stack, Priority.SIGN); break; case TOKEN.Ttype.PLUS: v = Parse(stack, Priority.SIGN); break; case TOKEN.Ttype.INTEGER: v = t.integer; break; case TOKEN.Ttype.BRACKETOPEN: v = Parse(stack, Priority.ALL); ConsumeToken(stack, TOKEN.Ttype.BRACKETCLOSE, "closing bracket expected"); break; case TOKEN.Ttype.FUNCTION: FunctionInfo fi = prefixFunctions[t.function]; v = fi.function(ParseArguments(stack, fi.numargs)); break; default: throw new ParseException("unexpected prefix"); } // Parse infix operators while (stack.Count != 0) { TOKEN.Ttype ttype = stack.Peek().ttype; if (ttype == TOKEN.Ttype.BRACKETCLOSE || ttype == TOKEN.Ttype.COMMA) { break; } OperatorInfo io = infixOperators[ttype]; if ((priority > io.priority) || (priority == io.priority && io.left_associative)) { return(v); } stack.Pop(); BigInteger b = (io.numargs == 2) ? Parse(stack, io.priority) : 0; v = io.function(v, b); } return(v); }