5-Jan-16 Recursive descent parsing. Some notes on recursive descent The starter code that I gave you did not exactly fit the grammar that I gave you Both.

Slides:



Advertisements
Similar presentations
Parsing V: Bottom-up Parsing
Advertisements

Semantics Static semantics Dynamic semantics attribute grammars
Recursion CS 367 – Introduction to Data Structures.
Honors Compilers An Introduction to Grammars Feb 12th 2002.
Lecture 3: Topics If-then-else Operator precedence While loops Static methods Recursion.
9/27/2006Prof. Hilfinger, Lecture 141 Syntax-Directed Translation Lecture 14 (adapted from slides by R. Bodik)
Trees. 2 Definition of a tree A tree is like a binary tree, except that a node may have any number of children Depending on the needs of the program,
16-Jun-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
Chapter 4 Lexical and Syntax Analysis Sections 1-4.
17-Jun-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
Parsing III (Eliminating left recursion, recursive descent parsing)
ISBN Chapter 4 Lexical and Syntax Analysis The Parsing Problem Recursive-Descent Parsing.
Trees. Definition of a tree A tree is like a binary tree, except that a node may have any number of children –Depending on the needs of the program, the.
26-Jun-15 Recursive descent parsing. The Stack One easy way to do recursive descent parsing is to have each parse method take the tokens it needs, build.
27-Jun-15 Recursive descent parsing. The Stack One easy way to do recursive descent parsing is to have each parse method take the tokens it needs, build.
28-Jun-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
30-Jun-15 Stacks. What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything.
MIT Top-Down Parsing Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology.
9/27/2006Prof. Hilfinger, Lecture 141 Parsing Odds and Ends Lecture 14 (P. N. Hilfinger, plus slides adapted from R. Bodik)
14-Jul-15 Parser Hints. The Stack To turn a “Recognizer” into a “Parser,” we need the use of a Stack All boolean Recognizer methods should continue to.
14-Jul-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
Bottom-up parsing Goal of parser : build a derivation
(2.1) Grammars  Definitions  Grammars  Backus-Naur Form  Derivation – terminology – trees  Grammars and ambiguity  Simple example  Grammar hierarchies.
CSC3315 (Spring 2009)1 CSC 3315 Lexical and Syntax Analysis Hamid Harroud School of Science and Engineering, Akhawayn University
Chapter 10: Compilers and Language Translation Invitation to Computer Science, Java Version, Third Edition.
CS 280 Data Structures Professor John Peterson. How Does Parsing Work? You need to know where to start (“statement”) This grammar is constructed so that.
Parsing III (Top-down parsing: recursive descent & LL(1) )
COMP Parsing 2 of 4 Lecture 22. How do we write programs to do this? The process of getting from the input string to the parse tree consists of.
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
Lexical and Syntax Analysis
Top Down Parsing - Part I Comp 412 Copyright 2010, Keith D. Cooper & Linda Torczon, all rights reserved. Students enrolled in Comp 412 at Rice University.
Recursive descent parsing 12-Nov-15. Abstract Syntax Trees (ASTs) An AST is a way of representing a computer program It is abstract because it throws.
CS 153: Concepts of Compiler Design September 16 Class Meeting Department of Computer Science San Jose State University Fall 2015 Instructor: Ron Mak
22-Nov-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
Chapter 4 Top-Down Parsing Recursive-Descent Gang S. Liu College of Computer Science & Technology Harbin Engineering University.
Top-down Parsing lecture slides from C OMP 412 Rice University Houston, Texas, Fall 2001.
More Parsing CPSC 388 Ellen Walker Hiram College.
Top-down Parsing Recursive Descent & LL(1) Comp 412 Copyright 2010, Keith D. Cooper & Linda Torczon, all rights reserved. Students enrolled in Comp 412.
Top-Down Parsing CS 671 January 29, CS 671 – Spring Where Are We? Source code: if (b==0) a = “Hi”; Token Stream: if (b == 0) a = “Hi”; Abstract.
Overview of Previous Lesson(s) Over View  In our compiler model, the parser obtains a string of tokens from the lexical analyzer & verifies that the.
Top-down Parsing. 2 Parsing Techniques Top-down parsers (LL(1), recursive descent) Start at the root of the parse tree and grow toward leaves Pick a production.
CS 330 Programming Languages 09 / 25 / 2007 Instructor: Michael Eckmann.
Parsing III (Top-down parsing: recursive descent & LL(1) )
ADTS, GRAMMARS, PARSING, TREE TRAVERSALS Lecture 13 CS2110 – Spring
CSE 3302 Programming Languages
CS 153: Concepts of Compiler Design September 14 Class Meeting
CS510 Compiler Lecture 4.
Recognizers 13-Sep-18.
Trees.
4 (c) parsing.
Recursive descent parsing
Lexical and Syntax Analysis
Top-Down Parsing CS 671 January 29, 2008.
CSE 3302 Programming Languages
CMPE 152: Compiler Design September 13 Class Meeting
ADTs, Grammars, Parsing, Tree traversals
Recursive descent parsing
Recognizers 1-Jan-19.
Recognizers 16-Jan-19.
Recognizers 22-Feb-19.
Trees.
Chapter 4: Lexical and Syntax Analysis Sangho Ha
The Recursive Descent Algorithm
Recursive descent parsing
High-Level Programming Language
Recursive descent parsing
Chapter 10: Compilers and Language Translation
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Stacks.
COP 4620 / 5625 Programming Language Translation / Compiler Writing Fall 2003 Lecture 2, 09/04/2003 Prof. Roy Levow.
Presentation transcript:

5-Jan-16 Recursive descent parsing

Some notes on recursive descent The starter code that I gave you did not exactly fit the grammar that I gave you Both work, both are correct Many things can be coded either recursively or iteratively I gave you an iterative grammar and recursive code

Recursive rule for ::= public boolean term() { if (!factor()) return false; if (!multiplyOperator()) return true; if (!term()) error("No term after '*' or '/' "); return true; }

Iterative rule for ::= { } public boolean term() { if (!factor()) return false; while (multiplyOperator()) { if (!factor()) error("No factor after '*' or '/' "); } return true; }

Parse trees Every construct (statement, expression, etc.) in a programming language can be represented as a parse tree

Recognizers and parsers A recognizer tells whether a given string “belongs to” (is correctly described by) a grammar A parser uses a grammar to construct a parse tree from a given string One kind of parser is a recursive descent parser Recursive descent parsers have some disadvantages: They are not as fast as some other methods It is difficult to provide really good error messages They cannot do parses that require arbitrarily long lookaheads And some advantages: They are exceptionally simple They can be constructed from recognizers simply by doing some extra work—specifically, building a parse tree Recursive descent parsers are great for “quick and dirty” parsing jobs

The Stack One easy way to do recursive descent parsing is to have each parse method take the tokens it needs, build a parse tree, and put the parse tree on a global stack Write a parse method for each nonterminal in the grammar Each parse method should get the tokens it needs, and only those tokens Those tokens (usually) go on the stack Each parse method may call other parse methods, and expect those methods to leave their results on the stack Each (successful) parse method should leave one result on the stack

Example: while statement ::= “while” The parse method for a while statement: Calls the Tokenizer, which returns a “while” token Makes the “while” into a tree node, which it puts on the stack Calls the parser for, which parses a condition and puts it on the stack Stack now contains: “while” (“top” is on right) Calls the parser for, which parses a block and puts it on the stack Stack now contains: “while” Pops the top three things from the stack, assembles them into a tree, and pushes this tree onto the stack

Recognizing a while statement // ::= “while” private boolean whileStatement() { if (keyword("while")) { if (condition()) { if (block()) { return true; } else error("Missing '{' "); } else error("Missing "); } return false; } Why do you suppose I named this method whileStatement() instead of while() ?

Parsing a while statement // ::= “while” private boolean whileStatement() { if (keyword("while")) { if (condition()) { if (block()) { makeTree(3, 2, 1); return true; } else error("Missing '{' "); } else error("Missing "); } return false; } This code assumes that keyword(String), condition(), and block() all leave their results on a stack On the stack, while = 3, = 2, = 1

Alternative code public boolean whileStatement () { if (keyword("while") && condition() && block()) { makeTree(3, 2, 1); return true; } return false; } No room for an error condition in this code

Alternative code with one message public boolean whileStatement() { if (keyword("while")) { if (condition()) && (block()) { makeTree(3, 2, 1); return true; } error("Error in \"while\" statement"); } return false; }

Simple makeTree() method After recognizing a while loop, the stack looks like this: And I could have written code like this: private void makeTree() { Tree right = stack.pop(); Tree left = stack.pop(); Tree root = stack.pop(); root.addChild(left); root.addChild(right); stack.push(root); } while This code assumes that the root is the third item down, etc., and that isn’t always the case I found it more convenient to write more flexible methods while

More general makeTree method private void makeTree(int keyword, int left, int right) { Tree root = getStackItem(keyword); Tree leftChild = getStackItem(left); Tree rightChild = getStackItem(right); stack.pop(); stack.pop(); stack.pop(); root.addChild(leftChild); root.addChild(rightChild); stack.push(root); }

Parser methods In the BNF, I have one long definition for ::= | "turn" | "take" | "drop"... In my code, I broke that into multiple methods ::= | | |...

My command() method public boolean command() { if (move()) return true; if (turn()) return true; if (take()) return true; if (drop()) return true;... return false; }

Helper methods I wrote a number of helper methods for the Parser and for the ParserTest classes It’s helpful to have methods to build trees quickly and easily private makeTree(String op) private Tree makeTree(String op, Tree left, Tree right) Java 5 allows a variable number of arguments, so you could write private Tree makeTree(String op, Tree... children) Another useful method is assertStackTop, which is just private void assertStackTop(Tree expected) { assertEquals(expected, parser.stack.peek()); } Example: Tree condition = makeTree("=", "2", "2"); assertStackTop(makeTree("if", condition, "list"));

Final comments You are welcome to use any of this code, but......my code is never the last word on anything! Code can always be improved While I think my code is generally useful, you always have to understand it well enough to adapt it to your particular needs

The End