// The LISP S-expression Parser. // Implements >> (object *). // // File: parser.cc // Author: {your name} <{your e-mail address}> // Assignment: 7 // The parser is a recursive descent parser implementing // the following grammar. // Grammar: // // sexpr ::= atom | () | ( sexpr rest // // rest ::= ) | . sexpr ) | sexpr rest #include "lisp.h" #include "scanner.h" // Interface with scanner. // Functions local to this file. // static object * read_sexpr (istream& s); static object * read_rest (istream& s); // The main s-expression reader. Returns ob == NULL // if an EOF is detected. // istream& operator >> (istream& s, object * & ob) { ob = read_sexpr (s); return s; } // Read s-expression. // static object * read_sexpr (istream& s) { token tok; object * ob; tok = get_token(s); switch (tok.type) { case LPAREN_TOKEN: tok = get_token(s); if (tok.type == RPAREN_TOKEN) return NIL; else { backup_token (); ob = read_sexpr (s); object* ob2 = read_rest(s); ob = make_cons (ob, ob2); return ob; } case NUMBER_TOKEN: case SYMBOL_TOKEN: return tok.value; case EOF_TOKEN: return NULL; default: error ( "READ: Undecipherable " "s-expression"); } } // read_rest -- the auxiliary s-expression reader, // called to read the rest of an s-expression (i.e., // the part that follows a left paren and an initial // s-expression). // object * read_rest (istream& s) { object * ob; token tok; tok = get_token(s); switch (tok.type) { case RPAREN_TOKEN: return NIL; case DOT_TOKEN: ob = read_sexpr (s); tok = get_token(s); if (tok.type == RPAREN_TOKEN) return ob; else error("READ: Bad dotted-pair " "construction"); default: backup_token(); ob = read_sexpr (s); ob = make_cons (ob, read_rest (s)); return ob; } }