142 let |
142 let |
143 fun del_of (Delim s) = SOME s |
143 fun del_of (Delim s) = SOME s |
144 | del_of _ = NONE; |
144 | del_of _ = NONE; |
145 |
145 |
146 fun dels_of (XProd (_, xsymbs, _, _)) = |
146 fun dels_of (XProd (_, xsymbs, _, _)) = |
147 mapfilter del_of xsymbs; |
147 List.mapPartial del_of xsymbs; |
148 in |
148 in |
149 map Symbol.explode (distinct (flat (map dels_of xprods))) |
149 map Symbol.explode (distinct (List.concat (map dels_of xprods))) |
150 end; |
150 end; |
151 |
151 |
152 |
152 |
153 |
153 |
154 (** datatype mfix **) |
154 (** datatype mfix **) |
204 val scan_symb = |
204 val scan_symb = |
205 scan_sym >> SOME || |
205 scan_sym >> SOME || |
206 $$ "'" -- Scan.one Symbol.is_blank >> K NONE; |
206 $$ "'" -- Scan.one Symbol.is_blank >> K NONE; |
207 |
207 |
208 val scan_symbs = Scan.repeat scan_symb --| Scan.ahead (Scan.one (not_equal "'")); |
208 val scan_symbs = Scan.repeat scan_symb --| Scan.ahead (Scan.one (not_equal "'")); |
209 val read_symbs = mapfilter I o the o Scan.read Symbol.stopper scan_symbs; |
209 val read_symbs = List.mapPartial I o valOf o Scan.read Symbol.stopper scan_symbs; |
210 |
210 |
211 fun unique_index xsymbs = |
211 fun unique_index xsymbs = |
212 if length (filter is_index xsymbs) <= 1 then xsymbs |
212 if length (List.filter is_index xsymbs) <= 1 then xsymbs |
213 else error "Duplicate index arguments (\\<index>)"; |
213 else error "Duplicate index arguments (\\<index>)"; |
214 in |
214 in |
215 val read_mixfix = unique_index o read_symbs o Symbol.explode; |
215 val read_mixfix = unique_index o read_symbs o Symbol.explode; |
216 val mfix_args = length o filter is_argument o read_mixfix; |
216 val mfix_args = length o List.filter is_argument o read_mixfix; |
217 val escape_mfix = implode o map (fn s => if is_meta s then "'" ^ s else s) o Symbol.explode; |
217 val escape_mfix = implode o map (fn s => if is_meta s then "'" ^ s else s) o Symbol.explode; |
218 end; |
218 end; |
219 |
219 |
220 |
220 |
221 (* mfix_to_xprod *) |
221 (* mfix_to_xprod *) |
259 if s <> "prop" andalso is_logtype s then Argument (logic, p) else a |
259 if s <> "prop" andalso is_logtype s then Argument (logic, p) else a |
260 | logify_types _ a = a; |
260 | logify_types _ a = a; |
261 |
261 |
262 |
262 |
263 val raw_symbs = read_mixfix sy handle ERROR => err_in_mfix "" mfix; |
263 val raw_symbs = read_mixfix sy handle ERROR => err_in_mfix "" mfix; |
264 val args = filter (fn Argument _ => true | _ => false) raw_symbs; |
264 val args = List.filter (fn Argument _ => true | _ => false) raw_symbs; |
265 val (const', typ', parse_rules) = |
265 val (const', typ', parse_rules) = |
266 if not (exists is_index args) then (const, typ, []) |
266 if not (exists is_index args) then (const, typ, []) |
267 else |
267 else |
268 let |
268 let |
269 val indexed_const = if const <> "" then "_indexed_" ^ const |
269 val indexed_const = if const <> "" then "_indexed_" ^ const |
291 (if lhs = "prop" then sprop else if is_logtype lhs then logic else lhs) |
291 (if lhs = "prop" then sprop else if is_logtype lhs then logic else lhs) |
292 else lhs; |
292 else lhs; |
293 val symbs' = map (logify_types copy_prod) symbs; |
293 val symbs' = map (logify_types copy_prod) symbs; |
294 val xprod = XProd (lhs', symbs', const', pri); |
294 val xprod = XProd (lhs', symbs', const', pri); |
295 |
295 |
296 val _ = (seq check_pri pris; check_pri pri; check_blocks symbs'); |
296 val _ = (List.app check_pri pris; check_pri pri; check_blocks symbs'); |
297 val xprod' = |
297 val xprod' = |
298 if Lexicon.is_terminal lhs' then err_in_mfix ("Illegal lhs: " ^ lhs') mfix |
298 if Lexicon.is_terminal lhs' then err_in_mfix ("Illegal lhs: " ^ lhs') mfix |
299 else if const <> "" then xprod |
299 else if const <> "" then xprod |
300 else if length (filter is_argument symbs') <> 1 then |
300 else if length (List.filter is_argument symbs') <> 1 then |
301 err_in_mfix "Copy production must have exactly one argument" mfix |
301 err_in_mfix "Copy production must have exactly one argument" mfix |
302 else if exists is_terminal symbs' then xprod |
302 else if exists is_terminal symbs' then xprod |
303 else XProd (lhs', map rem_pri symbs', "", chain_pri); |
303 else XProd (lhs', map rem_pri symbs', "", chain_pri); |
304 |
304 |
305 in (xprod', parse_rules) end; |
305 in (xprod', parse_rules) end; |
328 let |
328 let |
329 val (parse_ast_translation, parse_translation, print_translation, |
329 val (parse_ast_translation, parse_translation, print_translation, |
330 print_ast_translation) = trfuns; |
330 print_ast_translation) = trfuns; |
331 |
331 |
332 val (xprods, parse_rules') = map (mfix_to_xprod convert is_logtype) mfixes |
332 val (xprods, parse_rules') = map (mfix_to_xprod convert is_logtype) mfixes |
333 |> split_list |> apsnd (rev o flat); |
333 |> split_list |> apsnd (rev o List.concat); |
334 val mfix_consts = distinct (map (fn Mfix x => #3 x) mfixes @ map (fn XProd x => #3 x) xprods); |
334 val mfix_consts = distinct (map (fn Mfix x => #3 x) mfixes @ map (fn XProd x => #3 x) xprods); |
335 in |
335 in |
336 SynExt { |
336 SynExt { |
337 xprods = xprods, |
337 xprods = xprods, |
338 consts = consts union_string mfix_consts, |
338 consts = consts union_string mfix_consts, |