Lecture: Mini Language Interpreter Part I: parser and expression trees

Background Material

Reading

Theme

We implement an interpreter for the mini language from Chapter 13 of the Louden text. The grammer can be directly translated into bison and a parser generated. The interpreter converts the input program into a data structure that stores the program (a list of statements) and the program is interpreted by evaluating each statement in the context of the current environment. Executing a statement (assignment, if, or while) updates the environment, and when the program finishes executing (assuming it does), the final environment is returned. The interpreter is implemented by creating a class, with an evaluate method, for each syntactic category. When the parser detects a syntactic category the corresponding constructor is called. A map is used to store the environment and the program is executed by calling all of the evaluate methods of the statements in the program.

In part I of the implementation, we construct the parser, and implement classes for expressions. An abstract syntax tree is built for expressions. Note that it is not sufficient to simply return the value of the expression when parsing, since an expression (e.g. while statement) may need to be evaluated multiple times.

Topics

  1. Review mini language from chapter 13 (see Lecture 6)
  2. Parser for mini language (program.y, program.l). See program.ypp for a C++ version.

    To use bison with embedded C++ code, name the input yacc file name.ypp instead of name.y. bison will produce a C++ file name.tab.cpp. If you want to use a flex generated scanner, you should do the lex program in C. You will need an include file generated by bison to communicate the tokens to the parser. I used a C version of the yacc program (doesn't have to have any action statements, but just the appropriate union and token definitions). You will compile the lexer with gcc and then link this with the C++ program generated by bison.

    1. bison program.ypp # to create C++ file program.tab.cpp
    2. bison -d program.y # to create header file program.tab.h for lexer
    3. flex program.l
    4. gcc -c lex.yy.c # create the object file lex.yy.o
    5. g++ program.tab.cpp lex.yy.o # compile parser and link lexer
  3. Expression trees and Symbol Table. (expr.h, expr.cpp, main.cpp)
  4. Interfacing with bison (expr.ypp, expr.y, expr.l)
    1. bison expr.ypp # to create C++ file expr.tab.cpp
    2. bison -d expr.y # to create header file program.tab.h for lexer
    3. flex expr.l
    4. gcc -c lex.yy.c # create the object file lex.yy.o
    5. g++ expr.tab.cpp expr.cpp lex.yy.o # compiler parser and link lexer

References and programs

Exercises

Created: April 10, 2008 by jjohnson AT cs DOT drexel DOT DOT edu