-let parse_ast_pattern stream =
- exc_located_wrapper (fun () -> Grammar.Entry.parse level2_pattern stream)
-
-let parse_interpretation stream =
- exc_located_wrapper (fun () -> Grammar.Entry.parse level3_term stream)
-
-(** {2 Grammar extension} *)
-
-type associativity_kind = [ `Left | `Right | `None ]
-
-let symbol s = Gramext.Stoken ("SYMBOL", s)
-let ident s = Gramext.Stoken ("IDENT", s)
-let number s = Gramext.Stoken ("NUMBER", s)
-let term = Gramext.Sself
-
-type env_type = (string * (value_type * value)) list
-
-let rec pp_value =
- function
- | TermValue _ -> "@TERM@"
- | StringValue s -> sprintf "\"%s\"" s
- | NumValue n -> n
- | OptValue (Some v) -> "Some " ^ pp_value v
- | OptValue None -> "None"
- | ListValue l -> sprintf "[%s]" (String.concat "; " (List.map pp_value l))
-
-let rec pp_value_type =
- function
- | TermType -> "Term"
- | StringType -> "String"
- | NumType -> "Number"
- | OptType t -> "Maybe " ^ pp_value_type t
- | ListType l -> "List " ^ pp_value_type l
-
-let pp_env env =
- String.concat "; "
- (List.map
- (fun (name, (ty, value)) ->
- sprintf "%s : %s = %s" name (pp_value_type ty) (pp_value value))
- env)
-
-let make_action action bindings =
- let rec aux (vl : env_type) =
- function
- [] ->
- prerr_endline "aux: make_action";
- Gramext.action (fun (loc: location) -> action vl loc)
- | None :: tl ->
- prerr_endline "aux: none";
- Gramext.action (fun _ -> aux vl tl)
- (* LUCA: DEFCON 3 BEGIN *)
- | Some (name, TermType) :: tl ->
- prerr_endline "aux: term";
- Gramext.action
- (fun (v:term) -> aux ((name, (TermType, (TermValue v)))::vl) tl)
- | Some (name, StringType) :: tl ->
- prerr_endline "aux: string";
- Gramext.action
- (fun (v:string) ->
- aux ((name, (StringType, (StringValue v))) :: vl) tl)
- | Some (name, NumType) :: tl ->
- prerr_endline "aux: num";
- Gramext.action
- (fun (v:string) -> aux ((name, (NumType, (NumValue v))) :: vl) tl)
- | Some (name, OptType t) :: tl ->
- prerr_endline "aux: opt";
- Gramext.action
- (fun (v:'a option) ->
- aux ((name, (OptType t, (OptValue v))) :: vl) tl)
- | Some (name, ListType t) :: tl ->
- prerr_endline "aux: list";
- Gramext.action
- (fun (v:'a list) ->
- aux ((name, (ListType t, (ListValue v))) :: vl) tl)
- (* LUCA: DEFCON 3 END *)
- in
- aux [] (List.rev bindings)
-
-let flatten_opt =
- let rec aux acc =
- function
- [] -> List.rev acc
- | None::tl -> aux acc tl
- | Some hd::tl -> aux (hd::acc) tl
- in
- aux []
-
- (* given a level 1 pattern computes the new RHS of "term" grammar entry *)
-let extract_term_production pattern =
- let rec aux = function
- | Literal l -> aux_literal l
- | Layout l -> aux_layout l
- | Magic m -> aux_magic m
- | Variable v -> aux_variable v
- | _ -> assert false
- and aux_literal = function
- | `Symbol s -> [None, symbol s]
- | `Keyword s -> [None, ident s]
- | `Number s -> [None, number s]
- and aux_layout = function
- | Sub (p1, p2) -> aux p1 @ [None, symbol "\\SUB"] @ aux p2
- | Sup (p1, p2) -> aux p1 @ [None, symbol "\\SUP"] @ aux p2
- | Below (p1, p2) -> aux p1 @ [None, symbol "\\BELOW"] @ aux p2
- | Above (p1, p2) -> aux p1 @ [None, symbol "\\ABOVE"] @ aux p2
- | Frac (p1, p2) -> aux p1 @ [None, symbol "\\FRAC"] @ aux p2
- | Atop (p1, p2) -> aux p1 @ [None, symbol "\\ATOP"] @ aux p2
- | Over (p1, p2) -> aux p1 @ [None, symbol "\\OVER"] @ aux p2
- | Root (p1, p2) ->
- [None, symbol "\\ROOT"] @ aux p2 @ [None, symbol "\\OF"] @ aux p1
- | Sqrt p -> [None, symbol "\\SQRT"] @ aux p
- | Break -> []
- | Box (_, pl) -> List.flatten (List.map aux pl)
- and aux_magic = function
- | Opt p ->
- let p_bindings, p_atoms = List.split (aux p) in
- let p_names = flatten_opt p_bindings in
- [ None,
- Gramext.srules
- [ [ Gramext.Sopt
- (Gramext.srules
- [ p_atoms,
- (make_action
- (fun (env : env_type) (loc : location) ->
- prerr_endline "inner opt action";
- env)
- p_bindings)])],
- Gramext.action
- (fun (env_opt : env_type option) (loc : location) ->
- match env_opt with
- Some env ->
- prerr_endline "opt action (Some _)";
- List.map
- (fun (name, (typ, v)) ->
- (name, (OptType typ, OptValue (Some v))))
- env
- | None ->
- prerr_endline "opt action (None)";
- List.map
- (fun (name, typ) ->
- (name, (OptType typ, OptValue None)))
- p_names) ]]
- | _ -> assert false
- and aux_variable = function
- | NumVar s -> [Some (s, NumType), number ""]
- | TermVar s -> [Some (s, TermType), term]
- | IdentVar s -> [Some (s, StringType), ident ""]
- | Ascription (p, s) -> assert false (* TODO *)
- | FreshVar _ -> assert false
- in
- aux pattern
-
-let level_of_int precedence =
- (* TODO "mod" test to be removed as soon as we add all 100 levels *)
- if precedence mod 10 <> 0 || precedence < 0 || precedence > 100 then
- raise (Level_not_found precedence);
- string_of_int precedence
-
-type rule_id = Token.t Gramext.g_symbol list
-
-let extend level1_pattern ?(precedence = 0) ?associativity action =
- let p_bindings, p_atoms =
- List.split (extract_term_production level1_pattern)
- in
- let level = level_of_int precedence in
- let p_names = flatten_opt p_bindings in
- let entry = Grammar.Entry.obj (l2_pattern: 'a Grammar.Entry.e) in
- let _ =
- prerr_endline (string_of_int (List.length p_bindings));
- Grammar.extend
- [ entry, Some (Gramext.Level level),
- [ Some level, (* TODO should we put None here? *)
- associativity,
- [ p_atoms,
- (make_action
- (fun (env: env_type) (loc: location) -> (action env loc))
- p_bindings) ]]]
- in
- p_atoms