private static Expression ParseTerm(TokenStream tokenStream, SymbolTable symbols) { if (tokenStream.Peek() == '(') { tokenStream.Consume('('); var inner = ParseExp(tokenStream, symbols); tokenStream.Consume(')'); return inner; } if (tokenStream.Peek() == 'λ') { tokenStream.Consume('λ'); char id = tokenStream.Peek(); if (!Char.IsLetter(id)) throw new ParserException(String.Format("Expected identifier at position {0}", tokenStream.Position)); tokenStream.Consume(id); tokenStream.Consume('.'); var variable = new Symbol(id); var body = ParseExp(tokenStream, symbols.Plus(id, variable)); return new Lambda(variable, body); } if (Char.IsLetter(tokenStream.Peek())) { char id = tokenStream.Peek(); tokenStream.Consume(id); var variable = symbols.Lookup(id); if (variable != null) return new BoundVariable(variable); else return new FreeVariable(id); } throw new ParserException(String.Format("Unexpected character \"{0}\" at position {1}", tokenStream.Peek(), tokenStream.Position)); }
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); } }