1 / 41

Parsing Strategies

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.

ziva
Download Presentation

Parsing Strategies

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Parsing Strategies Eric Roberts CS 106B March 6, 2013

  2. Contest Results The CS106B Recursion Contest March 2013

  3. 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

  4. 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.

  5. 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.

  6. 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.

  7. 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

  8. 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; }

  9. /* * 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; }

  10. /* * 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; }

  11. 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

  12. 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 ^

  13. 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 ^ ^

  14. 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

  15. 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 = ^ ^

  16. 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 ^

  17. 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 ^ ^

  18. 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 ^

  19. 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 * ^ ^

  20. 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 ^

  21. 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 ^ ^

  22. 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 ^

  23. 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 + ^ ^

  24. 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

  25. 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 * ^ ^

  26. 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 ^

  27. 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 ^ ^

  28. 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 ^

  29. 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 ^

  30. 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

  31. 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

  32. 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

  33. 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

  34. 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

  35. 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

  36. 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.

  37. The Basic Starter Project

  38. 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.

  39. 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:

  40. The End

More Related