src/Pure/Syntax/parser.ML
changeset 67532 71b36ff8f94d
parent 67531 d19686205f86
child 67533 f253e5eaf995
equal deleted inserted replaced
67531:d19686205f86 67532:71b36ff8f94d
    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;