Help an ocamlyacc beginner

Hello ocamlers!

For a side project, I need a config file format both readable in ocaml and C or C++.
For now I’ve settled on using Libconfig : https://hyperrealm.github.io/libconfig/
It’s a C built library for parsing a custom but very versatile config file format.

The BNF grammar of this file format is documented at page 49 of the following .PDF : http://www.strauss-engineering.ch/tmp/libconfig.pdf

BTW, under this URI : http://www.strauss-engineering.ch/tmp/
you’ll find :

  • libconfig doco : libconfig.pdf
  • first attempt at a lexer: config_lexer.mll
  • first attempt at a parser : config_parser.mly (*)
  • first attempt at ocaml typing of the parser result: configuration.mli
  • libconfig configuration files examples : *.cfg
  • parser_test.ml : a basic test for the parser, using a generic printing lib.
  • build_parser.sh : a build script

I can’t figure out how to type the parser result using a standard variant type.
I’m totally noob about GADT’s and polymorphic variant BTW.

Can someone help with the ocaml typing? Thanks in advance.

(*) the ocamlyacc parser is a subset of libconfig one’s: I’ve dropped the heterogenous list support on the ocaml side.

best regards!

What is the issue more specifically? From your message, it sounds like you get a type checking error, which one? Normally, a big enough variant type should suffice for most parsing needs.

The spec says Group is setting list not value list.
Additional nitpicking: I would parse hex encoded values directly to their interpretation, also I prefer shorter names for types (no _t or _kind_t) and for the string value constructor.

So I would do

type scalar =
| Bool of bool
| Integer of int
| Integer64 of int64
| Float of float
| String of string

type value =
| Scalar of scalar
| Array of scalar list
| Group of setting list

and setting = string * value

type t = setting list

Also in the future instead of a directory url give a .zip url, it’s easier to download (my naive wget grabbed a bunch of extra stuff from your server before I killed it ;))

./build_parser.sh

46 states, 1240 transitions, table size 5236 bytes
4 rules never reduced

File “config_parser.mly”, line 68, characters 36-51:
Error: This expression has type Configuration.setting list
but an expression was expected of type Configuration.value_kind_t list
Type Configuration.setting = string * Configuration.value_kind_t
is not compatible with type Configuration.value_kind_t
line 68 of the .mly:

group:
| LBRACE RBRACE { [] }
line 68–> | LBRACE setting_list RBRACE { List.rev $2 }
;

the previous msg from myself was for octachron.

Thanks SkySkimmer, didn’t know the “type … and …”, that was the piece missing.

Now I’ve got something that build fine but totally mute, it output nothing yet, stay tuned for more adventure :slight_smile:

I’m sure this answer isn’t going to be useful, but just in case:

It’s possible that you’re spending a lot of effort, where if you were to choose a different config-file format, you could avoid almost all of it. [OTOH, perhaps you’re forced to use this format, in which case this comment is useless.]

If you can choose another format, you might choose INI-files, or YAML, or even (esp!) JSON; in each of these cases, there’s well-developed libraries in most languages for this format, including in Ocaml.

Just a thought.

P.S. I find JSON to be really nice, and esp. b/c the ubiquity of the format means it’ll be vanishingly rare for a language to not have a JSON interface library.

Sure JSON would do fine, but I want to limit the number of runtime lib dependencies somehow.