1 (* Copyright (C) 2005, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://helm.cs.unibo.it/
28 exception Parse_error of Token.flocation * string
30 let grammar = Grammar.gcreate CicNotationLexer.notation_lexer
32 let level1_pattern = Grammar.Entry.create grammar "level1_pattern"
33 let level2_pattern = Grammar.Entry.create grammar "level2_pattern"
34 let level3_term = Grammar.Entry.create grammar "level3_term"
35 let notation = Grammar.Entry.create grammar "notation" (* level1 <-> level 2 *)
37 Grammar.Entry.create grammar "interpretation" (* level2 <-> level 3 *)
39 let return_term loc term = ()
41 let loc_of_floc = function
42 | { Lexing.pos_cnum = loc_begin }, { Lexing.pos_cnum = loc_end } ->
46 let (x, y) = loc_of_floc floc in
47 failwith (sprintf "Error at characters %d - %d: %s" x y msg)
51 Pervasives.int_of_string s
53 failwith (sprintf "Lexer failure: string_of_int \"%s\" failed" s)
59 | l -> Layout (Box (H, l))
61 let fold_binder binder pt_names body =
62 let fold_cluster binder names ty body =
64 (fun name body -> Binder (binder, (Cic.Name name, ty), body))
68 (fun (names, ty) body -> fold_cluster binder names ty body)
71 let return_term loc term = AttributedTerm (`Loc loc, term)
74 GLOBAL: level1_pattern level2_pattern level3_term
75 notation interpretation;
76 (* {{{ Grammar for concrete syntax patterns, notation level 1 *)
77 level1_pattern: [ [ p = l1_pattern; EOI -> boxify p ] ];
78 l1_pattern: [ [ p = LIST0 l1_simple_pattern -> p ] ];
80 [ s = SYMBOL -> `Symbol s
81 | k = KEYWORD -> `Keyword k
82 | n = NUMBER -> `Number n
85 sep: [ [ SYMBOL "\\SEP"; sep = literal -> sep ] ];
86 (* row_sep: [ [ SYMBOL "\\ROWSEP"; sep = literal -> sep ] ];
87 field_sep: [ [ SYMBOL "\\FIELDSEP"; sep = literal -> sep ] ]; *)
89 [ SYMBOL "\\LIST0"; p = l1_simple_pattern; sep = OPT sep -> List0 (p, sep)
90 | SYMBOL "\\LIST1"; p = l1_simple_pattern; sep = OPT sep -> List1 (p, sep)
91 | SYMBOL "\\OPT"; p = l1_simple_pattern -> Opt p
94 l1_pattern_variable: [
95 [ id = IDENT -> TermVar id
96 | SYMBOL "\\TERM"; id = IDENT -> TermVar id
97 | SYMBOL "\\NUM"; id = IDENT -> NumVar id
98 | SYMBOL "\\IDENT"; id = IDENT -> IdentVar id
103 [ p1 = SELF; SYMBOL "\\SUB"; p2 = SELF ->
104 return_term loc (Layout (Sub (p1, p2)))
105 | p1 = SELF; SYMBOL "\\SUP"; p2 = SELF ->
106 return_term loc (Layout (Sup (p1, p2)))
107 | p1 = SELF; SYMBOL "\\BELOW"; p2 = SELF ->
108 return_term loc (Layout (Below (p1, p2)))
109 | p1 = SELF; SYMBOL "\\ABOVE"; p2 = SELF ->
110 return_term loc (Layout (Above (p1, p2)))
111 | SYMBOL "["; p1 = l1_pattern; SYMBOL "\\OVER"; p2 = l1_pattern;
113 return_term loc (Layout (Frac (boxify p1, boxify p2)))
114 | SYMBOL "["; p1 = l1_pattern; SYMBOL "\\ATOP"; p2 = l1_pattern;
116 return_term loc (Layout (Atop (boxify p1, boxify p2)))
117 (* | SYMBOL "\\ARRAY"; p = SELF; csep = OPT field_sep; rsep = OPT row_sep ->
118 return_term loc (Array (p, csep, rsep)) *)
119 | SYMBOL "\\FRAC"; p1 = SELF; p2 = SELF ->
120 return_term loc (Layout (Frac (p1, p2)))
121 | SYMBOL "\\SQRT"; p = SELF -> return_term loc (Layout (Sqrt p))
122 | SYMBOL "\\ROOT"; index = l1_pattern; SYMBOL "\\OF"; arg = SELF ->
123 return_term loc (Layout (Root (arg, Layout (Box (H, index)))))
124 | SYMBOL "\\HBOX"; SYMBOL "["; p = l1_pattern; SYMBOL "]" ->
125 return_term loc (Layout (Box (H, p)))
126 | SYMBOL "\\VBOX"; SYMBOL "["; p = l1_pattern; SYMBOL "]" ->
127 return_term loc (Layout (Box (V, p)))
128 | SYMBOL "\\BREAK" -> return_term loc (Layout Break)
129 | SYMBOL "["; p = l1_pattern; SYMBOL "]" ->
130 return_term loc (Layout (Box (H, p)))
131 | SYMBOL "["; p = l1_pattern; SYMBOL "\\AS"; id = IDENT; SYMBOL "]" ->
132 return_term loc (Variable (Ascription (Layout (Box (H, p)), id)))
135 [ m = l1_magic_pattern -> return_term loc (Magic m)
136 | v = l1_pattern_variable -> return_term loc (Variable v)
137 | l = literal -> return_term loc (Literal l)
141 (* {{{ Grammar for ast patterns, notation level 2 *)
142 level2_pattern: [ [ p = l2_pattern -> p ] ];
144 [ SYMBOL "\\PROP" -> `Prop
145 | SYMBOL "\\SET" -> `Set
146 | SYMBOL "\\TYPE" -> `Type
150 [ (* TODO explicit substitution *)
154 [ (* TODO meta substitution *)
157 possibly_typed_name: [
158 [ SYMBOL "("; id = IDENT; SYMBOL ":"; typ = l2_pattern; SYMBOL ")" ->
159 Cic.Name id, Some typ
160 | id = IDENT -> Cic.Name id, None
164 [ id = IDENT -> id, []
165 | SYMBOL "("; id = IDENT; vars = LIST1 possibly_typed_name; SYMBOL ")" ->
170 [ SYMBOL <:unicode<Pi>> (* Π *) -> `Pi
171 | SYMBOL <:unicode<exists>> (* ∃ *) -> `Exists
172 | SYMBOL <:unicode<forall>> (* ∀ *) -> `Forall
173 | SYMBOL <:unicode<lambda>> (* λ *) -> `Lambda
177 [ vars = LIST1 IDENT SEP SYMBOL ",";
178 ty = OPT [ SYMBOL ":"; p = l2_pattern -> p ] ->
182 vars = LIST1 IDENT SEP SYMBOL ",";
183 ty = OPT [ SYMBOL ":"; p = l2_pattern -> p ];
191 [ IDENT "rec" -> `Inductive
192 | IDENT "corec" -> `CoInductive
197 name = IDENT; args = bound_names;
198 index_name = OPT [ IDENT "on"; id = IDENT -> id ];
199 ty = OPT [ SYMBOL ":" ; p = l2_pattern -> p ];
200 SYMBOL <:unicode<def>> (* ≝ *); body = l2_pattern ->
201 let body = fold_binder `Lambda args body in
205 | Some ty -> Some (fold_binder `Pi args ty)
207 let rec position_of name p = function
209 | n :: _ when n = name -> Some p, p
210 | _ :: tl -> position_of name (p + 1) tl
212 let rec find_arg name n = function
213 | [] -> fail loc (sprintf "Argument %s not found" name)
215 (match position_of name 0 l with
216 | None, len -> find_arg name (n + len) tl
217 | Some where, len -> n + where)
220 match index_name with
222 | Some name -> find_arg name 0 args
224 (Cic.Name name, ty), body, index
229 l2_pattern_variable: [
230 [ SYMBOL "\\NUM"; id = IDENT -> NumVar id
231 | SYMBOL "\\IDENT"; id = IDENT -> IdentVar id
232 | SYMBOL "\\FRESH"; id = IDENT -> FreshVar id
237 kind = [ IDENT "left" -> `Left | IDENT "right" -> `Right ];
239 SYMBOL "\\LAMBDA"; id = IDENT; recursive = l2_pattern ->
240 Fold (kind, base, [id], recursive)
241 | SYMBOL "\\DEFAULT"; some = l2_pattern; none = l2_pattern ->
247 [ IDENT "let"; var = possibly_typed_name; SYMBOL <:unicode<def>> (* ≝ *);
248 p1 = l2_pattern; "in"; p2 = l2_pattern ->
249 return_term loc (LetIn (var, p1, p2))
250 | IDENT "let"; k = induction_kind; defs = let_defs; IDENT "in";
252 return_term loc (LetRec (k, defs, body))
255 [ b = binder; names = bound_names; SYMBOL "."; body = l2_pattern ->
256 return_term loc (fold_binder b names body)
261 [ p1 = l2_pattern; p2 = l2_pattern ->
262 let rec aux = function
264 | AttributedTerm (_, Appl (hd :: tl)) ->
268 return_term loc (Appl (aux p1 @ [p2]))
271 [ id = IDENT -> return_term loc (Ident (id, None))
272 | id = IDENT; s = explicit_subst -> return_term loc (Ident (id, Some s))
273 | u = URI -> return_term loc (Uri (u, None))
274 | n = NUMBER -> return_term loc (Num (n, 0))
275 | IMPLICIT -> return_term loc (Implicit)
276 | m = META -> return_term loc (Meta (int_of_string m, []))
277 | m = META; s = meta_subst -> return_term loc (Meta (int_of_string m, s))
278 | s = sort -> return_term loc (Sort s)
279 | s = SYMBOL -> return_term loc (Symbol (s, 0))
280 | outtyp = OPT [ SYMBOL "["; ty = l2_pattern; SYMBOL "]" -> ty ];
281 IDENT "match"; t = l2_pattern;
282 indty_ident = OPT [ SYMBOL ":"; id = IDENT -> id ];
283 IDENT "with"; SYMBOL "[";
285 lhs = match_pattern; SYMBOL <:unicode<Rightarrow>> (* ⇒ *);
290 return_term loc (Case (t, indty_ident, outtyp, patterns))
291 | SYMBOL "("; p1 = l2_pattern; SYMBOL ":"; p2 = l2_pattern; SYMBOL ")" ->
292 return_term loc (Appl [ Symbol ("cast", 0); p1; p2 ])
293 | SYMBOL "("; p = l2_pattern; SYMBOL ")" -> p
294 | v = l2_pattern_variable -> return_term loc (Variable v)
295 | m = l2_magic_pattern -> return_term loc (Magic m)
299 (* {{{ Grammar for interpretation, notation level 3 *)
301 [ id = IDENT -> IdentArg id
302 | SYMBOL <:unicode<eta>> (* η *); SYMBOL "."; a = SELF -> EtaArg (None, a)
303 | SYMBOL <:unicode<eta>> (* η *); id = IDENT; SYMBOL "."; a = SELF ->
308 [ u = URI -> UriPattern u
309 | a = argument -> ArgPattern a
310 | SYMBOL "("; terms = LIST1 SELF; SYMBOL ")" ->
314 | terms -> ApplPattern terms)
318 (* {{{ Notation glues *)
320 [ IDENT "left"; IDENT "associative" -> `Left
321 | IDENT "right"; IDENT "associative" -> `Right
324 precedence: [ [ IDENT "at"; IDENT "precedence"; n = NUMBER -> n ] ];
326 [ IDENT "notation"; p1 = level1_pattern; IDENT "for"; p2 = level2_pattern;
327 assoc = OPT associativity; prec = OPT precedence ->
332 [ IDENT "interpretation"; s = SYMBOL; args = LIST1 argument; IDENT "as";
340 let exc_located_wrapper f =
344 | Stdpp.Exc_located (floc, Stream.Error msg) ->
345 raise (Parse_error (floc, msg))
346 | Stdpp.Exc_located (floc, exn) ->
347 raise (Parse_error (floc, (Printexc.to_string exn)))
349 let parse_syntax_pattern stream =
350 exc_located_wrapper (fun () -> Grammar.Entry.parse level1_pattern stream)
352 let parse_ast_pattern stream =
353 exc_located_wrapper (fun () -> Grammar.Entry.parse level2_pattern stream)
355 let parse_interpretation stream =
356 exc_located_wrapper (fun () -> Grammar.Entry.parse level3_term stream)
358 (* vim:set encoding=utf8 foldmethod=marker: *)