I'm trying to have two different parsers with different entry points.
I have the following project hierarchy:
.
├── bin
│ ├── dune
│ ├── lexer.mll
│ ├── main.ml
│ ├── parser.messages
│ ├── parser.mly
│ └── test_parser.mly
├── dune-project
├── program.opam
└── test
lexer.mll
{
open Parser
exception Error of string
}
rule token = parse
| [' ' '\t'] { token lexbuf }
| '\n' { EOL }
| ['0'-'9']+ as i { INT (int_of_string i) }
| '+' { PLUS }
| eof { exit 0 }
| _ { raise Exit }
parser.mly
%token <int> INT
%token PLUS
%token EOL
%left PLUS
%start <int> main
%%
main:
| e = expr EOL
{ e }
%public expr:
| i = INT { i }
| e1 = expr PLUS e2 = expr { e1 + e2 }
and dune
(ocamllex
(modules lexer))
(menhir
(modules parser)
(flags --table)
)
(executable
(name main)
(public_name program)
(libraries menhirLib)
)
(rule
(targets parser_messages.ml)
(deps parser.messages parser.mly)
(action (with-stdout-to %{targets} (run menhir --compile-errors %{deps}))))
This works perfectly (the parser.messages has been generated by menhir --list-errors bin/parser.mly > bin/parser.messages
and is not really important)
However, I'd like to have a second parser that uses some rules defined in parser.mly
and according to http://gallium.inria.fr/~scherer/tmp/menhir-manual/main.html#sec23 it should be possible but I guess I'm doing it wrong:
test_parser.mly
%start <int> test
%%
test:
| el = separated_nonempty_list(COMMA, expr) EOL
{ List.fold_left (+) 0 e }
And in my dune file I added:
(menhir
(modules parser test_parser)
(merge_into test_parser)
(flags --table))
(rule
(targets test_parser_messages.ml)
(deps test_parser.messages test_parser.mly)
(action (with-stdout-to %{targets} (run menhir --compile-errors %{deps}))))
But when I dune build
:
❯ dune build
File "test_parser.mly", line 6, characters 21-25:
Error: expr is undefined.
File "bin/test_parser.mly", line 7, characters 27-28:
Error: Unbound value e
expr
is preceded by %public
in parser.mly so I thought I could use it from test_parser.mly
. Can this feature only be used with a common entry point and different producing rules?