Parsing strategies
Download
1 / 41

Parsing Strategies - PowerPoint PPT Presentation


  • 112 Views
  • Uploaded on

Parsing Strategies. Eric Roberts CS 106B March 6, 2013. Contest Results. The CS106B Recursion Contest March 2013. Recursion Contest Results. First place (algorithmic):. Dylan Moore , Connect Four. Runner-up (algorithmic):. Vineeth Gangaram , Heuristic Sudoku.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Parsing Strategies' - yelena


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Parsing strategies

Parsing Strategies

Eric Roberts

CS 106B

March 6, 2013


Contest results
Contest Results

The CS106B

Recursion Contest

March 2013


Recursion contest results
Recursion Contest Results

First place (algorithmic):

Dylan Moore, Connect Four

Runner-up (algorithmic):

VineethGangaram, Heuristic Sudoku

Runner-up (algorithmic):

Harry Simon, Sudoku Generator

First place (aesthetic):

Matt Lathrop, Recursive Artist

Runner-up (aesthetic):

Xiaolin Lin, L-Systems

Runner-up (aesthetic):

Jed Paul, Camouflage Creator

Honorable mention:

ThamindaEdirisooriya, Fractal Hero

Grand prize (both categories):

GioJacuzzi, Kaleidoscope

Honorable mention:

Brad Girardeau, The Game of Life

Honorable mention:

Christina Lee, Because Everyone Loves Sudoku


The problem of parsing

E constant

E identifier

E  E op E

E ( E )

The Problem of Parsing

  • The rules for forming an expression can be expressed in the form of a grammar, as follows:

  • The process of translating an expression from a string to its internal form is called parsing.


A two level grammar

E  T

E  E op E

T constant

T identifier

T ( E )

A Two-Level Grammar

  • The problem of parsing an expression can be simplified by changing the grammar to one that has two levels:

    • An expression is either a term or two expressions joined by an operator.

    • A term is either a constant, an identifier, or an expression enclosed in parentheses.

  • This design is reflected in the following revised grammar.


Ambiguity in parse structures

E

E

E

E

T

T

T

T

T

T

x

+

2

*

y

x

+

2

*

y

Ambiguity in Parse Structures

  • Although the two-level grammar from the preceding slide can recognize any expression, it is ambiguous because the same input string can generate more than one parse tree.

  • Ambiguity in grammars is typically resolved by providing the parser with information about the precedence of the operators. The text describes two strategies: Iversonian precedence, in which the operators all group to the right, and operator precedence, in which each operator is associated with an integer that defines its place in the precedence hierarchy.


Exercise parsing an expression

odd

=

2

*

n

+

1

odd

n

Exercise: Parsing an Expression

  • Diagram the expression tree that results from the input string

COMPOUND

=

COMPOUND

+

COMPOUND

*

IDENTIFIER

CONSTANT

IDENTIFIER

CONSTANT

2

1


The parser cpp implementation
The parser.cpp Implementation

/*

* Implementation notes:readE

* Usage: exp =readE(scanner, prec);

* ----------------------------------

* This function reads the next expression from the scanner by

* matching the input to the following ambiguous grammar:

*

* E -> T

* E -> E op E

*

* This version of the method uses precedence to resolve ambiguity.

*/

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp = readT(scanner);

string token;

while (true) {

token = scanner.nextToken();

inttprec = precedence(token);

if (tprec <= prec) break;

Expression *rhs = readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}


The parser cpp implementation1

/*

* Function:readT

* Usage: exp =readT(scanner);

* ----------------------------

* This function reads a single term from the scanner.

*/

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

The parser.cpp Implementation

/*

* Implementation notes:readE

* Usage: exp =readE(scanner, prec);

* ----------------------------------

* This function reads the next expression from the scanner by

* matching the input to the following ambiguous grammar:

*

* E -> T

* E -> E op E

*

* This version of the method uses precedence to resolve ambiguity.

*/

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}


The parser cpp implementation2

/*

* Function: precedence

* Usage: prec =precedence(token);

* --------------------------------

* This function returns the precedence of the specified operator

* token. If the token is not an operator, precedence returns 0.

*/

intprecedence(stringtoken) {

if (token == "=") return 1;

if (token == "+" || token == "-") return 2;

if (token == "*" || token == "/") return 3;

return 0;

}

The parser.cpp Implementation

/*

* Function: readT

* Usage: exp = readT(scanner);

* ----------------------------

* This function reads a single term from the scanner.

*/

Expression *readT(TokenScanner & scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}


Tracing the precedence parser
Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

scanner.scanNumbers();

Expression *exp =readE(scanner, 0);

. . .

}

scanner

exp

odd = 2 * n + 1

^

skip simulation


Tracing the precedence parser1

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

prec

tprec

token

exp

rhs

Tracing the Precedence Parser

int main() {

TokenScanner scanner = new TokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

scanner.scanNumbers();

Expression *exp = readE(scanner, 0);

. . .

}

0

odd = 2 * n + 1

^


Tracing the precedence parser2

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

prec

tprec

token

exp

rhs

scanner

token

exp

type

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

odd = 2 * n + 1

^

odd = 2 * n + 1

odd

WORD

^

^


Tracing the precedence parser3

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

prec

tprec

token

exp

rhs

scanner

token

exp

type

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

odd = 2 * n + 1


Tracing the precedence parser4

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

prec

tprec

token

exp

rhs

ID

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

^


Tracing the precedence parser5

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

ID

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

odd = 2 * n + 1

^


Tracing the precedence parser6

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

scanner

token

exp

type

ID

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

1

0

odd = 2 * n + 1

=

^

^

1

odd = 2 * n + 1

^

odd = 2 * n + 1

2

NUMBER

^

^


Tracing the precedence parser7

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

scanner

token

exp

type

ID

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

^

1

odd = 2 * n + 1

^


Tracing the precedence parser8

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

CONST

ID

2

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

3

odd = 2 * n + 1

*

^

^


Tracing the precedence parser9

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

CONST

ID

2

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

odd = 2 * n + 1

=

^

1

3

odd = 2 * n + 1

=

*

^

3

odd = 2 * n + 1

^


Tracing the precedence parser10

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

scanner

token

exp

type

CONST

ID

2

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

0

1

1

2

odd = 2 * n + 1

odd = 2 * n + 1

=

*

^

3

odd = 2 * n + 1

^

odd = 2 * n + 1

n

WORD

^

^


Tracing the precedence parser11

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

scanner

token

exp

type

CONST

ID

2

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

0

1

1

2

odd = 2 * n + 1

odd = 2 * n + 1

=

*

^

3

odd = 2 * n + 1

^


Tracing the precedence parser12

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

CONST

ID

ID

2

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

2

odd = 2 * n + 1

=

*

3

2

odd = 2 * n + 1

+

^

^


Tracing the precedence parser13

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

CONST

ID

ID

2

n

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

3

odd = 2 * n + 1


Tracing the precedence parser14

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

2

+

CONST

COMP

ID

ID

2

*

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

3

1

odd = 2 * n + 1

*

^

^


Tracing the precedence parser15

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

2

+

CONST

COMP

ID

ID

2

*

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

3

1

odd = 2 * n + 1

*

^

2

odd = 2 * n + 1

^


Tracing the precedence parser16

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

scanner

token

exp

type

2

+

CONST

COMP

ID

ID

2

*

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

3

odd = 2 * n + 1

*

^

2

odd = 2 * n + 1

^

odd = 2 * n + 1

NUMBER

1

^

^


Tracing the precedence parser17

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readT(TokenScanner& scanner) {

string token = scanner.nextToken();

TokenType type = scanner.getTokenType(token);

if (type == WORD) return new IdentifierExp(token);

if (type == NUMBER) return new ConstantExp(stringToInteger(token));

if (token != "(") error("Illegal term in expression");

Expression *exp = readE(scanner, 0);

if (scanner.nextToken() != ")") {

error("Unbalanced parentheses in expression");

}

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

scanner

token

exp

type

2

+

CONST

COMP

ID

ID

CONST

2

*

n

odd

1

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

3

odd = 2 * n + 1

*

^

2

odd = 2 * n + 1

^


Tracing the precedence parser18

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

2

+

CONST

COMP

ID

ID

CONST

2

*

odd

n

1

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

3

odd = 2 * n + 1

*

^

2

0

odd = 2 * n + 1

^


Tracing the precedence parser19

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

scanner

prec

prec

prec

tprec

tprec

tprec

token

token

token

exp

exp

exp

rhs

rhs

rhs

2

+

CONST

COMP

ID

ID

*

2

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

3

1

odd = 2 * n + 1

*

^

CONST

1


Tracing the precedence parser20

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

0

CONST

COMP

COMP

ID

ID

2

+

*

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

1

2

odd = 2 * n + 1

+

^

CONST

1


Tracing the precedence parser21

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

scanner

prec

prec

tprec

tprec

token

token

exp

exp

rhs

rhs

CONST

COMP

COMP

ID

ID

2

*

+

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

CONST

1


Tracing the precedence parser22

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

prec

tprec

token

exp

rhs

0

CONST

COMP

COMP

COMP

ID

ID

2

+

=

*

n

odd

Tracing the Precedence Parser

int main() {

TokenScanner scanner = newTokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

Expression *exp =readE(scanner, 0);

. . .

}

0

1

odd = 2 * n + 1

=

^

CONST

1


Tracing the precedence parser23

Expression *readE(TokenScanner& scanner, intprec) {

Expression *exp =readT(scanner);

string token;

while (true) {

token =scanner.nextToken();

inttprec=precedence(token);

if (tprec<= prec) break;

Expression *rhs =readE(scanner, tprec);

exp = new CompoundExp(token, exp, rhs);

}

scanner.saveToken(token);

return exp;

}

scanner

prec

tprec

token

exp

rhs

CONST

COMP

COMP

COMP

ID

ID

2

*

+

=

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = new TokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

scanner.scanNumbers();

Expression *exp = readE(scanner, 0);

. . .

}

scanner

exp

odd = 2 * n + 1

^

CONST

1


Tracing the precedence parser24

CONST

COMP

COMP

COMP

ID

ID

2

=

+

*

odd

n

Tracing the Precedence Parser

int main() {

TokenScanner scanner = new TokenScanner();

scanner.setInput("odd = 2 * n + 1");

scanner.ignoreWhitespace();

scanner.scanNumbers();

Expression *exp = readE(scanner, 0);

. . .

}

scanner

exp

odd = 2 * n + 1

^

CONST

1


Exercise coding a basic program
Exercise: Coding a BASIC Program

  • On the second practice midterm, one of the problems concerned the hailstone sequence. For any positive integer n, you compute the terms in the hailstone sequence by repeatedly executing the following steps:

    • If n is equal to 1, you’ve reached the end of the sequence and can stop.

    • Ifn is even, divide it by two.

    • If n is odd, multiply it by three and add one.

  • Write a BASIC program that reads in an integer and prints out its hailstone sequence.



Modules in the starter folder
Modules in the Starter Folder

Basic.cpp

You write this one, but it’s short.

You need to remove the = operator and add a few things to EvaluationContext.

exp.h

exp.cpp

parser.h

parser.cpp

You need to remove the = operator.

program.h

program.cpp

You’re given the interface, but need to write the private section and the implementation.

statement.h

statement.cpp

You’re given the interface and need to supply the implementation.


Your primary tasks
Your Primary Tasks

1.

2.

3.

Figure out how the pieces of the program go together and what you need to do.

Code the Program class, keeping in mind what methods need to run in constant time.

Implement the Statement class hierarchy:



ad