1 (* Title: Pure/Syntax/syntax |
1 (* Title: Pure/Syntax/syntax.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Tobias Nipkow and Markus Wenzel, TU Muenchen |
3 Author: Tobias Nipkow and Markus Wenzel, TU Muenchen |
|
4 |
|
5 Root of Isabelle's syntax module. |
|
6 |
|
7 TODO: |
|
8 extend_tables (requires extend_gram) (roots!) |
|
9 replace add_synrules by extend_tables |
|
10 extend, merge: make roots handling more robust |
|
11 extend: read_typ (incl check) as arg, remove def_sort |
|
12 extend: use extend_tables |
4 *) |
13 *) |
5 |
14 |
6 signature SYNTAX = |
15 signature SYNTAX = |
7 sig |
16 sig |
8 (* FIXME include AST0 (?) *) |
17 include AST0 |
9 include LEXICON0 |
18 include LEXICON0 |
10 include EXTENSION0 |
19 include EXTENSION0 |
11 include TYPE_EXT0 |
20 include TYPE_EXT0 |
12 include SEXTENSION1 |
21 include SEXTENSION1 |
13 include PRINTER0 |
22 include PRINTER0 |
14 structure Extension: EXTENSION |
23 type syntax |
15 structure Pretty: PRETTY |
24 val type_syn: syntax |
16 local open Extension.XGram Extension.XGram.Ast in |
25 val extend: syntax * (indexname -> sort) -> string list * string list * sext |
17 type syntax |
26 -> syntax |
18 val print_gram: syntax -> unit |
27 val merge: syntax * syntax -> syntax |
19 val print_trans: syntax -> unit |
28 val print_gram: syntax -> unit |
20 val print_syntax: syntax -> unit |
29 val print_trans: syntax -> unit |
21 val read_ast: syntax -> string * string -> ast |
30 val print_syntax: syntax -> unit |
22 val read: syntax -> typ -> string -> term |
31 val test_read: syntax -> string -> string -> unit |
23 val pretty_term: syntax -> term -> Pretty.T |
32 val read: syntax -> typ -> string -> term |
24 val pretty_typ: syntax -> typ -> Pretty.T |
33 val pretty_term: syntax -> term -> Pretty.T |
25 val string_of_term: syntax -> term -> string |
34 val pretty_typ: syntax -> typ -> Pretty.T |
26 val string_of_typ: syntax -> typ -> string |
35 val string_of_term: syntax -> term -> string |
27 val type_syn: syntax |
36 val string_of_typ: syntax -> typ -> string |
28 val extend: syntax * (indexname -> sort) -> string list * string list * sext |
|
29 -> syntax |
|
30 val merge: syntax * syntax -> syntax |
|
31 end |
|
32 end; |
37 end; |
33 |
38 |
34 functor SyntaxFun(structure Symtab: SYMTAB and TypeExt: TYPE_EXT |
39 functor SyntaxFun(structure Symtab: SYMTAB and TypeExt: TYPE_EXT |
35 and Parser: PARSER and SExtension: SEXTENSION and Printer: PRINTER |
40 and Parser: PARSER and SExtension: SEXTENSION and Printer: PRINTER |
36 sharing TypeExt.Extension.XGram = Parser.XGram = Printer.XGram |
41 sharing TypeExt.Extension = SExtension.Extension |
37 and TypeExt.Extension = SExtension.Extension |
42 and Parser.XGram = TypeExt.Extension.XGram = Printer.XGram |
38 and Parser.ParseTree.Ast = Parser.XGram.Ast)(*: SYNTAX *) = (* FIXME *) |
43 and Parser.XGram.Ast = Parser.ParseTree.Ast)(*: SYNTAX *) = (* FIXME *) |
39 struct |
44 struct |
40 |
45 |
41 structure Extension = TypeExt.Extension; |
46 structure Extension = TypeExt.Extension; |
42 structure XGram = Extension.XGram; |
47 structure XGram = Extension.XGram; |
43 structure Lexicon = Parser.ParseTree.Lexicon; |
48 structure Lexicon = Parser.ParseTree.Lexicon; |
44 open Lexicon Extension TypeExt SExtension Printer XGram XGram.Ast; |
49 open Lexicon Parser Parser.ParseTree Extension TypeExt SExtension Printer |
|
50 XGram XGram.Ast; |
45 |
51 |
46 |
52 |
47 fun lookup tab a = Symtab.lookup (tab, a); |
53 fun lookup tab a = Symtab.lookup (tab, a); |
48 |
54 |
49 |
55 |
50 |
56 |
51 (** datatype syntax **) |
57 (** datatype syntax **) |
52 |
58 |
53 datatype tables = |
59 datatype tables = |
54 Tab of { |
60 Tabs of { |
55 gram: Parser.Gram, |
61 lexicon: lexicon, |
56 lexicon: Lexicon, |
62 roots: string list, |
57 const_tab: unit Symtab.table, |
63 gram: gram, |
|
64 consts: string list, |
58 parse_ast_trtab: (ast list -> ast) Symtab.table, |
65 parse_ast_trtab: (ast list -> ast) Symtab.table, |
59 parse_preproc: ast -> ast, |
|
60 parse_ruletab: (ast * ast) list Symtab.table, |
66 parse_ruletab: (ast * ast) list Symtab.table, |
61 parse_postproc: ast -> ast, |
|
62 parse_trtab: (term list -> term) Symtab.table, |
67 parse_trtab: (term list -> term) Symtab.table, |
63 print_trtab: (term list -> term) Symtab.table, |
68 print_trtab: (term list -> term) Symtab.table, |
64 print_preproc: ast -> ast, |
|
65 print_ruletab: (ast * ast) list Symtab.table, |
69 print_ruletab: (ast * ast) list Symtab.table, |
66 print_postproc: ast -> ast, |
70 prtab: prtab}; |
67 print_tab: Printer.tab}; |
|
68 |
71 |
69 datatype gramgraph = |
72 datatype gramgraph = |
70 EmptyGG | |
73 EmptyGG | |
71 ExtGG of gramgraph ref * (ext * synrules) | |
74 ExtGG of gramgraph ref * (ext * synrules) | |
72 MergeGG of gramgraph ref * gramgraph ref; |
75 MergeGG of gramgraph ref * gramgraph ref; |
74 datatype syntax = Syntax of gramgraph ref * tables; |
77 datatype syntax = Syntax of gramgraph ref * tables; |
75 |
78 |
76 |
79 |
77 |
80 |
78 (*** compile syntax ***) |
81 (*** compile syntax ***) |
|
82 |
|
83 (* translation funs *) |
|
84 |
|
85 fun extend_trtab tab trfuns name = |
|
86 Symtab.balance (Symtab.st_of_alist (trfuns, tab)) handle Symtab.DUPLICATE s |
|
87 => error ("More than one " ^ name ^ " for " ^ quote s); |
|
88 |
|
89 val mk_trtab = extend_trtab Symtab.null; |
|
90 |
|
91 |
|
92 (* translation rules *) |
|
93 |
|
94 fun mk_ruletab rules = |
|
95 let |
|
96 fun add_rule (r, tab) = |
|
97 let val a = head_of_rule r; |
|
98 in |
|
99 (case lookup tab a of |
|
100 None => Symtab.update ((a, [r]), tab) |
|
101 | Some rs => Symtab.update ((a, r :: rs), tab)) |
|
102 end; |
|
103 in |
|
104 Symtab.balance (foldr add_rule (rules, Symtab.null)) |
|
105 end; |
|
106 |
|
107 fun extend_ruletab tab rules = |
|
108 mk_ruletab (flat (map #2 (Symtab.alist_of tab)) @ rules); |
|
109 |
|
110 |
|
111 (* mk_tables *) |
|
112 |
|
113 fun mk_tables (XGram xgram) = |
|
114 let |
|
115 val {roots, prods, consts, parse_ast_translation, parse_rules, |
|
116 parse_translation, print_translation, print_rules, |
|
117 print_ast_translation} = xgram; |
|
118 in |
|
119 Tabs { |
|
120 lexicon = mk_lexicon (literals_of prods), |
|
121 roots = roots, |
|
122 gram = mk_gram roots prods, |
|
123 consts = consts, |
|
124 parse_ast_trtab = mk_trtab parse_ast_translation "parse ast translation", |
|
125 parse_ruletab = mk_ruletab parse_rules, |
|
126 parse_trtab = mk_trtab parse_translation "parse translation", |
|
127 print_trtab = mk_trtab print_translation "print translation", |
|
128 print_ruletab = mk_ruletab print_rules, |
|
129 prtab = mk_prtab prods print_ast_translation} |
|
130 end; |
|
131 |
|
132 |
|
133 (* add_synrules *) |
|
134 |
|
135 fun add_synrules (Tabs tabs) (SynRules rules) = |
|
136 let |
|
137 val {lexicon, roots, gram, consts, parse_ast_trtab, parse_ruletab, |
|
138 parse_trtab, print_trtab, print_ruletab, prtab} = tabs; |
|
139 val {parse_rules, print_rules} = rules; |
|
140 in |
|
141 Tabs { |
|
142 lexicon = lexicon, roots = roots, gram = gram, consts = consts, |
|
143 parse_ast_trtab = parse_ast_trtab, |
|
144 parse_ruletab = extend_ruletab parse_ruletab parse_rules, |
|
145 parse_trtab = parse_trtab, |
|
146 print_trtab = print_trtab, |
|
147 print_ruletab = extend_ruletab print_ruletab print_rules, |
|
148 prtab = prtab} |
|
149 end; |
|
150 |
79 |
151 |
80 (* ggr_to_xgram *) |
152 (* ggr_to_xgram *) |
81 |
153 |
82 fun ggr_to_xgram ggr = |
154 fun ggr_to_xgram ggr = |
83 let |
155 let |
84 fun flatGG ggr (xg, v) = |
156 fun flatGG ggr (xg, v) = |
85 if ggr mem v then (xg, v) else flatGG' ggr (xg, ggr :: v) |
157 if ggr mem v then (xg, v) else flatGG' ggr (xg, ggr :: v) |
86 and flatGG' (ref EmptyGG) xgv = xgv |
158 and flatGG' (ref EmptyGG) xgv = xgv |
87 | flatGG' (ref (ExtGG (ggr, ext))) xgv = |
159 | flatGG' (ref (ExtGG (ggr, ext))) xgv = |
88 let |
160 let |
89 val (xg', v') = flatGG ggr xgv |
161 val (xg', v') = flatGG ggr xgv; |
90 in |
162 in |
91 (Extension.extend xg' ext, v') |
163 (extend_xgram xg' ext, v') |
92 end |
164 end |
93 | flatGG' (ref (MergeGG (ggr1, ggr2))) xgv = |
165 | flatGG' (ref (MergeGG (ggr1, ggr2))) xgv = |
94 flatGG ggr1 (flatGG ggr2 xgv); |
166 flatGG ggr1 (flatGG ggr2 xgv); |
95 in |
167 in |
96 fst (flatGG ggr (Extension.empty, [])) |
168 #1 (flatGG ggr (empty_xgram, [])) |
97 end; |
|
98 |
|
99 |
|
100 (* mk_ruletab *) |
|
101 |
|
102 fun mk_ruletab rules = |
|
103 let |
|
104 fun add_rule (r, tab) = |
|
105 let |
|
106 val a = head_of_rule r |
|
107 in |
|
108 case lookup tab a of |
|
109 None => Symtab.update ((a, [r]), tab) |
|
110 | Some rs => Symtab.update ((a, r :: rs), tab) |
|
111 end; |
|
112 in |
|
113 Symtab.balance (foldr add_rule (rules, Symtab.null)) |
|
114 end; |
169 end; |
115 |
170 |
116 |
171 |
117 (* make_syntax *) |
172 (* make_syntax *) |
118 |
173 |
119 fun make_syntax ggr = |
174 fun make_syntax ggr = Syntax (ggr, mk_tables (ggr_to_xgram ggr)); |
120 let |
|
121 fun mk_const_tab cs = |
|
122 Symtab.balance |
|
123 (Symtab.st_of_alist ((map (fn c => (c, ())) cs), Symtab.null)); |
|
124 |
|
125 fun mk_trtab alst name = |
|
126 Symtab.balance (Symtab.st_of_alist (alst, Symtab.null)) |
|
127 handle Symtab.DUPLICATE s => error ("More than one " ^ name ^ " for " ^ quote s); |
|
128 |
|
129 fun mk_proc (Some f) = f |
|
130 | mk_proc None = I; |
|
131 |
|
132 fun all_strings (opl: string prod list): string list = |
|
133 flat (map (fn Prod (_, syn, _, _) => terminals syn) opl); |
|
134 |
|
135 fun str_to_tok (opl: string prod list, lex: Lexicon): Token prod list = |
|
136 map |
|
137 (fn Prod (t, syn, s, pa) => |
|
138 Prod (t, translate (hd o tokenize lex) syn, s, pa)) |
|
139 opl; |
|
140 |
|
141 fun xgram_to_tables (XGram xgram) = |
|
142 let |
|
143 val {roots, prods, consts, parse_ast_translation, parse_preproc, parse_rules, |
|
144 parse_postproc, parse_translation, print_translation, print_preproc, |
|
145 print_rules, print_postproc, print_ast_translation} = xgram; |
|
146 val lexicon = mk_lexicon (all_strings prods); |
|
147 in |
|
148 Tab { |
|
149 gram = Parser.compile_xgram (roots, str_to_tok (prods, lexicon)), |
|
150 lexicon = lexicon, |
|
151 const_tab = mk_const_tab consts, |
|
152 parse_ast_trtab = mk_trtab parse_ast_translation "parse ast translation", |
|
153 parse_preproc = mk_proc parse_preproc, |
|
154 parse_ruletab = mk_ruletab parse_rules, |
|
155 parse_postproc = mk_proc parse_postproc, |
|
156 parse_trtab = mk_trtab parse_translation "parse translation", |
|
157 print_trtab = mk_trtab print_translation "print translation", |
|
158 print_preproc = mk_proc print_preproc, |
|
159 print_ruletab = mk_ruletab print_rules, |
|
160 print_postproc = mk_proc print_postproc, |
|
161 print_tab = mk_print_tab prods |
|
162 (mk_trtab print_ast_translation "print ast translation")} |
|
163 end; |
|
164 in |
|
165 Syntax (ggr, xgram_to_tables (ggr_to_xgram ggr)) |
|
166 end; |
|
167 |
|
168 |
|
169 (* add_synrules *) |
|
170 |
|
171 fun add_synrules (Tab tabs) (SynRules rules) = |
|
172 let |
|
173 val {gram, lexicon, const_tab, parse_ast_trtab, parse_preproc, parse_ruletab, |
|
174 parse_postproc, parse_trtab, print_trtab, print_preproc, print_ruletab, |
|
175 print_postproc, print_tab} = tabs; |
|
176 val {parse_rules, print_rules} = rules; |
|
177 val parse_rs = flat (map snd (Symtab.alist_of parse_ruletab)) @ parse_rules; |
|
178 val print_rs = flat (map snd (Symtab.alist_of print_ruletab)) @ print_rules; |
|
179 in |
|
180 Tab { |
|
181 gram = gram, lexicon = lexicon, const_tab = const_tab, |
|
182 parse_ast_trtab = parse_ast_trtab, |
|
183 parse_preproc = parse_preproc, |
|
184 parse_ruletab = mk_ruletab parse_rs, |
|
185 parse_postproc = parse_postproc, |
|
186 parse_trtab = parse_trtab, |
|
187 print_trtab = print_trtab, |
|
188 print_preproc = print_preproc, |
|
189 print_ruletab = mk_ruletab print_rs, |
|
190 print_postproc = print_postproc, |
|
191 print_tab = print_tab} |
|
192 end; |
|
193 |
175 |
194 |
176 |
195 |
177 |
196 (*** inspect syntax ***) |
178 (*** inspect syntax ***) |
197 |
|
198 (* print_syntax_old *) (* FIXME remove *) |
|
199 |
|
200 fun print_syntax_old (Syntax (_, Tab {gram, lexicon, ...})) = |
|
201 Parser.print_gram (gram, lexicon); |
|
202 |
|
203 |
|
204 |
179 |
205 fun xgram_of (Syntax (ggr, _)) = ggr_to_xgram ggr; |
180 fun xgram_of (Syntax (ggr, _)) = ggr_to_xgram ggr; |
206 |
181 |
207 fun string_of_big_list name prts = |
182 fun string_of_big_list name prts = |
208 Pretty.string_of (Pretty.blk (2, |
183 Pretty.string_of (Pretty.blk (2, |
209 separate Pretty.fbrk (Pretty.str name :: prts))); |
184 separate Pretty.fbrk (Pretty.str name :: prts))); |
210 |
185 |
211 |
186 fun string_of_strings name strs = |
212 (* print_gram *) (* FIXME check *) |
187 Pretty.string_of (Pretty.blk (2, |
|
188 separate (Pretty.brk 1) |
|
189 (map Pretty.str (name :: map quote (sort_strings strs))))); |
|
190 |
|
191 |
|
192 (* print_gram *) |
213 |
193 |
214 fun prt_gram (XGram {roots, prods, ...}) = |
194 fun prt_gram (XGram {roots, prods, ...}) = |
215 let |
195 let |
216 fun pretty_name name = [Pretty.str (name ^ " ="), Pretty.brk 1]; |
196 fun pretty_name name = [Pretty.str (name ^ " ="), Pretty.brk 1]; |
217 |
197 |
231 |
211 |
232 fun pretty_prod (Prod (name, xsymbs, const, pri)) = |
212 fun pretty_prod (Prod (name, xsymbs, const, pri)) = |
233 Pretty.blk (2, pretty_name name @ pretty_xsymbs xsymbs @ |
213 Pretty.blk (2, pretty_name name @ pretty_xsymbs xsymbs @ |
234 pretty_const const @ pretty_pri pri); |
214 pretty_const const @ pretty_pri pri); |
235 in |
215 in |
|
216 writeln (string_of_strings "lexicon:" (literals_of prods)); |
236 writeln (Pretty.string_of (Pretty.blk (2, |
217 writeln (Pretty.string_of (Pretty.blk (2, |
237 separate (Pretty.brk 1) (map Pretty.str ("roots:" :: roots))))); |
218 separate (Pretty.brk 1) (map Pretty.str ("roots:" :: roots))))); |
238 writeln (string_of_big_list "prods:" (map pretty_prod prods)) |
219 writeln (string_of_big_list "prods:" (map pretty_prod prods)) |
239 end; |
220 end; |
240 |
221 |
241 |
|
242 val print_gram = prt_gram o xgram_of; |
222 val print_gram = prt_gram o xgram_of; |
243 |
223 |
244 |
224 |
245 (* print_trans *) (* FIXME check *) |
225 (* print_trans *) |
246 |
226 |
247 fun prt_trans (XGram xgram) = |
227 fun prt_trans (XGram xgram) = |
248 let |
228 let |
249 fun string_of_strings name strs = |
|
250 Pretty.string_of (Pretty.blk (2, |
|
251 separate (Pretty.brk 1) (map Pretty.str (name :: map quote strs)))); |
|
252 |
|
253 fun string_of_trs name trs = string_of_strings name (map fst trs); |
229 fun string_of_trs name trs = string_of_strings name (map fst trs); |
254 |
|
255 fun string_of_proc name proc = |
|
256 Pretty.string_of (Pretty.blk (2, [Pretty.str name, Pretty.brk 1, |
|
257 Pretty.str (if is_none proc then "None" else "Some fn")])); |
|
258 |
230 |
259 fun string_of_rules name rules = |
231 fun string_of_rules name rules = |
260 string_of_big_list name (map pretty_rule rules); |
232 string_of_big_list name (map pretty_rule rules); |
261 |
233 |
262 |
234 val {consts, parse_ast_translation, parse_rules, parse_translation, |
263 val {consts, parse_ast_translation, parse_preproc, parse_rules, |
235 print_translation, print_rules, print_ast_translation, ...} = xgram; |
264 parse_postproc, parse_translation, print_translation, print_preproc, |
|
265 print_rules, print_postproc, print_ast_translation, ...} = xgram; |
|
266 in |
236 in |
267 writeln (string_of_strings "consts:" consts); |
237 writeln (string_of_strings "consts:" consts); |
268 writeln (string_of_trs "parse_ast_translation:" parse_ast_translation); |
238 writeln (string_of_trs "parse_ast_translation:" parse_ast_translation); |
269 writeln (string_of_proc "parse_preproc:" parse_preproc); |
|
270 writeln (string_of_rules "parse_rules:" parse_rules); |
239 writeln (string_of_rules "parse_rules:" parse_rules); |
271 writeln (string_of_proc "parse_postproc:" parse_postproc); |
|
272 writeln (string_of_trs "parse_translation:" parse_translation); |
240 writeln (string_of_trs "parse_translation:" parse_translation); |
273 writeln (string_of_trs "print_translation:" print_translation); |
241 writeln (string_of_trs "print_translation:" print_translation); |
274 writeln (string_of_proc "print_preproc:" print_preproc); |
|
275 writeln (string_of_rules "print_rules:" print_rules); |
242 writeln (string_of_rules "print_rules:" print_rules); |
276 writeln (string_of_proc "print_postproc:" print_postproc); |
|
277 writeln (string_of_trs "print_ast_translation:" print_ast_translation) |
243 writeln (string_of_trs "print_ast_translation:" print_ast_translation) |
278 end; |
244 end; |
279 |
245 |
280 |
|
281 val print_trans = prt_trans o xgram_of; |
246 val print_trans = prt_trans o xgram_of; |
282 |
247 |
283 |
248 |
284 (* print_syntax *) |
249 (* print_syntax *) |
285 |
250 |
292 |
257 |
293 |
258 |
294 |
259 |
295 (*** parsing and printing ***) |
260 (*** parsing and printing ***) |
296 |
261 |
297 (* read_ast *) |
262 (* mk_get_rules *) |
298 |
263 |
299 fun read_ast syn (root, s) = |
264 fun mk_get_rules ruletab = |
300 let |
|
301 val Syntax (_, Tab {gram, lexicon, parse_ast_trtab, ...}) = syn; |
|
302 val root = if Parser.parsable (gram, root) then root else error ("Unparsable root " ^ root) (* Extension.logic *); (* FIXME *) |
|
303 fun syn_err toks = |
|
304 error ("Syntax error at\n" ^ space_implode " " (map token_to_string toks)); |
|
305 in |
|
306 Parser.ParseTree.pt_to_ast (lookup parse_ast_trtab) |
|
307 (Parser.parse (gram, root, tokenize lexicon s)) |
|
308 handle Parser.SYNTAX_ERR toks => syn_err toks |
|
309 end; |
|
310 |
|
311 |
|
312 (* norm_ast *) |
|
313 |
|
314 fun norm_ast ruletab ast = |
|
315 let |
265 let |
316 fun get_rules a = |
266 fun get_rules a = |
317 (case lookup ruletab a of |
267 (case lookup ruletab a of |
318 Some rules => rules |
268 Some rules => rules |
319 | None => []); |
269 | None => []); |
320 in |
270 in |
321 normalize (if Symtab.is_null ruletab then None else Some get_rules) ast |
271 if Symtab.is_null ruletab then None else Some get_rules |
322 end; |
272 end; |
|
273 |
|
274 |
|
275 (* read_ast *) |
|
276 |
|
277 fun read_ast (Syntax (_, tabs)) xids root str = |
|
278 let |
|
279 val Tabs {lexicon, gram, parse_ast_trtab, ...} = tabs; |
|
280 in |
|
281 pt_to_ast (lookup parse_ast_trtab) |
|
282 (parse gram root (tokenize lexicon xids str)) |
|
283 end; |
|
284 |
|
285 |
|
286 |
|
287 (** test_read **) |
|
288 |
|
289 fun test_read (Syntax (_, tabs)) root str = |
|
290 let |
|
291 val Tabs {lexicon, gram, parse_ast_trtab, parse_ruletab, ...} = tabs; |
|
292 |
|
293 val toks = tokenize lexicon false str; |
|
294 val _ = writeln ("tokens: " ^ space_implode " " (map display_token toks)); |
|
295 |
|
296 val pt = parse gram root toks; |
|
297 val raw_ast = pt_to_ast (K None) pt; |
|
298 val _ = writeln ("raw: " ^ str_of_ast raw_ast); |
|
299 |
|
300 val pre_ast = pt_to_ast (lookup parse_ast_trtab) pt; |
|
301 val _ = normalize true true (mk_get_rules parse_ruletab) pre_ast; |
|
302 in () end; |
323 |
303 |
324 |
304 |
325 |
305 |
326 (** read **) |
306 (** read **) |
327 |
307 |
328 fun read (syn as Syntax (_, Tab tabs)) ty s = |
308 fun read (syn as Syntax (_, tabs)) ty str = |
329 let |
309 let |
330 val {parse_preproc, parse_ruletab, parse_postproc, parse_trtab, ...} = tabs; |
310 val Tabs {parse_ruletab, parse_trtab, ...} = tabs; |
331 val ast = read_ast syn (typ_to_nt ty, s); |
311 val ast = read_ast syn false (typ_to_nonterm ty) str; |
332 in |
312 in |
333 ast_to_term (lookup parse_trtab) |
313 ast_to_term (lookup parse_trtab) |
334 (parse_postproc (norm_ast parse_ruletab (parse_preproc ast))) |
314 (normalize_ast (mk_get_rules parse_ruletab) ast) |
335 end; |
315 end; |
336 |
316 |
337 |
317 |
338 |
318 |
339 (** pprint_ast **) |
319 (** read_rule **) |
340 |
320 |
341 val pprint_ast = Pretty.pprint o pretty_ast; |
321 fun read_rule syn (xrule as ((_, lhs_src), (_, rhs_src))) = |
342 |
322 let |
343 |
323 val Syntax (_, Tabs {consts, ...}) = syn; |
344 |
324 |
345 (** pretty term, typ **) |
325 fun constantify (ast as Constant _) = ast |
346 |
326 | constantify (ast as Variable x) = |
347 fun pretty_t t_to_ast pretty_t (syn as Syntax (_, Tab tabs)) t = |
327 if x mem consts then Constant x else ast |
348 let |
328 | constantify (Appl asts) = Appl (map constantify asts); |
349 val {print_trtab, print_preproc, print_ruletab, print_postproc, print_tab, ...} = tabs; |
329 |
350 val ast = t_to_ast (lookup print_trtab) t; |
330 fun read_pat (root, str) = |
351 in |
331 constantify (read_ast syn true root str) |
352 pretty_t print_tab |
332 handle ERROR => error ("The error above occurred in " ^ quote str); |
353 (print_postproc (norm_ast print_ruletab (print_preproc ast))) |
333 |
354 end; |
334 val rule as (lhs, rhs) = (pairself read_pat) xrule; |
355 |
335 in |
356 val pretty_term = pretty_t term_to_ast pretty_term_ast; |
336 (case rule_error rule of |
357 |
337 Some msg => |
358 val pretty_typ = pretty_t typ_to_ast pretty_typ_ast; |
338 error ("Error in syntax translation rule: " ^ msg ^ |
359 |
339 "\nexternal: " ^ quote lhs_src ^ " -> " ^ quote rhs_src ^ |
360 fun string_of_term syn t = Pretty.string_of (pretty_term syn t); |
340 "\ninternal: " ^ str_of_ast lhs ^ " -> " ^ str_of_ast rhs) |
361 |
341 | None => rule) |
362 fun string_of_typ syn ty = Pretty.string_of (pretty_typ syn ty); |
342 end; |
363 |
343 |
364 |
344 |
365 |
345 |
366 (*** build syntax ***) |
346 (** read_xrules **) |
367 |
347 |
368 (* type_syn *) |
348 fun read_xrules syn xrules = |
369 |
349 let |
370 val type_syn = make_syntax (ref (ExtGG (ref EmptyGG, (type_ext, empty_synrules)))); |
|
371 |
|
372 |
|
373 (* extend *) (* FIXME check *) |
|
374 |
|
375 fun extend (old_syn as Syntax (ggr, _), def_sort) (roots, xconsts, sext) = |
|
376 let |
|
377 fun read_typ s = typ_of_term def_sort (read old_syn typeT s); |
|
378 val ext = ext_of_sext roots xconsts read_typ sext; |
|
379 |
|
380 fun right_rule (xpat1 |-> xpat2) = Some (xpat1, xpat2) |
350 fun right_rule (xpat1 |-> xpat2) = Some (xpat1, xpat2) |
381 | right_rule (xpat1 <-| xpat2) = None |
351 | right_rule (xpat1 <-| xpat2) = None |
382 | right_rule (xpat1 <-> xpat2) = Some (xpat1, xpat2); |
352 | right_rule (xpat1 <-> xpat2) = Some (xpat1, xpat2); |
383 |
353 |
384 fun left_rule (xpat1 |-> xpat2) = None |
354 fun left_rule (xpat1 |-> xpat2) = None |
385 | left_rule (xpat1 <-| xpat2) = Some (xpat2, xpat1) |
355 | left_rule (xpat1 <-| xpat2) = Some (xpat2, xpat1) |
386 | left_rule (xpat1 <-> xpat2) = Some (xpat2, xpat1); |
356 | left_rule (xpat1 <-> xpat2) = Some (xpat2, xpat1); |
|
357 in |
|
358 (map (read_rule syn) (mapfilter right_rule xrules), |
|
359 map (read_rule syn) (mapfilter left_rule xrules)) |
|
360 end; |
|
361 |
|
362 |
|
363 |
|
364 (** pretty terms or typs **) |
|
365 |
|
366 fun pretty_t t_to_ast pretty_t (syn as Syntax (_, tabs)) t = |
|
367 let |
|
368 val Tabs {print_trtab, print_ruletab, prtab, ...} = tabs; |
|
369 val ast = t_to_ast (lookup print_trtab) t; |
|
370 in |
|
371 pretty_t prtab (normalize_ast (mk_get_rules print_ruletab) ast) |
|
372 end; |
|
373 |
|
374 val pretty_term = pretty_t term_to_ast pretty_term_ast; |
|
375 |
|
376 val pretty_typ = pretty_t typ_to_ast pretty_typ_ast; |
|
377 |
|
378 fun string_of_term syn t = Pretty.string_of (pretty_term syn t); |
|
379 |
|
380 fun string_of_typ syn ty = Pretty.string_of (pretty_typ syn ty); |
|
381 |
|
382 |
|
383 |
|
384 (*** build syntax ***) |
|
385 |
|
386 (* type_syn *) |
|
387 |
|
388 val type_syn = make_syntax (ref (ExtGG (ref EmptyGG, (type_ext, empty_synrules)))); |
|
389 |
|
390 |
|
391 (** extend **) |
|
392 |
|
393 fun extend (old_syn as Syntax (ggr, _), def_sort) (roots, xconsts, sext) = |
|
394 let |
|
395 fun read_typ s = typ_of_term def_sort (read old_syn typeT s); |
|
396 val ext = ext_of_sext roots xconsts read_typ sext; |
387 |
397 |
388 val (tmp_syn as Syntax (_, tmp_tabs)) = |
398 val (tmp_syn as Syntax (_, tmp_tabs)) = |
389 make_syntax (ref (ExtGG (ggr, (ext, empty_synrules)))); |
399 make_syntax (ref (ExtGG (ggr, (ext, empty_synrules)))); |
390 val Syntax (_, Tab {const_tab, ...}) = tmp_syn; |
400 |
391 |
401 val (parse_rules, print_rules) = read_xrules tmp_syn (xrules_of sext); |
392 fun constantify (ast as (Constant _)) = ast |
402 val rules = |
393 | constantify (ast as (Variable x)) = |
|
394 if is_some (lookup const_tab x) then Constant x else ast |
|
395 | constantify (Appl asts) = Appl (map constantify asts); |
|
396 |
|
397 fun read_pat (r_s as (root, s)) = |
|
398 constantify ((read_ast tmp_syn r_s) |
|
399 handle ERROR => error ("The error above occurred in " ^ quote s)); |
|
400 |
|
401 fun read_rule (xrule as ((_, lhs_src), (_, rhs_src))) = |
|
402 let |
|
403 val rule as (lhs, rhs) = (pairself read_pat) xrule; |
|
404 in |
|
405 case rule_error rule of |
|
406 Some msg => |
|
407 error ("Error in syntax translation rule: " ^ msg ^ |
|
408 "\nexternal: " ^ quote lhs_src ^ " -> " ^ quote rhs_src ^ |
|
409 "\ninternal: " ^ str_of_ast lhs ^ " -> " ^ str_of_ast rhs) |
|
410 | None => rule |
|
411 end; |
|
412 |
|
413 val xrules = xrules_of sext; |
|
414 val new_rules = |
|
415 SynRules { |
403 SynRules { |
416 parse_rules = map read_rule (mapfilter right_rule xrules), |
404 parse_rules = parse_rules, |
417 print_rules = map read_rule (mapfilter left_rule xrules)}; |
405 print_rules = print_rules}; |
418 in |
406 in |
419 Syntax (ref (ExtGG (ggr, (ext, new_rules))), add_synrules tmp_tabs new_rules) |
407 Syntax (ref (ExtGG (ggr, (ext, rules))), add_synrules tmp_tabs rules) |
420 end; |
408 end; |
421 |
409 |
422 |
410 |
423 (* merge *) |
411 (* merge *) |
424 |
412 |