Expression Trees Eric Roberts CS 106B March 4, 2013.

Slides:



Advertisements
Similar presentations
OO Programming in Java Objectives for today: Overriding the toString() method Polymorphism & Dynamic Binding Interfaces Packages and Class Path.
Advertisements

Intermediate Code Generation
Abstract Syntax Mooly Sagiv html:// 1.
CS106X – Programming Abstractions in C++ Cynthia Bailey Lee CS2 in C++ Peer Instruction Materials by Cynthia Bailey Lee is licensed under a Creative Commons.
ITEC200 – Week03 Inheritance and Class Hierarchies.
CS 280 Data Structures Professor John Peterson. Lexer Project Questions? Must be in by Friday – solutions will be posted after class The next project.
Basic Elements of C++ Chapter 2.
“is a”  Define a new class DerivedClass which extends BaseClass class BaseClass { // class contents } class DerivedClass : BaseClass { // class.
Predefined Classes in Java Ellen Walker CPSC 201 Data Structures Hiram College.
Object-Oriented Programming in C++
Mark Fontenot CSE Honors Principles of Computer Science I Note Set 14.
Parsing Strategies Eric Roberts CS 106B March 6, 2013.
CS106X – Programming Abstractions in C++ Cynthia Bailey Lee CS2 in C++ Peer Instruction Materials by Cynthia Bailey Lee is licensed under a Creative Commons.
TDDD55- Compilers and Interpreters Lesson 1 Zeinab Ganjei Department of Computer and Information Science Linköping University.
1 Inheritance. 2 Why use inheritance?  The most important aspect of inheritance is that it expresses a relationship between the new class and the base.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
Chapter 14 Abstract Classes and Interfaces. Abstract Classes An abstract class extracts common features and functionality of a family of objects An abstract.
Chapter 3 Part I. 3.1 Introduction Programs written in C ◦ All statements were located in function main Programs written in C++ ◦ Programs will consist.
Interfaces About Interfaces Interfaces and abstract classes provide more structured way to separate interface from implementation
Programming Abstractions Cynthia Lee CS106X. Inheritance Topics Inheritance  The basics › Example: Stanford GObject class  Polymorphism › Example: Expression.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Java Programming, Second Edition Chapter Twelve Advanced Inheritance Concepts.
Advanced BioPSE NCRR Programming Conventions and Standards J. Davison de St. Germain Chief Software Engineer SCI Institute December 2003 J.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Java Programming: Guided Learning with Early Objects Chapter 9 Inheritance and Polymorphism.
1 Assignment 2: AspectJ. 2 The simple language Tiny program y=2; x=2+y*3; z=x+y*2; –A program is a sequence of assignments; –Expressions on the right.
LECTURE 10 Semantic Analysis. REVIEW So far, we’ve covered the following: Compilation methods: compilation vs. interpretation. The overall compilation.
Operator Overloading.
Programming Abstractions
C++ Lesson 1.
Eine By: Avinash Reddy 09/29/2016.
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
Chapter 3 – Describing Syntax
Type Checking and Type Inference
Web Design & Development Lecture 9
Chapter Topics The Basics of a C++ Program Data Types
Chapter 3 Control Statements
Semantic Analysis Chapter 4.
Operators and Expressions
Inheritance and Polymorphism
Java Primer 1: Types, Classes and Operators
Enumeration Types In Triangle.
Semantic Analysis with Emphasis on Name Analysis
Basic Elements of C++.
Review: Two Programming Paradigms
Designing Classes Eric Roberts CS 106B January 16, 2015.
Lab 2 Expressions Tree and Parsing Strategies
CMPE Data Structures and Algorithms in C++ February 22 Class Meeting
CMPE 152: Compiler Design April 5 Class Meeting
Basic Elements of C++ Chapter 2.
CS212: Object Oriented Analysis and Design
3.3 Abstract Classes, Assignment, and Casting in a Hierarchy
Object-Oriented Programming: Polymorphism
Lab 05 – Expressions.
MSIS 655 Advanced Business Applications Programming
Chapter 17 Templates. Chapter 17 Templates Overview 17.1 Templates for Algorithm Abstraction 17.2 Templates for Data Abstraction.
Week 6 Object-Oriented Programming (2): Polymorphism
The Metacircular Evaluator
Syntax-Directed Translation
Java Inheritance.
Engineering Problem Solving with C++ An Object Based Approach
Engineering Problem Solving with C++ An Object Based Approach
Chapter 14 Abstract Classes and Interfaces
Review of C++ Language Basics
CMPE 152: Compiler Design February 12 Class Meeting
Standard Version of Starting Out with C++, 4th Edition
Static Binding Static binding chooses the function in the class of the base class pointer, ignoring any versions in the class of the object actually.
Chengyu Sun California State University, Los Angeles
Presentation transcript:

Expression Trees Eric Roberts CS 106B March 4, 2013

Where Are We Heading? In Assignment #6, your task is to implement an interpreter for the BASIC programming language. In doing so, you will learn a little bit about how interpreters and compilers work that will almost certainly prove useful as you write your own programs.

Bill Gates in The Social Network

Where Are We Heading? In Assignment #6, your task is to implement an interpreter for the BASIC programming language. In doing so, you will learn a little bit about how interpreters and compilers work that will almost certainly prove useful as you write your own programs. The goal for the next two days is to give you a sense of how a compiler can make sense of an arithmetic expression like y = 3 * (x + 1) Accomplishing that goal will unify three topics that we have already covered in CS106B: Recursion Tree structures Class hierarchies and inheritance

Recursive Structure of Expressions In most programming languages, an expression is a recursive structure that can contain subexpressions. In the model I use in Chapter 19, every expression has one of the following forms: An integer constant A variable name that holds an integer value Two expressions joined by an operator An expression enclosed in parentheses Before the interpreter can work with expressions, it must convert the string representation to a recursive data structure that mirrors the recursive definition of expressions. This process is called parsing.

The Expression Class Hierarchy Because expressions have more than one form, a C++ class that represents expressions can be represented most easily by a class hierarchy in which each of the expression types is a separate subclass, as shown in the following diagram: Expression ConstantExp IdentifierExp CompoundExp

The exp.h Interface /* * File: exp.h * ----------- * This interface defines a class hierarchy for arithmetic expressions. */ #ifndef _exp_h #define _exp_h #include <string> #include "map.h" #include "tokenscanner.h" /* Forward reference */ class EvaluationContext; * Type: ExpressionType * -------------------- * This enumerated type is used to differentiate the three different * expression types: CONSTANT, IDENTIFIER, and COMPOUND. enum ExpressionType { CONSTANT, IDENTIFIER, COMPOUND };

The exp.h Interface /* * Class: Expression * ----------------- * This class is used to represent a node in an expression tree. * Expression itself is an abstract class. Every Expression object * is therefore created using one of the three concrete subclasses: * ConstantExp, IdentifierExp, or CompoundExp. */ class Expression { public: Expression(); virtual ~Expression(); virtual int eval(EvaluationContext & context) = 0; virtual std::string toString() = 0; virtual ExpressionType type() = 0; /* Getter methods for convenience */ virtual int getConstantValue(); virtual std::string getIdentifierName(); virtual std::string getOperator(); virtual Expression *getLHS(); virtual Expression *getRHS(); }; /* * File: exp.h * ----------- * This interface defines a class hierarchy for arithmetic expressions. */ #ifndef _exp_h #define _exp_h #include <string> #include "map.h" #include "tokenscanner.h" /* Forward reference */ class EvaluationContext; * Type: ExpressionType * -------------------- * This enumerated type is used to differentiate the three different * expression types: CONSTANT, IDENTIFIER, and COMPOUND. enum ExpressionType { CONSTANT, IDENTIFIER, COMPOUND };

The exp.h Interface /* * Class: ConstantExp * ------------------ * This subclass represents a constant integer expression. */ class ConstantExp: public Expression { public: ConstantExp(int val); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual int getConstantValue(); private: int value; }; /* * Class: Expression * ----------------- * This class is used to represent a node in an expression tree. * Expression itself is an abstract class. Every Expression object * is therefore created using one of the three concrete subclasses: * ConstantExp, IdentifierExp, or CompoundExp. */ class Expression { public: Expression(); virtual ~Expression(); virtual int eval(EvaluationContext & context) = 0; virtual std::string toString() = 0; virtual ExpressionType type() = 0; /* Getter methods for convenience */ virtual int getConstantValue(); virtual std::string getIdentifierName(); virtual std::string getOperator(); virtual Expression *getLHS(); virtual Expression *getRHS(); };

The exp.h Interface /* * Class: IdentifierExp * -------------------- * This subclass represents a expression corresponding to a variable. */ class IdentifierExp: public Expression { public: IdentifierExp(string name); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual string getIdentifierName(); private: std::string name; }; /* * Class: ConstantExp * ------------------ * This subclass represents a constant integer expression. */ class ConstantExp: public Expression { public: ConstantExp(int val); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual int getConstantValue(); private: int value; };

The exp.h Interface /* * Class: CompoundExp * ------------------ * This subclass represents a compound expression. */ class CompoundExp: public Expression { public: CompoundExp(string op, Expression *lhs, Expression *rhs); virtual ~CompoundExp(); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual std::string getOperator(); virtual Expression *getLHS(); virtual Expression *getRHS(); private: std::string op; Expression *lhs, *rhs; }; /* * Class: IdentifierExp * -------------------- * This subclass represents a expression corresponding to a variable. */ class IdentifierExp: public Expression { public: IdentifierExp(string name); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual string getIdentifierName(); private: std::string name; };

The exp.h Interface /* * Class: EvaluationContext * ------------------------ * This class encapsulates the information that the evaluator needs to * know in order to evaluate an expression. */ class EvaluationContext { public: void setValue(std::string var, int value); int getValue(std::string var); bool isDefined(std::string var); private: Map<std::string,int> symbolTable; }; #endif /* * Class: CompoundExp * ------------------ * This subclass represents a compound expression. */ class CompoundExp: public Expression { public: CompoundExp(string op, Expression *lhs, Expression *rhs); virtual ~CompoundExp(); virtual int eval(EvaluationContext & context); virtual std::string toString(); virtual ExpressionType type(); virtual std::string getOperator(); virtual Expression *getLHS(); virtual Expression *getRHS(); private: std::string op; Expression *lhs, *rhs; };

Selecting Fields from Subtypes The Expression class exports several methods that allow clients to select fields from one of the concrete subtypes: virtual int getConstantValue(); virtual std::string getIdentifierName(); virtual std::string getOperator(); virtual Expression *getLHS(); virtual Expression *getRHS(); The implementation of these methods in the Expression class always generates an error. Each subclass overrides that implementation with code that returns the appropriate instance variable. These methods exist primarily for the convenience of the client. A more conventional strategy would be to have each subclass export only the getters that apply to that subtype. Adopting this strategy, however, forces clients to include explicit type casting, which quickly gets rather tedious.

Code for the eval Method int ConstantExp::eval(EvaluationContext & context) { return value; } int IdentifierExp::eval(EvaluationContext & context) { if (!context.isDefined(name)) error(name + " is undefined"); return context.getValue(name); int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") { if (right == 0) error("Division by 0"); return left / right; error("Illegal operator in expression"); return 0;

Exercise: Evaluating an Expression Trace through the steps involved in evaluating the expression y = ( 9 – x ) * 7 in a context in which x has the value 3. The representation of this expression looks like this: y ID 9 CONST x - COMP 7 * = On Wednesday, we’ll talk about how to parse the string version of the expression into its internal representation. For now, the goal is just to walk through the evaluation.

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 3); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp->eval(context) << endl; return 0; } context scanner exp x = 3 y = (9 – x) * 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this context x = 3 scanner exp y = (9 – x) * 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this scanner exp y = (9 – x) * 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int ConstantExp::eval(EvaluationContext & context) { return value; } context x = 3 this scanner exp y = (9 – x) * 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int ConstantExp::eval(EvaluationContext & context) { return value; } context x = 3 this scanner exp y = (9 – x) * 7 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this scanner exp y = (9 – x) * 7 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int IdentifierExp::eval(EvaluationContext & context) { if (!context.isDefined(name)) error(name + " is undefined"); return context.getValue(name); } context x = 3 this scanner exp y = (9 – x) * 7 7 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int IdentifierExp::eval(EvaluationContext & context) { if (!context.isDefined(name)) error(name + " is undefined"); return context.getValue(name); } context x = 3 this scanner exp y = (9 – x) * 7 7 3 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int ConstantExp::eval(EvaluationContext & context) { return value; } context x = 3 this scanner exp y = (9 – x) * 7 7 3 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int ConstantExp::eval(EvaluationContext & context) { return value; } context x = 3 this scanner exp y = (9 – x) * 7 7 3 9 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this 3 9 scanner exp y = (9 – x) * 7 7 6 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 2); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp.eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this 7 6 scanner exp y = (9 – x) * 7 , y = 42 42 y ID 9 CONST x - COMP 7 * =

Solution: Evaluating an Expression int main() { EvaluationContext context; context.setValue("x", 3); TokenScanner scanner = new TokenScanner("y = (9 – x) * 7"); scanner.ignoreWhitespace(); scanner.scanNumbers(); Expression *exp = parseExp(scanner); cout << exp->eval(context) << endl; return 0; } int CompoundExp::eval(EvaluationContext & context) { int right = rhs->eval(context); if (op == "=") { context.setValue(lhs->getIdentifierName(), right); return right; } int left = lhs->eval(context); if (op == "+") return left + right; if (op == "-") return left - right; if (op == "*") return left * right; if (op == "/") return left / right; error("Illegal operator in expression"); context x = 3 left right this 42 , y = 42 context scanner exp x = 3, y = 42 y = (9 – x) * 7 y ID 9 CONST x - COMP 7 * =

The End