123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- // $Id$
- using System;
- using System.Globalization;
- using System.IO;
- using System.Collections;
- namespace Lisp
- {
- /// <summary>
- /// Lisp parser
- /// </summary>
- /// <seealso cref="Lexer"/>
- public sealed class Parser {
- private Lexer Lexer;
- private Lexer.Token Token;
- public Parser(Lexer Lexer) {
- this.Lexer = Lexer;
- }
- public List Parse() {
- Token = Lexer.GetNextToken();
- if(Token != Lexer.Token.OPEN_PAREN)
- ParseError("file does not start with '('");
- List Result = InternParse();
- if(Token != Lexer.Token.EOF) {
- if(Token == Lexer.Token.CLOSE_PAREN)
- ParseError("too many ')'");
- else
- ParseError("extra tokens at end of file");
- }
- return Result;
- }
- private List InternParse() {
- ArrayList Entries = new ArrayList();
- while(Token != Lexer.Token.CLOSE_PAREN && Token != Lexer.Token.EOF) {
- switch(Token) {
- case Lexer.Token.OPEN_PAREN:
- Token = Lexer.GetNextToken();
- if(Token == Lexer.Token.SYMBOL
- && Lexer.TokenString == "_") {
- Token = Lexer.GetNextToken();
- if(Token != Lexer.Token.STRING)
- ParseError("Expected string after '(_ ' sequence");
- // TODO translate
- Entries.Add(Lexer.TokenString);
- Token = Lexer.GetNextToken();
- if(Token != Lexer.Token.CLOSE_PAREN)
- ParseError("Expected ')' after '(_ \"\"' sequence");
- break;
- }
- Entries.Add(InternParse());
- if(Token != Lexer.Token.CLOSE_PAREN)
- ParseError("Expected ')' token, got " + Token);
- break;
- case Lexer.Token.SYMBOL:
- Entries.Add(new Symbol(Lexer.TokenString));
- break;
- case Lexer.Token.STRING:
- Entries.Add(Lexer.TokenString);
- break;
- case Lexer.Token.INTEGER:
- int ival = Int32.Parse(Lexer.TokenString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
- Entries.Add(ival);
- break;
- case Lexer.Token.REAL:
- float fval = Single.Parse(Lexer.TokenString, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
- Entries.Add(fval);
- break;
- case Lexer.Token.TRUE:
- Entries.Add(true);
- break;
- case Lexer.Token.FALSE:
- Entries.Add(false);
- break;
- default:
- ParseError("Unexpected Token " + Token);
- break;
- }
- Token = Lexer.GetNextToken();
- }
- return new List(Entries.ToArray());
- }
- private void ParseError(string Message) {
- throw new LispException("Parse error in line "
- + Lexer.LineNumber + ": " + Message);
- }
- }
- }
|