Prof. Fateman CS 164 Lecture 8 1 Top-Down Parsing CS164 Lecture 8.

Slides:



Advertisements
Similar presentations
Chap. 5, Top-Down Parsing J. H. Wang Mar. 29, 2011.
Advertisements

Mooly Sagiv and Roman Manevich School of Computer Science
9/27/2006Prof. Hilfinger, Lecture 141 Syntax-Directed Translation Lecture 14 (adapted from slides by R. Bodik)
6/12/2015Prof. Hilfinger CS164 Lecture 111 Bottom-Up Parsing Lecture (From slides by G. Necula & R. Bodik)
Top-Down Parsing.
By Neng-Fa Zhou Syntax Analysis lexical analyzer syntax analyzer semantic analyzer source program tokens parse tree parser tree.
CS Summer 2005 Top-down and Bottom-up Parsing - a whirlwind tour June 20, 2005 Slide acknowledgment: Radu Rugina, CS 412.
Parsing III (Eliminating left recursion, recursive descent parsing)
COS 320 Compilers David Walker. last time context free grammars (Appel 3.1) –terminals, non-terminals, rules –derivations & parse trees –ambiguous grammars.
Prof. Bodik CS 164 Lecture 61 Building a Parser II CS164 3:30-5:00 TT 10 Evans.
1 Predictive parsing Recall the main idea of top-down parsing: Start at the root, grow towards leaves Pick a production and try to match input May need.
CS 310 – Fall 2006 Pacific University CS310 Parsing with Context Free Grammars Today’s reference: Compilers: Principles, Techniques, and Tools by: Aho,
Prof. Fateman CS 164 Lecture 91 Bottom-Up Parsing Lecture 9.
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.
1 Chapter 4: Top-Down Parsing. 2 Objectives of Top-Down Parsing an attempt to find a leftmost derivation for an input string. an attempt to construct.
Professor Yihjia Tsai Tamkang University
COS 320 Compilers David Walker. last time context free grammars (Appel 3.1) –terminals, non-terminals, rules –derivations & parse trees –ambiguous grammars.
Top-Down Parsing.
CPSC 388 – Compiler Design and Construction
COP4020 Programming Languages Computing LL(1) parsing table Prof. Xin Yuan.
Syntax Analysis – Part II Quick Look at Using Bison Top-Down Parsers EECS 483 – Lecture 5 University of Michigan Wednesday, September 20, 2006.
Parsing Chapter 4 Parsing2 Outline Top-down v.s. Bottom-up Top-down parsing Recursive-descent parsing LL(1) parsing LL(1) parsing algorithm First.
Top-Down Parsing - recursive descent - predictive parsing
4 4 (c) parsing. Parsing A grammar describes the strings of tokens that are syntactically legal in a PL A recogniser simply accepts or rejects strings.
Chapter 5 Top-Down Parsing.
4 4 (c) parsing. Parsing A grammar describes syntactically legal strings in a language A recogniser simply accepts or rejects strings A generator produces.
# 1 CMPS 450 Parsing CMPS 450 J. Moloney. # 2 CMPS 450 Check that input is well-formed Build a parse tree or similar representation of input Recursive.
Parsing III (Top-down parsing: recursive descent & LL(1) )
1 Top Down Parsing. CS 412/413 Spring 2008Introduction to Compilers2 Outline Top-down parsing SLL(1) grammars Transforming a grammar into SLL(1) form.
Parsing Jaruloj Chongstitvatana Department of Mathematics and Computer Science Chulalongkorn University.
Profs. Necula CS 164 Lecture Top-Down Parsing ICOM 4036 Lecture 5.
1 Compiler Construction Syntax Analysis Top-down parsing.
Syntax and Semantics Structure of programming languages.
4 4 (c) parsing. Parsing A grammar describes syntactically legal strings in a language A recogniser simply accepts or rejects strings A generator produces.
Exercise 1 A ::= B EOF B ::=  | B B | (B) Tokens: EOF, (, ) Generate constraints and compute nullable and first for this grammar. Check whether first.
Parsing Top-Down.
Top-down Parsing lecture slides from C OMP 412 Rice University Houston, Texas, Fall 2001.
Parsing — Part II (Top-down parsing, left-recursion removal) Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights reserved. Students.
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.
1 Context free grammars  Terminals  Nonterminals  Start symbol  productions E --> E + T E --> E – T E --> T T --> T * F T --> T / F T --> F F --> (F)
1 Nonrecursive Predictive Parsing  It is possible to build a nonrecursive predictive parser  This is done by maintaining an explicit stack.
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.
Top-Down Parsing.
CSE 5317/4305 L3: Parsing #11 Parsing #1 Leonidas Fegaras.
Top-Down Predictive Parsing We will look at two different ways to implement a non- backtracking top-down parser called a predictive parser. A predictive.
Parsing methods: –Top-down parsing –Bottom-up parsing –Universal.
1 Introduction to Parsing. 2 Outline l Regular languages revisited l Parser overview Context-free grammars (CFG ’ s) l Derivations.
CS 330 Programming Languages 09 / 25 / 2007 Instructor: Michael Eckmann.
1 Topic #4: Syntactic Analysis (Parsing) CSC 338 – Compiler Design and implementation Dr. Mohamed Ben Othman ( )
Chapter 2 (part) + Chapter 4: Syntax Analysis S. M. Farhad 1.
Bernd Fischer RW713: Compiler and Software Language Engineering.
UMBC  CSEE   1 Chapter 4 Chapter 4 (b) parsing.
Parsing III (Top-down parsing: recursive descent & LL(1) )
COMP 3438 – Part II-Lecture 6 Syntax Analysis III Dr. Zili Shao Department of Computing The Hong Kong Polytechnic Univ.
Top-down parsing 1. Last Time CYK – Step 1: get a grammar in Chomsky Normal Form – Step 2: Build all possible parse trees bottom-up Start with runs of.
Spring 16 CSCI 4430, A Milanova 1 Announcements HW1 due on Monday February 8 th Name and date your submission Submit electronically in Homework Server.
CMSC 330: Organization of Programming Languages Pushdown Automata Parsing.
9/30/2014IT 3271 How to construct an LL(1) parsing table ? 1.S  A S b 2.S  C 3.A  a 4.C  c C 5.C  abc$ S1222 A3 C545 LL(1) Parsing Table What is the.
Context free grammars Terminals Nonterminals Start symbol productions
Top-down parsing cannot be performed on left recursive grammars.
Top-Down Parsing.
4 (c) parsing.
Top-Down Parsing CS 671 January 29, 2008.
Ambiguity, Precedence, Associativity & Top-Down Parsing
Predictive Parsing Lecture 9 Wed, Feb 9, 2005.
Computing Follow(A) : All Non-Terminals
Syntax Analysis - Parsing
Nonrecursive Predictive Parsing
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Presentation transcript:

Prof. Fateman CS 164 Lecture 8 1 Top-Down Parsing CS164 Lecture 8

Prof. Fateman CS 164 Lecture 82 Announcements… Programming Assignment 2 due Thurs Sept 22. Midterm Exam #1 on Thursday Sept 29 –In Class –ONE handwritten page (2 sides). –Your handwriting –No computer printouts, no calculators or cellphones –Bring a pencil

Prof. Fateman CS 164 Lecture 83 Review We can specify language syntax using CFG A parser will answer whether   L(G) … and will build a parse tree … which is essentially an AST … and pass on to the rest of the compiler Next few lectures: –How do we answer   L(G) and build a parse tree? After that: from AST to … assembly language

Prof. Fateman CS 164 Lecture 84 Lecture Outline Implementation of parsers Two approaches –Top-down –Bottom-up Today: Top-Down –Easier to understand and program manually Next: Bottom-Up –More powerful and used by most parser generators

Prof. Fateman CS 164 Lecture 85 Intro to Top-Down Parsing Terminals are seen in order of appearance in the token stream: t 2 t 5 t 6 t 8 t 9 The parse tree is constructed –From the top –From left to right 1 t2t2 3 4 t5t5 7 t6t6 t9t9 t8t8

Prof. Fateman CS 164 Lecture 86 Recursive Descent Parsing Consider the grammar 3.10 in text.. S-> if E then S else S S -> begin S L S -> print E L -> end L -> ; S L E -> num = num

Prof. Fateman CS 164 Lecture 87 Recursive Descent Parsing: Parsing S S-> if E then S else S S -> begin S L S -> print E L -> end L -> ; S L E -> num = num ( defun s()(case (car tokens) (if (eat 'if) (e) (eat 'then) (s) (eat 'else) (s)) (begin (eat 'begin)(s)(l)) (print (eat 'print)(e)) (otherwise (eat 'if )))) ;cheap error. can't match if!

Prof. Fateman CS 164 Lecture 88 Recursive Descent Parsing: Parsing L S-> if E then S else S S -> begin S L S -> print E L -> end L -> ; S L E -> num = num ( defun l()(case (car tokens) (end (eat 'end)) (|;| (eat '|;|) (s)(l)) (otherwise (eat 'end))))

Prof. Fateman CS 164 Lecture 89 Recursive Descent Parsing : parsing E S-> if E then S else S S -> begin S L S -> print E L -> end L -> ; S L E -> num = num (defun e()(eat 'num) (eat '=) (eat 'num))

Prof. Fateman CS 164 Lecture 810 Recursive Descent Parsing : utilities Get-token = pop Parse checks for empty token list. (defun eat(h) (cond((equal h (car tokens)) (pop tokens)) ;; (pop x) means (setf x (cdr x)) (t (error "stuck at ~s" tokens)))) (defun parse (tokens)(s) (if (null tokens) "It is a sentence"))

Prof. Fateman CS 164 Lecture 811 Recursive Descent Parsing : tests (defparameter test '(begin print num = num \; if num = num then print num = num else print num = num end)) (parse test)  “It is a sentence” (parse ‘(if num then num))  Error: stuck at (then num)

Prof. Fateman CS 164 Lecture 812 This grammar is very easy. Why? S-> if E then S else S S -> begin S L S -> print E L -> end L -> ; S L E -> num = num We can always tell from the first symbol which rule to use. if, begin, print, end, ;, num.

Prof. Fateman CS 164 Lecture 813 Recursive Descent Parsing, “backtracking” Example 2 Consider another grammar… E  T + E | T T  int | int * T | ( E ) Token stream is: int 5 * int 2 Start with top-level non-terminal E Try the rules for E in order

Prof. Fateman CS 164 Lecture 814 Recursive Descent Parsing. Backtracking Try E 0  T 1 + E 2 Then try a rule for T 1  ( E 3 ) –But ( does not match input token int 5 Try T 1  int. Token matches. –But + after T 1 does not match input token * Try T 1  int * T 2 –This will match int but + after T 1 will be unmatched Parser has exhausted the choices for T 1 –Backtrack to choice for E 0 E  T + E | T T  int | int * T | ( E ) int 5 * int 2

Prof. Fateman CS 164 Lecture 815 Recursive Descent Parsing. Backtracking Try E 0  T 1 Follow same steps as before for T 1 –And succeed with T 1  int * T 2 and T 2  int –With the following parse tree E0E0 T1T1 int 5 * T2T2 int 2

Prof. Fateman CS 164 Lecture 816 Recursive Descent Parsing (Backtracking) Do we have to backtrack?? Trick is to look ahead to find the first terminal symbol to figure out for sure which rule to try. Indeed backtracking is not needed, if the grammar is suitable. This grammar is suitable for prediction. Sometimes you can come up with a “better” grammar for the same exact language.

Prof. Fateman CS 164 Lecture 817 Lookahead makes backtracking unnecessary (defun E() (T) (case (car tokens) (+ (eat '+) (E));E -> T+E (otherwise nil))) (defun T() ;; Lookahead resolves rule choice (case (car tokens) (\( (eat '\() (E) (eat '\)) ); T->(E) (int (eat 'int); T -> int | int*T (case (car tokens) ; look beyond int (* (eat '*)(T)); T -> int * T (otherwise nil))); T -> int (otherwise (eat 'end))))

Prof. Fateman CS 164 Lecture 818 When Recursive Descent Does Not Work Consider a production S  S a | … –suggests a program something like… –(defun S() (S) (eat ‘a)) S() will get into an infinite loop A left-recursive grammar has a non-terminal S S  + S  for some  Recursive descent does not work in such cases

Prof. Fateman CS 164 Lecture 819 Elimination of Left Recursion Consider the left-recursive grammar S  S  |  S generates all strings starting with a  and followed by a number of  [ ,  are strings of terminals, in these examples.] Can rewrite using right-recursion S   S’ S’   S’ | 

Prof. Fateman CS 164 Lecture 820 More Elimination of Left-Recursion In general S  S  1 | … | S  n |  1 | … |  m All strings derived from S start with one of  1,…,  m and continue with several instances of  1,…,  n Rewrite as S   1 S’ | … |  m S’ S’   1 S’ | … |  n S’ | 

Prof. Fateman CS 164 Lecture 821 General Left Recursion The grammar S  A  |  A  S  is also left-recursive (even without a left-recursive RULE) because S  + S   This left-recursion can also be eliminated

Prof. Fateman CS 164 Lecture 822 Summary of Recursive Descent Simple and general parsing strategy –Left-recursion must be eliminated first –… but that can be done automatically Not so popular because common parser-generator tools allow more freedom in making up grammars. (False) reputation of inefficiency If hand-written, powerful error correction and considerable flexibility. Sometimes Rec Des is used for lexical analysis. Balanced comment delimiters /*/*.. */.. */, e.g. In practice, backtracking does not happen ever.

Prof. Fateman CS 164 Lecture 823 Predictive Parsers: generalizing lookahead Like recursive-descent but parser can “predict” which production to use –By looking at the next few tokens –No backtracking Predictive parsers accept LL(k) grammars –L means “left-to-right” scan of input –L means “leftmost derivation” –k means “predict based on k tokens of lookahead” In practice, LL(1) is used

Prof. Fateman CS 164 Lecture 824 LL(1) Languages In recursive-descent, for each non-terminal and input token there may be a choice of production LL(1) means that for each non-terminal and token there is only one production Can be specified via 2D tables –One dimension for current non-terminal to expand –One dimension for next token –A table entry contains one production

Prof. Fateman CS 164 Lecture 825 Predictive Parsing and Left Factoring Recall the grammar E  T + E | T T  int | int * T | ( E ) Hard to predict because –For T two productions start with int –For E it is not clear how to predict A grammar must be left-factored before use for predictive parsing

Prof. Fateman CS 164 Lecture 826 Left-Factoring Example Recall the grammar E  T + E | T T  int | int * T | ( E ) Factor out common prefixes of productions E  T X X  + E |  T  ( E ) | int Y Y  * T | 

Prof. Fateman CS 164 Lecture 827 LL(1) Parsing Table Example Left-factored grammar E  T X X  + E |  T  ( E ) | int Y Y  * T |  The LL(1) parsing table: int*+()$ ET X X+ E  Tint Y( E ) Y* T 

Prof. Fateman CS 164 Lecture 828 LL(1) Parsing Table Example (Cont.) Consider the [E, int] entry –“When current non-terminal is E and next input is int, use production E  T X –This production can generate an int in the first place Consider the [Y,+] entry –“When current non-terminal is Y and current token is +, get rid of Y” –Y can be followed by + only in a derivation in which Y  

Prof. Fateman CS 164 Lecture 829 LL(1) Parsing Tables. Errors Blank entries indicate error situations –Consider the [E,*] entry –“There is no way to derive a string starting with * from non-terminal E”

Prof. Fateman CS 164 Lecture 830 Using Parsing Tables Method similar to recursive descent, except –For each non-terminal X –We look at the next token a –And chose the production shown at [X,a] We use a stack to keep track of pending non- terminals We reject when we encounter an error state We accept when we encounter end-of-input

Prof. Fateman CS 164 Lecture 831 LL(1) Parsing Algorithm initialize stack = and next repeat case stack of : if T[X,nextinput] = Y 1 …Y n then stack  ; else error (); : if t = nextinput then stack  ; else error (); until stack is empty

Prof. Fateman CS 164 Lecture 832 LL(1) Parsing Example Stack Input Action E $ int * int $ T X T X $ int * int $ int Y int Y X $ int * int $ terminal Y X $ * int $ * T * T X $ * int $ terminal T X $ int $ int Y int Y X $ int $ terminal Y X $ $  X $ $  $ $ ACCEPT

Prof. Fateman CS 164 Lecture 833 Constructing Parsing Tables LL(1) languages are those defined by a parsing table for the LL(1) algorithm No table entry can be multiply defined We want to generate parsing tables from CFG

Prof. Fateman CS 164 Lecture 834 Constructing Parsing Tables (Cont.) If A  , where in the line A do we place  ? In the column of t where t can start a string derived from  –   * t  –We say that t  First(  ) In the column of t if  is  and t can follow an A –S  *  A t  –We say t  Follow(A)

Prof. Fateman CS 164 Lecture 835 Computing First Sets Definition First(X) = { t | X  * t  }  {  | X  *  } Algorithm sketch: 1.First(t) = { t } 2.   First(X) if X   is a production 3.   First(X) if X  A 1 … A n –and   First(A i ) for 1  i  n 4.First(  )  First(X) if X  A 1 … A n  –and   First(A i ) for 1  i  n

Prof. Fateman CS 164 Lecture 836 First Sets. Example Recall the grammar E  T X X  + E |  T  ( E ) | int Y Y  * T |  First sets First( ( ) = { ( } First( T ) = {int, ( } First( ) ) = { ) } First( E ) = {int, ( } First( int) = { int } First( X ) = {+,  } First( + ) = { + } First( Y ) = {*,  } First( * ) = { * }

Prof. Fateman CS 164 Lecture 837 Computing First Sets by Computer Recall the grammar E  T X X  + E |  T  ( E ) | int Y Y  * T |  First sets First( ( ) = { ( } First( T ) = {int, ( } First( ) ) = { ) } First( E ) = {int, ( } First( int) = { int } First( X ) = {+,  } First( + ) = { + } First( Y ) = {*,  } First( * ) = { * }

Prof. Fateman CS 164 Lecture 838 Computing Follow Sets Definition: Follow(X) = { t | S  *  X t  } Intuition –If X  A B then First(B)  Follow(A) and Follow(X)  Follow(B) –Also if B  *  then Follow(X)  Follow(A) –If S is the start symbol then $  Follow(S)

Prof. Fateman CS 164 Lecture 839 Computing Follow Sets (Cont.) Algorithm sketch: 1. $  Follow(S) 2.First(  ) - {  }  Follow(X) –For each production A   X  3.Follow(A)  Follow(X) –For each production A   X  where   First(  )

Prof. Fateman CS 164 Lecture 840 Follow Sets. Example Recall the grammar E  T X X  + E |  T  ( E ) | int Y Y  * T |  Follow sets Follow( + ) = { int, ( } Follow( * ) = { int, ( } Follow( ( ) = { int, ( } Follow( E ) = {), $} Follow( X ) = {$, ) } Follow( T ) = {+, ), $} Follow( ) ) = {+,), $} Follow( Y ) = {+, ), $} Follow( int) = {*, +, ), $}

Prof. Fateman CS 164 Lecture 841 Constructing LL(1) Parsing Tables Construct a parsing table T for CFG G For each production A   in G do: –For each terminal t  First(  ) do T[A, t] =  –If   First(  ), for each t  Follow(A) do T[A, t] =  –If   First(  ) and $  Follow(A) do T[A, $] = 

Prof. Fateman CS 164 Lecture 842 Computing with Grammars. Step One: Representing a grammar in Lisp. (defparameter lect8 ;; here’s one way '((E -> T X) (T -> \( E \) ) (T -> int Y) (X -> + T) (X -> ) (Y -> * T) (Y -> )))

Prof. Fateman CS 164 Lecture 843 Computing some useful information (defun rhs(r) (cddr r)) ;; e.g. r is (E -> T + E) (defun lhs(r) (first r)) (defun non-terminals(g) (remove-duplicates (mapcar #'lhs g))) (defun terminals(g) (set-difference (reduce #'union (mapcar #'rhs g)) (non-terminals g) ))

Prof. Fateman CS 164 Lecture 844 Representing sets (defmacro First (x) ;x is a symbol `(gethash,x First)) (defmacro Follow(x) ;x is a symbol `(gethash,x Follow)) (defmacro addinto(place stuff) `(setf,place (union,place,stuff))) ;; alternatively, if we have just one set, like ;; which symbols are nullable, we might just ;; assign (setf nullable ‘()) ;; and (push ‘x nullable) ;; to insert x into that set… ;; same as (setf nullable (cons ‘x nullable)) ;;; you know this from your lexical analysis program, though..

Prof. Fateman CS 164 Lecture 845 Compute Nullable set ;; Compute nullable set of a grammar. The non-terminal symbol X is ;; nullable if X can derive an empty string, X =>..=>.. => empty. ;;Given ;; grammar g, return a lisp list of symbols that are nullable. (defun nullableset(g) (let ((nullable nil) (changed? t)) (while changed? (setf changed? nil) (dolist (r g); for each rule (cond ;; if X is already nullable, do nothing. ((member (lhs r) nullable) nil) ;; for each rule (X -> A B C ), ;; X is nullable if every one of A, B, C is nullable ((every #'(lambda(z)(member z nullable))(rhs r)) (push (lhs r) nullable) (setf changed? t))))) (sort nullable #'string<))) ;sort to make it look nice See firstfoll.cl for details

Prof. Fateman CS 164 Lecture 846 Compute Firstset (defun firstset(g);; g is a list of grammar rules (let ((First (make-hash-table)) ;; First is a hashtable, in addition to a relation First[x] (nullable (nullableset g)) (changed? t)) ;; for each terminal symbol j, First[j] = {j} (dolist (j (terminals g)) (setf (First j)(list j))) (while changed? (setf changed? nil) (dolist (r g) ;; for each rule in the grammar X -> A B C...see next slide... ;; did this First set or any other First set ;; change in this run? (setf changed? (or changed? (< setsize (length (First X))))))) ) ; exit from loop First )) See firstfoll.cl for details

Prof. Fateman CS 164 Lecture 847 (defun firstset(g);; g is a list of grammar rules (let ((First (make-hash-table)) ;; First is a hashtable, in addition to a relation First[x] (nullable (nullableset g)) (changed? t)) ;; for each terminal symbol j, First[j] = {j} (dolist (j (terminals g)) (setf (First j)(list j))) (while changed? (setf changed? nil) (dolist (r g) ;; for each rule in the grammar X -> A B C (let* ((X (lhs r)) (RHS (rhs r)) (setsize (length (First X)))) ;; First[X]= First[X] U First[A] (cond ((null RHS) nil) (t (addinto (First X)(First (car RHS))))) (while (member (car RHS) nullable) (pop RHS) (addinto (First X)(First (car RHS)) )) ;end of inner while ;; did this First set or any other First set ;; change in this run? (setf changed? (or changed? (< setsize (length (First X))))))) ) ; exit from loop First ))

Prof. Fateman CS 164 Lecture 848 Followset in Lisp ((defun followset(g);; g is a list of grammar rules (let ((First (firstset g)) (Follow (make-hash-table)) (nullable (nullableset g)) (changed? t)) (while changed? (setf changed? nil) (dolist (r g) ;; for each rule in the grammar X -> A B C D ;;(format t "~%rule is ~s" r) (do ((RHS (rhs r)(cdr RHS))) ;; test to end the do loop ((null RHS) 'done ) ;; let RHS be, in succession, ;; (A B C D) ;; (B C D) ;; (C D) ;; (D) (if (null RHS) nil ;; no change in follow set for erasing rule (let* ((A (car RHS)) (Blist (cdr RHS)); e.g. (B C D) (Asize (length (Follow A)))) (if(every #'(lambda(z)(member z nullable)) Blist) ;; X -> A... then anything ….more See firstfoll.cl for details

Prof. Fateman CS 164 Lecture 849 Followset in Lisp, continued ((defun followset(g);; g is a list of grammar rules ;;;;... (if(every #'(lambda(z)(member z nullable)) Blist) ;; X -> A... then anything ;; following X can follow A: ;; Follow[A] = Follow[A] U Follow[X] (addinto (Follow A)(Follow (lhs r)))) (if Blist;not empty ;; Follow[A]= Follow[A] U First[B] (addinto (Follow A)(First (car Blist)))) (while (and Blist (member (car Blist) nullable)) ;;false when Blist =() ;; if X -> A B C and B is nullable, then ;;Follow[A]=Follow[A] U First(C) (pop Blist) (addinto (Follow A)(First (car Blist)))) (setf changed? (or changed? (< Asize (length (Follow A)))))))))) ;; Remove the terminal symbols in Follow table ;; are uninteresting ;; Return the hashtable "Follow" which has pairs like. (mapc #'(lambda(v)(remhash v Follow)) (terminals g)) ;;(printfols Follow) ; print the table for human consumption Follow ; for further processing )) See firstfoll.cl for details

Prof. Fateman CS 164 Lecture 850 Predictive parsing table (pptab lect8) First Sets symbol First ( ) * + E ( int T ( int X + Y * int Follow Sets symbol Follow E ) T ) + X ) Y ) +

Prof. Fateman CS 164 Lecture 851 Predictive parsing table (ht2grid(pptab lect8)) rows = (E T X Y), cols= (|(| |)| * + int) ( ) * + int E |E -> T X | | | |E -> T X T |T -> ( E ) | | | |T -> int Y X | |X -> | |X -> + T | Y | |Y -> |Y -> * T |Y

Prof. Fateman CS 164 Lecture 852 Notes on LL(1) Parsing Tables If any entry is multiply defined then G is not LL(1) –If G is ambiguous –If G is left recursive –If G is not left-factored –And in other cases as well Most programming language grammars are not LL(1), but could be made so with a little effort. Firstfoll.cl builds an LL(1) parser. About 140 lines of Lisp code. (With comments, debugging code, test data, the file is about 550 lines)

Prof. Fateman CS 164 Lecture 853 Review For some grammars / languages there is a simple parsing strategy based on recursive descent. It even can be automated: Predictive parsing Next: a more powerful parsing strategy