4 Theory headers -- independent of outer syntax. |
4 Theory headers -- independent of outer syntax. |
5 *) |
5 *) |
6 |
6 |
7 signature THY_HEADER = |
7 signature THY_HEADER = |
8 sig |
8 sig |
9 val args: Token.T list -> (string * string list * (string * bool) list) * Token.T list |
9 type header = |
10 val read: Position.T -> string -> string * string list * (Path.T * bool) list |
10 {name: string, imports: string list, |
|
11 keywords: (string * (string * string list) option) list, |
|
12 uses: (Path.T * bool) list} |
|
13 val make: string -> string list -> (string * (string * string list) option) list -> |
|
14 (Path.T * bool) list -> header |
|
15 val declare_keyword: string * (string * string list) option -> theory -> theory |
|
16 val the_keyword: theory -> string -> Keyword.T option |
|
17 val args: header parser |
|
18 val read: Position.T -> string -> header |
11 end; |
19 end; |
12 |
20 |
13 structure Thy_Header: THY_HEADER = |
21 structure Thy_Header: THY_HEADER = |
14 struct |
22 struct |
15 |
23 |
16 (* keywords *) |
24 type header = |
|
25 {name: string, imports: string list, |
|
26 keywords: (string * (string * string list) option) list, |
|
27 uses: (Path.T * bool) list}; |
|
28 |
|
29 fun make name imports keywords uses : header = |
|
30 {name = name, imports = imports, keywords = keywords, uses = uses}; |
|
31 |
|
32 |
|
33 |
|
34 (** keyword declarations **) |
|
35 |
|
36 fun err_dup name = error ("Inconsistent declaration of outer syntax keyword " ^ quote name); |
|
37 |
|
38 structure Data = Theory_Data |
|
39 ( |
|
40 type T = Keyword.T option Symtab.table; |
|
41 val empty = Symtab.empty; |
|
42 val extend = I; |
|
43 fun merge data : T = Symtab.merge (op =) data handle Symtab.DUP name => err_dup name; |
|
44 ); |
|
45 |
|
46 fun declare_keyword (name, kind) = |
|
47 Data.map (fn data => |
|
48 Symtab.update_new (name, Option.map Keyword.make kind) data |
|
49 handle Symtab.DUP name => err_dup name); |
|
50 |
|
51 fun the_keyword thy name = |
|
52 (case Symtab.lookup (Data.get thy) name of |
|
53 SOME decl => decl |
|
54 | NONE => error ("Unknown outer syntax keyword " ^ quote name)); |
|
55 |
|
56 |
|
57 |
|
58 (** concrete syntax **) |
|
59 |
|
60 (* header keywords *) |
17 |
61 |
18 val headerN = "header"; |
62 val headerN = "header"; |
19 val theoryN = "theory"; |
63 val theoryN = "theory"; |
20 val importsN = "imports"; |
64 val importsN = "imports"; |
|
65 val keywordsN = "keywords"; |
21 val usesN = "uses"; |
66 val usesN = "uses"; |
22 val beginN = "begin"; |
67 val beginN = "begin"; |
23 |
68 |
24 val header_lexicon = Scan.make_lexicon |
69 val header_lexicon = |
25 (map Symbol.explode ["%", "(", ")", ";", beginN, headerN, importsN, theoryN, usesN]); |
70 Scan.make_lexicon |
|
71 (map Symbol.explode |
|
72 ["%", "(", ")", "::", ";", "and", beginN, headerN, importsN, keywordsN, theoryN, usesN]); |
26 |
73 |
27 |
74 |
28 (* header args *) |
75 (* header args *) |
29 |
76 |
30 val file_name = Parse.group (fn () => "file name") Parse.name; |
77 local |
|
78 |
|
79 val file_name = Parse.group (fn () => "file name") Parse.path; |
31 val theory_name = Parse.group (fn () => "theory name") Parse.name; |
80 val theory_name = Parse.group (fn () => "theory name") Parse.name; |
|
81 |
|
82 val keyword_kind = Parse.group (fn () => "outer syntax keyword kind") (Parse.name -- Parse.tags); |
|
83 val keyword_decl = Parse.name -- Scan.option (Parse.$$$ "::" |-- Parse.!!! keyword_kind); |
32 |
84 |
33 val file = |
85 val file = |
34 Parse.$$$ "(" |-- Parse.!!! (file_name --| Parse.$$$ ")") >> rpair false || |
86 Parse.$$$ "(" |-- Parse.!!! (file_name --| Parse.$$$ ")") >> rpair false || |
35 file_name >> rpair true; |
87 file_name >> rpair true; |
36 |
88 |
37 val uses = Scan.optional (Parse.$$$ usesN |-- Parse.!!! (Scan.repeat1 file)) []; |
89 in |
38 |
90 |
39 val args = |
91 val args = |
40 theory_name -- (Parse.$$$ importsN |-- |
92 theory_name -- |
41 Parse.!!! (Scan.repeat1 theory_name -- uses --| Parse.$$$ beginN)) |
93 (Parse.$$$ importsN |-- Parse.!!! (Scan.repeat1 theory_name)) -- |
42 >> Parse.triple2; |
94 Scan.optional (Parse.$$$ keywordsN |-- Parse.!!! (Parse.and_list1 keyword_decl)) [] -- |
|
95 Scan.optional (Parse.$$$ usesN |-- Parse.!!! (Scan.repeat1 file)) [] --| |
|
96 Parse.$$$ beginN >> |
|
97 (fn (((name, imports), keywords), uses) => make name imports keywords uses); |
|
98 |
|
99 end; |
43 |
100 |
44 |
101 |
45 (* read header *) |
102 (* read header *) |
46 |
103 |
47 val header = |
104 val header = |