Search code examples
ocamlfunctormenhir

Menhir Parser Functor?


Is it possible to make Menhir generate a functor? Or something to that effect?

For a small example, say you have a family of languages that share the same structure except for the value type and keywords. Say I have a module signature:

module type M = sig
  type value_type
  type keyword
end

with some AST functor:

module AST (M : M) = struct
  type t = ...
  ...
end

I can define multiple AST variants with different types and keywords by instantiating them with different M. e.g. AST1 = AST(M1), AST2 = AST(M2), etc.

If I want a Parser for AST(M).t, however, I am limited to making a different parser for each AST1, AST2, etc, unless there's a way to make the parser parametric on M.

I can alternatively define an intersection AST that can then be converted into each variant. But this requires traversing every AST after parsing, so I was hoping Menhir perhaps can do it in a single step.


Solution

  • You can define a parameterized parser by adding a %parameter header to your parser:

    %parameter<M:sig
      type value
      type keyword
    end>
    

    The menhir repository has an example at https://gitlab.inria.fr/fpottier/menhir/-/blob/master/demos/calc-param/parser.mly?ref_type=heads#L4.

    With this parameter will generate the parsing code inside a Make functor that you can call with your various implementation.