caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: skaller <skaller@users.sourceforge.net>
To: David Allsopp <dra-news@metastack.com>
Cc: OCaml List <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] Fairly dumb ocamlyacc question
Date: Wed, 25 Oct 2006 08:32:27 +1000	[thread overview]
Message-ID: <1161729147.4703.50.camel@rosella.wigram> (raw)
In-Reply-To: <003401c6f7b0$01f9ca10$5a878640@countertenor>

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


      parent reply	other threads:[~2006-10-24 22:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-24 21:04 David Allsopp
2006-10-24 21:40 ` [Caml-list] " Yann Régis-Gianas
2006-10-24 22:32 ` skaller [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1161729147.4703.50.camel@rosella.wigram \
    --to=skaller@users.sourceforge.net \
    --cc=caml-list@yquem.inria.fr \
    --cc=dra-news@metastack.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).