Bottom-Up Parsing. Parser Generation. LR Parsing. Constructing LR Parser

Similar documents
Parser Generation. Bottom-Up Parsing. Constructing LR Parser. LR Parsing. Construct parse tree bottom-up --- from leaves to the root

LR Parsing Techniques

Bottom-up parsing. Bottom-Up Parsing. Recall. Goal: For a grammar G, withstartsymbols, any string α such that S α is called a sentential form

Context-free grammars

Compiler Construction: Parsing

Section A. A grammar that produces more than one parse tree for some sentences is said to be ambiguous.

LR Parsing Techniques


Principles of Programming Languages

Let us construct the LR(1) items for the grammar given below to construct the LALR parsing table.

Parsing. Handle, viable prefix, items, closures, goto s LR(k): SLR(1), LR(1), LALR(1)

A left-sentential form is a sentential form that occurs in the leftmost derivation of some sentence.

Formal Languages and Compilers Lecture VII Part 4: Syntactic A

Parsing Wrapup. Roadmap (Where are we?) Last lecture Shift-reduce parser LR(1) parsing. This lecture LR(1) parsing

Parsing #1. Leonidas Fegaras. CSE 5317/4305 L3: Parsing #1 1

MODULE 14 SLR PARSER LR(0) ITEMS

CSE 401 Compilers. LR Parsing Hal Perkins Autumn /10/ Hal Perkins & UW CSE D-1

CSE P 501 Compilers. LR Parsing Hal Perkins Spring UW CSE P 501 Spring 2018 D-1

3. Syntax Analysis. Andrea Polini. Formal Languages and Compilers Master in Computer Science University of Camerino

Principle of Compilers Lecture IV Part 4: Syntactic Analysis. Alessandro Artale

S Y N T A X A N A L Y S I S LR

Formal Languages and Compilers Lecture VII Part 3: Syntactic A

Chapter 3. Parsing #1

PART 3 - SYNTAX ANALYSIS. F. Wotawa TU Graz) Compiler Construction Summer term / 309

LALR Parsing. What Yacc and most compilers employ.

CSCI312 Principles of Programming Languages


Parsing III. CS434 Lecture 8 Spring 2005 Department of Computer Science University of Alabama Joel Jones

Table-driven using an explicit stack (no recursion!). Stack can be viewed as containing both terminals and non-terminals.

LR Parsing, Part 2. Constructing Parse Tables. An NFA Recognizing Viable Prefixes. Computing the Closure. GOTO Function and DFA States

Monday, September 13, Parsers

CSC 4181 Compiler Construction. Parsing. Outline. Introduction

shift-reduce parsing

MIT Parse Table Construction. Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology

Bottom up parsing. The sentential forms happen to be a right most derivation in the reverse order. S a A B e a A d e. a A d e a A B e S.

Parsing III. (Top-down parsing: recursive descent & LL(1) )

Note that for recursive descent to work, if A ::= B1 B2 is a grammar rule we need First k (B1) disjoint from First k (B2).

Syntax Analysis. Martin Sulzmann. Martin Sulzmann Syntax Analysis 1 / 38

Syntactic Analysis. Top-Down Parsing

LR Parsers. Aditi Raste, CCOEW

Types of parsing. CMSC 430 Lecture 4, Page 1

Parsing. Roadmap. > Context-free grammars > Derivations and precedence > Top-down parsing > Left-recursion > Look-ahead > Table-driven parsing

Bottom-Up Parsing. Lecture 11-12

Compiler Construction 2016/2017 Syntax Analysis

Chapter 4: LR Parsing

CA Compiler Construction

UNIT-III BOTTOM-UP PARSING

Compiler Design 1. Bottom-UP Parsing. Goutam Biswas. Lect 6

UNIT III & IV. Bottom up parsing

Syntax Analysis. Amitabha Sanyal. ( as) Department of Computer Science and Engineering, Indian Institute of Technology, Bombay

EDAN65: Compilers, Lecture 06 A LR parsing. Görel Hedin Revised:

CS1622. Today. A Recursive Descent Parser. Preliminaries. Lecture 9 Parsing (4)

Wednesday, September 9, 15. Parsers

Parsers. What is a parser. Languages. Agenda. Terminology. Languages. A parser has two jobs:

Concepts Introduced in Chapter 4

Top-Down Parsing and Intro to Bottom-Up Parsing. Lecture 7

Wednesday, August 31, Parsers

Compilers. Bottom-up Parsing. (original slides by Sam

CS308 Compiler Principles Syntax Analyzer Li Jiang

Parsers. Xiaokang Qiu Purdue University. August 31, 2018 ECE 468

Chapter 4. Lexical and Syntax Analysis. Topics. Compilation. Language Implementation. Issues in Lexical and Syntax Analysis.

Chapter 4. Lexical and Syntax Analysis

In One Slide. Outline. LR Parsing. Table Construction

Syntax Analysis, III Comp 412

Introduction to Parsing. Comp 412

Parsing. Note by Baris Aktemur: Our slides are adapted from Cooper and Torczon s slides that they prepared for COMP 412 at Rice.

Conflicts in LR Parsing and More LR Parsing Types

LR Parsing LALR Parser Generators

Compilers. Yannis Smaragdakis, U. Athens (original slides by Sam

Parsing II Top-down parsing. Comp 412

Lecture 7: Deterministic Bottom-Up Parsing

Top-Down Parsing and Intro to Bottom-Up Parsing. Lecture 7

Simple LR (SLR) LR(0) Drawbacks LR(1) SLR Parse. LR(1) Start State and Reduce. LR(1) Items 10/3/2012

Review: Shift-Reduce Parsing. Bottom-up parsing uses two actions: Bottom-Up Parsing II. Shift ABC xyz ABCx yz. Lecture 8. Reduce Cbxy ijk CbA ijk

Syntax Analysis: Context-free Grammars, Pushdown Automata and Parsing Part - 4. Y.N. Srikant

4. Lexical and Syntax Analysis

Bottom-Up Parsing II. Lecture 8

3. Parsing. Oscar Nierstrasz

Lecture 8: Deterministic Bottom-Up Parsing

Syntax Analysis, III Comp 412

4. Lexical and Syntax Analysis

Bottom-Up Parsing II (Different types of Shift-Reduce Conflicts) Lecture 10. Prof. Aiken (Modified by Professor Vijay Ganesh.

Bottom-Up Parsing LR Parsing

Lexical and Syntax Analysis (2)

LR Parsing LALR Parser Generators

Bottom Up Parsing. Shift and Reduce. Sentential Form. Handle. Parse Tree. Bottom Up Parsing 9/26/2012. Also known as Shift-Reduce parsing

CS 406/534 Compiler Construction Parsing Part I

Syn S t yn a t x a Ana x lysi y s si 1

Bottom-Up Parsing. Lecture 11-12

Compilerconstructie. najaar Rudy van Vliet kamer 140 Snellius, tel rvvliet(at)liacs(dot)nl. college 3, vrijdag 22 september 2017

CSE 130 Programming Language Principles & Paradigms Lecture # 5. Chapter 4 Lexical and Syntax Analysis

Parsing Part II (Top-down parsing, left-recursion removal)

Parsing Techniques. CS152. Chris Pollett. Sep. 24, 2008.

LL(k) Parsing. Predictive Parsers. LL(k) Parser Structure. Sample Parse Table. LL(1) Parsing Algorithm. Push RHS in Reverse Order 10/17/2012

8 Parsing. Parsing. Top Down Parsing Methods. Parsing complexity. Top down vs. bottom up parsing. Top down vs. bottom up parsing

Syntax-Directed Translation

The Parsing Problem (cont d) Recursive-Descent Parsing. Recursive-Descent Parsing (cont d) ICOM 4036 Programming Languages. The Complexity of Parsing

Syntax Analysis. Tokens ---> Parse Tree. Main Problems. Grammars. Convert the list of tokens into a parse tree ( hierarchical analysis)

Syntax Analysis Part I

CSE431 Translation of Computer Languages

Transcription:

Parser Generation Main Problem: given a grammar G, how to build a top-down parser or a bottom-up parser for it? parser : a program that, given a sentence, reconstructs a derivation for that sentence ---- if done sucessfully, it recognize the sentence all parsers read their input left-to-right, but construct parse tree differently. bottom-up parsers --- construct the tree from leaves to root Bottom-Up Parsing Construct parse tree bottom-up --- from leaves to the root Bottom-up parsing always constructs right-most derivation Important parsing algorithms: shift-reduce, LR parsing LR parser components: input, stack (strings of grammar symbols and states), driver routine, parsing tables. input: a 1 a 2 a 3 a 4... a n $ shift-reduce, LR, LR, LLR, operator precedence top-down parsers --- construct the tree from root to leaves recursive descent, predictive parsing, LL(1) stack s m X m.. s 1 X 1 s 0 LR Parsing parsing output Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 1 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 2 of 27 LR Parsing sequence of new state symbols s 0, s 1, s 2,..., s m ----- each state sumarize the information contained in the stack below it. Parsing configurations: (stack, remaining input) written as (s 0 X 1 s 1 X 2 s 2...X m s m, a i a i+1 a i+2...a n $) next move is determined by s m and a i Parsing tables: CTION[s,a] and GOTO[s,X] Table CTION[s,a] --- s : state, a : terminal its entries (1) shift s k (2) reduce -> (3) accept (4) error Table G GOTO[s,X] --- s : state, X : non-terminal its entries are states Constructing LR Parser How to construct the parsing table CTION and GOTO? basic idea: first construct DF to recognize handles, then use DF to construct the parsing tables! different parsing table yield different LR parsers LR(1), LR(1), or LLR(1) augmented grammar for context-free grammar G = G(T,N,P,) is defined as G = G (T, N { }, P { -> }, ) ------ adding non-terminal and the production ->, and is the new start symbol. When -> is reduced, parser accepts. LR(0) item for productions of a context-free grammar G ----- is a production with dot at some position in the r.h.s. For -> XYZ, its items are ->.XYZ -> X.YZ -> XY.Z -> XYZ. For ->, its items are just ->. Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 3 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 4 of 27

LR(0) items and LR(0) DF Informally, item -> X.YZ means a string derivable from X has been seen, and one from YZ is expected. LR(0) items are used as state names for LR(0) DF or LR(0) NF that recognizes viable prefixes. Viable prefixes of a CFG are prefixes of right-sentential forms with no symbols to right of the handle; we can always add terminals on right to form a rightsentential form. Two way to construct the LR(0) DF: 1. first construct LR(0) NF and then convert it to a DF! 2. construct the LR(0) DF directly! From LR(0) DF to the Parsing Table -------- transition table for the DF is the GOTO table; the states of DF are states of the parser. Example: LR(0) Items CFG Grammar: E -> E + T T T -> T * F F ugmented Grammar: LR(0) terms: E -> E E -> E + T T T -> T * F F E ->. E T ->. T * F F -> ( E. ) E -> E. T -> T. * F F -> ( E ). E ->. E + T T -> T *. F F ->. id E -> E. + T T -> T * F. F -> id. E -> E +. T T ->. F E -> E + T. T -> F. E ->. T F ->. ( E ) E -> T. F -> (. E ) Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 5 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 6 of 27 From LR(0) NF to LR(0) DF Construct LR(0) NF with all LR(0) items of G as states, connect states by moving the dot; final states are those with dots at the end. 1. for each item ->.X ->.X -> X. 2. for each pair ->.B, B ->. (expect to see a string derivable from ) ->.B B ->. Convert NF to DF using subset construction algorithm. The states of the resulting LR(0) DF --- C = {I 1,I 2,..., I n } are called canonical LR(0) collection for grammar G Disadvantage: the NF is often huge, and converting from NF to DF is tedious and time-consuming. X Building LR(0) DF Directly Instead of building DF from NF, we can build the LR(0) DF directly. Given a set of LR(0) items I, CLOURE(I) is defined as for each item ->.B in I and each production B -> add B ->. to I, if it s not in I until I does not change GOTO(I,X) is defined as CLOURE(all items -> X. for each ->.X in I) Canonical LR(0) collection is computed by the following procedure: I 0 = CLOURE({ ->.}) and C = {I 0 } for each I C and grammar symbol X T = GOTO(I,X); if T and T C then C = C { T }; until C does not change Resulting LR(0) DF: C is the set of states; GOTO is the transition table Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 7 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 8 of 27

Constructing LR(1) Parsing Table From the LR(0) DF, we can construct the parsing table ----- LR(1) parsing table. The parser based on LR(1) parsing table is called LR(1) parser. The LR(1) grammars are those whose LR(1) parsing table does not contain any conflicts. lgorithm --- use C = {I 0,...,I n }, GOTO, FOLLOW: 1. If -> a.a is in I i and GOTO(I i,a) = I j where a is a terminal, set CTION[i,a] to shift j. 2. If ->. is in I i, set CTION[i,a] to reduce -> for all terminal a in FOLLOW(). 3. If ->. is in I i, set CTION[ i,$] to accept 4. If GOTO(I i,) = I j, set GOTO[i,] = j 5. set all other entries to error 6. set initial state to be I i with ->. Limitation of LR(1) Parser Unfortunately, many unambiguous grammars are not LR(1) gammars -> L = R R L -> *R id R -> L Canonical LR(0) collection --- L means l-value R means r-value * means contents of I0 : ->. I3: -> R. I6: -> L=.R ->.L=R R ->.L ->.R I4: L -> *.R L ->.*R L ->.*R R ->.L L ->.id L ->.id L ->.*R R ->.L L ->.id I7: L -> *R. I1 : ->. I5: L -> id. I8: R -> L. I2 : -> L.=R I9: -> L=R. R -> L. FOLLOW(R) = {=,...} state 2 has a shift/reduce conflict on = : shift 6 or reduce R -> L Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 9 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 10 of 27 LR(1) Parsing Conflict arises because LR(0) states do not encode enough left context --- in the previous example, reduction R -> L is wrong upon input = because R =... never appears in right-sentential form. olution: split LR(0) states by adding terminals to states, for example, [ - >., a] results in reduction only if next symbol is a. n LR(1) term is in the form of [ ->., a ] where -> is a production and a is a terminal or $ To build LR(1) parsing table --- we first build LR(1) DF --- then construct the parsing table using the same LR(1) algorithm except 2. only if [ ->., a] is in I i, then set CTION[i,a] to reduce -> To way to build LR(1) DF ---- from NF -> DF or build DF directly Building LR(1) DF Construct LR(1) NF with all LR(1) items of G as states, connect states by moving the dot; then convert the NF to DF. 1. for each item [ ->.X,a] Construct the LR(1) DF directly (see the Dragon book) Given a set of LR(1) items I, ->.X a 2. for each pair [ ->.B, a] B ->. and b in FIRT( a ). ->.B a CLOURE(I) is now defined as for each item [ ->.B, a] in I and each production B -> and each terminal b in FIRT( a) add [B ->. a] to I, if it s not in I until I does not change X -> X. a B ->. b Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 11 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 12 of 27

Constructing LR(1) Parser Canonical LR(1) collection is computed by the following procedure: I 0 = CLOURE([ ->., $]) and C = {I 0 } for each I C and grammar symbol X T = GOTO(I,X); if T and T C then C = C { T }; until C does not change Resulting LR(1) DF: C is the set of states; GOTO is the transition table From the LR(1) DF, we can construct the parsing table ----- LR(1) parsing table. The parser based on LR(1) parsing table is called LR(1) parser. The LR(1) grammars are those whose LR(1) parsing table does not contain any conflicts (no duplicate entries). Example: -> -> C C C -> c C d LLR(1) Parsing Bad News: LR(1) parsing tables are too big; for PCL, LR tables has about 100 states, LR table has about 1000 states. LLR (Lookhead-LR) parsing tables have same number of states as LR, but use lookahead for reductions. The LLR(1) DF can be constructed from the LR(1) DF. LLR(1) states can be constructed from LR(1) states by merging states with same core, or same LR(0) items, and union their lookahead sets. Merging I8: C -> cc., c/d I9: C -> cc., $ into a new state I89: C -> cc., c/d/$ Merging I3: C -> c.c, c/d I6: C -> c.c, $ C ->.cc, c/d C ->.cc, $ C ->.d, c/d C ->.d, $ into a new state I36: C -> c.c, c/d/$ C ->.cc, c/d/$ C ->.d, c/d/$i Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 13 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 14 of 27 LLR(1) Parsing (cont d) From the LLR(1) DF, we can construct the parsing table ----- LLR(1) parsing table. The parser based on LLR(1) parsing table is called LLR(1) parser. The LLR(1) grammars are those whose LLR(1) parsing table does not contain any conflicts (no duplicate entries). LLR(1) DF and LLR(1) parsing table can be constructed without creating LR(1) DF --- see Dragon book for detailed algorithm. LLR parser makes same number of moves as LR parser on correct input. On incorrect input, LLR parser may make erroneous reductions, but will signal error before shifting input, i.e., merging states makes reduce determination less accurate, but has no effect on shift actions. ummary: LR Parser Relation of three LR parsers: LR(1) > LLR(1) > LR(1) Most programming language constructs are LLR(1). The LR(1) is unnecessary in practice, but the LR(1) is not enough. YCC is an LLR(1) Parser Generator. When parsing ambiguious grammars using LR parsers, the parsing table will contain multiple entries. We can specify the precedence and associativity for terminals and productions to resolve the conflicts. YCC uses this trick. Other Issues in parser implementation: 1. compact representation of parsing table 2. error recovery and diagnosis. Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 15 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 16 of 27

Top-Down Parsing tarting from the start symbol and guessing which production to use next step. It often uses next input token to guide guessing. example: -> c d -> ab a Top-Down Parsing (cont d) Typical implementation is to write a recursive procedure for each non-terminal (according to the r.h.s. of each grammar rule) advance sets c to next input token Grammar: err reports error message input symbols: cad we are looking ahead only one at a time! c c matches d c a try to decide which rule of to use here? b d decide to use 1st alternative of c backtrack! a d guessed wrong, backtrack and try another one! E -> T E E -> + T E T -> F T T -> * F T F -> id ( E ) fun e() = (t(); eprime()) and eprime() = if (c = + ) then (advance(); t(); eprime()) and t() = (f(); tprime()) and tprime() = if (c = * ) then (advance(); f(); tprime()) and f() = (if (c = id) then advance() else if (c = ( ) then (advance(); e(); if (c= ) ) then advance() else err()) else err() Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 17 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 18 of 27 Recursive Descent Parsing The previously referred top-down parsing method is often called recursive descent parsing! Main challenges: 1. back-tracking is messy, difficult and inefficient (solution: use input lookahead to help make the right choice) 2. more alternatives --- even if we use one lookahead input char, there are still > 1 rules to choose --- -> ab a (solution: rewrite the grammar by left-factoring) 3. left-recursion might cause infinite loop what is the procedure for E -> E + E? (solution: rewrite the grammar by eliminating left-recursions) 4. error handling --- errors detected far away from actual source. lgorithm: Recursive Descent Parsing lgorithm (using 1-symbol lookahead in the input) 1. Given a set of grammar rules for a non-terminal -> 1 2... n we choose proper alternative by looking at first symbol it derives ---- next input symbol decides which i we use 2. for ->, it is taken when none of the others are selected lgorithm: constructing a recursive descent parser for grammar G 1. transform grammer G to G by removing left-recursions and do the leftfactoring. 2. write a (recursive) procedure for each non-terminal in G the Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 19 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 20 of 27

Left Recursion Elimination Elimination of Left Recursion (useful for top-down parsing only) replace productions of the form with Important: read ppel pp 51-53 for details -> -> -> (yields different parse trees but same language) example: E -> E + T T T -> T * F F become E -> T E E -> + T E T -> F T T -> * F T Left Factoring ome grammars are unsuitable for recursive descent, even if there is no left recursion dangling-else stmt -> if expr then stmt if expr then stmt else stmt... input symbol if does not uniquely determine alternative. Left Factoring --- factor out the common prefixes (see HU pp 178) change the production -> x y x z to -> x -> y z thus stmt -> if expr then stmt -> else stmt Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 21 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 22 of 27 Predictive Parsing Predictive parsing is just table-driven recursive descent; it contains: parsing stack --- contains terminals and non-terminals parsing table : a 2-dimensional table M[X,a] where X is non-terminal, a is terminal, and table entries are grammar productions or error indicators. algorithm $ is end-of-file, is start symbol push($); push(); while top <> $ do ( a <- the input char if top is a terminal or $ then (if top == a then pop(); advance() else err()) else if M[top,a] is X->Y 1 Y 2...Y k then (pop(); push(y k );...; push(y 1 )) else err() ) input: X... Y Z $ stack a 1 a 2 a 3 a 4... a n $ Predictive Parser Parsing Table M output Constructing Predictive Parser The key is to build the parse table M[,a] for each production -> do for each a FIRT( ) do add -> to M[,a] if FIRT( ) then for each b FOLLOW() do add -> to M[,b] rest of M is error FIRT( ) is a set of terminals (plus ) that begin strings derived from, where is any string of non-terminals and terminals. FOLLOW() is a set of terminals that can follow in a sentential form, where is any non-terminal Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 23 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 24 of 27

First & Follow To compute FIRT(X) for any grammar symbol X : FIRT(X) = {X}, if X is a terminal; FIRT(X) = FIRT(X) {a}, if X -> a ; FIRT(X) = FIRT(X) { }, if X -> ; and FIRT(X) = FIRT(X) FIRT(Y 1 Y 2...Y k ), if X -> Y 1 Y 2...Y k. until nothing new is added to any FIRT FIRT(Y 1 Y 2...Y k ) = FIRT(Y 1 )-{ } FIRT(Y 2 )-{ } if FIRT(Y 1 ) FIRT(Y 3 )-{ } if FIRT(Y 1 Y 2 )... FIRT(Y k )-{ } if FIRT(Y 1...Y k-1 ) { } if all FIRT(Y i ) (i=1,...,k) contain First & Follow (cont d) To compute FOLLOW(X) for any non-terminal X : FOLLOW() = FOLLOW() {$}, if is start symbol; FOLLOW(B) = FOLLOW(B) (FIRT( ) - { }), if -> B and FOLLOW(B) = FOLLOW(B) FOLLOW() if -> B or -> B and FIRT( ) Example: reason FOLLOW(E) = {$}, E is start symbol = {$ )}, F -> ( E ) FOLLOW(E )= FOLLOW(E) E -> T E = {$ )}, (Read ppel pp 47-53 for detailed examples) Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 25 of 27 Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 26 of 27 ummary: LL(1) Grammars grammar is LL(1) if parsing table M[,a] has no duplicate entries, which is equivalent to specifying that for each production 1. ll FIRT( i ) are disjoint. -> 1 2... n 2. t most one i can derive ; in that case, FOLLOW() must be disjoint from FIRT( 1 ) FIRT( 2 ) FIRT( n ) Left-recursion and ambiguity grammar lead to multiple entries in the parsing table. (try the dangling-else example) The main difficulty in using (top-down) predicative parsing is in rewriting a grammar into an LL(1) grammar. There is no general rule on how to resolve multiple entries in the parsing table. Copyright 1994-2014 Zhong hao, Yale University Parser Generation: Page 27 of 27