Presentation is loading. Please wait.

Presentation is loading. Please wait.

Recursive Descent Parsing Top-down parsing: build tree from root symbol Each production corresponds to one recursive procedure Each procedure recognizes.

Similar presentations


Presentation on theme: "Recursive Descent Parsing Top-down parsing: build tree from root symbol Each production corresponds to one recursive procedure Each procedure recognizes."— Presentation transcript:

1 Recursive Descent Parsing Top-down parsing: build tree from root symbol Each production corresponds to one recursive procedure Each procedure recognizes an instance of a non-terminal, consumes the corresponding part of the input, and returns tree fragment for the non-terminal

2 General model Each right-hand side of a production provides body for a function Each non-terminal on the rhs is translated into a call to the function that recognizes that non-terminal Each terminal in the rhs is translated into a call to the lexical scanner. Error if the resulting token is not the expected terminal. Each recognizing function returns a tree fragment.

3 Example: parsing a declaration FULL_TYPE_DECLARATION ::= type DEFINING_IDENTIFIER is TYPE_DEFINITION ; Translates into: get token type Find a defining_identifier -- function call get token is Recognize a type_definition -- function call get token semicolon In practice, we already know that the first token is type, that’s why this routine was called in the first place! Predictive parsing is guided by the next token

4 Example: parsing a loop FOR_STATEMENT ::= ITERATION_SCHEME loop STATEMENTS end loop; Node1 := find_iteration_scheme; -- call function get token loop List1 := Sequence of statements -- call function get token end get token loop get token semicolon; Result := build loop_node with Node1 and List1 return Result In case we fail to find any of the expected terminals or one of the called functions returns a failure, this function returns a failure indication.

5 Complications If there are multiple productions for a non- terminal, we need a mechanism to determine which production to use IF_STAT ::= if COND then Stats end if; IF_STAT ::= if COND then Stats ELSIF_PART end if; When next token is if, can’t tell which production to use.

6 Solution: factorize grammar If several productions have the same prefix, rewrite as single production: IF_STAT ::= if COND then STATS [ELSIF_PART] end if; Problem now reduces to recognizing whether an optional Component (ELSIF_PART) is present

7 Illustrate Solution Assume rule IF_STAT ::= if COND then STATS [else STATS] end_if; boolean function get_IF() if Token = if then Scan else return 0; if get_COND() = 0 then return 0; if Token = then then Scan else return 0; if get_STATS() = 0 then return 0; if Token = else then {Scan; if get_STATS() = 0 then return 0} ; if Token = end_if then {Scan; return 1} else return 0 End get_IF

8 Complication: left recursion Grammar cannot be left-recursive: E ::= E + T | T Problem: to find an E, start by finding an E… Original scheme leads to infinite loop: grammar is inappropriate for recursive- descent

9 Eliminating Left Recursion E ::= E + T | T means that eventually E expands into T + T + T …. Rewrite as: E ::= TE’ E’ ::= + TE’ |  Informally: E’ is a possibly empty sequence of terms separated by an operator

10 Recursion can involve multiple Productions A ::= B C | D B ::= A E | F Can be rewritten as: A ::= A E C | F C | D And then apply previous method General algorithm to detect and remove left- recursion from grammar (see ASU)

11 Further complication Transformation does not preserve associativity : E ::= E + T | T Parses a + b + c as (a + b) + c E ::= TE’, E’ ::= + TE’ |  Parses a + b +c as a + (b + c) Incorrect for a - b – c : must rewrite tree In practice, treat as E ::= T {+ T}*

12 In practice: use loop to find sequence of terms Node1 := P_Term; -- call function that recognizes a term loop exit when Token not in Token_Class_Binary_Addop; Node2 := New_Node (P_Binary_Adding_Operator); Scan; -- past operator Set_Left_Opnd (Node2, Node1); Set_Right_Opnd (Node2, P_Term); -- find next term Set_Op_Name (Node2); Node1 := Node2; -- operand for next operation end loop;


Download ppt "Recursive Descent Parsing Top-down parsing: build tree from root symbol Each production corresponds to one recursive procedure Each procedure recognizes."

Similar presentations


Ads by Google