discussion #71/13 discussion #7 recursive descent parsing
Post on 21-Dec-2015
243 views
TRANSCRIPT
Discussion #7 2/13
Topics• Recursive Descent Parsing
– Use tables to build recursive descent parsers– Parse tree construction
• Project #2 Parsing
Discussion #7 3/13
Recursive Descent Parsing• Consider an arbitrary production
S xAySz
and assume x is the current (top symbol), i.e.:
S
x
(xAySz, …)
Discussion #7 4/13
Recursive Descent Parsing (continued…)
• Make a method for S (indeed, for every non-terminal) as follows:– For S xAySz
• Attempt to read an x from the input.
• If success, call method A.
• If success, attempt to read a y from the input.
• If success call method S.
• If success attempt to read a z from the input.
• If success, method S reports success!
– If any of the above attempts fail, report failure.
Discussion #7 5/13
Recursive Descent Parsing (continued…)
• Make a method for S (indeed, for every non-terminal) as follows:– For S xAySz | q
• If x is the current input character then– call method A.
– If success, attempt to read a y from the input.
– If success call method S.
– If success attempt to read a z from the input.
– If success, method S reports success!
• Else if q is the current input character then, report success
• Else report error
Discussion #7 6/13
Recursive Descent Parsing (continued…)
• Output from each syntactical class is a left-child, right-sibling parse tree.
• E OEE produces:
E
O E E
Discussion #7 7/13
Recursive Descent Parsing Example
• Consider our prefix grammar:
E N | OEEO + | | * | /N 0 | 1 | … | 9
• Design a series of recursive methods:
E() to process N or O, E, E
O() to process +, , *, /
N() to process numbers 0 thru 9
Discussion #7 8/13
Data Structure for Parse Tree
class parseTree{… char value parseTree leftChild parseTree rightSibling…};
Discussion #7 9/13
Initialization: Call to Start Symbol
parseTree buildTree() // build parse tree{ … nextChar = readChar() // read 1st character ptree = E() // start syntactic class if (ptree == error) return error if (nextChar) return error // check for string finished return ptree // return the full parse tree}
parseTree E() // syntactic category E{ parseTree ptree,sibling1,sibling2 if (isCharInString(nextChar, "+-*/")) // E -> OEE {FIRST(OEE)} { ptree = O() // Try to recognize O if (ptree == error) return error sibling1 = E() // Try to recognize E if (sibling1 == error) return error sibling2 = E() // Try to recognize E if (sibling2 == error) return error ptree.rightSibling = sibling1 // Success, link O->E->E ptree.rightSibling.rightSibling = sibling2 } else if (isCharInString(nextChar, "0123456789")) // E -> N { ptree = N() // Try to recognize N if (ptree == error) return error } else return error
return new parseTree('E', ptree, null)} Discussion #7 10/13
Method for E
Discussion #7 11/13
Methods for N and OparseTree N() // syntactic category N{ ptree = new parseTree(nextChar, null, null) nextChar = readChar() return new parseTree('N', ptree, null)}
parseTree O() // syntactic category O{ ptree = new parseTree(nextChar, null, null) nextChar = readChar() return new parseTree('O', ptree, null)}
Discussion #7 12/13
Recursive Descent Parser Execution for +*-748/92
E
O
+
E
O
*
E
O
-
E
N
7
E
N
4
E
N
8
E
O
/
E
N
9
E
N
2
+ * - 7 4 8 / 9 2
E
O E E
* N N
2 3
Discussion #7 13/13
ConstructingRecursive Descent Parsers
• Can be applied to almost all grammars.• Required property: By looking at the look-ahead
symbol, we know which production to process next.• Grammars with this single-symbol look-ahead property
are called single-symbol look-ahead grammars.• Alternatives:
– Backtracking– LR(k) k symbol look ahead– Make grammar have single-symbol look ahead.