Chapter 4 Grammars and Parsing Prof Chung. 1 2008/03/18.

Slides:



Advertisements
Similar presentations
First Set First (  =A  ) = First(A), if ∉ First(A) First(A) – { } ∪ First(  ), if ∈ First(A) We will use some examples for this operation… Red : A Blue.
Advertisements

1 Parsing The scanner recognizes words The parser recognizes syntactic units Parser operations: Check and verify syntax based on specified syntax rules.
Context-Free Grammars
Lecture # 11 Grammar Problems.
CS5371 Theory of Computation
1 Chapter 5: Bottom-Up Parsing (Shift-Reduce). 2 - attempts to construct a parse tree for an input string beginning at the leaves (the bottom) and working.
Chapter 4 Lexical and Syntax Analysis Sections 1-4.
Chapter 3 Describing Syntax and Semantics Sections 1-3.
Context-Free Grammars Lecture 7
Parsing III (Eliminating left recursion, recursive descent parsing)
Chapter 3 Describing Syntax and Semantics Sections 1-3.
Parsing — Part II (Ambiguity, Top-down parsing, Left-recursion Removal)
Chapter 3 Describing Syntax and Semantics Sections 1-3.
1 The Parser Its job: –Check and verify syntax based on specified syntax rules –Report errors –Build IR Good news –the process can be automated.
LR(1) Languages An Introduction Professor Yihjia Tsai Tamkang University.
COP4020 Programming Languages
1 Chapter 3 Context-Free Grammars and Parsing. 2 Parsing: Syntax Analysis decides which part of the incoming token stream should be grouped together.
1 Contents Introduction Introduction A Simple Compiler A Simple Compiler Scanning – Theory and Practice Scanning – Theory and Practice Grammars and Parsing.
Chapter 3 Chang Chi-Chung Parse tree intermediate representation The Role of the Parser Lexical Analyzer Parser Source Program Token Symbol.
(2.1) Grammars  Definitions  Grammars  Backus-Naur Form  Derivation – terminology – trees  Grammars and ambiguity  Simple example  Grammar hierarchies.
EECS 6083 Intro to Parsing Context Free Grammars
CSC3315 (Spring 2009)1 CSC 3315 Lexical and Syntax Analysis Hamid Harroud School of Science and Engineering, Akhawayn University
1 Syntax and Semantics The Purpose of Syntax Problem of Describing Syntax Formal Methods of Describing Syntax Derivations and Parse Trees Sebesta Chapter.
1 Introduction to Parsing Lecture 5. 2 Outline Regular languages revisited Parser overview Context-free grammars (CFG’s) Derivations.
Formal Grammars Denning, Sections 3.3 to 3.6. Formal Grammar, Defined A formal grammar G is a four-tuple G = (N,T,P,  ), where N is a finite nonempty.
CPSC 388 – Compiler Design and Construction Parsers – Context Free Grammars.
Chapter 9 Syntax Analysis Winter 2007 SEG2101 Chapter 9.
1 Chapter 5 LL (1) Grammars and Parsers. 2 Naming of parsing techniques The way to parse token sequence L: Leftmost R: Righmost Top-down  LL Bottom-up.
BİL 744 Derleyici Gerçekleştirimi (Compiler Design)1 Syntax Analyzer Syntax Analyzer creates the syntactic structure of the given source program. This.
Context-Free Grammars
PART I: overview material
1 Syntax In Text: Chapter 3. 2 Chapter 3: Syntax and Semantics Outline Syntax: Recognizer vs. generator BNF EBNF.
1 Chapter 4 Grammars and Parsing. 2 Context-Free Grammars: Concepts and Notation A context-free grammar G = (Vt, Vn, S, P) –A finite terminal vocabulary.
C Chuen-Liang Chen, NTUCS&IE / 51 CONTEXT-FREE GRAMMARS Chuen-Liang Chen Department of Computer Science and Information Engineering National Taiwan University.
11 Chapter 4 Grammars and Parsing Grammar Grammars, or more precisely, context-free grammars, are the formalism for describing the structure of.
Parsing Introduction Syntactic Analysis I. Parsing Introduction 2 The Role of the Parser The Syntactic Analyzer, or Parser, is the heart of the front.
Bernd Fischer RW713: Compiler and Software Language Engineering.
CFG1 CSC 4181Compiler Construction Context-Free Grammars Using grammars in parsers.
Introduction to Parsing
Chap. 4, Formal Grammars and Parsing J. H. Wang Oct. 19, 2015.
ISBN Chapter 3 Describing Syntax and Semantics.
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.
Syntax Analysis - Parsing Compiler Design Lecture (01/28/98) Computer Science Rensselaer Polytechnic.
Re-enter Chomsky More about grammars. 2 Parse trees S  A B A  aA | a B  bB | b Consider L = { a m b n | m, n > 0 } (one/more a ’s followed by one/more.
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.
Unit-3 Parsing Theory (Syntax Analyzer) PREPARED BY: PROF. HARISH I RATHOD COMPUTER ENGINEERING DEPARTMENT GUJARAT POWER ENGINEERING & RESEARCH INSTITUTE.
Chapter 3 Context-Free Grammars Dr. Frank Lee. 3.1 CFG Definition The next phase of compilation after lexical analysis is syntax analysis. This phase.
Syntax Analyzer (Parser)
1 Pertemuan 7 & 8 Syntax Analysis (Parsing) Matakuliah: T0174 / Teknik Kompilasi Tahun: 2005 Versi: 1/6.
CSE 5317/4305 L3: Parsing #11 Parsing #1 Leonidas Fegaras.
Programming Languages and Design Lecture 2 Syntax Specifications of Programming Languages Instructor: Li Ma Department of Computer Science Texas Southern.
1 Topic #4: Syntactic Analysis (Parsing) CSC 338 – Compiler Design and implementation Dr. Mohamed Ben Othman ( )
Lecture # 10 Grammar Problems. Problems with grammar Ambiguity Left Recursion Left Factoring Removal of Useless Symbols These can create problems for.
Syntax Analysis By Noor Dhia Syntax analysis:- Syntax analysis or parsing is the most important phase of a compiler. The syntax analyzer considers.
Compiler Chapter 5. Context-free Grammar Dept. of Computer Engineering, Hansung University, Sung-Dong Kim.
1 Context-Free Languages & Grammars (CFLs & CFGs) Reading: Chapter 5.
lec02-parserCFG May 8, 2018 Syntax Analyzer
Introduction to Parsing
Programming Languages Translator
CS510 Compiler Lecture 4.
Chapter 3 Context-Free Grammar and Parsing
Introduction to Parsing (adapted from CS 164 at Berkeley)
Compiler Construction
CS 363 Comparative Programming Languages
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Context-Free Grammars
lec02-parserCFG May 27, 2019 Syntax Analyzer
COMPILER CONSTRUCTION
Presentation transcript:

Chapter 4 Grammars and Parsing Prof Chung /03/18

Outlines 2  Context-Free Grammars Context-Free Grammars  Errors in Context-Free Grammars Errors in Context-Free Grammars  Transforming Extended BNF Grammars Transforming Extended BNF Grammars  Parsers and Recognizers Parsers and Recognizers  Grammar Analysis Algorithms Grammar Analysis Algorithms

Context-Free Grammars: (1) Concepts and Notation  A context-free grammar G = (Vt, Vn, S, P)  A finite terminal vocabulary Vt  The token set produced by scanner  A finite set of nonterminal vocabulary Vn  Intermediate symbols 3 Denote symbols in Vt : a,b,c Denote symbols in Vn : A,B,C

Context-Free Grammars: (2) Concepts and Notation  A context-free grammar G = (Vt, Vn, S, P)  A start symbol S  Vn that starts all derivations  Also called goal symbol  P, a finite set of productions (rewriting rules) of the form A  X 1 X 2  X m  A  Vn, X i  Vn  Vt, 1  i  m  A  is a valid production 4

Context-Free Grammars: (3) Concepts and Notation  Other notations  Vocabulary V of G,  V= Vn  Vt  L(G), the set of string s derivable from S  Context-free language of grammar G  Notational conventions  Denote symbols in V : U,V,W,   Denote strings in V * : , , ,   Denote strings in V t * : u,v,w,  5

Context-Free Grammars: (4) Concepts and Notation  Derivation  One step derivation  If A , then  A   One or more steps derivation    Zero or more steps derivation    If S   , then  is said to be sentential form of the CFG  SF(G) is the set of sentential forms of grammar G  L(G) = {x  V t * |S   x}  L(G)=SF(G)  V t * 6

Context-Free Grammars: (5) Concepts and Notation  Left-most derivation  top-down parsers 【   lm ,   lm ,  lm  】  E.g. of leftmost derivation of F(V+V)  Right-most derivation (canonical derivation)  Buttom-up parsers 【   rm ,   rm ,  rm  】  E.g. of rightmost derivation of F(V+V) 7 E  lm Prefix(E)  lm F(E)  lm F(V Tail)  lm F(V+E)  lm F(V+V Tail)  lm F(V+V) E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 E  rm Prefix(E)  rm Prefix(V Tail)  rm Prefix(V+E)  rm Prefix(V+V Tail)  rm Prefix(V+V)  rm F(V+V) Same # of steps, but different order

Context-Free Grammars: (6) Concepts and Notation  A parse tree  rooted by the start symbol  Its leaves are grammar symbols or  A phase at next page… 8

Context-Free Grammars: (6) Concepts and Notation  Phrase  A phrase of a sentential form  is a sequence of symbols descended from a single non-terminal in the parse tree  Simple or prime phrase  is a phrase that contains no smaller phrase  Simple phrase  is a sequence of symbols directly derived from a non-terminal  Handle  The handle of a sentential form  is the left-most simple phrase  Simple phrases cannot overlap, so “leftmost” is unambiguous  Handles are important  because they represent individual derivation steps, which can be recognized by various parsing techniques. 9 Sentential Form : F(V Tail) Simple Phrases : F,VTail Handle : F Example

Context-Free Grammars: (7) Concepts and Notation  Regular grammars  Limited to productions of the form  The handle of a sentential form is the left-most simple phrase  Context-sensitive grammars  Require that nonterminals be rewritten only when they appear in a particular context.  Type-0 grammars  Still more general and allow arbitrary patterns to be rewritten.  Context-sensitive and Type-0 grammars are more powerful than CFGs, but less useful.  This is that efficient parsers for these extended grammar classes do not exist,  Without a parser there is no way to use a grammar definition to drive a compiler.  CFGs represent a nice balance between generality and practicality. 10 A  aB C  A  aB C  Rule : α A β  α δ β Rule : α  β

Errors in Context-Free Grammars (1)  Ambiguous  Grammars that allow different parse trees for the same terminal string 11 Equal ?

Errors in Context-Free Grammars (2)  “Useless nonterminals ”  Is unreachable or derive no terminal string are termed useless.  Can be safely removed from a grammar without changing the defined by the grammar.  A grammar containing useless nonterminals is said to be nonreduced.  After useless nonterminals are removed, the grammar is reduced.  Example :  In G 1, nonterminal C cannot be reached from S.  In G 1, nonterminal B derives no terminal string. 12 S  A | B A  a B  Bb C  c G1G1 S  A A  a G1G1 Reduced

 It is impossible to do :  Decide whether a given CFG is ambiguous  Analyze Wrong language  Production Exception  No general comparison algorithm applicable to all CFGs Errors in Context-Free Grammars (3) 13

Transforming Extened BNF Grammars  Extended BNF  BNF  Extended BNF allows  Square bracket [ ]  Optional list { } for (each production P=A  α [X 1 …X n ] β ) { Create a new nonterminal, N. Replace production P with p’ = A  α N β Add the productions: N  X 1 … Xn and N  } for (each production Q=B  γ {Y1…Ym} δ ) { Create a new nonterminal, M. Replace production Q with Q’ = B  γ M δ Add the productions: M  Y 1 … Y m M and M  } Algorithm to Transform Extended BNF Grammars into Standard Form 14  ID {, ID } ’  ID M M , ID M M   ID [ ID 1 ID 2 ] ’  ID N N , ID 1 ID 2 N 

Parsers and Recognizers (1)  Recognizer  An algorithm that does boolean-valued test  “Is this input syntactically valid?  Parser  Answers more general questions  Is this input valid?  And, if it is, what is its structure (parse tree)? 15

Parsers and Recognizers (2)  Two general approaches to parsing  Top-down parser  Expanding the parse tree (via predictions) in a depth-first manner  Preorder traversal of the parse tree  Predictive in nature  LL (lm)  Buttom-down parser  Beginning at its bottom (the leaves of the tree, which are terminal symbols) and determining the productions used to generate the leaves  Post-order traversal of the parse tree  LR (rm) 16

Parsers and Recognizers (3)  Naming of parsing techniques Top-down  LL Bottom-up  LR 17 The way to parse token sequence L: Leftmost R: Righmost

Grammar Analysis Algorithms (1)  Goal of this section  Discuss a number of important analysis algorithms for Grammars 18 typedef struct gram { symbol terminals[NUM_TERMINALS]; symbol nonterminals[NUM_NONTERMINIALS]; symbol start_symbol; int num-productions; struct prod { symbol lhs; int rhs_length; symbol rhs[MAX_RHS_LENGTH]; } produtcions[NUM_PRODUCTIONS]; symbol vocabulary[VOCABULARY]; } grammar; typedef struct prod production; typedef symbol terminal; typedef symbol nonterminal;

Grammar Analysis Algorithms (2)  What nonterminals can derive ?  Ex : A  BCD  BC  B   An iterative marking algorithm 19 Marked_vocabulary mark_lambda(const grammar g) { Step 1 : Initialize Step 2 : Nonterminals that derive trivially are marked. Step 3 : Nonterminals requiring a parse tree height of two are found. Step 4 : Continue finding nonterminals requiring parse trees of ever-increasing height, until no more nonterminals can be marked as deriving. } Source Code in Next page. 【 Cause & GOAL 】 Determining if a nonterminal can derive is not entirely trivial because the derivation may take more than one step.

Grammar Analysis Algorithms (3) typedef short boolean; typedef boolean marked_vocabulary[VOCABULARY]; /* Mark those vocabulary symbols found to derive (directly or indirectly). */ Marked_vocabulary mark_lambda(const grammar g) { …….……………………………………………………………………. for(v=0; v<VOCABBULARY; v++) derives_lambda[v] = FALSE; /* initially, nothing is marked */ do { changes = FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; if( !derives_lambda[p.lhs]) { if(p.rhs_length ==0) { /*derives directly */ changes = derives_lambda[p.lhs] = TRUE; continue; } /* does each part of RHS derive ? */ rhs_derives_lambda = derives_lambda[p.rhs[0]]; for(j=1;j<p.rhs_length;j++) rhs_derives_lambda = rhs_derives_lambda && deroves_lambda[p.rhs[j]]; if(rhs_derives_lambda) { changes =TRUE; derives_lambda[p.lhs] =TRUE; } }while (changes); return derives_lambda; } 20 static marked_vocabulary derives_lambda; boolean changes; /* any changes during last iteration? */ boolean rhs_derives_lambda; /* does the RHS derive ? */ symbol v; /* a word in vocabulary */ production p; /* a production in the grammar */ int i,j; /* loop variables */ More Example at next page…

Grammar Analysis Algorithms (4)  Definition of C data structures and subroutines  first_set[X]  contains terminal symbols and  X is any single vocabulary symbol  All the terminal symbols that can begin a sentential form derivable from   If  is the right-hand side of a production, then First(  ) contains terminal symbols that begin strings derivable from   follow_set[A]  contains terminal symbols and in some sentential form  A is a nonterminal symbol 21 Follow(A)={a  Vt|S  *  Aa  }  {if S  +  A then { } else  } First(  )={a  Vt|   * a  }  {if   * then { } else  } More Example at next page…

Grammar Analysis Algorithms (5) typedef set_of_terminal_or_lambda termsets; termset follow_set[NUM_NONTERMINAL]; termset first_set[SYMBOL]; marked vocabulary dervies_lambda = mark_lambda(g); /* mark_lambda(g) as defined above */ termset compute first (string_of_symbols alpha) { int i,k; termset result; k= length (alpha); if( k==0 ) result = SET_OF ( ); else { result = first_set[alpha[0]]; for (i=1; i<k && ∈ first_set[alpha[i-1]];i++) result = result ∪ ( first_set[alpha[i]] –SET_OF( )); if(i==k && ∈ first_set[alpha[k-1]]) result = result ∪ SET_OF( ); } return result; } 22 【 Cause 】 : For an arbitrary string , we can’t have the First and Follow sets pre-computed, so we use this function that return the set of terminals defined by First(  ). 【 Action 】: If  happens to be exactly one symbol long. 【 GOAL 】: This function will simply return first_set[  ]. It is a subroutine of fill_first_set() E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 More Example at next page…

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 23 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFirst Set EPrefixTail()VF+ (1)First Loop for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 24 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFirst Set EPrefixTail()VF+ (1)First Loop for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01  { }

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 25 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFirst Set EPrefixTail()VF+ (1)First Loop for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01  { }

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 26 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01  { } 2 {(} 

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 27 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {(}  

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 28 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {(}  

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 29 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {)}  {(} 

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 30 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {)}  {(} 

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 31 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {)}  {(} 

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 32 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {V}  {(}  {)}{V}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 33 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {V}  {(} {V} {)}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 34 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {V}  {(} {V} {)}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 35 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F}  {(} {V} {)}{V}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 36 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F}  {(} {V} {)}{V} {F, }

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 37 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, }{ } {F}  {(} {V} {)}{V}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 38 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, }{ } {+}  {(} {V} {)}{V}{F}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 39 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, }{ } {+}  {(} {V} {)}{V}{F}

StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 40 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } { } {+}  {(} {V} {)}{V}{F} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 41 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+, } {+}  {(} {V} {)}{V}{F} 3 {V}{F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 42 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 43 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 44 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 45 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 46 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 47 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 48 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 49 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, } {(}

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 50 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {(} {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, }

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 51 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, } {(}

do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); StepFirst Set EPrefixTail()VF+ (1)First Loop (2)Second (nested) Loop (3)Third Loop, production 1 for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  aβ) first_set[A]=first_set[A] ∪ SET_OF(a); } Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 52 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } Nonterminal A; terminal a; production p; booleanchanges; IntI, j; 01 { } 2 {F, } {+}  {V} {)}{V}{F} 3 {F,V,(} {F, } {(}{)}{V}{F}{+} {+, } {(}

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { …………… (0) …………… (1) …………… (2) …………… (3) } 53 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFirst Set EPrefixTail()VF+ (1)First Loop  { } (2)Second (nested) Loop {V} {F, }{+, } {(}{)}{V}{F}{+} (3)Third Loop, production 1 {V, F, (} {F, }{+, } {(}{)}{V}{F}{+} do { changes =FALSE; for (i=0;i<g.num_productions; i++) { p=g.productions[i]; first_set[p.lhs] = first_set[p.lhs] ∪ compute_first(p.rhs); if( first_set changed ) changes = TRUE; } } while (changes); for(i=0; i<NUM_NONTERMINAL; i++) { A=g.nonterminals[i]; if(derives_lambda[A]) first_set[A] = SET_OF( ); else first_set[A]=  ; } for(i=0;i<NUM_TERMINAL; i++) { a=g.terminals[i]; first_set[a] = SET_OF (a); for(j=0;j<NUM_NONTERMINAL; j++) { A=g.nonterminals[j]; if(there exists a production A  a β) first_set[A]=first_set[A] ∪ SET_OF(a); } Nonterminal A; terminal a; production p; booleanchanges; IntI, j;

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { Simple Method } 54 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 LookFirst Set EPrefixTail()VF+ (1) (2) (3) Simple Algorithm {(}{)}{V}{F}{+} {Prefix, V} {F, }{+, } {F, V,(} {F, }{+, } {F, V,(} {F, }{+, } More Operation at next page…

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { Simple Method } 55 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 LookFirst Set EPrefixTail()VF+ (1) Simple Algorithm {Prefix, V} {F, }{+, }

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { Simple Method } 56 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFirst Set EPrefixTail()VF+ (1) (2) Simple Algorithm {Prefix, V} {F, }{+, } {F, V, (} {F, }{+, } Translate Non-terminal in First Set “Prefix” can be replaced by “F” or “ ” So…. E  Prefix(E) Translate E  F(E) E  (E) But In “E  (E)”, the is empty… So catch more one… E  (E) The first set of “Prefix” and “Tail” do not have non-terminals!

Grammar Analysis Algorithms (6) Extern grammar g; void fill_first_set(void) { Simple Method } 57 E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 LookFirst Set EPrefixTail()VF+ (1) (2) (3) Simple Algorithm {(}{)}{V}{F}{+} {Prefix, V} {F, }{+, } {F, V,(} {F, }{+, } {F, V,(} {F, }{+, } More Operation at next page… The first set of terminals are itself

Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 58 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization noterminal A, B; int i; boolean changes; 0 1 { }

Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 59 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization noterminal A, B; int i; boolean changes; 0 1  { }

Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 60 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization { } noterminal A, B; int i; boolean changes; 0 1  

do { changes = FALSE; for (each production A  αBβ) { /* I.e. for each production and each occurrence of a nonterminal in its right-hand side.*/ follow_set[B] = follow_set[B] ∪ (compute_first(β) – SET_OF ( )); if( ∈ compute_first(β))€ follow_set[B] = follow_set[B] ∪ follow_set[A]; if(follow_set[B] changed) changes = TRUE; } }while (changes); Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 61 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization { }  (2)Process Prefix in production 1 { }  noterminal A, B; int i; boolean changes; 0 12 {(}  changes = FALSE TRUE

do { changes = FALSE; for (each production A  αBβ) { /* I.e. for each production and each occurrence of a nonterminal in its right-hand side.*/ follow_set[B] = follow_set[B] ∪ (compute_first(β) – SET_OF ( )); if( ∈ compute_first(β))€ follow_set[B] = follow_set[B] ∪ follow_set[A]; if(follow_set[B] changed) changes = TRUE; } }while (changes); Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 62 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization { }  (2)Process Prefix in production 1 { } {(}  (2)Process E in production 1 {(}  noterminal A, B; int i; boolean changes; 0 12 changes = FALSE TRUE {, )}{ }

do { changes = FALSE; for (each production A  αBβ) { /* I.e. for each production and each occurrence of a nonterminal in its right-hand side.*/ follow_set[B] = follow_set[B] ∪ (compute_first(β) – SET_OF ( )); if( ∈ compute_first(β))€ follow_set[B] = follow_set[B] ∪ follow_set[A]; if(follow_set[B] changed) changes = TRUE; } }while (changes); Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 63 for(i=0; i<NUM_NOTERMINAL; i++) { A = g.nonterminals[i]; follow_set[A] =  ; } E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1) Initialization { }  (2)Process Prefix in production 1 { } {(}  (2)Process E in production 1 {(}  (4)Process Tail in production 2 {, )} {(} noterminal A, B; int i; boolean changes; 0 12 changes = FALSE TRUE {, )}{ } {, )} 

Grammar Analysis Algorithms (7) Extern grammar g; void fill_follow_set(void) { …………… (0) …………… (1) …………… (2) } 64 for(i=0; i<NUM_NOTERMINAL; i++) { A = g,nonterminals[i]; follow_set[A] =  ; } do { changes = FALSE; for (each production A  αBβ) { /* I.e. for each production and each occurrence of a nonterminal in its right-hand side.*/ follow_set[B] = follow_set[B] ∪ (compute_first(β) – SET_OF ( )); if( ∈ compute_first(β))€ follow_set[B] = follow_set[B] ∪ follow_set[A]; if(follow_set[B] changed) changes = TRUE; } }while (changes); E  Prefix(E) E  V Tail Prefix  F Prefix  Tail  Tail  G0G0 StepFollow Set EPrefixTail (1)Initialization { }  (2)Process Prefix in production 1 { } {(}  (3)Process E in production 1 {, )} {(}  (4)Process Tail in production 2 {, )} {(} {, )} noterminal A, B; int i; boolean changes; 0 12

More examples (1) 65 S  aSe S  B B  bBe B  C C  cCe C  d The execution of fill_first_set() StepFirst Set SBCabcde StepFollow Set SBC (1)First Loop  (2)Second (nested) Loop{a}{b}{c, d}{a}{b}{c}{d}{e} (3)Third Loop, production 2{a, b}{b}{c, d}{a}{b}{c}{d}{e} (4)Third Loop, production 4{a, b}{b, c, d}{c, d}{a}{b}{c}{d}{e} (5)Third Loop, production 2{a, b, c, d}{b, c, d}{c, d}{a}{b}{c}{d}{e} (1)Initialization { }  (2)Process S in production 1 {e, }  (3)Process B in production 2 {e, }  (4)Process B in production 3No Changes (5)Process C in production 4 {e, } (6)Process C in production 5No Changes

More examples (2) StepFirst Set SABabc 66 S  ABc A  a A  B  b B  StepFollow Set SAB (1)First Loop  { } (2)Second (nested) Loop  {a, }{b, } {a}{b}{c} (3)Third Loop, production 1{a, b, c} {a, }{b, } {a}{b}{c} (1)Initialization { }  (2)Process A in production 1 { } {b, c}  (3)Process B in production 1 { } {b, c}{c}