75 chain productions are not stored as normal productions |
75 chain productions are not stored as normal productions |
76 but instead as an entry in "chains": from -> to; |
76 but instead as an entry in "chains": from -> to; |
77 lambda productions are stored as normal productions |
77 lambda productions are stored as normal productions |
78 and also as an entry in "lambdas"*) |
78 and also as an entry in "lambdas"*) |
79 |
79 |
80 val union_token = union Lexicon.matching_tokens; |
80 fun tokens_match toks = |
81 val subtract_token = subtract Lexicon.matching_tokens; |
81 (case apply2 Lexicon.kind_of_token toks of |
|
82 (Lexicon.Literal, Lexicon.Literal) => op = (apply2 Lexicon.str_of_token toks) |
|
83 | kinds => op = kinds); |
|
84 |
|
85 val tokens_union = union tokens_match; |
|
86 val tokens_subtract = subtract tokens_match; |
82 |
87 |
83 (*productions for which no starting token is |
88 (*productions for which no starting token is |
84 known yet are associated with this token*) |
89 known yet are associated with this token*) |
85 val unknown_start = Lexicon.eof; |
90 val unknown_start = Lexicon.eof; |
86 |
91 |
171 val new_lambda = |
176 val new_lambda = |
172 is_none tk andalso forall (lambdas_member lambdas) nts; |
177 is_none tk andalso forall (lambdas_member lambdas) nts; |
173 |
178 |
174 val new_tks = |
179 val new_tks = |
175 (if is_some tk then [the tk] else []) |
180 (if is_some tk then [the tk] else []) |
176 |> fold (union_token o starts_for_nt) nts |
181 |> fold (tokens_union o starts_for_nt) nts |
177 |> subtract (op =) l_starts; |
182 |> subtract (op =) l_starts; |
178 |
183 |
179 val added_tks' = union_token added_tks new_tks; |
184 val added_tks' = tokens_union added_tks new_tks; |
180 |
185 |
181 val nt_dependencies' = union (op =) nts nt_dependencies; |
186 val nt_dependencies' = union (op =) nts nt_dependencies; |
182 |
187 |
183 (*associate production with new starting tokens*) |
188 (*associate production with new starting tokens*) |
184 fun copy ([]: Lexicon.token option list) nt_prods = nt_prods |
189 fun copy ([]: Lexicon.token option list) nt_prods = nt_prods |
260 NTs lookahead depends*) |
265 NTs lookahead depends*) |
261 val (start_tk, start_nts) = lookahead_dependency lambdas' rhs []; |
266 val (start_tk, start_nts) = lookahead_dependency lambdas' rhs []; |
262 |
267 |
263 val start_tks = |
268 val start_tks = |
264 (if is_some start_tk then [the start_tk] else []) |
269 (if is_some start_tk then [the start_tk] else []) |
265 |> fold (union_token o starts_for_nt) start_nts; |
270 |> fold (tokens_union o starts_for_nt) start_nts; |
266 |
271 |
267 val opt_starts = |
272 val opt_starts = |
268 (if is_some new_lambdas then [NONE] |
273 (if is_some new_lambdas then [NONE] |
269 else if null start_tks then [SOME unknown_start] |
274 else if null start_tks then [SOME unknown_start] |
270 else []) @ map SOME start_tks; |
275 else []) @ map SOME start_tks; |
282 fun add_tks [] added prod_count = (added, prod_count) |
287 fun add_tks [] added prod_count = (added, prod_count) |
283 | add_tks (nt :: nts) added prod_count = |
288 | add_tks (nt :: nts) added prod_count = |
284 let |
289 let |
285 val ((old_nts, old_tks), nt_prods) = Array.sub (prods, nt); |
290 val ((old_nts, old_tks), nt_prods) = Array.sub (prods, nt); |
286 |
291 |
287 val new_tks = subtract_token old_tks start_tks; |
292 val new_tks = tokens_subtract old_tks start_tks; |
288 |
293 |
289 (*store new production*) |
294 (*store new production*) |
290 fun store [] prods is_new = |
295 fun store [] prods is_new = |
291 (prods, |
296 (prods, |
292 if is_some prod_count andalso is_new then |
297 if is_some prod_count andalso is_new then |
396 val nt_prods'' = |
401 val nt_prods'' = |
397 if key = SOME unknown_start then |
402 if key = SOME unknown_start then |
398 AList.update (op =) (key, tk_prods') nt_prods' |
403 AList.update (op =) (key, tk_prods') nt_prods' |
399 else nt_prods'; |
404 else nt_prods'; |
400 |
405 |
401 val added_tks = subtract_token old_tks new_tks; |
406 val added_tks = tokens_subtract old_tks new_tks; |
402 in |
407 in |
403 if null added_tks then |
408 if null added_tks then |
404 (Array.update (prods, nt, (lookahead, nt_prods'')); |
409 (Array.update (prods, nt, (lookahead, nt_prods'')); |
405 process_nts nts added) |
410 process_nts nts added) |
406 else |
411 else |
627 let |
632 let |
628 fun token_assoc (list, key) = |
633 fun token_assoc (list, key) = |
629 let |
634 let |
630 fun assoc [] result = result |
635 fun assoc [] result = result |
631 | assoc ((keyi, pi) :: pairs) result = |
636 | assoc ((keyi, pi) :: pairs) result = |
632 if is_some keyi andalso Lexicon.matching_tokens (the keyi, key) |
637 if is_some keyi andalso tokens_match (the keyi, key) |
633 orelse include_none andalso is_none keyi then |
638 orelse include_none andalso is_none keyi then |
634 assoc pairs (pi @ result) |
639 assoc pairs (pi @ result) |
635 else assoc pairs result; |
640 else assoc pairs result; |
636 in assoc list [] end; |
641 in assoc list [] end; |
637 |
642 |
671 in |
676 in |
672 processS used' (new_states @ States) (S :: Si, Sii) |
677 processS used' (new_states @ States) (S :: Si, Sii) |
673 end |
678 end |
674 | (_, _, _, Terminal a :: _, _, _) => (*scanner operation*) |
679 | (_, _, _, Terminal a :: _, _, _) => (*scanner operation*) |
675 processS used States |
680 processS used States |
676 (S :: Si, |
681 (S :: Si, if tokens_match (a, c) then movedot_term c S :: Sii else Sii) |
677 if Lexicon.matching_tokens (a, c) then movedot_term c S :: Sii else Sii) |
|
678 | (A, prec, ts, [], id, j) => (*completer operation*) |
682 | (A, prec, ts, [], id, j) => (*completer operation*) |
679 let val tt = if id = "" then ts else [Node (id, rev ts)] in |
683 let val tt = if id = "" then ts else [Node (id, rev ts)] in |
680 if j = i then (*lambda production?*) |
684 if j = i then (*lambda production?*) |
681 let |
685 let |
682 val (prec', used') = update_trees (A, (tt, prec)) used; |
686 val (prec', used') = update_trees (A, (tt, prec)) used; |