CS321 Prog Lang & Compilers                       Assignment #9
Assigned: Feb. 19, 2006            Due: Wednesday. Feb 21, 2006


In the grammars below, all symbols that start with am
upper case letter are Non-terminals, and all other
symbols are terminals. The symbol [empty] represents
the empty string.


1) Using the techniques discussed in class, write a recursive
descent parser for the following grammar. Be sure to thoroughly
test your program in what you hand in.

List  ::= [ Items ]
Items ::= id More
        | [empty]
More  ::= , id More
More  ::= [empty]


Your function should work as follows:
parse "[]"      ---->  []
parse "[a,b,c]" ---->  ["a","b","c"]


You need to write 3 functions with the following types

List:: unit -> string list
Items:: unit -> (string list) option
More:: unit -> (string list) option

The last two return a (string list) option, because both the
non-terminals More and Items can derive the empty string


You may use the following simple lexical analyser and match function.

(* ************************************************** *)
exception Error of string;

fun error s = (print s; raise (Error s));


datatype token =
  EOF
| Comma
| LeftBr
| RightBr
| Id of string;

fun lexan s =
let fun help [] = []
      | help (#"," :: xs) = Comma :: help xs
      | help (#"[" :: xs) = LeftBr :: help xs
      | help (#"]" :: xs) = RightBr :: help xs
      | help (x :: xs) =
         if Char.isAlpha x
            then Id(String.implode [x]) :: help xs
            else error ("Unexpected Token: "^(String.implode (x::xs)))
in help (String.explode s) end;

val lookahead = ref EOF;
val input = ref [EOF];
val location = ref 0;

fun init s = (location := 0;
              input := lexan s;
              lookahead := hd(!input);
              input := tl(!input));

fun tok2str EOF = "EOF"
  | tok2str Comma = ","
  | tok2str LeftBr = "["
  | tok2str RightBr = "]"
  | tok2str (Id c) = c;

fun match t =
if (!lookahead) = t
   then (if null(!input)
            then lookahead := EOF
            else (lookahead := hd(!input)
                 ; input := tl(!input)))
   else error ("looking for: "^(tok2str t)^
               " found: "^(tok2str (!lookahead)));


(* ************************************************** *)