caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
@ 2005-12-12 17:58 Francois Pottier
  2005-12-12 19:51 ` [Caml-list] " "Márk S. Zoltán"
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Francois Pottier @ 2005-12-12 17:58 UTC (permalink / raw)
  To: Caml Mailing List


Dear Caml users,

We are proud to announce the first release of Menhir. Menhir compiles LR(1)
grammar specifications to OCaml code.

Menhir is 90% compatible with ocamlyacc. That is, existing ocamlyacc grammar
specifications are accepted and compiled by Menhir; the resulting parsers run
and produce correct parse trees, except they produce incorrect position
information, because none of the functionality of module Parsing is
supported. Porting a grammar specification from ocamlyacc to Menhir requires
replacing all calls to the Parsing module with new keywords.

Why switch from ocamlyacc to Menhir? In short,

 * Menhir offers parameterized nonterminal symbols as well as a library of
   standard definitions, including options, sequences, and lists. It also
   offers limited support for EBNF syntax.

 * ocamlyacc accepts LALR(1) grammars; Menhir accepts LR(1) grammars, thus
   avoiding certain artificial conflicts.

 * Menhir explains conflicts in terms of the grammar, not (only) in terms of
   the automaton.

 * Menhir allows grammar specifications to be split over multiple files. It
   also allows several grammars to share a single set of tokens.

 * Menhir produces reentrant parsers.

 * Menhir is able to produce parsers that are parameterized by Ocaml modules.

 * ocamlyacc requires semantic values to be referred to via keywords: $1, $2,
   and so on. Menhir allows semantic values to be explicitly named.

 * Menhir's error and warning messages are usually more numerous and better
   than ocamlyacc's.

A more detailed comparison between ocamlyacc and Menhir appears in Menhir's
documentation.

This is an ALPHA-quality release, so there certainly remain a lot of bugs
to iron out. Nevertheless, we encourage intrepid testers to have a look
and send suggestions and bug reports our way. Thanks for your attention!

Menhir requires ocaml 3.09. The source distribution and the documentation can
be found at

  http://pauillac.inria.fr/~fpottier/menhir/menhir-20051212.tar.gz
  http://pauillac.inria.fr/~fpottier/menhir/manual.pdf

-- 
François Pottier and Yann Régis-Gianas
{Francois.Pottier,Yann.Regis-Gianas}@inria.fr
http://pauillac.inria.fr/~fpottier/
http://pauillac.inria.fr/~regisgia/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-12 17:58 [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml Francois Pottier
@ 2005-12-12 19:51 ` "Márk S. Zoltán"
  2005-12-13 21:07 ` Nathaniel Gray
  2005-12-15  6:35 ` Stefan Monnier
  2 siblings, 0 replies; 18+ messages in thread
From: "Márk S. Zoltán" @ 2005-12-12 19:51 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Caml Mailing List

I just tried to build menhir and failed at it. Maybe the bug is on my 
side, because I do not exactly do everything by the book. My 
installation is mingw over Win2k, ocaml-3.09-0, however, it is a custom 
build over native msys, no cygwin whatsoever involved. This was not an 
issue for the last few years - I am maintaining an ocaml line for this 
platform just for fun ever since I learned about msys. I would 
understand if you did not consider this issue to be too urgent, 
appearing on an unsupported platform etc. but I thought it may be 
something more generic, so here you go:

The output is the following:

$ ./configure
checking for ocamlc.opt... no
checking for ocamlc... ocamlc
checking the version of the ocaml bytecode compiler.... 3.09.0
checking for ocamlopt.opt... no
checking for ocamlopt... ocamlopt
checking the version of the ocaml native compiler.... 3.09.0
checking for ocamldep.opt... no
checking for ocamldep... ocamldep
checking for ocamlyacc... ocamlyacc
checking for ocamllex... ocamllex
checking for a BSD-compatible install... /bin/install -c
configure: creating ./config.status
config.status: creating Makefile

$ make install
make - --unix -s PGEN="ocamlyacc -v" PARSER=parser EXECUTABLE=stage-one 
executab
les
77 states, 5444 transitions, table size 22238 bytes
18222 additional bytes used for bindings
243 states, 3079 transitions, table size 13774 bytes
10161 additional bytes used for bindings
5 states, 258 transitions, table size 1062 bytes
23 states, 1876 transitions, table size 7642 bytes
1209 additional bytes used for bindings
make - --unix -s PGEN="./stage-one -v -lg 1 -la 1 -lc 1 --comment 
--infer --erro
r-recovery --stdlib ." PARSER=fancy-parser EXECUTABLE=menhir executables
I/O error: Invalid argument
Fatal error: exception Sys_error("Invalid argument")
make[1]: *** [parser.mli] Error 1
make: *** [bootstrap] Error 2

$


Regards

    M- S- Z-



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-12 17:58 [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml Francois Pottier
  2005-12-12 19:51 ` [Caml-list] " "Márk S. Zoltán"
@ 2005-12-13 21:07 ` Nathaniel Gray
  2005-12-14  6:08   ` skaller
  2005-12-15  6:35 ` Stefan Monnier
  2 siblings, 1 reply; 18+ messages in thread
From: Nathaniel Gray @ 2005-12-13 21:07 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 3195 bytes --]

This is pretty nice!  Every time I use ocamlyacc I think "somebody should
write something better."  Now it looks like somebody has!  I can't tell you
how many times I've wanted parameterized rules and simple "library" rules
for parsing delimiter-separated lists and such...

Cheers,
-n8

On 12/12/05, Francois Pottier <Francois.Pottier@inria.fr> wrote:
>
>
> Dear Caml users,
>
> We are proud to announce the first release of Menhir. Menhir compiles
> LR(1)
> grammar specifications to OCaml code.
>
> Menhir is 90% compatible with ocamlyacc. That is, existing ocamlyacc
> grammar
> specifications are accepted and compiled by Menhir; the resulting parsers
> run
> and produce correct parse trees, except they produce incorrect position
> information, because none of the functionality of module Parsing is
> supported. Porting a grammar specification from ocamlyacc to Menhir
> requires
> replacing all calls to the Parsing module with new keywords.
>
> Why switch from ocamlyacc to Menhir? In short,
>
> * Menhir offers parameterized nonterminal symbols as well as a library of
>    standard definitions, including options, sequences, and lists. It also
>    offers limited support for EBNF syntax.
>
> * ocamlyacc accepts LALR(1) grammars; Menhir accepts LR(1) grammars, thus
>    avoiding certain artificial conflicts.
>
> * Menhir explains conflicts in terms of the grammar, not (only) in terms
> of
>    the automaton.
>
> * Menhir allows grammar specifications to be split over multiple files. It
>    also allows several grammars to share a single set of tokens.
>
> * Menhir produces reentrant parsers.
>
> * Menhir is able to produce parsers that are parameterized by Ocaml
> modules.
>
> * ocamlyacc requires semantic values to be referred to via keywords: $1,
> $2,
>    and so on. Menhir allows semantic values to be explicitly named.
>
> * Menhir's error and warning messages are usually more numerous and better
>    than ocamlyacc's.
>
> A more detailed comparison between ocamlyacc and Menhir appears in
> Menhir's
> documentation.
>
> This is an ALPHA-quality release, so there certainly remain a lot of bugs
> to iron out. Nevertheless, we encourage intrepid testers to have a look
> and send suggestions and bug reports our way. Thanks for your attention!
>
> Menhir requires ocaml 3.09. The source distribution and the documentation
> can
> be found at
>
>   http://pauillac.inria.fr/~fpottier/menhir/menhir-20051212.tar.gz
>   http://pauillac.inria.fr/~fpottier/menhir/manual.pdf
>
> --
> François Pottier and Yann Régis-Gianas
> {Francois.Pottier,Yann.Regis-Gianas}@inria.fr
> http://pauillac.inria.fr/~fpottier/
> http://pauillac.inria.fr/~regisgia/
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>



--
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->

[-- Attachment #2: Type: text/html, Size: 4200 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-13 21:07 ` Nathaniel Gray
@ 2005-12-14  6:08   ` skaller
  2005-12-14  9:04     ` Francois Pottier
  0 siblings, 1 reply; 18+ messages in thread
From: skaller @ 2005-12-14  6:08 UTC (permalink / raw)
  To: Nathaniel Gray; +Cc: Francois.Pottier, Caml Mailing List

On Tue, 2005-12-13 at 13:07 -0800, Nathaniel Gray wrote:
> This is pretty nice!  Every time I use ocamlyacc I think "somebody
> should write something better."  Now it looks like somebody has!  I
> can't tell you how many times I've wanted parameterized rules and
> simple "library" rules for parsing delimiter-separated lists and
> such... 

Yes, it is pretty nice! However it still appears to have some
problems. Any comments appreciated.

0. The licence. Q public licence for the generator????
Please NO NO NO!! Not unless it is distributed
as part of the official distro. Is there any chance of that?
If not even GPL would be better ;(


1. Generating a functor is cute, but it doesn't seem to
allow arguments to parser functions. Perhaps I missed something?
Is there a way to use the functorisation with closures to
add an argument?

In particular, can the parser be generated *inside*
an environment such a function or let binding?
[Felix allows that, which means an extra argument is
not required, a variable in the environment can be used
instead]

2. The signature of parsers is still wrong? 
Ocamlyacc usesthe typing

	val parser: (lexbuf->token) -> lexbuf -> 'a

which is just bad. A better signature is

	val parser: ( unit -> token ) -> 'a

There is no need to provide location information: the correct
solution is to throw an exception, which is caught in a 
context which can determine the location.

It would be nice to be able to generate this signature 
with a command line switch, pragma, or some other mechanism,
even if the default is chosen for ocamlyacc compatibility.

3. I have doubts about the claim that parsers can 'share'
token types. I do not see how this is possible. It is
contradicted by the compilation model description, which
explains how it is necessary to join separate files making
up a grammar specification. In this case, the joined system
is going to generate a single token type, and any type
generated by another joining is certain to generate
a distinct type because

(a) the type is defined in a distinct ocaml module (mli file)
(b) the typing of normal variants is nominal

This problem would go away if polymorphic variants
were used instead, because the typenames are then simply
abbreviations, since pm-variants are structurally, not
nominally, typed.

Perhaps a command line switch, pragma, or whatever, to use
polymorphic variants instead of ordinary ones?

Actually, I personally find the 'yacc' technique of
generating tokens to be rather lame. Felix does this
much better -- the parser simply expects a token type
which is a variant, the type can be defined wherever
you like. In particular, the lexer and parser can
share that definition.

As far as I can see Menhir COULD do this, except of
course one would use %token as a special way
of generating the variant. All that would be required
I think is the syntax

%import_tokens "filename"

which refers to the token definition file -- as an
alternative to inlining these token definitions.
(if pm-variants are used you could probably support both,
though I'm not sure).

A token definition file then generates two files,
an ordinary mli file with the token variant type,
and, a special information file for the parser generator
(with the same information, but in a more useful form).

In Felix none of this is necessary because parsing is
built in, so the compiler can find the information required
for the parser generator directly from the token variant type.

4. Just curious, but how practical is LR(1) in terms of
generated code sizes? Felix is using Elkhound as its 
parser which is a GLR parser with an LALR(1) core. In theory
there is an option for choosing the core automaton, which
also allows LR(1) however I recall Scott McPeak commenting
it wasn't worth supporting because it generated tables
which were far too big. 

I'm curious how one would be able to predict the size of the 
generated code since I don't  really understand the 
additional constraints LALR(1) introduces .. 

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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14  6:08   ` skaller
@ 2005-12-14  9:04     ` Francois Pottier
  2005-12-14 10:27       ` Alessandro Baretta
  2005-12-14 20:51       ` skaller
  0 siblings, 2 replies; 18+ messages in thread
From: Francois Pottier @ 2005-12-14  9:04 UTC (permalink / raw)
  To: skaller; +Cc: Caml Mailing List


Hello,

On Wed, Dec 14, 2005 at 05:08:15PM +1100, skaller wrote:

> 0. The licence. Q public licence for the generator????
> Please NO NO NO!! Not unless it is distributed
> as part of the official distro. Is there any chance of that?

Our plan (not yet approved by the OCaml higher authorities)
is to make it part of the OCaml distribution.

> In particular, can the parser be generated *inside*
> an environment such a function or let binding?

No. The only way of passing arguments to the parser is through
functor arguments. (Or through global state, of course.) Why is
that a problem?

> Ocamlyacc usesthe typing
> 
> 	val parser: (lexbuf->token) -> lexbuf -> 'a
> 
> which is just bad. A better signature is
> 
> 	val parser: ( unit -> token ) -> 'a
> 
> There is no need to provide location information: the correct
> solution is to throw an exception, which is caught in a 
> context which can determine the location.

It can be nice to have the parser automatically extract position information
for you; doing it manually and explicitly within semantic actions would be
quite tedious.

On the other hand, the signature that you suggest would allow using lexers
that do not necessarily conform to the lexbuf interface; is that your point?
If so, we will consider adding a command line switch, as you suggest. It
would disallow the use of the position keywords ($startpos, $endpos, etc.)

> 3. I have doubts about the claim that parsers can 'share'
> token types. I do not see how this is possible. 

It certainly is possible: have a look at demos/calc-two in the
distribution. The example is artificial but illustrates the
possibility of sharing a token type.

> Actually, I personally find the 'yacc' technique of
> generating tokens to be rather lame. Felix does this
> much better -- the parser simply expects a token type
> which is a variant, the type can be defined wherever
> you like.

With Menhir, the token type can also be hand-written or generated via other
means. It doesn't have to be generated by Menhir. It has to be an algebraic
data type, though, not a polymorphic variant.

> %import_tokens "filename"

This is called --external-tokens Filename. It's a command line switch.

> 4. Just curious, but how practical is LR(1) in terms of
> generated code sizes? Felix is using Elkhound as its 
> parser which is a GLR parser with an LALR(1) core. In theory
> there is an option for choosing the core automaton, which
> also allows LR(1) however I recall Scott McPeak commenting
> it wasn't worth supporting because it generated tables
> which were far too big. 

There are two questions: how big is the automaton compared to
an LALR automaton? and how big is the code that implements the
automaton?

The answer to the first question is, in most cases, the grammar
is LALR(1) anyway, and the automaton generated by Menhir is
identical to the one that would be produced by ocamlyacc or
by some other LALR(1) parser generator. When the grammar is
not LALR(1), the LR(1) automaton has more states than an
LALR(1) automaton for the same grammar. The number of extra
states is usually small (often just one, or a handful). So
there's no concern here.

Considering the answer to the first question, the second
question would not arise at all if Menhir produced tables, like
ocamlyacc. However, Menhir does not produce tables; it
compiles the automaton down to a bunch of mutually recursive
functions. We have not yet scientifically assessed the
difference in size between tables and code, but a few
quick experiments indicate that it is reasonable (the
code is larger than the tables by a factor of two or
three).

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14  9:04     ` Francois Pottier
@ 2005-12-14 10:27       ` Alessandro Baretta
  2005-12-14 21:04         ` skaller
  2005-12-14 20:51       ` skaller
  1 sibling, 1 reply; 18+ messages in thread
From: Alessandro Baretta @ 2005-12-14 10:27 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Caml Mailing List

Francois Pottier wrote:

> Considering the answer to the first question, the second
> question would not arise at all if Menhir produced tables, like
> ocamlyacc. However, Menhir does not produce tables; it
> compiles the automaton down to a bunch of mutually recursive
> functions. We have not yet scientifically assessed the
> difference in size between tables and code, but a few
> quick experiments indicate that it is reasonable (the
> code is larger than the tables by a factor of two or
> three).
> 

In general, I like the approach, as it can easily scale to an extensible parser 
generator by late-binding the recursion through a record/array/table of 
functions. Have you thought about this at all?

Alex

-- 
*********************************************************************
http://www.barettadeit.com/
Baretta DE&IT
A division of Baretta SRL

tel. +39 02 370 111 55
fax. +39 02 370 111 54

Our technology:

The Application System/Xcaml (AS/Xcaml)
<http://www.asxcaml.org/>

The FreerP Project
<http://www.freerp.org/>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14  9:04     ` Francois Pottier
  2005-12-14 10:27       ` Alessandro Baretta
@ 2005-12-14 20:51       ` skaller
  2005-12-14 22:15         ` Joaquin Cuenca Abela
  1 sibling, 1 reply; 18+ messages in thread
From: skaller @ 2005-12-14 20:51 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Caml Mailing List

On Wed, 2005-12-14 at 10:04 +0100, Francois Pottier wrote:
> Hello,
> 
> On Wed, Dec 14, 2005 at 05:08:15PM +1100, skaller wrote:
> 
> > 0. The licence. Q public licence for the generator????
> > Please NO NO NO!! Not unless it is distributed
> > as part of the official distro. Is there any chance of that?
> 
> Our plan (not yet approved by the OCaml higher authorities)
> is to make it part of the OCaml distribution.

Good!!!

> > In particular, can the parser be generated *inside*
> > an environment such a function or let binding?
> 
> No. The only way of passing arguments to the parser is through
> functor arguments. (Or through global state, of course.) 

Which is the same thing...

> Why is that a problem?

Because it destroys re-entrancy. My parser is recursive,
it actually calls a recursive descent parser to handle
user defined extensions, that parser in turn can call
other parsers, including the original ocamlyacc parser.

Passing an argument to the parser is the natural way
to do this. What I'm actually doing now is storing
the data in a token, since this is the only way
to get the required data to the parser.

however it is a trick. It 'happens' to work at the
moment, but may break at any time (it works because
the information is constructed by the lexer which 
runs in an earlier phase -- that is good enough
for the current extensions I allow, but this
may change tomorrow -- I'd love to scope these
extensions properly, but that really does require
passing an argument)

It's just the usual reason for functional programming
and persistent data structures I guess.

> > Ocamlyacc usesthe typing
> > 
> > 	val parser: (lexbuf->token) -> lexbuf -> 'a
> > 
> > which is just bad. A better signature is
> > 
> > 	val parser: ( unit -> token ) -> 'a
> > 
> > There is no need to provide location information: the correct
> > solution is to throw an exception, which is caught in a 
> > context which can determine the location.
> 
> It can be nice to have the parser automatically extract position information
> for you; doing it manually and explicitly within semantic actions would be
> quite tedious.

Yes, it can be nice for a toy parser. For a complex production
quality parser there is no way to avoid working hard to manage
source location data.

> On the other hand, the signature that you suggest would allow using lexers
> that do not necessarily conform to the lexbuf interface; is that your point?

Indeed. (My parsers run off lists of tokens .. they're lexed using
ocamllex .. but in an earlier phase. And the lists are processed
in between, for example, whitespace tokens are elided because
the parser can't handle them)

> If so, we will consider adding a command line switch, as you suggest. It
> would disallow the use of the position keywords ($startpos, $endpos, etc.)

Yes. That makes sense. There are other alternatives, such as
requiring the tokeniser to return a pair, consisting of a
token and the location. In Ocamlyacc this would be a bad
idea, since it would require a fixed notion of location.

In Menhir, however, this is not so, since it can generate
a functor which can be parameterised by the location type.

> > 3. I have doubts about the claim that parsers can 'share'
> > token types. I do not see how this is possible. 
> 
> It certainly is possible: have a look at demos/calc-two in the
> distribution. The example is artificial but illustrates the
> possibility of sharing a token type.

Hmm .. ok, I will look.

> > Actually, I personally find the 'yacc' technique of
> > generating tokens to be rather lame. Felix does this
> > much better -- the parser simply expects a token type
> > which is a variant, the type can be defined wherever
> > you like.
> 
> With Menhir, the token type can also be hand-written or generated via other
> means. It doesn't have to be generated by Menhir. It has to be an algebraic
> data type, though, not a polymorphic variant.

Ah, I see, the same as Felix in that respect then.
This solves a lot of problems, IMHO.

> Considering the answer to the first question, the second
> question would not arise at all if Menhir produced tables, like
> ocamlyacc. However, Menhir does not produce tables; it
> compiles the automaton down to a bunch of mutually recursive
> functions. We have not yet scientifically assessed the
> difference in size between tables and code, but a few
> quick experiments indicate that it is reasonable (the
> code is larger than the tables by a factor of two or
> three).

I'm also curious as to the performance of code vs
table driven interpreter. One would think the code
is faster .. but size matters a lot on current CPUs
due to caching. Still, the O() performance will
be much the same -- 2-3 times larger code is reasonable
considering that it will probably make it easier
to enhance the generator (as has already been done
by be able to generate functors .. :)

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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14 10:27       ` Alessandro Baretta
@ 2005-12-14 21:04         ` skaller
  2005-12-15  8:46           ` Francois Pottier
  0 siblings, 1 reply; 18+ messages in thread
From: skaller @ 2005-12-14 21:04 UTC (permalink / raw)
  To: Alessandro Baretta; +Cc: Francois.Pottier, Caml Mailing List

On Wed, 2005-12-14 at 11:27 +0100, Alessandro Baretta wrote:
> Francois Pottier wrote:
> 
> > However, Menhir does not produce tables; it
> > compiles the automaton down to a bunch of mutually recursive
> > functions. We have not yet scientifically assessed the
> > difference in size between tables and code, but a few
> > quick experiments indicate that it is reasonable (the
> > code is larger than the tables by a factor of two or
> > three).
> > 
> 
> In general, I like the approach, as it can easily scale to an extensible parser 
> generator by late-binding the recursion through a record/array/table of 
> functions. Have you thought about this at all?

Actually the Felix parser does this right now -- and that is
why I'm asking for the parser functions to allow a parameter:
to pass in the data structure. I actually have simplistic
recursive descent interpreter which is called by ocamlyacc,
and which calls back into ocamlyacc: at present this
allows user defined statements to be added to the Felix
language. It is very crude, since there is no way
to properly type user non-terminals other than statements,
and it only allows extension of statements.

Interestingly the 'end of stream' issue discussed at length
in the Menhir manual then applies also to the points
of recursion. For a statement in Felix, there is no lookahead
at the end (they end with a semicolon). For expressions,
I have to read one token too many, keep a list of all
possible tokens that can terminate an expression,
introduce an 'augmented expression' which is an expression
followed by any of these tokens, and then in the action
code 'put back' the token into the token stream.

It would be really nice if I could write the
production as:

exprx: expr ~expr

where ~expr means 'any token which forces a reduction
of the whole expression' if you know what I mean.
I have to assemble this list by hand at the moment.
I did it by starting with a list of all the tokens,
and removing the ones which seemed to cause a conflict.
I will certainly forget to upgrade this list when I add
new tokens -- hence a desire for something like ~expr
which tells the parser to do it :)

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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14 20:51       ` skaller
@ 2005-12-14 22:15         ` Joaquin Cuenca Abela
  2005-12-15  8:40           ` Francois Pottier
  0 siblings, 1 reply; 18+ messages in thread
From: Joaquin Cuenca Abela @ 2005-12-14 22:15 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Caml Mailing List

Hi,

If you are still accepting suggestions for Menhir,
mine is to allow guards on rules to prevent the
reduction of a rule when the guard is false.

Some languages are easy to parse, with some exceptions
that are hard to express with a grammar, as "these two
tokens should be on the same line" (hard to do if
everywhere else new lines are ignored...)

Cheers,



Joaquin Cuenca Abela
e98cuenc at yahoo dot com

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-12 17:58 [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml Francois Pottier
  2005-12-12 19:51 ` [Caml-list] " "Márk S. Zoltán"
  2005-12-13 21:07 ` Nathaniel Gray
@ 2005-12-15  6:35 ` Stefan Monnier
  2005-12-15  8:47   ` [Caml-list] " Francois Pottier
  2 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2005-12-15  6:35 UTC (permalink / raw)
  To: caml-list

> We are proud to announce the first release of Menhir. Menhir compiles LR(1)
> grammar specifications to OCaml code.

Nice.
I wish it had something like ml-yacc's automatic handling of syntax-errors
(which tries to insert/delete tokens in the input stream until the parse
succeeds).


        Stefan


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14 22:15         ` Joaquin Cuenca Abela
@ 2005-12-15  8:40           ` Francois Pottier
  0 siblings, 0 replies; 18+ messages in thread
From: Francois Pottier @ 2005-12-15  8:40 UTC (permalink / raw)
  To: Joaquin Cuenca Abela; +Cc: Caml Mailing List


Hello,

On Wed, Dec 14, 2005 at 02:15:06PM -0800, Joaquin Cuenca Abela wrote:

> If you are still accepting suggestions for Menhir,
> mine is to allow guards on rules to prevent the
> reduction of a rule when the guard is false.

I don't see how to implement this in an LR parser... can you explain?

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-14 21:04         ` skaller
@ 2005-12-15  8:46           ` Francois Pottier
  2005-12-15 11:03             ` skaller
  0 siblings, 1 reply; 18+ messages in thread
From: Francois Pottier @ 2005-12-15  8:46 UTC (permalink / raw)
  To: skaller; +Cc: Alessandro Baretta, Caml Mailing List

On Thu, Dec 15, 2005 at 08:04:54AM +1100, skaller wrote:

> Interestingly the 'end of stream' issue discussed at length
> in the Menhir manual then applies also to the points
> of recursion.

That's a good point. Actually, we are planning to implement in Menhir a
mechanism that helps stop at some point and invoke an external lexer or parser
(this can be any piece of code that consumes characters off the input stream).
Doing this properly requires *not* reading the lookahead token. As you point
out, the problems that arise are similar to the way the end of stream is
handled.

> It would be really nice if I could write the
> production as:
> 
> exprx: expr ~expr
> 
> where ~expr means 'any token which forces a reduction
> of the whole expression' if you know what I mean.

No, I don't know exactly what you mean :) I need to think more to understand
if this construction makes sense. It makes the grammar self-referential, in a
way, so it at least has to be monotonic in order to make sense.

Our plan regarding calls to external lexers or parsers was to be more rigid,
that is, to require the current statement (or expression, or whatever) to be
unambiguously terminated (for instance, by a semicolon) at the point where the
external call is made. So what you do with statements would be accepted, but
what you do with expressions might be impossible.

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15  6:35 ` Stefan Monnier
@ 2005-12-15  8:47   ` Francois Pottier
  2005-12-15 16:41     ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Francois Pottier @ 2005-12-15  8:47 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: caml-list


Hello,

On Thu, Dec 15, 2005 at 01:35:40AM -0500, Stefan Monnier wrote:

> I wish it had something like ml-yacc's automatic handling of syntax-errors
> (which tries to insert/delete tokens in the input stream until the parse
> succeeds).

Do you mean instead of or in addition to the current mechanism? (I assume
instead of. I don't know if the two can be made to coexist.)

I am not particularly happy with Menhir's current error mechanism, which
attempts to follow yacc's. If you could explain to us why ML-Yacc's approach
is superior, that would be great.

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15  8:46           ` Francois Pottier
@ 2005-12-15 11:03             ` skaller
  0 siblings, 0 replies; 18+ messages in thread
From: skaller @ 2005-12-15 11:03 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Alessandro Baretta, Caml Mailing List

On Thu, 2005-12-15 at 09:46 +0100, Francois Pottier wrote:

> Doing this properly requires *not* reading the lookahead token. 

> As you point
> out, the problems that arise are similar to the way the end of stream is
> handled.
> 
> > It would be really nice if I could write the
> > production as:
> > 
> > exprx: expr ~expr
> > 
> > where ~expr means 'any token which forces a reduction
> > of the whole expression' if you know what I mean.
> 
> No, I don't know exactly what you mean :) I need to think more to understand
> if this construction makes sense. 

> It makes the grammar self-referential, in a
> way, so it at least has to be monotonic in order to make sense.
> 
> Our plan regarding calls to external lexers or parsers was to be more rigid,
> that is, to require the current statement (or expression, or whatever) to be
> unambiguously terminated (for instance, by a semicolon) at the point where the
> external call is made. So what you do with statements would be accepted, but
> what you do with expressions might be impossible.

So, the idea is this: for an 1 token look ahead parser,
all productions terminate either with 0 lookahead or 1 lookahead.

Now, you're saying only to support recursion for 0 lookahead
productions. 

So what if you have a 1 lookahead and you still want
to recurse??

One answer is: make a new augmented production with is 0 lookahead:

	prod': prod ~prod { $1, $2 }

where ~prod is the nonterminal

	~prod: 
		| t1 { t1 $1 } 
		| t2 { t2 $1 }
		| t3 { t3 $1 }
		....

where t1, t2, t3, .. are tokens that would not be shifted
by the parser, and therefore cause prod to be reduced.

The action then returns the result of prod, PLUS the 
lookahead token. Before recursing, we can simply
push the lookahead token back into the head of the
token stream.

Felix does precisely this -- it convents a 1 lookahead
production into a 0 lookahead production and therefore:

> what you do with expressions might be impossible.

seems possible by the above mechanism.
It is equivalent to adding a set of terminating tokens.

The *problem* is choosing terminating tokens that
are viable first tokens of any sequence of symbols
that can follow an expression elsewhere in the grammar.

For example consider:

	while expr do ..
	for i in expr to expr do

This grammar would be ambiguous, if, whilst parsing
an expression, a 'do' or 'to' token did not cause
expr to be reduced. So 'do' and 'to' are 'expression
termination tokens', that is, 'do' and 'to' are
members of the set '~expr'.

I forget the correct terminology about viable
prefixes and handles.. but I hope the idea is clear.

I think you did raise an important point though:
the meaning of ~x is dependent on the start symbol.
So the notation should probably be something like:

	start~x

meaning 'all the tokens which can terminate an x whilst
parsing start'.

This algorithm 'works' for finding 'start~x':

"try every token. If it leads to a conflict it is not
in start~x, otherwise it is"

I am doing that by hand at the moment. Here are the relevant 
parts of Felix:

%type <Flx_ast.expr_t * token> exprx
%start exprx

exprx:
  expr expr_terminator { $1,$2 }

expr_terminator:
  | SEMI { SEMI $1 }
  | USER_KEYWORD { USER_KEYWORD $1 }
  | VBAR { VBAR $1 }
  | ENDMARKER { ENDMARKER }

@for n,t in flx_expr_terminator_keywords:
  tangle("  | "  + t + " { " + t + " $1 }",inhibit_sref=1)

The @ stuff is a Python script that uses a Python table
to generate code, elsewhere i have:

flx_expr_terminator_keywords = [
    ("all", "ALL"),
    ("assert", "ASSERT"),
    ("body", "BODY"),
    ("call", "CALL"),
    ("case", "CASE"),

....

    ("with", "WITH"),
    ("until", "UNTIL"),
    ("_", "UNDERSCORE"),
    ("_gc_pointer", "GC_POINTER"),
    ("_svc", "SVC"),
  ]

flx_other_keywords = [
    ("and", "AND"),
    ("as", "AS"),
....
    ("regmatch", "REGMATCH"),
    ("the", "THE"),
    ("typematch", "TYPEMATCH"),
  ]

flx_keywords = flx_expr_terminator_keywords + flx_other_keywords


I generated the partition by trial and error. When I modify
the grammar I could miss some cases. In fact,
I have no idea if the set of terminators is maximal.
The parser KNOWS .. if I add an wrong keyword
into the terminator set I get a conflict.

The technique I am using would be impossible to maintain
if there were 20-30 such productions at 'recursion points'.
[At the moment in Felix there are just two: statements
and expression]

I hope this makes sense: I think what I'm asking for
is quite general, since it enables any LR1 parser
to be used with an LL parser, provided one can
'push back' the offending lookahead token.
(that is, of course, always possible to implement
by buffering for mutable streams, and persistence
for functional ones).


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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15  8:47   ` [Caml-list] " Francois Pottier
@ 2005-12-15 16:41     ` Stefan Monnier
  2005-12-15 16:50       ` Francois Pottier
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2005-12-15 16:41 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: caml-list

>> I wish it had something like ml-yacc's automatic handling of syntax-errors
>> (which tries to insert/delete tokens in the input stream until the parse
>> succeeds).

> Do you mean instead of or in addition to the current mechanism? (I assume
> instead of.  I don't know if the two can be made to coexist.)

I don't know enough of the details to tell you, but I'd guess it'd have to
be "instead of", indeed.

> I am not particularly happy with Menhir's current error mechanism, which
> attempts to follow yacc's.  If you could explain to us why ML-Yacc's
> approach is superior, that would be great.

ML-Yacc's error recovery if fully automatic: you write your grammar without
worrying about error handling and the generated parser automatically signals
syntax errors (note the "s" at the end: it doesn't just stop at the first
syntax error) by mentioning that it had to insert a ";" at line L1 and
remove an ID at line L2.

For toy projects it's amazing: you get good error messages with 0 effort.

The main downside of ML-Yacc IIRC has to do with the fact that it requires
a fairly strong decoupling between the lexer and parser (you can't do tricks
like change the lexer state from a parser semantic action IIRC), but it may
be just a limitation of ML-Yacc rather than of the underlying technique.

See http://www.smlnj.org/doc/ML-Yacc/mlyacc001.html#toc3


        Stefan


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15 16:41     ` Stefan Monnier
@ 2005-12-15 16:50       ` Francois Pottier
  2005-12-15 18:56         ` Stefan Monnier
  2005-12-30 21:57         ` Florian Weimer
  0 siblings, 2 replies; 18+ messages in thread
From: Francois Pottier @ 2005-12-15 16:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: caml-list


Hi Stefan,

Thanks for your answer.

> For toy projects it's amazing: you get good error messages with 0 effort.

What about non-toy projects? Are there times where the automatic error
recovery mechanism gets in the way?

-- 
François Pottier
Francois.Pottier@inria.fr
http://pauillac.inria.fr/~fpottier/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15 16:50       ` Francois Pottier
@ 2005-12-15 18:56         ` Stefan Monnier
  2005-12-30 21:57         ` Florian Weimer
  1 sibling, 0 replies; 18+ messages in thread
From: Stefan Monnier @ 2005-12-15 18:56 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: caml-list

>> For toy projects it's amazing: you get good error messages with 0 effort.
> What about non-toy projects? Are there times where the automatic error
> recovery mechanism gets in the way?

I wouldn't know, really.
SML/NJ uses it and I find its syntax error reporting to be generally good.
E.g. significantly better than OCaml's ;-)

But if it's not good enough, there are hooks to influence its behavior
(e.g. telling it what to try and add/remove first, thus telling it basically
what are tokens commonly forgotten and spuriously added), but I don't know
how it compares in practice to a well tuned yacc error recovery.


        Stefan


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml
  2005-12-15 16:50       ` Francois Pottier
  2005-12-15 18:56         ` Stefan Monnier
@ 2005-12-30 21:57         ` Florian Weimer
  1 sibling, 0 replies; 18+ messages in thread
From: Florian Weimer @ 2005-12-30 21:57 UTC (permalink / raw)
  To: Francois.Pottier; +Cc: Stefan Monnier, caml-list

* Francois Pottier:

> What about non-toy projects? Are there times where the automatic error
> recovery mechanism gets in the way?

AFAIK, MLton uses it, and the inserted symbols are often not those
that are actually missing.  This leads to error messages which are
rather confusing.  With manually written error handling, you can
surely do much better, but the effort pays off in special cases.
(Most of the time, the careful error handling code is never written,
of course.)


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2005-12-30 21:58 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-12 17:58 [ANNOUNCE] Alpha release of Menhir, an LR(1) parser generator for ocaml Francois Pottier
2005-12-12 19:51 ` [Caml-list] " "Márk S. Zoltán"
2005-12-13 21:07 ` Nathaniel Gray
2005-12-14  6:08   ` skaller
2005-12-14  9:04     ` Francois Pottier
2005-12-14 10:27       ` Alessandro Baretta
2005-12-14 21:04         ` skaller
2005-12-15  8:46           ` Francois Pottier
2005-12-15 11:03             ` skaller
2005-12-14 20:51       ` skaller
2005-12-14 22:15         ` Joaquin Cuenca Abela
2005-12-15  8:40           ` Francois Pottier
2005-12-15  6:35 ` Stefan Monnier
2005-12-15  8:47   ` [Caml-list] " Francois Pottier
2005-12-15 16:41     ` Stefan Monnier
2005-12-15 16:50       ` Francois Pottier
2005-12-15 18:56         ` Stefan Monnier
2005-12-30 21:57         ` Florian Weimer

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).