parsing strategies eric roberts cs 106b march 6, 2013
TRANSCRIPT
![Page 1: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/1.jpg)
Parsing Strategies
Eric RobertsCS 106B
March 6, 2013
![Page 2: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/2.jpg)
Contest Results
The CS106B
Recursion ContestMarch 2013
![Page 3: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/3.jpg)
Recursion Contest Results
First place (algorithmic): Dylan Moore, Connect FourRunner-up (algorithmic): Vineeth Gangaram, Heuristic SudokuRunner-up (algorithmic): Harry Simon, Sudoku Generator
First place (aesthetic): Matt Lathrop, Recursive Artist
Grand prize (both categories): Gio Jacuzzi, Kaleidoscope
Runner-up (aesthetic): Xiaolin Lin, L-SystemsRunner-up (aesthetic): Jed Paul, Camouflage Creator
Honorable mention: Brad Girardeau, The Game of LifeHonorable mention: Christina Lee, Because Everyone Loves Sudoku
Honorable mention: Thaminda Edirisooriya, Fractal Hero
![Page 4: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/4.jpg)
The Problem of Parsing• The rules for forming an expression can be expressed in the
form of a grammar, as follows:
E constant
E identifier
E E op E
E ( E )
• The process of translating an expression from a string to its internal form is called parsing.
![Page 5: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/5.jpg)
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.
T constant
T identifier
E E op E
T ( E )
E T
![Page 6: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/6.jpg)
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.
x + 2 * y
T T T
E
E
x + 2 * y
TTT
E
E
• 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.
![Page 7: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/7.jpg)
Exercise: Parsing an Expression• Diagram the expression tree that results from the input string
2 * n + 1odd =
IDENTIFIER
odd
CONSTANT
2
CONSTANT
1
IDENTIFIER
n
COMPOUND
*
COMPOUND
+
COMPOUND
=
![Page 8: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/8.jpg)
/* * 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, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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 Implementation
![Page 9: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/9.jpg)
/* * 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, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = precedence(token); if (tprec <= prec) break; Expression *rhs = readE(scanner, tprec); exp = new CompoundExp(token, exp, rhs); } scanner.saveToken(token); return exp;}
/* * 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
![Page 10: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/10.jpg)
/* * 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;}
/* * 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. */
int precedence(string token) { if (token == "=") return 1; if (token == "+" || token == "-") return 2; if (token == "*" || token == "/") return 3; return 0;}
The parser.cpp Implementation
![Page 11: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/11.jpg)
Tracing the Precedence Parser
skip simulation
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^
![Page 12: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/12.jpg)
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); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 0
![Page 13: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/13.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
0
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 token exptype
odd = 2 * n + 1^ ^
oddWORD
![Page 14: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/14.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
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 token exptype
![Page 15: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/15.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 0
odd
ID
^=1
![Page 16: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/16.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^=1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 1
![Page 17: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/17.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
1
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 token exptype
odd = 2 * n + 1^ ^
2NUMBER
![Page 18: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/18.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
1
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 token exptype
![Page 19: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/19.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 1
2
CONST
^ 3 *
![Page 20: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/20.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1
odd
ID
^ =
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^ 3 *=
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 3
![Page 21: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/21.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^2 *odd = 2 * n + 1 0 =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
3
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 token exptype
odd = 2 * n + 1^ ^
nWORD
![Page 22: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/22.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^2 *odd = 2 * n + 1 0 =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
3
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 token exptype
![Page 23: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/23.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd
ID
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
2
CONST
2 *odd = 2 * n + 1 0 =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 3
n
ID
^ 2 +
![Page 24: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/24.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd
ID
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
2
CONST
3odd = 2 * n + 1 0
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
n
ID
![Page 25: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/25.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 1
2
CONST
^3 *
n
ID
*
COMP
2 +
![Page 26: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/26.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^3 *
n
ID
*
COMP
2 +
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 2
![Page 27: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/27.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^3 *
n
ID
*
COMP
2 +
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^
2
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 token exptype
odd = 2 * n + 1^ ^
1NUMBER
![Page 28: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/28.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^3 *
n
ID
*
COMP
2 +
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 2
1
CONST
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 token exptype
![Page 29: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/29.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^3 *
n
ID
*
COMP
2 +
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1^ 2
1
CONST
0
![Page 30: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/30.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^3 *
n
ID
*
COMP
2 +
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
1
CONST
![Page 31: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/31.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 1
2
CONST
^ 2 +
n
ID
*
COMP
0
1
CONST
+
COMP
![Page 32: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/32.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
2
CONST
n
ID
*
COMP
1
CONST
+
COMP
![Page 33: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/33.jpg)
Tracing the Precedence Parser int main() { TokenScanner scanner = new TokenScanner(); scanner.setInput("odd = 2 * n + 1"); scanner.ignoreWhitespace(); Expression *exp = readE(scanner, 0); . . .}
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd = 2 * n + 1 0
odd
ID
^ =1
2
CONST
n
ID
*
COMP
1
CONST
+
COMP
0
=
COMP
![Page 34: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/34.jpg)
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^
Expression *readE(TokenScanner & scanner, int prec) { Expression *exp = readT(scanner); string token; while (true) { token = scanner.nextToken(); int tprec = 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
odd
ID
2
CONST
n
ID
*
COMP
1
CONST
+
COMP
=
COMP
![Page 35: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/35.jpg)
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); . . .}
odd
ID
2
CONST
n
ID
*
COMP
1
CONST
+
COMP
=
COMP
scanner exp
odd = 2 * n + 1^
![Page 36: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/36.jpg)
![Page 37: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/37.jpg)
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.– If n 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.
![Page 38: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/38.jpg)
The Basic Starter Project
![Page 39: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/39.jpg)
Modules in the Starter Folder
Basic.cpp You write this one, but it’s short.
exp.hexp.cpp
You need to remove the = operator and add a few things to EvaluationContext.
parser.hparser.cpp
You need to remove the = operator.
program.hprogram.cpp
You’re given the interface, but need to write the private section and the implementation.
statement.hstatement.cpp
You’re given the interface and need to supply the implementation.
![Page 40: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/40.jpg)
Your Primary TasksFigure out how the pieces of the program go together and what you need to do.
1.
Code the Program class, keeping in mind what methods need to run in constant time.
2.
Implement the Statement class hierarchy: 3.
![Page 41: Parsing Strategies Eric Roberts CS 106B March 6, 2013](https://reader030.vdocument.in/reader030/viewer/2022012910/56649ef35503460f94c05c79/html5/thumbnails/41.jpg)
The End