package elpi
ELPI - Embeddable λProlog Interpreter
Install
Dune Dependency
Authors
Maintainers
Sources
elpi-3.0.0.tbz
sha256=424e5a4631f5935a1436093b614917210b00259d16700912488ba4cd148115d1
sha512=fa54ce05101fafe905c6db2e5fa7ad79d714ec3b580add4ff711bad37fc9545a58795f69056d62f6c18d8c87d424acc1992ab7fb667652e980d182d4ed80ba16
doc/src/elpi.parser/parser_config.ml.html
Source file parser_config.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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
(* elpi: embedded lambda prolog interpreter *) (* license: GNU Lesser General Public License Version 2.1 or later *) (* ------------------------------------------------------------------------- *) open Elpi_util open Elpi_lexer_config.Lexer_config exception ParseError of Util.Loc.t * string (* this is the input of the parser functor in grammar.mly, it ties the knot: accumulate requires to call the same parser on another file, but file/module resolution is not a parser business *) module type ParseFile = sig val parse_file : ?cwd:string -> string -> Ast.Program.parser_output list val get_current_client_loc_payload : unit -> Obj.t option val set_current_clent_loc_pyload : Obj.t -> unit end let rec substrings i len_s s = if len_s - i >= 0 then String.sub s 0 i :: substrings (i+1) len_s s else [] let substrings s = List.rev @@ substrings 1 (String.length s) s let find_sub tab s = let rec aux = function | [] -> raise Not_found | x :: xs -> try Hashtbl.find tab x with Not_found -> aux xs in aux (substrings s) let precedence_of, umax_precedence, appl_precedence, inf_precedence = let tab = Hashtbl.create 21 in List.iteri (fun level { tokens; fixity } -> List.iter (function | Extensible { start; fixed; _ } -> Hashtbl.add tab start (fixity,level); List.iter (fun tok -> Hashtbl.add tab tok (fixity,level)) fixed | Fixed { the_token; _ } -> Hashtbl.add tab the_token (fixity,level) ) tokens; ) mixfix_symbols; let umax_precedence = List.length mixfix_symbols in let appl_precedence = umax_precedence + 1 in let inf_precedence = appl_precedence + 1 in (* greater than any used precedence*) (fun s -> try let fixity, prec = find_sub tab s in (*Format.eprintf "Printer: found %s %a %d\n%!" s pp_fixity (fst x) (snd x);*) Some fixity, prec with Not_found -> (*Format.eprintf "Printer: not found: %s\n%!" s;*) None, appl_precedence), umax_precedence, appl_precedence, inf_precedence let comma_precedence = 1 + (snd @@ precedence_of ",") let min_precedence = -1 (* minimal precedence in use *) let lam_precedence = -1 (* precedence of lambda abstraction *) let umin_precedence = 0 (* minimal user defined precedence *) let pp_fixed fmt l = l |> List.iter (fun x -> Format.fprintf fmt "%s @ " x) let pp_non_enclosed fmt = function | false -> () | true -> Format.fprintf fmt " [*]" let pp_tok_list fmt l = List.iter (function | Extensible { start; fixed; non_enclosed; _ } -> Format.fprintf fmt "%a%s..%a @ " pp_fixed fixed start pp_non_enclosed non_enclosed | Fixed { the_token; comment = None; _ } -> Format.fprintf fmt "%s @ " the_token | Fixed { the_token; comment = Some (id,_); _ } -> Format.fprintf fmt "%s (* see note %d *) @ " the_token id) l let pp_tok_list_comments fmt l = List.iter (function | Extensible _ -> () | Fixed { comment = None; _ } -> () | Fixed { comment = Some (id,txt); _ } -> Format.fprintf fmt "%d: %s@ " id txt) l let legacy_parser_compat_error = let open Format in let b = Buffer.create 80 in let fmt = formatter_of_buffer b in fprintf fmt "@[<v>"; fprintf fmt "%s@;" "Mixfix directives are not supported by this parser."; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "The parser is based on token families."; fprintf fmt "%s@;" "A family is identified by some starting characters, for example"; fprintf fmt "%s@;" "a token '+-->' belongs to the family of '+'. There is no need"; fprintf fmt "%s@;" "to declare it."; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "All the tokens of a family are parsed with the same precedence and"; fprintf fmt "%s@;" "associativity, for example 'x +--> y *--> z' is parsed as"; fprintf fmt "%s@;" "'x +--> (y *--> z)' since the family of '*' has higher precedence"; fprintf fmt "%s@;" "than the family of '+'."; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "Here the table of tokens and token families."; fprintf fmt "%s@;" "Token families are represented by the start symbols followed by '..'."; fprintf fmt "%s@;" "Tokens of families marked with [*] cannot end with the starting symbol,"; fprintf fmt "%s@;" "eg `foo` is not an infix, while `foo is."; fprintf fmt "%s@;" "The listing is ordered by increasing precedence."; fprintf fmt "%s@;" ""; pp_open_tbox fmt (); pp_set_tab fmt (); fprintf fmt "%-25s " "fixity"; pp_set_tab fmt (); fprintf fmt "| %s" "tokens / token families"; pp_print_tab fmt (); let col1 = "--------------------------" in fprintf fmt "%s" col1; pp_print_tab fmt (); fprintf fmt "+ -----------------------------------"; pp_print_tab fmt (); List.iter (fun { tokens; fixity; _ } -> fprintf fmt "%a" pp_fixity fixity; pp_print_tab fmt (); let s = let b = Buffer.create 80 in let fmt = formatter_of_buffer b in pp_set_margin fmt 40; fprintf fmt "| "; pp_open_hovbox fmt 1; fprintf fmt "%a" pp_tok_list tokens; pp_close_box fmt (); pp_print_flush fmt (); let s = Buffer.contents b in let pad = "\n" ^ String.(make (length col1) ' ') in Re.Str.(global_replace (regexp_string "\n") pad s) in fprintf fmt "%s" s; pp_print_tab fmt (); ) mixfix_symbols; pp_close_tbox fmt (); fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "If the token is a valid mixfix, and you want the file to stay compatible"; fprintf fmt "%s@;" "with Teyjus, you can ask Elpi to skip the directive. Eg:"; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "% elpi:skip 2 // skips the next two lines"; fprintf fmt "%s@;" "infixr ==> 120."; fprintf fmt "%s@;" "infixr || 120."; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "As a debugging facility one can ask Elpi to print the AST in order to"; fprintf fmt "%s@;" "verify how the text was parsed. Eg:"; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "echo 'MyFormula = a || b ==> c && d' | elpi -parse-term"; fprintf fmt "%s@;" ""; fprintf fmt "%s@;" "Notes:"; List.iter (fun { tokens; _ } -> fprintf fmt "%a" pp_tok_list_comments tokens; ) mixfix_symbols; fprintf fmt "@]"; pp_print_flush fmt (); Buffer.contents b ;; let error_mixfix loc = raise (ParseError(loc,legacy_parser_compat_error))
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>