Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam...

60
Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures and Algorithm Analysis Instructor: Dr. Ken Cosh Analysis and Presentation by Rob Agle

Transcript of Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam...

Page 1: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Case Study:A Recursive Descent Interpreter

Implementation in C++(Source Code Courtesy of Dr. Adam Drozdek)

Payap UniversityICS220 - Data Structures and Algorithm AnalysisInstructor: Dr. Ken CoshAnalysis and Presentation by Rob Agle

Page 2: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

First, let’s clear up some terminology…

Page 3: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Interpreter

Examples of “Interpreted” Languages

PythonPearl

JavaScript

RubySmalltalk

Java

• In general, a compiler is a program that converts an entire program from high level source code into some lower level representation (assembly or machine code for example).

• An interpreter on the other hand, traditionally translates high level instructions and executes them on the fly (at runtime).

• The lines between these two concepts are blurring however…

Page 4: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Interpreter

For our purposes – we can simply say that our interpreter will be used to translate and execute

one instruction statement at a time.

Page 5: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Interpreter

For our purposes – we can simply say that our interpreter will be used to translate and execute

one instruction statement at a time.

Page 6: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Interpreter

For our purposes – we can simply say that our interpreter will be used to translate and execute

one instruction statement at a time.

Page 7: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Interpreter

Things our interpreter understands:Variable Names: Any alphanumeric string

Operators: + - / * =Commands: Print, Status, End

Page 8: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

A process that allows us to descend – or “go down” to lower and lower levels of complexity via recursion,

and then work “backwards” towards a solution once all the pieces are in place.

Page 9: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

A process that allows us to descend – or “go down” to lower and lower levels of complexity via recursion,

and then work “backwards” towards a solution once all the pieces are in place.

Page 10: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

For Example:

var = 2*(3+5);

Page 11: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

For Example:

var = 2*(3+5);

Page 12: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

For Example:The statement: var = 2*(3+5); can be parsed and broken

down into its individual pieces using recursion.

Page 13: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descent

For Example:The statement: var = 2*(3+5); can be parsed and broken

down into its individual pieces using recursion.

Page 14: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descentvar = 2*(3+5);

Don’t worry about how, just imagine we magically use some combination of direct and indirect recursion

to break down the above statement into the following…

Page 15: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Recursive Descentvar = 2*(3+5);

Don’t worry about how, just imagine we magically use some combination of direct and indirect recursion

to break down the above statement into the following…

Page 16: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;

Page 17: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Page 18: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Operator Operator Operator

Page 19: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Operator

Factor

Operator Operator

Factor Factor

Page 20: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Operator

Factor

Operator Operator

Factor Factor

Term Term

Page 21: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Operator

Factor

Operator Operator

Factor Factor

Term Term

Expression

Expression

Page 22: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

var = 2 * ( 3 + 5 ) ;ID

Operator

Factor

Operator Operator

Factor Factor

Term Term

Expression

Expression

Page 23: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

What do we need (object wise) to accomplish this?

Data:• a list of all ID’s (variables)• An array of characters to store an input statement

Functionality:• A way to get the input statement from the user• A way to parse the input, get values for expressions (if any) and

its composite parts (terms, factors – if any) and perform indicated operations.• A few “black boxes”…

Page 24: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Data

Page 25: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Data:• a list of all ID’s (variables)• An array of characters to store an input statement

Functionality:• A way to get the input statement from the user• A way to parse the input, get values for expressions (if any) and

its composite parts (terms, factors – if any) and perform indicated operations.• A few “black boxes”…

What do we need (object wise) to accomplish this?

Page 26: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Functionality

Page 27: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

So – let’s go back to our concrete example and trace the program…

Page 28: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Trace: Input -> var = 2*(3+5);

Page 29: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Trace: Input -> var = 2*(3+5);

Page 30: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Page 31: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke =id =command =

getStatement()

Page 32: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke =id =command =

getStatement()

varVAR

var

Page 33: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

=var

Page 34: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

=

t =

R term()

?

Page 35: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

=

t =

R term()

?

R factor()

f = ?

Page 36: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

=

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0 1.0

Page 37: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

statement.idList =

Statement.ch = =2

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0 1.0

Page 38: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

2

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0 1.0

Page 39: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

2

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0 1.0

Page 40: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

*

statement.idList =

Statement.ch =

1.0 2.0

2

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0

Page 41: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

statement.idList =

Statement.ch =

2

2.0

*

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = ?

var = minus = id =

1.0

Page 42: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

statement.idList =

Statement.ch =

2

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

f =

*

R factor()

* ?

Page 43: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

*

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0 1.0

* ?

Page 44: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

*

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0 1.0

* ?

Page 45: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0 1.0

* ?

Page 46: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0 1.0

* ?

Page 47: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

Here, we have our first recursive function call…

Page 48: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

This conveniently allows us to naturally follow mathematical

precedence …

Page 49: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

A series of additional indirect recursive

calls will determine the value of (3+5)…

R term()

Page 50: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

statement.idList =

Statement.ch =

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

A series of additional indirect recursive

calls will determine the value of (3+5)…

R term()R factor()

Page 51: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

3

statement.idList =

Statement.ch =

?

R expression()

(

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

A series of additional indirect recursive

calls will determine the value of (3+5)…

R term()R factor()

Page 52: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

R factor()+

statement.idList =

Statement.ch = 3

?

R expression()

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

A series of additional indirect recursive

calls will determine the value of (3+5)…

R term()

Page 53: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

+

statement.idList =

Statement.ch =

?

R expression()

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

Page 54: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

)

statement.idList =

Statement.ch =

8

+

?

R expression()

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

R factor()

f = 2

var = minus = id =

1.0

* ?

We now see the same chain of recursive calls to term and factor…

Which eventually sets t = 8 in expression(). This value will be returned to factor…

Page 55: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

;

statement.idList =

Statement.ch =

R factor()

* 82 * ?

)

8

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

f =

var = minus = id =

1.0 • factor() can now return 8 to

term()

Page 56: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

16

statement.idList =

Statement.ch =

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t =

R term()

?

f = 2 * 8

• factor() can now return 8 to term()

• term() can return 2*8 =16 to expression()

;

Page 57: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

16

statement.idList =

Statement.ch =

R expression()

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

?

t = 16

• factor() can now return 8 to term()

• term() can return 2*8 =16 to expression()

• expression() also returns 16 to getStatement…

;

Page 58: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

16

statement.idList =

Statement.ch =

Trace: Input -> var = 2*(3+5);

Runti

me

Stac

ke = id =command =

getStatement()

varVAR

;

var => 16

Page 59: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Control is returned to the main function, where once again getStatement will be called…

Page 60: Case Study: A Recursive Descent Interpreter Implementation in C++ (Source Code Courtesy of Dr. Adam Drozdek) Payap University ICS220 - Data Structures.

Final Thoughts

For the sake of time – a lot of the non-recursive functions were overlooked and treated as black boxes.

Tracing your own input through the functions carefully will leave you with a solid understanding of recursion.

Recursive descent was once a popular way to build a parser. These days more complex parsers can be built

by parser generators. For more information (and a solid headache), google: LR parsers.