private static Expression ParseExp(TokenStream tokenStream, SymbolTable symbols)
 {
     var head = ParseTerm(tokenStream, symbols);
     while (true)
     {
         if (tokenStream.Done() || tokenStream.Peek() == ')')
             return head;
         var next = ParseTerm(tokenStream, symbols);
         head = new Apply(head, next);
     }
 }
 public static string Evaluate(string text)
 {
     var tokenStream = new TokenStream(text);
     Expression exp = ParseExp(tokenStream, new SymbolTable());
     if (!tokenStream.Done())
         throw new ParserException(String.Format("Extra characters after position {0}", tokenStream.Position));
     var resolved = exp.Reduce();
     if (resolved == null)
         return "";
     return resolved.ToString();
 }