The Semantic Parser

Modify your parser so that it builds abstract syntax trees for expressions. Modify the definition of type YYSTYPE to assuming that Node is the type of a tree node.

typedef union {
  char* str;
  int   ival;
  Node* tree;
}
YYSTYPE;
so that an attribute can be a string, an integer or a tree. In the same section where you define tokens using %token lines, add lines indicating types of all nonterminals that produce expressions. For example, write
%type <tree> expression
%type <tree> simpleExpresion
…
using the names of your expression nonterminals.

Now make each expression rule build a tree. For example, a rule that handles juxtaposition might look as follows.

 applyExpression : applyExpression  Term
                        {$$ = applyNode($1, $2);
                        }

Modify your definition rules so that they just print the definition by saying which identifier is being defined, and show the tree (in debug form) that it is equal to. The definition rule would become something like this.

 definition      : TOK_DEF  TOK_ID  '='  expression  TOK_END
                        {printf("Define %s = \n", $2);
                         print_tree($4);
                         printf("\n");
                        }


Running the program

Change your main function to the following.

int main(int argc, char** argv)
{
  if(argc == 2) {
    yyin = fopen(argv[1], "r");
    if(yyin == NULL) {
      return 1;
    }
    yyparse() 
    if(!error_occurred) {
      return interpreter();
    }
  }
  return 1;
}

Submitting your work

When you have this working, submit all of your source files using the following command (presuming given file names).

  ~abrahamsonk/5220/bin/submit semanticparser parser.y lexer.lex lexer.h token.h ast.c ast.h interpreter.c interpreter.h simplify.c simplify.h stringtable.c stringtable.h allocate.h
Be sure to submit all of your source files. Do not assume that I already have them because you submitted them before.