Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
bnfgen.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
module Grammar = Grammar let parse lexbuf = try let grammar = Parse_bnf.parse lexbuf (Bnf_parser.Incremental.grammar lexbuf.lex_curr_p) in let () = Grammar.check_grammar grammar in Ok grammar with | Util.Syntax_error (pos, err) -> begin match pos with | Some (line, pos) -> Error (Printf.sprintf "Syntax error on line %d, character %d: %s" line pos err) | None -> Error (Printf.sprintf "Syntax error: %s" err) end | Grammar.Grammar_error msg -> Error (Printf.sprintf "Grammar error: %s" msg) let grammar_from_channel ic = let lexbuf = Lexing.from_channel ic in parse lexbuf let grammar_from_file filename = let ic = open_in filename in let g = grammar_from_channel ic in let () = close_in ic in g let grammar_from_string s = let lexbuf = Lexing.from_string s in parse lexbuf let grammar_to_string = Grammar.to_string let depth_exceeded max_depth depth = match max_depth with | None -> false | Some max_depth -> depth > max_depth let check_grammar g = try Grammar.check_grammar g; Ok () with Grammar.Grammar_error msg -> Error msg let check_grammar_exn g = Grammar.check_grammar g type settings = { dump_stack: bool; debug: bool; debug_fun: (string -> unit); max_reductions : int option; max_nonproductive_reductions : int option; symbol_separator: string; } let default_settings = { dump_stack = false; debug = false; debug_fun = print_endline; max_reductions = None; max_nonproductive_reductions = None; symbol_separator = "" } let generate ?(settings=default_settings) callback grammar start_symbol = let rec aux settings callback grammar reductions nonprod_reductions sym_stack = let () = if settings.dump_stack then begin let syms_str = List.map Grammar.string_of_symbol sym_stack |> String.concat " " |> Printf.sprintf "Symbol stack: %s" in settings.debug_fun syms_str end in if depth_exceeded settings.max_reductions reductions then Error ("Maximum total number of reductions exceeded") else let output, sym_stack = Grammar.reduce_symbol ~debug:settings.debug ~debug_fun:settings.debug_fun ~separator:settings.symbol_separator sym_stack grammar in match output with | None -> if sym_stack = [] then Ok () else if depth_exceeded settings.max_nonproductive_reductions nonprod_reductions then Error ("Maximum number of non-productive reductions exceeded") else aux settings callback grammar (reductions + 1) (nonprod_reductions + 1) sym_stack | Some str -> let () = callback str in if sym_stack = [] then Ok () else aux settings callback grammar (reductions + 1) 0 sym_stack in try aux settings callback grammar 0 0 [Grammar.Nonterminal (start_symbol, Grammar.default_flags)] with Grammar.Grammar_error e -> Error e let generate_string ?(settings=default_settings) grammar start_symbol = let (>>=) = Result.bind in let buf = Buffer.create 4096 in let res = generate ~settings:settings (Buffer.add_string buf) grammar start_symbol in res >>= (fun () -> Ok (Buffer.contents buf))