Computer Science 5641
Compiler Design
Project Part 3 - Parser and Abstract Syntax Trees (60 points)
Due Thursday, November 18, 2004

Introduction

In this part of the project you will construct a parser for the language described below. In doing this you should make use of either of the scanners you implemented in part 2 of the project. You should use bison as your method for constructing your parser. Your parser should construct an abstract syntax tree and your test program should print out a nicely formatted version of the program understood by the parser (by recursively traversing the AST) or where an parse error occurs in the program.

The Language

The language you will be implementing has the following syntax:

A program consists of a sequence of global structure and/or variable declarations and function definitions.

A structure declaration takes the form:

where struct is a reserved word and the Identifier is any legal identifier token from the scanner. A FieldList consists of a set of field declarations of the form:

where Type is either one of the three reserved words char, int, or double or is a previously declared name for a structure. There must be at least one field declaration in a FieldList.

A variable declaration takes one of two forms:

where Type is as in a field declaration, the Identifier is any identifier token from the scanner and the Expression is a legal expression as defined below.

A function definition takes the format:

where Type and Identifier are the same as above, and the ParamList and StmtList are described below.

An expression in the language is built using the following rules:

In terms of precedence the operators have the following precedence (lowest to highest):

A ParamList consists of zero or more parameter items separated by commas (no comma at the end of the list). A parameter item has the format:

where Type and Identifier are as described previously.

An ArgList consists of zero or more arguments separated by commas (no comma at the end of the list). An argument is any legal Expression as described above.

A Stmtlist consists of zero or more statements. Legal statements are as follows:

where a VarReference is either (1) any legal identifier, or (2) a set of legal identifiers separated by the structure operator (.).

Errors

If an input file contains an error you should print out an error message indicating where the first error occurs in the file. As discussed below, you may implement more complex error messages for extra credit.

Output

If an input file is parsed correctly your program should produce an AST as discussed in class and in the textbook. To show this result your code should reproduce (in a readable format) the input program. For example if the input file was:

int count = 0;

struct point {
    int x;
    int y;
};

int func1 (point p) {
    if (func1 <= 0) return count; fi;
    count = count + p.x;
    return func1(p.x,p.y - 1); }

int main () {
    point num;
    stdout << "Please enter two numbers: ";
    stdin >> p.x;
    stdin >> p.y;

    int result = func1(p.x,p.y);

    stdout << "The result is ";
    stdout << result;
    stdout << "\n";
    return 0; }

The output of your program might be:

int count = 0;
struct point {
  int x;
  int y;
};
int func1 (point p) {
  if (func1 <= 0)
    return count;
  fi;
  count = count + p.x;
  return func1(p.x,p.y - 1);
}
int main () {
  point num;
  stdout << "Please enter two numbers: ";
  write("Please enter two numbers: ");
  stdin >> p.x;
  stdin >> p.y;
  int result = func1(p.x,p.y);
  stdout << "The result is ";
  stdout << result;
  stdout << "\n";
}

Note that you do not need to preserve parentheses from the original program and can simply print out every expression completely parenthesized.

What To Turn In

Turn in documented versions of all of your code (including test code). Also document your test cases and show results from your parser on each test file. You should also write a team report on this part of the project and in addition submit a short individual report from each member of the team.