Download presentation

Presentation is loading. Please wait.

Published byNya Lovitt Modified over 2 years ago

1
Recursive Descent Parsing (with combinators) Greg Morrisett

2
Last Time We saw how to use combinators to build not just a lexer, but a parser. The only difference is that parsers are generally recursive. And that recursion can get us into trouble.

3
For Example Suppose we have a grammar that looks like this: intlist -> INT intlist |

4
Using our Combinators intlist -> INT intlist | let int_p (ts:token list) = match ts with | (INT i)::rest -> [(i,rest)] | _ -> [] let rec intlist_p = fun ts -> ((int_p $ intlist_p) % cons ++ eps) ts

5
A Manual Parser intlist -> INT intlist | let rec intlist_p ts = match ts with | (INT i)::rest -> let (ints,ts’) = intlist_p rest in (i::ints, ts’) | _ -> ([], ts)

6
For Example But what if we instead wrote: intlist -> intlist INT | Now the grammar is left-recursive since in one case, we run into the non-terminal intlist before we see any terminal.

7
Using our Combinators intlist -> intlist INT | let int_p (ts:token list) = match ts with | (INT i)::rest -> [(i,rest)] | _ -> [] let rec intlist_p = fun ts -> ((intlist_p $ int_p) % cons_end ++ eps) ts

8
A Manual Parser intlist -> intlist INT | let rec intlist_p ts = let (ints, ts’) = intlist_p ts in match ts’ with | (INT i)::rest -> (ints @ [i], rest) | _ -> ([], ts) Oops! That’s definitely going to loop forever. So we want to avoid writing grammars that are left recursive.

9
Another Example exp -> INT | exp ‘+’ exp let rec exp_p ts = (int_p ++ (exp_p $ tok PLUS $ exp_p) % (function ((i,_),j) -> i+j))) ts

10
Inlining “++” let rec exp_p ts = (int_p ts) @ ((exp_p $ tok PLUS $ exp_p) % (function ((i,_),j) -> i+j) ts)

11
Inlining “$” and “%” let rec exp_p ts = (int_p ts) @ let s1 = exp_p ts in fold_right (function (i,ts1) a ->...)

12
Note – infinite loop! let rec exp_p ts = (int_p ts) @ let s1 = exp_p ts in fold_right (function (i,ts1) a ->...)

13
Refactoring the Grammar exp -> INT | exp ‘+’ exp exp -> INT | INT ‘+’ exp This accepts the same strings, but is no longer left-recursive.

14
With our Combinators exp -> INT | INT ‘+’ exp let rec exp_p ts = int_p ++ (int_p $ tok PLUS $ exp_p) % (function ((i,_),j) -> i+j)

15
Unwinding the definitions let rec exp_p ts = (int_p ts) ++ let s1 = int_p ts in fold_right (function (i,ts2) -> match ts2 with | PLUS::ts3 -> let s2 = exp_p ts2 in... By the time we do the recursive call, the list of tokens is smaller.

16
Let’s Scale Up exp -> INT | exp ‘+’ exp | exp ‘*’ exp In addition to the problem with left-recursion, we have the problem that we’ll get multiple parse results for an expression like “3 + 2 * 6”.

17
Getting Rid of Left Recursion exp -> INT | INT ‘+’ exp | INT ‘*’ exp let rec exp_p = int_p ++ (int_p $ tok PLUS $ exp_p) %... (int_p $ tok TIMES $ exp_p) %...

18
Grouping exp -> term | term ‘+’ exp term -> INT | INT * exp

19
Grouping exp -> term | term ‘+’ exp term -> INT | INT ‘*’ term let rec term ts = (INT ++ (INT $ tok TIMES $ term) %...) ts and exp ts = (term ++ (term $ tok PLUS $ exp) %...) ts

Similar presentations

Presentation is loading. Please wait....

OK

1 LEX & YACC Tutorial February 28, 2008 Tom St. John.

1 LEX & YACC Tutorial February 28, 2008 Tom St. John.

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google

Ppt on agriculture system in india Ppt on interest rate swaps Ppt on 2d and 3d figures Ppt on foldable screen technology Ppt on pricing policy objective Project ppt on online shopping Ppt on conservation of angular momentum Ppt on faculty development programme Ppt on media and networking Ppt on l&t finance ipo