Version française
Home     About     Download     Resources     Contact us    
Browse thread
Fairly dumb ocamlyacc question
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: skaller <skaller@u...>
Subject: Re: [Caml-list] Fairly dumb ocamlyacc question
On Tue, 2006-10-24 at 17:04 -0400, David Allsopp wrote:
> This should be obvious, but I can't quite solve it!

> top:
>   WEEKDAY AFTER_KWD NAME BEFORE_KWD NAME FAILS_KWD top {()}
> | WEEKDAY relative NAME {()}
> ;
> 
> relative:
>   BEFORE_KWD {()}
> | AFTER_KWD {()}
> ;
> ------------
> 
> Then I get a shift/reduce having parsed WEEKDAY AFTER_KWD... the parser
> can't figure out what to do if it sees NAME. 

That's right. Consider:

	WEEKDAY AFTER_KWD . NAME
	up to here  ------^

There are two way to parse this: your first and second rule,
and NAME doesn't disambiguate them.

Although you may think about these as the same ..
the parser cannot see into your action rules. 

It has to choose whether to parse AFTER_KWD as a single
token or to reduce the non-terminal 'relative',
and either choice could be wrong depending one what can
come *after* the token NAME -- which it can't take
into account because it's only an LALR(1) parser:
one token lookahead.


> This problem can be made to
> disappear by expanding the relative rules to give:
> 
> top:
>   WEEKDAY AFTER_KWD NAME BEFORE_KWD NAME FAILS_KWD top {()}
> | WEEKDAY AFTER_KWD NAME {()}
> | WEEKDAY BEFORE_KWD NAME {()}
> ;

Yes. There is another way too: to *contract* the rules:

relative:
  BEFORE_KWD { `Before }
| AFTER_KWD { `After }
;
-
top:
  WEEKDAY relative NAME BEFORE_KWD NAME FAILS_KWD top 
  {
    match $2 with
    | `Before -> failwith "BEFORE not allowed here"
    | `After -> ()
  }
| WEEKDAY relative NAME {()}
;

As a general rule of thumb: LR is bottom up not
top down. It isn't goal oriented, but *driven*
by the input. So the thing to do is provide
a unique, no exceptions, way to build small parts
up, such as 'relative' above, and use that always.

So to generalise you should write:

  WEEKDAY relative NAME relative NAME FAILS_KWD top 

and use a match in the action rule to refine
the allowed cases. Think of the syntax as a 
CRUDE way of understanding the input, without
much semantic content, which will parse a much
too general set of inputs .. then subtract the
bad inputs out with further analysis.

For big parsers you get more extreme .. no semantics
in the action rules .. just build the parse tree,
and analyse it later.


> I've tried a couple of tricks with %prec 

Don't ;(

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net