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