In the Notes on Programming Language Syntax page, an example parser for a simple language is given, using C syntax. Write the parser using F#, but you may only use functional programming and immutable date. Create the list of tokens as a discriminated union, which (in the simplest case) looks like an enumeration. type TERMINAL = IF|THEN|ELSE|BEGIN|END|PRINT|SEMICOLON|ID|EOF With this type declared, you can use the terminals like you would use enumerated values in Java. Use immutable data. The C-code example uses mutable data. Pass the program into the start symbol function. Pass the input yet to be processed to each non-terminal function. The main function might look like this: let test_program program = let result = program |> S match result with | [] -> failwith "Early termination or missing EOF" | x::xs -> if x = EOF then accept() else error() You do not have to parse input strings. Assume that the parsing has been done. Pass a list of tokens that represent a program into the start symbol. Try these program examples: [IF;ID;THEN;BEGIN;PRINT;ID;SEMICOLON;PRINT;ID;END;ELSE;PRINT;ID;EOF] [IF;ID;THEN;IF;ID;THEN;PRINT;ID;ELSE;PRINT;ID;ELSE;BEGIN;PRINT;ID;END;EOF] Causes error: [IF;ID;THEN;BEGIN;PRINT;ID;SEMICOLON;PRINT;ID;SEMICOLON;END;ELSE;PRINT;ID;EOF] Print an accept message when the input is valid and completely consumed. Generate appropriate error messages for incorrect symbols, not enough input, and too much input. Once you have the parser recognizing input, generate a parse tree using a discriminated type. Implement a parser using functional programming and immutable data for the unambiguous grammar for arithmetic expressions, from the Notes on Programming Language Syntax. E -> E + T | E - T | T T -> T * F | T / F | F F -> i | (E) Use the suggestion in the notes to get around the fact that this grammar appears to need more than one lookahead token. Once you have the parser recognizing input, generate a parse tree using a discriminated type. Recall that an F# function that takes two arguments can be coded in either uncurried form (in which case it takes a pair as its input) or curried form (in which case it takes the first argument and returns a function that takes the second argument). In fact it is easy to convert from one form to the other in F#. To this end, define an F# function curry f that converts an uncurried function to a curried function, and an F# function uncurry f that does the opposite conversion. For example, > (+);; val it : (int -> int -> int) = [email protected] > > let plus = uncurry (+);; val plus : (int * int -> int) > plus (2,3);; val it : int = 5 > let cplus = curry plus;; val cplus : (int -> int -> int) > let plus3 = cplus 3;; val plus3 : (int -> int) > plus3 10;; val it : int = 13 What are the types of curry and uncurry ? Given vectors u = (u 1 , u 2 ,..., u n ) and .