dune/src/meta.ml

96 lines
2.2 KiB
OCaml
Raw Normal View History

2016-11-13 10:01:32 +00:00
open Import
2016-11-12 11:48:24 +00:00
type t =
2016-11-13 10:01:32 +00:00
{ name : string
; entries : entry list
2016-11-12 11:48:24 +00:00
}
2016-11-13 10:01:32 +00:00
and entry =
| Comment of string
| Var of string * predicate list * action * string
| Package of t
2016-11-12 11:48:24 +00:00
2016-11-13 10:01:32 +00:00
and action = Set | Add
2016-11-12 11:48:24 +00:00
and predicate =
2016-11-13 10:03:07 +00:00
| P of string
| A of string
2016-11-13 10:01:32 +00:00
module Parse = struct
let error = lex_error
let next = Meta_lexer.token
let package_name lb =
match next lb with
| String s ->
if String.contains s '.' then
error lb "'.' not allowed in sub-package names";
s
| _ -> error lb "package name expected"
let string lb =
match lb with
| String s -> s
| _ -> error lb "string expected"
let lparen lb =
match next lb with
| Lparen -> ()
| _ -> error lb "'(' expected"
let action lb =
match next lb with
| Equal -> Set
| Plus_equal -> Add
| _ -> error lb "'=' or '+=' expected"
let comma lb =
match next lb with
| Comma -> ()
| _ -> error lb "',' expected"
let rec predicates_and_action lb acc =
match next lb with
| Rparen -> (List.rev acc, action lb)
| Name n -> comma lb; predicates_and_action lb (P n :: acc)
| Minus ->
let n =
match next lb with
| Name p -> p
| _ -> error lb "name expected"
in
comma lb;
predicates_and_action lb (A n :: acc)
| _ -> error lb "name, '-' or ')' expected"
let rec entries lb depth acc =
match next lb with
| Rparen ->
if depth > 0 then
List.rev acc
else
error lb "closing parenthesis without matching opening one"
| Name "package" ->
let name = package_name lb in
lparen lb;
let entries = entries lb (depth + 1) [] in
entries lb depth (Package { name; entries } :: acc)
| Name var ->
let preds, action =
match next lb with
| Equal -> ([], Set)
| Plus_equal -> ([], Add)
| Lparen -> predicates_and_action lb []
| _ -> error lb "'=', '+=' or '(' expected"
in
let value = string lb in
Var (var, preds, action, value)
| _ ->
error lb "'package' or variable name expected"
end
2016-11-12 11:48:24 +00:00
2016-11-13 10:03:07 +00:00
let load fn =
2016-11-13 10:01:32 +00:00
with_lexbuf_from_file fn ~f:(fun lb ->
Parse.entries lb 0 [])