Computer Science 60
Principles of Computer Science
Fall 2005


Assignment 8 "Lite": Parsing and Prolog!
Due Monday, October 24 by 11:59 PM

Please remember to complete the on-line mid-semester course evaluation before you submit this assignment. Thank you!

This assignment has three parts. In the first part, you will implement a recursive descent parser for a small "language". In the second and third parts, you will have a chance to start playing with Prolog.

Part 1: Recursive Descent Parsing (35 Points)


In this part of the assignment you will be writing a recursive descent parser and an evaluator for arithmetic expressions with addition, multiplication, exponentiation, negation, and parenthesization. In particular, we will use the unambiguous context-free grammar that we saw in class:
S -> P + S | P
P -> E * P | E
E -> U ^ E | U
U -> ( S ) | - V | V
V -> '0' | ... | '9'
Your task is to write a recursive descent parser in rex for this grammar. One of the functions in your file should be called parse. This function takes a string to parse and returns a list of two things:
  1. A parse tree, a tree of operations and variables that reflects the computational structure of the input expression as we demonstrated in class.
  2. A residue list, a list of characters (tokens) that have not yet been parsed.

Note that the first element in each case will be a parse tree, and the second element will be the residue list. If the parsing was successful, the residue will be the empty list.

From our experience, a good way to approach this problem is to first build a parser for a simplified version of this grammar. For example, you might begin with the grammar:

S -> P + S | P
P -> E * P | E
E -> V
V -> '0' | ... | '9'
Once you get the parser working for this grammar, you can extend it to the full grammar for this problem.

Note that in the full grammar, the rules for variable U are a little different from the other rules, in that they handle parentheses and negation. Think about these rules! While they seem a bit strange, they actually are "easier" for the parser than the other rules!

Here's an example of how your parse function will behave once you have implemented the full grammar. Notice that in the first two examples, the residue is empty because parsing was successful. The third example did not succeed in parsing because the input was malformed.

rex > parse("1+2^3");
[[+, 1, [^, 2, 3]], []]

rex > parse("(1+2)^3+-4");
[[+, [^, [+, 1, 2], 3], [-, 4]], []]

rex > parse("1+2*+3");
[[+, 1, [*, 2, Error]], [BADTOKEN, 3]]

Take a look at (and feel free to use any part of) the file part1.rex which is in the directory /cs/cs60/assignments/assignment8. It shows a recursive descent parser for expressions using only addition. Note the use of explode to tokenize the original string, i.e., to break it into individual meaningful units, which in this case are single characters. Note that your input string should have no whitespace, since whitespace will be converted into additional "space" characters by explode.

Once you have successfully written your recursive descent parser, implement an Evaluate function and whatever other helper functions you need. Evaluate takes as input an arithmetic expression (with addition and multiplication and one digit numbers) and returns its arithmetic value. For example, here is how your Evaluate function should behave.

rex > Evaluate("1+2^4");
17

rex > Evaluate("1*2+3");
5

3 rex > Evaluate("1+");
Bad Input
Notice that this function should return the string "Bad Input" if the expression is malformed. The Evaluate function will need to call the parser and some helper functions. You may wish to use the rex built-in function make_number which takes a character as input returns a number corresponding to that character. For example,
rex > make_number('4');
4

rex > 1 + make_number('2');
3

Remember to place all of your code for this part of the assignment in a file called part1.rex.

For 5 extra credit points augment your grammar, parser and evaluator to permit the use of multi-digit numbers as input. For example, we could ask Evaluate("(60+42)+-1"). If you do this bonus, make sure to put a comment in the first line of your part1.rex file stating that "THIS SUBMISSION HANDLES THE BONUS PROBLEM".

Part 2: Playing with Prolog! (15 Points)


In the directory /cs/cs60/assignments/assignment8 you will find a file called part2.pl. This file contains an expanded database of the Simpsons family. You should make a copy of this file and add the following rules to this file. You may also add any additional helper rules that you wish, including anything that we looked at in class. However, please don't change the facts about parenthood/relationships among the Simpsons! Recall that "," is the symbol for AND, ";" is the SYMBOL for OR, and "\+" is the symbol for NOT. Please look at the class notes for other Prolog syntax. Your file should be called part2.pl and submit it using cs60submit.

Part 3: Lists in Prolog (25 Points)


Here, you will write three Prolog rules for lists. Please submit these rules in one file called part3.pl using cs60submit. You may use any helper rules that you like. In particular, some of the rules that we saw in class may be useful to you here. You may implement and use any of them.