emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master ab6f759: * externals-list: Convert wisi to :external


From: Stefan Monnier
Subject: [elpa] master ab6f759: * externals-list: Convert wisi to :external
Date: Sat, 28 Nov 2020 14:48:03 -0500 (EST)

branch: master
commit ab6f7599ecd637a08b59b247807a40d1ed6f5dc1
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * externals-list: Convert wisi to :external
---
 externals-list                                     |    1 +
 packages/wisi/NEWS                                 |  303 --
 packages/wisi/README                               |   14 -
 packages/wisi/build-wisitoken-bnf-generate.sh      |    7 -
 packages/wisi/dir                                  |   19 -
 packages/wisi/emacs_wisi_common_parse.adb          |  508 ---
 packages/wisi/emacs_wisi_common_parse.ads          |  157 -
 packages/wisi/gen_emacs_wisi_lr_parse.adb          |   39 -
 packages/wisi/gen_emacs_wisi_lr_parse.ads          |   55 -
 packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb |   44 -
 packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads |   50 -
 packages/wisi/gen_emacs_wisi_packrat_parse.adb     |  180 -
 packages/wisi/gen_emacs_wisi_packrat_parse.ads     |   42 -
 packages/wisi/gen_run_wisi_libadalang_parse.adb    |  176 -
 packages/wisi/gen_run_wisi_libadalang_parse.ads    |   30 -
 packages/wisi/gen_run_wisi_lr_parse.adb            |   37 -
 packages/wisi/gen_run_wisi_lr_parse.ads            |   42 -
 packages/wisi/gen_run_wisi_lr_text_rep_parse.adb   |   44 -
 packages/wisi/gen_run_wisi_lr_text_rep_parse.ads   |   44 -
 packages/wisi/gen_run_wisi_packrat_parse.adb       |  241 --
 packages/wisi/gen_run_wisi_packrat_parse.ads       |   36 -
 packages/wisi/long_float_elementary_functions.ads  |   21 -
 packages/wisi/recover_stats.adb                    |  271 --
 packages/wisi/run_wisi_common_parse.adb            |  356 --
 packages/wisi/run_wisi_common_parse.ads            |   73 -
 ...da_containers-gen_doubly_linked_lists_image.adb |   50 -
 ...da_containers-gen_doubly_linked_lists_image.ads |   28 -
 packages/wisi/sal-ada_containers.ads               |   21 -
 packages/wisi/sal-gen_array_image.adb              |   34 -
 packages/wisi/sal-gen_array_image.ads              |   24 -
 packages/wisi/sal-gen_bounded_definite_queues.adb  |  103 -
 packages/wisi/sal-gen_bounded_definite_queues.ads  |  117 -
 ...l-gen_bounded_definite_stacks-gen_image_aux.adb |   42 -
 ...l-gen_bounded_definite_stacks-gen_image_aux.ads |   27 -
 packages/wisi/sal-gen_bounded_definite_stacks.adb  |   82 -
 packages/wisi/sal-gen_bounded_definite_stacks.ads  |  103 -
 .../sal-gen_bounded_definite_vectors-gen_image.adb |   40 -
 .../sal-gen_bounded_definite_vectors-gen_image.ads |   23 -
 ...-gen_bounded_definite_vectors-gen_image_aux.adb |   35 -
 ...-gen_bounded_definite_vectors-gen_image_aux.ads |   23 -
 .../sal-gen_bounded_definite_vectors-gen_refs.adb  |   35 -
 .../sal-gen_bounded_definite_vectors-gen_refs.ads  |   54 -
 packages/wisi/sal-gen_bounded_definite_vectors.adb |  120 -
 packages/wisi/sal-gen_bounded_definite_vectors.ads |  145 -
 ...unded_definite_vectors_sorted-gen_image_aux.adb |   35 -
 ...unded_definite_vectors_sorted-gen_image_aux.ads |   23 -
 ...en_bounded_definite_vectors_sorted-gen_refs.adb |   29 -
 ...en_bounded_definite_vectors_sorted-gen_refs.ads |   39 -
 .../sal-gen_bounded_definite_vectors_sorted.adb    |   96 -
 .../sal-gen_bounded_definite_vectors_sorted.ads    |  100 -
 .../wisi/sal-gen_definite_doubly_linked_lists.adb  |  317 --
 .../wisi/sal-gen_definite_doubly_linked_lists.ads  |  172 -
 ...finite_doubly_linked_lists_sorted-gen_image.adb |   47 -
 ...finite_doubly_linked_lists_sorted-gen_image.ads |   25 -
 ...sal-gen_definite_doubly_linked_lists_sorted.adb |  542 ---
 ...sal-gen_definite_doubly_linked_lists_sorted.ads |  190 -
 packages/wisi/sal-gen_graphs.adb                   |  719 ----
 packages/wisi/sal-gen_graphs.ads                   |  190 -
 .../sal-gen_indefinite_doubly_linked_lists.adb     |  211 -
 .../sal-gen_indefinite_doubly_linked_lists.ads     |  128 -
 packages/wisi/sal-gen_trimmed_image.adb            |   28 -
 packages/wisi/sal-gen_trimmed_image.ads            |   23 -
 ...-gen_unbounded_definite_min_heaps_fibonacci.adb |  354 --
 ...-gen_unbounded_definite_min_heaps_fibonacci.ads |  112 -
 ...gen_unbounded_definite_queues-gen_image_aux.adb |   35 -
 ...gen_unbounded_definite_queues-gen_image_aux.ads |   23 -
 .../wisi/sal-gen_unbounded_definite_queues.adb     |   97 -
 .../wisi/sal-gen_unbounded_definite_queues.ads     |  110 -
 .../sal-gen_unbounded_definite_red_black_trees.adb |  870 ----
 .../sal-gen_unbounded_definite_red_black_trees.ads |  198 -
 ...gen_unbounded_definite_stacks-gen_image_aux.adb |   42 -
 ...gen_unbounded_definite_stacks-gen_image_aux.ads |   27 -
 .../wisi/sal-gen_unbounded_definite_stacks.adb     |  219 -
 .../wisi/sal-gen_unbounded_definite_stacks.ads     |  158 -
 ...n_unbounded_definite_vectors-gen_comparable.adb |   73 -
 ...n_unbounded_definite_vectors-gen_comparable.ads |   30 -
 ...al-gen_unbounded_definite_vectors-gen_image.adb |   50 -
 ...al-gen_unbounded_definite_vectors-gen_image.ads |   24 -
 ...en_unbounded_definite_vectors-gen_image_aux.adb |   43 -
 ...en_unbounded_definite_vectors-gen_image_aux.ads |   28 -
 .../wisi/sal-gen_unbounded_definite_vectors.adb    |  585 ---
 .../wisi/sal-gen_unbounded_definite_vectors.ads    |  252 --
 .../sal-gen_unbounded_definite_vectors_sorted.adb  |  374 --
 .../sal-gen_unbounded_definite_vectors_sorted.ads  |  172 -
 .../wisi/sal-gen_unconstrained_array_image.adb     |   34 -
 .../wisi/sal-gen_unconstrained_array_image.ads     |   24 -
 .../wisi/sal-gen_unconstrained_array_image_aux.adb |   33 -
 .../wisi/sal-gen_unconstrained_array_image_aux.ads |   25 -
 packages/wisi/sal-generic_decimal_image.adb        |   48 -
 packages/wisi/sal-generic_decimal_image.ads        |   37 -
 packages/wisi/sal.adb                              |   32 -
 packages/wisi/sal.ads                              |   75 -
 packages/wisi/standard_common.gpr                  |  152 -
 packages/wisi/wisi-fringe.el                       |  152 -
 packages/wisi/wisi-parse-common.el                 |  403 --
 packages/wisi/wisi-prj.el                          | 1614 --------
 packages/wisi/wisi-process-parse.el                |  844 ----
 packages/wisi/wisi-run-indent-test.el              |  399 --
 packages/wisi/wisi-skel.el                         |  187 -
 packages/wisi/wisi-tests.el                        |  120 -
 packages/wisi/wisi.adb                             | 2434 -----------
 packages/wisi/wisi.ads                             |  769 ----
 packages/wisi/wisi.el                              | 1725 --------
 packages/wisi/wisi.gpr.gp                          |   64 -
 packages/wisi/wisi.info                            | 1294 ------
 packages/wisi/wisi.texi                            |  812 ----
 packages/wisi/wisitoken-bnf-generate.adb           |  634 ---
 packages/wisi/wisitoken-bnf-generate_grammar.adb   |   86 -
 packages/wisi/wisitoken-bnf-generate_packrat.adb   |  333 --
 packages/wisi/wisitoken-bnf-generate_utils.adb     |  724 ----
 packages/wisi/wisitoken-bnf-generate_utils.ads     |  174 -
 packages/wisi/wisitoken-bnf-output_ada.adb         |  512 ---
 packages/wisi/wisitoken-bnf-output_ada_common.adb  | 1392 -------
 packages/wisi/wisitoken-bnf-output_ada_common.ads  |   90 -
 packages/wisi/wisitoken-bnf-output_ada_emacs.adb   | 1916 ---------
 .../wisi/wisitoken-bnf-output_elisp_common.adb     |  212 -
 .../wisi/wisitoken-bnf-output_elisp_common.ads     |   54 -
 packages/wisi/wisitoken-bnf-utils.adb              |   45 -
 packages/wisi/wisitoken-bnf-utils.ads              |   29 -
 packages/wisi/wisitoken-bnf.adb                    |  355 --
 packages/wisi/wisitoken-bnf.ads                    |  358 --
 packages/wisi/wisitoken-followed_by.adb            |  207 -
 packages/wisi/wisitoken-gen_token_enum.adb         |  133 -
 packages/wisi/wisitoken-gen_token_enum.ads         |  122 -
 .../wisi/wisitoken-generate-lr-lalr_generate.adb   |  611 ---
 .../wisi/wisitoken-generate-lr-lalr_generate.ads   |   87 -
 .../wisi/wisitoken-generate-lr-lr1_generate.adb    |  343 --
 .../wisi/wisitoken-generate-lr-lr1_generate.ads    |   91 -
 packages/wisi/wisitoken-generate-lr.adb            | 1510 -------
 packages/wisi/wisitoken-generate-lr.ads            |  214 -
 packages/wisi/wisitoken-generate-lr1_items.adb     |  553 ---
 packages/wisi/wisitoken-generate-lr1_items.ads     |  335 --
 packages/wisi/wisitoken-generate-packrat.adb       |  247 --
 packages/wisi/wisitoken-generate-packrat.ads       |   75 -
 packages/wisi/wisitoken-generate.adb               |  665 ---
 packages/wisi/wisitoken-generate.ads               |  200 -
 packages/wisi/wisitoken-lexer-re2c.adb             |  307 --
 packages/wisi/wisitoken-lexer-re2c.ads             |  144 -
 packages/wisi/wisitoken-lexer-regexp.adb           |  259 --
 packages/wisi/wisitoken-lexer-regexp.ads           |  114 -
 packages/wisi/wisitoken-lexer.adb                  |   61 -
 packages/wisi/wisitoken-lexer.ads                  |  187 -
 .../wisitoken-parse-lr-mckenzie_recover-base.adb   |  451 --
 .../wisitoken-parse-lr-mckenzie_recover-base.ads   |  185 -
 ...wisitoken-parse-lr-mckenzie_recover-explore.adb | 1875 ---------
 ...wisitoken-parse-lr-mckenzie_recover-explore.ads |   28 -
 .../wisitoken-parse-lr-mckenzie_recover-parse.adb  |  327 --
 .../wisitoken-parse-lr-mckenzie_recover-parse.ads  |   83 -
 .../wisi/wisitoken-parse-lr-mckenzie_recover.adb   | 1306 ------
 .../wisi/wisitoken-parse-lr-mckenzie_recover.ads   |  310 --
 packages/wisi/wisitoken-parse-lr-parser.adb        | 1256 ------
 packages/wisi/wisitoken-parse-lr-parser.ads        |  162 -
 packages/wisi/wisitoken-parse-lr-parser_lists.adb  |  416 --
 packages/wisi/wisitoken-parse-lr-parser_lists.ads  |  274 --
 .../wisi/wisitoken-parse-lr-parser_no_recover.adb  |  574 ---
 .../wisi/wisitoken-parse-lr-parser_no_recover.ads  |   92 -
 packages/wisi/wisitoken-parse-lr.adb               |  767 ----
 packages/wisi/wisitoken-parse-lr.ads               |  698 ----
 .../wisi/wisitoken-parse-packrat-generated.adb     |   96 -
 .../wisi/wisitoken-parse-packrat-generated.ads     |   76 -
 .../wisi/wisitoken-parse-packrat-procedural.adb    |  267 --
 .../wisi/wisitoken-parse-packrat-procedural.ads    |   86 -
 packages/wisi/wisitoken-parse-packrat.adb          |   63 -
 packages/wisi/wisitoken-parse-packrat.ads          |   75 -
 packages/wisi/wisitoken-parse.adb                  |  108 -
 packages/wisi/wisitoken-parse.ads                  |   84 -
 packages/wisi/wisitoken-parse_table-mode.el        |   95 -
 packages/wisi/wisitoken-productions.adb            |   83 -
 packages/wisi/wisitoken-productions.ads            |   88 -
 packages/wisi/wisitoken-semantic_checks.adb        |  152 -
 packages/wisi/wisitoken-semantic_checks.ads        |  106 -
 packages/wisi/wisitoken-syntax_trees-lr_utils.adb  |  939 -----
 packages/wisi/wisitoken-syntax_trees-lr_utils.ads  |  475 ---
 packages/wisi/wisitoken-syntax_trees.adb           | 2111 ----------
 packages/wisi/wisitoken-syntax_trees.ads           |  805 ----
 packages/wisi/wisitoken-text_io_trace.adb          |  113 -
 packages/wisi/wisitoken-text_io_trace.ads          |   53 -
 packages/wisi/wisitoken-to_tree_sitter.adb         |  528 ---
 packages/wisi/wisitoken-user_guide.info            |  611 ---
 packages/wisi/wisitoken-wisi_ada.adb               |  160 -
 packages/wisi/wisitoken-wisi_ada.ads               |   81 -
 packages/wisi/wisitoken.adb                        |  367 --
 packages/wisi/wisitoken.ads                        |  508 ---
 packages/wisi/wisitoken_grammar_actions.adb        |  182 -
 packages/wisi/wisitoken_grammar_actions.ads        |  237 --
 packages/wisi/wisitoken_grammar_main.adb           |  662 ---
 packages/wisi/wisitoken_grammar_main.ads           |   34 -
 packages/wisi/wisitoken_grammar_re2c.c             | 4303 --------------------
 packages/wisi/wisitoken_grammar_re2c_c.ads         |   63 -
 packages/wisi/wisitoken_grammar_runtime.adb        | 3442 ----------------
 packages/wisi/wisitoken_grammar_runtime.ads        |  166 -
 191 files changed, 1 insertion(+), 61364 deletions(-)

diff --git a/externals-list b/externals-list
index 4fbb1b9..1e25d68 100644
--- a/externals-list
+++ b/externals-list
@@ -179,6 +179,7 @@
  ("webfeeder"          :external 
"https://gitlab.com/ambrevar/emacs-webfeeder.git";)
  ("websocket"          :external 
"https://github.com/ahyatt/emacs-websocket.git";)
  ("windower"           :external "https://gitlab.com/ambrevar/emacs-windower";)
+ ("wisi" :external nil)
  ("wisitoken-grammar-mode" :external nil)
  ("which-key"           :external "https://github.com/justbur/emacs-which-key";)
  ("wpuzzle" :external nil)
diff --git a/packages/wisi/NEWS b/packages/wisi/NEWS
deleted file mode 100644
index 621c257..0000000
--- a/packages/wisi/NEWS
+++ /dev/null
@@ -1,303 +0,0 @@
-GNU Emacs wisi NEWS -- history of user-visible changes.
-
-Copyright (C) 2014 - 2020 Free Software Foundation, Inc.
-
-Please send wisi bug reports to bug-gnu-emacs@gnu.org, with
-'wisi' in the subject. If possible, use M-x report-emacs-bug.
-
-
-* wisi 3.1.2
-4 Jun 2020
-
-** New dispatching function wisi-xref-completion-delim-regex for
-   setting completion delimiters; example use in gpr-query.el.
-
-** wisi-get-identifier (used by wisi-goto-spec/body and others) sets
-   completion delimiters using wisi-xref-completion-delim-regex.
-
-** A bug in wisi-before-change is fixed; it was missing many buffer
-   changes, causing the parser not to be run when it should be.
-
-* wisi 3.1.1
-14 May 2020
-
-** packaging bug fix
-
-* wisi 3.1.0
-11 May 2020
-
-** Add Wisitoken.Syntax_Trees.Insert_Token, to allow using inserted
-   virtual terminals tokens in indent. Several related changes to
-   allow treating virtual terminals on par with actual terminals.
-
-** New elisp generic functions: wisi-xref-completion-table, 
wisi-xref-completion-regexp, wisi-xref-completion-at-point-table
-
-** New elisp functions: wisi-filter-table, wisi-completion-at-point, 
wisi-skel-add-token-after
-
-** wisi-get-identifier uses wisi-xref-completion-table.
-
-** wisi-prj-identifier-at-point returns (IDENT START END)
-
-** In wisi.ads: augmented tokens are no stored only in the syntax
-   tree; new functions Get_Aug_Token_Const_1, Get_Aug_Token_Const,
-   Get_Aug_Token_Var provide access to them. Parse_Data_Type contains
-   a reference to the shared Terminals.
-
-* wisi 3.0.1
-30 Jan 2020
-
-** fix packaging bugs
-
-** improve xref integration
-
-* wisi 3.0.0
-19 Dec 2019
-
-** parser process protocol version 5
-
-** Add project.el integration. See wisi.info for more information.
-
-** Move autocase functions from ada-mode to wisi.
-
-** Replace most ada-mode function variables with dispatching on wisi-prj.
-
-** New commands `wisi-goto-containing-statement-start', 
`wisi-indent-containing-statement'.
-
-** Displayed parser errors are sorted in increasing error position.
-
-* wisi 2.2.1
-17 Aug 2019
-
-** parser process protocol version 4
-
-** fix packaging bugs
-
-* wisi 2.2.0
-13 Aug 2019
-
-** parser process protocol version 3
-
-** Support for the elisp parser and lexer is deleted; only the Ada
-   process parser is supported.
-
-** New user variable `wisi-indent-context-lines' specifies the minimum
-   number of lines before point to include in a parse for indenting a
-   single line. This gives better results when indenting in a nested
-   'if then else', for example. The default value is 0; you must
-   change it to see an effect.
-
-** Error correction is faster by approximately 30%;
-   %mckenzie_enqueue_limit can be raised accordingly.
-
-** %mckenzie_enqueue_limit is now applied to the total of all parsers
-    in recovery; previously, it was applied to each parser separately.
-    Applying to the total gives a more consistent maximum user wait
-    time for recovery, at the cost of not finding solutions when there
-    are many parsers involved. You may want to increase
-    %mckenzie_enqueue_limit for this as well.
-
-** In the process parser, `wisi-statement-start' now sets 'containing'
-   in all contained caches to the start token, if not set already;
-   previously it only did this if the token was mentioned in the
-   `wisi-statement-start' action. This makes `wisi-containing-action'
-   unnecessary.
-
-** `wisi-containing-action' is deleted.
-
-** An argument of `wisi-motion-action' that is a vector may now
-   provide only one token ID. That token ID is searched for in the
-   containing token region, and the motion token chain starting at the
-   first one found is included in the current right hand side motion
-   token chain.
-
-** The process parser supports a new parse command `wisi-refactor',
-   which returns a new message "Edit". It is intended for performing
-   syntax-guided refactoring of code statements.
-
-* wisi 2.1.1
-11 Jul 2019
-
-** parser process protocol version 3
-
-** User variable wisi-mckenzie-cost-limit is deleted; set
-   wisi-mckenzie-enqueue-limit instead, it gives better results.
-
-** `wisi-show-parse-errors' now shows errors in a dedicated window, so
-   it will not be resized or reused.
-
-** New grammar action `wisi-name-action'; sets a name that will be
-   fontified. This replaces the previous 'name' navigate class.
-
-** Support 'nil' as an indent argument; useful for the first token,
-   whose indent is typically unknown. Indent functions that do not
-   accumulate now only check for "nil", not "zero or nil".
-
-** New file wisi-xref.el provides a completion table built from tokens
-   marked by the new grammar action `wisi-name-action'.
-
-** The process parser checks the parser process protocol version, to
-   ensure the elisp code matches the process code.
-
-** The process parser supports passing data to a language-specific
-   elisp function, via the `language-action-table' field of the
-   `wisi-process--parser' struct.
-
-** New user option `wisi-parse-max-parallel' to set the number of
-   parallel parsers used; Java needs more than Ada.
-
-* wisi 2.1.0
-21 Mar 2019
-
-** parser process protocol version 2
-
-** Add support for partial parsing; useful in very large files. Files
-   larger than wisi-partial-parse-threshold (default 100_001) will be
-   parsed partially.
-
-** Miscellaneous speed-ups in the Ada code; 'pragma Inline', better use of Ada 
tasks.
-
-** Better error correction in the Ada process parser; insert minimimal
-  tokens to complete a statement/declaration before or after the error
-  point.
-
-* wisi 2.0.1
-8 Dec 2018
-
-** parser process protocol version 1
-
-** Assign copyright in Ada files to FSF
-
-** Update user guide, include it in elpa package
-
-* wisi 2.0.0
-17 Nov 2018
-
-** Change indentation engine to compute indent directly in parser actions.
-
-** Add error correcting external process parser.
-
-** Factor out wisi-elisp-lexer.el from wisi.el, and
-   ada-wisi-elisp-parse.el from ada-wisi.el. Move elisp grammar
-   actions from wisi.el to wisi-elisp-parse.el; they are not used with
-   the process parser.
-
-** Add support for error corrections in parser; 'wisi-repair-error'
-   can apply the corrections to the buffer text.
-
-** Display marks in fringe at location of errors detected by
-   background parser.
-
-** include sources for wisitoken parser runtime, parser generator.
-
-* wisi 1.1.6
-3 Oct 2017
-
-** wisi-forward-find-cache-token - new function.
-
-** New minor-mode parse_table-mode helps navigating parse table
-   listings output by 'wisi-generate -v 1'; useful when debugging
-   grammars.
-
-* wisi 1.1.5
-9 Jul 2017
-
-** wisi-indent-fallback allows setting the indent engine to use when
-   the wisi engine fails.
-
-** wisi-comment-indent now uses comment-column for comments following
-   code on the same line.
-
-** wisi-forward-statement-keyword tolerates end of buffer, and uses
-   either cache-next or cache-end.
-
-** forward-sexp-function is set to wisi-forward-sexp, which handles
-   parens, strings, and statements.
-
-* wisi 1.1.4
-31 Oct 2016
-
-** wisi-validate-cache takes optional error-on-fail arg.
-
-* wisi 1.1.3
-26 Jul 2016
-
-** improve use of quotes in doc strings.
-
-* wisi 1.1.2
-20 Jan 2016
-
-** wisi-compile no longer requires semantic.
-
-** wisi-parse slightly faster
-
-** minor bug fixes
-
-** wisi-extend-action now takes two args (first last)
-
-** wisi-face-action-1 optional arg no-override is replaced by 
override-no-error.
-
-* wisi 1.1.1
-10 Apr 2015
-
-** rename wisi-font-lock-size-threshold to wisi-size-threshold, use
-   for more things in ada-mode
-
-* wisi 1.1.0
-18 Nov 2014
-
-** change wisi-forward-token to not return text; simpler, faster
-
-** remove face from wisi-cache; set font-lock-face property directly.
-
-** add support for numeric literal tokens.
-
-** change wisi-*-action to take a vector of arguments; faster for
-   external parser, catches more errors.
-
-** add wisi-font-lock-size-threshold
-
-* wisi 1.0.6
-28 Sep 2014
-
-** add face to wisi-cache
-
-** wisi-before/after-change : improve checks for invalidate-cache
-
-** wisi-motion-action takes class with each token-id
-
-** new parse actions: wisi-extend-action, wisi-face-action
-
-** new functions: wisi-goto-statement-start, -end.
-
-** fix misc bugs
-
-* wisi 1.0.5
-12 Jul 2014
-
-** wisi-parse-max-parallel-current - new variable for debugging slow parsing 
issues
-
-** wisi-set-end - new algorithm giving significant speedup
-
-* wisi 1.0.4
-19 Apr 2014
-
-** add support for GNAT Ada bracket hex character notation
-
-* wisi 1.0.3
-16 Mar 2014
-
-** fix another packaging bug; forgot to add files to ELPA git!
-
-* wisi 1.0.2
-14 Mar 2014
-
-** Emacs 24.2 supported, via cl-lib in Gnu ELPA
-
-* wisi 1.0.1
-
-** minor fixes for byte compiler warnings
-
-* wisi 1.0
-Feb 2 2014
-
-** first release in ELPA
diff --git a/packages/wisi/README b/packages/wisi/README
deleted file mode 100644
index 5898d91..0000000
--- a/packages/wisi/README
+++ /dev/null
@@ -1,14 +0,0 @@
-Emacs wisi package 3.1.2
-
-The wisi package provides utilities for using generalized
-error-correcting LR parsers (in external processes) to do indentation,
-fontification, and navigation; and integration with Emacs package.el.
-See ada-mode for an example of its use.
-
-It also provides wisitoken-parse_table-mode, for navigating the
-diagnostic parse tables output by wisitoken-bnf-generate.
-
-The generated code is in Ada; it requires the AdaCore gnat compiler
-that you may not have installed. It is available in many packaging
-systems, or as a binary download from
-https://www.adacore.com/download.
diff --git a/packages/wisi/build-wisitoken-bnf-generate.sh 
b/packages/wisi/build-wisitoken-bnf-generate.sh
deleted file mode 100755
index faa4094..0000000
--- a/packages/wisi/build-wisitoken-bnf-generate.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-# Build wisitoken-bnf-generate.exe, for generating code from grammar files.
-# 
-# Instead of using this, you should consider using the complete
-# wisitoken development tree; see
-# http://stephe-leake.org/ada/wisitoken.html
-
-gprbuild -p -j8 -P wisi.gpr wisitoken-bnf-generate
diff --git a/packages/wisi/dir b/packages/wisi/dir
deleted file mode 100644
index fbc9cbb..0000000
--- a/packages/wisi/dir
+++ /dev/null
@@ -1,19 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Parser generators
-* wisitoken-bnf-generate: (wisitoken-bnf-generate).
-                                Ada and Elisp parser generator
diff --git a/packages/wisi/emacs_wisi_common_parse.adb 
b/packages/wisi/emacs_wisi_common_parse.adb
deleted file mode 100644
index 59d20e5..0000000
--- a/packages/wisi/emacs_wisi_common_parse.adb
+++ /dev/null
@@ -1,508 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Text_IO;
-with GNAT.OS_Lib;
-with SAL;
-with System.Multiprocessors;
-with System.Storage_Elements;
-with WisiToken.Lexer;
-package body Emacs_Wisi_Common_Parse is
-
-   procedure Usage (Name : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("usage: " & Name & "[--recover-log <file-name>]");
-      Put_Line ("enters a loop waiting for commands:");
-      Put_Line ("Prompt is '" & Prompt & "'");
-      Put_Line ("commands are case sensitive");
-      Put_Line ("See wisi-process-parse.el *--send-parse, *--send-noop for 
arguments.");
-   end Usage;
-
-   procedure Read_Input (A : System.Address; N : Integer)
-   is
-      use System.Storage_Elements;
-
-      B         : System.Address := A;
-      Remaining : Integer        := N;
-      Read      : Integer;
-   begin
-      --  We use GNAT.OS_Lib because it does not buffer input, so it runs
-      --  under Emacs nicely; GNAT Text_IO does not return text until
-      --  some fairly large buffer is filled.
-      --
-      --  With GNAT GPL 2016, GNAT.OS_Lib.Read does _not_ wait for all N
-      --  bytes or EOF; it returns as soon as it gets some bytes.
-      loop
-         Read := GNAT.OS_Lib.Read (GNAT.OS_Lib.Standin, B, Remaining);
-         if Read = 0 then
-            --  Pipe closed; probably parent Emacs crashed. Force exit.
-            raise SAL.Programmer_Error with "input pipe closed";
-         end if;
-         Remaining := Remaining - Read;
-         exit when Remaining <= 0;
-         B := B + Storage_Offset (Read);
-      end loop;
-   end Read_Input;
-
-   function Get_Command_Length return Integer
-   is
-      Temp : aliased String (1 .. 3) := (others => ' '); -- initialize for 
error message
-   begin
-      Read_Input (Temp'Address, Temp'Length);
-      return Integer'Value (Temp);
-   exception
-   when Constraint_Error =>
-      --  From Integer'Value
-      raise Protocol_Error with "invalid command byte count; '" & Temp & "'";
-   end Get_Command_Length;
-
-   function Get_String
-     (Source : in     String;
-      Last   : in out Integer)
-     return String
-   is
-      use Ada.Strings.Fixed;
-      First : constant Integer := Index
-        (Source  => Source,
-         Pattern => """",
-         From    => Last + 1);
-   begin
-      Last := Index
-        (Source  => Source,
-         Pattern => """",
-         From    => First + 1);
-
-      if First = 0 or Last = 0 then
-         raise Protocol_Error with "no '""' found for string";
-      end if;
-
-      return Source (First + 1 .. Last - 1);
-   end Get_String;
-
-   function Get_Integer
-     (Source : in     String;
-      Last   : in out Integer)
-     return Integer
-   is
-      use Ada.Strings.Fixed;
-      First : constant Integer := Last + 2; -- final char of previous item, 
space
-   begin
-      Last := Index
-        (Source  => Source,
-         Pattern => " ",
-         From    => First);
-
-      if Last = 0 then
-         Last := Source'Last;
-      else
-         Last := Last - 1;
-      end if;
-
-      return Integer'Value (Source (First .. Last));
-   exception
-   when others =>
-      Ada.Text_IO.Put_Line ("bad integer '" & Source (First .. Source'Last) & 
"'");
-      raise;
-   end Get_Integer;
-
-   function Get_Process_Start_Params return Process_Start_Params
-   is
-      use Ada.Command_Line;
-      procedure Put_Usage
-      is
-         use Ada.Text_IO;
-      begin
-         Put_Line (Standard_Error, "process start args:");
-         Put_Line (Standard_Error, "--help : put this help");
-         Put_Line (Standard_Error, "--recover-log <file_name> : log recover 
actions to file");
-      end Put_Usage;
-
-      Next_Arg : Integer := 1;
-   begin
-      return Result : Process_Start_Params do
-         loop
-            exit when Next_Arg > Argument_Count;
-
-            if Next_Arg <= Argument_Count and then Argument (Next_Arg) = 
"--help" then
-               Put_Usage;
-               raise Finish;
-
-            elsif Next_Arg + 1 <= Argument_Count and then Argument (Next_Arg) 
= "--recover-log" then
-               Result.Recover_Log_File_Name := 
Ada.Strings.Unbounded.To_Unbounded_String (Argument (Next_Arg + 1));
-               Next_Arg := Next_Arg + 2;
-            end if;
-         end loop;
-      end return;
-   end Get_Process_Start_Params;
-
-   function Get_Parse_Params (Command_Line : in String; Last : in out Integer) 
return Parse_Params
-   is
-      use WisiToken;
-   begin
-      return Result : Parse_Params do
-         --  We don't use an aggregate, to enforce execution order.
-         --  Match wisi-process-parse.el wisi-process--send-parse
-
-         Result.Post_Parse_Action    := Wisi.Post_Parse_Action_Type'Val 
(Get_Integer (Command_Line, Last));
-         Result.Source_File_Name     := +Get_String (Command_Line, Last);
-         Result.Begin_Byte_Pos       := Get_Integer (Command_Line, Last);
-
-         --  Emacs end is after last char.
-         Result.End_Byte_Pos         := Get_Integer (Command_Line, Last) - 1;
-
-         Result.Goal_Byte_Pos        := Get_Integer (Command_Line, Last);
-         Result.Begin_Char_Pos       := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Begin_Line           := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.End_Line             := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Begin_Indent         := Get_Integer (Command_Line, Last);
-         Result.Partial_Parse_Active := 1 = Get_Integer (Command_Line, Last);
-         Result.Debug_Mode           := 1 = Get_Integer (Command_Line, Last);
-         Result.Parse_Verbosity      := Get_Integer (Command_Line, Last);
-         Result.McKenzie_Verbosity   := Get_Integer (Command_Line, Last);
-         Result.Action_Verbosity     := Get_Integer (Command_Line, Last);
-         Result.McKenzie_Disable     := Get_Integer (Command_Line, Last);
-         Result.Task_Count           := Get_Integer (Command_Line, Last);
-         Result.Check_Limit          := Get_Integer (Command_Line, Last);
-         Result.Enqueue_Limit        := Get_Integer (Command_Line, Last);
-         Result.Max_Parallel         := Get_Integer (Command_Line, Last);
-         Result.Byte_Count           := Get_Integer (Command_Line, Last);
-      end return;
-   end Get_Parse_Params;
-
-   function Get_Refactor_Params (Command_Line : in String; Last : in out 
Integer) return Refactor_Params
-   is
-      use WisiToken;
-   begin
-      return Result : Refactor_Params do
-         --  We don't use an aggregate, to enforce execution order.
-         --  Match wisi-process-parse.el wisi-process--send-refactor
-
-         Result.Refactor_Action    := Get_Integer (Command_Line, Last);
-         Result.Source_File_Name   := +Get_String (Command_Line, Last);
-         Result.Parse_Region.First := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Region.Last  := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last) - 1);
-
-         Result.Edit_Begin           := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Begin_Char_Pos := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Begin_Line     := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Parse_End_Line       := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Parse_Begin_Indent   := Get_Integer (Command_Line, Last);
-         Result.Debug_Mode           := 1 = Get_Integer (Command_Line, Last);
-         Result.Parse_Verbosity      := Get_Integer (Command_Line, Last);
-         Result.Action_Verbosity     := Get_Integer (Command_Line, Last);
-         Result.Max_Parallel         := Get_Integer (Command_Line, Last);
-         Result.Byte_Count           := Get_Integer (Command_Line, Last);
-      end return;
-   end Get_Refactor_Params;
-
-   procedure Process_Stream
-     (Name                      : in     String;
-      Language_Protocol_Version : in     String;
-      Partial_Parse_Active      : in out Boolean;
-      Params                    : in     Process_Start_Params;
-      Parser                    : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data                : in out Wisi.Parse_Data_Type'Class;
-      Descriptor                : in     WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-      use WisiToken; -- "+", "-" Unbounded_string
-
-      procedure Cleanup
-      is begin
-         if Is_Open (Parser.Recover_Log_File) then
-            Close (Parser.Recover_Log_File);
-         end if;
-      end Cleanup;
-
-   begin
-      declare
-         use Ada.Directories;
-         use Ada.Strings.Unbounded;
-      begin
-         if Length (Params.Recover_Log_File_Name) > 0 then
-            Put_Line (";; logging to '" & (-Params.Recover_Log_File_Name) & 
"'");
-            --  to Current_Output, visible from Emacs
-
-            if Exists (-Params.Recover_Log_File_Name) then
-               Open (Parser.Recover_Log_File, Append_File, 
-Params.Recover_Log_File_Name);
-            else
-               Create (Parser.Recover_Log_File, Out_File, 
-Params.Recover_Log_File_Name);
-            end if;
-         end if;
-      end;
-
-      Parser.Trace.Set_Prefix (";; "); -- so debug messages don't confuse 
Emacs.
-
-      Put_Line
-        (Name & " protocol: process version " & Protocol_Version & " language 
version " & Language_Protocol_Version);
-
-      --  Read commands and tokens from standard_input via GNAT.OS_Lib,
-      --  send results to standard_output.
-      loop
-         Put (Prompt); Flush;
-         declare
-            Command_Length : constant Integer := Get_Command_Length;
-            Command_Line   : aliased String (1 .. Command_Length);
-            Last           : Integer;
-
-            function Match (Target : in String) return Boolean
-            is begin
-               Last := Command_Line'First + Target'Length - 1;
-               return Last <= Command_Line'Last and then Command_Line 
(Command_Line'First .. Last) = Target;
-            end Match;
-         begin
-            Read_Input (Command_Line'Address, Command_Length);
-
-            Put_Line (";; " & Command_Line);
-
-            if Match ("parse") then
-               --  Args: see wisi-process-parse.el 
wisi-process-parse--send-parse
-               --  Input: <source text>
-               --  Response:
-               --  [response elisp vector]...
-               --  [elisp error form]...
-               --  prompt
-               declare
-                  Params : constant Parse_Params := Get_Parse_Params 
(Command_Line, Last);
-                  Buffer : Ada.Strings.Unbounded.String_Access;
-
-                  procedure Clean_Up
-                  is
-                     use all type SAL.Base_Peek_Type;
-                  begin
-                     Parser.Lexer.Discard_Rest_Of_Input;
-                     if Parser.Parsers.Count > 0 then
-                        Parse_Data.Put
-                          (Parser.Lexer.Errors,
-                           Parser.Parsers.First.State_Ref.Errors,
-                           Parser.Parsers.First.State_Ref.Tree);
-                     end if;
-                     Ada.Strings.Unbounded.Free (Buffer);
-                  end Clean_Up;
-
-               begin
-                  Trace_Parse    := Params.Parse_Verbosity;
-                  Trace_McKenzie := Params.McKenzie_Verbosity;
-                  Trace_Action   := Params.Action_Verbosity;
-                  Debug_Mode     := Params.Debug_Mode;
-
-                  Partial_Parse_Active        := Params.Partial_Parse_Active;
-                  Parser.Partial_Parse_Active := Params.Partial_Parse_Active;
-
-                  if WisiToken.Parse.LR.McKenzie_Defaulted (Parser.Table.all) 
then
-                     --  There is no McKenzie information; don't override that.
-                     null;
-                  elsif Params.McKenzie_Disable = -1 then
-                     --  Use default
-                     Parser.Enable_McKenzie_Recover := True;
-                  else
-                     Parser.Enable_McKenzie_Recover := Params.McKenzie_Disable 
= 0;
-                  end if;
-
-                  Parse_Data.Initialize
-                    (Post_Parse_Action => Params.Post_Parse_Action,
-                     Lexer             => Parser.Lexer,
-                     Descriptor        => Descriptor'Unrestricted_Access,
-                     Base_Terminals    => Parser.Terminals'Unrestricted_Access,
-                     Begin_Line        => Params.Begin_Line,
-                     End_Line          => Params.End_Line,
-                     Begin_Indent      => Params.Begin_Indent,
-                     Params            => Command_Line (Last + 2 .. 
Command_Line'Last));
-
-                  if Params.Task_Count > 0 then
-                     Parser.Table.McKenzie_Param.Task_Count := 
System.Multiprocessors.CPU_Range (Params.Task_Count);
-                  end if;
-                  if Params.Check_Limit > 0 then
-                     Parser.Table.McKenzie_Param.Check_Limit := 
Base_Token_Index (Params.Check_Limit);
-                  end if;
-                  if Params.Enqueue_Limit > 0 then
-                     Parser.Table.McKenzie_Param.Enqueue_Limit := 
Params.Enqueue_Limit;
-                  end if;
-
-                  if Params.Max_Parallel > 0 then
-                     Parser.Max_Parallel := SAL.Base_Peek_Type 
(Params.Max_Parallel);
-                  end if;
-
-                  Buffer := new String (Params.Begin_Byte_Pos .. 
Params.End_Byte_Pos);
-
-                  Read_Input (Buffer (Params.Begin_Byte_Pos)'Address, 
Params.Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access
-                    (Buffer, Params.Source_File_Name, Params.Begin_Char_Pos, 
Params.Begin_Line);
-
-                  --  Parser.Line_Begin_Token First, Last set by Lex_All
-                  begin
-                     Parser.Parse;
-                  exception
-                  when WisiToken.Partial_Parse =>
-                     null;
-                  end;
-                  Parser.Execute_Actions;
-                  Parse_Data.Put (Parser);
-                  Clean_Up;
-
-               exception
-               when Syntax_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error)");
-
-               when E : Parse_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error """ & 
Ada.Exceptions.Exception_Message (E) & """)");
-
-               when E : Fatal_Error =>
-                  Clean_Up;
-                  Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) 
& """)");
-               end;
-
-            elsif Match ("refactor") then
-               --  Args: see wisi-process-parse.el 
wisi-process-parse--send-refactor
-               --  Input: <source text>
-               --  Response:
-               --  [edit elisp vector]...
-               --  prompt
-               declare
-                  Params : constant Refactor_Params := Get_Refactor_Params 
(Command_Line, Last);
-                  Buffer : Ada.Strings.Unbounded.String_Access;
-
-                  procedure Clean_Up
-                  is
-                     use all type SAL.Base_Peek_Type;
-                  begin
-                     Parser.Lexer.Discard_Rest_Of_Input;
-                     if Parser.Parsers.Count > 0 then
-                        Parse_Data.Put
-                          (Parser.Lexer.Errors,
-                           Parser.Parsers.First.State_Ref.Errors,
-                           Parser.Parsers.First.State_Ref.Tree);
-                     end if;
-                     Ada.Strings.Unbounded.Free (Buffer);
-                  end Clean_Up;
-
-               begin
-                  Trace_Parse  := Params.Parse_Verbosity;
-                  Trace_Action := Params.Action_Verbosity;
-                  Debug_Mode   := Params.Debug_Mode;
-
-                  Partial_Parse_Active := True;
-
-                  Parse_Data.Initialize
-                    (Post_Parse_Action => Wisi.Navigate, -- mostly ignored
-                     Lexer             => Parser.Lexer,
-                     Descriptor        => Descriptor'Unrestricted_Access,
-                     Base_Terminals    => Parser.Terminals'Unrestricted_Access,
-                     Begin_Line        => Params.Parse_Begin_Line,
-                     End_Line          => Params.Parse_End_Line,
-                     Begin_Indent      => Params.Parse_Begin_Indent,
-                     Params            => "");
-
-                  if Params.Max_Parallel > 0 then
-                     Parser.Max_Parallel := SAL.Base_Peek_Type 
(Params.Max_Parallel);
-                  end if;
-
-                  Buffer := new String (Integer (Params.Parse_Region.First) .. 
Integer (Params.Parse_Region.Last));
-
-                  Read_Input (Buffer (Buffer'First)'Address, 
Params.Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access
-                    (Buffer, Params.Source_File_Name, 
Params.Parse_Begin_Char_Pos, Params.Parse_Begin_Line);
-                  begin
-                     Parser.Parse;
-                  exception
-                  when WisiToken.Partial_Parse =>
-                     null;
-                  end;
-                  Parser.Execute_Actions;
-                  Parse_Data.Refactor (Parser.Parsers.First_State_Ref.Tree, 
Params.Refactor_Action, Params.Edit_Begin);
-                  Clean_Up;
-
-               exception
-               when Syntax_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error ""refactor " & 
Params.Parse_Region.First'Image &
-                              Params.Parse_Region.Last'Image & ": syntax 
error"")");
-
-               when E : Parse_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error ""refactor " & 
Params.Parse_Region.First'Image &
-                              Params.Parse_Region.Last'Image & ": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-
-               when E : others => -- includes Fatal_Error
-                  Clean_Up;
-                  Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) 
& """)");
-               end;
-
-            elsif Match ("noop") then
-               --  Args: <source byte count>
-               --  Input: <source text>
-               --  Response: prompt
-               declare
-                  Byte_Count  : constant Integer                             
:= Get_Integer (Command_Line, Last);
-                  Buffer      : constant Ada.Strings.Unbounded.String_Access 
:= new String (1 .. Byte_Count);
-                  Token       : Base_Token;
-                  Lexer_Error : Boolean;
-                  pragma Unreferenced (Lexer_Error);
-               begin
-                  Token.ID := Invalid_Token_ID;
-                  Read_Input (Buffer (1)'Address, Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access (Buffer, +"");
-                  loop
-                     exit when Token.ID = Parser.Trace.Descriptor.EOI_ID;
-                     Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  end loop;
-               exception
-               when Syntax_Error =>
-                  Parser.Lexer.Discard_Rest_Of_Input;
-               end;
-
-            elsif Match ("quit") then
-               exit;
-
-            else
-               Put_Line ("(error ""bad command: '" & Command_Line & "'"")");
-            end if;
-         exception
-         when E : Protocol_Error =>
-            --  don't exit the loop; allow debugging bad elisp
-            Put_Line ("(error ""protocol error "": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-         end;
-      end loop;
-      Cleanup;
-   exception
-   when Finish =>
-      null;
-
-   when E : others =>
-      Cleanup;
-      Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-      New_Line (2);
-      Put_Line
-        ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) 
& ": " &
-           Ada.Exceptions.Exception_Message (E) & """)");
-   end Process_Stream;
-
-end Emacs_Wisi_Common_Parse;
diff --git a/packages/wisi/emacs_wisi_common_parse.ads 
b/packages/wisi/emacs_wisi_common_parse.ads
deleted file mode 100644
index e646eba..0000000
--- a/packages/wisi/emacs_wisi_common_parse.ads
+++ /dev/null
@@ -1,157 +0,0 @@
---  Abstract :
---
---  Common utilities for Gen_Emacs_Wisi_*_Parse
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Strings.Unbounded;
-with System;
-with Wisi;
-with WisiToken.Parse.LR.Parser;
-package Emacs_Wisi_Common_Parse is
-
-   Protocol_Version : constant String := "5";
-   --  Protocol_Version defines the data sent between elisp and the
-   --  background process, except for the language-specific parameters,
-   --  which are defined by the Language_Protocol_Version parameter to
-   --  Parse_Stream, below.
-   --
-   --  This value must match wisi-process-parse.el
-   --  wisi-process-parse-protocol-version.
-   --
-   --  See wisi-process-parse.el functions, and this package body, for
-   --  the implementation of the protocol.
-   --
-   --  Only changes once per wisi release. Increment as soon as required,
-   --  record new version in NEWS-wisi.text.
-
-   Prompt : constant String := ";;> ";
-
-   Protocol_Error : exception;
-   Finish         : exception;
-
-   procedure Usage (Name : in String);
-
-   procedure Read_Input (A : System.Address; N : Integer);
-
-   function Get_Command_Length return Integer;
-
-   function Get_String
-     (Source : in     String;
-      Last   : in out Integer)
-     return String;
-
-   function Get_Integer
-     (Source : in     String;
-      Last   : in out Integer)
-     return Integer;
-
-   type Process_Start_Params is record
-      Recover_Log_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-      --  log enabled if non-empty.
-   end record;
-
-   function Get_Process_Start_Params return Process_Start_Params;
-   --  Get from Ada.Command_Line. Handles --help by outputing help,
-   --  raising Finish.
-
-   procedure Process_Stream
-     (Name                      : in     String;
-      Language_Protocol_Version : in     String;
-      Partial_Parse_Active      : in out Boolean;
-      Params                    : in     Process_Start_Params;
-      Parser                    : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data                : in out Wisi.Parse_Data_Type'Class;
-      Descriptor                : in     WisiToken.Descriptor);
-
-   ----------
-   --  Parse command
-
-   type Parse_Params is record
-      Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-      Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-
-      Begin_Byte_Pos : Integer;
-      --  Source file byte position of first char sent; start parse here.
-
-      End_Byte_Pos : Integer;
-      --  Byte position of last char sent.
-
-      Goal_Byte_Pos : Integer;
-      --  Byte position of end of desired parse region; terminate parse at
-      --  or after here.
-
-      Begin_Char_Pos : WisiToken.Buffer_Pos;
-      --  Char position of first char sent.
-
-      Begin_Line : WisiToken.Line_Number_Type;
-      End_Line   : WisiToken.Line_Number_Type;
-      --  Line number of line containing Begin_Byte_Pos, End_Byte_Pos
-
-      Begin_Indent : Integer;
-      --  Indentation of Line_Begin
-
-      Partial_Parse_Active : Boolean;
-      Debug_Mode           : Boolean;
-      Parse_Verbosity      : Integer;
-      McKenzie_Verbosity   : Integer;
-      Action_Verbosity     : Integer;
-      McKenzie_Disable     : Integer;
-      Task_Count           : Integer;
-      Check_Limit          : Integer;
-      Enqueue_Limit        : Integer;
-      Max_Parallel         : Integer;
-      Byte_Count           : Integer;
-      --  Count of bytes of source file sent.
-   end record;
-
-   function Get_Parse_Params (Command_Line : in String; Last : in out Integer) 
return Parse_Params;
-
-   ----------
-   --  Refactor command
-
-   type Refactor_Params is record
-      Refactor_Action  : Positive; -- Language-specific
-      Source_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-
-      Parse_Region : WisiToken.Buffer_Region;
-      --  Source file byte region to parse.
-
-      Edit_Begin : WisiToken.Buffer_Pos;
-      --  Source file byte position at start of expression to refactor.
-
-      Parse_Begin_Char_Pos : WisiToken.Buffer_Pos;
-      --  Char position of first char sent.
-
-      Parse_Begin_Line : WisiToken.Line_Number_Type;
-      Parse_End_Line   : WisiToken.Line_Number_Type;
-      --  Line numbers of lines containing Parse_Begin_Byte_Pos, 
Parse_End_Byte_Pos
-
-      Parse_Begin_Indent : Integer;
-      --  Indentation of Parse_Begin_Line
-
-      Debug_Mode       : Boolean;
-      Parse_Verbosity  : Integer;
-      Action_Verbosity : Integer;
-      Max_Parallel     : Integer;
-      Byte_Count       : Integer;
-      --  Count of bytes of source file sent.
-   end record;
-
-   function Get_Refactor_Params (Command_Line : in String; Last : in out 
Integer) return Refactor_Params;
-
-end Emacs_Wisi_Common_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_parse.adb 
b/packages/wisi/gen_emacs_wisi_lr_parse.adb
deleted file mode 100644
index 0f81868..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_parse.adb
+++ /dev/null
@@ -1,39 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2014, 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_LR_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-
-   Params : constant Process_Start_Params := Get_Process_Start_Params;
-begin
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access,
-      Parse_Data'Unchecked_Access);
-
-   Process_Stream (Name, Language_Protocol_Version, Partial_Parse_Active, 
Params, Parser, Parse_Data, Descriptor);
-
-end Gen_Emacs_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_parse.ads 
b/packages/wisi/gen_emacs_wisi_lr_parse.ads
deleted file mode 100644
index 02eac21..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_parse.ads
+++ /dev/null
@@ -1,55 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; parse token stream, return
---  parser actions.
---
---  See gen_run_wisi_parse.ads for a standalone version.
---
---  References :
---
---  [1] On the elisp side, the inter-process protocol is defined in
---  wisi-process-parse.el, functions wisi-process-parse--send-parse
---  and wisi-process-parse--execute.
---
---  [2] On the Ada side, it is defined here, and in
---  wisitoken-wisi_runtime.adb
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type  is new Wisi.Parse_Data_Type with private;
-
-   Name                           : in String; --  for Usage, error messages.
-   Language_Protocol_Version      : in String; --  Defines language-specific 
parse parameters.
-   Descriptor                     : in WisiToken.Descriptor;
-   Partial_Parse_Active           : in out Boolean;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Emacs_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb 
b/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb
deleted file mode 100644
index 31f1052..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2014, 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_LR_Text_Rep_Parse
-is
-   use WisiToken; -- "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-
-   Params : constant Process_Start_Params := Get_Process_Start_Params;
-begin
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access,
-      Parse_Data'Unchecked_Access,
-      Ada.Directories.Containing_Directory (Ada.Command_Line.Command_Name) & 
"/" & Text_Rep_File_Name);
-
-   Process_Stream (Name, Language_Protocol_Version, Partial_Parse_Active, 
Params, Parser, Parse_Data, Descriptor);
-
-end Gen_Emacs_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads 
b/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads
deleted file mode 100644
index f9ff468..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; parse token stream, return
---  parser actions.
---
---  See gen_run_wisi_parse.ads for a standalone version.
---
---  References : see gen_emacs_wisi_lr_parse.ads
---
---  Copyright (C) 2017, 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type  is new Wisi.Parse_Data_Type with private;
-
-   Name                           : in String; --  for Usage, error messages. 
"_wisi_parse" will be appended
-   Language_Protocol_Version      : in String; --  Defines language-specific 
parse parameters.
-   Descriptor                     : in WisiToken.Descriptor;
-   Partial_Parse_Active           : in out Boolean;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-   Text_Rep_File_Name             : in String;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Text_Rep_File_Name             : in              String);
-
-procedure Gen_Emacs_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_packrat_parse.adb 
b/packages/wisi/gen_emacs_wisi_packrat_parse.adb
deleted file mode 100644
index b4e95f6..0000000
--- a/packages/wisi/gen_emacs_wisi_packrat_parse.adb
+++ /dev/null
@@ -1,180 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-with GNAT.OS_Lib;
-with GNAT.Traceback.Symbolic;
-with System.Storage_Elements;
-with WisiToken.Lexer;
-with WisiToken.Parse.Packrat;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_Parse_Packrat
-is
-   use WisiToken; -- "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace (Descriptor'Access);
-   Parser     : WisiToken.Parse.Packrat.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-begin
-   Create_Parser (Parser, Trace'Unrestricted_Access, 
Parse_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-   begin
-      case Argument_Count is
-      when 0 =>
-         null;
-
-      when others =>
-         Usage (Name);
-         raise Programmer_Error with "invalid option count: " & Integer'Image 
(Argument_Count);
-      end case;
-   end;
-
-   Put_Line (Name & " " & Version & ", protocol version " & Protocol_Version);
-
-   --  Read commands and tokens from standard_input via GNAT.OS_Lib,
-   --  send results to standard_output.
-   loop
-      Put (Prompt); Flush;
-      declare
-         Command_Length : constant Integer := Get_Command_Length;
-         Command_Line   : aliased String (1 .. Command_Length);
-         Last           : Integer;
-
-         function Match (Target : in String) return Boolean
-         is begin
-            Last := Command_Line'First + Target'Length - 1;
-            return Last <= Command_Line'Last and then Command_Line 
(Command_Line'First .. Last) = Target;
-         end Match;
-      begin
-         Read_Input (Command_Line'Address, Command_Length);
-
-         Put_Line (";; " & Command_Line);
-
-         if Match ("parse") then
-            --  Args: see Usage
-            --  Input: <source text>
-            --  Response:
-            --  [response elisp vector]...
-            --  [elisp error form]...
-            --  prompt
-            declare
-               use Wisi;
-               Cl_Params : constant Command_Line_Params := Get_Cl_Params 
(Command_Line, Last);
-               Buffer    : Ada.Strings.Unbounded.String_Access;
-
-               procedure Clean_Up
-               is begin
-                  Parser.Lexer.Discard_Rest_Of_Input;
-                  Parser.Put_Errors (-Cl_Param.Source_File_Name);
-                  Ada.Strings.Unbounded.Free (Buffer);
-               end Clean_Up;
-
-            begin
-               --  Computing Line_Count in elisp allows parsing in parallel 
with
-               --  sending source text.
-
-               Trace_Parse    := Cl_Params.Parse_Verbosity;
-               Trace_McKenzie := Cl_Params.McKenzie_Verbosity;
-               Trace_Action   := Cl_Params.Action_Verbosity;
-               Debug_Mode     := Cl_Params.Debug_Mode;
-
-               Parse_Data.Initialize
-                 (Post_Parse_Action => Cl_Params.Post_Parse_Action,
-                  Descriptor        => Descriptor'Access,
-                  Source_File_Name  => -Cl_Params.Source_File_Name,
-                  Line_Count        => Cl_Params.Line_Count,
-                  Params            => Command_Line (Last + 2 .. 
Command_Line'Last));
-
-               Buffer := new String (1 .. Cl_Params.Byte_Count);
-               Read_Input (Buffer (1)'Address, Cl_Params.Byte_Count);
-
-               Parser.Lexer.Reset_With_String_Access (Buffer);
-               Parser.Parse;
-               Parser.Execute_Actions;
-               Put (Parse_Data);
-               Clean_Up;
-
-            exception
-            when Syntax_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error)");
-
-            when E : Parse_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message 
(E) & """)");
-
-            when E : Fatal_Error =>
-               Clean_Up;
-               Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-            end;
-
-         elsif Match ("noop") then
-            --  Args: <source byte count>
-            --  Input: <source text>
-            --  Response: prompt
-            declare
-               Byte_Count  : constant Integer                             := 
Get_Integer (Command_Line, Last);
-               Buffer      : constant Ada.Strings.Unbounded.String_Access := 
new String (1 .. Byte_Count);
-               Token       : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               Token.ID := Invalid_Token_ID;
-               Read_Input (Buffer (1)'Address, Byte_Count);
-
-               Parser.Lexer.Reset_With_String_Access (Buffer);
-               loop
-                  exit when Token.ID = Parser.Trace.Descriptor.EOF_ID;
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-               end loop;
-            exception
-            when Syntax_Error =>
-               Parser.Lexer.Discard_Rest_Of_Input;
-            end;
-
-         elsif Match ("quit") then
-            exit;
-
-         else
-            Put_Line ("(error ""bad command: '" & Command_Line & "'"")");
-         end if;
-      exception
-      when E : Protocol_Error =>
-         --  don't exit the loop; allow debugging bad elisp
-         Put_Line ("(error ""protocol error "": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-   end loop;
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Emacs_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_emacs_wisi_packrat_parse.ads 
b/packages/wisi/gen_emacs_wisi_packrat_parse.ads
deleted file mode 100644
index 79c69ec..0000000
--- a/packages/wisi/gen_emacs_wisi_packrat_parse.ads
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; packrat parse token stream,
---  return parser actions.
---
---  See gen_run_wisi_parse_packrat.ads for a standalone version.
---
---  References :
---
---  See gen_emacs_wisi_parse.ads
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.Packrat;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Runtime;
-generic
-   type Parse_Data_Type  is new WisiToken.Wisi_Runtime.Parse_Data_Type with 
private;
-
-   Name       : in String; --  for Usage, error messages. 
"_wisi_parse_packrat" will be appended
-   Descriptor : in WisiToken.Descriptor;
-
-   with procedure Create_Parser
-     (Parser    :    out          WisiToken.Parse.Packrat.Parser;
-      Trace     : not null access WisiToken.Trace'Class;
-      User_Data : in              WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Emacs_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_run_wisi_libadalang_parse.adb 
b/packages/wisi/gen_run_wisi_libadalang_parse.adb
deleted file mode 100644
index c154136..0000000
--- a/packages/wisi/gen_run_wisi_libadalang_parse.adb
+++ /dev/null
@@ -1,176 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with Wisi.Libadalang;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_Libadalang_Parse
-is
-   use WisiToken; -- Token_ID, "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : Wisi.Libadalang.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-   procedure Put_Usage
-   is begin
-      Put_Line ("usage: <file_name> <parse_action> [options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m : parse, action");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      New_Line;
-   end Put_Usage;
-
-   Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-   Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-   Lang_Params       : Ada.Strings.Unbounded.Unbounded_String;
-
-   Repeat_Count : Integer := 1;
-   Arg          : Integer;
-   Start        : Ada.Real_Time.Time;
-
-begin
-   declare
-      use Ada.Command_Line;
-   begin
-      if Argument_Count < 1 then
-         Put_Usage;
-         Set_Exit_Status (Failure);
-         return;
-      end if;
-
-      Source_File_Name  := +Ada.Command_Line.Argument (1);
-      Post_Parse_Action := Wisi.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-      Arg               := 3;
-
-      loop
-         exit when Arg > Argument_Count;
-
-         if Argument (Arg) = "--lang_params" then
-            Lang_Params := +Argument (Arg + 1);
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--repeat_count" then
-            Repeat_Count := Integer'Value (Argument (Arg + 1));
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--verbosity" then
-            WisiToken.Trace_Parse  := Integer'Value (Argument (Arg + 1));
-            WisiToken.Trace_Action := Integer'Value (Argument (Arg + 2));
-            Arg                    := Arg + 3;
-
-         else
-            Put_Line ("unrecognized option: '" & Argument (Arg) & "'");
-            Put_Usage;
-            return;
-         end if;
-      end loop;
-   end;
-
-   Parser.Trace            := Trace'Unrestricted_Access;
-   Parser.Lexer            := new Wisi.Libadalang.Lexer 
(Trace'Unrestricted_Access);
-   Parser.User_Data        := Parse_Data'Unrestricted_Access;
-   Parser.Source_File_Name := Source_File_Name;
-
-   Parser.Tree.Initialize (Shared_Tree => 
Parser.Base_Tree'Unrestricted_Access, Flush => True);
-
-   Parse_Data.Initialize
-     (Post_Parse_Action => Post_Parse_Action,
-      Descriptor        => Descriptor'Unrestricted_Access,
-      Source_File_Name  => -Source_File_Name,
-      Line_Count        => 1, --  FIXME: fix wisi_runtime to not need this!
-      Params            => -Lang_Params);
-
-   if Repeat_Count > 1 then
-      Start := Ada.Real_Time.Clock;
-   end if;
-
-   for I in 1 .. Repeat_Count loop
-      declare
-         procedure Clean_Up
-         is begin
-            if I = 1 then
-               null;
-               --  FIXME: Errors!
-               --  Parse_Data.Put
-               --    (Parser.Lexer.Errors,
-               --     Parser.Parsers.First.State_Ref.Errors,
-               --     Parser.Parsers.First.State_Ref.Tree);
-            end if;
-         end Clean_Up;
-
-      begin
-         Parse_Data.Reset;
-         Parser.Parse;
-         Parser.Execute_Actions;
-
-         if Repeat_Count = 1 then
-            Parse_Data.Put;
-
-            --  FIXME: put errors via parse_data.put
-            if Parser.Any_Errors then
-               Parser.Put_Errors;
-            end if;
-            --  Parse_Data.Put
-            --       (Parser.Lexer.Errors,
-            --        Parser.Parsers.First.State_Ref.Errors,
-            --        Parser.Parsers.First.State_Ref.Tree);
-         end if;
-      exception
-      when WisiToken.Syntax_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error)");
-
-      when E : WisiToken.Parse_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-
-      when E : WisiToken.Fatal_Error =>
-         Clean_Up;
-         Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-   end loop;
-
-   if Repeat_Count > 1 then
-      declare
-         use Ada.Real_Time;
-         Finish : constant Time := Clock;
-      begin
-         Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-         Put_Line ("per iteration:" & Duration'Image (To_Duration ((Finish - 
Start) / Repeat_Count)));
-      end;
-   end if;
-
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Run_Wisi_Libadalang_Parse;
diff --git a/packages/wisi/gen_run_wisi_libadalang_parse.ads 
b/packages/wisi/gen_run_wisi_libadalang_parse.ads
deleted file mode 100644
index 356c67d..0000000
--- a/packages/wisi/gen_run_wisi_libadalang_parse.ads
+++ /dev/null
@@ -1,30 +0,0 @@
---  Abstract :
---
---  Run an Emacs libadalang parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_libadalang_parse.ads for the Emacs background process.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Wisi;
-with WisiToken;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor : in WisiToken.Descriptor;
-
-procedure Gen_Run_Wisi_Libadalang_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_parse.adb 
b/packages/wisi/gen_run_wisi_lr_parse.adb
deleted file mode 100644
index 84498de..0000000
--- a/packages/wisi/gen_run_wisi_lr_parse.adb
+++ /dev/null
@@ -1,37 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Run_Wisi_Common_Parse;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_LR_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-begin
-   --  Create parser first so Put_Usage has defaults from Parser.Table,
-   --  and Get_CL_Params can override them.
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access, Parse_Data'Unchecked_Access);
-
-   Run_Wisi_Common_Parse.Parse_File (Parser, Parse_Data, Descriptor);
-
-end Gen_Run_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_parse.ads 
b/packages/wisi/gen_run_wisi_lr_parse.ads
deleted file mode 100644
index 34fbd3c..0000000
--- a/packages/wisi/gen_run_wisi_lr_parse.ads
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  Run an Emacs LR parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_lr_parse.ads for the Emacs background process.
---
---  Copyright (C) 2017, 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor                     : in WisiToken.Descriptor;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Run_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb 
b/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb
deleted file mode 100644
index 45bc5e1..0000000
--- a/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Run_Wisi_Common_Parse;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_LR_Text_Rep_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-begin
-   --  Create parser first so Put_Usage has defaults from Parser.Table,
-   --  and Get_CL_Params can override them.
-   declare
-      use Ada.Command_Line;
-   begin
-      --  text_rep file is in same directory as exectuable.
-      Create_Parser
-        (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-         Trace'Unrestricted_Access, Parse_Data'Unchecked_Access,
-         Ada.Directories.Containing_Directory (Command_Name) & "/" & 
Text_Rep_File_Name);
-
-      Run_Wisi_Common_Parse.Parse_File (Parser, Parse_Data, Descriptor);
-   end;
-end Gen_Run_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads 
b/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads
deleted file mode 100644
index dd45d16..0000000
--- a/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  Run an Emacs LR text_rep parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_*_parse.ads for the Emacs background process.
---
---  Copyright (C) 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor                     : in WisiToken.Descriptor;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-   Text_Rep_File_Name             : in String;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Text_Rep_File_Name             : in              String);
-
-procedure Gen_Run_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_run_wisi_packrat_parse.adb 
b/packages/wisi/gen_run_wisi_packrat_parse.adb
deleted file mode 100644
index fb3e900..0000000
--- a/packages/wisi/gen_run_wisi_packrat_parse.adb
+++ /dev/null
@@ -1,241 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.IO_Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with WisiToken.Lexer;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_Parse_Packrat
-is
-   use WisiToken; -- Token_ID, "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace (Descriptor'Access);
-   Parser     : WisiToken.Parse.Packrat.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-   procedure Put_Usage
-   is begin
-      Put_Line ("usage: " & Name & "_wisi_parse <file_name> <parse_action> 
[options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m l:");
-      Put_Line ("   n: parser; m: mckenzie; l: action");
-      Put_Line ("   0 - only report parse errors");
-      Put_Line ("   1 - shows spawn/terminate parallel parsers, error recovery 
enter/exit");
-      Put_Line ("   2 - add each parser cycle, error recovery enqueue/check");
-      Put_Line ("   3 - parse stack in each cycle, error recovery parse 
actions");
-      Put_Line ("   4 - add lexer debug");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--lexer_only : only run lexer, for profiling");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      Put_Line ("--pause : when repeating, prompt for <enter> after each 
parse; allows seeing memory leaks");
-      New_Line;
-   end Put_Usage;
-
-   Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-   Post_Parse_Action : WisiToken.Wisi_Runtime.Post_Parse_Action_Type;
-
-   Line_Count   : WisiToken.Line_Number_Type := 1;
-   Lexer_Only   : Boolean                    := False;
-   Repeat_Count : Integer                    := 1;
-   Pause        : Boolean                    := False;
-   Arg          : Integer;
-   Lang_Params  : Ada.Strings.Unbounded.Unbounded_String;
-   Start        : Ada.Real_Time.Time;
-begin
-   Create_Parser (Parser, Trace'Unrestricted_Access, 
Parse_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-   begin
-      if Argument_Count < 1 then
-         Put_Usage;
-         Set_Exit_Status (Failure);
-         return;
-      end if;
-
-      Source_File_Name  := +Ada.Command_Line.Argument (1);
-      Post_Parse_Action := WisiToken.Wisi_Runtime.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-      Arg               := 3;
-
-      loop
-         exit when Arg > Argument_Count;
-
-         if Argument (Arg) = "--verbosity" then
-            WisiToken.Trace_Parse    := Integer'Value (Argument (Arg + 1));
-            WisiToken.Trace_McKenzie := Integer'Value (Argument (Arg + 2));
-            WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 3));
-            Arg                      := Arg + 4;
-
-         elsif Argument (Arg) = "--lang_params" then
-            Lang_Params := +Argument (Arg + 1);
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--lexer_only" then
-            Lexer_Only := True;
-            Arg := Arg + 1;
-
-         elsif Argument (Arg) = "--pause" then
-            Pause := True;
-            Arg := Arg + 1;
-
-         elsif Argument (Arg) = "--repeat_count" then
-            Repeat_Count := Integer'Value (Argument (Arg + 1));
-            Arg := Arg + 2;
-
-         else
-            Put_Line ("unrecognized option: '" & Argument (Arg) & "'");
-            Put_Usage;
-            return;
-         end if;
-      end loop;
-   end;
-
-   --  Do this after setting Trace_Parse so lexer verbosity is set
-   begin
-      Parser.Lexer.Reset_With_File (-Source_File_Name);
-   exception
-   when Ada.IO_Exceptions.Name_Error =>
-      Put_Line (Standard_Error, "'" & (-Source_File_Name) & "' cannot be 
opened");
-      return;
-   end;
-
-   --  See comment in wisi-wisi_runtime.ads for why we still need this.
-   declare
-      Token : Base_Token;
-      Lexer_Error : Boolean;
-      pragma Unreferenced (Lexer_Error);
-   begin
-      loop
-         begin
-            Lexer_Error := Parser.Lexer.Find_Next (Token);
-            exit when Token.ID = Descriptor.EOF_ID;
-         exception
-         when WisiToken.Syntax_Error =>
-            Parser.Lexer.Discard_Rest_Of_Input;
-            Parser.Put_Errors (-Source_File_Name);
-            Put_Line ("(lexer_error)");
-         end;
-      end loop;
-      Line_Count := Token.Line;
-   end;
-
-   if WisiToken.Trace_Action > WisiToken.Outline then
-      Put_Line ("line_count:" & Line_Number_Type'Image (Line_Count));
-   end if;
-
-   Parse_Data.Initialize
-     (Post_Parse_Action => Post_Parse_Action,
-      Descriptor        => Descriptor'Access,
-      Source_File_Name  => -Source_File_Name,
-      Line_Count        => Line_Count,
-      Params            => -Lang_Params);
-
-   if Repeat_Count > 1 then
-      Start := Ada.Real_Time.Clock;
-   end if;
-
-   for I in 1 .. Repeat_Count loop
-      declare
-         procedure Clean_Up
-         is begin
-            Parser.Lexer.Discard_Rest_Of_Input;
-            if Repeat_Count = 1 then
-               Parser.Put_Errors (-Source_File_Name);
-            end if;
-         end Clean_Up;
-
-      begin
-         Parse_Data.Reset;
-         Parser.Lexer.Reset;
-
-         if Lexer_Only then
-            declare
-               Token : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               Parser.Lexer.Reset;
-               loop
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  exit when Token.ID = Descriptor.EOF_ID;
-               end loop;
-               --  We don't handle errors here; that was done in the count 
lines loop
-               --  above.
-            end;
-         else
-            Parser.Parse;
-            Parser.Execute_Actions;
-
-            if Repeat_Count = 1 then
-               Parse_Data.Put;
-               Parser.Put_Errors (-Source_File_Name);
-            end if;
-         end if;
-      exception
-      when WisiToken.Syntax_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error)");
-
-      when E : WisiToken.Parse_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-
-      when E : WisiToken.Fatal_Error =>
-         Clean_Up;
-         Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-
-      if Pause then
-         Put_Line ("Enter to continue:");
-         Flush (Standard_Output);
-         declare
-            Junk : constant String := Get_Line;
-            pragma Unreferenced (Junk);
-         begin
-            null;
-         end;
-      end if;
-   end loop;
-
-   if Repeat_Count > 1 then
-      declare
-         use Ada.Real_Time;
-         Finish : constant Time := Clock;
-      begin
-         Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-         Put_Line ("per iteration:" & Duration'Image (To_Duration ((Finish - 
Start) / Repeat_Count)));
-      end;
-   end if;
-
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Run_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_run_wisi_packrat_parse.ads 
b/packages/wisi/gen_run_wisi_packrat_parse.ads
deleted file mode 100644
index 538da1d..0000000
--- a/packages/wisi/gen_run_wisi_packrat_parse.ads
+++ /dev/null
@@ -1,36 +0,0 @@
---  Abstract :
---
---  Run an Emacs packrate parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_parse_packrat.ads for the Emacs background process.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.Packrat;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Runtime;
-generic
-   type Parse_Data_Type is new WisiToken.Wisi_Runtime.Parse_Data_Type with 
private;
-
-   Descriptor : in WisiToken.Descriptor;
-
-   with procedure Create_Parser
-     (Parser    :    out          WisiToken.Parse.Packrat.Parser;
-      Trace     : not null access WisiToken.Trace'Class;
-      User_Data : in              WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Run_Wisi_Parse_Packrat;
diff --git a/packages/wisi/long_float_elementary_functions.ads 
b/packages/wisi/long_float_elementary_functions.ads
deleted file mode 100644
index d5664b7..0000000
--- a/packages/wisi/long_float_elementary_functions.ads
+++ /dev/null
@@ -1,21 +0,0 @@
---  Abstract :
---
---  instantiation
---
---  Copyright (C) 2017 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Numerics.Generic_Elementary_Functions;
-package Long_Float_Elementary_Functions is new 
Ada.Numerics.Generic_Elementary_Functions (Long_Float);
diff --git a/packages/wisi/recover_stats.adb b/packages/wisi/recover_stats.adb
deleted file mode 100644
index e1fed7b..0000000
--- a/packages/wisi/recover_stats.adb
+++ /dev/null
@@ -1,271 +0,0 @@
---  Abstract :
---
---  Summarize error recover log.
---
---  Copyright (C) 2019 - 2020 Stephen Leake All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Long_Float_Text_IO;
-with Ada.Strings.Fixed; use Ada.Strings.Fixed;
-with Ada.Strings.Maps;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with SAL.Gen_Stats.Gen_Image;
-with SAL.Long_Float_Stats;
-with WisiToken.Parse.LR;
-procedure Recover_Stats
-is
-   subtype Strategies is WisiToken.Parse.LR.Strategies;
-
-   File : File_Type;
-
-   Delimiters : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set (",() ");
-   Number     : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set ("0123456789");
-
-   type Strategy_Counts is array (Strategies) of Natural;
-
-   type Recover_Label is (Full, Partial);
-
-   type Recover_Summary is record
-      Event_Count : Integer := 0;
-      --  1 per recover event (1 line in log file)
-
-      Enqueue_Stats : SAL.Long_Float_Stats.Stats_Type;
-      Check_Stats   : SAL.Long_Float_Stats.Stats_Type;
-
-      Strat_Counts_Total   : Strategy_Counts := (others => 0);
-      Strat_Counts_Present : Strategy_Counts := (others => 0);
-      --  1 per recover event if used
-
-      Recover_Count_Present : Integer := 0;
-      --  1 per parser in recover result
-
-      Recover_Count_Total : Integer := 0;
-      --  Sum of all strategy counts
-
-      Fail_Event_Count      : Integer := 0; -- for all reasons
-      Fail_Enqueue_Limit    : Integer := 0;
-      Fail_No_Configs_Left  : Integer := 0;
-      Fail_Programmer_Error : Integer := 0;
-      Fail_Other            : Integer := 0;
-   end record;
-
-   Summary : array (Recover_Label) of Recover_Summary;
-begin
-   Open (File, In_File, Ada.Command_Line.Argument (1));
-
-   loop
-      exit when End_Of_File (File);
-      declare
-         --  The recover log is written by code in
-         --  wisitoken-parse-lr-parser.adb Parse (search for Recover_Log).
-         --
-         --  A line has the syntax:
-         --  yyyy-mm-dd hh:mm:ss <partial> <success> pre_parser_count 
'<file_name>' (<parser_data>)...
-         --
-         --  where there is one (<parser_data) for each parser active after 
recover. <parser_data> is:
-         --
-         --  (<strategy_counts>) <enqueue_count> <check_count> <success>
-         --
-         --  Note that the per-parser success is always TRUE; it would not be
-         --  active if recover had failed.
-
-         Line  : constant String := Get_Line (File);
-         First : Integer         := Index (Line, " "); -- after date
-         Last  : Integer;
-
-         Label : Recover_Label := Full;
-
-         function Line_Eq (Item : in String) return Boolean
-         is begin
-            return Line (First .. First + Item'Length - 1) = Item;
-         end Line_Eq;
-
-         function Next_Integer return Integer
-         is begin
-            Find_Token
-              (Line, Number,
-               From  => Last + 1,
-               Test  => Ada.Strings.Inside,
-               First => First,
-               Last  => Last);
-            return Integer'Value (Line (First .. Last));
-         exception
-         when Constraint_Error =>
-            raise Constraint_Error with "bad integer '" & Line (First .. Last 
- 1) & "' " &
-              Ada.Text_IO.Count'Image (Ada.Text_IO.Line (File) - 1) & 
First'Image & Last'Image;
-         end Next_Integer;
-
-         function Next_Boolean return  Boolean
-         is begin
-            First := Last + 2;
-            Last  := -1 + Index (Line, Delimiters, First);
-            return Boolean'Value (Line (First .. Last));
-         end Next_Boolean;
-
-         function Read_Strat_Counts (Strategy_Found : out Boolean) return 
Strategy_Counts
-         is begin
-            Strategy_Found := False;
-            Last := Index (Line, "(", Last + 1);
-            return Result : Strategy_Counts do
-               for I in Strategies loop
-                  Result (I) := Next_Integer;
-                  if Result (I) > 0 then
-                     Strategy_Found := True;
-                  end if;
-               end loop;
-               Last := 1 + Index (Line, ")", Last + 1);
-            end return;
-         end Read_Strat_Counts;
-
-      begin
-         First := Index (Line, " ", First + 1); -- after time
-         Last  := Index (Line, " ", First + 1); -- after Partial_Parse_Active
-         if Boolean'Value (Line (First + 1 .. Last - 1)) then
-            Label := Partial;
-         end if;
-
-         Summary (Label).Event_Count := Summary (Label).Event_Count + 1;
-
-         First := Last + 1;
-         if Line (First .. First + 3) = "FAIL" then
-            Summary (Label).Fail_Event_Count := Summary 
(Label).Fail_Event_Count + 1;
-            First := First + 4;
-
-            if Line_Eq ("NO_CONFIGS_LEFT") then
-               Summary (Label).Fail_No_Configs_Left := Summary 
(Label).Fail_No_Configs_Left + 1;
-            elsif Line_Eq ("ENQUEUE_LIMIT") then
-               Summary (Label).Fail_Enqueue_Limit := Summary 
(Label).Fail_Enqueue_Limit + 1;
-            elsif Line_Eq ("PROGRAMMER_ERROR") then
-               Summary (Label).Fail_Programmer_Error := Summary 
(Label).Fail_Programmer_Error + 1;
-            else
-               Summary (Label).Fail_Other := Summary (Label).Fail_Other + 1;
-            end if;
-
-         else
-            --  Process per-parser data
-            Last := Index (Line, "(", Last + 1);
-            loop
-               exit when Line (Last + 1) = ')';
-               declare
-                  Strategy_Found : Boolean;
-                  Strat_Counts   : constant Strategy_Counts := 
Read_Strat_Counts (Strategy_Found);
-                  Enqueue_Count  : constant Integer         := Next_Integer;
-                  Check_Count    : constant Integer         := Next_Integer;
-                  Success        : constant Boolean         := Next_Boolean;
-                  pragma Unreferenced (Success);
-               begin
-                  Summary (Label).Recover_Count_Present := Summary 
(Label).Recover_Count_Present + 1;
-
-                  if not Strategy_Found then
-                     raise SAL.Programmer_Error;
-                  else
-                     Summary (Label).Enqueue_Stats.Accumulate (Long_Float 
(Enqueue_Count));
-                     Summary (Label).Check_Stats.Accumulate (Long_Float 
(Check_Count));
-                     for I in Strategies loop
-                        Summary (Label).Recover_Count_Total    :=
-                          Summary (Label).Recover_Count_Total + Strat_Counts 
(I);
-                        Summary (Label).Strat_Counts_Total (I) :=
-                          Summary (Label).Strat_Counts_Total (I) + 
Strat_Counts (I);
-                        if Strat_Counts (I) > 0 then
-                           Summary (Label).Strat_Counts_Present (I) := Summary 
(Label).Strat_Counts_Present (I) + 1;
-                        end if;
-                     end loop;
-                  end if;
-               end;
-            end loop;
-         end if;
-      end;
-   end loop;
-
-   declare
-      use Ada.Strings;
-
-      Label_Field     : String (1 .. 23); -- fits strategy and fail labels
-      Count_Field     : String (1 .. 8);
-      Percent_Field   : String (1 .. 4);
-      --  Shared by Put_If, Put_Percent
-
-      procedure Put_If
-        (Summary_Label : in Recover_Label;
-         Name          : in String;
-         Count         : in Integer;
-         Always        : in Boolean := False)
-      is
-         Percent_Present : constant Integer :=
-           Integer (100.0 * Float (Count) / Float (Summary 
(Summary_Label).Event_Count));
-      begin
-         if Count > 0 or Always then
-            Move (Name, Label_Field); Put (Label_Field & " => ");
-            Move (Count'Image, Count_Field, Justify => Right); Put 
(Count_Field);
-            Move (Percent_Present'Image & "%", Percent_Field, Justify => 
Right); Put_Line (Percent_Field);
-         end if;
-      end Put_If;
-
-      package Stats_Image is new SAL.Long_Float_Stats.Gen_Image
-        (Real_IO           => Ada.Long_Float_Text_IO,
-         Default_Mean_Fore => 7,
-         Default_Mean_Aft  => 0,
-         Default_Mean_Exp  => 0,
-         Default_Sd_Fore   => 7,
-         Default_Sd_Aft    => 1,
-         Default_Sd_Exp    => 0);
-
-      procedure Put_Percent (Summary_Label : in Recover_Label; Present, Total 
: in Integer; Name : in String)
-      is
-         Percent_Present : constant Integer :=
-           Integer (100.0 * Float (Present) / Float (Summary 
(Summary_Label).Recover_Count_Present));
-         Percent_Total   : constant Integer :=
-           Integer (100.0 * Float (Total) / Float (Summary 
(Summary_Label).Recover_Count_Total));
-      begin
-         Move (Name, Label_Field); Put (Label_Field);
-         Move (Present'Image, Count_Field, Justify => Right); Put 
(Count_Field);
-         Move (Percent_Present'Image & "%", Percent_Field, Justify => Right); 
Put (Percent_Field & " /");
-         Move (Total'Image, Count_Field, Justify => Right); Put (Count_Field);
-         Move (Percent_Total'Image & "%", Percent_Field, Justify => Right); 
Put_Line (Percent_Field);
-      end Put_Percent;
-
-   begin
-      for I in Recover_Label loop
-         Put_Line (I'Image);
-         Put_Line ("present/total:" & Summary (I).Event_Count'Image & " /" & 
Summary (I).Recover_Count_Total'Image);
-         if Summary (I).Event_Count > 0 then
-            Put_Line ("           mean        std. dev.    min     max");
-            Put_Line ("Enqueue: " & Stats_Image.Image (Summary 
(I).Enqueue_Stats.Display));
-            Put_Line ("Check:   " & Stats_Image.Image (Summary 
(I).Check_Stats.Display));
-            Put_If (I, "FAIL", Summary (I).Fail_Event_Count, Always => True);
-            Put_If (I, "FAIL_ENQUEUE_LIMIT", Summary (I).Fail_Enqueue_Limit);
-            Put_If (I, "FAIL_NO_CONFIGS_LEFT", Summary 
(I).Fail_No_Configs_Left);
-            Put_If (I, "FAIL_PROGRAMMER_ERROR", Summary 
(I).Fail_Programmer_Error);
-            Put_If (I, "FAIL_OTHER", Summary (I).Fail_Other);
-            for J in Strategies loop
-               Put_Percent
-                 (I,
-                  Summary (I).Strat_Counts_Present (J),
-                  Summary (I).Strat_Counts_Total (J),
-                  J'Image);
-            end loop;
-         end if;
-         New_Line;
-      end loop;
-   end;
-exception
-when E : others =>
-   Put_Line (Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E));
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Recover_Stats;
diff --git a/packages/wisi/run_wisi_common_parse.adb 
b/packages/wisi/run_wisi_common_parse.adb
deleted file mode 100644
index c79f2e7..0000000
--- a/packages/wisi/run_wisi_common_parse.adb
+++ /dev/null
@@ -1,356 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.IO_Exceptions;
-with Ada.Real_Time;
-with Ada.Text_IO;
-with SAL;
-with System.Multiprocessors;
-package body Run_Wisi_Common_Parse is
-
-   procedure Usage (Parser : in out WisiToken.Parse.LR.Parser.Parser)
-   is
-      use all type WisiToken.Parse.LR.Parse_Table_Ptr;
-      use Ada.Text_IO;
-   begin
-      Put_Line ("usage: parse <parse_action> <file_name> [partial parse 
params] [options]");
-      Put_Line ("   or: refactor <refactor_action> <file_name> <edit_begin> 
[options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("partial parse params: begin_byte_pos end_byte_pos 
goal_byte_pos begin_char_pos begin_line" &
-                  " end_line begin_indent");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m l: (no 'm' for refactor)");
-      Put_Line ("   n: parser; m: mckenzie; l: action");
-      Put_Line ("   0 - only report parse errors");
-      Put_Line ("   1 - shows spawn/terminate parallel parsers, error recovery 
enter/exit");
-      Put_Line ("   2 - add each parser cycle, error recovery enqueue/check");
-      Put_Line ("   3 - parse stack in each cycle, error recovery parse 
actions");
-      Put_Line ("   4 - add lexer debug, dump syntax tree");
-      Put_Line ("--check_limit n  : set error recover token check limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Check_Limit'Image));
-      Put_Line ("--check_delta n  : set error recover delta check limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Check_Delta_Limit'Image));
-      Put_Line ("--enqueue_limit n  : set error recover token enqueue limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Enqueue_Limit'Image));
-      Put_Line ("--max_parallel n  : set maximum count of parallel parsers 
(default" &
-                  WisiToken.Parse.LR.Parser.Default_Max_Parallel'Image & ")");
-      Put_Line ("--task_count n : worker tasks in error recovery");
-      Put_Line ("--disable_recover : disable error recovery; default enabled");
-      Put_Line ("--debug_mode : tracebacks from unhandled exceptions; default 
disabled");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      New_Line;
-   end Usage;
-
-   function Get_CL_Params (Parser : in out WisiToken.Parse.LR.Parser.Parser) 
return Command_Line_Params
-   is
-      use Ada.Command_Line;
-      use WisiToken;
-      Arg     : Integer := 1;
-      Command : Command_Type;
-   begin
-      if Argument_Count < 1 then
-         Usage (Parser);
-         Set_Exit_Status (Failure);
-         raise Finish;
-
-      elsif Argument (Arg) = "--help" then
-         Usage (Parser);
-         raise Finish;
-
-      elsif Argument_Count < 2 then
-         Usage (Parser);
-         Set_Exit_Status (Failure);
-         raise Finish;
-      end if;
-
-      Command := Command_Type'Value (Ada.Command_Line.Argument (1));
-
-      return Result : Command_Line_Params (Command) do
-         Result.Source_File_Name  := +Ada.Command_Line.Argument (3);
-
-         case Command is
-         when Parse =>
-            Result.Post_Parse_Action := Wisi.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-
-            if Argument_Count >= 4 and then Argument (4)(1) /= '-' then
-               Result.Begin_Byte_Pos := WisiToken.Buffer_Pos'Value (Argument 
(4));
-               Result.End_Byte_Pos   := WisiToken.Buffer_Pos'Value (Argument 
(5)) - 1; -- match emacs region
-               Result.Goal_Byte_Pos  := WisiToken.Buffer_Pos'Value (Argument 
(6));
-               Result.Begin_Char_Pos := WisiToken.Buffer_Pos'Value (Argument 
(7));
-               Result.Begin_Line     := WisiToken.Line_Number_Type'Value 
(Argument (8));
-               Result.End_Line       := WisiToken.Line_Number_Type'Value 
(Argument (9));
-               Result.Begin_Indent   := Integer'Value (Argument (10));
-               Arg                   := 11;
-            else
-               Result.Begin_Byte_Pos := WisiToken.Invalid_Buffer_Pos;
-               Result.End_Byte_Pos   := WisiToken.Invalid_Buffer_Pos;
-               Result.Begin_Char_Pos := WisiToken.Buffer_Pos'First;
-               Result.Begin_Line     := WisiToken.Line_Number_Type'First;
-               Arg                   := 4;
-            end if;
-
-         when Refactor =>
-            Result.Refactor_Action := Integer'Value (Argument (2));
-            Result.Edit_Begin      := WisiToken.Buffer_Pos'Value (Argument 
(4));
-            Arg                    := 5;
-         end case;
-
-         loop
-            exit when Arg > Argument_Count;
-
-            if Argument (Arg) = "--verbosity" then
-               WisiToken.Trace_Parse    := Integer'Value (Argument (Arg + 1));
-               case Command is
-               when Parse =>
-                  WisiToken.Trace_McKenzie := Integer'Value (Argument (Arg + 
2));
-                  WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 
3));
-                  Arg                      := Arg + 4;
-               when Refactor =>
-                  WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 
2));
-                  Arg                      := Arg + 3;
-               end case;
-
-               WisiToken.Debug_Mode := WisiToken.Trace_Parse > Outline or 
WisiToken.Trace_McKenzie > Outline;
-
-            elsif Argument (Arg) = "--check_limit" then
-               Parser.Table.McKenzie_Param.Check_Limit := Token_Index'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--check_delta" then
-               Parser.Table.McKenzie_Param.Check_Delta_Limit := Integer'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--debug_mode" then
-               WisiToken.Debug_Mode := True;
-               Arg := Arg + 1;
-
-            elsif Argument (Arg) = "--disable_recover" then
-               Parser.Enable_McKenzie_Recover := False;
-               Arg := Arg + 1;
-
-            elsif Argument (Arg) = "--enqueue_limit" then
-               Parser.Table.McKenzie_Param.Enqueue_Limit := Integer'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--lang_params" then
-               Result.Lang_Params := +Argument (Arg + 1);
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--max_parallel" then
-               Parser.Max_Parallel := SAL.Base_Peek_Type'Value (Argument (Arg 
+ 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--repeat_count" then
-               Result.Repeat_Count := Integer'Value (Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--task_count" then
-               Parser.Table.McKenzie_Param.Task_Count := 
System.Multiprocessors.CPU_Range'Value (Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            else
-               Ada.Text_IO.Put_Line ("unrecognized option: '" & Argument (Arg) 
& "'");
-               Usage (Parser);
-               Set_Exit_Status (Failure);
-               raise SAL.Parameter_Error;
-            end if;
-         end loop;
-      end return;
-   exception
-   when Finish =>
-      raise;
-
-   when E : others =>
-      Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E));
-      Usage (Parser);
-      Set_Exit_Status (Failure);
-      raise SAL.Parameter_Error;
-   end Get_CL_Params;
-
-   procedure Parse_File
-     (Parser     : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data : in out Wisi.Parse_Data_Type'Class;
-      Descriptor : in     WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-      use WisiToken;
-
-      Start     : Ada.Real_Time.Time;
-      End_Line  : WisiToken.Line_Number_Type;
-
-      function Image_Augmented (Aug : in Base_Token_Class_Access) return String
-      is begin
-         --  For Syntax_Trees.Print_Tree
-         return Wisi.Image (Aug, Descriptor);
-      end Image_Augmented;
-
-   begin
-      Parser.Trace.Set_Prefix (";; "); -- so we get the same debug messages as 
Emacs_Wisi_Common_Parse
-
-      declare
-         Cl_Params : constant Command_Line_Params := Get_CL_Params (Parser);
-      begin
-         begin
-            case Cl_Params.Command is
-            when Parse =>
-               Parser.Lexer.Reset_With_File
-                 (-Cl_Params.Source_File_Name, Cl_Params.Begin_Byte_Pos, 
Cl_Params.End_Byte_Pos,
-                  Cl_Params.Begin_Char_Pos, Cl_Params.Begin_Line);
-            when Refactor =>
-               Parser.Lexer.Reset_With_File (-Cl_Params.Source_File_Name);
-            end case;
-         exception
-         when Ada.IO_Exceptions.Name_Error =>
-            Put_Line (Standard_Error, "'" & (-Cl_Params.Source_File_Name) & "' 
cannot be opened");
-            return;
-         end;
-
-         --  Parser.Line_Begin_Token First, Last set by Lex_All
-
-         if Cl_Params.Command = Refactor or else Cl_Params.End_Line = 
Invalid_Line_Number then
-            --  User did not provide; run lexer to get end line.
-            declare
-               Token       : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               loop
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  exit when Token.ID = Descriptor.EOI_ID;
-               end loop;
-               End_Line := Token.Line;
-            end;
-         else
-            End_Line := Cl_Params.End_Line;
-         end if;
-
-         Parse_Data.Initialize
-           (Post_Parse_Action =>
-              (case Cl_Params.Command is
-               when Parse    => Cl_Params.Post_Parse_Action,
-               when Refactor => Wisi.Navigate),
-            Lexer            => Parser.Lexer,
-            Descriptor       => Descriptor'Unrestricted_Access,
-            Base_Terminals   => Parser.Terminals'Unrestricted_Access,
-            Begin_Line       =>
-              (case Cl_Params.Command is
-               when Parse => Cl_Params.Begin_Line,
-               when Refactor => WisiToken.Line_Number_Type'First),
-            End_Line         => End_Line,
-            Begin_Indent     =>
-              (case Cl_Params.Command is
-               when Parse    => Cl_Params.Begin_Indent,
-               when Refactor => 0),
-            Params            => -Cl_Params.Lang_Params);
-
-         if Cl_Params.Repeat_Count > 1 then
-            Start := Ada.Real_Time.Clock;
-         end if;
-
-         for I in 1 .. Cl_Params.Repeat_Count loop
-            declare
-               procedure Clean_Up
-               is
-                  use all type SAL.Base_Peek_Type;
-               begin
-                  Parser.Lexer.Discard_Rest_Of_Input;
-                  if Cl_Params.Repeat_Count = 1 and Parser.Parsers.Count > 0 
then
-                     Parse_Data.Put
-                       (Parser.Lexer.Errors,
-                        Parser.Parsers.First.State_Ref.Errors,
-                        Parser.Parsers.First.State_Ref.Tree);
-                  end if;
-               end Clean_Up;
-
-            begin
-               Parse_Data.Reset;
-               Parser.Lexer.Reset;
-
-               begin
-                  Parser.Parse;
-               exception
-               when WisiToken.Partial_Parse =>
-                  null;
-               end;
-
-               Parser.Execute_Actions (Image_Augmented'Unrestricted_Access);
-
-               case Cl_Params.Command is
-               when Parse =>
-                  if Cl_Params.Repeat_Count = 1 then
-                     Parse_Data.Put (Parser);
-                     Parse_Data.Put
-                       (Parser.Lexer.Errors,
-                        Parser.Parsers.First.State_Ref.Errors,
-                        Parser.Parsers.First.State_Ref.Tree);
-                  end if;
-
-               when Refactor =>
-                  Parse_Data.Refactor
-                    (Parser.Parsers.First_State_Ref.Tree,
-                     Cl_Params.Refactor_Action, Cl_Params.Edit_Begin);
-               end case;
-            exception
-            when WisiToken.Syntax_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error)");
-
-            when E : WisiToken.Parse_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Name (E) 
& " " &
-                           Ada.Exceptions.Exception_Message (E) & """)");
-
-            when E : others => -- includes Fatal_Error
-               Clean_Up;
-               Put_Line ("(error """ & Ada.Exceptions.Exception_Name (E) & " " 
&
-                           Ada.Exceptions.Exception_Message (E) & """)");
-            end;
-         end loop;
-
-         if Cl_Params.Repeat_Count > 1 then
-            declare
-               use Ada.Real_Time;
-               Finish : constant Time := Clock;
-            begin
-               Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-               Put_Line ("per iteration:" & Duration'Image (To_Duration 
((Finish - Start) / Cl_Params.Repeat_Count)));
-            end;
-         end if;
-      end;
-   exception
-   when SAL.Parameter_Error | Finish =>
-      --  From Get_CL_Params; already handled.
-      null;
-
-   when E : others =>
-      Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-      New_Line (2);
-      Put_Line
-        ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) 
& ": " &
-           Ada.Exceptions.Exception_Message (E) & """)");
-   end Parse_File;
-
-end Run_Wisi_Common_Parse;
diff --git a/packages/wisi/run_wisi_common_parse.ads 
b/packages/wisi/run_wisi_common_parse.ads
deleted file mode 100644
index c00d007..0000000
--- a/packages/wisi/run_wisi_common_parse.ads
+++ /dev/null
@@ -1,73 +0,0 @@
---  Abstract :
---
---  Common utilities for Gen_Run_Wisi_*_Parse
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Strings.Unbounded;
-with Wisi;
-with WisiToken.Parse.LR.Parser;
-package Run_Wisi_Common_Parse is
-
-   Finish : exception;
-
-   procedure Usage (Parser : in out WisiToken.Parse.LR.Parser.Parser);
-   --  Puts parameter description to Current_Output.
-
-   type Command_Type is (Parse, Refactor);
-
-   type Command_Line_Params (Command : Command_Type) is record
-
-      Source_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-      Lang_Params      : Ada.Strings.Unbounded.Unbounded_String;
-      Repeat_Count     : Integer := 1;
-
-      case Command is
-      when Parse =>
-         Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-         Begin_Byte_Pos    : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         End_Byte_Pos      : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         Goal_Byte_Pos     : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         Begin_Char_Pos    : WisiToken.Buffer_Pos       := 
WisiToken.Buffer_Pos'First;
-         Begin_Line        : WisiToken.Line_Number_Type := 
WisiToken.Line_Number_Type'First;
-         End_Line          : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-         Begin_Indent      : Integer                    := 0;
-
-      when Refactor =>
-         --  We assume the file contains only the one statement/declaration
-         --  that needs refactoring.
-
-         Refactor_Action : Positive;
-         --  Language-specific
-
-         Edit_Begin : WisiToken.Buffer_Pos;
-         --  Source file byte position at start of expression to refactor.
-      end case;
-   end record;
-
-   function Get_CL_Params (Parser : in out WisiToken.Parse.LR.Parser.Parser) 
return Command_Line_Params;
-   --  For any errors, calls Usage, raises SAL.Parameter_Error.
-   --
-   --  Handles --help by outputing help, raising Finish.
-
-   procedure Parse_File
-     (Parser     : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data : in out Wisi.Parse_Data_Type'Class;
-      Descriptor : in     WisiToken.Descriptor);
-   --  Calls Get_CL_Params, reads in file, parses, does post-parse actions.
-
-end Run_Wisi_Common_Parse;
diff --git a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb 
b/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb
deleted file mode 100644
index a5dd042..0000000
--- a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-  (Item   : in Lists.List;
-   Strict : in Boolean := False)
-  return String
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result     : Unbounded_String := To_Unbounded_String ("(");
-   Need_Comma : Boolean          := False;
-begin
-   if Strict and Item.Length = 0 then
-      return "(1 .. 0 => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(1 => " & Element_Image (Lists.Element (Item.First)) & ")";
-
-   else
-      for El of Item loop
-         if Need_Comma then
-            Result := Result & ", ";
-         else
-            Need_Comma := True;
-         end if;
-         Result := Result & Element_Image (El);
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image;
diff --git a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads 
b/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads
deleted file mode 100644
index 39e9b9e..0000000
--- a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  Image for normal Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-with Ada.Containers.Doubly_Linked_Lists;
-generic
-   type Element_Type is private;
-   with function "=" (Left, Right : Element_Type) return Boolean is <>;
-   with package Lists is new Ada.Containers.Doubly_Linked_Lists (Element_Type, 
"=");
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-  (Item   : in Lists.List;
-   Strict : in Boolean := False)
-  return String;
diff --git a/packages/wisi/sal-ada_containers.ads 
b/packages/wisi/sal-ada_containers.ads
deleted file mode 100644
index 4afad1e..0000000
--- a/packages/wisi/sal-ada_containers.ads
+++ /dev/null
@@ -1,21 +0,0 @@
---  Abstract :
---
---  Root of extensions to Ada.Containers.
---
---  Copyright (C) 2019 Free Software Foundation All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-package SAL.Ada_Containers is
-
-end SAL.Ada_Containers;
diff --git a/packages/wisi/sal-gen_array_image.adb 
b/packages/wisi/sal-gen_array_image.adb
deleted file mode 100644
index 7f9097d..0000000
--- a/packages/wisi/sal-gen_array_image.adb
+++ /dev/null
@@ -1,34 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Array_Image (Item : in Array_Type) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I));
-      if I = Item'Last then
-         Result := Result & ")";
-      else
-         Result := Result & ", ";
-      end if;
-   end loop;
-   return To_String (Result);
-end SAL.Gen_Array_Image;
diff --git a/packages/wisi/sal-gen_array_image.ads 
b/packages/wisi/sal-gen_array_image.ads
deleted file mode 100644
index 53bd25f..0000000
--- a/packages/wisi/sal-gen_array_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image for normal Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type) of Element_Type;
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Array_Image (Item : in Array_Type) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_queues.adb 
b/packages/wisi/sal-gen_bounded_definite_queues.adb
deleted file mode 100644
index 71b68c5..0000000
--- a/packages/wisi/sal-gen_bounded_definite_queues.adb
+++ /dev/null
@@ -1,103 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2004, 2008, 2009, 2011, 2017, 2019 Free Software Foundation 
All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Queues
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   ----------
-   --  Public subprograms
-
-   procedure Clear (Queue : in out Queue_Type) is
-   begin
-      Queue.Count := 0;
-   end Clear;
-
-   function Count (Queue : in Queue_Type) return Base_Peek_Type is 
(Queue.Count);
-
-   function Is_Empty (Queue : in Queue_Type) return Boolean is
-   begin
-      return Queue.Count = 0;
-   end Is_Empty;
-
-   function Is_Full (Queue : in Queue_Type) return Boolean is
-   begin
-      return Queue.Count = Queue.Size;
-   end Is_Full;
-
-   procedure Remove (Queue : in out Queue_Type; Item : out Item_Type)
-   is begin
-      Item := Queue.Data (Queue.Head);
-
-      Queue.Count := Queue.Count - 1;
-
-      if Queue.Count > 0 then
-         Queue.Head := Wrap (Queue.Size, Queue.Head + 1);
-      end if;
-   end Remove;
-
-   function Remove (Queue : in out Queue_Type) return Item_Type with
-     Spark_Mode => Off
-   is begin
-      return Item : Item_Type  do
-         Remove (Queue, Item);
-      end return;
-   end Remove;
-
-   procedure Drop (Queue : in out Queue_Type)
-   is begin
-      Queue.Count := Queue.Count - 1;
-
-      if Queue.Count > 0 then
-         Queue.Head := Wrap (Queue.Size, Queue.Head + 1);
-      end if;
-   end Drop;
-
-   function Peek (Queue : in Queue_Type; N : Peek_Type := 1) return Item_Type
-     is (Queue.Data (Wrap (Queue.Size, Queue.Head + N - 1)));
-   --  Expression function to allow use in Spark proofs of conditions in spec.
-
-   procedure Add (Queue : in out Queue_Type; Item : in Item_Type) is
-   begin
-      if Queue.Count = 0 then
-         Queue.Tail  := 1;
-         Queue.Head  := 1;
-         Queue.Count := 1;
-      else
-         Queue.Tail  := Wrap (Queue.Size, Queue.Tail + 1);
-         Queue.Count := Queue.Count + 1;
-      end if;
-      Queue.Data (Queue.Tail) := Item;
-   end Add;
-
-   procedure Add_To_Head (Queue : in out Queue_Type; Item : in Item_Type) is
-   begin
-      if Queue.Count = 0 then
-         Queue.Tail  := 1;
-         Queue.Head  := 1;
-         Queue.Count := 1;
-      else
-         Queue.Head  := Wrap (Queue.Size, Queue.Head - 1);
-         Queue.Count := Queue.Count + 1;
-      end if;
-      Queue.Data (Queue.Head) := Item;
-   end Add_To_Head;
-
-end SAL.Gen_Bounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_bounded_definite_queues.ads 
b/packages/wisi/sal-gen_bounded_definite_queues.ads
deleted file mode 100644
index 5614519..0000000
--- a/packages/wisi/sal-gen_bounded_definite_queues.ads
+++ /dev/null
@@ -1,117 +0,0 @@
---  Abstract:
---
---  A generic queue, allowing definite non-limited item types.
---
---  Copyright (C) 2004, 2008, 2009, 2011, 2017, 2019 Free Software Foundation  
All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Item_Type is private;
-package SAL.Gen_Bounded_Definite_Queues
-  with Spark_Mode
-is
-   pragma Pure;
-   pragma Suppress (All_Checks); --  Users must check Is_Full before Add, 
Is_Empty before Remove.
-
-   subtype Size_Type is Peek_Type range 1 .. Peek_Type'Last / 2;
-   --  The upper limit is needed to avoid overflow in Peek.
-
-   type Queue_Type (Size : Size_Type) is private;
-   --  Size is maximum number of items in the queue.
-
-   procedure Clear (Queue : in out Queue_Type)
-   with Post => Count (Queue) = 0;
-   --  Empty Queue of all items.
-
-   function Count (Queue : in Queue_Type) return Base_Peek_Type;
-   --  Returns count of items in the Queue
-
-   function Is_Empty (Queue : in Queue_Type) return Boolean
-   with Post => Is_Empty'Result = (Count (Queue) = 0);
-   --  Returns true if no items are in Queue.
-
-   function Is_Full (Queue : in Queue_Type) return Boolean
-   with Post => Is_Full'Result = (Count (Queue) = Queue.Size);
-   --  Returns true if Queue is full.
-
-   procedure Remove (Queue : in out Queue_Type; Item : out Item_Type) with
-     Pre  => Count (Queue) > 0,
-     Post => Count (Queue) = Count (Queue)'Old - 1 and Item = Peek (Queue'Old) 
and
-             (for all I in 1 .. Count (Queue) => Peek (Queue'Old, I + 1) = 
Peek (Queue, I));
-   --  Remove head item from Queue, return it.
-
-   function Remove (Queue : in out Queue_Type) return Item_Type with
-     Spark_Mode => Off;
-
-   function Get (Queue : in out Queue_Type) return Item_Type renames Remove;
-
-   procedure Drop (Queue : in out Queue_Type) with
-     Pre  => Count (Queue) > 0,
-     Post => Count (Queue) = Count (Queue)'Old - 1 and
-             (for all I in 1 .. Count (Queue) => Peek (Queue'Old, I + 1) = 
Peek (Queue, I));
-   --  Remove head item from Queue, discard it.
-
-   function Peek (Queue : in Queue_Type; N : Peek_Type := 1) return Item_Type 
with
-     Pre  => Count (Queue) in 1 .. Queue.Size and N in 1 .. Count (Queue);
-   --  Return a copy of a queue item, without removing it. N = 1 is
-   --  the queue head.
-
-   procedure Add (Queue : in out Queue_Type; Item : in Item_Type) with
-     Pre  => Count (Queue) in 0 .. Queue.Size - 1,
-     Post => Count (Queue) = Count (Queue)'Old + 1 and Peek (Queue, Count 
(Queue)) = Item and
-             (for all I in 1 .. Count (Queue)'Old => Peek (Queue'Old, I) = 
Peek (Queue, I));
-   --  Add Item to the tail of Queue.
-
-   procedure Put (Queue : in out Queue_Type; Item : in Item_Type) renames Add;
-
-   procedure Add_To_Head (Queue : in out Queue_Type; Item : in Item_Type) with
-     Pre  => Count (Queue) in 0 .. Queue.Size - 1,
-     Post => Count (Queue) = Count (Queue)'Old + 1 and
-             (Peek (Queue) = Item and
-              (for all I in 2 .. Count (Queue) => Peek (Queue'Old, I - 1) = 
Peek (Queue, I)));
-   --  Add Item to the head of Queue.
-
-private
-
-   type Item_Array_Type is array (Peek_Type range <>) of Item_Type;
-
-   type Queue_Type (Size : Size_Type) is
-   record
-      Head  : Peek_Type      := 1;
-      Tail  : Peek_Type      := 1;
-      Count : Base_Peek_Type := 0;
-      Data  : Item_Array_Type (1 .. Size);
-      --  Add at Tail + 1, remove at Head. Count is current count;
-      --  easier to keep track of that than to compute Is_Empty for
-      --  each Add and Remove.
-      --
-      --  Empty is indicated by Count = 0; head and tail are arbitrary
-      --  in that case.
-   end record with
-     Type_Invariant =>
-       (Head in 1 .. Size and
-        Tail in 1 .. Size and
-        Count in 0 .. Size) and then
-       (Count = 0 or else Wrap (Size, Head + Count - 1) = Tail);
-
-   function Wrap (Size : in Size_Type; I : in Base_Peek_Type) return Peek_Type
-     is (if I > Size then I - Size
-         elsif I = 0 then Size
-         else I)
-     with
-       Pre  => I in 0 .. 2 * Size - 1,
-       Post => Wrap'Result in 1 .. Size;
-
-end SAL.Gen_Bounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb
deleted file mode 100644
index 7dcd96f..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type :=
-     (if Depth = 0
-      then Item.Top
-      else Base_Peek_Type'Min (Depth, Item.Top));
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads
deleted file mode 100644
index e960398..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads
+++ /dev/null
@@ -1,27 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks.adb 
b/packages/wisi/sal-gen_bounded_definite_stacks.adb
deleted file mode 100644
index fc81daa..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks.adb
+++ /dev/null
@@ -1,82 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 1998, 2003, 2009, 2015, 2017 - 2019 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied
---  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---  See the GNU General Public License for more details. You should
---  have received a copy of the GNU General Public License distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce an
---  executable, that does not by itself cause the resulting executable
---  to be covered by the GNU General Public License. This exception
---  does not however invalidate any other reasons why the executable
---  file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Stacks
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   procedure Clear (Stack : in out Sgbds.Stack)
-   is begin
-      Stack.Top := 0;
-   end Clear;
-
-   function Depth (Stack : in Sgbds.Stack) return Size_Type
-     is (Stack.Top);
-
-   function Is_Empty (Stack : in Sgbds.Stack) return Boolean
-   is begin
-      return Stack.Top = 0;
-   end Is_Empty;
-
-   function Is_Full (Stack : in Sgbds.Stack) return Boolean
-   is begin
-      return Stack.Top = Stack.Size;
-   end Is_Full;
-
-   function Peek
-     (Stack : in Sgbds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type
-     is (Stack.Data (Stack.Top - Index + 1));
-
-   procedure Pop (Stack : in out Sgbds.Stack; Count : in Base_Peek_Type := 1)
-   is begin
-      Stack.Top := Stack.Top - Count;
-   end Pop;
-
-   procedure Pop (Stack : in out Sgbds.Stack; Item : out Element_Type)
-   is begin
-      Item := Stack.Peek (1);
-      Stack.Top := Stack.Top - 1;
-   end Pop;
-
-   function Pop (Stack : in out Sgbds.Stack) return Element_Type with
-     Spark_Mode => Off
-   is begin
-      return Result : Element_Type do
-         Pop (Stack, Result);
-      end return;
-   end Pop;
-
-   procedure Push (Stack : in out Sgbds.Stack; Item : in Element_Type)
-   is begin
-      Stack.Top := Stack.Top + 1;
-      Stack.Data (Stack.Top) := Item;
-   end Push;
-
-end SAL.Gen_Bounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks.ads 
b/packages/wisi/sal-gen_bounded_definite_stacks.ads
deleted file mode 100644
index e2ba7ab..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks.ads
+++ /dev/null
@@ -1,103 +0,0 @@
---  Abstract:
---
---  Bounded stack implementation, with full Spark verification,
---  optimized for speed.
---
---  Copyright (C) 1998-2000, 2002-2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied
---  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---  See the GNU General Public License for more details. You should
---  have received a copy of the GNU General Public License distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is private;
-package SAL.Gen_Bounded_Definite_Stacks
-  with Spark_Mode
-is
-   pragma Pure;
-   --  pragma Suppress (All_Checks); --  Users must check Is_Full before Push, 
Is_Empty before Pop etc.
-
-   package Sgbds renames SAL.Gen_Bounded_Definite_Stacks;
-
-   subtype Size_Type is Base_Peek_Type range 0 .. Base_Peek_Type'Last / 2;
-   --  The upper limit is needed to avoid overflow in Peek.
-   --  Zero included for Depth result.
-
-   type Stack (Size : Size_Type) is tagged private;
-   --  Tagged to allow Object.Method notation.
-
-   --  No Empty_Stack constant, to avoid requiring a Default_Element.
-
-   procedure Clear (Stack : in out Sgbds.Stack)
-   with Post'Class => Depth (Stack) = 0;
-   --  Empty Stack of all items.
-
-   function Depth (Stack : in Sgbds.Stack) return Size_Type;
-   --  Returns current count of items in Stack
-
-   function Is_Empty (Stack : in Sgbds.Stack) return Boolean
-   with Post'Class => Is_Empty'Result = (Depth (Stack) = 0);
-   --  Returns true iff no items are in Stack.
-
-   function Is_Full (Stack : in Sgbds.Stack) return Boolean
-   with Post'Class => Is_Full'Result = (Depth (Stack) = Stack.Size);
-   --  Returns true iff Stack is full.
-
-   function Peek (Stack : in Sgbds.Stack; Index : in Peek_Type := 1) return 
Element_Type
-   with Pre'Class  => Depth (Stack) in 1 .. Stack.Size and Index in 1 .. Depth 
(Stack);
-   --  Return the Index'th item from the top of Stack; the Item is _not_ 
removed.
-   --  Top item has index 1.
-
-   procedure Pop (Stack : in out Sgbds.Stack; Count : in Base_Peek_Type := 1) 
with
-     Pre'Class  => Depth (Stack) in 1 .. Stack.Size and Count in 0 .. Depth 
(Stack),
-     Post'Class => Depth (Stack) = Depth (Stack)'Old - Count and then
-                   (for all I in 1 .. Depth (Stack) => Peek (Stack'Old, I + 
Count) = Peek (Stack, I));
-   --  Remove Count Items from the top of Stack, discard them.
-
-   procedure Pop (Stack : in out Sgbds.Stack; Item : out Element_Type) with
-     Pre'Class  => Depth (Stack) in 1 .. Stack.Size,
-     Post'Class =>
-       Depth (Stack) = Depth (Stack)'Old - 1 and then
-       (Item = Peek (Stack'Old) and
-        (for all I in 1 .. Depth (Stack) => Peek (Stack'Old, I + 1) = Peek 
(Stack, I)));
-   --  Remove one item from the top of Stack, return in Item.
-
-   function Pop (Stack : in out Sgbds.Stack) return Element_Type with
-     Spark_Mode => Off;
-   --  Remove one item from the top of Stack, and return it.
-
-   procedure Push (Stack : in out Sgbds.Stack; Item : in Element_Type) with
-     Pre'Class  => Depth (Stack) in 0 .. Stack.Size - 1,
-     Post'Class =>
-       Depth (Stack) = Depth (Stack)'Old + 1 and then
-       (Item = Peek (Stack) and
-        (for all I in 1 .. Depth (Stack'Old) => Peek (Stack'Old, I) = Peek 
(Stack, I + 1)));
-   --  Add Item to the top of Stack.
-
-private
-
-   type Element_Array is array (Size_Type range <>) of aliased Element_Type;
-
-   type Stack (Size : Size_Type) is tagged record
-      Top  : Base_Peek_Type := Invalid_Peek_Index; -- empty
-      Data : Element_Array (1 .. Size);
-      --  Top of stack is at Data (Top).
-      --  Data (1 .. Top) has been set at some point.
-   end record with
-     Dynamic_Predicate => Stack.Top in 0 .. Stack.Size;
-
-end SAL.Gen_Bounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb
deleted file mode 100644
index ae901fe..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb
+++ /dev/null
@@ -1,40 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image (Item : in Vector) return 
String
-is
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := To_Peek_Index (Item.Last);
-begin
-   for I in 1 .. Last loop
-      Result := Result &
-        (if Trim
-         then Fixed.Trim (Element_Image (Item.Elements (I)), Left)
-         else Element_Image (Item.Elements (I)));
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Image;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads
deleted file mode 100644
index 950b9d0..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-   Trim : in Boolean;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image (Item : in Vector) return 
String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb
deleted file mode 100644
index 685ef13..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux (Item : in Vector; Aux 
: in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := To_Peek_Index (Item.Last);
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads
deleted file mode 100644
index 241e67b..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux (Item : in Vector; Aux 
: in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb
deleted file mode 100644
index 8f9d741..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors.Gen_Refs is
-
-   function Variable_Ref
-     (Container : aliased in out Vector;
-      Index     :         in     Index_Type)
-     return Variable_Reference_Type
-   is begin
-      return (Element => Container.Elements (To_Peek_Index (Index))'Access, 
Dummy => 1);
-   end Variable_Ref;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (To_Peek_Index (Index))'Access, 
Dummy => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads
deleted file mode 100644
index c235cbc..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads
+++ /dev/null
@@ -1,54 +0,0 @@
---  Abstract :
---
---  Variable_Reference for parent.
---
---  In a child package because it's not Spark, and Spark does not
---  allow 'Spark_Mode => Off' on type declarations.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-package SAL.Gen_Bounded_Definite_Vectors.Gen_Refs
-  with Spark_Mode => Off
-is
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Ref (Container : aliased in out Vector; Index : in 
Index_Type) return Variable_Reference_Type
-   with Inline,
-     Pre => Index in Index_Type'First .. Last_Index (Container);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   with Inline,
-     Pre => Index in Index_Type'First .. Last_Index (Container);
-
-private
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors.adb
deleted file mode 100644
index 17aac08..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors.adb
+++ /dev/null
@@ -1,120 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is (Ada.Containers.Count_Type (To_Peek_Index (Container.Last)));
-
-   function Is_Full (Container : in Vector) return Boolean
-   is begin
-      return Length (Container) = Capacity;
-   end Is_Full;
-
-   procedure Clear (Container : in out Vector)
-   is begin
-      Container.Last := No_Index;
-   end Clear;
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   is (Container.Elements (Peek_Type (Index - Index_Type'First + 1)));
-
-   procedure Replace_Element
-     (Container : in out Vector;
-      Index     : in     Index_Type;
-      New_Item  : in     Element_Type)
-   is begin
-      Container.Elements (To_Peek_Index (Index)) := New_Item;
-   end Replace_Element;
-
-   function Last_Index (Container : Vector) return Extended_Index
-   is (Container.Last);
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type)
-   is
-      J : constant Peek_Type := To_Peek_Index (Container.Last + 1);
-   begin
-      Container.Elements (J) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Append;
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type)
-   is
-      J : constant Peek_Type := Peek_Type (Container.Last + 1 - 
Index_Type'First + 1);
-   begin
-      Container.Elements (2 .. J) := Container.Elements (1 .. J - 1);
-      Container.Elements (1) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Prepend;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type;
-      Before    : in     Extended_Index)
-   is
-      J : constant Peek_Type := To_Peek_Index ((if Before = No_Index then 
Container.Last + 1 else Before));
-      K : constant Base_Peek_Type := To_Peek_Index (Container.Last);
-   begin
-      Container.Elements (J + 1 .. K + 1) := Container.Elements (J .. K);
-      Container.Elements (J) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Insert;
-
-   function "+" (Item : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Append (Result, Item);
-      end return;
-   end "+";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      --  WORKAROUND: If init Result with ":= Left", GNAT Community 2019
-      --  checks Default_Initial_Condition (which fails when Left is not
-      --  empty)! That is only supposed to be checked when initialized by
-      --  default. Reported to AdaCore as ticket S724-042.
-      return Result : Vector do
-         Result := Left;
-         Append (Result, Right);
-      end return;
-   end "&";
-
-   procedure Delete_First (Container : in out Vector; Count : in 
Ada.Containers.Count_Type := 1)
-   is
-      use Ada.Containers;
-   begin
-      if Count = 0 then
-         return;
-      end if;
-
-      declare
-         New_Last : constant Extended_Index := Extended_Index (Integer 
(Container.Last) - Integer (Count));
-         J        : constant Base_Peek_Type := Base_Peek_Type (Count);
-         K        : constant Peek_Type      := To_Peek_Index (Container.Last);
-      begin
-         --  Delete items 1 .. J, shift remaining down.
-         Container.Elements (1 .. K - J) := Container.Elements (J + 1 .. K);
-         Container.Last := New_Last;
-      end;
-   end Delete_First;
-
-end SAL.Gen_Bounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors.ads
deleted file mode 100644
index 9e698e2..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors.ads
+++ /dev/null
@@ -1,145 +0,0 @@
---  Abstract :
---
---  A simple bounded vector of definite items, in Spark.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Index_Type is range <>;
-   type Element_Type is private;
-   Capacity : in Ada.Containers.Count_Type;
-package SAL.Gen_Bounded_Definite_Vectors
-  with Spark_Mode
-is
-   use all type Ada.Containers.Count_Type;
-
-   subtype Extended_Index is Index_Type'Base
-     range Index_Type'First - 1 ..
-           Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
-
-   pragma Assert (Capacity <= Ada.Containers.Count_Type (Index_Type'Last - 
Index_Type'First + 1));
-
-   No_Index : constant Extended_Index := Extended_Index'First;
-
-   type Vector is private with
-     Default_Initial_Condition => Length (Vector) = 0;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type 
with
-     Post => Length'Result in 0 .. Capacity;
-
-   function Is_Full (Container : in Vector) return Boolean with
-     Post => Is_Full'Result = (Length (Container) = Capacity);
-
-   function Has_Space (Container : in Vector; Item_Count : in 
Ada.Containers.Count_Type) return Boolean
-     is (Length (Container) + Item_Count <= Capacity)
-     with Pre => Item_Count <= Ada.Containers.Count_Type'Last - Length 
(Container);
-
-   procedure Clear (Container : in out Vector) with
-     Post => Length (Container) = 0;
-
-   function First_Index (Container : in Vector) return Index_Type is 
(Index_Type'First) with
-       Depends => (First_Index'Result => null, null => Container);
-
-   function Last_Index (Container : in Vector) return Extended_Index;
-   --  No_Index when Container is empty.
-
-   function Element (Container : in Vector; Index : in Index_Type) return 
Element_Type
-   with Pre => Index <= Last_Index (Container);
-   --  Index of first element in Vector is Index_Type'First.
-
-   procedure Replace_Element
-     (Container : in out Vector;
-      Index     : in     Index_Type;
-      New_Item  : in     Element_Type)
-   with
-     Pre  => Index <= Last_Index (Container),
-     Post => Element (Container, Index) = New_Item;
-   --  Index of first element in Vector is Index_Type'First.
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type) 
with
-     Pre  => Length (Container) < Capacity,
-     Post => Length (Container) = Length (Container'Old) + 1 and
-             Element (Container, Last_Index (Container)) = New_Item and
-             (for all I in Index_Type'First .. Last_Index (Container) - 1 =>
-                Element (Container'Old, I) = Element (Container, I));
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type) 
with
-     Pre  => Length (Container) < Capacity,
-     Post => Length (Container) = Length (Container'Old) + 1 and then
-             (Element (Container, Index_Type'First) = New_Item and
-              (for all I in Index_Type'First .. Last_Index (Container'Old) =>
-                 Element (Container'Old, I) = Element (Container, I + 1)));
-   --  Insert New_Item at beginning of Container; current elements slide right.
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type;
-      Before    : in     Extended_Index) with
-     Pre  => Length (Container) < Capacity and Before <= Last_Index 
(Container),
-     Contract_Cases =>
-       (Before = No_Index =>
-          Length (Container) = Length (Container'Old) + 1 and
-          Element (Container, Last_Index (Container)) = New_Item and
-          (for all I in Index_Type'First .. Last_Index (Container) - 1 =>
-             Element (Container'Old, I) = Element (Container, I)),
-        Before /= No_Index =>
-          Length (Container) = Length (Container'Old) + 1 and
-          Element (Container, Before) = New_Item and
-             (for all I in Index_Type'First .. Before - 1 =>
-                Element (Container'Old, I) = Element (Container, I)) and
-             (for all I in Before + 1 .. Last_Index (Container) =>
-                Element (Container'Old, I - 1) = Element (Container, I)));
-   --  Insert New_Item before Before, or after Last_Index if Before is
-   --  No_Index. Current elements at Before and after slide right.
-   --  New_Item then has index Before.
-
-   function "+" (Item : in Element_Type) return Vector with
-     Post => Length ("+"'Result) = 1 and
-             Element ("+"'Result, Index_Type'First) = Item;
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector with
-     Pre  => Length (Left) < Capacity,
-     Post => Length ("&"'Result) = Length (Left) + 1 and
-             (for all I in Index_Type'First .. Last_Index (Left) => Element 
(Left, I) = Element ("&"'Result, I)) and
-             Element ("&"'Result, Last_Index ("&"'Result)) = Right;
-
-   procedure Delete_First (Container : in out Vector; Count : in 
Ada.Containers.Count_Type := 1) with
-     Pre  => Length (Container) >= Count,
-     Post => Length (Container) = Length (Container)'Old - Count and then
-             (for all I in Index_Type'First .. Last_Index (Container) =>
-                Element (Container'Old, Index_Type (Integer (I) + Integer 
(Count))) = Element (Container, I));
-   --  Remaining elements slide down.
-
-private
-
-   type Array_Type is array (Peek_Type range 1 .. Peek_Type (Capacity)) of 
aliased Element_Type;
-
-   type Vector is
-   record
-      Elements : Array_Type;
-      Last     : Extended_Index := No_Index;
-   end record with
-     Type_Invariant => To_Peek_Index (Last) <= Elements'Last;
-   pragma Annotate (GNATprove, Intentional, "type ""Vector"" is not fully 
initialized",
-                    "Only items in Elements with index < Last are accessed");
-
-   ----------
-   --  For child units
-
-   function To_Peek_Index (Index : in Extended_Index) return Base_Peek_Type is
-     (Base_Peek_Type (Index - Index_Type'First + 1));
-
-end SAL.Gen_Bounded_Definite_Vectors;
diff --git 
a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb
deleted file mode 100644
index cee9c74..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux (Item : in 
Vector; Aux : in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := Item.Last;
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux;
diff --git 
a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads
deleted file mode 100644
index 28c56fd..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux (Item : in 
Vector; Aux : in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb
deleted file mode 100644
index fb5d619..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb
+++ /dev/null
@@ -1,29 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs is
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Elements (Index)'Access,
-         Dummy   => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads
deleted file mode 100644
index 17e98c4..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads
+++ /dev/null
@@ -1,39 +0,0 @@
---  Abstract :
---
---  Constant_Reference for parent.
---
---  In a child package because it's not Spark, and Spark does not
---  allow 'Spark_Mode => Off' on type declarations.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-package SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs is
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type with
-     Inline;
-
-private
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb
deleted file mode 100644
index 8b89a7f..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb
+++ /dev/null
@@ -1,96 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors_Sorted is
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-     is (Ada.Containers.Count_Type (Container.Last));
-
-   function Is_Full (Container : in Vector) return Boolean
-   is begin
-      return Container.Last = Peek_Type (Capacity);
-   end Is_Full;
-
-   procedure Clear (Container : in out Vector)
-   is begin
-      Container.Last := No_Index;
-   end Clear;
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-     is (Container.Last);
-
-   function Element (Container : in Vector; Index : in Peek_Type) return 
Element_Type
-     is (Container.Elements (Index));
-
-   procedure Insert
-     (Container       : in out Vector;
-      New_Item        : in     Element_Type;
-      Ignore_If_Equal : in     Boolean := False)
-   is
-      K : constant Base_Peek_Type := Container.Last;
-      J : Base_Peek_Type := K;
-   begin
-      if K = 0 then
-         --  Container empty
-         Container.Last := 1;
-         Container.Elements (1) := New_Item;
-         return;
-      end if;
-
-      loop
-         --  These seem obvious, but gnatprove needs them (in 2019).
-         pragma Loop_Invariant (J <= Container.Last);
-         pragma Loop_Invariant (J <= Container.Elements'Last);
-         pragma Loop_Variant (Decreases => J);
-
-         --  This is less obvious, helps a lot.
-         pragma Loop_Invariant
-           ((for all I in J + 1 .. Container.Last => Element_Compare
-             (New_Item, Container.Elements (I)) = Less));
-
-         exit when J < 1;
-
-         case Element_Compare (New_Item, Container.Elements (J)) is
-         when Less =>
-            J := J - 1;
-         when Equal =>
-            if Ignore_If_Equal then
-               return;
-            else
-               --  Insert after J
-               exit;
-            end if;
-         when Greater =>
-            --  Insert after J
-            exit;
-         end case;
-      end loop;
-
-      --  Note that this assertion is _not_ a Loop_Invariant; the whole
-      --  point here is to find the right J.
-      pragma Assert
-        (for all I in 1 .. J - 1 =>
-           Element_Compare (Container.Elements (I), New_Item) in Less | Equal);
-
-      Container.Elements (J + 2 .. K + 1) := Container.Elements (J + 1 .. K);
-      Container.Elements (J + 1) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Insert;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads
deleted file mode 100644
index e86fbca..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads
+++ /dev/null
@@ -1,100 +0,0 @@
---  Abstract :
---
---  A simple bounded sorted vector of definite items, in Spark.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is private;
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-   Capacity : in Ada.Containers.Count_Type;
-package SAL.Gen_Bounded_Definite_Vectors_Sorted
-  with Spark_Mode
-is
-   use all type Ada.Containers.Count_Type;
-
-   No_Index : constant Base_Peek_Type := 0;
-
-   type Vector is private with
-     Default_Initial_Condition => Last_Index (Vector) = No_Index;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type 
with
-     Post => Length'Result in 0 .. Capacity;
-
-   function Is_Full (Container : in Vector) return Boolean with
-     Post => Is_Full'Result = (Length (Container) = Capacity);
-
-   procedure Clear (Container : in out Vector) with
-     Post => Last_Index (Container) = No_Index;
-
-   function First_Index (Container : in Vector) return Peek_Type
-     is (Peek_Type'First) with
-       Depends => (First_Index'Result => null, null => Container);
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type with
-     Inline;
-
-   function Element (Container : in Vector; Index : in Peek_Type) return 
Element_Type with
-     Pre => Index in First_Index (Container) .. Last_Index (Container);
-
-   function Is_Sorted (Container : in Vector) return Boolean is
-     --  See comment on similar Is_Sorted below
-     (for all I in First_Index (Container) .. Last_Index (Container) - 1 =>
-        (for all J in I + 1 .. Last_Index (Container) =>
-           Element_Compare (Element (Container, I), Element (Container, J)) in 
Less | Equal));
-
-   procedure Insert
-     (Container       : in out Vector;
-      New_Item        : in     Element_Type;
-      Ignore_If_Equal : in     Boolean := False) with
-     Pre  => Last_Index (Container) < Peek_Type (Capacity),
-     Post => Is_Sorted (Container) and
-             (if Ignore_If_Equal then
-                (Last_Index (Container) = Last_Index (Container'Old) or
-                 Last_Index (Container) = Last_Index (Container'Old) + 1)
-              else
-                Last_Index (Container) = Last_Index (Container'Old) + 1);
-   --  Insert New_Item in sorted position. Items are sorted in increasing
-   --  order according to Element_Compare. New_Item is inserted after
-   --  Equal items, unless Ignore_If_Equal is true, in which case
-   --  New_Item is not inserted.
-
-private
-
-   type Array_Type is array (Peek_Type range 1 .. Peek_Type (Capacity)) of 
aliased Element_Type;
-
-   function Is_Sorted (Container : in Array_Type; Last : in Base_Peek_Type) 
return Boolean
-     --  This is too hard for gnatprove (in 2019):
-     --  is (for all I in Container'First .. Last - 1 =>
-     --        Element_Compare (Container (I), Container (I + 1)) in Less | 
Equal)
-     --  This works:
-     is (for all I in Container'First .. Last - 1 =>
-           (for all J in I + 1 .. Last =>
-              Element_Compare (Container (I), Container (J)) in Less | Equal))
-     with Pre => Last <= Container'Last;
-
-   subtype Index_Type is Base_Peek_Type range No_Index .. Base_Peek_Type 
(Capacity);
-   --  Helps with proofs
-
-   type Vector is record
-      Elements : Array_Type;
-      Last     : Index_Type := No_Index;
-   end record with
-     Type_Invariant => Last <= Elements'Last and Is_Sorted (Vector.Elements, 
Vector.Last);
-   pragma Annotate (GNATprove, Intentional, "type ""Vector"" is not fully 
initialized",
-                    "Only items in Elements with index <= Last are accessed");
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists.adb
deleted file mode 100644
index d86441a..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists.adb
+++ /dev/null
@@ -1,317 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Definite_Doubly_Linked_Lists is
-
-   procedure Delete_Node (Container : in out List; Node : in out Node_Access)
-   is begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node);
-   end Delete_Node;
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Next_Source : Node_Access := Container.Head;
-      New_Node    : Node_Access;
-   begin
-      if Next_Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => Next_Source.Element,
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Next_Source := Next_Source.Next;
-         exit when Next_Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   function Length (Container : in List) return Ada.Containers.Count_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   procedure Append (Container : in out List; Element : in Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Tail.Next := New_Node;
-         Container.Tail      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Append;
-
-   procedure Prepend (Container : in out List; Element : in Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => null,
-         Next    => Container.Head);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Head.Prev := New_Node;
-         Container.Head      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Prepend;
-
-   function To_List (Element : in Element_Type) return List
-   is begin
-      return Result : List do
-         Result.Append (Element);
-      end return;
-   end To_List;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Head);
-      end if;
-   end First;
-
-   function Last (Container : in List) return Cursor
-   is begin
-      if Container.Tail = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Tail);
-      end if;
-   end Last;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Previous (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Prev = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Prev);
-         end if;
-      end if;
-   end Previous;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      Delete_Node (Container, Position.Ptr);
-      Position        := (Ptr => null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   procedure Delete_First (Container : in out List)
-   is
-      use all type Ada.Containers.Count_Type;
-      Node : Node_Access := Container.Head;
-   begin
-      Delete_Node (Container, Node);
-      Container.Count := Container.Count - 1;
-   end Delete_First;
-
-   procedure Insert
-     (Container : in out List;
-      Before    : in     Cursor;
-      Element   : in     Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Before = (Ptr => null) then
-         Container.Append (Element);
-      else
-         if Before.Ptr = Container.Head then
-            declare
-               --  old list: before ...
-               --  newlist:  new  before ...
-               New_Node : constant Node_Access := new Node_Type'
-                 (Element => Element,
-                  Prev    => null,
-                  Next    => Before.Ptr);
-            begin
-               Before.Ptr.Prev := New_Node;
-               Container.Head  := New_Node;
-            end;
-         else
-            declare
-               --  old list: ... prev  before ...
-               --  newlist:  ... prev  new  before ...
-               New_Node : constant Node_Access := new Node_Type'
-                 (Element => Element,
-                  Prev    => Before.Ptr.Prev,
-                  Next    => Before.Ptr);
-            begin
-               Before.Ptr.Prev.Next := New_Node;
-               Before.Ptr.Prev      := New_Node;
-
-            end;
-         end if;
-         Container.Count := Container.Count + 1;
-      end if;
-   end Insert;
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   is begin
-      return Position.Ptr.Element'Access;
-   end Persistent_Ref;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Ref;
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return First (Object.Container.all);
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      return Last (Object.Container.all);
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Next (Position);
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Previous (Position);
-   end Previous;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists.ads
deleted file mode 100644
index 8470daf..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists.ads
+++ /dev/null
@@ -1,172 +0,0 @@
---  Abstract :
---
---  A generic doubly linked list with definite elements, allowing
---  permanent references to elements.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-package SAL.Gen_Definite_Doubly_Linked_Lists is
-
-   type List is new Ada.Finalization.Controlled with private
-   with
-      Constant_Indexing => Constant_Reference,
-      Variable_Indexing => Variable_Reference,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   type List_Access_Constant is access constant List;
-   for List_Access_Constant'Storage_Size use 0;
-
-   type List_Access is access all List;
-   for List_Access'Storage_Size use 0;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   procedure Clear (Container : in out List) renames Finalize;
-
-   function Length (Container : in List) return Ada.Containers.Count_Type;
-
-   procedure Append (Container : in out List; Element : in Element_Type);
-
-   procedure Prepend (Container : in out List; Element : in Element_Type);
-
-   function To_List (Element : in Element_Type) return List;
-
-   type Cursor is private;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   No_Element : constant Cursor;
-   function First (Container : in List) return Cursor;
-   function Last (Container : in List) return Cursor;
-
-   procedure Next (Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Next (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-   function Previous (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   procedure Delete_First (Container : in out List);
-
-   procedure Insert
-     (Container : in out List;
-      Before    : in     Cursor;
-      Element   : in     Element_Type);
-   --  If Before is No_Element, insert after Last.
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   with Pre => Has_Element (Position);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-   --  Not 'Constant_Ref' because that is taken, and it is wrong for 
Constant_Indexing
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-private
-   type Node_Type;
-
-   type Node_Access is access Node_Type;
-
-   type Node_Type is record
-      Element : aliased Element_Type;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access               := null;
-      Tail  : Node_Access               := null;
-      Count : Ada.Containers.Count_Type := 0;
-   end record;
-
-   type Cursor is record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   No_Element : constant Cursor := (Ptr => null);
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   type Iterator (Container : not null access constant List) is new 
Iterator_Interfaces.Reversible_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists;
diff --git 
a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb
deleted file mode 100644
index 6e6efb3..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb
+++ /dev/null
@@ -1,47 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image
-  (Item : in List; Strict : in Boolean := False) return String
-is
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result     : Unbounded_String := To_Unbounded_String ("(");
-   Need_Comma : Boolean          := False;
-begin
-   if Strict and Item.Length = 0 then
-      return "(1 .. 0 => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(1 => " & Element_Image (Element (Item.First)) & ")";
-
-   else
-      for El of Item loop
-         if Need_Comma then
-            Result := Result & ", ";
-         else
-            Need_Comma := True;
-         end if;
-         Result := Result & Element_Image (El);
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image;
diff --git 
a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads
deleted file mode 100644
index 4080707..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads
+++ /dev/null
@@ -1,25 +0,0 @@
---  Abstract :
---
---  Image of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image
-  (Item : in List; Strict : in Boolean := False) return String;
---  Image of Item, in Ada aggregate syntax. If Strict, use correct
---  syntax for 0 and 1 item; otherwise, use () and (item).
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb
deleted file mode 100644
index 702914d..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb
+++ /dev/null
@@ -1,542 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Definite_Doubly_Linked_Lists_Sorted is
-
-   ----------
-   --  Body subprograms, alphabetical
-
-   procedure Find
-     (Container     : in     List;
-      Element       : in     Element_Type;
-      Found         :    out Node_Access;
-      Found_Compare :    out Compare_Result)
-   is
-      --  Return pointer to first item in Container for which Compare (item,
-      --  element) returns True or Greater. If no such element exists, Found
-      --  is null, Found_Compare is Less.
-      use Ada.Containers;
-   begin
-      if Container.Head = null then
-         Found         := null;
-         Found_Compare := Less;
-         return;
-      end if;
-
-      declare
-         Low_Index  : Count_Type  := 1;
-         High_Index : Count_Type  := Container.Count;
-         Next_Node  : Node_Access := Container.Head;
-         Next_Index : Count_Type  := Low_Index;
-         Old_Index  : Count_Type;
-      begin
-         loop
-            Old_Index  := Next_Index;
-            Next_Index := (Low_Index + High_Index) / 2;
-
-            if Next_Index > Old_Index then
-               for I in Old_Index + 1 .. Next_Index loop
-                  Next_Node := Next_Node.Next;
-               end loop;
-            elsif Next_Index < Old_Index then
-               for I in Next_Index .. Old_Index - 1 loop
-                  Next_Node := Next_Node.Prev;
-               end loop;
-            end if;
-
-            case Element_Compare (Next_Node.Element, Element) is
-            when Less =>
-               if Next_Index = High_Index then
-                  --  no more nodes to check
-                  Found         := null;
-                  Found_Compare := Less;
-                  return;
-               elsif Next_Index = Low_Index then
-                  --  force check of high_index
-                  Low_Index := High_Index;
-               else
-                  Low_Index := Next_Index;
-               end if;
-
-            when Equal =>
-               Found         := Next_Node;
-               Found_Compare := Equal;
-               return;
-
-            when Greater =>
-               if Low_Index = Next_Index then
-                  --  no more nodes to check
-                  Found         := Next_Node;
-                  Found_Compare := Greater;
-                  return;
-               elsif High_Index = Next_Index then
-                  --  Desired result is either high_index or low_index
-                  pragma Assert (Low_Index + 1 = High_Index);
-                  case Element_Compare (Next_Node.Prev.Element, Element) is
-                  when Less =>
-                     Found         := Next_Node;
-                     Found_Compare := Greater;
-                     return;
-                  when Equal =>
-                     Found         := Next_Node.Prev;
-                     Found_Compare := Equal;
-                     return;
-                  when Greater =>
-                     Found         := Next_Node.Prev;
-                     Found_Compare := Greater;
-                     return;
-                  end case;
-               else
-                  High_Index := Next_Index;
-               end if;
-            end case;
-         end loop;
-      end;
-   end Find;
-
-   procedure Insert_Before
-     (Container : in out List;
-      Before    : in     Node_Access;
-      Element   : in     Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Before.Prev,
-         Next    => Before);
-   begin
-      if Before = Container.Head then
-         Before.Prev    := New_Node;
-         Container.Head := New_Node;
-      else
-         Before.Prev.Next := New_Node;
-         Before.Prev      := New_Node;
-      end if;
-   end Insert_Before;
-
-   procedure Insert_After_Tail
-     (Container : in out List;
-      Element   : in     Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      Container.Tail.Next := New_Node;
-      Container.Tail      := New_Node;
-   end Insert_After_Tail;
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Next_Source : Node_Access := Container.Head;
-      New_Node    : Node_Access;
-   begin
-      if Next_Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => Next_Source.Element,
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Next_Source := Next_Source.Next;
-         exit when Next_Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   overriding function "=" (Left, Right : in List) return Boolean
-   is
-      Left_I  : Node_Access := Left.Head;
-      Right_I : Node_Access := Right.Head;
-   begin
-      loop
-         exit when Left_I = null;
-
-         if Right_I = null then
-            return False;
-         elsif Left_I.Element /= Right_I.Element then
-            return False;
-         end if;
-
-         Left_I  := Left_I.Next;
-         Right_I := Right_I.Next;
-      end loop;
-      return Right_I = null;
-   end "=";
-
-   function Length (Container : in List) return Ada.Containers.Count_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   function To_List (Element : in Element_Type) return List
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => null,
-         Next    => null);
-   begin
-      return Result : constant List :=
-        (Ada.Finalization.Controlled with
-         Head  => New_Node,
-         Tail  => New_Node,
-         Count => 1);
-   end To_List;
-
-   procedure Insert (Container : in out List; Element : in Element_Type)
-   is
-      Node    : Node_Access := Container.Head;
-      Compare : Compare_Result;
-   begin
-      if Node = null then
-         Container := To_List (Element);
-      else
-         Find (Container, Element, Node, Compare);
-
-         Container.Count := Container.Count + 1;
-
-         if Node = null then
-            Insert_After_Tail (Container, Element);
-         else
-            Insert_Before (Container, Node, Element);
-         end if;
-      end if;
-   end Insert;
-
-   function Contains (Container : in List; Element : in Element_Type) return 
Boolean
-   is
-      Node    : Node_Access := Container.Head;
-      Compare : Compare_Result;
-   begin
-      Find (Container, Element, Node, Compare);
-      return Compare = Equal;
-   end Contains;
-
-   procedure Merge
-     (Target : in out List;
-      Source : in     List;
-      Added  :    out Boolean)
-   is
-      Target_I : Node_Access := Target.Head;
-      Source_I : Node_Access := Source.Head;
-   begin
-      if Target_I = null then
-         if Source_I = null then
-            Added := False;
-         else
-            Target.Head  := Source.Head;
-            Target.Tail  := Source.Tail;
-            Target.Count := Source.Count;
-            Adjust (Target);
-
-            Added := True;
-         end if;
-
-      elsif Source_I = null then
-         Added := False;
-
-      else
-         Added := False;
-         loop
-            exit when Source_I = null;
-
-            if Target_I = null then
-               Added := True;
-               Target.Count := Target.Count + 1;
-               Insert_After_Tail (Target, Source_I.Element);
-               Source_I := Source_I.Next;
-
-            else
-               case Element_Compare (Target_I.Element, Source_I.Element) is
-               when Greater =>
-                  Added := True;
-                  Target.Count := Target.Count + 1;
-                  Insert_Before (Target, Target_I, Source_I.Element);
-                  Source_I := Source_I.Next;
-
-               when Equal =>
-                  Target_I := Target_I.Next;
-                  Source_I := Source_I.Next;
-
-               when Less =>
-                  Target_I := Target_I.Next;
-               end case;
-            end if;
-         end loop;
-      end if;
-   end Merge;
-
-   procedure Merge
-     (Target  : in out List;
-      Source  : in     List;
-      Added   :    out Boolean;
-      Exclude : in     Element_Type)
-   is
-      Target_I : Node_Access := Target.Head;
-      Source_I : Node_Access := Source.Head;
-   begin
-      Added := False;
-
-      if Target_I = null then
-         if Source_I = null then
-            return;
-         else
-            loop
-               if Source_I = null then
-                  return;
-               end if;
-               exit when Source_I.Element /= Exclude;
-               Source_I := Source_I.Next;
-            end loop;
-
-            Added    := True;
-            Target   := To_List (Source_I.Element);
-            Source_I := Source_I.Next;
-         end if;
-      end if;
-
-      loop
-         exit when Source_I = null;
-
-         if Source_I.Element = Exclude then
-            Source_I := Source_I.Next;
-
-         elsif Target_I = null then
-            Added := True;
-            Target.Count := Target.Count + 1;
-            Insert_After_Tail (Target, Source_I.Element);
-            Source_I := Source_I.Next;
-
-         else
-            case Element_Compare (Target_I.Element, Source_I.Element) is
-            when Greater =>
-               Added := True;
-               Target.Count := Target.Count + 1;
-               Insert_Before (Target, Target_I, Source_I.Element);
-               Source_I := Source_I.Next;
-
-            when Equal =>
-               Target_I := Target_I.Next;
-               Source_I := Source_I.Next;
-
-            when Less =>
-               Target_I := Target_I.Next;
-            end case;
-         end if;
-      end loop;
-   end Merge;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : aliased in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Container'Access, null);
-      else
-         return (Container'Access, Container.Head);
-      end if;
-   end First;
-
-   function Last (Container : aliased in List) return Cursor
-   is begin
-      if Container.Tail = null then
-         return (Container'Access, null);
-      else
-         return (Container'Access, Container.Tail);
-      end if;
-   end Last;
-
-   function Find (Container : aliased in List; Element : in Element_Type) 
return Cursor
-   is
-      Node    : Node_Access;
-      Compare : Compare_Result;
-   begin
-      Find (Container, Element, Node, Compare);
-
-      if Node = null then
-         return (Container'Access, null);
-      elsif Compare = Equal then
-         return (Container'Access, Node);
-      else
-         return (Container'Access, null);
-      end if;
-   end Find;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Position.Container, null);
-         else
-            return (Position.Container, Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Previous (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Prev = null then
-            return (Position.Container, null);
-         else
-            return (Position.Container, Position.Ptr.Prev);
-         end if;
-      end if;
-   end Previous;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      Node : Node_Access renames Position.Ptr;
-   begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node);
-      Position        := (Container'Access, null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   function Pop (Container : in out List) return Element_Type
-   is
-      Node : Node_Access := Container.Head;
-   begin
-      return Result : constant Element_Type := Container.Head.Element do
-         Container.Head := Node.Next;
-         if Node.Next = null then
-            Container.Tail := null;
-         else
-            Node.Next.Prev := null;
-         end if;
-         Free (Node);
-         Container.Count := Container.Count - 1;
-      end return;
-   end Pop;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Ref;
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return First (Object.Container.all);
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      return Last (Object.Container.all);
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Next (Position);
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Previous (Position);
-   end Previous;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads
deleted file mode 100644
index 91ffeda..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads
+++ /dev/null
@@ -1,190 +0,0 @@
---  Abstract :
---
---  A generic sorted doubly linked list with definite elements.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-package SAL.Gen_Definite_Doubly_Linked_Lists_Sorted is
-   use all type Ada.Containers.Count_Type;
-
-   type List is new Ada.Finalization.Controlled with private
-   with
-      Constant_Indexing => Constant_Reference,
-      Variable_Indexing => Variable_Reference,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   --  If user uses Variable_Indexing, they must not change the sort
-   --  order of the elements.
-
-   type List_Access is access all List;
-   for List_Access'Storage_Size use 0;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   procedure Clear (Container : in out List) renames Finalize;
-
-   overriding function "=" (Left, Right : in List) return Boolean;
-   --  True if contents are the same.
-
-   function Length (Container : in List) return Ada.Containers.Count_Type;
-
-   function To_List (Element : in Element_Type) return List;
-
-   procedure Insert (Container : in out List; Element : in Element_Type);
-   --  Insert Element before first item for which Element_Order (item,
-   --  element) returns True.
-
-   function Contains (Container : in List; Element : in Element_Type) return 
Boolean;
-
-   procedure Merge
-     (Target : in out List;
-      Source : in     List;
-      Added  :    out Boolean);
-   --  Add all elements of Source to Target, if they are not already
-   --  present.
-   --
-   --  Added is True if any element was not already present.
-
-   procedure Merge
-     (Target  : in out List;
-      Source  : in     List;
-      Added   :    out Boolean;
-      Exclude : in     Element_Type);
-   --  Add all elements of Source to Target, if they are not already
-   --  present, and are not equal to Exclude.
-   --
-   --  Added is True if any element was not already present.
-
-   type Cursor (<>) is private;
-
-   function No_Element (Container : aliased in List) return Cursor;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   function First (Container : aliased in List) return Cursor;
-   function Last (Container : aliased in List) return Cursor;
-
-   function Find (Container : aliased in List; Element : in Element_Type) 
return Cursor;
-   --  No_Element if Element not found.
-
-   procedure Next (Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Next (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-   function Previous (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Pop (Container : in out List) return Element_Type
-   with Pre => Container.Length > 0;
-   --  Return Container.First, delete it from Container.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type 
with
-     Inline, Pre => Has_Element (Position);
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-   --  User must not change the element in a way that affects the sort order.
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-private
-   type Node_Type;
-
-   type Node_Access is access Node_Type;
-
-   type Node_Type is record
-      Element : aliased Element_Type;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access               := null;
-      Tail  : Node_Access               := null;
-      Count : Ada.Containers.Count_Type := 0;
-   end record;
-
-   type Cursor (Container : not null access constant List) is
-   record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   function No_Element (Container : aliased in List) return Cursor
-     is (Container'Access, null);
-
-   type Iterator (Container : not null access constant List) is new 
Iterator_Interfaces.Reversible_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
diff --git a/packages/wisi/sal-gen_graphs.adb b/packages/wisi/sal-gen_graphs.adb
deleted file mode 100644
index ef0fcc3..0000000
--- a/packages/wisi/sal-gen_graphs.adb
+++ /dev/null
@@ -1,719 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017, 2019 Free Software Foundation All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with SAL.Gen_Bounded_Definite_Queues;
-with SAL.Gen_Unbounded_Definite_Stacks;
-package body SAL.Gen_Graphs is
-
-   package Vertex_Queues is new SAL.Gen_Bounded_Definite_Queues (Vertex_Index);
-   package Vertex_Stacks is new SAL.Gen_Unbounded_Definite_Stacks 
(Vertex_Index);
-
-   function Find (Data : in Edge_Data; List : in Edge_Node_Lists.List) return 
Edge_Node_Lists.Cursor
-   is begin
-      for I in List.Iterate loop
-         if Edge_Node_Lists.Element (I).Data = Data then
-            return I;
-         end if;
-      end loop;
-      return Edge_Node_Lists.No_Element;
-   end Find;
-
-   ----------
-   --  Visible subprograms
-
-   procedure Add_Edge
-     (Graph    : in out Gen_Graphs.Graph;
-      Vertex_A : in     Vertex_Index;
-      Vertex_B : in     Vertex_Index;
-      Data     : in     Edge_Data)
-   is
-      Multigraph : Boolean := False;
-
-      procedure Update_First_Last (Vertex : in Vertex_Index)
-      is
-         use all type Ada.Containers.Count_Type;
-      begin
-         if Graph.Vertices.Length = 0 then
-            Graph.Vertices.Set_First_Last (Vertex, Vertex);
-         else
-            if Vertex < Graph.Vertices.First_Index then
-               Graph.Vertices.Set_First_Last (Vertex, 
Graph.Vertices.Last_Index);
-            elsif Vertex > Graph.Vertices.Last_Index then
-               Graph.Vertices.Set_First_Last (Graph.Vertices.First_Index, 
Vertex);
-            end if;
-         end if;
-      end Update_First_Last;
-
-   begin
-      Update_First_Last (Vertex_A);
-      Update_First_Last (Vertex_B);
-
-      Graph.Last_Edge_ID := Graph.Last_Edge_ID + 1;
-      if (for some E of Graph.Vertices (Vertex_A) => E.Vertex_B = Vertex_B) 
then
-         Multigraph       := True;
-         Graph.Multigraph := True;
-      end if;
-
-      Graph.Vertices (Vertex_A).Append ((Graph.Last_Edge_ID, Vertex_B, 
Multigraph, Data));
-   end Add_Edge;
-
-   function Count_Nodes (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type
-   is begin
-      return Graph.Vertices.Length;
-   end Count_Nodes;
-
-   function Count_Edges (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type
-   is
-      use Ada.Containers;
-      Result : Count_Type := 0;
-   begin
-      for Edges of Graph.Vertices loop
-         Result := Result + Edges.Length;
-      end loop;
-      return Result;
-   end Count_Edges;
-
-   function Multigraph (Graph : in Gen_Graphs.Graph) return Boolean
-   is begin
-      return Graph.Multigraph;
-   end Multigraph;
-
-   function "+" (Right : in Edge_Item) return Edge_Lists.List
-   is
-      use Edge_Lists;
-   begin
-      return Result : List do
-         Append (Result, Right);
-      end return;
-   end "+";
-
-   function Edges (Graph : in Gen_Graphs.Graph; Vertex : in Vertex_Index) 
return Edge_Lists.List
-   is begin
-      return Result : Edge_Lists.List do
-         for E of Graph.Vertices (Vertex) loop
-            Result.Append ((E.ID, E.Data));
-         end loop;
-      end return;
-   end Edges;
-
-   function Image (Item : in Path) return String
-   is
-      use Ada.Strings.Unbounded;
-
-      Result : Unbounded_String := To_Unbounded_String ("(");
-   begin
-      for I in Item'Range loop
-         Result := Result & Trimmed_Image (Item (I).Vertex) & " " &
-           Image ((if I = Item'Last then Item (Item'First).Edges else Item (I 
+ 1).Edges)) & " -> ";
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end Image;
-
-   function "<" (Left, Right : in Path) return Boolean
-   is begin
-      for I in Left'Range loop
-         if I > Right'Last then
-            return False;
-         elsif Left (I).Vertex < Right (I).Vertex then
-            return True;
-         elsif Left (I).Vertex > Right (I).Vertex then
-            return False;
-         else
-            --  =; check remaining elements
-            null;
-         end if;
-      end loop;
-
-      if Left'Last < Right'Last then
-         return True;
-      else
-         --  All =
-         return False;
-      end if;
-   end "<";
-
-   function Find_Paths
-     (Graph : in out Gen_Graphs.Graph;
-      From  : in     Vertex_Index;
-      To    : in     Edge_Data)
-     return Path_Arrays.Vector
-   is
-      use Vertex_Queues;
-
-      Vertex_Queue  : Queue_Type
-        (Size => Peek_Type (Graph.Vertices.Last_Index - 
Graph.Vertices.First_Index + 1));
-
-      type Colors is (White, Gray, Black);
-
-      type Aux_Node is record
-         Color       : Colors            := Colors'First;
-         D           : Natural           := Natural'Last;
-         Parent      : Vertex_Index'Base := Invalid_Vertex;
-         Parent_Set  : Boolean           := False;
-         Parent_Edge : Edge_Node_Lists.Cursor := Edge_Node_Lists.No_Element;
-      end record;
-
-      package Aux_Arrays is new SAL.Gen_Unbounded_Definite_Vectors 
(Vertex_Index, Aux_Node, (others => <>));
-      Aux : Aux_Arrays.Vector;
-
-      function Build_Path
-        (Tail_Vertex : in Vertex_Index;
-         Tail_Edge   : in Edge_Node_Lists.Cursor)
-        return Path
-      is
-      begin
-         return Result : Path (1 .. Aux (Tail_Vertex).D + 1)
-         do
-            declare
-               use Edge_Node_Lists;
-               V_Index   : Vertex_Index := Tail_Vertex;
-               Last_Edge : Cursor       := Tail_Edge;
-            begin
-               for I in reverse 1 .. Result'Length loop
-                  declare
-                     V : Aux_Node renames Aux (V_Index);
-                  begin
-                     if Last_Edge = No_Element then
-                        Result (I) := (V_Index, Edge_Lists.Empty_List);
-                     else
-                        Result (I) := (V_Index, +(Element (Last_Edge).ID, 
Element (Last_Edge).Data));
-                     end if;
-
-                     if V.Parent_Set then
-                        Last_Edge := V.Parent_Edge;
-                        V_Index   := V.Parent;
-                     end if;
-                  end;
-               end loop;
-            end;
-         end return;
-      end Build_Path;
-
-      Result_List : Path_Arrays.Vector;
-      Result_Edge : Edge_Node_Lists.Cursor;
-   begin
-      --  [1] figure 22.3 breadth-first search; 'From' = s.
-
-      Aux.Set_First_Last (Graph.Vertices.First_Index, 
Graph.Vertices.Last_Index);
-
-      for I in Aux.First_Index .. Aux.Last_Index loop
-         if I = From then
-            Aux (I).Color      := Gray;
-            Aux (I).D          := 0;
-            Aux (I).Parent_Set := False;
-
-         else
-            Aux (I).Color      := White;
-            Aux (I).D          := Natural'Last;
-            Aux (I).Parent_Set := False;
-         end if;
-      end loop;
-
-      Put (Vertex_Queue, From);
-
-      while not Is_Empty (Vertex_Queue) loop
-         declare
-            U_Index : constant Vertex_Index := Get (Vertex_Queue);
-            U       : Aux_Node renames Aux (U_Index);
-         begin
-            Edges :
-            for C in Graph.Vertices (U_Index).Iterate loop
-               declare
-                  use all type Edge_Node_Lists.Cursor;
-                  V_Index : constant Vertex_Index := Edge_Node_Lists.Element 
(C).Vertex_B;
-                  V       : Aux_Node renames Aux (V_Index);
-               begin
-                  if V.Color = White then
-                     V.Color       := Gray;
-                     V.D           := U.D + 1;
-                     V.Parent      := U_Index;
-                     V.Parent_Edge := C;
-                     V.Parent_Set  := True;
-
-                     Result_Edge := Find (To, Graph.Vertices (V_Index));
-                     if Result_Edge /= Edge_Node_Lists.No_Element then
-                        Result_List.Append (Build_Path (V_Index, Result_Edge));
-                     end if;
-
-                     Put (Vertex_Queue, V_Index);
-                  end if;
-               end;
-            end loop Edges;
-            U.Color := Black;
-         end;
-      end loop;
-      return Result_List;
-   end Find_Paths;
-
-   function Find_Cycles_Tiernan (Graph : in Gen_Graphs.Graph)
-     return Path_Arrays.Vector
-   is
-      --  Implements [2] "Algorithm EC"
-      --
-      --  vertex 0 = Invalid_Vertex
-      --  vertex 1 = Graph.Vertices.First_Index
-      --  vertex N = Graph.Vertices.Last_Index
-
-      First : Vertex_Index renames Graph.Vertices.First_Index;
-      Last  : Vertex_Index renames Graph.Vertices.Last_Index;
-
-      G : Vertex_Arrays.Vector renames Graph.Vertices;
-      P : Path (1 .. Integer (Last - First + 1));
-      K : Positive := 1; -- ie P_Last
-
-      type H_Row is array (G.First_Index .. G.Last_Index) of Vertex_Index'Base;
-      H : array (G.First_Index .. G.Last_Index) of H_Row := (others => (others 
=> Invalid_Vertex));
-
-      Next_Vertex_Found : Boolean;
-
-      Result : Path_Arrays.Vector;
-
-      function Contains (P : in Path; V : in Vertex_Index) return Boolean
-      is (for some N of P => N.Vertex = V);
-
-      function Contains (Row : in H_Row; V : in Vertex_Index) return Boolean
-      is (for some N of Row => N = V);
-
-      function Contains (Edges : in Edge_Lists.List; ID : in Edge_ID) return 
Boolean
-        is (for some E of Edges => E.ID = ID);
-
-      procedure Add_Alternate_Edges (P : in out Path)
-      is
-         function Dec (I : in Positive) return Positive
-           is (if I = P'First then P'Last else I - 1);
-      begin
-         for I in P'Range loop
-            for New_Edge of G (P (Dec (I)).Vertex) loop
-               if New_Edge.Vertex_B = P (I).Vertex and (not Contains (P 
(I).Edges, New_Edge.ID)) then
-                  P (I).Edges.Append ((New_Edge.ID, New_Edge.Data));
-               end if;
-            end loop;
-         end loop;
-      end Add_Alternate_Edges;
-
-   begin
-      P (1) := (First, Edge_Lists.Empty_List);
-
-      All_Initial_Vertices :
-      loop
-         Explore_Vertex :
-         loop
-            Path_Extension :
-            loop  -- EC2 Path Extension
-               Next_Vertex_Found := False;
-
-               Find_Next_Vertex :
-               for Edge of G (P (K).Vertex) loop
-                  declare
-                     Next_Vertex : constant Vertex_Index := Edge.Vertex_B; -- 
ie G[P[k],j]
-                  begin
-                     if Next_Vertex > P (1).Vertex and -- (1)
-                       (not Contains (P, Next_Vertex)) and -- (2)
-                       (not Contains (H (P (K).Vertex), Next_Vertex))
-                     then
-                        K     := K + 1;
-                        P (K) := (Next_Vertex, +(Edge.ID, Edge.Data));
-
-                        Next_Vertex_Found := True;
-                        exit Find_Next_Vertex;
-                     end if;
-                  end;
-               end loop Find_Next_Vertex;
-
-               exit Path_Extension when not Next_Vertex_Found;
-            end loop Path_Extension;
-
-            --  EC3 Circuit Confirmation
-            for Edge of G (P (K).Vertex) loop
-               if Edge.Vertex_B = P (1).Vertex then
-                  P (1).Edges := +(Edge.ID, Edge.Data);
-                  if Graph.Multigraph then
-                     Add_Alternate_Edges (P (1 .. K));
-                  end if;
-                  Result.Append (P (1 .. K));
-                  exit;
-               end if;
-            end loop;
-
-            --  EC4 Vertex Closure
-            exit Explore_Vertex when K = 1;
-
-            H (P (K).Vertex) := (others => Invalid_Vertex);
-            for M in H (P (K - 1).Vertex)'Range loop
-               if H (P (K - 1).Vertex)(M) = Invalid_Vertex then
-                  H (P (K - 1).Vertex)(M) := P (K).Vertex;
-                  P (K) := (Invalid_Vertex, Edge_Lists.Empty_List);
-                  exit;
-               end if;
-            end loop;
-            K := K - 1;
-         end loop Explore_Vertex;
-
-         --  EC5 Advance Initial Index
-         exit All_Initial_Vertices when P (1).Vertex = 
Graph.Vertices.Last_Index;
-
-         P (1) := (P (1).Vertex + 1, Edge_Lists.Empty_List);
-         pragma Assert (K = 1);
-         H := (others => (others => Invalid_Vertex));
-      end loop All_Initial_Vertices;
-
-      --  EC6 Terminate
-      return Result;
-   end Find_Cycles_Tiernan;
-
-   function Find_Cycles (Graph : in Gen_Graphs.Graph) return Path_Arrays.Vector
-   is
-      --  Implements Circuit-Finding Algorithm from [3]
-
-      use all type Ada.Containers.Count_Type;
-
-      pragma Warnings (Off, """Edited_Graph"" is not modified, could be 
declared constant");
-      Edited_Graph : Gen_Graphs.Graph := Graph;
-
-      Result : Path_Arrays.Vector;
-
-      A_K     : Adjacency_Structures.Vector;
-      B       : Adjacency_Structures.Vector;
-      Blocked : array (Graph.Vertices.First_Index .. 
Graph.Vertices.Last_Index) of Boolean := (others => False);
-
-      Stack : Vertex_Stacks.Stack;
-      S     : Vertex_Index := Graph.Vertices.First_Index;
-
-      Dummy : Boolean;
-      pragma Unreferenced (Dummy);
-
-      function Circuit (V : in Vertex_Index) return Boolean
-      is
-         F : Boolean := False;
-
-         procedure Unblock (U : in Vertex_Index)
-         is begin
-            Blocked (U) := False;
-            declare
-               use Vertex_Lists;
-               Cur  : Cursor := B (U).First;
-               Temp : Cursor;
-               W    : Vertex_Index;
-            begin
-               loop
-                  exit when not Has_Element (Cur);
-                  W := Element (Cur);
-                  Temp := Cur;
-                  Next (Cur);
-                  B (U).Delete (Temp);
-                  if Blocked (W) then
-                     Unblock (W);
-                  end if;
-               end loop;
-            end;
-         end Unblock;
-
-         procedure Add_Result
-         is
-            Cycle : Path (1 .. Integer (Stack.Depth));
-         begin
-            for I in 1 .. Stack.Depth loop
-               Cycle (Integer (Stack.Depth - I + 1)) := (Stack.Peek (I), 
Edge_Lists.Empty_List);
-               --  We add the edge info later, after finding all the cycles.
-            end loop;
-            Result.Append (Cycle);
-            if Trace > 0 then
-               Ada.Text_IO.Put_Line ("cycle " & Image (Cycle));
-            end if;
-         end Add_Result;
-
-      begin
-         if Trace > 0 then
-            Ada.Text_IO.Put_Line ("circuit start" & V'Image);
-         end if;
-
-         Stack.Push (V);
-         Blocked (V) := True;
-         if V in A_K.First_Index .. A_K.Last_Index then
-            for W of A_K (V) loop
-               if W = S then
-                  Add_Result;
-                  F := True;
-               elsif not Blocked (W) then
-                  if Circuit (W) then
-                     F := True;
-                  end if;
-               end if;
-            end loop;
-         end if;
-         if F then
-            Unblock (V);
-         else
-            if V in A_K.First_Index .. A_K.Last_Index then
-               for W of A_K (V) loop
-                  if (for all V1 of B (W) => V /= V1) then
-                     B (W).Append (V);
-                  end if;
-               end loop;
-            end if;
-         end if;
-         Stack.Pop;
-         if Trace > 0 then
-            Ada.Text_IO.Put_Line ("circuit finish" & V'Image);
-         end if;
-         return F;
-      end Circuit;
-
-   begin
-      --  [3] restricts the graph to not have loops (edge v-v) or multiple
-      --  edges between two nodes. So we first delete any such edges.
-      Delete_Loops_Multigraph :
-      for V in Edited_Graph.Vertices.First_Index .. 
Edited_Graph.Vertices.Last_Index loop
-         declare
-            use Edge_Node_Lists;
-            Cur        : Cursor  := Edited_Graph.Vertices (V).First;
-            Temp       : Cursor;
-            Found_Loop : Boolean := False;
-         begin
-            loop
-               exit when not Has_Element (Cur);
-               if Element (Cur).Vertex_B = V then
-                  if not Found_Loop then
-                     --  This is a cycle we want in the result. Edge data is 
added to all
-                     --  cycles later.
-                     Result.Append (Path'(1 => (V, Edge_Lists.Empty_List)));
-                     Found_Loop := True;
-                  end if;
-                  Temp := Cur;
-                  Next (Cur);
-                  Edited_Graph.Vertices (V).Delete (Temp);
-               elsif Element (Cur).Multigraph then
-                  --  These will be added back from Graph after we find all 
cycles.
-                  Temp := Cur;
-                  Next (Cur);
-                  Edited_Graph.Vertices (V).Delete (Temp);
-               else
-                  Next (Cur);
-               end if;
-            end loop;
-         end;
-      end loop Delete_Loops_Multigraph;
-
-      B.Set_First_Last (Graph.Vertices.First_Index, Graph.Vertices.Last_Index);
-
-      --  Start of body of Circuit-Finding Algorithm from [3]
-      loop
-         exit when S = Graph.Vertices.Last_Index;
-         declare
-            use Component_Lists;
-            Subgraph         : Adjacency_Structures.Vector;
-            Components       : Component_Lists.List;
-            Cur              : Component_Lists.Cursor;
-            Least_Vertex_Cur : Component_Lists.Cursor;
-            Least_Vertex_V   : Vertex_Index := Vertex_Index'Last;
-
-            function Delete_Edges (Edges : in Edge_Node_Lists.List) return 
Vertex_Lists.List
-            is begin
-               return Result : Vertex_Lists.List do
-                  for Edge of Edges loop
-                     if Edge.Vertex_B >= S then
-                        Result.Append (Edge.Vertex_B);
-                     end if;
-                  end loop;
-               end return;
-            end Delete_Edges;
-         begin
-            Subgraph.Set_First_Last (S, Edited_Graph.Vertices.Last_Index);
-            for V in S .. Edited_Graph.Vertices.Last_Index loop
-               Subgraph (V) := Delete_Edges (Edited_Graph.Vertices (V));
-            end loop;
-
-            Components := Strongly_Connected_Components (Subgraph, 
Non_Trivial_Only => True);
-            Cur        := Components.First;
-            loop
-               exit when not Has_Element (Cur);
-
-               if Element (Cur).Length > 1 then
-                  declare
-                     Comp : Vertex_Lists.List renames 
Components.Constant_Reference (Cur);
-                  begin
-                     for W of Comp loop
-                        if W < Least_Vertex_V then
-                           Least_Vertex_Cur := Cur;
-                           Least_Vertex_V   := W;
-                        end if;
-                     end loop;
-                  end;
-               end if;
-               Next (Cur);
-            end loop;
-
-            A_K.Clear;
-            if Has_Element (Least_Vertex_Cur) then
-               declare
-                  Component : Vertex_Lists.List renames Components 
(Least_Vertex_Cur);
-                  Min : Vertex_Index := Vertex_Index'Last;
-                  Max : Vertex_Index := Vertex_Index'First;
-               begin
-                  if Trace > 0 then
-                     Ada.Text_IO.Put_Line ("strong component " & 
Least_Vertex_V'Image);
-                     Ada.Text_IO.Put_Line (Image (Component));
-                  end if;
-                  for V of Component loop
-                     if Min > V then
-                        Min := V;
-                     end if;
-                     if Max < V then
-                        Max := V;
-                     end if;
-                  end loop;
-                  A_K.Set_First_Last (Min, Max);
-                  for V of Component loop
-                     for Edge of Edited_Graph.Vertices (V) loop
-                        A_K (V).Append (Edge.Vertex_B);
-                     end loop;
-                  end loop;
-               end;
-            end if;
-         end;
-
-         if A_K.Length > 0 then
-            S := A_K.First_Index;
-            for I in A_K.First_Index .. A_K.Last_Index loop
-               Blocked (I) := False;
-               B (I).Clear;
-            end loop;
-            Dummy := Circuit (S);
-            S := S + 1;
-         else
-            S := Graph.Vertices.Last_Index;
-         end if;
-      end loop;
-
-      --  Add edge data.
-      for Cycle of Result loop
-         for I in Cycle'First .. Cycle'Last loop
-            declare
-               Prev_I : constant Positive := (if I = Cycle'First then 
Cycle'Last else I - 1);
-            begin
-               for Edge of Graph.Vertices (Cycle (Prev_I).Vertex) loop
-                  if Cycle (I).Vertex = Edge.Vertex_B then
-                     Cycle (I).Edges.Append ((Edge.ID, Edge.Data));
-                  end if;
-               end loop;
-            end;
-         end loop;
-      end loop;
-      return Result;
-   end Find_Cycles;
-
-   function Loops (Graph : in Gen_Graphs.Graph) return Vertex_Lists.List
-   is begin
-      return Result : Vertex_Lists.List do
-         for V in Graph.Vertices.First_Index .. Graph.Vertices.Last_Index loop
-            for Edge of Graph.Vertices (V) loop
-               if V = Edge.Vertex_B then
-                  Result.Append (V);
-                  exit;
-               end if;
-            end loop;
-         end loop;
-      end return;
-   end Loops;
-
-   function To_Adjancency (Graph : in Gen_Graphs.Graph) return 
Adjacency_Structures.Vector
-   is
-      function To_Vertex_List (Edges : in Edge_Node_Lists.List) return 
Vertex_Lists.List
-      is begin
-         return Result : Vertex_Lists.List do
-            for Edge of Edges loop
-               Result.Append (Edge.Vertex_B);
-            end loop;
-         end return;
-      end To_Vertex_List;
-   begin
-      return Result : Adjacency_Structures.Vector do
-         Result.Set_First_Last (Graph.Vertices.First_Index, 
Graph.Vertices.Last_Index);
-         for V in Graph.Vertices.First_Index .. Graph.Vertices.Last_Index loop
-            Result (V) := To_Vertex_List (Graph.Vertices (V));
-         end loop;
-      end return;
-   end To_Adjancency;
-
-   function Strongly_Connected_Components
-     (Graph            : in Adjacency_Structures.Vector;
-      Non_Trivial_Only : in Boolean := False)
-     return Component_Lists.List
-   is
-      --  Implements [4] section 4.
-
-      Low_Link : array (Graph.First_Index .. Graph.Last_Index) of 
Vertex_Index'Base := (others => Invalid_Vertex);
-
-      Number : array (Graph.First_Index .. Graph.Last_Index) of 
Vertex_Index'Base := (others => Invalid_Vertex);
-      --  Number is the order visited in the depth-first search.
-
-      Points : Vertex_Stacks.Stack;
-
-      I : Vertex_Index'Base := Graph.First_Index - 1;
-
-      Result : Component_Lists.List;
-
-      procedure Strong_Connect (V : in Vertex_Index)
-      is begin
-         I            := I + 1;
-         Number (V)   := I;
-         Low_Link (V) := I;
-         Points.Push (V);
-
-         for W of Graph (V) loop
-            if Number (W) = Invalid_Vertex then
-               --  (v, w) is a tree arc
-               Strong_Connect (W);
-               Low_Link (V) := Vertex_Index'Min (Low_Link (V), Low_Link (W));
-
-            elsif Number (W) < Number (V) then
-               --  (v, w) is a frond or cross-link
-               if (for some P of Points => P = W) then
-                  Low_Link (V) := Vertex_Index'Min (Low_Link (V), Low_Link 
(W));
-               end if;
-            end if;
-         end loop;
-         if Low_Link (V) = Number (V) then
-            --  v is the root of a component
-            declare
-               use all type Ada.Containers.Count_Type;
-               Component : Vertex_Lists.List;
-            begin
-               while (not Points.Is_Empty) and then Number (Points.Peek) >= 
Number (V) loop
-                  Component.Append (Points.Pop);
-               end loop;
-               if (not Non_Trivial_Only) or Component.Length > 1 then
-                  Result.Append (Component);
-               end if;
-            end;
-         end if;
-      end Strong_Connect;
-   begin
-      for W in Graph.First_Index .. Graph.Last_Index loop
-         if Number (W) = Invalid_Vertex then
-            Strong_Connect (W);
-         end if;
-      end loop;
-      return Result;
-   end Strongly_Connected_Components;
-
-end SAL.Gen_Graphs;
diff --git a/packages/wisi/sal-gen_graphs.ads b/packages/wisi/sal-gen_graphs.ads
deleted file mode 100644
index 03cc1c6..0000000
--- a/packages/wisi/sal-gen_graphs.ads
+++ /dev/null
@@ -1,190 +0,0 @@
---  Abstract :
---
---  Type and operations for graphs.
---
---  References:
---
---  [1] Introduction to Algorithms, Thomas H. Cormen, Charles E.
---  Leiserson, Ronald L. Rivest, Clifford Stein.
---
---  [2] "An Efficient Search Algorithm to Find the Elementary Circuits
---  of a Graph", James C. Tiernan, Communications of the ACM Volume 13
---  Number 12 December 1970.
---  
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.516.9454&rep=rep1&type=pdf
---
---  [3] "Finding all the Elementary Circuits of a Directed Graph",
---  Donald B. Johnson, SIAM J. Comput. Vol 4, No. 1, March 1975.
---  https://epubs.siam.org/doi/abs/10.1137/0204007
---
---  [4] "Depth-First Search and Linear Graph Algorithms", Robert
---  Tarjan, SIAM J. Comput. Vol. 1, No 2, June 1972.
---  https://epubs.siam.org/doi/abs/10.1137/0201010
---
---  Copyright (C) 2017, 2019, 2020 Free Software Foundation All Rights 
Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Containers.Indefinite_Vectors;
-with SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image;
-with SAL.Gen_Trimmed_Image;
-with SAL.Gen_Unbounded_Definite_Vectors;
-generic
-   type Edge_Data is private;
-   Default_Edge_Data : in Edge_Data;
-   type Vertex_Index is range <>;
-   Invalid_Vertex : in Vertex_Index'Base;
-
-   type Path_Index is range <>;
-
-   with function Edge_Image (Item : in Edge_Data) return String;
-
-package SAL.Gen_Graphs is
-
-   type Graph is tagged private;
-
-   procedure Add_Edge
-     (Graph    : in out Gen_Graphs.Graph;
-      Vertex_A : in     Vertex_Index;
-      Vertex_B : in     Vertex_Index;
-      Data     : in     Edge_Data);
-   --  Adds a directed edge from Vertex_A to Vertex_B.
-
-   function Count_Nodes (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type;
-   function Count_Edges (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type;
-
-   function Multigraph (Graph : in Gen_Graphs.Graph) return Boolean;
-   --  If more than one edge is added between two vertices, the graph is
-   --  a multigraph. The edges are given separate identifiers internally.
-
-   Multigraph_Error : exception;
-
-   type Base_Edge_ID is range 0 .. Integer'Last;
-   subtype Edge_ID is Base_Edge_ID range 1 .. Base_Edge_ID'Last;
-   Invalid_Edge_ID : constant Base_Edge_ID := 0;
-   --  Edge ids are unique graph-wide, assigned by Add_Edge.
-
-   type Edge_Item is record
-      ID   : Base_Edge_ID := Invalid_Edge_ID;
-      Data : Edge_Data    := Default_Edge_Data;
-   end record;
-   function Image (Item : in Edge_Item) return String
-     is (Edge_Image (Item.Data));
-
-   package Edge_Lists is new Ada.Containers.Doubly_Linked_Lists (Edge_Item);
-
-   function "+" (Right : in Edge_Item) return Edge_Lists.List;
-
-   function Edges (Graph : in Gen_Graphs.Graph; Vertex : in Vertex_Index) 
return Edge_Lists.List;
-   --  All edges from Vertex, as set by Add_Edge.
-
-   function Image is new SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-     (Element_Type  => Edge_Item,
-      Lists         => Edge_Lists,
-      Element_Image => Image);
-
-   type Path_Item is record
-      Vertex : Vertex_Index'Base := Invalid_Vertex;
-      Edges  : Edge_Lists.List;
-      --  Edges describe the edges leading from the previous vertex
-      --  in the path to Vertex. If this is the first vertex in an open
-      --  path, Edges is empty. If it is the first vertex in a
-      --  cycle, the edge are from the last vertex in the cycle.
-   end record;
-
-   type Path is array (Positive range <>) of Path_Item;
-
-   function Image (Item : in Path) return String;
-   --  For trace, debugging.
-
-   package Path_Arrays is new Ada.Containers.Indefinite_Vectors (Path_Index, 
Path);
-
-   function "<" (Left, Right : in Path) return Boolean;
-
-   package Sort_Paths is new Path_Arrays.Generic_Sorting;
-
-   function Find_Paths
-     (Graph : in out Gen_Graphs.Graph;
-      From  : in     Vertex_Index;
-      To    : in     Edge_Data)
-     return Path_Arrays.Vector;
-   --  Return all non-cyclic paths starting at From that lead to a To
-   --  edge, using algorithm [1]. First entry in each item in result is
-   --  From, with first edge. Last entry in result contains edge data for
-   --  To.
-   --
-   --  Raises Multigraph_Error if Graph is a multigraph.
-
-   function Find_Cycles_Tiernan (Graph : in Gen_Graphs.Graph) return 
Path_Arrays.Vector;
-   --  Return all cyclic paths in Graph, using algorithm [2] extended for
-   --  multigraphs.
-   --
-   --  Time complexity is exponential in the number of nodes. Used in
-   --  unit tests for Find_Cycles, since [2] is easier to
-   --  implement.
-
-   function Find_Cycles (Graph : in Gen_Graphs.Graph) return 
Path_Arrays.Vector;
-   --  Return all cyclic paths in Graph, using algorithm [3] extended for
-   --  multigraphs.
-   --
-   --  Time complexity is linear in the number of nodes and edges.
-
-   package Vertex_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Vertex_Index);
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Vertex_Index);
-   function Image is new SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-     (Vertex_Index, "=", Vertex_Lists, Trimmed_Image);
-
-   function Loops (Graph : in Gen_Graphs.Graph) return Vertex_Lists.List;
-   --  List of vertices that have an edge to themselves.
-
-   package Adjacency_Structures is new SAL.Gen_Unbounded_Definite_Vectors
-     (Vertex_Index, Vertex_Lists.List, Vertex_Lists.Empty_List);
-   --  Graphs with no Edge_ID or Edge_Data; useful as intermediate results.
-
-   function To_Adjancency (Graph : in Gen_Graphs.Graph) return 
Adjacency_Structures.Vector;
-
-   package Component_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Vertex_Lists.List, Vertex_Lists."=");
-
-   function Strongly_Connected_Components
-     (Graph            : in Adjacency_Structures.Vector;
-      Non_Trivial_Only : in Boolean := False)
-     return Component_Lists.List;
-   --  Find strongly connected components of Graph, using algorithm in [4].
-   --  If Non_Trivial_Only, don't include single-vertex components.
-
-   Trace : Integer := 0;
-   --  Some bodies output debug info to Text_IO.Current_Output for
-   --  non-zero values of Trace.
-private
-
-   type Edge_Node is record
-      --  Edge is from vertex contaning this Node to Vertex_B
-      ID         : Edge_ID;
-      Vertex_B   : Vertex_Index;
-      Multigraph : Boolean; -- Same Vertex_B as another edge in same vertex.
-      Data       : Edge_Data;
-   end record;
-
-   package Edge_Node_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Edge_Node);
-
-   package Vertex_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Vertex_Index, Edge_Node_Lists.List, Edge_Node_Lists.Empty_List);
-
-   type Graph is tagged record
-      Last_Edge_ID : Base_Edge_ID := Invalid_Edge_ID;
-      Multigraph   : Boolean      := False;
-      Vertices     : Vertex_Arrays.Vector;
-   end record;
-
-end SAL.Gen_Graphs;
diff --git a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb 
b/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb
deleted file mode 100644
index 71d3f61..0000000
--- a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb
+++ /dev/null
@@ -1,211 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Indefinite_Doubly_Linked_Lists is
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Source   : Node_Access := Container.Head;
-      New_Node : Node_Access;
-   begin
-      if Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => new Element_Type'(Source.Element.all),
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Source := Source.Next;
-         exit when Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head.Element);
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   function Length (Container : in List) return SAL.Base_Peek_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   procedure Append (Container : in out List; Element : in Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => new Element_Type'(Element),
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Tail.Next := New_Node;
-         Container.Tail      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Append;
-
-   procedure Prepend (Container : in out List; Element : in Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => new Element_Type'(Element),
-         Prev    => null,
-         Next    => Container.Head);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Head.Prev := New_Node;
-         Container.Head      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Prepend;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Head);
-      end if;
-   end First;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element.all;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      Node : Node_Access renames Position.Ptr;
-   begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node.Element);
-      Free (Node);
-      Position        := (Ptr => null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Persistent_Ref;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element, Dummy => 1);
-   end Constant_Ref;
-
-   function Constant_Reference (Container : in List; Position : in Peek_Type) 
return Constant_Reference_Type
-   is
-      Ptr : Node_Access := Container.Head;
-   begin
-      for I in 2 .. Position loop
-         Ptr := Ptr.Next;
-      end loop;
-      return (Element => Ptr.all.Element, Dummy => 1);
-   end Constant_Reference;
-
-   function Variable_Reference (Container : in List; Position : in Peek_Type) 
return Variable_Reference_Type
-   is
-      Ptr : Node_Access := Container.Head;
-   begin
-      for I in 2 .. Position loop
-         Ptr := Ptr.Next;
-      end loop;
-      return (Element => Ptr.all.Element, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element, Dummy => 1);
-   end Variable_Ref;
-
-end SAL.Gen_Indefinite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads 
b/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads
deleted file mode 100644
index b1d1cdb..0000000
--- a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads
+++ /dev/null
@@ -1,128 +0,0 @@
---  Abstract :
---
---  A generic doubly linked list with indefinite elements, allowing
---  permanent references to elements.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type (<>) is private;
-package SAL.Gen_Indefinite_Doubly_Linked_Lists is
-
-   type List is new Ada.Finalization.Controlled with private with
-     Constant_Indexing => Constant_Reference,
-     Variable_Indexing => Variable_Reference;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   function Length (Container : in List) return Base_Peek_Type;
-
-   procedure Append (Container : in out List; Element : in Element_Type);
-
-   procedure Prepend (Container : in out List; Element : in Element_Type);
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   function First (Container : in List) return Cursor;
-
-   procedure Next (Position : in out Cursor);
-
-   function Next (Position : in Cursor) return Cursor;
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   with Pre => Has_Element (Position);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Constant_Reference (Container : in List; Position : in Peek_Type) 
return Constant_Reference_Type
-   with Inline, Pre => Position <= Container.Length;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Peek_Type) 
return Variable_Reference_Type
-   with Inline, Pre => Position <= Container.Length;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-private
-   type Node_Type;
-   type Node_Access is access Node_Type;
-   type Element_Access is access Element_Type;
-
-
-   type Node_Type is record
-      Element : Element_Access;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-   procedure Free is new Ada.Unchecked_Deallocation (Element_Type, 
Element_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access        := null;
-      Tail  : Node_Access        := null;
-      Count : SAL.Base_Peek_Type := 0;
-   end record;
-
-   type Cursor is record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   No_Element : constant Cursor := (Ptr => null);
-
-end SAL.Gen_Indefinite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_trimmed_image.adb 
b/packages/wisi/sal-gen_trimmed_image.adb
deleted file mode 100644
index 41fb042..0000000
--- a/packages/wisi/sal-gen_trimmed_image.adb
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings;
-with Ada.Strings.Fixed;
-function SAL.Gen_Trimmed_Image (Item : in Element_Type) return String
-is
-   use Ada.Strings;
-   use Ada.Strings.Fixed;
-begin
-   return Trim (Element_Type'Image (Item), Both);
-end SAL.Gen_Trimmed_Image;
diff --git a/packages/wisi/sal-gen_trimmed_image.ads 
b/packages/wisi/sal-gen_trimmed_image.ads
deleted file mode 100644
index 3ff29f9..0000000
--- a/packages/wisi/sal-gen_trimmed_image.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Generic trimmed image.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is range <>;
-function SAL.Gen_Trimmed_Image (Item : in Element_Type) return String;
---  Return image of Item with no leading space.
diff --git a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb 
b/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb
deleted file mode 100644
index c88a0cb..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb
+++ /dev/null
@@ -1,354 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Unchecked_Deallocation;
-with Long_Float_Elementary_Functions;
-package body SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci is
-
-   ----------
-   --  local subprogram specs (as needed), alphabetical order
-
-   procedure Insert_Into_Root_List (Heap : in out Heap_Type; X : in 
Node_Access);
-
-   procedure Link (Y, X : in Node_Access);
-
-   procedure Remove_From_List (X : in Node_Access);
-
-   procedure Swap (A, B : in out Node_Access);
-
-   ----------
-   --  local subprogram bodies, alphabetical order
-
-   procedure Consolidate (Heap : in out Heap_Type)
-   is
-      --  [1] 19.4 max degree of Fibonacci heap
-      Phi : constant := 1.61803398874989484820458683436563811772; -- 
https://oeis.org/A001622/constant
-      Max_Degree : constant Integer := Integer
-        (Long_Float_Elementary_Functions.Log (Long_Float (Heap.Count), Base => 
Phi));
-
-      --  [1] 19.2 CONSOLIDATE
-      A : array (0 .. Max_Degree) of Node_Access := (others => null);
-
-      W    : Node_Access := Heap.Min;
-      Last : Node_Access := Heap.Min;
-      X, Y : Node_Access;
-      D    : Integer;
-
-      Min_Key : Key_Type;
-   begin
-      loop
-         X := W;
-         W := W.Right;
-
-         D := X.Degree;
-
-         loop
-            exit when A (D) = null;
-
-            Y := A (D);
-            if Key (Y.Element) < Key (X.Element) then
-               Swap (X, Y);
-            end if;
-            if Y = Last and W /= Last then
-               Last := Y.Right;
-            end if;
-            Link (Y, X);
-            A (D) := null;
-            D := D + 1;
-            exit when D = A'Last;
-         end loop;
-
-         A (D) := X;
-
-         exit when W = Last;
-      end loop;
-
-      Heap.Min := null;
-      for I in A'Range loop
-         if A (I) /= null then
-            if Heap.Min = null then
-               Heap.Min       := A (I);
-               Heap.Min.Left  := Heap.Min;
-               Heap.Min.Right := Heap.Min;
-               Min_Key        := Key (Heap.Min.Element);
-            else
-               Insert_Into_Root_List (Heap, A (I));
-               if Key (A (I).Element) < Min_Key then
-                  Heap.Min := A (I);
-                  Min_Key := Key (A (I).Element);
-               end if;
-            end if;
-         end if;
-      end loop;
-   end Consolidate;
-
-   procedure Copy_Node (Old_Obj : in Node_Access; New_Obj : in out Heap_Type)
-   is
-      Child : Node_Access;
-   begin
-      if Old_Obj = null then
-         return;
-      end if;
-
-      if Old_Obj.Child /= null then
-         Child := Old_Obj.Child;
-
-         loop
-            Add (New_Obj, Child.Element);
-            Child := Child.Right;
-            exit when Child = Old_Obj.Child;
-         end loop;
-      end if;
-
-      Add (New_Obj, Old_Obj.Element);
-   end Copy_Node;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
-
-   procedure Free_Node (Item : in out Node_Access)
-   is
-      Child : Node_Access;
-      Temp  : Node_Access;
-   begin
-      if Item = null then
-         return;
-      end if;
-
-      --  Parent has already been free'd
-      --  Siblings are freed by caller
-
-      --  Free children
-      if Item.Child /= null then
-         Child := Item.Child;
-
-         loop
-            Temp  := Child;
-            Child := Child.Right;
-            Free_Node (Temp);
-            exit when Child = Item.Child;
-         end loop;
-      end if;
-      Free (Item);
-   end Free_Node;
-
-   procedure Insert_Into_Root_List (Heap : in out Heap_Type; X : in 
Node_Access)
-   is begin
-      --  match [1] fig 19.3
-      X.Right             := Heap.Min;
-      X.Left              := Heap.Min.Left;
-      Heap.Min.Left.Right := X;
-      Heap.Min.Left       := X;
-   end Insert_Into_Root_List;
-
-   procedure Link (Y, X : in Node_Access)
-   is begin
-      --  [1] 19.2 FIB-HEAP-LINK
-      Remove_From_List (Y);
-      Y.Parent := X;
-      X.Degree := X.Degree + 1;
-      if X.Child = null then
-         X.Child := Y;
-         Y.Right := Y;
-         Y.Left  := Y;
-      else
-         --  Insert Y into X child list
-         Y.Right            := X.Child;
-         Y.Left             := X.Child.Left;
-         X.Child.Left.Right := Y;
-         X.Child.Left       := Y;
-      end if;
-      Y.Mark := False;
-   end Link;
-
-   procedure Remove_From_List (X : in Node_Access)
-   is begin
-      X.Left.Right := X.Right;
-      X.Right.Left := X.Left;
-   end Remove_From_List;
-
-   procedure Swap (A, B : in out Node_Access)
-   is
-      C : constant Node_Access := A;
-   begin
-      A := B;
-      B := C;
-   end Swap;
-
-   ----------
-   --  Visible operations
-
-   overriding
-   procedure Initialize (Object : in out Heap_Type)
-   is begin
-      --  Min is null by default.
-      Object.Count := 0;
-   end Initialize;
-
-   overriding
-   procedure Finalize (Object : in out Heap_Type)
-   is
-      Next : Node_Access := Object.Min;
-      Temp : Node_Access;
-   begin
-      if Next = null then
-         return;
-      end if;
-
-      loop
-         Temp := Next;
-         Next := Next.Right;
-         Free_Node (Temp);
-         exit when Next = Object.Min;
-      end loop;
-      Object.Min   := null;
-      Object.Count := 0;
-   end Finalize;
-
-   overriding
-   procedure Adjust (Object : in out Heap_Type)
-   is
-      Old_Obj : Node_Access := Object.Min;
-      Last : constant Node_Access := Old_Obj;
-   begin
-      if Old_Obj = null then
-         return;
-      end if;
-
-      Object.Min := null;
-      Object.Count := 0;
-
-      loop
-         Copy_Node (Old_Obj, Object);
-         Old_Obj := Old_Obj.Right;
-         exit when Old_Obj = Last;
-      end loop;
-   end Adjust;
-
-   procedure Clear (Heap : in out Heap_Type)
-   is begin
-      Finalize (Heap);
-   end Clear;
-
-   function Count (Heap : in Heap_Type) return Base_Peek_Type
-   is begin
-      return Heap.Count;
-   end Count;
-
-   function Remove (Heap : in out Heap_Type) return Element_Type
-   is
-      Z           : Node_Access := Heap.Min;
-      Child, Temp : Node_Access;
-   begin
-      if Heap.Count = 0 then
-         raise Container_Empty;
-      end if;
-
-      --  [1] 19.2 FIB-HEAP-EXTRACT-MIN
-      Child := Z.Child;
-      for I in 1 .. Z.Degree loop
-         Temp        := Child;
-         Child       := Child.Right;
-         Temp.Parent := null;
-         Insert_Into_Root_List (Heap, Temp);
-      end loop;
-
-      Remove_From_List (Z);
-
-      if Z.Right = Z then
-         Heap.Min := null;
-      else
-         Heap.Min := Z.Right;
-         Consolidate (Heap);
-      end if;
-      Heap.Count := Heap.Count - 1;
-
-      return Result : constant Element_Type := Z.Element do
-         Free (Z);
-      end return;
-   end Remove;
-
-   function Min_Key (Heap : in out Heap_Type) return Key_Type
-   is begin
-      return Key (Heap.Min.Element);
-   end Min_Key;
-
-   procedure Drop (Heap : in out Heap_Type)
-   is
-      Junk : Element_Type := Remove (Heap);
-      pragma Unreferenced (Junk);
-   begin
-      null;
-   end Drop;
-
-   procedure Add (Heap : in out Heap_Type; Item : in Element_Type)
-   is
-      X : constant Node_Access := new Node'(Item, null, null, null, null, 0, 
False);
-   begin
-      --  [1] 19.2 FIB-HEAP-INSERT
-      if Heap.Min = null then
-         Heap.Min       := X;
-         Heap.Min.Left  := Heap.Min;
-         Heap.Min.Right := Heap.Min;
-      else
-         Insert_Into_Root_List (Heap, X);
-
-         if Key (Item) < Key (Heap.Min.Element) then
-            Heap.Min := X;
-         end if;
-      end if;
-      Heap.Count := Heap.Count + 1;
-   end Add;
-
-   function Peek (Heap : in Heap_Type) return Constant_Reference_Type
-   is begin
-      return (Element => Heap.Min.all.Element'Access, Dummy => 1);
-   end Peek;
-
-   procedure Process (Heap : in Heap_Type; Process_Element : access procedure 
(Element : in Element_Type))
-   is
-      type Cursor is record
-         --  Every node is in a circular list. List_Origin is the node where we
-         --  entered the list, so we know when we are done.
-         Node        : Node_Access;
-         List_Origin : Node_Access;
-      end record;
-
-      Cur : Cursor := (Heap.Min, Heap.Min);
-
-      procedure Process_Node (Cur : in out Cursor)
-      is
-         Next_Cur : Cursor;
-      begin
-         loop
-            if Cur.Node.Child /= null then
-               Next_Cur := (Cur.Node.Child, Cur.Node.Child);
-               Process_Node (Next_Cur);
-            end if;
-            Process_Element (Cur.Node.Element);
-            Cur.Node := Cur.Node.Right;
-            exit when Cur.Node = Cur.List_Origin;
-         end loop;
-      end Process_Node;
-   begin
-      if Cur.Node /= null then
-         Process_Node (Cur);
-      end if;
-   end Process;
-
-end SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci;
diff --git a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads 
b/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads
deleted file mode 100644
index aab9fcf..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads
+++ /dev/null
@@ -1,112 +0,0 @@
---  Abstract:
---
---  An unbounded minimum Fibonacci heap of definite non-limited elements.
---
---  References:
---
---  [1] Introduction to Algorithms, Third Edition. Thomas H. Cormen,
---  Charles E. Leiserson, Ronald L. Rivest, Clifford Stein. Chapter 19.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-generic
-   type Element_Type is private;
-   type Key_Type is private;
-   with function Key (Item : in Element_Type) return Key_Type;
-   with procedure Set_Key (Item : in out Element_Type; Key : in Key_Type);
-   pragma Unreferenced (Set_Key); -- needed for Decrease_Key
-   with function "<" (Left, Right : in Key_Type) return Boolean is <>;
-package SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci is
-
-   type Heap_Type is new Ada.Finalization.Controlled with private;
-
-   Empty_Heap : constant Heap_Type;
-
-   overriding
-   procedure Initialize (Object : in out Heap_Type);
-
-   overriding
-   procedure Finalize (Object : in out Heap_Type);
-
-   overriding
-   procedure Adjust (Object : in out Heap_Type);
-
-   procedure Clear (Heap : in out Heap_Type);
-   --  Empty Heap.
-
-   function Count (Heap : in Heap_Type) return Base_Peek_Type;
-   --  Return count of elements in Heap.
-
-   function Remove (Heap : in out Heap_Type) return Element_Type;
-   --  Remove minimum element in Heap, return it.
-
-   function Min_Key (Heap : in out Heap_Type) return Key_Type;
-   --  Return a copy of the minimum key value.
-
-   function Get (Heap : in out Heap_Type) return Element_Type renames Remove;
-
-   procedure Drop (Heap : in out Heap_Type);
-   --  Remove minimum element in Heap, discard it.
-
-   procedure Add (Heap : in out Heap_Type; Item : in Element_Type);
-   --  Add Item to Heap.
-
-   procedure Insert (Heap : in out Heap_Type; Item : in Element_Type) renames 
Add;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Peek (Heap : in Heap_Type) return Constant_Reference_Type;
-   --  Return a constant reference to the min element.
-   pragma Inline (Peek);
-
-   --  We don't provide a Cursor/Iterator interface; to complex to
-   --  implement. So far, we only need a read-only forward iterator,
-   --  which Process provides.
-
-   procedure Process (Heap : in Heap_Type; Process_Element : access procedure 
(Element : in Element_Type));
-   --  Call Process_Element with each Element in Heap. Min is first; rest are 
in
-   --  arbitrary order.
-
-private
-
-   type Node;
-   type Node_Access is access Node;
-
-   type Node is record
-      Element : aliased Element_Type;
-      Parent  : Node_Access;
-      Child   : Node_Access;
-      Left    : Node_Access;
-      Right   : Node_Access;
-      Degree  : Natural;
-      Mark    : Boolean;
-   end record;
-
-   type Heap_Type is new Ada.Finalization.Controlled with record
-      Min   : Node_Access;
-      Count : Base_Peek_Type;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Heap : constant Heap_Type := (Ada.Finalization.Controlled with Min => 
null, Count => 0);
-
-end SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb
deleted file mode 100644
index 2a1990b..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux (Item : in Queue; Aux 
: in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := Item.Count;
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads
deleted file mode 100644
index dafa8d9..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux (Item : in Queue; Aux 
: in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues.adb 
b/packages/wisi/sal-gen_unbounded_definite_queues.adb
deleted file mode 100644
index af53823..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues.adb
+++ /dev/null
@@ -1,97 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Queues is
-
-   procedure Clear (Queue : in out Pkg.Queue)
-   is begin
-      Queue.Data.Clear;
-   end Clear;
-
-   function Count (Queue : in Pkg.Queue) return Base_Peek_Type
-   is begin
-      return Base_Peek_Type (Queue.Data.Length);
-   end Count;
-
-   function Is_Empty (Queue : in Pkg.Queue) return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      return Queue.Data.Length = 0;
-   end Is_Empty;
-
-   function Remove (Queue : in out Pkg.Queue) return Element_Type
-   is
-      use Element_Lists;
-   begin
-      return A : constant Element_Type := Element (Queue.Data.First) do
-         Queue.Data.Delete_First;
-      end return;
-   end Remove;
-
-   procedure Drop (Queue : in out Pkg.Queue)
-   is begin
-      Queue.Data.Delete_First;
-   end Drop;
-
-   function Peek (Queue : in Pkg.Queue; N : Peek_Type := 1) return 
Constant_Reference_Type
-   is
-      use Ada.Containers;
-      use Element_Lists;
-      I : Cursor := Queue.Data.First;
-   begin
-      if Count_Type (N) > Queue.Data.Length then
-         raise Parameter_Error;
-      end if;
-
-      for K in 2 .. N loop
-         Next (I);
-      end loop;
-
-      return (Element => Element_Lists.Constant_Reference (Queue.Data, 
I).Element, Dummy => 1);
-   end Peek;
-
-   function Variable_Peek (Queue : in out Pkg.Queue; N : Peek_Type := 1) 
return Variable_Reference_Type
-   is
-      use Ada.Containers;
-      use Element_Lists;
-      I : Cursor := Queue.Data.First;
-   begin
-      if Count_Type (N) > Queue.Data.Length then
-         raise Parameter_Error;
-      end if;
-
-      for K in 2 .. N loop
-         Next (I);
-      end loop;
-
-      return (Element => Element_Lists.Variable_Reference (Queue.Data, 
I).Element, Dummy => 1);
-   end Variable_Peek;
-
-   procedure Add (Queue : in out Pkg.Queue; Item : in Element_Type)
-   is begin
-      Queue.Data.Append (Item);
-   end Add;
-
-   procedure Add_To_Head (Queue : in out Pkg.Queue; Item : in Element_Type)
-   is begin
-      Queue.Data.Prepend (Item);
-   end Add_To_Head;
-
-end SAL.Gen_Unbounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues.ads 
b/packages/wisi/sal-gen_unbounded_definite_queues.ads
deleted file mode 100644
index 237800d..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues.ads
+++ /dev/null
@@ -1,110 +0,0 @@
---  Abstract:
---
---  An unbounded queue of definite non-limited elements.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with SAL.Gen_Definite_Doubly_Linked_Lists;
-generic
-   type Element_Type is private;
-package SAL.Gen_Unbounded_Definite_Queues is
-
-   package Pkg renames SAL.Gen_Unbounded_Definite_Queues;
-
-   type Queue is tagged private;
-
-   Empty_Queue : constant Queue;
-
-   procedure Clear (Queue : in out Pkg.Queue);
-   --  Empty Queue.
-
-   function Count (Queue : in Pkg.Queue) return Base_Peek_Type;
-   --  Return count of items in the Queue
-
-   function Length (Queue : in Pkg.Queue) return Base_Peek_Type renames Count;
-
-   function Is_Empty (Queue : in Pkg.Queue) return Boolean;
-   --  Return true if no items are in Queue.
-
-   function Is_Full (Queue : in Pkg.Queue) return Boolean is (False);
-   --  Return true if Queue is full.
-
-   function Remove (Queue : in out Pkg.Queue) return Element_Type;
-   --  Remove head/front item from Queue, return it.
-   --
-   --  Raise Container_Empty if Is_Empty.
-
-   function Get (Queue : in out Pkg.Queue) return Element_Type renames Remove;
-
-   procedure Drop (Queue : in out Pkg.Queue);
-   --  Remove head/front item from Queue, discard it.
-   --
-   --  Raise Container_Empty if Is_Empty.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private
-   with
-      Implicit_Dereference => Element;
-
-   function Peek (Queue : in Pkg.Queue; N : Peek_Type := 1) return 
Constant_Reference_Type;
-   pragma Inline (Peek);
-   --  Return a constant reference to a queue item. N = 1 is the queue
-   --  head.
-   --
-   --  Raise Parameter_Error if N > Count
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private
-   with Implicit_Dereference => Element;
-
-   function Variable_Peek (Queue : in out Pkg.Queue; N : Peek_Type := 1) 
return Variable_Reference_Type;
-   pragma Inline (Variable_Peek);
-   --  Return a variable reference to a queue item. N = 1 is the queue
-   --  head.
-   --
-   --  Raises Parameter_Error if N > Count
-
-   procedure Add (Queue : in out Pkg.Queue; Item : in Element_Type);
-   --  Add Element to the tail/back of Queue.
-
-   procedure Put (Queue : in out Pkg.Queue; Item : in Element_Type) renames 
Add;
-
-   procedure Add_To_Head (Queue : in out Pkg.Queue; Item : in Element_Type);
-   --  Add Element to the head/front of Queue.
-
-private
-
-   package Element_Lists is new SAL.Gen_Definite_Doubly_Linked_Lists 
(Element_Type);
-
-   --  We don't provide cursors or write access to queue elements, so we
-   --  don't need any tampering checks.
-
-   type Queue is tagged record
-      Data : Element_Lists.List;
-      --  Add at Tail/Back = Last, remove at Head/Front = First.
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Queue : constant Queue := (Data => Element_Lists.Empty_List);
-
-end SAL.Gen_Unbounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb 
b/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb
deleted file mode 100644
index 0cbd6dd..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb
+++ /dev/null
@@ -1,870 +0,0 @@
---  Abstract :
---
---  Generic unbounded red-black tree with definite elements.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Red_Black_Trees is
-
-   --  Local declarations (alphabetical order)
-
-   function Count_Tree (Item : in Node_Access; Nil : in Node_Access) return 
Ada.Containers.Count_Type
-   with Pre => Nil /= null;
-
-   procedure Delete_Fixup (T : in out Tree; X : in out Node_Access);
-
-   function Find (Root : in Node_Access; Key : in Key_Type; Nil : in 
Node_Access) return Node_Access
-   with Pre => Nil /= null;
-
-   procedure Left_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   with Pre => X /= null;
-
-   procedure Right_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   with Pre => X /= null;
-
-   procedure Transplant (T : in out Pkg.Tree; U, V : in Node_Access)
-   with Pre => U /= null and T.Root /= null;
-
-   ----------
-   --  local bodies (alphabetical order)
-
-   function Count_Tree (Item : in Node_Access; Nil : in Node_Access) return 
Ada.Containers.Count_Type
-   is
-      use all type Ada.Containers.Count_Type;
-      Result : Ada.Containers.Count_Type := 0;
-   begin
-      if Item.Left /= Nil then
-         Result := Result + Count_Tree (Item.Left, Nil);
-      end if;
-
-      if Item.Right /= Nil then
-         Result := Result + Count_Tree (Item.Right, Nil);
-      end if;
-
-      return Result + 1;
-   end Count_Tree;
-
-   procedure Delete_Fixup (T : in out Tree; X : in out Node_Access)
-   is
-      W : Node_Access;
-   begin
-      --  [1] 13.3 RB-Delete-Fixup
-      --  X is either "doubly black" or "red and black"
-      --  X.Parent is set, even if X = Nil.
-      --  In all cases, Nil.Left = null.Right = null.
-
-      while X /= T.Root and X.Color = Black loop
-         if X = X.Parent.Left then
-            W := X.Parent.Right;
-            if W.Color = Red then
-               W.Color        := Black;
-               X.Parent.Color := Red;
-               Left_Rotate (T, X.Parent);
-               W              := X.Parent.Right;
-            end if;
-
-            if W.Left.Color = Black and W.Right.Color = Black then
-               W.Color := Red;
-               X := X.Parent;
-            else
-               if W.Right.Color = Black then
-                  W.Left.Color := Black;
-                  W.Color      := Red;
-                  Right_Rotate (T, W);
-                  W            := X.Parent.Right;
-               end if;
-               W.Color        := X.Parent.Color;
-               X.Parent.Color := Black;
-               W.Right.Color  := Black;
-               Left_Rotate (T, X.Parent);
-               X              := T.Root;
-            end if;
-         else
-            W := X.Parent.Left;
-            if W.Color = Red then
-               W.Color        := Black;
-               X.Parent.Color := Red;
-               Right_Rotate (T, X.Parent);
-               W              := X.Parent.Left;
-            end if;
-
-            if W.Right.Color = Black and W.Left.Color = Black then
-               W.Color := Red;
-               X       := X.Parent;
-            else
-               if W.Left.Color = Black then
-                  W.Right.Color := Black;
-                  W.Color       := Red;
-                  Left_Rotate (T, W);
-                  W             := X.Parent.Left;
-               end if;
-               W.Color        := X.Parent.Color;
-               X.Parent.Color := Black;
-               W.Left.Color   := Black;
-               Right_Rotate (T, X.Parent);
-               X              := T.Root;
-            end if;
-         end if;
-      end loop;
-      X.Color := Black;
-   end Delete_Fixup;
-
-   function Find (Root : in Node_Access; Key : in Key_Type; Nil : in 
Node_Access) return Node_Access
-   is
-      Node : Node_Access := Root;
-   begin
-      while Node /= Nil loop
-         case Key_Compare (Key, Pkg.Key (Node.Element)) is
-         when Equal =>
-            return Node;
-         when Less =>
-            Node := Node.Left;
-         when Greater =>
-            Node := Node.Right;
-         end case;
-      end loop;
-      return null;
-   end Find;
-
-   procedure Free_Tree (Item : in out Node_Access; Nil : in Node_Access)
-   is begin
-      if Item = Nil or Item = null then
-         raise Programmer_Error;
-      end if;
-
-      if Item.Left /= Nil then
-         Free_Tree (Item.Left, Nil);
-      end if;
-
-      if Item.Right /= Nil then
-         Free_Tree (Item.Right, Nil);
-      end if;
-
-      Free (Item);
-   end Free_Tree;
-
-   procedure Insert_Fixup (Tree : in out Pkg.Tree; Z : in out Node_Access)
-   is
-      --  [1] 13.3 RB-Insert-Fixup (T, z)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : Node_Access;
-   begin
-      while Z.Parent /= Nil and then Z.Parent.Color = Red loop
-         if Z.Parent = Z.Parent.Parent.Left then
-            Y := Z.Parent.Parent.Right;
-            if Y /= Nil and then Y.Color = Red then
-               Z.Parent.Color        := Black;
-               Y.Color               := Black;
-               Z.Parent.Parent.Color := Red;
-               Z                     := Z.Parent.Parent;
-            else
-               if Z = Z.Parent.Right then
-                  Z := Z.Parent;
-                  Left_Rotate (Tree, Z);
-               end if;
-               Z.Parent.Color        := Black;
-               Z.Parent.Parent.Color := Red;
-               Right_Rotate (Tree, Z.Parent.Parent);
-            end if;
-         else
-            Y := Z.Parent.Parent.Left;
-            if Y /= Nil and then Y.Color = Red then
-               Z.Parent.Color        := Black;
-               Y.Color               := Black;
-               Z.Parent.Parent.Color := Red;
-               Z                     := Z.Parent.Parent;
-            else
-               if Z = Z.Parent.Left then
-                  Z := Z.Parent;
-                  Right_Rotate (Tree, Z);
-               end if;
-               Z.Parent.Color        := Black;
-               Z.Parent.Parent.Color := Red;
-               Left_Rotate (Tree, Z.Parent.Parent);
-            end if;
-         end if;
-      end loop;
-      Tree.Root.Color := Black;
-   end Insert_Fixup;
-
-   procedure Left_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   is
-      --  [1] 13.2 Left-Rotate (T, x)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : constant Node_Access := X.Right;
-   begin
-      X.Right := Y.Left;
-      if Y.Left /= Nil then
-         Y.Left.Parent := X;
-      end if;
-      Y.Parent := X.Parent;
-      if X.Parent = Nil then
-         Tree.Root := Y;
-      elsif X = X.Parent.Left then
-         X.Parent.Left := Y;
-      else
-         X.Parent.Right := Y;
-      end if;
-      Y.Left   := X;
-      X.Parent := Y;
-   end Left_Rotate;
-
-   function Minimum (Node : in Node_Access; Nil : in Node_Access) return 
Node_Access
-   is begin
-      return Result : Node_Access := Node
-      do
-         while Result.Left /= Nil loop
-            Result := Result.Left;
-         end loop;
-      end return;
-   end Minimum;
-
-   procedure Right_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   is
-      --  [1] 13.2 Right-Rotate (T, x)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : constant Node_Access := X.Left;
-   begin
-      X.Left := Y.Right;
-      if Y.Right /= Nil then
-         Y.Right.Parent := X;
-      end if;
-      Y.Parent := X.Parent;
-      if X.Parent = Nil then
-         Tree.Root := Y;
-      elsif X = X.Parent.Right then
-         X.Parent.Right := Y;
-      else
-         X.Parent.Left := Y;
-      end if;
-      Y.Right  := X;
-      X.Parent := Y;
-   end Right_Rotate;
-
-   procedure Transplant (T : in out Pkg.Tree; U, V : in Node_Access)
-   is
-      Nil : Node_Access renames T.Nil;
-   begin
-      --  [1] 13.4 RB-Transplant, 12.3 Transplant
-
-      if U.Parent = Nil then
-         T.Root := V;
-      elsif U = U.Parent.Left then
-         U.Parent.Left := V;
-      else
-         U.Parent.Right := V;
-      end if;
-      V.Parent := U.Parent;
-   end Transplant;
-
-   ----------
-   --  Public subprograms, spec order
-
-   overriding procedure Finalize (Object : in out Tree)
-   is begin
-      if Object.Root /= null then
-         if Object.Root = Object.Nil then
-            Free (Object.Nil);
-            Object.Root := null;
-         else
-            Free_Tree (Object.Root, Object.Nil);
-            Free (Object.Nil);
-         end if;
-      end if;
-   end Finalize;
-
-   overriding procedure Initialize (Object : in out Tree)
-   is begin
-      Object.Nil       := new Node;
-      Object.Nil.Color := Black;
-      Object.Root      := Object.Nil;
-   end Initialize;
-
-   function Has_Element (Cursor : in Pkg.Cursor) return Boolean
-   is begin
-      return Cursor.Node /= null;
-   end Has_Element;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Node.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Constant_Reference_Type
-   is
-      Node : constant Node_Access := Find (Container.Root, Key, Container.Nil);
-   begin
-      if Node = null then
-         raise Not_Found;
-      else
-         --  WORKAROUND: GNAT Community 2019 requires .all here, GNAT Pro 21.0w
-         --  20200426 requires it _not_ be here. The code is technically legal
-         --  either way, so both compilers have a bug. Keeping .all for now;
-         --  just delete it if you are using 21.0w. Hopefully 21 will fix the
-         --  bug. AdaCore ticket T503-001 on Eurocontrol support contract.
-         return (Element => Node.all.Element'Access, Dummy => 1);
-      end if;
-   end Constant_Reference;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      --  WORKAROUND: see note in Constant_Reference
-      return (Element => Position.Node.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Variable_Reference_Type
-   is
-      Node : constant Node_Access := Find (Container.Root, Key, Container.Nil);
-   begin
-      if Node = null then
-         raise Not_Found;
-      else
-         --  WORKAROUND: see note in Constant_Reference
-         return (Element => Node.all.Element'Access, Dummy => 1);
-      end if;
-   end Variable_Reference;
-
-   function Iterate (Tree : in Pkg.Tree'Class) return Iterator
-   is begin
-      return (Tree.Root, Tree.Nil);
-   end Iterate;
-
-   overriding function First (Iterator : in Pkg.Iterator) return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      if Node = Nil then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         loop
-            exit when Node.Left = Nil;
-            Node := Node.Left;
-         end loop;
-
-         return
-           (Node       => Node,
-            Direction  => Ascending,
-            Left_Done  => True,
-            Right_Done => False);
-      end if;
-
-   end First;
-
-   overriding function Next (Iterator : in Pkg.Iterator; Position : in Cursor) 
return Cursor
-   is
-      Nil : Node_Access renames Iterator.Nil;
-   begin
-      if Position.Direction /= Ascending then
-         raise Programmer_Error;
-      end if;
-
-      if Position.Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-
-      elsif Position.Left_Done or Position.Node.Left = Nil then
-         if Position.Right_Done or Position.Node.Right = Nil then
-            if Position.Node.Parent = Nil then
-               return
-                 (Node       => null,
-                  Direction  => Unknown,
-                  Left_Done  => True,
-                  Right_Done => True);
-            else
-               declare
-                  Node : constant Node_Access := Position.Node.Parent;
-                  Temp : constant Cursor      :=
-                    (Node       => Node,
-                     Direction  => Ascending,
-                     Left_Done  => Node.Right = Position.Node or Node.Left = 
Position.Node,
-                     Right_Done => Node.Right = Position.Node);
-               begin
-                  if Temp.Right_Done then
-                     return Next (Iterator, Temp);
-                  else
-                     return Temp;
-                  end if;
-               end;
-            end if;
-         else
-            declare
-               Node : constant Node_Access := Position.Node.Right;
-               Temp : constant Cursor      :=
-                 (Node       => Node,
-                  Direction  => Ascending,
-                  Left_Done  => Node.Left = Nil,
-                  Right_Done => False);
-            begin
-               if Temp.Left_Done then
-                  return Temp;
-               else
-                  return Next (Iterator, Temp);
-               end if;
-            end;
-         end if;
-      else
-         declare
-            Node : constant Node_Access := Position.Node.Left;
-            Temp : constant Cursor      :=
-              (Node       => Node,
-               Direction  => Ascending,
-               Left_Done  => Node.Left = Nil,
-               Right_Done => False);
-         begin
-            if Temp.Left_Done then
-               return Temp;
-            else
-               return Next (Iterator, Temp);
-            end if;
-         end;
-      end if;
-   end Next;
-
-   overriding function Last (Iterator : in Pkg.Iterator) return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      if Node = Nil then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         loop
-            exit when Node.Right = Nil;
-            Node := Node.Right;
-         end loop;
-         return
-           (Node       => Node,
-            Direction  => Descending,
-            Right_Done => True,
-            Left_Done  => False);
-      end if;
-   end Last;
-
-   overriding function Previous (Iterator : in Pkg.Iterator; Position : in 
Cursor) return Cursor
-   is
-      Nil : Node_Access renames Iterator.Nil;
-   begin
-      if Position.Direction /= Descending then
-         raise Programmer_Error;
-      end if;
-
-      if Position.Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-
-      elsif Position.Right_Done or Position.Node.Right = Nil then
-         if Position.Left_Done or Position.Node.Left = Nil then
-            if Position.Node.Parent = Nil then
-               return
-                 (Node       => null,
-                  Direction  => Unknown,
-                  Left_Done  => True,
-                  Right_Done => True);
-            else
-               declare
-                  Node : constant Node_Access := Position.Node.Parent;
-                  Temp : constant Cursor      :=
-                    (Node       => Node,
-                     Direction  => Descending,
-                     Right_Done => Node.Left = Position.Node or Node.Right = 
Position.Node,
-                     Left_Done  => Node.Left = Position.Node);
-               begin
-                  if Temp.Left_Done then
-                     return Previous (Iterator, Temp);
-                  else
-                     return Temp;
-                  end if;
-               end;
-            end if;
-         else
-            declare
-               Node : constant Node_Access := Position.Node.Left;
-               Temp : constant Cursor      :=
-                 (Node       => Node,
-                  Direction  => Descending,
-                  Right_Done => Node.Right = Nil,
-                  Left_Done  => False);
-            begin
-               if Temp.Right_Done then
-                  return Temp;
-               else
-                  return Previous (Iterator, Temp);
-               end if;
-            end;
-         end if;
-      else
-         declare
-            Node : constant Node_Access := Position.Node.Right;
-            Temp : constant Cursor      :=
-              (Node       => Node,
-               Direction  => Descending,
-               Right_Done => Node.Right = Nil,
-               Left_Done  => False);
-         begin
-            if Temp.Right_Done then
-               return Temp;
-            else
-               return Previous (Iterator, Temp);
-            end if;
-         end;
-      end if;
-   end Previous;
-
-   function Previous (Iterator : in Pkg.Iterator; Key : in Key_Type) return 
Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      while Node /= Nil loop
-         declare
-            Current_Key : Key_Type renames Pkg.Key (Node.Element);
-         begin
-            case Key_Compare (Key, Current_Key) is
-            when Equal =>
-                  return Previous (Iterator, (Node, Descending, Right_Done => 
True, Left_Done => False));
-
-            when Less =>
-               if Node.Left = Nil then
-                  return Previous (Iterator, (Node, Descending, Right_Done => 
True, Left_Done => True));
-               else
-                  Node := Node.Left;
-               end if;
-
-            when Greater =>
-               if Node.Right = Nil then
-                  return (Node, Descending, Right_Done => True, Left_Done => 
False);
-               else
-                  Node := Node.Right;
-               end if;
-            end case;
-         end;
-      end loop;
-
-      return
-        (Node       => null,
-         Direction  => Unknown,
-         Left_Done  => True,
-         Right_Done => True);
-   end Previous;
-
-   function Find
-     (Iterator  : in Pkg.Iterator;
-      Key       : in Key_Type;
-      Direction : in Direction_Type := Ascending)
-     return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : constant Node_Access := Find (Iterator.Root, Key, Nil);
-   begin
-      if Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         return
-           (Node       => Node,
-            Direction  => Direction,
-            Left_Done  =>
-              (case Direction is
-               when Ascending | Unknown => True,
-               when Descending => Node.Left = Nil),
-            Right_Done =>
-              (case Direction is
-               when Ascending => Node.Right = Nil,
-               when Descending | Unknown => True));
-      end if;
-   end Find;
-
-   function Find_In_Range
-     (Iterator    : in Pkg.Iterator;
-      Direction   : in Known_Direction_Type;
-      First, Last : in Key_Type)
-     return Cursor
-   is
-      Nil       : Node_Access renames Iterator.Nil;
-      Node      : Node_Access := Iterator.Root;
-      Candidate : Node_Access := null; -- best result found so far
-   begin
-      while Node /= Nil loop
-         declare
-            Current_Key : Key_Type renames Key (Node.Element);
-         begin
-            case Direction is
-            when Ascending =>
-               case Key_Compare (First, Current_Key) is
-               when Equal =>
-                     return (Node, Ascending, Right_Done => False, Left_Done 
=> True);
-
-               when Less =>
-                  if Node.Left = Nil then
-                     case Key_Compare (Current_Key, Last) is
-                     when Less | Equal =>
-                        return (Node, Ascending, Right_Done => False, 
Left_Done => True);
-                     when Greater =>
-                        if Candidate = null then
-                           return No_Element;
-                        else
-                           return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                        end if;
-                     end case;
-                  else
-                     case Key_Compare (Last, Current_Key) is
-                     when Greater | Equal =>
-                        Candidate := Node;
-                     when Less =>
-                        null;
-                     end case;
-                     Node := Node.Left;
-                  end if;
-
-               when Greater =>
-                  if Node.Right = Nil then
-                     if Candidate = null then
-                        return No_Element;
-                     else
-                        return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                     end if;
-                  else
-                     Node := Node.Right;
-                  end if;
-               end case;
-
-            when Descending =>
-               if Last = Current_Key then
-                  return (Node, Descending, Right_Done => True, Left_Done => 
False);
-
-               else
-                  case Key_Compare (Last, Current_Key) is
-                  when Greater =>
-                     if Node.Right = Nil then
-                        case Key_Compare (Current_Key, First) is
-                        when Greater | Equal =>
-                           return (Node, Descending, Right_Done => True, 
Left_Done => False);
-                        when Less =>
-                           if Candidate = null then
-                              return No_Element;
-                           else
-                              return (Candidate, Ascending, Right_Done => 
False, Left_Done => True);
-                           end if;
-                        end case;
-                     else
-                        case Key_Compare (First, Current_Key) is
-                        when Less | Equal =>
-                           Candidate := Node;
-                        when Greater =>
-                           null;
-                        end case;
-                        Node := Node.Right;
-                     end if;
-                  when Equal | Less =>
-                     if Node.Left = Nil then
-                        if Candidate = null then
-                           return No_Element;
-                        else
-                           return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                        end if;
-                     else
-                        Node := Node.Left;
-                     end if;
-                  end case;
-               end if;
-            end case;
-         end;
-      end loop;
-
-      return No_Element;
-   end Find_In_Range;
-
-   function Count (Tree : in Pkg.Tree) return Ada.Containers.Count_Type
-   is begin
-      if Tree.Root = Tree.Nil then
-         return 0;
-      else
-         return Count_Tree (Tree.Root, Tree.Nil);
-      end if;
-   end Count;
-
-   function Present (Container : in Tree; Key : in Key_Type) return Boolean
-   is
-      Nil  : Node_Access renames Container.Nil;
-      Node : Node_Access := Container.Root;
-   begin
-      while Node /= Nil loop
-         case Key_Compare (Key, Pkg.Key (Node.Element)) is
-         when Equal =>
-            return True;
-         when Less =>
-            Node := Node.Left;
-         when Greater =>
-            Node := Node.Right;
-         end case;
-      end loop;
-      return False;
-   end Present;
-
-   function Insert (Tree : in out Pkg.Tree; Element : in Element_Type) return 
Cursor
-   is
-      --  [1] 13.3 RB-Insert (T, z)
-      Nil   : Node_Access renames Tree.Nil;
-      Z     : Node_Access       := new Node'(Element, Nil, Nil, Nil, Red);
-      Key_Z : constant Key_Type := Key (Z.Element);
-      Y     : Node_Access       := Nil;
-      X     : Node_Access       := Tree.Root;
-
-      Result      : Node_Access;
-      Compare_Z_Y : Compare_Result;
-   begin
-      Nil.Parent := null;
-      Nil.Left   := null;
-      Nil.Right  := null;
-
-      while X /= Nil loop
-         Y := X;
-         Compare_Z_Y := Key_Compare (Key_Z, Key (X.Element));
-         case Compare_Z_Y is
-         when Less =>
-            X := X.Left;
-         when Equal | Greater =>
-            X := X.Right;
-         end case;
-      end loop;
-
-      Z.Parent := Y;
-      if Y = Nil then
-         Tree.Root := Z;
-      else
-         case Compare_Z_Y is
-         when Less =>
-            Y.Left := Z;
-         when Equal | Greater =>
-            Y.Right := Z;
-         end case;
-      end if;
-
-      Result := Z;
-      if Z = Tree.Root then
-         Z.Color := Black;
-      else
-         Insert_Fixup (Tree, Z);
-      end if;
-
-      return
-        (Node       => Result,
-         Direction  => Unknown,
-         Left_Done  => True,
-         Right_Done => True);
-   end Insert;
-
-   procedure Insert (Tree : in out Pkg.Tree; Element : in Element_Type)
-   is
-      Temp : Cursor := Insert (Tree, Element);
-      pragma Unreferenced (Temp);
-   begin
-      null;
-   end Insert;
-
-   procedure Delete (Tree : in out Pkg.Tree; Position : in out Cursor)
-   is
-      Nil          : Node_Access renames Tree.Nil;
-      T            : Pkg.Tree renames Tree;
-      Z            : constant Node_Access :=
-        (if Position.Node = null then raise Parameter_Error else 
Position.Node);
-      Y            : Node_Access          := Z;
-      Y_Orig_Color : Color                := Y.Color;
-      X            : Node_Access;
-   begin
-      --  Catch logic errors in use of Nil
-      Nil.Parent := null;
-      Nil.Left   := null;
-      Nil.Right  := null;
-
-      --  [1] 13.4 RB-Delete.
-      if Z.Left = Nil then
-         X := Z.Right;
-         Transplant (T, Z, Z.Right);
-
-      elsif Z.Right = Nil then
-         X := Z.Left;
-         Transplant (T, Z, Z.Left);
-
-      else
-         Y            := Minimum (Z.Right, Nil);
-         Y_Orig_Color := Y.Color;
-         X            := Y.Right;
-         if Y.Parent = Z then
-            X.Parent := Y;
-            --  This is already true unless X = Nil, in which case delete_fixup
-            --  needs the info.
-         else
-            Transplant (T, Y, Y.Right);
-            Y.Right := Z.Right;
-
-            Y.Right.Parent := Y;
-            --  This is already true unless Y.Right = Nil, in which case
-            --  delete_fixup needs the info.
-         end if;
-
-         Transplant (T, Z, Y);
-         Y.Left := Z.Left;
-
-         Y.Left.Parent := Y;
-         --  This is already true unless Y.Left = Nil, in which case
-         --  delete_fixup needs the info.
-
-         Y.Color := Z.Color;
-      end if;
-
-      if Y_Orig_Color = Black then
-         Delete_Fixup (T, X);
-      end if;
-
-      Free (Position.Node);
-   end Delete;
-
-end SAL.Gen_Unbounded_Definite_Red_Black_Trees;
diff --git a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads 
b/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads
deleted file mode 100644
index f886ed9..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads
+++ /dev/null
@@ -1,198 +0,0 @@
---  Abstract :
---
---  Generic unbounded red-black tree with definite elements, definite
---  or indefinite key.
---
---  References :
---
---  [1] Introduction to Algorithms, Thomas H. Cormen, Charles E.
---  Leiserson, Ronald L. Rivest, Clifford Stein.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   type Key_Type (<>) is private;
-   with function Key (Element : in Element_Type) return Key_Type is <>;
-   with function Key_Compare (Left, Right : in Key_Type) return Compare_Result 
is <>;
-package SAL.Gen_Unbounded_Definite_Red_Black_Trees is
-
-   package Pkg renames Gen_Unbounded_Definite_Red_Black_Trees;
-
-   type Tree is new Ada.Finalization.Limited_Controlled with private
-   with
-     Constant_Indexing => Constant_Reference,
-     Variable_Indexing => Variable_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   overriding procedure Finalize (Object : in out Tree);
-   overriding procedure Initialize (Object : in out Tree);
-
-   type Direction_Type is (Ascending, Descending, Unknown);
-   subtype Known_Direction_Type is Direction_Type range Ascending .. 
Descending;
-   --  Direction of Iterators.
-   --  If Ascending, Next may be called.
-   --  If Descending, Previous may be called.
-   --  If Unknown, neither.
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Cursor : in Pkg.Cursor) return Boolean;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Constant_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Constant_Reference_Type with
-     Inline;
-   --  Raises Not_Found if Key not found in Container.
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Variable_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Variable_Reference_Type with
-     Inline;
-   --  Raises Not_Found if Key not found in Container.
-
-   package Iterators is new Ada.Iterator_Interfaces (Cursor, Has_Element);
-
-   type Iterator is new Iterators.Reversible_Iterator with private;
-
-   function Iterate (Tree : in Pkg.Tree'Class) return Iterator;
-
-   overriding function First (Iterator : in Pkg.Iterator) return Cursor;
-   overriding function Next (Iterator : in Pkg.Iterator; Position : in Cursor) 
return Cursor;
-   overriding function Last (Iterator : in Pkg.Iterator) return Cursor;
-   overriding function Previous (Iterator : in Pkg.Iterator; Position : in 
Cursor) return Cursor;
-
-   function Previous (Iterator : in Pkg.Iterator; Key : in Key_Type) return 
Cursor;
-   --  Initialise Iterator to descending, starting at element with
-   --  largest key < Key. Has_Element (result) is False if there is no
-   --  such element.
-
-   function Find
-     (Iterator  : in Pkg.Iterator;
-      Key       : in Key_Type;
-      Direction : in Direction_Type := Ascending)
-     return Cursor;
-   --  Has_Element is False if Key is not in Container.
-
-   function Find_In_Range
-     (Iterator    : in Pkg.Iterator;
-      Direction   : in Known_Direction_Type;
-      First, Last : in Key_Type)
-     return Cursor;
-   --  Find first element with key in range First .. Last. If Direction
-   --  is Ascending, start at First, otherwise start at Last.
-   --
-   --  Has_Element (result) is False if there is no such element.
-   --
-   --  The Iterator does not remember First, Last; the user must check
-   --  those for any element that Next or Previous returns.
-
-   function Count (Tree : in Pkg.Tree) return Ada.Containers.Count_Type;
-
-   function Present (Container : in Tree; Key : in Key_Type) return Boolean;
-
-   procedure Insert (Tree : in out Pkg.Tree; Element : in Element_Type);
-   function Insert (Tree : in out Pkg.Tree; Element : in Element_Type) return 
Cursor;
-   --  Result points to newly inserted element.
-
-   procedure Delete (Tree : in out Pkg.Tree; Position : in out Cursor);
-   --  Delete element at Position, set Position to No_Element.
-private
-
-   type Node;
-   type Node_Access is access Node;
-
-   type Color is (Red, Black);
-
-   type Node is record
-      Element : aliased Element_Type;
-      Parent  : Node_Access;
-      Left    : Node_Access;
-      Right   : Node_Access;
-      Color   : Pkg.Color;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
-
-   type Tree is new Ada.Finalization.Limited_Controlled with record
-      Root : Node_Access;
-      Nil  : Node_Access;
-      --  Nil is the node pointed to by all links that would otherwise be
-      --  'null'. This simplifies several algorithm (for example,
-      --  Node.Left.Color is always valid). Its parent, left, right links
-      --  are used as temp storage for some algorithms (especially Delete).
-      --  Nil.Color is Black.
-   end record;
-
-   type Cursor is record
-      Node : Node_Access := null;
-
-      Direction  : Direction_Type := Unknown;
-      --  Set in First or Last, enforced in next/prev (cannot change 
direction).
-
-      Left_Done  : Boolean := True;
-      Right_Done : Boolean := True;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   No_Element : constant Cursor :=
-     (Node       => null,
-      Direction  => Unknown,
-      Left_Done  => True,
-      Right_Done => True);
-
-   type Iterator is new Iterators.Reversible_Iterator with
-   record
-      Root : Node_Access;
-      Nil  : Node_Access;
-   end record;
-
-end SAL.Gen_Unbounded_Definite_Red_Black_Trees;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb
deleted file mode 100644
index c4b52a6..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type :=
-     (if Depth = 0
-      then Item.Top
-      else Base_Peek_Type'Min (Depth, Item.Top));
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads
deleted file mode 100644
index 801ffd3..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads
+++ /dev/null
@@ -1,27 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks.adb 
b/packages/wisi/sal-gen_unbounded_definite_stacks.adb
deleted file mode 100644
index 072c104..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks.adb
+++ /dev/null
@@ -1,219 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 1998, 2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied
---  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---  See the GNU General Public License for more details. You should
---  have received a copy of the GNU General Public License distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce an
---  executable, that does not by itself cause the resulting executable
---  to be covered by the GNU General Public License. This exception
---  does not however invalidate any other reasons why the executable
---  file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Stacks is
-
-   ----------
-   --  local subprogram bodies
-
-   procedure Grow (Stack : in out Sguds.Stack; Desired_Size : in 
Base_Peek_Type)
-   is
-      New_Data : constant Element_Array_Access := new Element_Array (1 .. 
Desired_Size);
-   begin
-      New_Data (1 .. Stack.Top) := Stack.Data (1 .. Stack.Top);
-      Free (Stack.Data);
-      Stack.Data := New_Data;
-   end Grow;
-
-   ----------
-   --  Spec visible subprograms
-   overriding procedure Finalize (Stack : in out Sguds.Stack)
-   is begin
-      if Stack.Data /= null then
-         Free (Stack.Data);
-         Stack.Top := Invalid_Peek_Index;
-      end if;
-   end Finalize;
-
-   overriding procedure Adjust (Stack : in out Sguds.Stack)
-   is begin
-      if Stack.Data /= null then
-         Stack.Data := new Element_Array'(Stack.Data.all);
-      end if;
-   end Adjust;
-
-   overriding
-   function "=" (Left, Right : in Sguds.Stack) return Boolean
-   is begin
-      if Left.Data = null then
-         return Right.Data = null;
-      elsif Left.Top /= Right.Top then
-         return False;
-      else
-         --  Assume stacks differ near top.
-         for I in reverse 1 .. Left.Top loop
-            if Left.Data (I) /= Right.Data (I) then
-               return False;
-            end if;
-         end loop;
-         return True;
-      end if;
-   end "=";
-
-   procedure Clear (Stack : in out Sguds.Stack)
-   is begin
-      --  We don't change the reserved capacity, on the assumption the
-      --  stack will be used again.
-      Stack.Top := 0;
-   end Clear;
-
-   function Depth (Stack : in Sguds.Stack) return Base_Peek_Type
-   is begin
-      return Stack.Top;
-   end Depth;
-
-   function Is_Empty (Stack : in Sguds.Stack) return Boolean
-   is begin
-      return Stack.Top = 0;
-   end Is_Empty;
-
-   function Peek
-     (Stack : in Sguds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type
-   is begin
-      return Stack.Data (Stack.Top - Index + 1);
-   end Peek;
-
-   procedure Pop (Stack : in out Sguds.Stack; Count : in Base_Peek_Type := 1)
-   is begin
-      if Stack.Top < Count then
-         raise Container_Empty;
-      else
-         Stack.Top := Stack.Top - Count;
-      end if;
-   end Pop;
-
-   function Pop (Stack : in out Sguds.Stack) return Element_Type
-   is begin
-      if Stack.Top = 0 then
-         raise Container_Empty;
-      else
-         return Result : constant Element_Type := Stack.Peek (1)
-         do
-            Stack.Top := Stack.Top - 1;
-         end return;
-      end if;
-   end Pop;
-
-   procedure Push (Stack : in out Sguds.Stack; Item : in Element_Type)
-   is begin
-      if Stack.Data = null then
-         --  Adding a generic parameter for a reasonably large default initial
-         --  size here makes Wisitoken McKenzie recover slightly slower,
-         --  presumably due to increased cache thrashing.
-         Stack.Data := new Element_Array (1 .. 2);
-      elsif Stack.Top = Stack.Data'Last then
-         Grow (Stack, Desired_Size => 2 * Stack.Data'Last);
-      end if;
-      Stack.Top := Stack.Top + 1;
-      Stack.Data (Stack.Top) := Item;
-   end Push;
-
-   function Top (Stack : in Sguds.Stack) return Element_Type
-   is begin
-      if Stack.Top < 1 then
-         raise SAL.Container_Empty;
-      else
-         return Peek (Stack, 1);
-      end if;
-   end Top;
-
-   procedure Set_Depth
-     (Stack : in out Sguds.Stack;
-      Depth : in     Peek_Type)
-   is begin
-      if Stack.Data = null then
-         Stack.Data := new Element_Array (1 .. 2 * Depth);
-      elsif Depth > Stack.Data'Last then
-         Grow (Stack, Desired_Size => 2 * Depth);
-      end if;
-   end Set_Depth;
-
-   procedure Set
-     (Stack   : in out Sguds.Stack;
-      Index   : in     Peek_Type;
-      Depth   : in     Peek_Type;
-      Element : in     Element_Type)
-   is begin
-      --  Same Position algorithm as in Peek
-      Stack.Top := Depth;
-      Stack.Data (Depth - Index + 1) := Element;
-   end Set;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Peek_Type)
-     return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Data (Container.Top - Position + 1)'Access,
-         Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Data (Container.Top - Position.Ptr + 1)'Access,
-         Dummy => 1);
-   end Constant_Reference;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Container.Depth >= Position.Ptr;
-   end Has_Element;
-
-   type Iterator (Container : not null access constant Stack) is new 
Iterator_Interfaces.Forward_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   function Iterate (Container : aliased in Stack) return 
Iterator_Interfaces.Forward_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return (Object.Container, 1);
-   end First;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return (Position.Container, Position.Ptr + 1);
-   end Next;
-
-end SAL.Gen_Unbounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks.ads 
b/packages/wisi/sal-gen_unbounded_definite_stacks.ads
deleted file mode 100644
index 3d1e1e7..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks.ads
+++ /dev/null
@@ -1,158 +0,0 @@
---  Abstract:
---
---  Stack implementation.
---
---  Copyright (C) 1998-2000, 2002-2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied
---  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---  See the GNU General Public License for more details. You should
---  have received a copy of the GNU General Public License distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-package SAL.Gen_Unbounded_Definite_Stacks is
-
-   package Sguds renames SAL.Gen_Unbounded_Definite_Stacks;
-
-   type Stack is new Ada.Finalization.Controlled with private
-   with
-     Constant_Indexing => Constant_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   Empty_Stack : constant Stack;
-
-   overriding procedure Finalize (Stack : in out Sguds.Stack);
-   overriding procedure Adjust (Stack : in out Sguds.Stack);
-
-   overriding function "=" (Left, Right : in Sguds.Stack) return Boolean;
-
-   procedure Clear (Stack : in out Sguds.Stack);
-   --  Empty Stack of all items.
-
-   function Depth (Stack : in Sguds.Stack) return Base_Peek_Type;
-   --  Returns current count of items in the Stack
-
-   function Is_Empty (Stack : in Sguds.Stack) return Boolean;
-   --  Returns true iff no items are in Stack.
-
-   function Peek
-     (Stack : in Sguds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type with Inline;
-   --  Return the Index'th item from the top of Stack; the Item is _not_ 
removed.
-   --  Top item has index 1.
-   --
-   --  Raises Constraint_Error if Index > Depth.
-   --
-   --  See also Constant_Ref, implicit indexing
-
-   procedure Pop (Stack : in out Sguds.Stack; Count : in Base_Peek_Type := 1);
-   --  Remove Count Items from the top of Stack, discard them.
-   --
-   --  Raises Container_Empty if there are fewer than Count items on
-   --  Stack.
-
-   function Pop (Stack : in out Sguds.Stack) return Element_Type;
-   --  Remove Item from the top of Stack, and return it.
-   --
-   --  Raises Container_Empty if Is_Empty.
-
-   procedure Push (Stack : in out Sguds.Stack; Item : in Element_Type);
-   --  Add Item to the top of Stack.
-   --
-   --  May raise Container_Full.
-
-   function Top (Stack : in Sguds.Stack) return Element_Type;
-   --  Return the item at the top of Stack; the Item is _not_ removed.
-   --  Same as Peek (Stack, 1).
-   --
-   --  Raises Container_Empty if Is_Empty.
-
-   procedure Set_Depth
-     (Stack : in out Sguds.Stack;
-      Depth : in     Peek_Type);
-   --  Empty Stack, set its Depth to Depth. Must be followed by Set
-   --  for each element.
-   --
-   --  Useful when creating a stack from pre-existing data.
-
-   procedure Set
-     (Stack   : in out Sguds.Stack;
-      Index   : in     Peek_Type;
-      Depth   : in     Peek_Type;
-      Element : in     Element_Type);
-   --  Set a Stack element. Index is the same as Peek Index; Depth is
-   --  used to compute the index in the underlying array.
-   --
-   --  Stack must have been initialized by Set_Depth.
-   --
-   --  Useful when creating a stack from pre-existing data.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Peek_Type)
-     return Constant_Reference_Type
-   with Inline, Pre => Position in 1 .. Container.Depth;
-
-   type Cursor (<>) is private;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Stack) return 
Iterator_Interfaces.Forward_Iterator'Class;
-
-private
-
-   type Element_Array is array (Peek_Type range <>) of aliased Element_Type;
-   type Element_Array_Access is access Element_Array;
-   procedure Free is new Ada.Unchecked_Deallocation (Element_Array, 
Element_Array_Access);
-
-   type Stack is new Ada.Finalization.Controlled with record
-      Top  : Base_Peek_Type := Invalid_Peek_Index; -- empty
-      Data : Element_Array_Access;
-
-      --  Top of stack is at Data (Top).
-      --  Data (1 .. Top) has been set at some point.
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Stack : constant Stack := (Ada.Finalization.Controlled with 
Invalid_Peek_Index, null);
-
-   type Cursor (Container : not null access constant Stack) is
-   record
-      Ptr : Peek_Type;
-   end record;
-
-end SAL.Gen_Unbounded_Definite_Stacks;
diff --git 
a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb
deleted file mode 100644
index 16c1fe8..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb
+++ /dev/null
@@ -1,73 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable is
-
-   function Compare (Left, Right : in Vector) return Compare_Result
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Left.Length = 0 then
-         if Right.Length = 0 then
-            return Equal;
-         else
-            --  null is less than non-null
-            return Less;
-         end if;
-
-      elsif Right.Length = 0 then
-         return Greater;
-
-      else
-         declare
-            I : Base_Peek_Type := To_Peek_Type (Left.First);
-            J : Base_Peek_Type := To_Peek_Type (Right.First);
-
-            Left_Last  : constant Base_Peek_Type := To_Peek_Type (Left.Last);
-            Right_Last : constant Base_Peek_Type := To_Peek_Type (Right.Last);
-         begin
-            loop
-               exit when I > Left_Last or J > Right_Last;
-
-               case Element_Compare (Left.Elements (I), Right.Elements (J)) is
-               when Less =>
-                  return Less;
-               when Equal =>
-                  I := I + 1;
-                  J := J + 1;
-               when Greater =>
-                  return Greater;
-               end case;
-            end loop;
-            if I > Left_Last then
-               if J > Right_Last then
-                  return Equal;
-               else
-                  --  right is longer
-                  return Less;
-               end if;
-            else
-               --  left is longer
-               return Greater;
-            end if;
-         end;
-      end if;
-   end Compare;
-
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable;
diff --git 
a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads
deleted file mode 100644
index 56d84c0..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads
+++ /dev/null
@@ -1,30 +0,0 @@
---  Abstract :
---
---  Add "<" to parent
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-package SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable is
-
-   type Vector is new SAL.Gen_Unbounded_Definite_Vectors.Vector with null 
record;
-
-   function Compare (Left, Right : in Vector) return Compare_Result;
-   --  Similar to Ada "<" for arrays; Ada Reference Manual
-   --  section 4.5.2 para 26/3.
-
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb
deleted file mode 100644
index 929994a..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image (Item : in Vector; 
Strict : in Boolean := False) return String
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings;
-   use Ada.Strings.Fixed;
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   First  : constant Base_Peek_Type := To_Peek_Type (Item.First_Index);
-   Last   : constant Base_Peek_Type := To_Peek_Type (Item.Last_Index);
-begin
-   if Strict and Item.Length = 0 then
-      return "(" & Trim (Index_Type'Image (Index_Type'First), Left) & " .. " &
-        Trim (Index_Type'Image (Extended_Index'First), Left) & " => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(" & Trim (Index_Type'Image (Index_Type'First), Left) & " => " &
-        Element_Image (Item.Elements (First)) & ")";
-
-   else
-      for I in First .. Last loop
-         Result := Result & Element_Image (Item.Elements (I));
-         if I /= Last then
-            Result := Result & ", ";
-         end if;
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Image;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads
deleted file mode 100644
index 274e1f1..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image (Item : in Vector; 
Strict : in Boolean := False) return String;
---  Image of Item, in Ada aggregate syntax. If Strict, use correct
---  syntax for 0 and 1 item; otherwise, use () and (item).
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb
deleted file mode 100644
index e0d90a6..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb
+++ /dev/null
@@ -1,43 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2019 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux
-  (Item        : in Vector;
-   Aux         : in Aux_Data;
-   Association : in Boolean := False)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   First  : constant Base_Peek_Type := To_Peek_Type (Item.First_Index);
-   Last   : constant Base_Peek_Type := To_Peek_Type (Item.Last_Index);
-begin
-   for I in First .. Last loop
-      if Association then
-         Result := Result & Index_Trimmed_Image (To_Index_Type (I)) & " => ";
-      end if;
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads
deleted file mode 100644
index eb8a89a..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 - 2019 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Index_Trimmed_Image (Item : in Index_Type) return String;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux
-  (Item        : in Vector;
-   Aux         : in Aux_Data;
-   Association : in Boolean := False)
-  return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors.adb
deleted file mode 100644
index 9e1c189..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors.adb
+++ /dev/null
@@ -1,585 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors is
-
-   function To_Peek_Type (Item : in Extended_Index) return Base_Peek_Type
-   is begin
-      return Base_Peek_Type'Base (Item - Index_Type'First) + Peek_Type'First;
-   end To_Peek_Type;
-
-   function To_Index_Type (Item : in Base_Peek_Type) return Extended_Index
-   is begin
-      return Extended_Index (Item - Peek_Type'First) + Index_Type'First;
-   end To_Index_Type;
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type)
-   is
-      --  Reallocate Elements so Elements (Index) is a valid element.
-
-      Old_First  : constant Peek_Type := Elements'First;
-      Old_Last   : constant Peek_Type := Elements'Last;
-      New_First  : Peek_Type          := Old_First;
-      New_Last   : Peek_Type          := Old_Last;
-      New_Length : Peek_Type          := Elements'Length;
-
-      New_Array : Array_Access;
-   begin
-      loop
-         exit when New_First <= Index;
-         New_Length := New_Length * 2;
-         New_First  := Peek_Type'Max (Peek_Type'First, Old_Last - New_Length + 
1);
-      end loop;
-      loop
-         exit when New_Last >= Index;
-         New_Length := New_Length * 2;
-         New_Last   := Peek_Type'Min (Peek_Type'Last, New_First + New_Length - 
1);
-      end loop;
-
-      New_Array := new Array_Type (New_First .. New_Last);
-
-      --  We'd like to use this:
-      --
-      --  New_Array (New_First .. Old_First - 1) := (others => <>);
-      --
-      --  but that can overflow the stack, since the aggregate is allocated
-      --  on the stack.
-
-      for I in New_First .. Old_First - 1 loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      New_Array (Old_First .. Old_Last) := Elements.all;
-
-      for I in Old_Last + 1 .. New_Last loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      Free (Elements);
-      Elements := New_Array;
-   end Grow;
-
-   ----------
-   --  public subprograms
-
-   overriding procedure Finalize (Container : in out Vector)
-   is begin
-      Free (Container.Elements);
-      Container.First := No_Index;
-      Container.Last  := No_Index;
-   end Finalize;
-
-   overriding procedure Adjust (Container : in out Vector)
-   is begin
-      if Container.Elements /= null then
-         Container.Elements := new Array_Type'(Container.Elements.all);
-      end if;
-   end Adjust;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      --  We assume the type ranges are sensible, so no exceptions occur
-      --  here.
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (To_Peek_Type (Container.Last) - 
Container.Elements'First + 1);
-      end if;
-   end Length;
-
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Elements'Length);
-      end if;
-   end Capacity;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index)
-   is
-      First_Peek : constant Peek_Type := To_Peek_Type (First);
-      Last_Peek  : constant Peek_Type := To_Peek_Type (Last);
-   begin
-      if Container.Elements = null then
-         Container.Elements := new Array_Type (First_Peek .. Last_Peek);
-      else
-         if First_Peek < Container.Elements'First then
-            Grow (Container.Elements, First_Peek);
-         end if;
-         if Last_Peek < Container.Elements'Last then
-            Grow (Container.Elements, Last_Peek);
-         end if;
-      end if;
-   end Set_Capacity;
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   is begin
-      return Container.Elements (To_Peek_Type (Index));
-   end Element;
-
-   procedure Replace_Element (Container : Vector; Index : Index_Type; New_Item 
: in Element_Type)
-   is begin
-      Container.Elements (To_Peek_Type (Index)) := New_Item;
-   end Replace_Element;
-
-   function First_Index (Container : Vector) return Extended_Index
-   is begin
-      if Container.First = No_Index then
-         return No_Index + 1;
-      else
-         return Container.First;
-      end if;
-   end First_Index;
-
-   function Last_Index (Container : Vector) return Extended_Index
-   is begin
-      return Container.Last;
-   end Last_Index;
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type)
-   is begin
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Container.Last  := Index_Type'First;
-      else
-         Container.Last := Container.Last + 1;
-      end if;
-
-      declare
-         J : constant Base_Peek_Type := To_Peek_Type (Container.Last);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (J .. J);
-
-         elsif J > Container.Elements'Last then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (J) := New_Item;
-      end;
-   end Append;
-
-   procedure Append (Container : in out Vector; New_Items : in Vector)
-   is
-      use all type Ada.Containers.Count_Type;
-      Old_Last : Extended_Index := Container.Last;
-   begin
-      if New_Items.Length = 0 then
-         return;
-      end if;
-
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Old_Last        := Container.First - 1;
-         Container.Last  := Container.First + Extended_Index 
(New_Items.Length) - 1;
-      else
-         Container.Last := Container.Last + Extended_Index (New_Items.Length);
-      end if;
-
-      declare
-         I : constant Peek_Type := To_Peek_Type (Old_Last + 1);
-         J : constant Peek_Type := To_Peek_Type (Container.Last);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (I .. J);
-         elsif J > Container.Elements'Last then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (I .. J) := New_Items.Elements
-           (To_Peek_Type (New_Items.First) .. To_Peek_Type (New_Items.Last));
-      end;
-   end Append;
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type)
-   is begin
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Container.Last  := Index_Type'First;
-      else
-         Container.First := Container.First - 1;
-      end if;
-
-      declare
-         J : constant Peek_Type := To_Peek_Type (Container.First);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (J .. J);
-
-         elsif J < Container.Elements'First then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (J) := New_Item;
-      end;
-   end Prepend;
-
-   procedure Prepend
-     (Target       : in out Vector;
-      Source       : in     Vector;
-      Source_First : in     Index_Type;
-      Source_Last  : in     Index_Type)
-   is
-      Source_I : constant Peek_Type := To_Peek_Type (Source_First);
-      Source_J : constant Peek_Type := To_Peek_Type (Source_Last);
-   begin
-      if Target.Elements = null then
-         Target.Elements := new Array_Type'(Source.Elements (Source_I .. 
Source_J));
-         Target.First    := Source_First;
-         Target.Last     := Source_Last;
-      else
-         declare
-            New_First : constant Index_Type := Target.First - (Source_Last - 
Source_First + 1);
-            I         : constant Peek_Type  := To_Peek_Type (New_First);
-            J         : constant Peek_Type  := To_Peek_Type (Target.First - 1);
-         begin
-            if Target.Elements'First > I then
-               Grow (Target.Elements, I);
-            end if;
-            Target.Elements (I .. J) := Source.Elements (Source_I .. Source_J);
-            Target.First := New_First;
-         end;
-      end if;
-   end Prepend;
-
-   procedure Insert
-     (Container : in out Vector;
-      Element   : in     Element_Type;
-      Before    : in     Index_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         Container.Append (Element);
-      else
-         Container.Last := Container.Last + 1;
-
-         declare
-            J : constant Peek_Type := To_Peek_Type (Before);
-            K : constant Base_Peek_Type := To_Peek_Type (Container.Last);
-         begin
-            if K > Container.Elements'Last then
-               Grow (Container.Elements, K);
-            end if;
-
-            Container.Elements (J + 1 .. K) := Container.Elements (J .. K - 1);
-            Container.Elements (J) := Element;
-         end;
-      end if;
-   end Insert;
-
-   procedure Merge
-     (Target : in out Vector;
-      Source : in out Vector)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Source.Length = 0 then
-         Source.Clear;
-
-      elsif Target.Length = 0 then
-         Target := Source;
-         Source.Clear;
-
-      else
-         declare
-            New_First : constant Index_Type := Extended_Index'Min 
(Target.First, Source.First);
-            New_Last  : constant Index_Type := Extended_Index'Max 
(Target.Last, Source.Last);
-            New_I     : constant Peek_Type  := To_Peek_Type (New_First);
-            New_J     : constant Base_Peek_Type  := To_Peek_Type (New_Last);
-         begin
-            if New_I < Target.Elements'First then
-               Grow (Target.Elements, New_I);
-            end if;
-            if New_J > Target.Elements'Last then
-               Grow (Target.Elements, New_J);
-            end if;
-
-            Target.Elements (To_Peek_Type (Source.First) .. To_Peek_Type 
(Source.Last)) := Source.Elements
-              (To_Peek_Type (Source.First) .. To_Peek_Type (Source.Last));
-
-            Target.First := New_First;
-            Target.Last  := New_Last;
-
-            Source.Clear;
-         end;
-      end if;
-   end Merge;
-
-   function To_Vector (Item : in Element_Type; Count : in 
Ada.Containers.Count_Type := 1) return Vector
-   is begin
-      return Result : Vector do
-         for I in 1 .. Count loop
-            Result.Append (Item);
-         end loop;
-      end return;
-   end To_Vector;
-
-   function "+" (Element : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Append (Element);
-      end return;
-   end "+";
-
-   function "&" (Left, Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Append (Left);
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector := Left do
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   procedure Set_First (Container : in out Vector; First : in Index_Type)
-   is
-      J : constant Peek_Type := To_Peek_Type (First);
-   begin
-      Container.First := First;
-      if Container.Last = No_Index then
-         Container.Last := First - 1;
-      end if;
-
-      if Container.Last >= First then
-         if Container.Elements = null then
-            Container.Elements := new Array_Type'(J .. To_Peek_Type 
(Container.Last) => Default_Element);
-
-         elsif Container.Elements'First > J then
-            Grow (Container.Elements, J);
-         end if;
-      end if;
-   end Set_First;
-
-   procedure Set_Last (Container : in out Vector; Last : in Extended_Index)
-   is
-      J : constant Base_Peek_Type := To_Peek_Type (Last);
-   begin
-      Container.Last := Last;
-      if Container.First = No_Index then
-         Container.First := Last + 1;
-      end if;
-
-      if Last >= Container.First then
-         if Container.Elements = null then
-            Container.Elements := new Array_Type'(To_Peek_Type 
(Container.First) .. J => Default_Element);
-
-         elsif Container.Elements'Last < J then
-            Grow (Container.Elements, J);
-         end if;
-      end if;
-   end Set_Last;
-
-   procedure Set_First_Last
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index)
-   is begin
-      Set_First (Container, First);
-      Set_Last (Container, Last);
-   end Set_First_Last;
-
-   procedure Delete (Container : in out Vector; Index : in Index_Type)
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      Container.Elements (J .. J) := (J => <>);
-      if Index = Container.Last then
-         Container.Last := Container.Last - 1;
-      end if;
-   end Delete;
-
-   function Contains (Container : in Vector; Element : in Element_Type) return 
Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         return False;
-      else
-         for It of Container.Elements.all loop
-            if It = Element then
-               return True;
-            end if;
-         end loop;
-         return False;
-      end if;
-   end Contains;
-
-   function Element (Position : Cursor) return Element_Type
-   is begin
-      return Position.Container.Elements (Position.Index);
-   end Element;
-
-   function First (Container : aliased in Vector) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         return (Container'Access, Invalid_Peek_Index);
-      else
-         return (Container'Access, To_Peek_Type (Container.First));
-      end if;
-   end First;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return (Position.Container, Invalid_Peek_Index);
-      elsif Position.Index < To_Peek_Type (Position.Container.Last) then
-         return (Position.Container, Position.Index + 1);
-      else
-         return (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Next;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         null;
-      elsif Position.Index < To_Peek_Type (Position.Container.Last) then
-         Position.Index := Position.Index + 1;
-      else
-         Position := (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Next;
-
-   function Prev (Position : in Cursor) return Cursor
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return (Position.Container, Invalid_Peek_Index);
-      elsif Position.Index > To_Peek_Type (Position.Container.First) then
-         return (Position.Container, Position.Index - 1);
-      else
-         return (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Prev;
-
-   procedure Prev (Position : in out Cursor)
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         null;
-      elsif Position.Index > To_Peek_Type (Position.Container.First) then
-         Position.Index := Position.Index - 1;
-      else
-         Position := (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Prev;
-
-   function To_Cursor
-     (Container : aliased in Vector;
-      Index     :         in Extended_Index)
-     return Cursor
-   is begin
-      return (Container'Access, To_Peek_Type (Index));
-   end To_Cursor;
-
-   function To_Index (Position : in Cursor) return Extended_Index
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return No_Index;
-      else
-         return To_Index_Type (Position.Index);
-      end if;
-   end To_Index;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Index_Type) 
return Constant_Reference_Type
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      return (Element => Container.Elements (J)'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Ref
-     (Container : aliased in Vector;
-      Index     :         in Index_Type)
-     return Variable_Reference_Type
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      return (Element => Container.Elements (J)'Access, Dummy => 1);
-   end Variable_Ref;
-
-   overriding function First (Object : Iterator) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Object.Container.Length = 0 then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, To_Peek_Type (Object.Container.First));
-      end if;
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Object.Container.Length = 0 then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, To_Peek_Type (Object.Container.Last));
-      end if;
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = To_Peek_Type (Object.Container.Last) then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, Position.Index + 1);
-      end if;
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = To_Peek_Type (Index_Type'First) then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, Position.Index - 1);
-      end if;
-   end Previous;
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Constant_Ref;
-
-   function Variable_Ref
-     (Container : aliased in Vector;
-      Position  :         in Cursor)
-     return Variable_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Variable_Ref;
-
-end SAL.Gen_Unbounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors.ads
deleted file mode 100644
index 29ecae0..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors.ads
+++ /dev/null
@@ -1,252 +0,0 @@
---  Abstract :
---
---  A simple unbounded vector of definite items, intended to be faster
---  than Ada.Containers.Vectors.
---
---  Prepend is as fast (in amortized time) as Append.
---
---  It provides no checking of cursor tampering; higher level code
---  must ensure that.
---
---  Design:
---
---  See ARM 3.10.2 "explicitly aliased" for why we need 'aliased' in
---  several subprogram argument modes, and why Container must be an
---  access discriminant in Cursor and Iterator.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Index_Type is range <>;
-   type Element_Type is private;
-   Default_Element : in Element_Type;
-package SAL.Gen_Unbounded_Definite_Vectors is
-
-   subtype Extended_Index is Index_Type'Base
-     range Index_Type'First - 1 ..
-           Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
-
-   No_Index : constant Extended_Index := Extended_Index'First;
-
-   type Vector is new Ada.Finalization.Controlled with private with
-     Constant_Indexing => Constant_Ref,
-     Variable_Indexing => Variable_Ref,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   Empty_Vector : constant Vector;
-
-   overriding procedure Finalize (Container : in out Vector);
-   overriding procedure Adjust (Container : in out Vector);
-
-   overriding function "=" (Left, Right : in Vector) return Boolean is
-     (raise Programmer_Error);
-   --  Use Gen_Comparable child.
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type;
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index);
-   --  Allocates memory, but does not change Container.First, Container.Last.
-
-   procedure Clear (Container : in out Vector)
-   renames Finalize;
-
-   function First_Index (Container : Vector) return Extended_Index;
-   --  No_Index + 1 when Container is empty, so "for I in C.First_Index
-   --  .. C.Last_Index loop" works.
-   --
-   --  If you need No_Index for an empty Container, use To_Index 
(Container.First).
-
-   function Last_Index (Container : Vector) return Extended_Index;
-   --  No_Index when Container is empty.
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   with Pre => Index >= Container.First_Index and Index <= 
Container.Last_Index;
-
-   procedure Replace_Element (Container : Vector; Index : Index_Type; New_Item 
: in Element_Type);
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type);
-   --  Insert New_Item at end of Container.
-   --
-   --  Raises Constraint_Error if index of new item would be greater than
-   --  Index_Type'Last.
-
-   procedure Append (Container : in out Vector; New_Items : in Vector);
-   --  Insert all elements of New_Items at end of Container.
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type);
-   --  Insert New_Item at beginning of Container.
-   --
-   --  Raises Constraint_Error if index of new item would be less than
-   --  Index_Type'First.
-
-   procedure Prepend
-     (Target       : in out Vector;
-      Source       : in     Vector;
-      Source_First : in     Index_Type;
-      Source_Last  : in     Index_Type);
-   --  Copy Source (Source_First .. Source_Last) to Target, before
-   --  Target.First_Index.
-
-   procedure Insert
-     (Container : in out Vector;
-      Element   : in     Element_Type;
-      Before    : in     Index_Type);
-   --  Existing elements at Before and after are slid to higher indices.
-
-   procedure Merge
-     (Target : in out Vector;
-      Source : in out Vector);
-   --  Copy all elements from Source to Target, to the same index range,
-   --  deleting them from Source, and overwriting overlapping ranges.
-
-   function To_Vector (Item : in Element_Type; Count : in 
Ada.Containers.Count_Type := 1) return Vector;
-
-   function "+" (Element : in Element_Type) return Vector;
-
-   function "&" (Left, Right : in Element_Type) return Vector;
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector;
-
-   procedure Set_First_Last
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index);
-   --  Elements in First .. Last that have not been set have
-   --  Default_Element value.
-
-   procedure Delete (Container : in out Vector; Index : in Index_Type);
-   --  Replace Index element contents with default. If Index =
-   --  Container.Last_Index, Container.Last_Index is decremented.
-
-   function Contains (Container : in Vector; Element : in Element_Type) return 
Boolean;
-   --  Return True if Element is in Container, False if not.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   with Inline, Pre => Index in Container.First_Index .. Container.Last_Index;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Variable_Reference_Type
-   with Inline, Pre => Index in Container.First_Index .. Container.Last_Index;
-
-   type Cursor (<>) is private;
-
-   function Has_Element (Position : Cursor) return Boolean;
-   function Element (Position : Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-   function First (Container : aliased in Vector) return Cursor;
-   function Next (Position : in Cursor) return Cursor;
-   procedure Next (Position : in out Cursor);
-   function Prev (Position : in Cursor) return Cursor;
-   procedure Prev (Position : in out Cursor);
-
-   function To_Cursor
-     (Container : aliased in Vector;
-      Index     :         in Extended_Index)
-     return Cursor
-   with Pre => Index = No_Index or Index in Container.First_Index .. 
Container.Last_Index;
-
-   function To_Index (Position : in Cursor) return Extended_Index;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-   function Constant_Ref (Container : aliased in Vector; Position : in Cursor) 
return Constant_Reference_Type
-   with Pre => Has_Element (Position) and then
-               To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-
-   function Variable_Ref (Container : aliased in Vector; Position  : in 
Cursor) return Variable_Reference_Type
-   with Pre => Has_Element (Position) and then
-               To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-   pragma Inline (Variable_Ref);
-
-private
-
-   type Array_Type is array (SAL.Peek_Type range <>) of aliased Element_Type;
-   type Array_Access is access Array_Type;
-   procedure Free is new Ada.Unchecked_Deallocation (Array_Type, Array_Access);
-
-   type Vector is new Ada.Finalization.Controlled with
-   record
-      Elements : Array_Access;
-      --  Elements may be non-null with First = No_Index, after
-      --  Set_Capacity. If First /= No_Index and Last >= First, Elements /=
-      --  null. First > Last means Vector is empty.
-      First    : Extended_Index := No_Index;
-      Last     : Extended_Index := No_Index;
-   end record;
-
-   type Vector_Access is access constant Vector;
-   for Vector_Access'Storage_Size use 0;
-
-   type Cursor (Container : not null access constant Vector) is
-   record
-      Index : Base_Peek_Type := Invalid_Peek_Index;
-   end record;
-
-   type Iterator (Container : not null access constant Vector) is new 
Iterator_Interfaces.Reversible_Iterator with
-     null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Vector : constant Vector := (Ada.Finalization.Controlled with others 
=> <>);
-
-   ----------
-   --  Visible for contracts/SPARK
-
-   function Has_Element (Position : Cursor) return Boolean
-     is (Position.Index /= Invalid_Peek_Index);
-
-   ----------
-   --  Visible for child package
-
-   function To_Peek_Type (Item : in Extended_Index) return Base_Peek_Type with 
Inline;
-   function To_Index_Type (Item : in Base_Peek_Type) return Extended_Index;
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type);
-
-end SAL.Gen_Unbounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb
deleted file mode 100644
index 8e40695..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb
+++ /dev/null
@@ -1,374 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors_Sorted is
-
-   ----------
-   --  Body subprograms, arbitrary order
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type)
-   is
-      --  Reallocate Elements so Elements (Index) is a valid element.
-
-      Old_First  : constant Peek_Type := Elements'First;
-      Old_Last   : constant Peek_Type := Elements'Last;
-      New_First  : Peek_Type          := Old_First;
-      New_Last   : Peek_Type          := Old_Last;
-      New_Length : Peek_Type          := Elements'Length;
-
-      New_Array : Array_Access;
-   begin
-      loop
-         exit when New_First <= Index;
-         New_Length := New_Length * 2;
-         New_First  := Peek_Type'Max (Peek_Type'First, Old_Last - New_Length + 
1);
-      end loop;
-      loop
-         exit when New_Last >= Index;
-         New_Length := New_Length * 2;
-         New_Last   := Peek_Type'Min (Peek_Type'Last, New_First + New_Length - 
1);
-      end loop;
-
-      New_Array := new Array_Type (New_First .. New_Last);
-
-      --  We'd like to use this:
-      --
-      --  New_Array (New_First .. Old_First - 1) := (others => <>);
-      --
-      --  but that can overflow the stack, since the aggregate is allocated
-      --  on the stack.
-
-      for I in New_First .. Old_First - 1 loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      New_Array (Old_First .. Old_Last) := Elements.all;
-
-      for I in Old_Last + 1 .. New_Last loop
-         New_Array (I .. I)   := (others => <>);
-      end loop;
-
-      Free (Elements);
-      Elements := New_Array;
-   end Grow;
-
-   procedure Find
-     (Container : in     Vector;
-      Key       : in     Key_Type;
-      Found     :    out Boolean;
-      At_After  :    out Base_Peek_Type)
-   with Pre => Container.Last /= No_Index
-   is
-      --  If Found is True, item is at At_After. If False, item should be
-      --  inserted after At_After.
-      Low  : Base_Peek_Type := Peek_Type'First - 1;
-      High : Base_Peek_Type := Container.Last + 1;
-      I    : Base_Peek_Type := Low + High / 2;
-   begin
-      loop
-         case Key_Compare (Key, To_Key (Container.Elements (I))) is
-         when Less =>
-            High := I;
-            if I = Low then
-               Found    := False;
-               At_After := I;
-               return;
-
-            elsif I - 1 = Low then
-               Found    := False;
-               At_After := I - 1;
-               return;
-
-            else
-               I := I - (I - Low) / 2;
-            end if;
-
-         when Equal =>
-            Found    := True;
-            At_After := I;
-            return;
-
-         when Greater =>
-            Low := I;
-            if I = High then
-               Found    := False;
-               At_After := I - 1;
-               return;
-
-            elsif I + 1 = High then
-               Found    := False;
-               At_After := I;
-               return;
-
-            else
-               I := I + (High - I) / 2;
-            end if;
-         end case;
-      end loop;
-   end Find;
-
-   ----------
-   --  Public subprograms
-
-   overriding procedure Finalize (Container : in out Vector)
-   is begin
-      Free (Container.Elements);
-      Container.Last := No_Index;
-   end Finalize;
-
-   overriding procedure Adjust (Container : in out Vector)
-   is begin
-      if Container.Elements /= null then
-         Container.Elements := new Array_Type'(Container.Elements.all);
-      end if;
-   end Adjust;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      --  We assume the type ranges are sensible, so no exceptions occur
-      --  here.
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Last - 
Container.Elements'First + 1);
-      end if;
-   end Length;
-
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Elements'Length);
-      end if;
-   end Capacity;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      Length    : in     Ada.Containers.Count_Type)
-   is
-      First_Peek : constant Peek_Type      := Peek_Type'First;
-      Last_Peek  : constant Base_Peek_Type := Base_Peek_Type (Length);
-   begin
-      if Length = 0 then
-         return;
-      elsif Container.Elements = null then
-         Container.Elements := new Array_Type (First_Peek .. Last_Peek);
-      else
-         if First_Peek < Container.Elements'First then
-            Grow (Container.Elements, First_Peek);
-         end if;
-         if Last_Peek < Container.Elements'Last then
-            Grow (Container.Elements, Last_Peek);
-         end if;
-      end if;
-   end Set_Capacity;
-
-   function Has_Element (Position : Cursor) return Boolean is
-   begin
-      return Position.Index /= Invalid_Peek_Index;
-   end Has_Element;
-
-   function "&" (Left, Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Insert (Left);
-         Result.Insert (Right);
-      end return;
-   end "&";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector := Left do
-         Result.Insert (Right);
-      end return;
-   end "&";
-
-   function Contains (Container : in Vector; Key : in Key_Type) return Boolean
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return False;
-      end if;
-      Find (Container, Key, Found, I);
-      return Found;
-   end Contains;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type)
-   is
-      New_Key : constant Key_Type       := To_Key (New_Item);
-      J       : constant Peek_Type      := Peek_Type'First;
-      K       : constant Base_Peek_Type := Container.Last;
-      I       : Base_Peek_Type          := K;
-   begin
-      if Container.Last = No_Index then
-         Container.Last := Peek_Type'First;
-         I              := Container.Last;
-
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (I .. I);
-            --  else Set_Capacity called.
-         end if;
-         Container.Elements (I) := New_Item;
-         return;
-
-      else
-         Container.Last := Container.Last + 1;
-      end if;
-
-      pragma Assert (Container.Elements /= null);
-
-      if I + 1 > Container.Elements'Last then
-         Grow (Container.Elements, I + 1);
-      end if;
-
-      loop
-         exit when I < J;
-
-         case Key_Compare (New_Key, To_Key (Container.Elements (I))) is
-         when Less =>
-            --  Linear search is simple, we assume insert is used far less 
often
-            --  than Find. And this is optimal when inserting in Key order.
-            I :=  I - 1;
-         when Equal =>
-            --  Insert after I
-            exit;
-         when Greater =>
-            --  Insert after I
-            exit;
-         end case;
-      end loop;
-
-      if I < J then
-         --  Insert before all
-         Container.Elements (J + 1 .. K + 1) := Container.Elements (J .. K);
-         Container.Elements (J) := New_Item;
-      else
-         --  Insert after I
-         Container.Elements (I + 2 .. K + 1) := Container.Elements (I + 1 .. 
K);
-         Container.Elements (I + 1) := New_Item;
-      end if;
-   end Insert;
-
-   function Find
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Type
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return (Element => null, Dummy => 1);
-      end if;
-      Find (Container, Key, Found, I);
-      if Found then
-         return (Element => Container.Elements (I)'Access, Dummy => 1);
-      else
-         return (Element => null, Dummy => 1);
-      end if;
-   end Find;
-
-   function Find_Constant
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Constant_Type
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return (Element => null, Dummy => 1);
-      end if;
-      Find (Container, Key, Found, I);
-      if Found then
-         return (Element => Container.Elements (I)'Access, Dummy => 1);
-      else
-         return (Element => null, Dummy => 1);
-      end if;
-   end Find_Constant;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      if Object.Container.Elements = null then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Peek_Type'First);
-      end if;
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      if Object.Container.Elements = null then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Object.Container.Last);
-      end if;
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = Object.Container.Last then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Position.Index + 1);
-      end if;
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      if Position.Index = Peek_Type'First then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Position.Index - 1);
-      end if;
-   end Previous;
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Constant_Ref;
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-   is begin
-      return Container.Last;
-   end Last_Index;
-
-   function To_Index (Position : in Cursor) return Base_Peek_Type
-   is begin
-      return Position.Index;
-   end To_Index;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Index)'Access, Dummy => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Unbounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads
deleted file mode 100644
index 2a52c74..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads
+++ /dev/null
@@ -1,172 +0,0 @@
---  Abstract :
---
---  A simple unbounded sorted vector of definite items.
---
---  Copyright (C) 2019 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   type Key_Type is private;
-   with function To_Key (Item : in Element_Type) return Key_Type;
-   with function Key_Compare (Left, Right : in Key_Type) return Compare_Result;
-package SAL.Gen_Unbounded_Definite_Vectors_Sorted is
-
-   use all type Ada.Containers.Count_Type;
-
-   type Vector is new Ada.Finalization.Controlled with private with
-      Constant_Indexing => Constant_Ref,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   Empty_Vector : constant Vector;
-
-   overriding procedure Finalize (Container : in out Vector);
-   overriding procedure Adjust (Container : in out Vector);
-
-   procedure Clear (Container : in out Vector)
-   renames Finalize;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type;
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      Length    : in     Ada.Containers.Count_Type);
-   --  Allocates uninitialized memory; does not change Container.First,
-   --  Container.Last.
-
-   function "&" (Left, Right : in Element_Type) return Vector;
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector;
-
-   function Contains (Container : in Vector; Key : in Key_Type) return Boolean;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type);
-   --  Insert New_Item in sorted position. Items are sorted in increasing
-   --  order according to Element_Compare.
-   --
-   --  Raises Duplicate_Key if To_Key (New_Item) is already in Container.
-
-   type Find_Reference_Type (Element : access Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Find
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Type;
-   --  Result.Element is null if Key not in Container. User must not modify 
Key.
-
-   type Find_Reference_Constant_Type (Element : access constant Element_Type) 
is private with
-     Implicit_Dereference => Element;
-
-   function Find_Constant
-     (Container : aliased in Vector;
-      Key       : in Key_Type)
-     return Find_Reference_Constant_Type;
-   --  Result.Element is null if Key not in Container.
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Position : Cursor) return Boolean;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   with Inline,
-     Pre => To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-
-   function First_Index (Container : in Vector) return Peek_Type is 
(Peek_Type'First);
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-   with Inline;
-   function To_Index (Position : in Cursor) return Base_Peek_Type;
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   with Inline,
-     Pre => Index in Container.First_Index .. Container.Last_Index;
-
-private
-
-   type Array_Type is array (SAL.Peek_Type range <>) of aliased Element_Type;
-   type Array_Access is access Array_Type;
-   procedure Free is new Ada.Unchecked_Deallocation (Array_Type, Array_Access);
-
-   No_Index : constant Base_Peek_Type := 0;
-
-   type Vector is new Ada.Finalization.Controlled with
-   record
-      Elements : Array_Access;
-      --  Elements may be non-null with First = No_Index, after
-      --  Set_Capacity. If First /= No_Index and Last >= First, Elements /=
-      --  null.
-      Last     : Base_Peek_Type := No_Index;
-   end record;
-
-   type Vector_Access is access constant Vector;
-   for Vector_Access'Storage_Size use 0;
-
-   type Cursor is record
-      Index : Base_Peek_Type := No_Index;
-   end record;
-
-   type Iterator (Container : not null access constant Vector) is new 
Iterator_Interfaces.Reversible_Iterator
-     with null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   type Find_Reference_Type (Element : access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Find_Reference_Constant_Type (Element : access constant Element_Type) 
is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Vector : constant Vector := (Ada.Finalization.Controlled with others 
=> <>);
-
-   No_Element : constant Cursor := (others => <>);
-
-   ----------
-   --  Visible for child package
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type);
-
-end SAL.Gen_Unbounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image.adb 
b/packages/wisi/sal-gen_unconstrained_array_image.adb
deleted file mode 100644
index 7ea1c83..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image.adb
+++ /dev/null
@@ -1,34 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Unconstrained_Array_Image (Item : in Array_Type) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I));
-      if I = Item'Last then
-         Result := Result & ")";
-      else
-         Result := Result & ", ";
-      end if;
-   end loop;
-   return To_String (Result);
-end SAL.Gen_Unconstrained_Array_Image;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image.ads 
b/packages/wisi/sal-gen_unconstrained_array_image.ads
deleted file mode 100644
index 226ba00..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image for unconstrained Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type range <>) of Element_Type;
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Unconstrained_Array_Image (Item : in Array_Type) return 
String;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image_aux.adb 
b/packages/wisi/sal-gen_unconstrained_array_image_aux.adb
deleted file mode 100644
index 9e4c5cd..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image_aux.adb
+++ /dev/null
@@ -1,33 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Unconstrained_Array_Image_Aux (Item : in Array_Type; Aux : in 
Aux_Data) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I), Aux);
-      if I < Item'Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unconstrained_Array_Image_Aux;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image_aux.ads 
b/packages/wisi/sal-gen_unconstrained_array_image_aux.ads
deleted file mode 100644
index ad2b9cb..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image_aux.ads
+++ /dev/null
@@ -1,25 +0,0 @@
---  Abstract :
---
---  Image for unconstrained Ada array types
---
---  Copyright (C) 2019, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type range <>) of Element_Type;
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unconstrained_Array_Image_Aux (Item : in Array_Type; Aux : in 
Aux_Data) return String;
diff --git a/packages/wisi/sal-generic_decimal_image.adb 
b/packages/wisi/sal-generic_decimal_image.adb
deleted file mode 100644
index 2699277..0000000
--- a/packages/wisi/sal-generic_decimal_image.adb
+++ /dev/null
@@ -1,48 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 2005, 2006, 2009 Stephen Leake.  All Rights Reserved.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this  unit  does not  by itself cause  the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file  might be covered by the  GNU Public License.
-
-pragma License (Modified_GPL);
-
-function SAL.Generic_Decimal_Image
-  (Item  : in Number_Type;
-   Width : in Natural)
-  return String
-is
-   pragma Warnings (Off);
-   --  Avoid warning about "abs applied to non-negative value has no
-   --  effect" for some instantiations.
-   Temp : Integer := abs Integer (Item);
-   --  IMPROVEME: need test for Decimal_Image, include constrained positive 
number_type
-   pragma Warnings (On);
-   Digit : Integer;
-   Image : String (1 .. Width);
-begin
-   for I in reverse Image'Range loop
-      Digit     := Temp mod 10;
-      Temp      := Temp / 10;
-      Image (I) := Character'Val (Character'Pos ('0') + Digit);
-   end loop;
-   return Image;
-end SAL.Generic_Decimal_Image;
diff --git a/packages/wisi/sal-generic_decimal_image.ads 
b/packages/wisi/sal-generic_decimal_image.ads
deleted file mode 100644
index ec749f6..0000000
--- a/packages/wisi/sal-generic_decimal_image.ads
+++ /dev/null
@@ -1,37 +0,0 @@
---  Abstract:
---
---  Generic leading zero unsigned decimal image
---
---  Copyright (C) 2004, 2009, 2019 Free Software Foundation.  All Rights 
Reserved.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this  unit  does not  by itself cause  the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file  might be covered by the  GNU Public License.
-
-pragma License (Modified_GPL);
-
-generic
-   type Number_Type is range <>;
-function SAL.Generic_Decimal_Image
-  (Item  : in Number_Type;
-   Width : in Natural)
-  return String;
---  Return a decimal unsigned image of Item, padded with leading zeros
---  to Width. If Width is too small for Item, leading digits are
---  silently truncated.
-pragma Pure (SAL.Generic_Decimal_Image);
diff --git a/packages/wisi/sal.adb b/packages/wisi/sal.adb
deleted file mode 100644
index 6265651..0000000
--- a/packages/wisi/sal.adb
+++ /dev/null
@@ -1,32 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 1997 - 2004, 2006, 2009, 2019, 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option) any
---  later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
---  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
---  General Public License for more details. You should have received a
---  copy of the GNU General Public License distributed with SAL; see
---  file COPYING. If not, write to the Free Software Foundation, 59
---  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce
---  an executable, that does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
---
-package body SAL is
-
-   function Version return String is
-   begin
-      return "SAL 3.5";
-   end Version;
-
-end SAL;
diff --git a/packages/wisi/sal.ads b/packages/wisi/sal.ads
deleted file mode 100644
index 1e63dbc..0000000
--- a/packages/wisi/sal.ads
+++ /dev/null
@@ -1,75 +0,0 @@
---  Abstract:
---
---  Root package for Stephe's Ada Library packages.
---
---  See sal.html for more information.
---
---  See http://stephe-leake.org/ada/sal.html for the
---  latest version.
---
---  Contact Stephe at stephen_leake@stephe-leake.org.
---
---  Copyright (C) 1997 - 2004, 2008, 2009, 2015, 2017, 2018 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option) any
---  later version. SAL is distributed in the hope that it will be
---  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
---  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
---  General Public License for more details. You should have received a
---  copy of the GNU General Public License distributed with SAL; see
---  file COPYING. If not, write to the Free Software Foundation, 59
---  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce
---  an executable, that does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-
-package SAL is
-   pragma Pure;
-
-   function Version return String;
-   --  Returns string with format "SAL x.xx".
-
-   Container_Empty                  : exception;
-   Container_Full                   : exception;
-   Config_File_Error                : exception;
-   Domain_Error                     : exception;
-   Duplicate_Key                    : exception;
-   Initialization_Error             : exception;
-   Invalid_Format                   : exception;
-   Invalid_Limit                    : exception;
-   Invalid_Operation                : exception;
-   Invalid_Range                    : exception;
-   Iterator_Error                   : exception;
-   Not_Found                        : exception;
-   Not_Implemented                  : exception;
-   Parameter_Error                  : exception;
-   Programmer_Error                 : exception;
-   Range_Error                      : exception;
-
-   --------------
-   --  General options
-
-   type Direction_Type is (Forward, Backward);
-
-   type Duplicate_Action_Type is (Allow, Ignore, Error);
-
-   type Overflow_Action_Type is (Overwrite, Error);
-
-   --  We use a new type for Peek_Type, not just
-   --  Ada.Containers.Count_Type, to enforce Peek_Type'First = top/first.
-   type Base_Peek_Type is new Ada.Containers.Count_Type range 0 .. 
Ada.Containers.Count_Type'Last;
-   subtype Peek_Type is Base_Peek_Type range 1 .. Base_Peek_Type'Last;
-   Invalid_Peek_Index : constant Base_Peek_Type := 0;
-
-   type Compare_Result is (Less, Equal, Greater);
-end SAL;
diff --git a/packages/wisi/standard_common.gpr 
b/packages/wisi/standard_common.gpr
deleted file mode 100644
index ce019c7..0000000
--- a/packages/wisi/standard_common.gpr
+++ /dev/null
@@ -1,152 +0,0 @@
---  Abstract :
---
---  Standard settings for all of Stephe's Ada projects.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-project Standard_Common is
-   for Source_Dirs use ();
-
-   type Build_Type is ("Debug", "Normal");
-   Build : Build_Type := External ("Standard_Common_Build", "Normal");
-
-   type Profile_Type is ("On", "Off");
-   Profile : Profile_Type := External ("Standard_Common_Profile", "Off");
-
-   type Mem_Check_Type is ("On", "Off");
-   Mem_Check : Profile_Type := External ("Standard_Common_Mem_Check", "Off");
-   --  Note that Mem_Check requires Build_Type = Debug to be useful
-
-   -- In main project file, add:
-   -- case Standard_Common.Mem_Check is
-   -- when "On" =>
-   --    for Runtime ("Ada") use "adalib_debug";
-   -- when "Off" =>
-   --    null;
-   -- end case;
-
-   package Compiler is
-      -- Switches for gcc
-
-      Base_Style_Checks := "-gnaty3abcefhiklnOprtx";
-      Line_Length := "-gnatyM120";
-
-      Style_Checks := (Base_Style_Checks, Line_Length);
-
-      Common_Switches :=
-        (
-         "-fstack-check",
-         "-g",
-         "-gnat2012",
-         "-gnatfqQ", -- f = all error messages, qQ = process semantics, 
generate .ali if syntax errors
-         "-gnatw.d", -- warnings about tags
-         "-gnatwaBCeJL", -- wa = most warnings, wB = no warn on bad fixed 
values, wC = no warn on conditionals
-                         -- we = error on warning, wJ = no warn on 
obsolescent, wL = no warn on elaboration
-         "-gnatyO" -- warn on overriding
-        );
-
-      --  -gnatVa causes some inline procedures to be non-inlineable;
-      --  suppress that warning with -gnatwP.
-      Debug_Switches := Common_Switches &
-        (
-         "-O0", --  we don't use -Og because that causes gdb to report 
incorrect results in some cases in Ada.
-         "-gnata",  -- assertions, pre/post-conditions
-         "-gnatVa", -- validity checks
-         "-gnateE", -- extra info in exceptions
-         "-gnatwaP" -- no warn on Inline
-        );
-
-      --  -O3 is measurably faster than -O2 for wisitoken generate
-      --  LR1. We include -fstack-check because it catches
-      --  hard-to-find bugs, and the processors are so fast.
-      --  -fno-var-tracking-assignments speeds compiling of large
-      --  files; var tracking is only useful for debugging.
-      Base_Release_Switches := Common_Switches &
-        (
-         "-O3",
-         "-fno-var-tracking-assignments",
-         "-gnatyO"
-        );
-
-      Inlining := ("-gnatn");
-
-      Release_Switches := Base_Release_Switches & Inlining;
-
-      -- No -ansi; GNAT 7.1 compiler C header files are mingw 64, which don't 
support -ansi
-      Debug_Switches_C := ("-Wall", "-Wstrict-prototypes", "-pedantic", 
"-Werror", "-g", "-O0", "-funwind-tables");
-      Debug_Switches_C_Non_Pedantic := ("-Wall", "-Wstrict-prototypes", 
"-Werror", "-g", "-O0", "-funwind-tables");
-      Release_Switches_C := ("-Wall", "-Wstrict-prototypes", "-pedantic", 
"-Werror", "-g", "-O2", "-funwind-tables");
-      Release_Switches_C_Non_Pedantic := ("-Wall", "-Wstrict-prototypes", 
"-Werror", "-g", "-O2", "-funwind-tables");
-
-   end Compiler;
-
-   --  In project files, normally use this:
-   --  package Compiler is
-   --  for Default_Switches ("Ada") use
-   --     Standard_Common.Compiler.Release_Switches &
-   --     Standard_Common.Compiler.Style_Checks;
-   --  end Compiler;
-
-   package Builder is
-      --  Switches for gnatmake
-      for Default_Switches ("Ada") use ("-C");
-
-      case Profile is
-      when "On" =>
-         for Global_Compilation_Switches ("Ada") use ("-pg");
-      when "Off" =>
-         null;
-      end case;
-   end Builder;
-
-   --  In project files, normally use this:
-   --  package Builder is
-   --     for Default_Switches ("Ada") use 
Standard_Common.Builder'Default_Switches ("Ada");
-   --  end Builder;
-
-   package Binder is
-      --  Switches for gnatbind
-      for Default_Switches ("Ada") use ("-E");
-
-      Debug_Configuration_Pragmas := "Normalize_Scalars";
-   end Binder;
-
-   --  In project files, normally use this:
-   --  package Binder is
-   --     for Default_Switches ("Ada") use 
Standard_Common.Binder'Default_Switches ("Ada");
-   --  end Binder;
-
-   package Linker is
-      case Profile is
-      when "On" =>
-         case Mem_Check is
-         when "On" =>
-            for Linker_Options use ("-pg", "-lgmem");
-         when "Off" =>
-            for Linker_Options use ("-pg");
-         end case;
-
-      when "Off" =>
-         case Mem_Check is
-         when "On" =>
-            for Linker_Options use ("-lgmem");
-         when "Off" =>
-            null;
-         end case;
-      end case;
-   end Linker;
-
-   --  In project files, no linker package is needed.
-end Standard_Common;
diff --git a/packages/wisi/wisi-fringe.el b/packages/wisi/wisi-fringe.el
deleted file mode 100644
index 2194b09..0000000
--- a/packages/wisi/wisi-fringe.el
+++ /dev/null
@@ -1,152 +0,0 @@
-;;; wisi-fringe.el --- show approximate error locations in the fringe
-;;
-;; Copyright (C) 2018 - 2019  Free Software Foundation, Inc.
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-;; Design:
-;;
-;; Bitmaps are displayed in the fringe by putting a 'display property
-;; on buffer text. However, just doing that also hides the buffer
-;; text. To avoid that, we put the ’display property on a string, and
-;; then an overlay containing that string as ’before-string or
-;; ’after-string on the newline of a buffer line.
-;;
-;; We show approximate error positions in the entire buffer with
-;; single-pixel lines in the right fringe, and mark error lines with
-;; ’!!’ in the left fringe.
-
-(defun wisi-fringe-create-bitmaps ()
-  "Return an array of bitmap symbols containing the fringe bitmaps."
-  ;; First create the ’!!’ bitmap.
-  (define-fringe-bitmap 'wisi-fringe--double-exclaim-bmp
-    (vector
-     #b00000000
-     #b01100110
-     #b01100110
-     #b01100110
-     #b01100110
-     #b01100110
-     #b00000000
-     #b01100110
-     #b01010110
-     #b00000000))
-
-  ;; In condensing the entire buffer to the current window height, we
-  ;; assume a 10 point font, which allows 6 distinct line positions
-  ;; each one pixel high, with one blank pixel between.
-
-  (let ((result (make-vector 64 nil))
-       (i 1))
-    (while (<= i (length result))
-      (aset result (1- i)
-           (define-fringe-bitmap (intern (format "wisi-fringe--line-%d-bmp" i))
-             (vector
-              (if (>= i 32) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 32) 16) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 16) 8) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 8) 4) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 4) 2) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 2) 1) #b11111111 #b00000000)
-              )))
-      (setq i (1+ i)))
-    result))
-
-(defconst wisi-fringe-bitmaps (wisi-fringe-create-bitmaps)
-  "Array of 64 bitmap symbols.")
-
-(defun wisi-fringe--put-right (line bitmap-index)
-  (save-excursion
-    (goto-char (point-min))
-    (forward-line (1- line))
-    (let* ((endpos (line-end-position))
-          (ov (make-overlay endpos (1+ endpos)))
-          (bmp (aref wisi-fringe-bitmaps bitmap-index)))
-      (overlay-put ov 'after-string (propertize "-" 'display (list 
'right-fringe bmp 'compilation-error)))
-      (overlay-put ov 'wisi-fringe t)
-      )))
-
-(defun wisi-fringe--put-left (line)
-  (save-excursion
-    (goto-char (point-min))
-    (forward-line (1- line))
-    (let* ((endpos (line-end-position))
-          (ov (make-overlay endpos (1+ endpos)))
-          (bmp 'wisi-fringe--double-exclaim-bmp))
-      (overlay-put ov 'before-string (propertize "-" 'display (list 
'left-fringe bmp 'compilation-error)))
-      (overlay-put ov 'wisi-fringe t)
-      )))
-
-(defun wisi-fringe--scale (error-line buffer-lines window-line-first 
window-lines)
-  "Return a cons (LINE . BIN) for ERROR-LINE,
-where LINE is the line to display the error bar on, and BIN is a
-6-bit bit vector giving the relative position in that line.
-BUFFER-LINES is the count of lines in the buffer.
-WINDOW-LINE-FIRST is the first and last lines of the buffer
-visible in the window. WINDOW-LINES is the count of lines visible
-in the window."
-  ;; If the end of buffer is inside the window, and this calculation
-  ;; puts a mark after that, it will actually be put on the last real
-  ;; line. That’s good enough for our purposes.
-
-  ;; partial-lines / window-line = 6
-  ;; buffer-lines / window-line = 1/scale
-  ;; buffer-lines / partial-line  = (window-line / partial-lines) * 
(buffer-lines / window-line) = 1/6 * 1/scale
-  (let* ((scale (/ window-lines (float buffer-lines)))
-        (line (floor (* scale error-line)))
-        (rem (- error-line (floor (/ line scale)))))
-    (cons (+ window-line-first line) (lsh 1 (min 5 (floor (* rem (* 6 
scale))))))))
-
-(defun wisi-fringe-clean ()
-  "Remove all wisi-fringe marks."
-  (remove-overlays (point-min) (point-max) 'wisi-fringe t))
-
-(defun wisi-fringe-display-errors (positions)
-  "Display markers in the left and right fringe for each buffer position in 
POSITIONS.
-The buffer containing POSITIONS must be current, and the window
-displaying that buffer must be current."
-  ;; We don't recompute fringe display on scroll, because the user
-  ;; will probably have edited the code by then, triggering a new
-  ;; parse.
-  (wisi-fringe-clean)
-  (let (scaled-posns
-       (buffer-lines (line-number-at-pos (point-max)))
-       (window-lines (window-height))
-       (window-pos-first (window-start))
-       (window-pos-last  (window-end))
-       (window-line-first (line-number-at-pos (window-start))))
-    (dolist (pos positions)
-      (let* ((line (line-number-at-pos pos))
-            (scaled-pos (wisi-fringe--scale line buffer-lines 
window-line-first window-lines)))
-       (when (and (>= pos window-pos-first)
-                  (<= pos window-pos-last))
-         (wisi-fringe--put-left line))
-       (if (and scaled-posns
-                (= (caar scaled-posns) (car scaled-pos)))
-           (setcdr (car scaled-posns) (logior (cdar scaled-posns) (cdr 
scaled-pos)))
-         (push scaled-pos scaled-posns))
-       ))
-
-    (dolist (pos scaled-posns)
-      (wisi-fringe--put-right (car pos) (1- (cdr pos))))
-    ))
-
-(provide 'wisi-fringe)
diff --git a/packages/wisi/wisi-parse-common.el 
b/packages/wisi/wisi-parse-common.el
deleted file mode 100644
index 2140b50..0000000
--- a/packages/wisi/wisi-parse-common.el
+++ /dev/null
@@ -1,403 +0,0 @@
-;;; wisi-parse-common.el --- declarations used by wisi-parse.el, 
wisi-ada-parse.el, and wisi.el -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2014, 2015, 2017 - 2019  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(defcustom wisi-partial-parse-threshold 100001
-  "Minimum size that will be parsed by each call to the parser.
-A parse is always requested at a point (or on a region); the
-point is first expanded to a start point before the region and an
-end point after the region, that the parser can gracefully
-handle. If the final region covers the entire buffer, a complete
-parse is done. Indent assumes the start point of the parse region
-is properly indented. Most navigate parses ignore this setting
-and parse the whole buffer."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-partial-parse-threshold)
-
-(cl-defstruct (wisi--lexer-error)
-  pos ;; position (integer) in buffer where error was detected.
-  message  ;; string error message
-  inserted ;; char inserted after pos.
-  )
-
-(cl-defstruct (wisi--parse-error-repair)
-  pos ;; position (integer) in buffer where insert/delete is done.
-  inserted ;; list of token IDs that were inserted before pos
-  deleted  ;; list of token IDs that were deleted after pos
-  deleted-region ;; buffer (cons FIRST LAST) region deleted
-  )
-
-(cl-defstruct (wisi--parse-error)
-  ;; Includes information derived from compiler error recovery to edit
-  ;; text to fix one error. Used by ’wisi-repair-error’ to edit buffer.
-  pos      ;; position (integer or marker) in buffer where error was detected.
-  message  ;; string error message
-  repair   ;; list of wisi--parse-error-repair.
-  )
-
-(cl-defstruct wisi-parser
-  ;; Separate lists for lexer and parse errors, because lexer errors
-  ;; must be repaired first, before parse errors can be repaired. And
-  ;; they have different structures.
-  lexer-errors
-  ;; list of wisi--lexer-errors from last parse.  Can be more than one if
-  ;; lexer supports error recovery.
-  parse-errors
-  ;; List of wisi--parse-errors from last parse. Can be more than one if
-  ;; parser supports error recovery.
-
-  repair-image
-  ;; alist of (TOKEN-ID . STRING); used by repair error
-)
-
-(cl-defgeneric wisi-parse-format-language-options ((parser wisi-parser))
-  "Return a string to be sent to the parser, containing settings
-for the language-specific parser options."
-  )
-
-(cl-defgeneric wisi-parse-expand-region ((_parser wisi-parser) begin end)
-  "Return a cons SEND-BEGIN . SEND-END that is an expansion of
-region BEGIN END that starts and ends at points the parser can
-handle gracefully."
-  (cons begin end))
-
-(defvar-local wisi--parser nil
-  "The current wisi parser; a ‘wisi-parser’ object.")
-
-(defun wisi-read-parse-action ()
-  "Read a parse action symbol from the minibuffer."
-  (intern-soft (completing-read "parse action (indent): " '(face navigate 
indent) nil t nil nil 'indent)))
-
-(defun wisi-search-backward-skip (regexp skip-p)
-  "Search backward for REGEXP. If SKIP-P returns non-nil, search again.
-SKIP-P is a function taking no parameters.
-Return nil if no match found before bob."
-  (let ((maybe-found-p (search-backward-regexp regexp nil t)))
-    (while (and maybe-found-p
-               (funcall skip-p)
-               (setq maybe-found-p (search-backward-regexp regexp nil t))))
-    maybe-found-p))
-
-(defun wisi-search-forward-skip (regexp skip-p)
-  "Search forward for REGEXP. If SKIP-P returns non-nil, search again.
-SKIP-P is a function taking no parameters.
-Return nil if no match found before eob."
-  (let ((maybe-found-p (search-forward-regexp regexp nil t)))
-    (while (and maybe-found-p
-               (funcall skip-p)
-               (setq maybe-found-p (search-forward-regexp regexp nil t))))
-    maybe-found-p))
-
-(defun wisi-show-expanded-region ()
-  "For debugging. Expand currently selected region."
-  (interactive)
-  (let ((region (wisi-parse-expand-region wisi--parser (region-beginning) 
(region-end))))
-    (message "pre (%d . %d) post %s" (region-beginning) (region-end) region)
-    (set-mark (car region))
-    (goto-char (cdr region))
-    ))
-
-(cl-defgeneric wisi-parse-adjust-indent ((_parser wisi-parser) indent _repair)
-  "Adjust INDENT for REPAIR (a wisi--parse-error-repair struct). Return new 
indent."
-  indent)
-
-(cl-defgeneric wisi-parse-current ((parser wisi-parser) begin send-end 
parse-end)
-  "Parse current buffer starting at BEGIN, continuing at least thru PARSE-END.
-If using an external parser, send it BEGIN thru SEND-END.")
-
-(cl-defgeneric wisi-refactor ((parser wisi-parser) refactor-action parse-begin 
parse-end edit-begin)
-  "Send parser command to perform REFACTOR-ACTION on region PARSE-BEGIN 
PARSE-END at point EDIT_BEGIN.
-The parse region is not expanded first; it must be the statement
-or declaration containing EDIT_BEGIN.")
-
-(cl-defgeneric wisi-parse-kill ((parser wisi-parser))
-  "Kill any external process associated with parser.")
-
-(cl-defgeneric wisi-parse-find-token ((parser wisi-parser) token-symbol)
-  "Find token with TOKEN-SYMBOL on current parser stack, return token struct.
-For use in grammar actions.")
-
-(cl-defgeneric wisi-parse-stack-peek ((parser wisi-parser) n)
-  "Return the Nth token on the parse stack.
-For use in grammar actions.")
-
-(cl-defstruct
-  (wisi-cache
-   (:constructor wisi-cache-create)
-   (:copier nil))
-  nonterm;; nonterminal from parse
-
-  token
-  ;; terminal symbol from wisi-keyword-table or
-  ;; wisi-punctuation-table, or lower-level nonterminal from parse
-
-  last ;; pos of last char in token, relative to first (0 indexed)
-
-  class ;; one of wisi-class-list
-
-  containing
-  ;; Marker at the start of the containing statement for this token.
-  ;; nil for outermost containing.
-
-  prev ;; marker at previous motion token in statement; nil if none
-  next ;; marker at next motion token in statement; nil if none
-  end  ;; marker at token at end of current statement
-  )
-
-(defun wisi-get-cache (pos)
-  "Return `wisi-cache' struct from the `wisi-cache' text property at POS."
-  (get-text-property pos 'wisi-cache))
-
-(defun wisi-backward-cache ()
-  "Move point backward to the beginning of the first token preceding point 
that has a cache.
-Returns cache, or nil if at beginning of buffer."
-  ;; If point is not near cache, p-s-p-c will return pos just after
-  ;; cache, so 1- is the beginning of cache.
-  ;;
-  ;; If point is just after end of cache, p-s-p-c will return pos at
-  ;; start of cache.
-  ;;
-  ;; So we test for the property before subtracting 1.
-  (let ((pos (previous-single-property-change (point) 'wisi-cache))
-       cache)
-    (cond
-     ((null pos)
-      (goto-char (point-min))
-      nil)
-
-     ((setq cache (get-text-property pos 'wisi-cache))
-      (goto-char pos)
-      cache)
-
-     (t
-      (setq pos (1- pos))
-      (setq cache (get-text-property pos 'wisi-cache))
-      (goto-char pos)
-      cache)
-     )))
-
-(defun wisi-forward-cache ()
-  "Move point forward to the beginning of the first token after point that has 
a cache.
-Returns cache, or nil if at end of buffer."
-  (let (cache pos)
-    (when (get-text-property (point) 'wisi-cache)
-      ;; on a cache; get past it
-      (goto-char (1+ (point))))
-
-    (setq cache (get-text-property (point) 'wisi-cache))
-    (if cache
-       nil
-
-      (setq pos (next-single-property-change (point) 'wisi-cache))
-      (if pos
-         (progn
-           (goto-char pos)
-           (setq cache (get-text-property pos 'wisi-cache)))
-       ;; at eob
-       (goto-char (point-max))
-       (setq cache nil))
-      )
-    cache
-    ))
-
-(defun wisi-cache-region (cache &optional start)
-  "Return region designated by START (default point) to cache last."
-  (unless start (setq start (point)))
-  (cons start (+ start (wisi-cache-last cache))))
-
-(defvar wisi-debug 0
-  "wisi debug mode:
-0 : normal - ignore parse errors, for indenting new code
-1 : report parse errors (for running tests)
-2 : show parse states, position point at parse errors
-3 : also show top 10 items of parser stack.")
-
-;; The following parameters are easily changeable for debugging.
-(defvar wisi-action-disable nil
-  "If non-nil, disable all elisp actions during parsing.
-Allows timing parse separate from actions.")
-
-(defvar-local wisi-trace-mckenzie 0
-  "McKenzie trace level; 0 for none")
-
-(defvar-local wisi-trace-action 0
-  "Parse action trace level; 0 for none")
-
-(defvar-local wisi-mckenzie-disable nil
-  "If non-nil, disable McKenzie error recovery. Otherwise, use parser 
default.")
-
-(defcustom wisi-mckenzie-task-count nil
-  "If integer, sets McKenzie error recovery task count.
-Higher value (up to system processor limit) runs error recovery
-faster, but may encounter race conditions.  Using only one task
-makes error recovery repeatable; useful for tests.  If nil, uses
-value from grammar file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-task-count)
-
-(defcustom wisi-mckenzie-check-limit nil
-  "If integer, sets McKenzie error recovery algorithm token check limit.
-This sets the number of tokens past the error point that must be
-parsed successfully for a solution to be deemed successful.
-Higher value gives better solutions, but may fail if there are
-two errors close together.  If nil, uses value from grammar
-file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-check-limit)
-
-(defcustom wisi-mckenzie-enqueue-limit nil
-  "If integer, sets McKenzie error recovery algorithm enqueue limit.
-This sets the maximum number of solutions that will be considered.
-Higher value has more recover power, but will be slower to fail.
-If nil, uses value from grammar file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-enqueue-limit)
-
-(defcustom wisi-parse-max-parallel 15
-  "Maximum number of parallel parsers during regular parsing.
-Parallel parsers are used to resolve redundancy in the grammar.
-If a file needs more than this, it's probably an indication that
-the grammar is excessively redundant."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-
-(defvar wisi-parse-max-stack-size 500
-  "Maximum parse stack size.
-Larger stack size allows more deeply nested constructs.")
-;; end of easily changeable parameters
-
-(defvar wisi--parse-action nil
-  ;; not buffer-local; only let-bound in wisi-indent-region, 
wisi-validate-cache
-  "Reason current parse is begin run; one of
-{indent, face, navigate}.")
-
-(defvar-local wisi-indent-comment-col-0 nil
-  "If non-nil, comments currently starting in column 0 are left in column 0.
-Otherwise, they are indented with previous comments or code.
-Normally set from a language-specific option.")
-
-(defvar-local wisi-end-caches nil
-  "List of buffer positions of caches in current statement that need 
wisi-cache-end set.")
-
-(defconst wisi-eoi-term 'Wisi_EOI
-  ;; must match FastToken wisi-output_elisp.adb EOI_Name, which must
-  ;; be part of a valid Ada identifer.
-  "End Of Input token.")
-
-(defconst wisi-class-list
-  [motion ;; motion-action
-   statement-end
-   statement-override
-   statement-start
-   misc ;; other stuff
-   ]
-  "array of valid token classes; checked in wisi-statement-action, used in 
wisi-process-parse.")
-
-(defun wisi-error-msg (message &rest args)
-  (let ((line (line-number-at-pos))
-       (col (- (point) (line-beginning-position))))
-    (format
-     "%s:%d:%d: %s"
-       (buffer-name) ;; buffer-file-name is sometimes nil here!?
-       line col
-       (apply 'format message args))))
-
-(defvar wisi-parse-error nil)
-(put 'wisi-parse-error
-     'error-conditions
-     '(error wisi-parse-error))
-(put 'wisi-parse-error
-     'error-message
-     "wisi parse error")
-
-(cl-defstruct wisi-tok
-  token  ;; symbol from a token table ;; IMPROVEME: rename to ’id’?
-  region ;; cons giving buffer region containing token text
-
-  nonterminal ;; t if a nonterminal
-
-  line ;; Line number at start of token. Nil for empty nonterminals
-
-  first
-  ;; For terminals, t if token is the first token on a line.
-  ;;
-  ;; For nonterminals, line number of first contained line (not
-  ;; including trailing comments) that needs indenting; it is a
-  ;; comment, or begins with a contained token.
-  ;;
-  ;; Otherwise nil.
-
-  ;; The following are non-nil if token (terminal or non-terminal) is
-  ;; followed by blank or comment lines
-  comment-line ;; first blank or comment line following token
-  comment-end ;; position at end of blank or comment lines
-  )
-
-(defun wisi-token-text (token)
-  "Return buffer text from token range."
-  (let ((region (wisi-tok-region token)))
-    (and region
-       (buffer-substring-no-properties (car region) (cdr region)))))
-
-(defun wisi-and-regions (left right)
-  "Return region enclosing both LEFT and RIGHT."
-  (if left
-      (if right
-         (cons (min (car left) (car right))
-               (max (cdr left) (cdr right)))
-       left)
-    right))
-
-(defun wisi--set-line-begin (line-count)
-  "Return a vector of line-beginning positions, with length LINE-COUNT."
-  (let ((result (make-vector line-count 0)))
-    (save-excursion
-      (goto-char (point-min))
-
-      (dotimes (i line-count)
-       (aset result i (point))
-       (forward-line 1)))
-    result))
-
-;;;; debugging
-(defun wisi-tok-debug-image (tok)
-  "Return id and region from TOK, as string."
-  (cond
-   ((wisi-tok-region tok)
-    (format "(%s %d . %d)"
-           (wisi-tok-token tok)
-           (car (wisi-tok-region tok))
-           (cdr (wisi-tok-region tok))))
-   (t
-    (format "(%s)" (wisi-tok-token tok)))
-   ))
-
-(provide 'wisi-parse-common)
diff --git a/packages/wisi/wisi-prj.el b/packages/wisi/wisi-prj.el
deleted file mode 100644
index 501c09f..0000000
--- a/packages/wisi/wisi-prj.el
+++ /dev/null
@@ -1,1614 +0,0 @@
-;;; wisi-prj.el --- project integration -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2019 - 2020  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Usage:
-;;
-;; See wisi.info (compiled from wisi.texi).
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'find-file)
-(require 'wisi)
-
-(cl-defstruct wisi-prj
-  name     ;; A user-friendly string, used in menus and messages.
-
-  compile-env
-  ;; List of strings NAME=VALUE for `compilation-environment'; used
-  ;; when running the compiler or makefile. Also prepended to
-  ;; `process-environment' when the project file is parsed, or when
-  ;; the project file is used by a tool in an external process.
-
-  file-env
-  ;; Environment (list of strings NAME=VALUE) set in project file;
-  ;; prepended to `process-environment' running tools in an external
-  ;; process.
-
-  compiler
-  xref
-  ;; xref functionality is often provided by the compiler. We allow
-  ;; for separate compiler and xref objects, to handle the case where
-  ;; the compiler is a cross-compiler for an embedded target, and xref
-  ;; is provided by a host compiler.
-
-  (case-exception-files nil)
-  ;; List of casing exception files; from `casing' project variable.
-  ;;
-  ;; New exceptions may be added interactively via
-  ;; `wisi-case-create-exception'.  If an exception is defined in
-  ;; multiple files, the first occurence is used.
-  ;;
-  ;; The file format is one word per line, which gives the casing to be
-  ;; used for that word in source code.  If the line starts with
-  ;; the character *, then the exception will be used for partial
-  ;; words that either start at the beginning of a word or after a _
-  ;; character, and end either at the end of the word or at a _
-  ;; character.  Characters after the first word are ignored, and not
-  ;; preserved when the list is written back to the file."
-
-  (case-full-exceptions '())
-  ;; Alist of full words that have special casing, built from
-  ;; case-exception-files. Indexed by properly cased word; value is t.
-
-  (case-partial-exceptions '())
-  ;; Alist of partial words that have special casing, built from
-  ;; project casing files list partial word exceptions. Indexed by
-  ;; properly cased word; value is t.
-
-  source-path ;; list of absolute directory file names
-
-  file-pred
-  ;; Function taking an absolute file name, returns non-nil
-  ;; if the file should be included in `project-files'.
-  )
-
-(defun wisi-prj-require-prj ()
-  "Return current `wisi-prj' object.
-Throw an error if current project is not an wisi-prj."
-  (let ((prj (project-current)))
-    (if (wisi-prj-p prj)
-       prj
-      (error "current project is not a wisi project."))))
-
-(defun wisi-prj-current-prj ()
-  "Return current `wisi-prj' object.
-If (project-current) does not return a wisi-prj, return a default prj."
-  (let ((prj (project-current)))
-    (if (wisi-prj-p prj)
-       prj
-      (make-wisi-prj :name "default"))))
-
-(defvar wisi-prj-file-extensions (list "prj")
-  "List of wisi project file extensions.
-Used when searching for project files.")
-
-(defvar wisi-prj--cache nil
-  "Alist holding currently parsed project objects.
-Indexed by absolute project file name.")
-
-(cl-defgeneric wisi-prj-default (prj)
-  "Return a project with default values.
-Used to reset a project before refreshing it.")
-
-(cl-defgeneric wisi-prj-parse-one (_project _name _value)
-  "If recognized by PROJECT, set NAME, VALUE in PROJECT, return non-nil.
-Else return nil."
-  nil)
-
-(cl-defgeneric wisi-prj-parse-final (_project _prj-file-name)
-  "Do any final processing on PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-prj-select (project)
-  "PROJECT is selected; perform any required actions.")
-
-(cl-defgeneric wisi-prj-deselect (project)
-  "PROJECT is deselected; undo any select actions.")
-
-(cl-defgeneric wisi-prj-refresh-cache (prj not-full)
-  "Reparse the project file for PRJ, refresh all cached data in PRJ.
-If NOT-FULL is non-nil, very slow refresh operations may be skipped.")
-
-(cl-defgeneric wisi-prj-identifier-ignore-case (prj)
-  "Return non-nil if case should be ignored when comparing identifiers.")
-
-;; We provide nil defaults for some methods, because some language
-;; modes don't have a language-specific compiler (eg java-wisi) or
-;; xref process (eg gpr-mode).
-
-(cl-defgeneric wisi-compiler-parse-one (compiler project name value)
-  "Set NAME, VALUE in COMPILER, if recognized by COMPILER.
-PROJECT is an `wisi-prj' object; COMPILER is `wisi-prj-compiler'.")
-
-(cl-defgeneric wisi-compiler-parse-final (_compiler _project _prj-file-name)
-  "Do any compiler-specific processing on COMPILER and PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-compiler-select-prj (_compiler _project)
-  "PROJECT has been selected; do any compiler-specific actions required."
-  nil)
-
-(cl-defgeneric wisi-compiler-deselect-prj (_compiler _project)
-  "PROJECT has been de-selected; undo any compiler-specific select actions."
-  nil)
-
-(cl-defgeneric wisi-compiler-show-prj-path (compiler)
-  "Display buffer listing project file search path.")
-
-(cl-defgeneric wisi-compiler-fix-error (compiler source-buffer)
-  "Attempt to fix a compilation error, return non-nil if fixed.
-Current buffer is compilation buffer; point is at an error message.
-SOURCE-BUFFER contains the source code referenced in the error message.")
-
-(cl-defgeneric wisi-xref-parse-one (_xref _project _name _value)
-  "If recognized by XREF, set NAME, VALUE in XREF, return non-nil.
-Else return nil."
-  nil)
-
-(cl-defgeneric wisi-xref-parse-final (_xref _project _prj-file-name)
-  "Do any xref-specific processing on XREF and PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-xref-select-prj (_xref _project)
-  "PROJECT has been selected; do any xref-specific actions required."
-  nil)
-
-(cl-defgeneric wisi-xref-deselect-prj (_xref _project)
-  "PROJECT has been de-selected; undo any xref-specific select actions."
-  nil)
-
-(cl-defgeneric wisi-xref-refresh-cache (_xref _project _no-full)
-  "Refresh cached information in XREF. If no-full is non-nil,
-slow refresh operations may be skipped."
-  nil)
-
-(cl-defgeneric wisi-xref-completion-table (xref project)
-  "Return a completion table of names defined in PROJECT, for navigating to 
the declarations.
-The table is an alist of (ANNOTATED-SYMBOL . LOC), where:
-
-- ANNOTATED-SYMBOL is the simple name and possibly annotations
-such as function arguments, controlling type, containing package,
-and line number.
-
-- LOC is the declaration of the name as a list (FILE LINE
-COLUMN).")
-
-(cl-defgeneric wisi-xref-completion-delim-regex (xref)
-  "Return the value for `completion-pcm--delim-wild-regex' to be used with 
`wisi-xref-completion-table'.")
-
-(cl-defgeneric wisi-xref-completion-regexp (xref)
-  "Return a regular expression matching the result of completing with 
`wisi-xref-completion-table'.
-Group 1 must be the simple symbol; the rest of the item may be annotations.")
-
-(cl-defgeneric wisi-xref-completion-at-point-table (xref project)
-  "Return a completion table of names defined in PROJECT, for 
`completion-at-point'.
-The table is a simple list of symbols.")
-
-(cl-defgeneric wisi-xref-definitions (xref project item)
-  "Return all definitions (classwide) of ITEM (an xref-item), as a list of 
xref-items.")
-
-(cl-defgeneric wisi-xref-references (xref project item)
-  "Return all references to ITEM (an xref-item), as a list of xref-items.")
-
-(cl-defgeneric wisi-xref-other (project &key identifier filename line column)
-  "Return cross reference information.
-PROJECT - dispatching object, normally a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier (may be nil)
-COLUMN - Emacs column of the start of the identifier (may be nil)
-Point is on the start of the identifier.
-Returns a list (FILE LINE COLUMN) giving the corresponding location;
-FILE is an absolute file name.  If point is at the specification, the
-corresponding location is the
-body, and vice versa.")
-
-(defvar-local wisi-xref-full-path nil
-  "If non-nil, xref functions show full paths in results.")
-
-(defun wisi-goto-source (file line column)
-  "Find and select FILE, at LINE and COLUMN.
-FILE may be absolute, or on `compilation-search-path'.
-LINE, COLUMN are Emacs origin."
-  (let ((file-1
-        (if (file-name-absolute-p file) file
-          (ff-get-file-name compilation-search-path file))))
-    (if file-1
-       (setq file file-1)
-      (error "File %s not found; installed library, or set project?" file))
-    )
-
-  (push-mark (point) t)
-
-  (let ((buffer (get-file-buffer file)))
-    (cond
-     ((bufferp buffer)
-      ;; use pop-to-buffer, so package other-frame-window works.
-      (pop-to-buffer buffer (list #'display-buffer-same-window)))
-
-     ((file-exists-p file)
-      (find-file file))
-
-     (t
-      (error "'%s' not found" file))))
-
-  ;; move the cursor to the correct position
-  (goto-char (point-min))
-  (forward-line (1- line))
-  (forward-char column))
-
-(defun wisi-show-xref (xref)
-  "Display XREF location."
-  (let ((marker (xref-location-marker (xref-item-location xref))))
-    (push-mark)
-    (pop-to-buffer (marker-buffer marker) (list #'display-buffer-same-window))
-    (goto-char (marker-position marker))))
-
-(defun wisi-filter-table (table file)
-  "If FILE is nil, return TABLE. Otherwise return only items in TABLE with 
location FILE."
-  (cond
-   ((null file)
-    table)
-
-   (t
-    (let (result)
-      (dolist (item table)
-       (when (string= file (car (cdr item)))
-         (push item result)))
-      result))))
-
-(defun wisi-get-identifier (prompt)
-  "Get identifier at point, or, if no identifier at point or with user arg, 
prompt for one.
-Single user arg completes on all identifiers in project; double
-user arg limits completion to current file."
-  ;; Similar to xref--read-identifier, but uses a different completion
-  ;; table, because we want a more specific reference.
-  (let* ((prj (project-current))
-         (def (xref-backend-identifier-at-point prj)))
-
-    (cond
-     ((or current-prefix-arg
-          (not def))
-      (let* ((table (wisi-filter-table (wisi-xref-completion-table 
(wisi-prj-xref prj) prj)
-                                      (when (equal '(16) current-prefix-arg) 
(buffer-file-name))))
-            (completion-pcm--delim-wild-regex 
(wisi-xref-completion-delim-regex (wisi-prj-xref prj)))
-            (id
-             ;; Since the user decided not to use the identifier at
-             ;; point, don't use it as the default.
-              (completing-read prompt table nil nil nil 
'xref--read-identifier-history)))
-        (if (equal id "")
-            (user-error "No identifier provided")
-
-         ;; The user may have forced exit from completing-read with a
-         ;; string that is not in the table (because gpr-query is out
-         ;; of date, for example).
-          (or (and (consp (car table)) ;; alist; return key and value.
-                  (assoc id table))
-             id))))
-     (t def))))
-
-(defun wisi-goto-spec/body (identifier)
-  "Goto declaration or body for IDENTIFIER (default symbol at point).
-If no symbol at point, or with prefix arg, prompt for symbol, goto spec."
-  (interactive (list (wisi-get-identifier "Goto spec/body of: ")))
-  (let ((prj (project-current))
-       desired-loc)
-    (cond
-     ((consp identifier)
-      ;; alist element from wisi-xref-completion-table; desired
-      ;; location is primary declaration
-      (setq desired-loc
-           (xref-make (car identifier)
-                      (xref-make-file-location
-                       (nth 0 (cdr identifier)) ;; file
-                       (nth 1 (cdr identifier)) ;; line
-                       (nth 2 (cdr identifier)) ;; column
-                       ))))
-
-     ((stringp identifier)
-      ;; from xref-backend-identifier-at-point; desired location is 'other'
-      (let ((item (wisi-xref-item identifier prj)))
-       (condition-case-unless-debug err
-           (with-slots (summary location) item
-             (let ((eieio-skip-typecheck t))
-               (with-slots (file line column) location
-                 (let ((target
-                        (wisi-xref-other
-                         (wisi-prj-xref prj) prj
-                         :identifier summary
-                         :filename file
-                         :line line
-                         :column column)))
-                   (setq desired-loc
-                         (xref-make summary
-                                    (xref-make-file-location
-                                     (nth 0 target) ;; file
-                                     (nth 1 target) ;; line
-                                     (nth 2 target))) ;; column
-                         )))))
-         (user-error ;; from gpr-query; current file might be new to project, 
so try wisi-names
-          (let ((item (assoc identifier (wisi-names nil t))))
-            (if item
-                (setq desired-loc
-                      (xref-make identifier
-                                 (xref-make-file-location
-                                  (nth 1 item) ;; file
-                                  (nth 2 item) ;; line
-                                  (nth 3 item))))
-              (signal (car err) (cdr err)))))
-         )))
-
-     (t ;; something else
-      (error "unknown case in wisi-goto-spec/body")))
-    (wisi-show-xref desired-loc)
-    ))
-
-(cl-defgeneric wisi-prj-identifier-at-point (_project)
-  "Return (IDENT START END) giving the identifier and its bounds at point.
-Return nil if no identifier is at point."
-  ;; default implementation
-  (let ((bounds (bounds-of-thing-at-point 'symbol)))
-    (when bounds
-      (list (car bounds) (cdr bounds) (buffer-substring-no-properties (car 
bounds) (cdr bounds))))))
-
-(defun wisi-completion-at-point ()
-  "For `completion-at-point-functions'."
-  (let ((prj (project-current)))
-    (when (wisi-prj-p prj)
-      (save-excursion
-       (let ((table (wisi-xref-completion-at-point-table (wisi-prj-xref prj) 
prj))
-             (bounds (wisi-prj-identifier-at-point prj)))
-         (when bounds
-           ;; xref symbol table may be out of date; try dabbrevs
-           (list (nth 0 bounds) (nth 1 bounds) table :exclusive 'no))
-         )))
-    ))
-
-(defun wisi-check-current-project (file-name &optional default-prj-function)
-  "If FILE-NAME (must be absolute) is found in the current
-project source directories, return the current
-project. Otherwise, if the current project is a wisi project,
-throw an error.  If the current project is not a wisi project,
-and DEFAULT-PRJ-FUNCTION is non-nil, use it to return a default
-project. Otherwise throw an error."
-  (let ((visited-file (file-truename file-name)) ;; file-truename handles 
symbolic links
-        (project (project-current)))
-    (if (wisi-prj-p project)
-       (let ((found-file (locate-file (file-name-nondirectory visited-file)
-                                      (wisi-prj-source-path project))))
-         (unless found-file
-           (error "current file not part of current project; wrong project?"))
-
-         (setq found-file (file-truename found-file))
-
-         ;; (nth 10 (file-attributes ...)) is the inode; required when hard
-         ;; links are present.
-         (let* ((visited-file-inode (nth 10 (file-attributes visited-file)))
-                (found-file-inode (nth 10 (file-attributes found-file))))
-           (unless (equal visited-file-inode found-file-inode)
-              (error "%s (opened) and %s (found in project) are two different 
files"
-                    file-name found-file)))
-         project)
-
-      ;; create a project?
-      (if default-prj-function
-         (funcall default-prj-function nil (file-name-directory file-name))
-       (error "current project is not a wisi project."))
-      )))
-
-(cl-defgeneric wisi-xref-parents (xref project &key identifier filename line 
column)
-  "Displays parent type declarations.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier
-
-Displays a buffer in compilation-mode giving locations of the parent type 
declarations.")
-
-(defun wisi-show-declaration-parents ()
-  "Display the locations of the parent type declarations of the type 
identifier around point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-parents
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column)))
-    ))
-
-(cl-defgeneric wisi-xref-all (xref project &key identifier filename line 
column local-only append)
-  "Displays cross reference information.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol (a string).
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier
-LOCAL-ONLY - if t, show references in FILE only
-APPEND - if t, keep previous output in result buffer
-Displays a buffer in compilation-mode giving locations where the
-identifier is declared or referenced.")
-
-(defun wisi-show-references (&optional append)
-  "Show all references of identifier at point.
-With prefix, keep previous references in output buffer."
-  (interactive "P")
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-all
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column))
-     :local-only nil
-     :append append)
-    ))
-
-(defun wisi-show-local-references (&optional append)
-  "Show all references of identifier at point occuring in current file.
-With prefix, keep previous references in output buffer."
-  (interactive "P")
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-all
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column))
-     :local-only t
-     :append append)
-    ))
-
-(cl-defgeneric wisi-xref-overriding (xref project &key identifier filename 
line column)
-  "Displays a buffer in compilation-mode giving locations of the overriding 
declarations.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier ")
-
-(defun wisi-show-overriding ()
-  "Show all overridings of identifier at point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-overriding
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column)))
-    ))
-
-(cl-defgeneric wisi-xref-overridden (xref project &key identifier filename 
line column)
-  "Returns a list (FILE LINE COLUMN) giving the location of the overridden 
declaration.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier")
-
-(defun wisi-show-overridden ()
-  "Show the overridden declaration of identifier at point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project))
-        (target
-         (wisi-xref-overridden
-          (wisi-prj-xref project)
-          project
-          :identifier (nth 2 id)
-          :filename (file-name-nondirectory (buffer-file-name))
-          :line (line-number-at-pos)
-          :column (save-excursion (goto-char (nth 0 id)) (current-column)))))
-
-    (wisi-goto-source (nth 0 target)
-                     (nth 1 target)
-                     (nth 2 target))
-  ))
-
-;;;; wisi-prj specific methods
-
-(cl-defmethod project-roots ((_project wisi-prj))
-  ;; Not meaningful
-  nil)
-
-(cl-defmethod project-files ((project wisi-prj) &optional dirs)
-  (let (result)
-    (dolist (dir (or dirs
-                    (wisi-prj-source-path project)))
-      (mapc
-       (lambda (absfile)
-        (when (and (not (string-equal "." (substring absfile -1)))
-                   (not (string-equal ".." (substring absfile -2)))
-                   (not (file-directory-p absfile))
-                    (or (null (wisi-prj-file-pred project))
-                       (funcall (wisi-prj-file-pred project) absfile)))
-          (push absfile result)))
-       (when (file-readable-p dir) ;; GNAT puts non-existing dirs on path.
-        (directory-files dir t))))
-    result))
-
-(defun wisi-refresh-prj-cache (not-full)
-  "Refresh all cached data in the current project, and re-select it.
-With prefix arg, very slow refresh operations may be skipped."
-  (interactive "P")
-  (let ((prj (project-current)))
-    (unless (wisi-prj-p prj)
-      (error "current project is not a wisi project"))
-    (wisi-prj-refresh-cache prj not-full)
-    (wisi-prj-select prj)))
-
-(defvar wisi-prj--current-file nil
-  "Current wisi project file (the most recently selected); an
-absolute file name.")
-
-(defun wisi-prj-clear-current ()
-  "Clear the current project selection; make no project current."
-  (interactive)
-  (setq wisi-prj--current-file nil))
-
-(defun wisi-prj-show ()
-  "Show name of current project."
-  (interactive)
-  (message
-   (cond
-    (wisi-prj--current-file
-     (wisi-prj-name (cdr (assoc wisi-prj--current-file wisi-prj--cache))))
-    (t
-     (let ((prj (project-current)))
-       (if (wisi-prj-p prj)
-          (wisi-prj-name prj)
-        "not a wisi project"))))))
-
-(cl-defmethod wisi-prj-parse-final (project _prj-file)
-  (wisi--case-read-all-exceptions project))
-
-(cl-defmethod wisi-prj-refresh-cache ((project wisi-prj) not-full)
-  (when wisi-prj--cache
-    (wisi-prj-deselect project)
-    (let ((prj-file (car (rassoc project wisi-prj--cache))))
-       (setq wisi-prj--cache (delete (cons prj-file project) wisi-prj--cache))
-       (setq project (wisi-prj-default project))
-       (wisi-prj-parse-file :prj-file prj-file :init-prj project :cache t)
-       (wisi-xref-refresh-cache (wisi-prj-xref project) project not-full)
-       (wisi-prj-select project))))
-
-(cl-defmethod wisi-prj-select ((project wisi-prj))
-  (setq compilation-search-path (wisi-prj-source-path project))
-
-  ;; ‘compilation-environment’ is buffer-local, but the user might
-  ;; delete that buffer. So set both global and local.
-  (let ((comp-env
-        (append
-         (wisi-prj-compile-env project)
-         (wisi-prj-file-env project)
-         (copy-sequence (wisi-prj-file-env project))))
-       (comp-buf (get-buffer "*compilation*")))
-    (when (buffer-live-p comp-buf)
-      (with-current-buffer comp-buf
-       (setq compilation-environment comp-env)))
-    (set-default 'compilation-environment comp-env))
-
-  (wisi-compiler-select-prj (wisi-prj-compiler project) project)
-  (wisi-xref-select-prj     (wisi-prj-xref project)     project))
-
-(cl-defmethod wisi-prj-deselect ((project wisi-prj))
-  (wisi-xref-deselect-prj (wisi-prj-xref project) project)
-  (wisi-compiler-deselect-prj (wisi-prj-compiler project) project)
-  (setq compilation-environment nil)
-  (setq compilation-search-path nil))
-
-(defvar wisi-prj-parse-hook nil
-  "Hook run at start of `wisi-prj-parse-file'.")
-
-(defvar wisi-prj-parser-alist (list (cons "prj" #'wisi-prj-parse-file-1))
-  "Alist of parsers for project files, indexed by file extension.
-Parser is called with two arguments; the project file name and
-a project. Parser should update the project with values from the file.")
-
-(cl-defmethod wisi-prj-parse-one (project name value)
-  "If NAME is a wisi-prj slot, set it to VALUE, return t.
-Else return nil."
-  (cond
-   ((string= name "casing")
-    (cl-pushnew (expand-file-name
-                 (substitute-in-file-name value))
-                (wisi-prj-case-exception-files project)
-               :test #'string-equal)
-    t)
-
-   ((string= name "src_dir")
-    (cl-pushnew (directory-file-name (expand-file-name 
(substitute-in-file-name value)))
-                (wisi-prj-source-path project)
-               :test #'string-equal)
-    t)
-
-   ((= ?$ (elt name 0))
-    ;; Process env var.
-    (setf (wisi-prj-file-env project)
-         (cons (concat (substring name 1) "=" (substitute-in-file-name value))
-               (wisi-prj-file-env project)))
-    t)
-
-   ))
-
-(defvar-local wisi-prj-parse-undefined-function nil
-  "Function called if a project file variable name is not recognized.
-Called with three args: PROJECT NAME VALUE.")
-
-(defun wisi-prj-parse-file-1 (prj-file project)
-  "Wisi project file parser."
-  (with-current-buffer (find-file-noselect prj-file)
-    (goto-char (point-min))
-
-    ;; process each line
-    (while (not (eobp))
-
-      ;; ignore lines that don't have the format "name=value", put
-      ;; 'name', 'value' in match-string.
-      (when (looking-at "^\\([^= \n]+\\)=\\(.*\\)")
-       (let ((name (match-string 1))
-             (value (match-string 2))
-             result)
-
-         ;; Both compiler and xref need to see some settings; eg gpr_file, env 
vars.
-         (when (wisi-compiler-parse-one (wisi-prj-compiler project) project 
name value)
-           (setq result t))
-         (when (wisi-xref-parse-one (wisi-prj-xref project) project name value)
-           (setq result t))
-
-         (unless result
-           (setq result (wisi-prj-parse-one project name value)))
-
-         (when (and (not result)
-                    wisi-prj-parse-undefined-function)
-           (funcall wisi-prj-parse-undefined-function project name value))
-
-          ))
-
-      (forward-line 1)
-      )
-    ))
-
-(cl-defun wisi-prj-parse-file (&key prj-file init-prj cache)
-  "Read project file PRJ-FILE with default values from INIT-PRJ.
-PRJ-FILE parser is from `wisi-prj-parser-alist'; if that yields
-no parser, no error occurs; the file is just a placeholder.  If
-CACHE is non-nil, add the project to `wisi-prj--cache'.  In any
-case, return the project."
-  (setq prj-file (expand-file-name prj-file))
-
-  (run-hooks 'wisi-prj-parse-hook)
-
-  (let* ((default-directory (file-name-directory prj-file))
-        (parser (cdr (assoc (file-name-extension prj-file) 
wisi-prj-parser-alist)))
-        (project init-prj)
-        (process-environment (append (wisi-prj-compile-env init-prj) 
process-environment)))
-
-    (when parser
-      ;; If no parser, prj-file is just a placeholder; there is no file to 
parse.
-      ;; For example, sal-android-prj has no project file.
-       (funcall parser prj-file project)
-       (wisi-prj-parse-final project prj-file)
-       (wisi-compiler-parse-final (wisi-prj-compiler project) project prj-file)
-       (wisi-xref-parse-final (wisi-prj-xref project) project prj-file))
-
-    (when cache
-      ;; Cache the project properties
-      (if (assoc prj-file wisi-prj--cache)
-         (setcdr (assoc prj-file wisi-prj--cache) project)
-       (push (cons prj-file project) wisi-prj--cache)))
-
-    project))
-
-(defun wisi-prj-show-prj-path ()
-  "Show the compiler project file search path."
-  (interactive)
-  (wisi-compiler-show-prj-path (wisi-prj-compiler (wisi-prj-require-prj))))
-
-(defun wisi-prj-show-src-path ()
-  "Show the project source file search path."
-  (interactive)
-  (if compilation-search-path
-      (progn
-       (pop-to-buffer (get-buffer-create "*source file search path*"))
-       (erase-buffer)
-       (dolist (file compilation-search-path)
-         (insert (format "%s\n" file))))
-    (message "no source file search path set")
-    ))
-
-(defun wisi-fix-compiler-error ()
-  "Attempt to fix the current compiler error.
-Point must be at the source location referenced in a compiler error.
-In `compilation-last-buffer', point must be at the compiler error.
-Leave point at fixed code."
-  (interactive)
-  (let ((source-buffer (current-buffer))
-       (line-move-visual nil)); screws up next-line otherwise
-
-    (cond
-     ((equal compilation-last-buffer wisi-error-buffer)
-      (set-buffer source-buffer)
-      (wisi-repair-error))
-
-     (t
-      (with-current-buffer compilation-last-buffer
-       (let ((comp-buf-pt (point))
-             (success
-              (wisi-compiler-fix-error
-               (wisi-prj-compiler (wisi-prj-require-prj))
-               source-buffer)))
-         ;; restore compilation buffer point
-         (set-buffer compilation-last-buffer)
-         (goto-char comp-buf-pt)
-
-         (unless success
-           (error "error not recognized"))
-         )))
-      )))
-
-;;;; auto-casing
-
-(defvar-local wisi-auto-case nil
-  "Buffer-local value indicating whether to change case while typing.
-When non-nil, automatically change case of preceding word while
-typing.  Casing of keywords is done according to
-`wisi-case-keyword', identifiers according to
-`wisi-case-identifier'."
-  ;; This is not a defcustom, because it's buffer-local.
-  )
-
-(defvar-local wisi-case-keyword 'lower-case
-  "Indicates how to adjust the case of `wisi-keywords'.
-Value is one of lower-case, upper-case."
-  ;; This is not a defcustom, because it's buffer-local
-  )
-
-(defvar-local wisi-case-identifier 'mixed-case
-  "Buffer-local value indicating how to case language keywords.
-Value is one of:
-
-- mixed-case : Mixed_Case
-- lower-case : lower_case
-- upper-case : UPPER_CASE")
-
-(defvar-local wisi-case-strict t
-  "If nil, preserve uppercase chars in identifiers.")
-
-(defvar-local wisi-language-keywords nil
-  "List of keywords for auto-case.")
-
-(defvar-local wisi-case-adjust-p-function nil
-  "Function taking one argument, the typed char; called from wisi-case-adjust.
-Return non-nil if case of symbol at point should be adjusted.
-Point is on last char of symbol.")
-
-(defun wisi-case-show-files ()
-  "Show casing files list for the current project."
-  (interactive)
-  (let ((project (project-current)))
-
-    (if (and (wisi-prj-p project)
-            (wisi-prj-case-exception-files project))
-       (progn
-         (pop-to-buffer (get-buffer-create "*casing files*"))
-         (erase-buffer)
-         (dolist (file (wisi-prj-case-exception-files project))
-           (insert (format "%s\n" file))))
-      (message "no casing files")
-      )))
-
-(defun wisi--case-save-exceptions (full-exceptions partial-exceptions 
file-name)
-  "Save FULL-EXCEPTIONS, PARTIAL-EXCEPTIONS to the file FILE-NAME."
-  ;; If there is a buffer visiting file-name, it may be out of date
-  ;; due to a previous save-exceptions, which will give a user prompt
-  ;; about editing a file that has changed on disk. Update the buffer
-  (let ((buf (get-file-buffer file-name)))
-    (when buf
-      (with-current-buffer buf
-                       (revert-buffer nil t t))))
-
-  (with-temp-file (expand-file-name file-name)
-    (mapc (lambda (x) (insert (car x) "\n"))
-         (sort (copy-sequence full-exceptions)
-               (lambda(a b) (string< (car a) (car b)))))
-    (mapc (lambda (x) (insert "*" (car x) "\n"))
-         (sort (copy-sequence partial-exceptions)
-               (lambda(a b) (string< (car a) (car b)))))
-    ))
-
-(defun wisi--case-read-exceptions (file-name)
-  "Read the content of the casing exception file FILE-NAME.
-Return (cons full-exceptions partial-exceptions)."
-  (setq file-name (expand-file-name (substitute-in-file-name file-name)))
-  (if (file-readable-p file-name)
-      (let (full-exceptions partial-exceptions word)
-       (with-temp-buffer
-         (insert-file-contents file-name)
-         (while (not (eobp))
-
-           (setq word (buffer-substring-no-properties
-                       (point) (save-excursion (skip-syntax-forward "w_") 
(point))))
-
-           (if (char-equal (string-to-char word) ?*)
-               ;; partial word exception
-               (progn
-                 (setq word (substring word 1))
-                 (unless (assoc-string word partial-exceptions t)
-                   (push (cons word t) partial-exceptions)))
-
-             ;; full word exception
-             (unless (assoc-string word full-exceptions t)
-               (push (cons word t) full-exceptions)))
-
-           (forward-line 1))
-         )
-       (cons full-exceptions partial-exceptions))
-
-    ;; else file not readable; might be a new project with no
-    ;; exceptions yet, so just return empty pair
-    (message "'%s' is not a readable file." file-name)
-    '(nil . nil)
-    ))
-
-(defun wisi--case-merge-exceptions (result new)
-  "Merge NEW exeptions into RESULT.
-An item in both lists has the RESULT value."
-  (dolist (item new)
-    (unless (assoc-string (car item) result t)
-      (push item result)))
-  result)
-
-(defun wisi--case-merge-all-exceptions (exceptions project)
-  "Merge EXCEPTIONS into PROJECT case-full-exceptions, 
case-partial-exceptions."
-  (setf (wisi-prj-case-full-exceptions project)
-       (wisi--case-merge-exceptions (wisi-prj-case-full-exceptions project)
-                                    (car exceptions)))
-  (setf (wisi-prj-case-partial-exceptions project)
-       (wisi--case-merge-exceptions (wisi-prj-case-partial-exceptions project)
-                                    (cdr exceptions))))
-
-(defun wisi--case-read-all-exceptions (project)
-  "Read case exceptions from all files in PROJECT casing files."
-  (setf (wisi-prj-case-full-exceptions project) '())
-  (setf (wisi-prj-case-partial-exceptions project) '())
-
-  (dolist (file (wisi-prj-case-exception-files project))
-    (wisi--case-merge-all-exceptions (wisi--case-read-exceptions file) 
project)))
-
-(defun wisi--case-add-exception (word exceptions)
-  "Add case exception WORD to EXCEPTIONS, replacing current entry, if any."
-  (if (assoc-string word exceptions t)
-      (setcar (assoc-string word exceptions t) word)
-    (push (cons word t) exceptions))
-  exceptions)
-
-(defun wisi-case-create-exception (&optional partial)
-  "Define a word as an auto-casing exception in the current project.
-The word is the active region, or the symbol at point.  If
-PARTIAL is non-nil, create a partial word exception.  User is
-prompted to choose a file from the project case-exception-files
-if it is a list."
-  (interactive)
-  (let* ((project (wisi-prj-require-prj))
-        (file-name
-        (cond
-          ((< 1 (length (wisi-prj-case-exception-files project)))
-           (completing-read "case exception file: " 
(wisi-prj-case-exception-files project)
-                            nil ;; predicate
-                            t   ;; require-match
-                            nil ;; initial-input
-                            nil ;; hist
-                            (car (wisi-prj-case-exception-files project)) ;; 
default
-                            ))
-
-          ((= 1 (length (wisi-prj-case-exception-files project)))
-           (car (wisi-prj-case-exception-files project)))
-
-          (t
-           (error "No exception file specified; set `casing' in project 
file."))
-          ))
-       word)
-
-    (if (use-region-p)
-       (progn
-         (setq word (buffer-substring-no-properties (region-beginning) 
(region-end)))
-         (deactivate-mark))
-      (save-excursion
-       (let ((syntax (if partial "w" "w_")))
-         (skip-syntax-backward syntax)
-         (setq word
-               (buffer-substring-no-properties
-                (point)
-                (progn (skip-syntax-forward syntax) (point))
-                )))))
-
-    (let* ((exceptions (wisi--case-read-exceptions file-name))
-          (file-full-exceptions (car exceptions))
-          (file-partial-exceptions (cdr exceptions)))
-
-      (cond
-       ((null partial)
-       (setf (wisi-prj-case-full-exceptions project)
-             (wisi--case-add-exception word (wisi-prj-case-full-exceptions 
project)))
-       (setq file-full-exceptions (wisi--case-add-exception word 
file-full-exceptions)))
-
-       (t
-       (setf (wisi-prj-case-partial-exceptions project)
-             (wisi--case-add-exception word (wisi-prj-case-partial-exceptions 
project)))
-       (setq file-partial-exceptions (wisi--case-add-exception word 
file-partial-exceptions)))
-
-       )
-      (wisi--case-save-exceptions file-full-exceptions file-partial-exceptions 
file-name)
-      (message "created %s case exception '%s' in file '%s'"
-              (if partial "partial" "full")
-              word
-              file-name)
-      )
-    ))
-
-(defun wisi-case-create-partial-exception ()
-  "Define active region or word at point as a partial word exception.
-User is prompted to choose a file from the project
-case-exception-files if it is a list."
-  (interactive)
-  (wisi-case-create-exception t))
-
-(defun wisi-after-keyword-p ()
-  "Return non-nil if point is after an element of `wisi-language-keywords'."
-  (let ((word (buffer-substring-no-properties
-              (save-excursion (skip-syntax-backward "w_") (point))
-              (point))))
-    (member (downcase word) wisi-language-keywords)))
-
-(defvar-local wisi--ret-binding #'wisi-indent-newline-indent)
-(defvar-local wisi--lfd-binding #'newline-and-indent)
-
-(defun wisi-case-keyword (beg end)
-  (cl-ecase wisi-case-keyword
-    (lower-case (downcase-region beg end))
-    (upper-case (upcase-region beg end))
-    ))
-
-(defun wisi-case-identifier (start end case-strict)
-  (cl-ecase wisi-case-identifier
-    (mixed-case (wisi-mixed-case start end case-strict))
-    (lower-case (downcase-region start end))
-    (upper-case (upcase-region start end))
-    ))
-
-(defun wisi-mixed-case (start end case-strict)
-  "Adjust case of region START END to Mixed_Case."
-  (let ((done nil)
-       next)
-    (if (or case-strict wisi-case-strict)
-       (downcase-region start end))
-    (goto-char start)
-    (while (not done)
-      (setq next
-           (or
-            (save-excursion (when (search-forward "_" end t) (point-marker)))
-            (copy-marker (1+ end))))
-
-      ;; upcase first char
-      (upcase-region (point) (1+ (point)))
-
-      (goto-char next)
-      (if (< (point) end)
-         (setq start (point))
-       (setq done t))
-      )))
-
-(defun wisi-case-adjust-identifier (&optional force-case)
-  "Adjust case of the previous word as an identifier.
-Uses `wisi-case-identifier', with exceptions defined in
-`wisi-case-full-exceptions', `wisi-case-partial-exceptions'.  If
-force-case non-nil (default prefix), treat `wisi-strict-case' as
-t."
-  (interactive "P")
-  (save-excursion
-    ;; We don't complain when there is no project; we may be editing a
-    ;; random Ada file.
-    (let ((prj (wisi-prj-current-prj))
-         (end   (point-marker))
-         (start (progn (skip-syntax-backward "w_") (point)))
-         match
-         next
-         (done nil))
-
-      (if (setq match
-               (assoc-string (buffer-substring-no-properties start end)
-                             (wisi-prj-case-full-exceptions prj)
-                             t ;; case-fold
-                             ))
-         ;; full word exception
-         (progn
-           ;; 'save-excursion' puts a marker at 'end'; if we do
-           ;; 'delete-region' first, it moves that marker to 'start',
-           ;; then 'insert' inserts replacement text after the
-           ;; marker, defeating 'save-excursion'. So we do 'insert' first.
-           (insert (car match))
-           (delete-region (point) end))
-
-       ;; else apply wisi-case-identifier
-       (wisi-case-identifier start end force-case)
-
-       ;; apply partial-exceptions
-       (goto-char start)
-       (while (not done)
-         (setq next
-               (or
-                (save-excursion (when (search-forward "_" end t) 
(point-marker)))
-                (copy-marker (1+ end))))
-
-         (when (setq match (assoc-string (buffer-substring-no-properties start 
(1- next))
-                                         (wisi-prj-case-partial-exceptions prj)
-                                         t))
-           ;; see comment above at 'full word exception' for why
-           ;; we do insert first.
-           (insert (car match))
-           (delete-region (point) (1- next)))
-
-         (goto-char next)
-         (if (< (point) end)
-             (setq start (point))
-           (setq done t))
-          ))
-      )))
-
-(defun wisi-case-adjust-keyword ()
-  "Adjust the case of the previous symbol as a keyword."
-  (save-excursion
-    (let ((end   (point-marker))
-         (start (progn (skip-syntax-backward "w_") (point))))
-      (wisi-case-keyword start end)
-    )))
-
-(defun wisi-case-adjust (&optional typed-char in-comment)
-  "Adjust the case of the symbol before point.
-When invoked interactively, TYPED-CHAR must be
-`last-command-event', and it must not have been inserted yet.  If
-IN-COMMENT is non-nil, adjust case of words in comments and
-strings as code, and treat `wisi-case-strict' as t in code."
-  (when (not (bobp))
-    (when (save-excursion
-           (forward-char -1); back to last character in symbol
-           (and (not (bobp))
-                (eq (char-syntax (char-after)) ?w); it can be capitalized
-
-                (or in-comment
-                    (not (wisi-in-string-or-comment-p)))
-
-                (or (null wisi-case-adjust-p-function)
-                    (funcall wisi-case-adjust-p-function typed-char))
-                ))
-
-      ;; The indentation engine may trigger a reparse on
-      ;; non-whitespace changes, but we know we don't need to reparse
-      ;; for this change (assuming the user has not abused case
-      ;; exceptions!).
-      (let ((inhibit-modification-hooks t))
-       (cond
-        ;; Some attributes are also keywords, but captialized as
-        ;; attributes. So check for attribute first.
-        ((and
-          (not in-comment)
-          (save-excursion
-            (skip-syntax-backward "w_")
-            (eq (char-before) ?')))
-         (wisi-case-adjust-identifier in-comment))
-
-        ((and
-          (not in-comment)
-          (not (eq typed-char ?_))
-          (wisi-after-keyword-p))
-         (wisi-case-adjust-keyword))
-
-        (t (wisi-case-adjust-identifier in-comment))
-        ))
-      )))
-
-(defun wisi-case-adjust-at-point (&optional in-comment)
-  "If ’wisi-auto-case’ is non-nil, adjust case of symbol at point.
-Also move to end of symbol.  With prefix arg, adjust case as code
-even if in comment or string; otherwise, capitalize words in
-comments and strings.  If ’wisi-auto-case’ is nil, capitalize
-current word."
-  (interactive "P")
-  (cond
-   ((or (null wisi-auto-case)
-       (and (not in-comment)
-            (wisi-in-string-or-comment-p)))
-    (skip-syntax-backward "w_")
-    (capitalize-word 1))
-
-   (t
-    (when
-       (and (not (eobp))
-            ;; We use '(syntax-after (point))' here, not '(char-syntax
-            ;; (char-after))', because the latter does not respect
-            ;; syntax-propertize functions
-            (memq (syntax-class (syntax-after (point))) '(2 3)))
-      (skip-syntax-forward "w_"))
-    (wisi-case-adjust nil in-comment))
-   ))
-
-(defun wisi-case-adjust-region (begin end)
-  "Adjust case of all words in region BEGIN END."
-  (interactive "r")
-  (narrow-to-region begin end)
-  (save-excursion
-    (goto-char begin)
-    (while (not (eobp))
-      (forward-comment (point-max))
-      (skip-syntax-forward "^w_")
-      (skip-syntax-forward "w_")
-      (wisi-case-adjust)))
-  (widen))
-
-(defun wisi-case-adjust-buffer ()
-  "Adjust case of current buffer."
-  (interactive)
-  (wisi-case-adjust-region (point-min) (point-max)))
-
-(defun wisi-case-adjust-interactive (arg)
-  "If `wisi-auto-case' is non-nil, adjust the case of the previous symbol,
-and process the character just typed.  To be bound to keys that
-should cause auto-casing.  ARG is the prefix the user entered
-with \\[universal-argument]."
-  (interactive "P")
-
-  ;; Character typed has not been inserted yet.
-  (let ((lastk last-command-event)
-       (do-adjust nil))
-    (cond
-     ((null wisi-auto-case))
-     (t
-      (setq do-adjust t)))
-
-    (cond
-     ((eq lastk ?\n)
-        (when do-adjust
-         (wisi-case-adjust lastk))
-       (funcall wisi--lfd-binding))
-
-     ((memq lastk '(?\r return))
-      (when do-adjust
-       (wisi-case-adjust lastk))
-      (funcall wisi--ret-binding))
-
-     (t
-      (when do-adjust
-       (wisi-case-adjust lastk))
-      (self-insert-command (prefix-numeric-value arg)))
-     )))
-
-(defun wisi-case-activate-keys (map)
-  "Modify the key bindings for all the keys that should adjust casing."
-  (mapc (function
-        (lambda(key)
-          (define-key
-            map
-            (char-to-string key)
-            'wisi-case-adjust-interactive)))
-       '( ?_ ?% ?& ?* ?\( ?\) ?- ?= ?+
-             ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?/ ?\n 32 ?\r ))
-  )
-
-;;;; xref backend
-
-(defconst wisi-file-line-col-regexp
-  ;; matches Gnu-style file references:
-  ;; 
C:\Projects\GDS\work_dscovr_release\common\1553\gds-mil_std_1553-utf.ads:252:25
-  ;; 
/Projects/GDS/work_dscovr_release/common/1553/gds-mil_std_1553-utf.ads:252:25
-  ;; gds-mil_std_1553-utf.ads:252:25 - when wisi-xref-full-path is nil
-  "\\(\\(?:.:\\\\\\|/\\)?[^:]*\\):\\([0-9]+\\):\\([0-9]+\\)"
-  ;; 1                              2            3
-  "Regexp matching <file>:<line>:<column> where <file> is an absolute file 
name or basename.")
-
-(defun wisi-xref-item (identifier prj)
-  "Given IDENTIFIER, return an xref-item, with line, column nil if unknown.
-IDENTIFIER is from a user prompt with completion, or from
-`xref-backend-identifier-at-point'."
-  (let* ((t-prop (get-text-property 0 'xref-identifier identifier))
-        ident file line column)
-    (cond
-     (t-prop
-      ;; IDENTIFIER is from wisi-xref-identifier-at-point.
-      (setq ident (substring-no-properties identifier 0 nil))
-      (setq file (plist-get t-prop :file))
-      (setq line (plist-get t-prop :line))
-      (setq column (plist-get t-prop :column))
-      )
-
-     ((string-match (wisi-xref-completion-regexp (wisi-prj-xref prj)) 
identifier)
-      ;; IDENTIFIER is from prompt/completion on wisi-xref-completion-table
-      (setq ident (match-string 1 identifier))
-
-      (let* ((table (wisi-xref-completion-table (wisi-prj-xref prj) prj))
-            (loc (cdr (assoc identifier table))))
-
-       (setq file (nth 0 loc))
-       (setq line (nth 1 loc))
-       (setq column (nth 2 loc))
-       ))
-
-     ((string-match wisi-names-regexp identifier)
-      ;; IDENTIFIER is from prompt/completion on wisi-names.
-      (setq ident (match-string 1 identifier))
-      (setq file (buffer-file-name))
-      (when (match-string 2 identifier)
-       (setq line (string-to-number (match-string 2 identifier))))
-      )
-
-     (t
-      ;; IDENTIFIER has no line/column info
-      (setq ident identifier)
-      (setq file (buffer-file-name)))
-     )
-
-    (unless (file-name-absolute-p file)
-      (setq file (locate-file file compilation-search-path)))
-
-    (let ((eieio-skip-typecheck t)) ;; allow line, column nil.
-      (xref-make ident (xref-make-file-location file line column)))
-    ))
-
-(cl-defmethod xref-backend-definitions ((prj wisi-prj) identifier)
-  (wisi-xref-definitions (wisi-prj-xref prj) prj (wisi-xref-item identifier 
prj)))
-
-(cl-defmethod xref-backend-identifier-at-point ((prj wisi-prj))
-  (save-excursion
-    (let ((id (wisi-prj-identifier-at-point prj)))
-      (when id
-       (put-text-property
-        0 1
-        'xref-identifier
-        (list ':file (buffer-file-name)
-              ':line (line-number-at-pos)
-              ':column (save-excursion (goto-char (nth 0 id)) 
(current-column)))
-        (nth 2 id))
-       (nth 2 id)))))
-
-(cl-defmethod xref-backend-identifier-completion-table ((prj wisi-prj))
-  (wisi-filter-table (wisi-xref-completion-table (wisi-prj-xref prj) prj)
-                    (when (equal '(16) current-prefix-arg) 
(buffer-file-name))))
-
-(cl-defmethod xref-backend-references  ((prj wisi-prj) identifier)
-  (wisi-xref-references (wisi-prj-xref prj) prj (wisi-xref-item identifier 
prj)))
-
-;;;###autoload
-(defun wisi-prj-xref-backend ()
-  "For `xref-backend-functions'; return the current wisi project."
-  ;; We return the project, not the xref object, because the
-  ;; wisi-xref-* functions need the project.
-  (let ((prj (project-current)))
-    (when (wisi-prj-p prj)
-      prj)))
-
-;;;; project-find-functions alternatives
-
-(defvar wisi-prj--dominating-alist nil
-"Alist of (DOMINATING-FILE . PRJ-FILE-NAME): DOMINATING-FILE is
-an absolute filename that can be found by
-`wisi-prj-find-dominating-cached' or
-`wisi-prj-find-dominating-cached'.  PRJ-FILE-NAME is the wisi
-project file for the project for that file.")
-
-;;;###autoload
-(defun wisi-prj-select-cache (prj-file init-prj &optional dominating-file)
-  "Select project matching PRJ-FILE in `wisi-prj--cache' as current project,
-parsing and caching if needed. Also add DOMINATING-FILE (default
-current buffer file name) to `wisi-prj--dominating-alist' (for
-`wisi-prj-select-dominating'.)"
-  (let ((old-prj (project-current)))
-    ;; If old-prj is not a wisi-prj, we don't know how to deselect it;
-    ;; just ignore that.  If prj-file is the current file, user is
-    ;; re-selecting it.
-    (when (wisi-prj-p old-prj)
-      (wisi-prj-deselect old-prj)))
-
-  (unless (or (memq #'wisi-prj-current-cached project-find-functions)
-             (memq #'wisi-prj-current-cached (default-value 
'project-find-functions)))
-    (message "wisi-prj-select-cache used without wisi-prj-current-cached in 
project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-
-  (let ((new-prj (cdr (assoc prj-file wisi-prj--cache))))
-    (unless new-prj
-      (setq new-prj (wisi-prj-parse-file :prj-file prj-file :init-prj init-prj 
:cache t))
-      (unless new-prj
-       (error "parsing project file '%s' failed" prj-file)))
-
-    (setq wisi-prj--current-file prj-file)
-    (wisi-prj-select new-prj)))
-
-;;;###autoload
-(defun wisi-prj-select-dominating (&optional dominating-file)
-  "Unless it is already current, select a wisi-prj matching DOMINATING-FILE.
-DOMINATING-FILE defaults to the current buffer file name.
-Useful before running `compilation-start', to ensure the correct
-project is current."
-  (when (or dominating-file (buffer-file-name))
-    ;; buffer-file-name is nil in *compilation* buffer
-    (let ((prj-file (cdr (assoc (or dominating-file (buffer-file-name)) 
wisi-prj--dominating-alist))))
-      (unless (string-equal prj-file wisi-prj--current-file)
-       (message "Switching to project file '%s'" prj-file)
-       (let ((old-prj (cdr (assoc  wisi-prj--current-file wisi-prj--cache)))
-             (new-prj (cdr (assoc prj-file wisi-prj--cache))))
-         (when (wisi-prj-p old-prj)
-           (wisi-prj-deselect old-prj))
-         (when (wisi-prj-p new-prj)
-           (wisi-prj-select new-prj))
-         (setq wisi-prj--current-file prj-file))))))
-
-;;;###autoload
-(defun wisi-prj-current-cached (_dir)
-  "For `project-find-functions'; return the current project from 
`wisi-prj--cache'."
-  (cdr (assoc wisi-prj--current-file wisi-prj--cache)))
-
-(defvar wisi-prj--default nil
-  "Alist of (PRJ-FILE . INIT-PRJ), for `wisi-prj-parse-current'.
-PRJ-FILE is an absolute project file name; INIT-PRJ is the
-initial `wisi-prj' object for that project file.")
-
-;;;###autoload
-(defun wisi-prj-select-file (prj-file default-prj &optional dominating-file)
-  "Set PRJ-FILE as current project, add DEFAULT-PRJ to `wisi-prj--default'.
-Also add DOMINATING-FILE (default current buffer file name) to
-`wisi-prj--dominating-alist' (for `wisi-prj-select-dominating'.)"
-  (unless (or (memq #'wisi-prj-current-parse project-find-functions)
-             (memq #'wisi-prj-current-parse (default-value 
'project-find-functions)))
-    (message "wisi-prj-select-file used without wisi-prj-current-parse in 
project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-  (setq wisi-prj--current-file prj-file)
-  (add-to-list 'wisi-prj--default (cons prj-file default-prj)))
-
-;;;###autoload
-(defun wisi-prj-current-parse (_dir)
-  "For `project-find-functions'; parse the current project file, select and 
return the project"
-  (let ((prj (wisi-prj-parse-file
-             :prj-file wisi-prj--current-file
-             :init-prj (cdr (assoc-string wisi-prj--current-file 
wisi-prj--default))
-             :cache nil)))
-    (wisi-prj-select prj)
-    prj))
-
-(defvar wisi-prj--dominating nil
-  "List of relative filenames for `wisi-prj-find-dominating-cached'
-and `wisi-prj-find-dominating-parse'. Set by `wisi-prj-set-dominating'.")
-
-(defun wisi-prj-reset-cache ()
-  "Delete all wisi project cached info."
-  (interactive)
-  (setq wisi-prj--cache nil)
-  (setq wisi-prj--current-file nil)
-  (setq wisi-prj--default nil)
-  (setq wisi-prj--dominating nil)
-  (setq wisi-prj--dominating-alist nil))
-
-;;;###autoload
-(defun wisi-prj-cache-dominating (prj-file default-prj &optional 
dominating-file)
-  "Parse prj-file, add to `wisi-prj--cache'.
-Also add (DOMINATING-FILE . PRJ-FILE) to `wisi-prj--dominating-alist'.
-DOMINATING-FILE defaults to (buffer-file-name). "
-  (unless (or (memq #'wisi-prj-find-dominating-cached project-find-functions)
-             (memq #'wisi-prj-find-dominating-cached (default-value 
'project-find-functions)))
-    (message "wisi-prj-cache-dominating used without 
wisi-prj-find-dominating-cached in project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating (file-name-nondirectory dominating-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-  (wisi-prj-parse-file :prj-file prj-file :init-prj default-prj :cache t)
-  nil)
-
-(defun wisi-prj--find-dominating-file (start-dir)
-  "Return the project file matching `wisi-prj--dominating'."
-  (let* (dom-file
-        (_dom-dir
-         (locate-dominating-file
-          start-dir
-          (lambda (dir)
-            (let ((names wisi-prj--dominating))
-              (while names
-                (let ((filename (expand-file-name (pop names) dir)))
-                  (when (file-exists-p filename)
-                    (setq dom-file filename)
-                    (setq names nil)))))
-            dom-file))))
-    (cdr (assoc-string dom-file wisi-prj--dominating-alist))))
-
-;;;###autoload
-(defun wisi-prj-find-dominating-cached (dir)
-  "For `project-find-functions'; return the cached project
-matching `wisi-prj--dominating' (nil if none). Select it if it is
-not the current project."
-  (let* ((prj-file (wisi-prj--find-dominating-file dir))
-        (new-prj (cdr (assoc-string prj-file wisi-prj--cache))))
-    (when prj-file
-      (unless (string= prj-file wisi-prj--current-file)
-       (let ((old-prj (cdr (assoc-string wisi-prj--current-file 
wisi-prj--cache))))
-         (when old-prj (wisi-prj-deselect old-prj))
-         (unless new-prj
-           ;; User may have used `wisi-prj-set-dominating' instead of
-           ;; `wisi-prj-cache-dominating'; parse the project file now.
-           (wisi-prj-parse-file
-            :prj-file prj-file
-            :init-prj (cdr (assoc-string prj-file wisi-prj--default))
-            :cache t))
-         (when new-prj (wisi-prj-select new-prj))))
-      new-prj)))
-
-;;;###autoload
-(defun wisi-prj-set-dominating (prj-file default-prj &optional dom-file)
-  "Add (DOM-FILE . PRJ-FILE) to `wisi-prj--dominating-alist',
-and (PRJ-FILE . DEFAULT-PRJ) to `wisi-prj--default'.
-DOM-FILE defaults to (buffer-file-name).
-For example, call this in the Local Vars of a Makefile to
-associate a project with that Makefile."
-  (unless (or (memq #'wisi-prj-find-dominating-parse project-find-functions)
-             (memq #'wisi-prj-find-dominating-parse (default-value 
'project-find-functions)))
-    (message "wisi-prj-cache-dominating used without 
wisi-prj-find-dominating-parse in project-find-functions"))
-
-  (setq dom-file (if dom-file (expand-file-name dom-file) (buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating (file-name-nondirectory dom-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dom-file prj-file))
-  (add-to-list 'wisi-prj--default (cons prj-file default-prj))
-  nil)
-
-;;;###autoload
-(defun wisi-prj-find-dominating-parse (dir)
-  "For `project-find-functions'; parse, select, and return the project
-file matching `wisi-prj--dominating'."
-  (let ((prj-file (wisi-prj--find-dominating-file dir)))
-    (when prj-file
-      (let ((prj (wisi-prj-parse-file
-                 :prj-file prj-file
-                 :init-prj (cdr (assoc-string prj-file wisi-prj--default))
-                 :cache nil)))
-       (wisi-prj-select prj)
-       prj))))
-
-;;;###autoload
-(defun wisi-prj-dtrt-parse-file (prj-file default-prj dominating-file 
&optional dir)
-  "Depending on wisi-prj function in `project-find-functions',
-Do The Right Thing to make PRJ-FILE active and selected; return the project."
-  (cond
-   ((memq #'wisi-prj-find-dominating-parse project-find-functions)
-    (wisi-prj-set-dominating prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-find-dominating-cached project-find-functions)
-    (wisi-prj-cache-dominating prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-current-cached project-find-functions)
-    (wisi-prj-select-cache prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-current-parse project-find-functions)
-    (wisi-prj-select-file prj-file default-prj dominating-file))
-
-   (t
-    (user-error "No wisi-prj function in project-find-functions"))
-   )
-  (project-current nil (or dir default-directory)))
-
-;;;###autoload
-(defun wisi-prj-find-function-set-p ()
-  "Return non-nil if a wisi-prj function is present in 
`project-find-functions'."
-  (or (memq #'wisi-prj-find-dominating-parse project-find-functions)
-      (memq #'wisi-prj-find-dominating-cached project-find-functions)
-      (memq #'wisi-prj-current-cached project-find-functions)
-      (memq #'wisi-prj-current-parse project-find-functions)))
-
-;;;; project menu
-
-(defun wisi-prj--menu-compute ()
-  "Return an easy-menu menu for `wisi-prj-menu--install'.
-Menu displays cached wisi projects."
-  (let (menu)
-    (dolist (item wisi-prj--cache)
-      (push
-       (vector
-       (concat (wisi-prj-name (cdr item))
-               (when (equal (car item) wisi-prj--current-file) "  *")) ;; 
current project
-       `(lambda () (interactive)
-          (when wisi-prj--current-file
-            (wisi-prj-deselect (cdr (assoc wisi-prj--current-file 
wisi-prj--cache))))
-          (setq wisi-prj--current-file ,(car item))
-          (wisi-prj-select ,(cdr item)))
-       t)
-       menu)
-      )
-    (nreverse menu)))
-
-(defun wisi-prj-menu-install ()
-  "Install the project menu if appropriate, to display cached wisi projects."
-  (when
-      (or (memq #'wisi-prj-find-dominating-cached project-find-functions)
-         (memq #'wisi-prj-current-cached project-find-functions))
-
-    (let ((menu (wisi-prj--menu-compute)))
-      (if menu
-         (define-key-after
-           global-map
-           [menu-bar wisi-prj-select]
-           (easy-menu-binding
-            (easy-menu-create-menu
-             "Wisi Prj Select";; EDE uses "Project" menu
-             menu))
-           (lookup-key global-map [menu-bar tools]))
-       ;; delete empty menu
-         (define-key-after
-           global-map
-           [menu-bar wisi-prj-select]
-           nil
-           (lookup-key global-map [menu-bar tools]))
-       ))
-    ))
-
-(add-hook 'menu-bar-update-hook 'wisi-prj-menu-install)
-
-(defun wisi-prj-completion-table ()
-  "Return list of names of cached projects."
-  (mapcar (lambda (item) (wisi-prj-name (cdr item))) wisi-prj--cache))
-
-(defun wisi-prj-delete (name)
-  "Delete project NAME (default prompt) from the cached projects."
-  (interactive (list (completing-read "project name: " 
(wisi-prj-completion-table))))
-  (let (pair)
-    (dolist (item wisi-prj--cache)
-      (if (string= name (wisi-prj-name (cdr item)))
-         (setq pair item)))
-
-    (setq wisi-prj--cache (delete pair wisi-prj--cache))
-
-    (setq wisi-prj--dominating-alist
-         (cl-delete-if (lambda (item)
-                         (string= (car pair) (cdr item)))
-                       wisi-prj--dominating-alist))
-    ))
-
-(provide 'wisi-prj)
-;; end wisi-prj.el
diff --git a/packages/wisi/wisi-process-parse.el 
b/packages/wisi/wisi-process-parse.el
deleted file mode 100644
index bddd033..0000000
--- a/packages/wisi/wisi-process-parse.el
+++ /dev/null
@@ -1,844 +0,0 @@
-;;; wisi-process-parse.el --- interface to external parse program
-;;
-;; Copyright (C) 2014, 2017 - 2020 Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-(require 'cl-lib)
-(require 'wisi-parse-common)
-
-(defgroup wisi nil
-  "Options for Wisi package."
-  :group 'programming)
-
-(defcustom wisi-process-time-out 5.0
-  "Time out waiting for parser response. An error occurs if there
-  is no response from the parser after waiting this amount (in
-  seconds)."
-  :type 'float
-  :safe 'numberp)
-(make-variable-buffer-local 'wisi-process-time-out)
-
-(defconst wisi-process-parse-protocol-version "5"
-  "Defines data exchanged between this package and the background process.
-Must match emacs_wisi_common_parse.ads Protocol_Version.")
-
-(defconst wisi-process-parse-prompt "^;;> "
-  "Regexp matching executable prompt; indicates previous command is complete.")
-
-(defconst wisi-process-parse-quit-cmd "004quit\n"
-  "Command to external process telling it to quit.")
-
-;;;;; sessions
-
-;; The executable builds internal parser structures on startup,
-;; then runs a loop, waiting for parse requests.
-;;
-;; We only need one process per language; there is no persistent state
-;; in the process between parses, and processes are too heavy-weight
-;; to have one per buffer. We use a global alist of parser objects to
-;; find the right one for the current buffer.
-
-(cl-defstruct (wisi-process--parser (:include wisi-parser))
-  (label nil)             ;; string uniquely identifying parser
-  language-protocol-version ;; string identifying language-specific params
-  (exec-file nil)        ;; absolute file name of executable
-  (exec-opts nil)         ;; list of process start options for executable
-  (token-table nil)       ;; vector of token symbols, indexed by integer
-  (face-table nil)       ;; vector of face symbols, indexed by integer
-  (busy nil)              ;; t while parser is active
-  (process nil)          ;; running *_wisi_parse executable
-  (buffer nil)                   ;; receives output of executable
-  line-begin              ;; vector of beginning-of-line positions in buffer
-  (total-wait-time 0.0)   ;; total time during last parse spent waiting for 
subprocess output.
-  (response-count 0)      ;; responses received from subprocess during last 
parse; for profiling.
-  end-pos                 ;; last character position parsed
-  language-action-table   ;; array of function pointers, each taking an sexp 
sent by the process
-  )
-
-(defvar wisi-process--alist nil
-  "Alist mapping string label to ‘wisi-process--session’ struct")
-
-;;;###autoload
-(defun wisi-process-parse-get (parser)
-  "Return a ‘wisi-process--parser’ object matching PARSER label.
-If label found in ‘wisi-process--alist’, return that.
-Otherwise add PARSER to ‘wisi-process--alist’, return it."
-  (or (cdr (assoc (wisi-process--parser-label parser) wisi-process--alist))
-      (let ((exec-file (locate-file (wisi-process--parser-exec-file parser) 
exec-path '("" ".exe"))))
-
-       (unless exec-file
-         (error "%s not found on `exec-path'; run 'build.sh' in the ELPA 
package."
-                (wisi-process--parser-exec-file parser)))
-
-       (push (cons (wisi-process--parser-label parser) parser) 
wisi-process--alist)
-
-       parser
-     )))
-
-(defun wisi-process-parse-set-exec (label exec-file)
-  "Change the EXEC-FILE for parsers with LABEL."
-  (let ((parser (cdr (assoc label wisi-process--alist))))
-    (when parser
-      (wisi-parse-kill parser)
-      (setf (wisi-process--parser-exec-file parser) exec-file))))
-
-(defun wisi-process-parse--check-version (parser)
-  "Verify protocol version reported by process."
-  ;; The process has just started; the first non-comment line in the
-  ;; process buffer contains the process and language protocol versions.
-  (with-current-buffer (wisi-process--parser-buffer parser)
-    (goto-char (point-min))
-    (if (search-forward-regexp "protocol: process version \\([0-9]+\\) 
language version \\([0-9]+\\)" nil t)
-       (unless (and (match-string 1)
-                    (string-equal (match-string 1) 
wisi-process-parse-protocol-version)
-                    (match-string 2)
-                    (string-equal (match-string 2) 
(wisi-process--parser-language-protocol-version parser)))
-         (wisi-parse-kill parser)
-         (error "%s parser process protocol version mismatch: elisp %s %s, 
process %s %s"
-                (wisi-process--parser-label parser)
-                wisi-process-parse-protocol-version 
(wisi-process--parser-language-protocol-version parser)
-                (match-string 1) (match-string 2)))
-      ;; Search failed
-      (error "%s parser process protocol version message not found"
-            (wisi-process--parser-label parser))
-    )))
-
-(defun wisi-process-parse--require-process (parser)
-  "Start the process for PARSER if not already started."
-  (unless (process-live-p (wisi-process--parser-process parser))
-    (let ((process-connection-type nil) ;; use a pipe, not a pty; avoid 
line-by-line reads
-         (process-name (format " *%s_wisi_parse*" (wisi-process--parser-label 
parser))))
-
-      (unless (buffer-live-p (wisi-process--parser-buffer parser))
-       ;; User may have killed buffer to kill parser.
-       (setf (wisi-process--parser-buffer parser)
-             (get-buffer-create process-name)))
-
-      (with-current-buffer (wisi-process--parser-buffer parser)
-       (erase-buffer)); delete any previous messages, prompt
-
-      (setf (wisi-process--parser-process parser)
-           (make-process
-            :name process-name
-            :buffer (wisi-process--parser-buffer parser)
-            :command (append (list (wisi-process--parser-exec-file parser))
-                             (wisi-process--parser-exec-opts parser))))
-
-      (set-process-query-on-exit-flag (wisi-process--parser-process parser) 
nil)
-
-      (wisi-process-parse--wait parser)
-      (wisi-process-parse--check-version parser)
-      )))
-
-(defun wisi-process-parse--wait (parser)
-  "Wait for the current command to complete."
-  (let ((process (wisi-process--parser-process parser))
-       (search-start (point-min))
-       (wait-count 0)
-       (found nil))
-
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (while (and (process-live-p process)
-                 (progn
-                   ;; process output is inserted before point, so move back 
over it to search it
-                   (goto-char search-start)
-                   (not (setq found (re-search-forward 
wisi-process-parse-prompt (point-max) t)))))
-       (setq search-start (point));; don't search same text again
-       (setq wait-count (1+ wait-count))
-       (accept-process-output process 0.1))
-
-      (unless found
-       (wisi-process-parse-show-buffer parser)
-       (error "%s process died" (wisi-process--parser-exec-file parser)))
-      )))
-
-(defun wisi-process-parse-show-buffer (parser)
-  "Show PARSER buffer."
-  (if (buffer-live-p (wisi-process--parser-buffer parser))
-      (pop-to-buffer (wisi-process--parser-buffer parser))
-    (error "wisi-process-parse process not active")))
-
-(defun wisi-process-parse--send-parse (parser begin send-end parse-end)
-  "Send a parse command to PARSER external process, followed by
-the content of the current buffer from BEGIN thru SEND-END.  Does
-not wait for command to complete. PARSE-END is end of desired
-parse region."
-  ;; Must match "parse" command arguments read by
-  ;; emacs_wisi_common_parse.adb Get_Parse_Params.
-  (let* ((cmd (format "parse %d \"%s\" %d %d %d %d %d %d %d %d %d %d %d %d %d 
%d %d %d %d %d %s"
-                     (cl-ecase wisi--parse-action
-                       (navigate 0)
-                       (face 1)
-                       (indent 2))
-                     (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                     (position-bytes begin)
-                     (position-bytes send-end)
-                     (position-bytes parse-end)
-                     begin ;; char_pos
-                     (line-number-at-pos begin)
-                     (line-number-at-pos send-end)
-                     (save-excursion (goto-char begin) (back-to-indentation) 
(current-column));; indent-begin
-                     (if (or (and (= begin (point-min)) (= parse-end 
(point-max)))
-                             (< (point-max) wisi-partial-parse-threshold))
-                         0 1) ;; partial parse active
-                     (if (> wisi-debug 0) 1 0) ;; debug_mode
-                     (1- wisi-debug) ;; trace_parse
-                     wisi-trace-mckenzie
-                     wisi-trace-action
-                     (if wisi-mckenzie-disable 1 0)
-                     (or wisi-mckenzie-task-count -1)
-                     (or wisi-mckenzie-check-limit -1)
-                     (or wisi-mckenzie-enqueue-limit -1)
-                     (or wisi-parse-max-parallel -1)
-                     (- (position-bytes send-end) (position-bytes begin)) ;; 
send-end is after last byte
-                     (wisi-parse-format-language-options parser)
-                     ))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties begin 
send-end))
-
-    ;; We don’t wait for the send to complete; the external process
-    ;; may start parsing and send an error message.
-    ))
-
-(defun wisi-process-parse--send-refactor (parser refactor-action parse-begin 
parse-end edit-begin)
-  "Send a refactor command to PARSER external process, followed
-by the content of the current buffer from PARSE-BEGIN thru
-PARSE-END, wait for command to complete. PARSER will respond with
-one or more Edit messages."
-  ;; Must match "refactor" command arguments read by
-  ;; emacs_wisi_common_parse.adb Get_Refactor_Params.
-  (let* ((cmd (format "refactor %d \"%s\" %d %d %d %d %d %d %d %d %d %d %d %d"
-                     refactor-action
-                     (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                     (position-bytes parse-begin)
-                     (position-bytes parse-end)
-                     (position-bytes edit-begin)
-                     parse-begin ;; char_pos
-                     (line-number-at-pos parse-begin)
-                     (line-number-at-pos parse-end)
-                     (save-excursion (goto-char parse-begin) 
(back-to-indentation) (current-column));; indent-begin
-                     (if (> wisi-debug 0) 1 0) ;; debug-mode
-                     (1- wisi-debug) ;; trace_parse
-                     wisi-trace-action
-                     (or wisi-parse-max-parallel -1)
-                     (- (position-bytes parse-end) (position-bytes 
parse-begin)) ;; parse-end is after last byte
-                     ))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties parse-begin 
parse-end))
-    (wisi-process-parse--wait parser)
-    ))
-
-(defun wisi-process-parse--send-noop (parser)
-  "Send a noop command to PARSER external process, followed by
-the content of the current buffer.  Does not wait for command to
-complete."
-  (let* ((cmd (format "noop %d" (1- (position-bytes (point-max)))))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties (point-min) 
(point-max)))
-    ))
-
-(defun wisi-process-parse--marker-or-nil (item)
-  (if (= -1 item) nil (copy-marker item t)))
-
-(defun wisi-process-parse--Navigate_Cache (parser sexp)
-  ;; sexp is [Navigate_Cache pos statement_id id length class containing_pos 
prev_pos next_pos end_pos]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1)))
-    (with-silent-modifications
-      (put-text-property
-       pos
-       (1+ pos)
-       'wisi-cache
-       (wisi-cache-create
-       :nonterm    (aref (wisi-process--parser-token-table parser) (aref sexp 
2))
-       :token      (aref (wisi-process--parser-token-table parser) (aref sexp 
3))
-       :last       (aref sexp 4)
-       :class      (aref wisi-class-list (aref sexp 5))
-       :containing (wisi-process-parse--marker-or-nil (aref sexp 6))
-       :prev       (wisi-process-parse--marker-or-nil (aref sexp 7))
-       :next       (wisi-process-parse--marker-or-nil (aref sexp 8))
-       :end        (wisi-process-parse--marker-or-nil (aref sexp 9))
-       )))
-    ))
-
-(defun wisi-process-parse--Name_Property (parser sexp)
-  ;; sexp is [Name_Property first-pos last-pos]
-  ;; see ‘wisi-process-parse--execute’
-  ;; implements wisi-name-action
-  (with-silent-modifications
-    (put-text-property (aref sexp 1) (1+ (aref sexp 2)) 'wisi-name t)))
-
-(defun wisi-process-parse--Face_Property (parser sexp)
-  ;; sexp is [Face_Property first-pos last-pos face-index]
-  ;; see ‘wisi-process-parse--execute’
-  ;; implements wisi--face-action-1
-  (with-silent-modifications
-    (add-text-properties
-     (aref sexp 1)
-     (1+ (aref sexp 2))
-     (list 'font-lock-face (aref (wisi-process--parser-face-table parser) 
(aref sexp 3))
-          'fontified t)
-     )))
-
-(defun wisi-process-parse--Indent (parser sexp)
-  ;; sexp is [Indent line-number indent]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref (wisi-process--parser-line-begin parser) (1- (aref sexp 
1)))))
-    (with-silent-modifications
-      (when (< (point-min) pos)
-       (put-text-property
-        (1- pos)
-        pos
-        'wisi-indent
-        (aref sexp 2)))
-      )))
-
-(defun wisi-process-parse--Lexer_Error (parser sexp)
-  ;; sexp is [Lexer_Error char-position <message> <repair-char>]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1))
-       err)
-
-    (goto-char pos);; for current-column
-
-    (setq err
-         (make-wisi--lexer-error
-          :pos (copy-marker pos)
-          :message
-          (format "%s:%d:%d: %s"
-                  (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                  ;; file-name can be nil during vc-resolve-conflict
-                  (line-number-at-pos pos)
-                  (current-column)
-                  (aref sexp 2))
-          :inserted (when (= 4 (length sexp)) (aref sexp 3))))
-
-    (push err (wisi-parser-lexer-errors parser))
-    ))
-
-(defun wisi-process-parse--Parser_Error (parser sexp)
-  ;; sexp is [Parser_Error char-position <string>]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1))
-       err)
-
-    (goto-char pos);; for current-column
-
-    (setq err
-         (make-wisi--parse-error
-          :pos (copy-marker pos)
-          :message
-          (format "%s:%d:%d: %s"
-                  (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                  ;; file-name can be nil during vc-resolve-conflict
-                  (line-number-at-pos pos)
-                  (1+ (current-column))
-                  (aref sexp 2))))
-
-    (push err (wisi-parser-parse-errors parser))
-    ))
-
-(defun wisi-process-parse--Check_Error (parser sexp)
-  ;; sexp is [Check_Error code name-1-pos name-2-pos <string>]
-  ;; see ‘wisi-process-parse--execute’
-  (let* ((name-1-pos (aref sexp 2))
-       (name-1-col (1+ (progn (goto-char name-1-pos)(current-column)))) ;; 
gnat columns are 1 + emacs columns
-       (name-2-pos (aref sexp 3))
-       (name-2-col (1+ (progn (goto-char name-2-pos)(current-column))))
-       (file-name (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) ""))
-       ;; file-name can be nil during vc-resolve-conflict
-       (err (make-wisi--parse-error
-             :pos (copy-marker name-1-pos)
-             :message
-             (format "%s:%d:%d: %s %s:%d:%d"
-                     file-name (line-number-at-pos name-1-pos) name-1-col
-                     (aref sexp 4)
-                     file-name (line-number-at-pos name-2-pos) name-2-col)))
-       )
-
-    (push err (wisi-parser-parse-errors parser))
-    ))
-
-(defun wisi-process-parse--Recover (parser sexp)
-  ;; sexp is [Recover [pos [inserted] [deleted] deleted-region]...]
-  ;; see ‘wisi-process-parse--execute’
-  ;; convert to list of wisi--parse-error-repair, add to last error
-  (let* ((token-table (wisi-process--parser-token-table parser))
-        (last-error (car (wisi-parser-parse-errors parser))))
-    (unless (= 1 (length sexp))
-      (cl-do ((i 1 (1+ i))) ((= i (length sexp)))
-       (push
-        (make-wisi--parse-error-repair
-         :pos (copy-marker (aref (aref sexp i) 0))
-         :inserted (mapcar (lambda (id) (aref token-table id)) (aref (aref 
sexp i) 1))
-         :deleted  (mapcar (lambda (id) (aref token-table id)) (aref (aref 
sexp i) 2))
-         :deleted-region (aref (aref sexp i) 3))
-        (wisi--parse-error-repair last-error)))
-      )))
-
-(defun wisi-process-parse--End (parser sexp)
-  ;; sexp is [End pos]
-  ;; see ‘wisi-process-parse--execute’
-  (setf (wisi-process--parser-end-pos parser) (1+ (aref sexp 1))))
-
-(defun wisi-process-parse--Edit (parser sexp)
-  ;; sexp is [Edit begin end text]
-  (delete-region (aref sexp 1) (1+ (aref sexp 2)))
-  (goto-char (aref sexp 1))
-  (insert (aref sexp 3)))
-
-(defun wisi-process-parse--Language (parser sexp)
-  ;; sexp is [Language language-action ...]
-  (funcall (aref (wisi-process--parser-language-action-table parser) (aref 
sexp 1)) sexp))
-
-(defun wisi-process-parse--execute (parser sexp)
-  "Execute encoded SEXP sent from external process."
-  ;; sexp is [action arg ...]; an encoded instruction that we need to execute
-  ;;
-  ;; Actions:
-  ;;
-  ;; [Navigate_Cache pos statement_id id length class containing_pos prev_pos 
next_pos end_pos]
-  ;;    Set a wisi-cache text-property.
-  ;;    *pos          : integer buffer position; -1 if nil (not set)
-  ;;    *id           : integer index into parser-token-table
-  ;;    length        : integer character count
-  ;;    class         : integer index into wisi-class-list
-  ;;
-  ;; [Name_Property first-pos last-pos]
-  ;;
-  ;; [Face_Property first-pos last-pos face-index]
-  ;;    Set a font-lock-face text-property
-  ;;    face-index: integer index into parser-elisp-face-table
-  ;;
-  ;; [Indent line-number indent]
-  ;;    Set an indent text property
-  ;;
-  ;; [Lexer_Error char-position <message> <repair-char>]
-  ;;    The lexer detected an error at char-position.
-  ;;
-  ;;    If <repair-char> is not ASCII NUL, it was inserted immediately
-  ;;    after char-position to fix the error.
-  ;;
-  ;; [Parser_Error char-position <message>]
-  ;;    The parser detected a syntax error; save information for later
-  ;;    reporting.
-  ;;
-  ;;    If error recovery is successful, there can be more than one
-  ;;    error reported during a parse.
-  ;;
-  ;; [Check_Error code name-1-pos name-2-pos <string>]
-  ;;    The parser detected a semantic check error; save information
-  ;;    for later reporting.
-  ;;
-  ;;    If error recovery is successful, there can be more than one
-  ;;    error reported during a parse.
-  ;;
-  ;; [Recover [pos [inserted] [deleted] deleted-region]...]
-  ;;    The parser finished a successful error recovery.
-  ;;
-  ;;    pos: Buffer position
-  ;;
-  ;;    inserted: Virtual tokens (terminal or non-terminal) inserted
-  ;;    before pos.
-  ;;
-  ;;    deleted: Tokens deleted after pos.
-  ;;
-  ;;    deleted-region: source buffer region containing deleted tokens
-  ;;
-  ;;    Args are token ids; index into parser-token-table. Save the
-  ;;    information for later use by ’wisi-repair-error’.
-  ;;
-  ;; [Edit begin end text]
-  ;;    Replace region BEGIN . END with TEXT; normally the result of a
-  ;;    refactor command.
-  ;;
-  ;; [Language ...]
-  ;;    Dispatch to a language-specific action, via
-  ;;    `wisi-process--parser-language-action-table'.
-  ;;
-  ;;
-  ;; Numeric action codes are given in the case expression below
-
-  (cl-ecase (aref sexp 0)
-    (1  (wisi-process-parse--Navigate_Cache parser sexp))
-    (2  (wisi-process-parse--Face_Property parser sexp))
-    (3  (wisi-process-parse--Indent parser sexp))
-    (4  (wisi-process-parse--Lexer_Error parser sexp))
-    (5  (wisi-process-parse--Parser_Error parser sexp))
-    (6  (wisi-process-parse--Check_Error parser sexp))
-    (7  (wisi-process-parse--Recover parser sexp))
-    (8  (wisi-process-parse--End parser sexp))
-    (9  (wisi-process-parse--Name_Property parser sexp))
-    (10 (wisi-process-parse--Edit parser sexp))
-    (11 (wisi-process-parse--Language parser sexp))
-    ))
-
-;;;;; main
-
-(cl-defmethod wisi-parse-kill ((parser wisi-process--parser))
-  (when (process-live-p (wisi-process--parser-process parser))
-    ;; We used to send a quit command first, to be nice. But there's
-    ;; no timeout on that, so it would hang when the process
-    ;; executable is not reading command input.
-    (when (process-live-p (wisi-process--parser-process parser))
-      (kill-process (wisi-process--parser-process parser)))
-    )
-  (setf (wisi-process--parser-busy parser) nil))
-
-(defvar wisi--lexer nil) ;; wisi-elisp-lexer.el
-(declare-function wisi-elisp-lexer-reset "wisi-elisp-lexer")
-
-(defun wisi-process-parse--prepare (parser)
-  ;; font-lock can trigger a face parse while navigate or indent parse
-  ;; is active, due to ‘accept-process-output’ below. Signaling an
-  ;; error tells font-lock to try again later.
-  (if (wisi-process--parser-busy parser)
-      (progn
-       (setf (wisi-parser-parse-errors parser)
-             (list
-              (make-wisi--parse-error
-               :pos 0
-               :message (format "%s:%d:%d: parser busy (try 
’wisi-kill-parser’)"
-                                (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "") 1 1))
-              ))
-       (error "%s parse abandoned; parser busy - use partial parse?" 
wisi--parse-action)
-       )
-
-    ;; It is not possible for a background elisp function (ie
-    ;; font-lock) to interrupt this code between checking and setting
-    ;; parser-busy; background elisp can only run when we call
-    ;; accept-process-output below.
-    (setf (wisi-process--parser-busy parser) t)
-
-    ;; If the parser process has not started yet,
-    ;; wisi-process-parse--require-process calls
-    ;; wisi-process-parse--wait, which can let font-lock invoke the
-    ;; parser again. Thus this call must be after we set
-    ;; wisi-process--parser-busy t
-    (wisi-process-parse--require-process parser)
-
-    (setf (wisi-process--parser-total-wait-time parser) 0.0)
-    (setf (wisi-parser-lexer-errors parser) nil)
-    (setf (wisi-parser-parse-errors parser) nil)
-    ))
-
-(defun wisi-process-parse--handle-messages (parser)
-  (condition-case-unless-debug err
-      (let* ((source-buffer (current-buffer))
-            (response-buffer (wisi-process--parser-buffer parser))
-            (process (wisi-process--parser-process parser))
-            (w32-pipe-read-delay 0) ;; fastest subprocess read
-            response
-            response-end
-            (response-count 0)
-            sexp-start
-            (need-more nil) ;; point-max if need more, to check for new input
-            (done nil)
-            start-wait-time)
-
-       (set-buffer response-buffer)
-       (setq sexp-start (point-min))
-
-       ;; process responses until prompt received
-       (while (not done)
-
-         ;; process all complete responses currently in buffer
-         (while (and (not need-more)
-                     (not done))
-
-           (goto-char sexp-start)
-
-           (cond
-            ((eobp)
-             (setq need-more (point-max)))
-
-            ((looking-at wisi-process-parse-prompt)
-             (setq done t))
-
-            ((or (looking-at "\\[") ;; encoded action
-                 (looking-at "(")) ;; error or other elisp expression to eval
-             (condition-case nil
-                 (setq response-end (scan-sexps (point) 1))
-               (error
-                ;; incomplete response
-                (setq need-more (point-max))
-                nil))
-
-             (unless need-more
-               (setq response-count (1+ response-count))
-               (setq response (car (read-from-string 
(buffer-substring-no-properties (point) response-end))))
-               (goto-char response-end)
-               (forward-line 1)
-               (setq sexp-start (point))
-
-               (set-buffer source-buffer) ;; for put-text-property in actions
-               (cond
-                ((listp response)
-                 ;; non-syntax error of some sort
-                 (cond
-                  ((equal '(parse_error) response)
-                   ;; Parser detected a syntax error, and recovery failed, so 
signal it.
-
-                   (when (> wisi-debug 0)
-                     ;; Save a copy of parser output; may be overwritten by 
subsequent parse face attempts.
-                     (set-buffer response-buffer)
-                     (let ((content (buffer-substring-no-properties 
(point-min) (point-max)))
-                           (buf-name (concat (buffer-name) "-save-error")))
-                       (set-buffer (get-buffer-create buf-name))
-                       (insert content)))
-
-                   (if (wisi-parser-parse-errors parser)
-                       (signal 'wisi-parse-error
-                               (wisi--parse-error-message (car 
(wisi-parser-parse-errors parser))))
-
-                     ;; can have no errors when testing a new parser
-                     (push
-                      (make-wisi--parse-error :pos 0 :message "parser failed 
with no message")
-                      (wisi-parser-parse-errors parser))
-                     (signal 'wisi-parse-error "parser failed with no 
message")))
-
-                  ((equal 'parse_error (car response))
-                   ;; Parser detected some other error non-fatal error, so 
signal it.
-                   (push
-                    (make-wisi--parse-error :pos 0 :message (cadr response))
-                    (wisi-parser-parse-errors parser))
-                   (signal 'wisi-parse-error (cdr response)))
-
-                  ((and (eq 'error (car response))
-                        (string-prefix-p "bad command:" (cadr response)))
-                   ;; Parser dropped bytes, is treating buffer
-                   ;; content bytes as commands. Kill the process
-                   ;; to kill the pipes; there is no other way to
-                   ;; flush them.
-                   (kill-process (wisi-process--parser-process parser))
-                   (signal 'wisi-parse-error "parser lost sync; killed"))
-
-                  (t
-                   ;; Some other error
-                   (condition-case-unless-debug err
-                       (eval response)
-                     (error
-                      (push (make-wisi--parse-error :pos (point) :message 
(cadr err)) (wisi-parser-parse-errors parser))
-                      (signal (car err) (cdr err)))))
-                  ))
-
-                ((arrayp response)
-                 ;; encoded action
-                 (condition-case-unless-debug err
-                     (wisi-process-parse--execute parser response)
-                   (wisi-parse-error
-                    (push (make-wisi--parse-error :pos (point) :message (cadr 
err)) (wisi-parser-parse-errors parser))
-                    (signal (car err) (cdr err)))
-
-                   (error ;; ie from un-commented 
[C:\Windows\system32\KERNEL32.DLL], or bug in action code above.
-                    (set-buffer response-buffer)
-                    (let ((content (buffer-substring-no-properties (point-min) 
(point-max)))
-                          (buf-name (concat (buffer-name) "-save-error")))
-                      (set-buffer (get-buffer-create buf-name))
-                      (insert content)
-                      (insert (format "%s" err))
-                      (error "parser failed; error messages in %s" buf-name)))
-                   ))
-                )
-
-               (set-buffer response-buffer)
-               ))
-
-            (t
-             ;; debug output
-             (forward-line 1)
-             (setq sexp-start (point)))
-            )
-             )
-
-           (unless done
-             ;; end of response buffer
-             (unless (process-live-p process)
-               (set-buffer response-buffer)
-               (let ((content (buffer-substring-no-properties (point-min) 
(point-max)))
-                     (buf-name (concat (buffer-name) "-save-error")))
-                 (set-buffer (get-buffer-create buf-name))
-                 (insert content)
-                 (error "parser failed; error messages in %s" buf-name)))
-
-             (setq start-wait-time (float-time))
-
-             ;; If we specify no time-out here, we get messages about
-             ;; "blocking call with quit inhibited", when this is
-             ;; called by font-lock from the display engine.
-             ;;
-             ;; Specifying just-this-one t prevents C-q from
-             ;; interrupting this?
-             (accept-process-output
-              process
-              wisi-process-time-out
-              nil ;; milliseconds
-              nil)  ;; just-this-one
-
-             (setf (wisi-process--parser-total-wait-time parser)
-                   (+ (wisi-process--parser-total-wait-time parser)
-                      (- (float-time) start-wait-time)))
-
-             (when (and (= (point-max) need-more)
-                        (> (wisi-process--parser-total-wait-time parser) 
wisi-process-time-out))
-               (error "wisi-process-parse timing out; increase 
`wisi-process-time-out'? (or bad syntax in process output)"))
-
-             (setq need-more nil))
-           );; while not done
-
-         ;; got command prompt
-         (unless (process-live-p process)
-           (wisi-process-parse-show-buffer parser)
-           (error "wisi-process-parse process died"))
-
-         (setf (wisi-process--parser-response-count parser) response-count)
-
-         (setf (wisi-process--parser-busy parser) nil)
-         (set-buffer source-buffer)
-         ;; If we get here, the parse succeeded (possibly with error
-         ;; recovery); move point to end of parsed region.
-         (goto-char (wisi-process--parser-end-pos parser))
-         )
-
-      (wisi-parse-error
-       (setf (wisi-process--parser-busy parser) nil)
-       (signal (car err) (cdr err)))
-
-      (error
-       (setf (wisi-process--parser-busy parser) nil)
-       (signal (car err) (cdr err))
-       )))
-
-(cl-defmethod wisi-parse-current ((parser wisi-process--parser) begin send-end 
parse-end)
-  (wisi-process-parse--prepare parser)
-  (let ((total-line-count (1+ (count-lines (point-max) (point-min)))))
-    (setf (wisi-process--parser-line-begin parser) (wisi--set-line-begin 
total-line-count))
-    (wisi-process-parse--send-parse parser begin send-end parse-end)
-
-    ;; We reset the elisp lexer, because post-parse actions may use it.
-    (when wisi--lexer
-      (wisi-elisp-lexer-reset total-line-count wisi--lexer))
-    )
-  (wisi-process-parse--handle-messages parser)
-  (cons begin (point))
-  )
-
-(cl-defmethod wisi-refactor ((parser wisi-process--parser) refactor-action 
parse-begin parse-end edit-begin)
-  (save-excursion
-    (wisi-process-parse--prepare parser)
-    (wisi-process-parse--send-refactor parser refactor-action parse-begin 
parse-end edit-begin)
-    (wisi-process-parse--handle-messages parser))
-  )
-
-(defvar wisi--parser nil) ;; wisi.el
-
-(defun wisi-process-send-tokens-noop ()
-  "Run lexer, send tokens to subprocess; otherwise no operation.
-For use with ’wisi-time’."
-  (wisi-process-parse--require-process wisi--parser)
-  (if (wisi-process--parser-busy wisi--parser)
-      (error "%s parser busy" wisi--parse-action)
-
-    ;; not busy
-    (let* ((source-buffer (current-buffer))
-          (action-buffer (wisi-process--parser-buffer wisi--parser))
-          (process (wisi-process--parser-process wisi--parser))
-          (sexp-start (point-min))
-          (need-more nil)
-          (done nil))
-
-      (setf (wisi-process--parser-busy wisi--parser) t)
-      (wisi-process-parse--send-noop wisi--parser)
-
-      (set-buffer action-buffer)
-      (while (and (process-live-p process)
-                 (not done))
-       (goto-char sexp-start)
-       (cond
-        ((eobp)
-         (setq need-more t))
-
-        ((looking-at wisi-process-parse-prompt)
-         (setq done t))
-
-        (t
-         (forward-line 1)
-         (setq sexp-start (point)))
-        )
-
-       (unless done
-         ;; end of response buffer
-         (unless (process-live-p process)
-           (wisi-process-parse-show-buffer wisi--parser)
-           (error "wisi-process-parse process died"))
-
-         (accept-process-output process 1.0 nil nil)
-         (setq need-more nil))
-       )
-      (set-buffer source-buffer)
-      (setf (wisi-process--parser-busy wisi--parser) nil)
-      )))
-
-;;;;; debugging
-(defun wisi-process-parse-ids-to-enum (token-table &rest int-ids)
-  "Translate INT-IDS from process integer token ids to elisp enumeral ids.
-Returns reversed sequence."
-  (let ((enum-ids nil))
-    (cl-dolist (i int-ids)
-      (push (aref token-table i) enum-ids))
-    enum-ids))
-
-(defun wisi-process-parse-show-args ()
-  "Show the partial parse command-line args for run_ada_[lalr | lr1]_parse for 
current region.
-Also add it to the kill ring."
-  (interactive)
-  (let* ((begin (region-beginning))
-        (end   (region-end))
-        (parse-action (wisi-read-parse-action))
-        (msg
-         (format "%s %s %d %d %d %d %d %d %d"
-                 (file-name-nondirectory (buffer-file-name))
-                 parse-action
-                 (position-bytes begin)
-                 (position-bytes end)
-                 (position-bytes end)
-                 begin ;; char_pos
-                 (line-number-at-pos begin)
-                 (line-number-at-pos end)
-                 (save-excursion (goto-char begin) (back-to-indentation) 
(current-column));; indent-begin
-                 )))
-    (kill-new msg)
-    (message msg)))
-
-(provide 'wisi-process-parse)
diff --git a/packages/wisi/wisi-run-indent-test.el 
b/packages/wisi/wisi-run-indent-test.el
deleted file mode 100644
index 8c0eef0..0000000
--- a/packages/wisi/wisi-run-indent-test.el
+++ /dev/null
@@ -1,399 +0,0 @@
-;;; wisi-run-indent-test.el --- utils for automating indentation and casing 
tests
-;;
-;; Copyright (C) 2018 - 2020  Free Software Foundation, Inc.
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-(require 'wisi-tests)
-(require 'wisi-prj)
-
-;; user can set these to t in an EMACSCMD
-(defvar skip-cmds nil)
-(defvar skip-reindent-test nil)
-(defvar skip-recase-test nil)
-(defvar skip-write nil)
-
-(defun test-in-comment-p ()
-  (nth 4 (syntax-ppss)))
-
-(defun test-face (token face)
-  "Test if all of TOKEN in next code line has FACE.
-FACE may be a list."
-  (save-excursion
-    (when (test-in-comment-p)
-      (beginning-of-line); forward-comment doesn't move if inside a comment!
-      (forward-comment (point-max)))
-    (condition-case err
-       (search-forward token (line-end-position 5))
-      (error
-       (error "can't find '%s'" token)))
-
-    (save-match-data
-      (wisi-validate-cache (line-beginning-position) (line-end-position) nil 
'face)
-      (font-lock-ensure (line-beginning-position) (line-end-position)))
-    
-    ;; We don't use face-at-point, because it doesn't respect
-    ;; font-lock-face set by the parser! And we want to check for
-    ;; conflicts between font-lock-keywords and the parser.
-
-    ;; font-lock-keywords sets 'face property, parser sets 'font-lock-face.
-
-    ;; In emacs < 27, if we use (get-text-property (point) 'face), we
-    ;; also get 'font-lock-face, but not vice-versa. So we have to use
-    ;; text-properties-at to check for both.
-    (let* ((token (match-string 0))
-          (props (text-properties-at (match-beginning 0)))
-          key
-          token-face)
-
-      (cond
-       ((plist-get props 'font-lock-face)
-       (setq key 'font-lock-face)
-       (setq token-face (plist-get props 'font-lock-face)))
-
-       ((plist-get props 'face)
-       (setq key 'face)
-       (setq token-face (plist-get props 'face)))
-       )
-
-      (when (and (memq 'font-lock-face props)
-                (memq 'face props))
-       (describe-text-properties (match-beginning 0))
-       (error "mixed font-lock-keyword and parser faces for '%s'" token))
-
-      (unless (not (text-property-not-all 0 (length token) key token-face 
token))
-       (error "mixed faces, expecting %s for '%s'" face token))
-
-      (unless (or (and (listp face)
-                      (memq token-face face))
-                 (eq token-face face))
-       (error "found face %s, expecting %s for '%s'" token-face face token))
-    )))
-
-(defun test-face-1 (search token face)
-  "Move to end of comment, search for SEARCH, call `test-face'."
-  (save-excursion
-    (when (test-in-comment-p)
-      (beginning-of-line); forward-comment doesn't move if inside a comment!
-      (forward-comment (point-max)))
-    (search-forward search)
-    (test-face token face)
-    ))
-
-(defun test-cache-class (token class)
-  "Test if TOKEN in next code line has wisi-cache with class CLASS."
-  (save-excursion
-    (wisi-validate-cache (line-beginning-position 0) (line-end-position 3) nil 
'navigate)
-    (beginning-of-line); forward-comment doesn't move if inside a comment!
-    (forward-comment (point-max))
-    (condition-case err
-       (search-forward token (line-end-position 5))
-      (error
-       (error "can't find '%s'" token)))
-
-    (let ((cache (get-text-property (match-beginning 0) 'wisi-cache)))
-
-      (unless cache (error "no cache"))
-      (unless (eq (wisi-cache-class cache) class)
-       (error "expecting class %s, found '%s'" class (wisi-cache-class cache)))
-    )))
-
-(defun test-cache-containing (containing contained)
-  "Test if CONTAINING in next code line has wisi-cache with that contains 
CONTAINED."
-  (save-excursion
-    (wisi-validate-cache (line-beginning-position 0) (line-end-position 3) nil 
'navigate)
-    (beginning-of-line)
-    (forward-comment (point-max))
-    (let (containing-pos contained-cache)
-      (search-forward containing (line-end-position 5))
-      (setq containing-pos (match-beginning 0))
-
-      (search-forward contained (line-end-position 5))
-      (setq contained-cache (get-text-property (match-beginning 0) 
'wisi-cache))
-
-      (unless contained-cache (error "no cache on %s" contained))
-      (unless (= containing-pos (wisi-cache-containing contained-cache))
-       (error "expecting %d, got %d" containing-pos (wisi-cache-containing 
contained-cache)))
-    )))
-
-(defvar test-refactor-markers nil
-  "Stores positions altered by `test-refactor-1' for `test-refactor-2'.
-Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
-
-(defun test-refactor-1 (action inverse-action search-string refactor-string)
-  (beginning-of-line)
-  (forward-comment (point-max)) ;; forward-comment does not work from inside 
comment
-  (search-forward search-string (line-end-position 7))
-  (wisi-validate-cache (line-end-position -7) (line-end-position 7) t 
'navigate)
-  (search-forward refactor-string (line-end-position 7))
-  (let* ((edit-begin (match-beginning 0))
-        (cache (wisi-goto-statement-start))
-        (parse-begin (point))
-        (parse-end (wisi-cache-end cache)))
-    (setq parse-end (+ parse-end (wisi-cache-last (wisi-get-cache 
(wisi-cache-end cache)))))
-    (push (list
-          inverse-action
-          (copy-marker parse-begin nil)
-          (copy-marker parse-end nil)
-          (copy-marker edit-begin nil))
-         test-refactor-markers)
-    (wisi-refactor wisi--parser action parse-begin parse-end edit-begin)
-    ))
-
-(defun test-refactor-inverse ()
-  "Reverse refactors done by recent set of `test-refactor-1'."
-  (save-excursion
-    (condition-case-unless-debug nil
-       (dolist (item test-refactor-markers)
-         (wisi-refactor wisi--parser
-                        (nth 0 item)
-                        (marker-position (nth 1 item))
-                        (marker-position (nth 2 item))
-                        (marker-position (nth 3 item))))
-      (error nil))
-    (setq test-refactor-markers nil)))
-
-(defun run-test-here ()
-  "Run an indentation and casing test on the current buffer."
-  (interactive)
-  (setq indent-tabs-mode nil)
-  (setq jit-lock-context-time 0.0);; for test-face
-
-  ;; Test files use wisi-prj-select-cached to parse and select a project file.
-  (setq project-find-functions (list #'wisi-prj-current-cached))
-  (setq xref-backend-functions (list #'wisi-prj-xref-backend))
-
-
-  (let ((error-count 0)
-       (test-buffer (current-buffer))
-       cmd-line
-       last-result last-cmd expected-result)
-    ;; Look for EMACS* comments in the file:
-    ;;
-    ;; EMACSCMD: <form>
-    ;;    Executes the lisp form inside a save-excursion, saves the result as 
a lisp object.
-    ;;
-    ;; EMACSRESULT: <form>
-    ;;    point is moved to end of line, <form> is evaluated inside
-    ;;    save-excursion and compared (using `equal') with the result
-    ;;    of the previous EMACSCMD, and the test fails if they don't
-    ;;    match.
-    ;;
-    ;; EMACSRESULT_START:<first list element>
-    ;; EMACSRESULT_ADD:  <list element>
-    ;; EMACSRESULT_FINISH:
-    ;;    build a list, compare it to the result of the previous EMACSCMD.
-    ;;
-    ;; EMACS_SKIP_UNLESS: <form>
-    ;;   skip entire test if form evals nil
-    ;;
-    ;; EMACSDEBUG: <form>
-    ;;    Eval form, display result. Also used for setting breakpoint.
-
-    (goto-char (point-min))
-    (while (and (not skip-cmds)
-               (re-search-forward (concat comment-start "EMACS\\([^:]+\\):") 
nil t))
-      (cond
-       ((string= (match-string 1) "CMD")
-       (looking-at ".*$")
-       (save-excursion
-         (setq cmd-line (line-number-at-pos)
-               last-cmd (match-string 0)
-               last-result
-               (condition-case-unless-debug err
-                   (eval (car (read-from-string last-cmd)))
-                 (error
-                    (setq error-count (1+ error-count))
-                    (message "%s:%d: command: %s"
-                             (buffer-file-name) cmd-line last-cmd)
-                    (message "%s:%d: %s: %s"
-                             (buffer-file-name)
-                             (line-number-at-pos)
-                             (car err)
-                             (cdr err))))
-               )
-         ;; save-excursion does not preserve mapping of buffer to
-         ;; window, but some tests depend on that. For example,
-         ;; execute-kbd-macro doesn’t work properly if current buffer
-         ;; is not visible..
-         (pop-to-buffer test-buffer)))
-
-       ((string= (match-string 1) "RESULT")
-       (looking-at ".*$")
-       (setq expected-result (save-excursion (end-of-line 1) (eval (car 
(read-from-string (match-string 0))))))
-       (unless (equal expected-result last-result)
-         (setq error-count (1+ error-count))
-         (message
-          (concat
-           (format "error: %s:%d:\n" (buffer-file-name) (line-number-at-pos))
-           (format "Result of '%s' does not match.\nGot    '%s',\nexpect '%s'"
-                   last-cmd
-                   last-result
-                   expected-result)
-           ))))
-
-       ((string= (match-string 1) "RESULT_START")
-       (looking-at ".*$")
-       (setq expected-result (list (save-excursion (end-of-line 1) (eval (car 
(read-from-string (match-string 0))))))))
-
-       ((string= (match-string 1) "RESULT_ADD")
-       (looking-at ".*$")
-       (let ((val (save-excursion (end-of-line 1)
-                                  (eval (car (read-from-string (match-string 
0)))))))
-         (when val
-           (setq expected-result (append expected-result (list val))))))
-
-       ((string= (match-string 1) "RESULT_FINISH")
-       (unless (equal (length expected-result) (length last-result))
-         (setq error-count (1+ error-count))
-         (message
-          (concat
-           (format "error: %s:%d:\n" (buffer-file-name) (line-number-at-pos))
-           (format "Length of result of '%s' does not match.\nGot    
'%s',\nexpect '%s'"
-                   last-cmd
-                   (length last-result)
-                   (length expected-result)))))
-
-       (let ((i 0))
-         (while (< i (length expected-result))
-           (unless (equal (nth i expected-result) (nth i last-result))
-             (setq error-count (1+ error-count))
-             (message
-              (concat
-               (format "error: %s:%d:\n" (buffer-file-name) 
(line-number-at-pos))
-               (format "Nth (%d) result of '%s' does not match.\nGot    
'%s',\nexpect '%s'"
-                       i
-                       last-cmd
-                       (nth i last-result)
-                       (nth i expected-result))
-               )))
-           (setq i (1+ i)))))
-
-       ((string= (match-string 1) "_SKIP_UNLESS")
-       (looking-at ".*$")
-       (unless (eval (car (read-from-string (match-string 0))))
-         (setq skip-cmds t)
-         (setq skip-reindent-test t)
-         (setq skip-recase-test t)
-         ;; We don’t set ‘skip-write’ t here, so the *.diff Make target 
succeeds.
-         ))
-
-       ((string= (match-string 1) "DEBUG")
-       (looking-at ".*$")
-       (message "DEBUG: %s:%d %s"
-                (current-buffer)
-                (line-number-at-pos)
-                (save-excursion
-                 (eval (car (read-from-string (match-string 0)))))))
-
-       (t
-       (setq error-count (1+ error-count))
-       (error (concat "Unexpected EMACS test command " (match-string 1))))))
-
-    (when (> error-count 0)
-      (error
-       "%s:%d: aborting due to previous errors (%d)"
-       (buffer-file-name) (line-number-at-pos (point)) error-count))
-    )
-
-  (unless skip-reindent-test
-    ;; Reindent the buffer
-    (message "indenting")
-
-    ;; first unindent; if the indentation rules do nothing, the test
-    ;; would pass, otherwise!  Only unindent by 1 column, so comments
-    ;; not currently in column 0 are still not in column 0, in case
-    ;; the mode supports a special case for comments in column 0.
-    (indent-rigidly (point-min) (point-max) -1)
-
-    ;; indent-region uses save-excursion, so we can't goto an error location
-    (indent-region (point-min) (point-max))
-
-    ;; Cleanup the buffer; indenting often leaves trailing whitespace;
-    ;; files must be saved without any.
-    (delete-trailing-whitespace)
-    )
-
-  (when (and wisi-auto-case (not skip-recase-test))
-    (message "casing")
-    (wisi-case-adjust-buffer))
-  )
-
-(defvar cl-print-readably); cl-print.el, used by edebug
-
-(defun large-frame ()
-  (interactive)
-  (modify-frame-parameters
-      nil
-      (list
-       (cons 'width 120) ;; characters; fringe extra
-       (cons 'height 71) ;; characters
-       (cons 'left 0) ;; pixels
-       (cons 'top 0))))
-(define-key global-map "\C-cp" 'large-screen)
-
-(defun run-test (file-name)
-  "Run an indentation and casing test on FILE-NAME."
-  (interactive "f")
-
-  (package-initialize) ;; for uniquify-files
-
-  ;; Let edebug display strings full-length, and show internals of records
-  (setq cl-print-readably t)
-
-  ;; we'd like to run emacs from a makefile as:
-  ;;
-  ;; emacs -Q --batch -l runtest.el -f run-test-here <filename>
-  ;;
-  ;; However, the function specified with -f is run _before_
-  ;; <filename> is visited. So we try this instead:
-  ;;
-  ;; emacs -Q --batch -l runtest.el --eval '(run-test "<filename>")'
-  ;;
-  ;; And then we discover that processes spawned with start-process
-  ;; don't run when emacs is in --batch mode. So we try this:
-  ;;
-  ;; emacs -Q -l runtest.el --eval '(progn (run-test 
"<filename>")(kill-emacs))'
-  ;;
-  ;; Then we have problems with font lock defaulting to jit-lock; that
-  ;; screws up font-lock tests because the test runs before jit-lock
-  ;; does. This forces default font-lock, which fontifies the whole
-  ;; buffer when (font-lock-fontify-buffer) is called, which tests
-  ;; that rely on font-lock do explicitly.
-  (setq font-lock-support-mode nil)
-
-  (setq xref-prompt-for-identifier nil)
-
-  (let ((dir default-directory))
-    (find-file file-name) ;; sets default-directory
-
-    (run-test-here)
-
-    (unless skip-write
-      ;; Write the result file; makefile will diff.
-      (when skip-reindent-test
-       ;; user sets skip-reindent-test when testing interactive editing
-       ;; commands, so the diff would fail. Revert to the original file,
-       ;; save a copy of that.
-       (revert-buffer t t))
-
-      (delete-trailing-whitespace)
-      (write-file (concat dir (file-name-nondirectory file-name) ".tmp")) )
-    )
-  )
-
-(provide 'wisi-run-indent-test)
-;; end of file
diff --git a/packages/wisi/wisi-skel.el b/packages/wisi/wisi-skel.el
deleted file mode 100644
index 9af5b9b..0000000
--- a/packages/wisi/wisi-skel.el
+++ /dev/null
@@ -1,187 +0,0 @@
-;;; wisi-skel.el --- Extensions skeleton  -*- lexical-binding:t -*-
-
-;; Copyright (C) 1987, 1993, 1994, 1996-2020  Free Software Foundation, Inc.
-
-;; Authors: Stephen Leake <stephen_leake@stephe-leake.org>
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Design:
-;;
-;; The primary user command is `wisi-skel-expand', which inserts the
-;; skeleton associated with the previous word (possibly skipping a
-;; name).
-
-(require 'skeleton)
-
-(defvar-local wisi-skel-token-alist nil
-  "Alist of (STRING . ELEMENT), used by `wisi-skel-expand'.
-STRING should be a grammar symbol in the current language.
-
-ELEMENT may be:
-- a skeleton, which is inserted
-- an alist of (STRING . SKELETON). User is prompted with `completing-read',
-  selected skeleton is inserted.")
-
-(defun wisi-skel-add-token-after (alist token skel after-1 &optional after-2)
-  "Add a new entry in ALIST (should be an instance of `wisi-skel-token-alist')
-after AFTER-1. If AFTER-1 is a nested alist, add the new entry after AFTER-2."
-  (let ((tail alist)
-       done)
-    (if (string= after-1 (car (car alist)))
-       (setcdr alist (cons (cons token skel) (cdr alist)))
-
-      (while (and (not done) tail)
-       (if (string= after-1 (car-safe (car (cdr tail))))
-           (cond
-            ((symbolp (cdr (car (cdr tail))))
-             (setcdr tail (cons (cons token skel) (cdr (cdr tail))))
-             (setq done t))
-
-            ((consp (cdr (car (cdr tail))))
-             (wisi-skel-add-token-after (cdr (car (cdr tail))) token skel 
after-2)
-             (setq done t))
-            )
-         ;; else
-         (setq tail (cdr tail))
-         ))
-      )))
-
-(defun wisi-skel-build-prompt (alist count)
-  "Build a prompt from the keys of the ALIST.
-The prompt consists of the first COUNT keys from the alist, separated by `|', 
with
-trailing `...' if there are more keys."
-  (if (>= count (length alist))
-      (concat (mapconcat 'car alist " | ") " : ")
-    (let ((alist-1 (butlast alist (- (length alist) count))))
-      (concat (mapconcat 'car alist-1 " | ") " | ... : "))
-  ))
-
-(defvar wisi-skel-test-input nil
-  "Override prompt for input from wisi-skel-token-alist, for unit testing."
-  ;; see test/ada_skel.adb
-  )
-
-(defun wisi-skel-expand (&optional name)
-  "Expand the token or placeholder before point to a skeleton.
-Tokens are defined by `wisi-skel-token-alist'; they must have
-symbol syntax.  A placeholder is a token enclosed in generic
-comment delimiters.  If the symbol before point is not in
-`wisi-skel-token-alist', assume it is a name, and use the symbol
-before that as the token."
-  (interactive "*")
-
-  ;; Skip trailing space, newline, and placeholder delimiter.
-  ;; Standard comment end included for languages where that is newline.
-  (skip-syntax-backward " !>")
-
-  (let* ((wisi-inhibit-parse t) ;; don't parse until skeleton is fully inserted
-        (end (point))
-        ;; Include punctuation here, to handle a dotted name (ie Ada.Text_IO)
-        (token (progn (skip-syntax-backward "w_.")
-                      (downcase (buffer-substring-no-properties (point) end))))
-        (skel (assoc-string token wisi-skel-token-alist))
-        (handled nil))
-
-    (if skel
-       (progn
-         (when (listp (cdr skel))
-           (let* ((alist (cdr skel))
-                  (prompt (wisi-skel-build-prompt alist 4)))
-             (setq skel (assoc-string
-                         (or wisi-skel-test-input (completing-read prompt 
alist))
-                         alist))
-             ))
-
-         ;; delete placeholder delimiters around token, token, and
-         ;; name. point is currently before token.
-         (skip-syntax-backward "!")
-         (delete-region
-          (point)
-          (progn
-            (skip-syntax-forward "!w_")
-            (when name
-              (skip-syntax-forward " ")
-              (skip-syntax-forward "w_."))
-            (point)))
-         (let ((skeleton-end-newline nil))
-           (funcall (cdr skel) name))
-         (setq handled t))
-
-      ;; word in point .. end is not a token; assume it is a name
-      (when (not name)
-       ;; avoid infinite recursion
-
-       (when wisi-auto-case
-         ;; Adjust case now, because skeleton insert won't.
-         ;;
-         ;; We didn't do it above, because we don't want to adjust case
-         ;; on tokens and placeholders.
-         (save-excursion (wisi-case-adjust-region (point) end)))
-
-       (condition-case-unless-debug nil
-           (progn
-             (wisi-skel-expand (buffer-substring-no-properties (point) end))
-             (setq handled t))
-         (user-error ;; leave handled nil
-          ))
-       ))
-
-    (when (not handled)
-      (setq name (buffer-substring-no-properties (point) end))
-      ;; restore point
-      (goto-char end)
-      (user-error "'%s' is not a skeleton token" name))
-    ))
-
-;;;###autoload
-(defun wisi-skel-hippie-try (old)
-  "For `hippie-expand-try-functions-list'."
-  (if old
-      ;; hippie is asking us to try the "next" completion; we don't have one
-      nil
-    (let ((pos (point))
-         (undo-len (if (eq 't pending-undo-list)
-                       0
-                     (length pending-undo-list))))
-      (undo-boundary)
-      (condition-case nil
-         (progn
-           (wisi-skel-expand)
-           t)
-       (error
-        ;; undo hook action if any
-        (unless (or (eq 't pending-undo-list)
-                    (= undo-len (length pending-undo-list)))
-          (undo))
-
-        ;; undo motion
-        (goto-char pos)
-        nil)))))
-
-(defun wisi-skel-next-placeholder ()
-  "Move point to after next placeholder."
-  (interactive)
-  (skip-syntax-forward "^!")
-  (skip-syntax-forward "w_!"))
-
-(defun wisi-skel-prev-placeholder ()
-  "Move point to after previous placeholder."
-  (interactive)
-  (skip-syntax-backward "^!"))
-
-(provide 'wisi-skel)
-;;; wisi-skel.el ends here
diff --git a/packages/wisi/wisi-tests.el b/packages/wisi/wisi-tests.el
deleted file mode 100644
index b730cf1..0000000
--- a/packages/wisi/wisi-tests.el
+++ /dev/null
@@ -1,120 +0,0 @@
-;;; wisi-tests.el --- Common utils for wisi tests -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2012 - 2019  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-
-(require 'cl-lib)
-(require 'wisi)
-
-(defvar wisi-test-parser 'process
-  "Set to ’process to test external process parser.")
-
-(defvar test-syntax-table
-  (let ((table (make-syntax-table)))
-    ;; make-syntax-table sets all alphanumeric to w, etc; so we only
-    ;; have to add test-specific things.
-
-    ;; operator symbols
-    (modify-syntax-entry ?&  "." table)
-    (modify-syntax-entry ?*  "." table)
-    (modify-syntax-entry ?+  "." table)
-    (modify-syntax-entry ?-  "." table)
-    (modify-syntax-entry ?/  "." table)
-    (modify-syntax-entry ?<  "." table)
-    (modify-syntax-entry ?=  "." table)
-    (modify-syntax-entry ?>  "." table)
-    (modify-syntax-entry ?|  "." table)
-
-    ;; \f and \n end a comment - see test-syntax-propertize for comment start
-    (modify-syntax-entry ?\f  ">   " table)
-    (modify-syntax-entry ?\n  ">   " table)
-    table
-    ))
-
-(defun test-syntax-propertize (start end)
-  "Assign `syntax-table' properties in accessible part of buffer."
-  ;; (info "(elisp)Syntax Properties")
-  (let ((modified (buffer-modified-p))
-       (buffer-undo-list t)
-       (inhibit-read-only t)
-       (inhibit-point-motion-hooks t)
-       (inhibit-modification-hooks t))
-    (goto-char start)
-    (while (re-search-forward
-            "\\(--\\)"; 1: comment start
-           end t)
-      ;; The help for syntax-propertize-extend-region-functions
-      ;; implies that 'start end' will always include whole lines, in
-      ;; which case we don't need
-      ;; syntax-propertize-extend-region-functions
-      (cond
-       ((match-beginning 1)
-       (put-text-property
-        (match-beginning 1) (match-end 1) 'syntax-table '(11 . nil)))
-       ))
-    (unless modified
-      (restore-buffer-modified-p nil))))
-
-(defun wisi-tests-setup (grammar-name)
-  ;; grammar-elisp file must be on load-path
-  ;; use Ada style comments in source
-  (set-syntax-table test-syntax-table)
-  (set (make-local-variable 'syntax-propertize-function) 
'test-syntax-propertize)
-  (syntax-ppss-flush-cache (point-min));; force re-evaluate with hook.
-
-  (cl-ecase wisi-test-parser
-    (process
-     (require 'wisi-process-parse)
-     (require (intern (concat grammar-name "-process"))) ;; generated by 
wisi-generate
-     (require (intern grammar-name)) ;; declares parser cl-defstruct
-     (add-to-list 'exec-path default-directory)
-     (wisi-setup
-      :indent-calculate nil
-      :post-indent-fail nil
-      :parser
-      (wisi-process-parse-get
-       (funcall
-       (intern-soft (concat "make-" grammar-name "-wisi-parser"))
-       :label grammar-name
-       :exec-file (concat grammar-name "_wisi_parse.exe")
-       :face-table (symbol-value (intern-soft (concat grammar-name 
"-process-face-table")))
-       :token-table (symbol-value (intern-soft (concat grammar-name 
"-process-token-table")))
-       )))
-     (setq wisi-mckenzie-disable nil)
-     )
-    )
-
-  ;; Not clear why this is not being done automatically
-  (syntax-propertize (point-max))
-  )
-
-;;; Initialization
-
-;; Default includes mtn, among others, which is broken in Emacs 22.2
-(setq vc-handled-backends '(CVS))
-
-(setq eval-expression-debug-on-error nil)
-
-;; ’package-initialize’ is not here; it must be run as part of one of the
-;; -l or --eval command line options
-
-(provide 'wisi-tests)
-;; end of file
diff --git a/packages/wisi/wisi.adb b/packages/wisi/wisi.adb
deleted file mode 100644
index 91dacab..0000000
--- a/packages/wisi/wisi.adb
+++ /dev/null
@@ -1,2434 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-with Ada.Strings.Bounded;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with SAL;
-with WisiToken.Semantic_Checks;
-package body Wisi is
-   use WisiToken;
-
-   Chars_Per_Int : constant Integer := Integer'Width;
-
-   ----------
-   --  body subprogram specs (as needed), alphabetical
-
-   function Indent_Nil_P (Indent : in Indent_Type) return Boolean;
-
-   function Max_Anchor_ID
-     (Data       : in out Parse_Data_Type;
-      First_Line : in     Line_Number_Type;
-      Last_Line  : in     Line_Number_Type)
-     return Integer;
-
-   function Paren_In_Anchor_Line
-     (Data         : in out Parse_Data_Type'Class;
-      Tree         : in     Syntax_Trees.Tree'Class;
-      Anchor_Token : in     Augmented_Token;
-      Offset       : in     Integer)
-     return Integer;
-
-   ----------
-   --  body subprograms bodies, alphabetical
-
-   procedure Adjust_Paren_State
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree'Class;
-      First_Token_Index : in     Token_Index;
-      First_Line        : in     Line_Number_Type;
-      Adjust            : in     Integer)
-   is begin
-      for I in First_Token_Index .. Data.Terminals.Last_Index loop
-         declare
-            Aug : Augmented_Token renames Get_Aug_Token_Var (Data, Tree, I);
-         begin
-            Aug.Paren_State := Aug.Paren_State + Adjust;
-         end;
-      end loop;
-
-      for Line in First_Line .. Data.Line_Paren_State.Last_Index loop
-         Data.Line_Paren_State (Line) := Data.Line_Paren_State (Line) + Adjust;
-      end loop;
-   end Adjust_Paren_State;
-
-   function Image (Aug : in WisiToken.Base_Token_Class_Access; Descriptor : in 
WisiToken.Descriptor) return String
-   is begin
-      return Image (Augmented_Token_Access (Aug).all, Descriptor);
-   end Image;
-
-   function Image (Action : in WisiToken.Syntax_Trees.Semantic_Action) return 
String
-   is
-      pragma Unreferenced (Action);
-   begin
-      return "action";
-   end Image;
-
-   function Image (Anchor_IDs : in Anchor_ID_Vectors.Vector) return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String := +"(";
-   begin
-      for I in Anchor_IDs.First_Index .. Anchor_IDs.Last_Index loop
-         Result := Result & Integer'Image (Anchor_IDs (I));
-         if I /= Anchor_IDs.Last_Index then
-            Result := Result & ", ";
-         else
-            Result := Result & ")";
-         end if;
-      end loop;
-      return -Result;
-   end Image;
-
-   function Image (Indent : in Indent_Type) return String
-   is begin
-      case Indent.Label is
-      when Not_Set =>
-         return "(" & Indent_Label'Image (Indent.Label) & ")";
-
-      when Int =>
-         return "(" & Indent_Label'Image (Indent.Label) & Integer'Image 
(Indent.Int_Indent) & ")";
-
-      when Anchor_Nil =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Nil_IDs) & ", nil)";
-
-      when Anchor_Int =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Int_IDs) & ", " & Integer'Image
-           (Indent.Anchor_Int_Indent) & ")";
-
-      when Anchored =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Integer'Image 
(Indent.Anchored_ID) & ", " &
-           Integer'Image (Indent.Anchored_Delta) & ")";
-
-      when Anchor_Anchored =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Anchored_IDs) & Integer'Image
-           (Indent.Anchor_Anchored_ID) & ", " & Integer'Image 
(Indent.Anchor_Anchored_Delta) & ")";
-      end case;
-   end Image;
-
-   procedure Indent_Apply_Anchored
-     (Delta_Indent : in     Simple_Delta_Type;
-      Indent       : in out Indent_Type)
-   with Pre => Delta_Indent.Label = Anchored
-   is begin
-      --  Add Delta_Indent to Indent
-
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Anchored, Delta_Indent.Anchored_ID, 
Delta_Indent.Anchored_Delta);
-
-      when Int =>
-         if Delta_Indent.Anchored_Accumulate then
-            Indent := (Anchored, Delta_Indent.Anchored_ID, Indent.Int_Indent + 
Delta_Indent.Anchored_Delta);
-         end if;
-
-      when Anchor_Nil =>
-         Indent :=
-           (Anchor_Anchored,
-            Indent.Anchor_Nil_IDs,
-            Delta_Indent.Anchored_ID,
-            Delta_Indent.Anchored_Delta);
-
-      when Anchor_Int =>
-         if Delta_Indent.Anchored_Accumulate then
-            Indent :=
-              (Anchor_Anchored,
-               Indent.Anchor_Int_IDs,
-               Delta_Indent.Anchored_ID,
-               Delta_Indent.Anchored_Delta + Indent.Anchor_Int_Indent);
-         end if;
-
-      when Anchored | Anchor_Anchored =>
-         --  already anchored
-         null;
-      end case;
-   end Indent_Apply_Anchored;
-
-   procedure Indent_Apply_Int (Indent : in out Indent_Type; Offset : in 
Integer)
-   is begin
-      --  Add an Int indent to Indent
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Int, Offset);
-
-      when Int =>
-         Indent.Int_Indent := Indent.Int_Indent + Offset;
-
-      when Anchor_Nil         =>
-         Indent :=
-           (Label             => Anchor_Int,
-            Anchor_Int_IDs    => Indent.Anchor_Nil_IDs,
-            Anchor_Int_Indent => Offset);
-
-      when Anchor_Int =>
-         Indent.Anchor_Int_Indent := Indent.Anchor_Int_Indent + Offset;
-
-      when Anchored | Anchor_Anchored =>
-         null;
-      end case;
-   end Indent_Apply_Int;
-
-   procedure Indent_Line
-     (Data         : in out Parse_Data_Type;
-      Line         : in     Line_Number_Type;
-      Delta_Indent : in     Delta_Type)
-   is
-      --  See note in Indent_Anchored_2 for why we can't use renames here.
-      Indent : Indent_Type := Data.Indents (Line);
-   begin
-      case Delta_Indent.Label is
-      when Simple =>
-         case Delta_Indent.Simple_Delta.Label is
-         when None =>
-            null;
-
-         when Int =>
-            Indent_Apply_Int (Indent, Delta_Indent.Simple_Delta.Int_Delta);
-
-         when Anchored =>
-            Indent_Apply_Anchored (Delta_Indent.Simple_Delta, Indent);
-         end case;
-
-      when Hanging =>
-         if Delta_Indent.Hanging_Accumulate or Indent_Nil_P (Data.Indents 
(Line)) then
-            if Line = Delta_Indent.Hanging_First_Line then
-               --  Apply delta_1
-               case Delta_Indent.Hanging_Delta_1.Label is
-               when None =>
-                  null;
-               when Int =>
-                  Indent_Apply_Int (Indent, 
Delta_Indent.Hanging_Delta_1.Int_Delta);
-               when Anchored =>
-                  Indent_Apply_Anchored (Delta_Indent.Hanging_Delta_1, Indent);
-               end case;
-            else
-               if Delta_Indent.Hanging_Paren_State = Data.Line_Paren_State 
(Line) then
-                  case Delta_Indent.Hanging_Delta_2.Label is
-                  when None =>
-                     null;
-                  when Int =>
-                     Indent_Apply_Int (Indent, 
Delta_Indent.Hanging_Delta_2.Int_Delta);
-                  when Anchored =>
-                     Indent_Apply_Anchored (Delta_Indent.Hanging_Delta_2, 
Indent);
-                  end case;
-               end if;
-            end if;
-         end if;
-      end case;
-
-      if Trace_Action > Extra then
-         Ada.Text_IO.Put_Line (";; indent_line: " & Line_Number_Type'Image 
(Line) & " => " & Image (Indent));
-      end if;
-
-      Data.Indents.Replace_Element (Line, Indent);
-   end Indent_Line;
-
-   function Indent_Nil_P (Indent : in Indent_Type) return Boolean
-   is begin
-      return Indent.Label in Not_Set | Anchor_Nil;
-   end Indent_Nil_P;
-
-   function Max_Anchor_ID
-     (Data       : in out Parse_Data_Type;
-      First_Line : in     Line_Number_Type;
-      Last_Line  : in     Line_Number_Type)
-     return Integer
-   is
-      Result : Integer := First_Anchor_ID - 1;
-   begin
-      for Line in First_Line .. Last_Line loop
-         declare
-            Indent : Indent_Type renames Data.Indents (Line);
-         begin
-            case Indent.Label is
-            when Not_Set | Int =>
-               null;
-            when Anchor_Nil =>
-               Result := Integer'Max (Result, Indent.Anchor_Nil_IDs 
(Indent.Anchor_Nil_IDs.First_Index));
-            when Anchor_Int =>
-               Result := Integer'Max (Result, Indent.Anchor_Int_IDs 
(Indent.Anchor_Int_IDs.First_Index));
-            when Anchored =>
-               Result := Integer'Max (Result, Indent.Anchored_ID);
-            when Anchor_Anchored =>
-               Result := Integer'Max (Result, Indent.Anchor_Anchored_ID);
-            end case;
-         end;
-      end loop;
-      return Result;
-   end Max_Anchor_ID;
-
-   function Paren_In_Anchor_Line
-     (Data         : in out Parse_Data_Type'Class;
-      Tree         : in     Syntax_Trees.Tree'Class;
-      Anchor_Token : in     Augmented_Token;
-      Offset       : in     Integer)
-     return Integer
-   is
-      use Valid_Node_Index_Arrays;
-      use all type Ada.Containers.Count_Type;
-
-      Left_Paren_ID  : Token_ID renames Data.Left_Paren_ID;
-      Right_Paren_ID : Token_ID renames Data.Right_Paren_ID;
-
-      I              : Base_Token_Index := Anchor_Token.First_Terminals_Index;
-      Paren_Count    : Integer          := 0;
-      Paren_Char_Pos : Buffer_Pos       := Invalid_Buffer_Pos;
-      Text_Begin_Pos : Buffer_Pos       := Invalid_Buffer_Pos;
-   begin
-      Find_First :
-      loop
-         declare
-            Tok : Aug_Token_Const_Ref renames Get_Aug_Token_Const (Data, Tree, 
I);
-         begin
-            if Tok.Deleted then
-               null;
-
-            elsif Tok.ID = Left_Paren_ID then
-               Paren_Count := Paren_Count + 1;
-               if Paren_Count = 1 then
-                  Paren_Char_Pos := Tok.Char_Region.First;
-               end if;
-
-            elsif Tok.ID = Right_Paren_ID then
-               Paren_Count := Paren_Count - 1;
-
-            end if;
-
-            if Tok.First then
-               Text_Begin_Pos := Tok.Char_Region.First;
-               exit Find_First;
-            else
-               if Length (Tok.Inserted_Before) > 0 then
-                  for Node of Tok.Inserted_Before loop
-                     declare
-                        Ins_Tok : Augmented_Token renames Augmented_Token 
(Tree.Augmented (Node).all);
-                     begin
-                        if Ins_Tok.ID = Left_Paren_ID then
-                           Paren_Count := Paren_Count + 1;
-                           if Paren_Count = 1 then
-                              Paren_Char_Pos := Tok.Char_Region.First;
-                           end if;
-
-                        elsif Ins_Tok.ID = Right_Paren_ID then
-                           Paren_Count := Paren_Count - 1;
-
-                        end if;
-
-                        if Ins_Tok.First then
-                           Text_Begin_Pos := Tok.Char_Region.First;
-                           exit Find_First;
-                        end if;
-                     end;
-                  end loop;
-               end if;
-            end if;
-         end;
-         I := I - 1;
-      end loop Find_First;
-
-      if Paren_Char_Pos /= Invalid_Buffer_Pos and Text_Begin_Pos /= 
Invalid_Buffer_Pos then
-         return 1 + Offset + Integer (Paren_Char_Pos - Text_Begin_Pos);
-      else
-         return Offset;
-      end if;
-   end Paren_In_Anchor_Line;
-
-   procedure Put (Cache : in Navigate_Cache_Type)
-   is
-      package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (Max 
=> 2 + 11 * Chars_Per_Int);
-      use Bounded;
-
-      Line : Bounded_String := To_Bounded_String ("[");
-
-      procedure Append (Item : in Nil_Buffer_Pos)
-      is begin
-         if Item.Set then
-            Append (Line, Buffer_Pos'Image (Item.Item));
-         else
-            Append (Line, " -1");
-         end if;
-      end Append;
-   begin
-      Append (Line, Navigate_Cache_Code);
-      Append (Line, Buffer_Pos'Image (Cache.Pos));
-      Append (Line, Token_ID'Image (Cache.Statement_ID));
-      Append (Line, Token_ID'Image (Cache.ID));
-      Append (Line, Integer'Image (Cache.Length));
-      Append (Line, Integer'Image (Navigate_Class_Type'Pos (Cache.Class)));
-      Append (Cache.Containing_Pos);
-      Append (Cache.Prev_Pos);
-      Append (Cache.Next_Pos);
-      Append (Cache.End_Pos);
-      Append (Line, ']');
-      Ada.Text_IO.Put_Line (To_String (Line));
-   end Put;
-
-   procedure Put (Cache : in WisiToken.Buffer_Region)
-   is begin
-      Ada.Text_IO.Put_Line
-        ("[" & Name_Property_Code & Buffer_Pos'Image (Cache.First) & 
Buffer_Pos'Image (Cache.Last) & "]");
-   end Put;
-
-   procedure Put (Cache : in Face_Cache_Type)
-   is
-      package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (Max 
=> 2 + 4 * Chars_Per_Int);
-      use Bounded;
-
-      Line : Bounded_String := To_Bounded_String ("[");
-   begin
-      if Cache.Face.Set then
-         Append (Line, Face_Property_Code);
-         Append (Line, Buffer_Pos'Image (Cache.Char_Region.First));
-         Append (Line, Buffer_Pos'Image (Cache.Char_Region.Last));
-         Append (Line, Integer'Image (Cache.Face.Item));
-         Append (Line, ']');
-         Ada.Text_IO.Put_Line (To_String (Line));
-      end if;
-   end Put;
-
-   procedure Put (Line_Number : in Line_Number_Type; Item : in Indent_Type)
-   is begin
-      --  All Anchors must be resolved at this point, but not all lines have
-      --  an indent computed. A negative indent is an error in either the
-      --  grammar indent rules or the algorithms in this package.
-      case Item.Label is
-      when Not_Set =>
-         --  Especially with partial parse, we have no idea what this indent 
should be.
-         null;
-
-      when Int =>
-         declare
-            --  We can easily get negative indents when there are syntax 
errors.
-            Ind : constant Integer := Integer'Max (0, Item.Int_Indent);
-         begin
-            Ada.Text_IO.Put_Line
-              ('[' & Indent_Code & Line_Number_Type'Image (Line_Number) & 
Integer'Image (Ind) & ']');
-         end;
-
-      when Anchor_Nil | Anchor_Int | Anchored | Anchor_Anchored =>
-         raise SAL.Programmer_Error with "Indent item has non-int label: " & 
Indent_Label'Image (Item.Label);
-      end case;
-   end Put;
-
-   procedure Put
-     (Item : in Parse.LR.Configuration;
-      Data : in Parse_Data_Type;
-      Tree : in Syntax_Trees.Tree)
-   is
-      use Ada.Strings.Unbounded;
-      use Parse.LR;
-      use Parse.LR.Config_Op_Arrays, Parse.LR.Config_Op_Array_Refs;
-
-      --  Output is a sequence of edit regions; each is:
-      --  [edit-pos [inserted token-ids] [deleted token-ids] deleted-region]
-
-      type State_Label is
-        (None,     -- not started yet
-         Inserted, -- edit-pos, some insert ids appended
-         Deleted); -- some delete ids appended
-
-      State : State_Label := None;
-      --  State of the current edit region.
-
-      Line           : Unbounded_String := To_Unbounded_String ("[");
-      Deleted_Region : Buffer_Region    := Null_Buffer_Region;
-      Last_Deleted : Config_Op (Delete) := (Delete, Invalid_Token_ID, 
Invalid_Token_Index);
-
-      procedure Start_Edit_Region (Op : in Insert_Delete_Op)
-      is begin
-         Append (Line, "[");
-         Append (Line, Get_Aug_Token_Const (Data, Tree, Parse.LR.Token_Index 
(Op)).Char_Region.First'Image);
-         Append (Line, "[");
-      end Start_Edit_Region;
-
-      function Deleted_Region_Image return String
-      is begin
-         return "(" & Deleted_Region.First'Image & " . " & Buffer_Pos'Image 
(Deleted_Region.Last + 1) & ")";
-      end Deleted_Region_Image;
-
-      procedure Terminate_Edit_Region
-      is begin
-         case State is
-         when None =>
-            null;
-         when Inserted =>
-            Append (Line, "][]" & Deleted_Region_Image & "]");
-         when Deleted =>
-            Append (Line, "]" & Deleted_Region_Image & "]");
-         end case;
-         Deleted_Region := Null_Buffer_Region;
-      end Terminate_Edit_Region;
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line (";; " & Parse.LR.Image (Item.Ops, 
Data.Descriptor.all));
-      end if;
-
-      Append (Line, Recover_Code);
-      for I in First_Index (Item.Ops) .. Last_Index (Item.Ops) loop
-         declare
-            Op : Config_Op renames Constant_Ref (Item.Ops, I);
-         begin
-            case Op.Op is
-            when Fast_Forward =>
-               Terminate_Edit_Region;
-               State := None;
-
-            when Undo_Reduce | Push_Back =>
-               null;
-
-            when Insert =>
-               case State is
-               when None =>
-                  Start_Edit_Region (Op);
-
-               when Inserted =>
-                  null;
-
-               when Deleted =>
-                  Terminate_Edit_Region;
-                  Start_Edit_Region (Op);
-
-               end case;
-               Append (Line, Token_ID'Image (Op.Ins_ID));
-               State := Inserted;
-
-            when Delete =>
-               Deleted_Region := Deleted_Region and Get_Aug_Token_Const (Data, 
Tree, Op.Del_Token_Index).Char_Region;
-               declare
-                  Skip : Boolean := False;
-               begin
-                  case State is
-                  when None =>
-                     Start_Edit_Region (Op);
-                     Append (Line, "][");
-
-                  when Inserted =>
-                     Append (Line, "][");
-
-                  when Deleted =>
-                     if Data.Embedded_Quote_Escape_Doubled and then
-                       ((Last_Deleted.Del_ID = Data.Descriptor.String_1_ID and
-                           Op.Del_ID = Data.Descriptor.String_1_ID) or
-                          (Last_Deleted.Del_ID = Data.Descriptor.String_2_ID 
and
-                             Op.Del_ID = Data.Descriptor.String_2_ID))
-                     then
-                        declare
-                           Tok_1 : Augmented_Token renames Get_Aug_Token_Const
-                             (Data, Tree, Last_Deleted.Del_Token_Index);
-                           Tok_2 : Augmented_Token renames Get_Aug_Token_Const 
(Data, Tree, Op.Del_Token_Index);
-                        begin
-                           if Tok_1.Char_Region.Last + 1 = 
Tok_2.Char_Region.First then
-                              --  Buffer text was '"""', lexer repair changed 
it to '""""'. The
-                              --  repaired text looks like a single string 
with an embedded quote.
-                              --  But here, it is two STRING_LITERAL tokens. 
Don't send the second
-                              --  delete to elisp. See 
test/ada_mode-recover_string_quote_1.adb
-                              Skip := True;
-                           end if;
-                        end;
-                     end if;
-                  end case;
-                  State := Deleted;
-
-                  if not Skip then
-                     Append (Line, Token_ID'Image (Op.Del_ID));
-                  end if;
-               end;
-               Last_Deleted := Op;
-            end case;
-         end;
-      end loop;
-
-      case State is
-      when None =>
-         null;
-      when Inserted | Deleted =>
-         Terminate_Edit_Region;
-      end case;
-      Append (Line, "]");
-      Ada.Text_IO.Put_Line (To_String (Line));
-   end Put;
-
-   procedure Resolve_Anchors (Data : in out Parse_Data_Type)
-   is
-      Begin_Indent  : Integer renames Data.Begin_Indent;
-      Anchor_Indent : array (First_Anchor_ID .. Data.Max_Anchor_ID) of Integer;
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line (";; Begin_Indent: " & Integer'Image 
(Data.Begin_Indent));
-         for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-            Ada.Text_IO.Put_Line (";; " & Line_Number_Type'Image (I) & ", " & 
Image (Data.Indents (I)));
-         end loop;
-         Ada.Text_IO.Put_Line (";; resolve anchors");
-      end if;
-
-      for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-         declare
-            Indent : constant Indent_Type := Data.Indents (I);
-         begin
-            case Indent.Label is
-            when Not_Set =>
-               --  Indent not computed, therefore not output.
-               null;
-
-            when Int =>
-               Data.Indents.Replace_Element (I, (Int, Indent.Int_Indent + 
Begin_Indent));
-
-            when Anchor_Nil =>
-               for I of Indent.Anchor_Nil_IDs loop
-                  Anchor_Indent (I) := Begin_Indent;
-               end loop;
-               Data.Indents.Replace_Element (I, (Int, Begin_Indent));
-
-            when Anchor_Int =>
-               for I of Indent.Anchor_Int_IDs loop
-                  Anchor_Indent (I) := Indent.Anchor_Int_Indent + Begin_Indent;
-               end loop;
-               Data.Indents.Replace_Element (I, (Int, Indent.Anchor_Int_Indent 
+ Begin_Indent));
-
-            when Anchored =>
-               Data.Indents.Replace_Element
-                 (I, (Int, Anchor_Indent (Indent.Anchored_ID) + 
Indent.Anchored_Delta));
-
-            when Anchor_Anchored =>
-               declare
-                  Temp : constant Integer :=
-                    Anchor_Indent (Indent.Anchor_Anchored_ID) + 
Indent.Anchor_Anchored_Delta;
-               begin
-                  for I of Indent.Anchor_Anchored_IDs loop
-                     Anchor_Indent (I) := Temp;
-                  end loop;
-                  Data.Indents.Replace_Element (I, (Int, Temp));
-               end;
-            end case;
-         end;
-      end loop;
-   end Resolve_Anchors;
-
-   procedure Set_End
-     (Data           : in out Parse_Data_Type;
-      Containing_Pos : in     Buffer_Pos;
-      End_Pos        : in     Buffer_Pos)
-   is
-      use Navigate_Cursor_Lists;
-      I            : Cursor := Data.End_Positions.First;
-      Delete_Cache : Boolean;
-      Temp         : Cursor;
-   begin
-      loop
-         exit when not Has_Element (I);
-         declare
-            Cache : Navigate_Cache_Type renames Data.Navigate_Caches (Element 
(I));
-         begin
-            if Cache.Pos in Containing_Pos .. End_Pos then
-               Cache.End_Pos := (True, End_Pos);
-               Delete_Cache := True;
-            else
-               Delete_Cache := False;
-            end if;
-         end;
-         if Delete_Cache then
-            Temp := Next (I);
-            Delete (Data.End_Positions, I);
-
-            I := Temp;
-         else
-            Next (I);
-         end if;
-
-      end loop;
-   end Set_End;
-
-   ----------
-   --  public subprograms (declaration order)
-
-   procedure Initialize
-     (Data              : in out Parse_Data_Type;
-      Lexer             : in     WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : in     Base_Token_Array_Access;
-      Post_Parse_Action : in     Post_Parse_Action_Type;
-      Begin_Line        : in     Line_Number_Type;
-      End_Line          : in     Line_Number_Type;
-      Begin_Indent      : in     Integer;
-      Params            : in     String)
-   is
-      pragma Unreferenced (Params);
-   begin
-      Data.Line_Begin_Char_Pos.Set_First_Last
-        (First   => Begin_Line,
-         Last    => End_Line);
-
-      --  + 1 for data on line following last line; see Lexer_To_Augmented.
-      Data.Line_Paren_State.Set_First_Last
-        (First   => Begin_Line,
-         Last    => End_Line + 1);
-
-      Data.Lexer             := Lexer;
-      Data.Descriptor        := Descriptor;
-      Data.Base_Terminals    := Base_Terminals;
-      Data.Post_Parse_Action := Post_Parse_Action;
-
-      case Post_Parse_Action is
-      when Navigate | Face =>
-         null;
-      when Indent =>
-         Data.Indents.Set_First_Last
-           (First   => Begin_Line,
-            Last    => End_Line);
-
-         Data.Begin_Indent := Begin_Indent;
-      end case;
-
-      Data.Reset;
-   exception
-   when E : others =>
-      raise SAL.Programmer_Error with "wisi.initialize: " & 
Ada.Exceptions.Exception_Name (E) & ": " &
-        Ada.Exceptions.Exception_Message (E);
-   end Initialize;
-
-   overriding procedure Reset (Data : in out Parse_Data_Type)
-   is begin
-      Data.Last_Terminal_Node := WisiToken.Invalid_Node_Index;
-
-      Data.Leading_Non_Grammar.Clear;
-
-      --  Data.Line_Begin_Char_Pos  set in Initialize, overwritten in 
Lexer_To_Augmented
-
-      for S of Data.Line_Paren_State loop
-         S := 0;
-      end loop;
-      Data.Current_Paren_State := 0;
-
-      Data.Navigate_Caches.Finalize;
-      Data.Navigate_Caches.Initialize;
-
-      Data.Name_Caches.Finalize;
-      Data.Name_Caches.Initialize;
-
-      Data.End_Positions.Clear;
-
-      Data.Face_Caches.Finalize;
-      Data.Face_Caches.Initialize;
-
-      for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-         Data.Indents.Replace_Element (I, (Label => Not_Set));
-      end loop;
-      Data.Max_Anchor_ID := First_Anchor_ID - 1;
-   end Reset;
-
-   function Source_File_Name (Data : in Parse_Data_Type) return String
-   is begin
-      return Data.Lexer.File_Name;
-   end Source_File_Name;
-
-   function Post_Parse_Action (Data : in Parse_Data_Type) return 
Post_Parse_Action_Type
-   is begin
-      return Data.Post_Parse_Action;
-   end Post_Parse_Action;
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          Parse_Data_Type;
-      Tree  : in out          Syntax_Trees.Tree'Class;
-      Token : in              Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Lexer.First then
-         Data.Line_Begin_Char_Pos (Token.Line) := Token.Char_Region.First;
-
-         if Token.Line > Data.Line_Begin_Char_Pos.First_Index and then
-           Data.Line_Begin_Char_Pos (Token.Line - 1) = Invalid_Buffer_Pos
-         then
-            --  Previous token contains multiple lines; ie %code in 
wisitoken_grammar.wy
-            declare
-               First_Set_Line : Line_Number_Type;
-            begin
-               for Line in reverse Data.Line_Begin_Char_Pos.First_Index .. 
Token.Line - 1 loop
-                  if Data.Line_Begin_Char_Pos (Line) /= Invalid_Buffer_Pos then
-                     First_Set_Line := Line;
-                     exit;
-                  end if;
-               end loop;
-               for Line in First_Set_Line + 1 .. Token.Line - 1 loop
-                  Data.Line_Begin_Char_Pos (Line) := Data.Line_Begin_Char_Pos 
(First_Set_Line); -- good enough
-               end loop;
-            end;
-         end if;
-      end if;
-
-      if Token.ID < Data.Descriptor.First_Terminal then
-         --  Non-grammar token
-
-         if Token.ID = Data.Descriptor.New_Line_ID then
-            Data.Line_Paren_State (Token.Line + 1) := Data.Current_Paren_State;
-         end if;
-
-         if Data.Last_Terminal_Node = Invalid_Node_Index then
-            Data.Leading_Non_Grammar.Append ((Token with Lexer.First));
-         else
-            declare
-               Containing_Token : Aug_Token_Var_Ref renames Get_Aug_Token_Var 
(Tree, Data.Last_Terminal_Node);
-
-               Trailing_Blank : constant Boolean :=
-                 Token.ID = Data.Descriptor.New_Line_ID and
-                 (Containing_Token.Non_Grammar.Length > 0 and then
-                    Containing_Token.Non_Grammar
-                      (Containing_Token.Non_Grammar.Last_Index).ID = 
Data.Descriptor.New_Line_ID);
-            begin
-               if Lexer.First and
-                 (Token.ID in Data.First_Comment_ID .. Data.Last_Comment_ID or
-                    Trailing_Blank)
-               then
-                  if Containing_Token.First_Trailing_Comment_Line = 
Invalid_Line_Number then
-                     Containing_Token.First_Trailing_Comment_Line := 
Token.Line;
-                  end if;
-                  Containing_Token.Last_Trailing_Comment_Line  := Token.Line;
-               end if;
-
-               Containing_Token.Non_Grammar.Append ((Token with Lexer.First));
-            end;
-         end if;
-
-      else
-         --  grammar token
-         declare
-            Temp : constant Augmented_Token_Access := new Augmented_Token'
-              (Token with
-               Deleted                     => False,
-               First                       => Lexer.First,
-               Paren_State                 => Data.Current_Paren_State,
-               First_Terminals_Index       => Data.Terminals.Last_Index,
-               Last_Terminals_Index        => Data.Terminals.Last_Index,
-               First_Indent_Line           => (if Lexer.First then Token.Line 
else Invalid_Line_Number),
-               Last_Indent_Line            => (if Lexer.First then Token.Line 
else Invalid_Line_Number),
-               First_Trailing_Comment_Line => Invalid_Line_Number, -- Set by 
Reduce
-               Last_Trailing_Comment_Line  => Invalid_Line_Number,
-               Non_Grammar                 => 
Non_Grammar_Token_Arrays.Empty_Vector,
-               Inserted_Before             => 
Valid_Node_Index_Arrays.Empty_Vector);
-         begin
-            Data.Last_Terminal_Node := Token.Tree_Index;
-
-            if Token.ID = Data.Left_Paren_ID then
-               Data.Current_Paren_State := Data.Current_Paren_State + 1;
-
-            elsif Token.ID = Data.Right_Paren_ID then
-               Data.Current_Paren_State := Data.Current_Paren_State - 1;
-            end if;
-
-            Tree.Set_Augmented (Token.Tree_Index, Base_Token_Class_Access 
(Temp));
-         end;
-      end if;
-   end Lexer_To_Augmented;
-
-   overriding
-   procedure Insert_Token
-     (Data  : in out Parse_Data_Type;
-      Tree  : in out Syntax_Trees.Tree'Class;
-      Token : in     Valid_Node_Index)
-   is
-      use Valid_Node_Index_Arrays;
-
-      Before_Index : constant Token_Index := Tree.Before (Token);
-      Before_Aug : Aug_Token_Var_Ref renames Get_Aug_Token_Var (Data, Tree, 
Before_Index);
-
-      --  Set data that allows using Token when computing indent.
-
-      Indent_Line : constant Line_Number_Type :=
-        (if Before_Aug.First
-         then Before_Aug.Line
-         else Invalid_Line_Number);
-
-      --  Set for Insert_After False; see below for True.
-      New_Aug : constant Augmented_Token_Access := new Augmented_Token'
-        (ID                          => Tree.ID (Token),
-         Tree_Index                  => Token,
-         Byte_Region                 => (First | Last => 
Before_Aug.Byte_Region.First),
-         Line                        => Before_Aug.Line,
-         Column                      => Before_Aug.Column,
-         Char_Region                 => (First | Last => 
Before_Aug.Char_Region.First),
-         Deleted                     => False,
-         First                       => Before_Aug.First,
-         Paren_State                 => Before_Aug.Paren_State,
-         First_Terminals_Index       => Invalid_Token_Index,
-         Last_Terminals_Index        => Invalid_Token_Index,
-         First_Indent_Line           => Indent_Line,
-         Last_Indent_Line            => Indent_Line,
-         First_Trailing_Comment_Line => Invalid_Line_Number,
-         Last_Trailing_Comment_Line  => Invalid_Line_Number,
-         Non_Grammar                 => Non_Grammar_Token_Arrays.Empty_Vector,
-         Inserted_Before             => Valid_Node_Index_Arrays.Empty_Vector);
-
-      Prev_Terminal : constant Node_Index := Tree.Prev_Terminal (Token);
-      --  Invalid_Node_Index if Token is inserted before first grammar token
-
-      Insert_After : Boolean := False;
-   begin
-      Tree.Set_Augmented (Token, Base_Token_Class_Access (New_Aug));
-
-      Append (Before_Aug.Inserted_Before, Token);
-
-      if Prev_Terminal /= Invalid_Node_Index and Before_Aug.First then
-         declare
-            use all type Ada.Containers.Count_Type;
-            use all type Ada.Text_IO.Count;
-
-            --  See test/ada_mode-interactive_2.adb, "Typing ..."; three tests.
-            --
-            --  When typing new code, we want a new blank line to be indented 
as
-            --  if the code was there already. To accomplish that, we put the
-            --  inserted tokens at the end of the line before the Before token;
-            --  that will be after the non-grammar on the previous terminal.
-            --
-            --  Compare to test/ada_mode-recover_20.adb. There we are not 
typing
-            --  new code, but there is a blank line; the right paren is placed 
at
-            --  the end of the blank line, causing the comment to be indented.
-
-            Prev_Aug : Aug_Token_Var_Ref renames Get_Aug_Token_Var (Tree, 
Prev_Terminal);
-
-            --  Prev_Aug.Non_Grammar must have at least one New_Line, since
-            --  Before_Aug.First is True. The whitespace after the New_Line is 
not
-            --  given a token.
-            --
-            --  If the first two tokens in Prev_Non_Grammar are both New_Lines,
-            --  there is a blank line after the code line (and before any
-            --  comments); assume that is the edit point.
-            Insert_On_Blank_Line : constant Boolean := 
Prev_Aug.Non_Grammar.Length >= 2 and then
-              (Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index).ID = 
Data.Descriptor.New_Line_ID and
-                 Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index + 
1).ID = Data.Descriptor.New_Line_ID);
-
-            --  In Ada, 'end' is Insert_After except when Insert_On_Blank_Line 
is
-            --  True (see test/ada_mode-interactive_2.adb Record_1), so 
Insert_After
-            --  needs Insert_On_Blank_Line.
-         begin
-            Insert_After := Parse_Data_Type'Class (Data).Insert_After (Tree, 
Token, Insert_On_Blank_Line);
-
-            if Insert_After then
-               if Insert_On_Blank_Line then
-                  declare
-                     Prev_Non_Grammar : constant Non_Grammar_Token :=
-                       Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index 
+ 1);
-                     --  The newline nominally after the inserted token.
-                  begin
-                     New_Aug.Byte_Region := (First | Last => 
Prev_Non_Grammar.Byte_Region.Last - 1);
-                     New_Aug.Char_Region := (First | Last => 
Prev_Non_Grammar.Char_Region.Last - 1);
-
-                     New_Aug.First  := True;
-                     New_Aug.Line   := Prev_Non_Grammar.Line;
-                     New_Aug.Column := Prev_Aug.Column + Ada.Text_IO.Count 
(Length (New_Aug.Char_Region)) - 1;
-
-                     New_Aug.First_Indent_Line := Prev_Non_Grammar.Line;
-                     New_Aug.Last_Indent_Line  := Prev_Non_Grammar.Line;
-
-                     for I in Prev_Aug.Non_Grammar.First_Index + 1 .. 
Prev_Aug.Non_Grammar.Last_Index loop
-                        New_Aug.Non_Grammar.Append (Prev_Aug.Non_Grammar (I));
-                     end loop;
-
-                     Prev_Aug.Non_Grammar.Set_First_Last
-                       (Prev_Aug.Non_Grammar.First_Index, 
Prev_Aug.Non_Grammar.First_Index);
-                  end;
-               else
-                  New_Aug.Byte_Region := (First | Last => 
Prev_Aug.Byte_Region.Last);
-                  New_Aug.Char_Region := (First | Last => 
Prev_Aug.Char_Region.Last);
-
-                  New_Aug.First  := False;
-                  New_Aug.Line   := Prev_Aug.Line;
-                  New_Aug.Column := Prev_Aug.Column + Ada.Text_IO.Count 
(Length (Prev_Aug.Char_Region)) - 1;
-
-                  New_Aug.First_Indent_Line := Invalid_Line_Number;
-                  New_Aug.Last_Indent_Line  := Invalid_Line_Number;
-
-                  New_Aug.Non_Grammar  := Prev_Aug.Non_Grammar;
-                  Prev_Aug.Non_Grammar := 
Non_Grammar_Token_Arrays.Empty_Vector;
-
-               end if;
-
-               New_Aug.First_Trailing_Comment_Line := 
Prev_Aug.First_Trailing_Comment_Line;
-               New_Aug.Last_Trailing_Comment_Line  := 
Prev_Aug.Last_Trailing_Comment_Line;
-
-               Prev_Aug.First_Trailing_Comment_Line := Invalid_Line_Number;
-               Prev_Aug.Last_Trailing_Comment_Line  := Invalid_Line_Number;
-            end if;
-         end;
-      end if;
-
-      if New_Aug.First and not Insert_After then
-         Before_Aug.First             := False;
-         Before_Aug.First_Indent_Line := Invalid_Line_Number;
-         Before_Aug.Last_Indent_Line  := Invalid_Line_Number;
-      end if;
-
-      if New_Aug.ID = Data.Left_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Before_Index, New_Aug.Line + 1, +1);
-
-      elsif New_Aug.ID = Data.Right_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Before_Index, New_Aug.Line + 1, -1);
-      end if;
-   end Insert_Token;
-
-   overriding
-   procedure Delete_Token
-     (Data                : in out Parse_Data_Type;
-      Tree                : in out Syntax_Trees.Tree'Class;
-      Deleted_Token_Index : in     WisiToken.Token_Index)
-   is
-      use all type Ada.Containers.Count_Type;
-      Deleted_Token    : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Deleted_Token_Index);
-      Prev_Token_Index : Base_Token_Index := Deleted_Token_Index - 1;
-      Next_Token_Index : Base_Token_Index := Deleted_Token_Index + 1;
-   begin
-      if Deleted_Token.Deleted then
-         --  This can happen if error recovery screws up.
-         if WisiToken.Trace_Action > WisiToken.Detail then
-            Ada.Text_IO.Put_Line (";; delete token again; ignored " & Image 
(Deleted_Token, Data.Descriptor.all));
-         end if;
-         return;
-      end if;
-      if WisiToken.Trace_Action > WisiToken.Detail then
-         Ada.Text_IO.Put_Line (";; delete token " & Image (Deleted_Token, 
Data.Descriptor.all));
-      end if;
-
-      Deleted_Token.Deleted := True;
-
-      if Deleted_Token.Non_Grammar.Length > 0 then
-         --  Move Non_Grammar to previous non-deleted token
-
-         loop
-            exit when Prev_Token_Index = Base_Token_Index'First;
-            exit when Get_Aug_Token_Const (Data, Tree, 
Prev_Token_Index).Deleted = False;
-            Prev_Token_Index := Prev_Token_Index - 1;
-         end loop;
-
-         if Prev_Token_Index = Base_Token_Index'First then
-            Deleted_Token.Non_Grammar 
(Deleted_Token.Non_Grammar.First_Index).First := Deleted_Token.First;
-            Data.Leading_Non_Grammar.Append (Deleted_Token.Non_Grammar);
-         else
-            declare
-               Prev_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Prev_Token_Index);
-            begin
-               Prev_Token.Non_Grammar.Append (Deleted_Token.Non_Grammar);
-
-               if Deleted_Token.First_Trailing_Comment_Line /= 
Invalid_Line_Number then
-                  if Prev_Token.First_Trailing_Comment_Line = 
Invalid_Line_Number then
-                     Prev_Token.First_Trailing_Comment_Line := 
Deleted_Token.First_Trailing_Comment_Line;
-                  end if;
-                  Prev_Token.Last_Trailing_Comment_Line  := 
Deleted_Token.Last_Trailing_Comment_Line;
-               end if;
-            end;
-         end if;
-      end if;
-
-      --  Data.Terminals.Last_Index is Wisi_EOI; it is never deleted
-      loop
-         exit when Get_Aug_Token_Const (Data, Tree, Next_Token_Index).Deleted 
= False;
-         Next_Token_Index := Next_Token_Index + 1;
-         exit when Next_Token_Index = Data.Terminals.Last_Index;
-      end loop;
-
-      if Deleted_Token.First and
-        (Next_Token_Index = Data.Terminals.Last_Index or else
-           Get_Aug_Token_Const (Data, Tree, Next_Token_Index).Line > 
Deleted_Token.Line)
-      then
-         --  Deleted_Token.Line is now blank; add to previous token non
-         --  grammar.
-         if Prev_Token_Index > Base_Token_Index'First then
-            declare
-               Prev_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Prev_Token_Index);
-            begin
-               if Prev_Token.First_Trailing_Comment_Line = Invalid_Line_Number 
then
-                  Prev_Token.First_Trailing_Comment_Line := Deleted_Token.Line;
-                  Prev_Token.Last_Trailing_Comment_Line  := Deleted_Token.Line;
-               else
-                  if Prev_Token.First_Trailing_Comment_Line > 
Deleted_Token.Line then
-                     Prev_Token.First_Trailing_Comment_Line := 
Deleted_Token.Line;
-                  end if;
-                  if Prev_Token.Last_Trailing_Comment_Line < 
Deleted_Token.Line then
-                     Prev_Token.Last_Trailing_Comment_Line := 
Deleted_Token.Line;
-                  end if;
-               end if;
-            end;
-         end if;
-      end if;
-
-      if Deleted_Token.First and Next_Token_Index < Data.Terminals.Last_Index 
then
-         declare
-            Next_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Next_Token_Index);
-         begin
-            if not Next_Token.First then
-               Next_Token.First             := True;
-               Next_Token.First_Indent_Line := Deleted_Token.First_Indent_Line;
-               Next_Token.Last_Indent_Line  := Deleted_Token.Last_Indent_Line;
-            end if;
-         end;
-      end if;
-
-      if Deleted_Token.ID = Data.Left_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Deleted_Token_Index + 1, 
Deleted_Token.Line + 1, -1);
-
-      elsif Deleted_Token.ID = Data.Right_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Deleted_Token_Index + 1, 
Deleted_Token.Line + 1, +1);
-
-      end if;
-   end Delete_Token;
-
-   overriding
-   procedure Reduce
-     (Data    : in out Parse_Data_Type;
-      Tree    : in out Syntax_Trees.Tree'Class;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array)
-   is
-      Aug_Nonterm : constant Augmented_Token_Access := new Augmented_Token'
-        (ID          => Tree.ID (Nonterm),
-         Byte_Region => Tree.Byte_Region (Nonterm),
-         others      => <>);
-
-      Trailing_Comment_Done : Boolean := False;
-   begin
-      Tree.Set_Augmented (Nonterm, Base_Token_Class_Access (Aug_Nonterm));
-
-      for I in reverse Tokens'Range loop
-         --  'reverse' to find token containing trailing comments; last
-         --  non-empty token.
-         declare
-            Aug_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-         begin
-
-            if Data.Post_Parse_Action = Indent then
-               if Aug_Token.First_Terminals_Index /= Invalid_Token_Index then
-                  Aug_Nonterm.First_Terminals_Index := 
Aug_Token.First_Terminals_Index;
-               end if;
-
-               if Aug_Nonterm.Last_Terminals_Index = Invalid_Token_Index then
-                  Aug_Nonterm.Last_Terminals_Index := 
Aug_Token.Last_Terminals_Index;
-               end if;
-
-               Aug_Nonterm.First := Aug_Nonterm.First or Aug_Token.First;
-
-               if Aug_Token.First_Indent_Line /= Invalid_Line_Number then
-                  Aug_Nonterm.First_Indent_Line := Aug_Token.First_Indent_Line;
-               elsif Trailing_Comment_Done and 
Aug_Token.First_Trailing_Comment_Line /= Invalid_Line_Number then
-                  Aug_Nonterm.First_Indent_Line := 
Aug_Token.First_Trailing_Comment_Line;
-               end if;
-
-               if Aug_Nonterm.Last_Indent_Line = Invalid_Line_Number then
-                  if Trailing_Comment_Done and 
Aug_Token.Last_Trailing_Comment_Line /= Invalid_Line_Number then
-                     Aug_Nonterm.Last_Indent_Line := 
Aug_Token.Last_Trailing_Comment_Line;
-                  elsif Aug_Token.Last_Indent_Line /= Invalid_Line_Number then
-                     Aug_Nonterm.Last_Indent_Line := 
Aug_Token.Last_Indent_Line;
-                  end if;
-               end if;
-
-               if not Trailing_Comment_Done then
-                  Aug_Nonterm.First_Trailing_Comment_Line := 
Aug_Token.First_Trailing_Comment_Line;
-                  Aug_Nonterm.Last_Trailing_Comment_Line  := 
Aug_Token.Last_Trailing_Comment_Line;
-                  Trailing_Comment_Done := True;
-               end if;
-
-            end if; --  Compute_Indent
-
-            if Aug_Token.Line /= Invalid_Line_Number then
-               Aug_Nonterm.Line   := Aug_Token.Line;
-               Aug_Nonterm.Column := Aug_Token.Column;
-            end if;
-
-            if Aug_Nonterm.Char_Region.First > Aug_Token.Char_Region.First then
-               Aug_Nonterm.Char_Region.First := Aug_Token.Char_Region.First;
-            end if;
-
-            if Aug_Nonterm.Char_Region.Last < Aug_Token.Char_Region.Last then
-               Aug_Nonterm.Char_Region.Last := Aug_Token.Char_Region.Last;
-            end if;
-
-            Aug_Nonterm.Paren_State := Aug_Token.Paren_State;
-         end;
-      end loop;
-   end Reduce;
-
-   procedure Statement_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Statement_Param_Array)
-   is
-      Nonterm_Tok        : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Nonterm);
-      First_Item         : Boolean                := True;
-      Start_Set          : Boolean                := False;
-      Override_Start_Set : Boolean                := False;
-      Containing_Pos     : Nil_Buffer_Pos         := Nil;
-   begin
-      for Pair of Params loop
-         if not (Pair.Index in Tokens'Range) then
-            raise Fatal_Error with Error_Message
-              (File_Name => Data.Lexer.File_Name,
-               Line      => Nonterm_Tok.Line,
-               Column    => Nonterm_Tok.Column,
-               Message   => "wisi-statement-action: " & Trimmed_Image 
(Tree.Production_ID (Nonterm)) &
-                 " token index" & SAL.Peek_Type'Image (Pair.Index) &
-                 " not in tokens range (" & SAL.Peek_Type'Image (Tokens'First) 
& " .." &
-                 SAL.Peek_Type'Image (Tokens'Last) & "); bad grammar action.");
-
-         elsif Tree.Byte_Region (Tokens (Pair.Index)) /= Null_Buffer_Region 
then
-            declare
-               use all type WisiToken.Syntax_Trees.Node_Label;
-               Token  : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1
-                 (Tree,
-                  (if Pair.Class = Statement_End and then
-                     Tree.Label (Tokens (Pair.Index)) = 
WisiToken.Syntax_Trees.Nonterm
-                   then Tree.Last_Terminal (Tokens (Pair.Index))
-                   else Tokens (Pair.Index)));
-
-               Cache_Pos : constant Buffer_Pos         := 
Token.Char_Region.First;
-               Cursor    : Navigate_Cache_Trees.Cursor := 
Navigate_Cache_Trees.Find
-                 (Data.Navigate_Caches.Iterate, Cache_Pos,
-                  Direction => Navigate_Cache_Trees.Unknown);
-            begin
-               if Navigate_Cache_Trees.Has_Element (Cursor) then
-                  declare
-                     Cache : Navigate_Cache_Type renames Data.Navigate_Caches 
(Cursor);
-                  begin
-                     if Pair.Class = Statement_Start then
-                        if Start_Set then
-                           Cache.Class := Motion;
-                        else
-                           Cache.Class := Statement_Start;
-                           Start_Set   := True;
-                        end if;
-                     elsif Override_Start_Set then
-                        Cache.Class := Statement_Start;
-                        Start_Set   := True;
-                     else
-                        Cache.Class := Pair.Class;
-                     end if;
-                     Cache.Statement_ID   := Tree.ID (Nonterm);
-                     Cache.Containing_Pos := Containing_Pos;
-                  end;
-               else
-                  Cursor := Data.Navigate_Caches.Insert
-                    ((Pos            => Cache_Pos,
-                      Statement_ID   => Tree.ID (Nonterm),
-                      ID             => Token.ID,
-                      Length         => Length (Token.Char_Region),
-                      Class          => (if Override_Start_Set then 
Statement_Start else Pair.Class),
-                      Containing_Pos => Containing_Pos,
-                      others         => Nil));
-               end if;
-
-               Data.End_Positions.Append (Cursor);
-
-               if First_Item then
-                  First_Item := False;
-                  if Override_Start_Set or Pair.Class = Statement_Start then
-                     Override_Start_Set := False;
-                     Containing_Pos     := (True, Token.Char_Region.First);
-
-                     --  Set containing on all contained caches
-                     declare
-                        use Navigate_Cache_Trees;
-                        Iterator : constant Navigate_Cache_Trees.Iterator := 
Data.Navigate_Caches.Iterate;
-                        Cursor   : Navigate_Cache_Trees.Cursor            := 
Find_In_Range
-                          (Iterator, Ascending, Nonterm_Tok.Char_Region.First 
+ 1, -- don't set containing on start
-                           Nonterm_Tok.Char_Region.Last);
-                     begin
-                        loop
-                           exit when not Has_Element (Cursor);
-                           declare
-                              Cache : Navigate_Cache_Type renames 
Data.Navigate_Caches (Cursor);
-                           begin
-                              if not Cache.Containing_Pos.Set then
-                                 Cache.Containing_Pos := Containing_Pos;
-                              end if;
-                              exit when Nonterm_Tok.Char_Region.Last < 
Cache.Pos + 1;
-                           end;
-                           Cursor := Iterator.Next (Cursor);
-                        end loop;
-                     end;
-                  end if;
-               end if;
-
-               if Pair.Class = Statement_End and Containing_Pos.Set then
-                  Set_End (Data, Containing_Pos.Item, Cache_Pos);
-               end if;
-            end;
-
-         else
-            --  Token.Byte_Region is null
-            if First_Item and Pair.Class = Statement_Start then
-               Override_Start_Set := True;
-            end if;
-         end if;
-      end loop;
-   end Statement_Action;
-
-   procedure Name_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Name    : in     WisiToken.Positive_Index_Type)
-   is begin
-      if not (Name in Tokens'Range) then
-         declare
-            Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 (Tree, 
Tokens (Tokens'First));
-         begin
-            raise Fatal_Error with Error_Message
-              (File_Name => Data.Lexer.File_Name,
-               Line      => Token.Line,
-               Column    => Token.Column,
-               Message   => "wisi-name-action: " & Trimmed_Image 
(Tree.Production_ID (Nonterm)) & " name (" &
-                 Trimmed_Image (Name) & ") not in Tokens range (" & 
SAL.Peek_Type'Image (Tokens'First) & " .." &
-                 SAL.Peek_Type'Image (Tokens'Last) & "); bad grammar action.");
-         end;
-      end if;
-
-      if Tree.Is_Virtual (Tokens (Name)) then
-         --  Virtual tokens have the same Char_Region as the token they are
-         --  inserted before (for indent purposes), which leads to Name_Action
-         --  appearing to be applied twice. test/ada_mode-fatal_error_1.adb.
-         --  They also don't appear in the actual buffer, so setting a face or
-         --  completing on them is pointless.
-         return;
-      end if;
-
-      declare
-         use Name_Cache_Trees;
-         Name_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 (Tree, 
Tokens (Name));
-         Cursor     : constant Name_Cache_Trees.Cursor := Find
-           (Data.Name_Caches.Iterate, Name_Token.Char_Region.First,
-            Direction => Name_Cache_Trees.Unknown);
-      begin
-         if Name_Token.Char_Region = Null_Buffer_Region then
-            return;
-         elsif Has_Element (Cursor) then
-            raise Fatal_Error with Error_Message
-              (File_Name            => Data.Lexer.File_Name,
-               Line                 => Name_Token.Line,
-               Column               => Name_Token.Column,
-               Message              => Tree.Image
-                 (Tokens (Name), Data.Descriptor.all,
-                  Node_Numbers      => WisiToken.Trace_Action > Extra,
-                  Include_RHS_Index => WisiToken.Trace_Action > Extra)
-                 & ": wisi-name-action: name set twice.");
-         else
-            if Trace_Action > Detail then
-               Ada.Text_IO.Put_Line
-                 ("Name_Action " & Tree.Image
-                    (Nonterm, Data.Descriptor.all,
-                     Node_Numbers      => WisiToken.Trace_Action > Extra,
-                     Include_RHS_Index => WisiToken.Trace_Action > Extra) & " 
" & Tree.Image
-                       (Tokens (Name), Data.Descriptor.all,
-                        Node_Numbers      => WisiToken.Trace_Action > Extra,
-                        Include_RHS_Index => WisiToken.Trace_Action > Extra));
-            end if;
-
-            Data.Name_Caches.Insert (Name_Token.Char_Region);
-         end if;
-      end;
-   end Name_Action;
-
-   procedure Motion_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Motion_Param_Array)
-   is
-      use Navigate_Cache_Trees;
-
-      Start          : Nil_Buffer_Pos    := (Set => False);
-      Iter           : constant Iterator := Data.Navigate_Caches.Iterate;
-      Prev_Cache_Cur : Cursor;
-      Cache_Cur      : Cursor;
-   begin
-      if WisiToken.Trace_Action > Outline then
-         Ada.Text_IO.Put_Line
-           ("Motion_Action " & Image (Tree.ID (Nonterm), Data.Descriptor.all) 
& " " &
-              Image (Tree.Byte_Region (Nonterm)));
-      end if;
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               use all type WisiToken.Syntax_Trees.Node_Label;
-               Token  : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-               Region : constant Buffer_Region := Token.Char_Region;
-               Skip   : Boolean                := False;
-            begin
-               if not Start.Set then
-                  Start := (True, Region.First);
-               end if;
-
-               case Tree.Label (Tokens (Param.Index)) is
-               when Shared_Terminal =>
-                  Cache_Cur := Find (Iter, Region.First);
-               when Virtual_Terminal | Virtual_Identifier =>
-                  return;
-
-               when Syntax_Trees.Nonterm =>
-                  if Param.ID = Invalid_Token_ID then
-                     Cache_Cur := Find (Iter, Region.First);
-
-                  else
-                     Skip      := True;
-                     Cache_Cur := Find_In_Range (Iter, Ascending, 
Region.First, Region.Last);
-                     loop
-                        exit when not Has_Element (Cache_Cur);
-                        if Data.Navigate_Caches (Cache_Cur).Pos > Region.Last 
then
-                           Cache_Cur := No_Element;
-                           exit;
-
-                        elsif Data.Navigate_Caches (Cache_Cur).ID = Param.ID 
and
-                          not Data.Navigate_Caches (Cache_Cur).Prev_Pos.Set
-                        then
-                           Skip := False;
-                           exit;
-                        end if;
-
-                        Cache_Cur := Next (Iter, Cache_Cur);
-                     end loop;
-                  end if;
-               end case;
-
-               if not Skip then
-                  if not Has_Element (Cache_Cur) then
-                     raise Fatal_Error with Error_Message
-                       (File_Name => Data.Lexer.File_Name,
-                        Line      => Token.Line,
-                        Column    => Token.Column,
-                        Message   => "wisi-motion-action: token " &
-                          WisiToken.Image (Token.ID, Data.Descriptor.all) &
-                          " has no cache; add to statement-action for " &
-                          Trimmed_Image (Tree.Production_ID (Nonterm)) & ".");
-                  end if;
-
-                  if Has_Element (Prev_Cache_Cur) then
-                     declare
-                        Cache      : Navigate_Cache_Type renames 
Data.Navigate_Caches (Cache_Cur);
-                        Prev_Cache : Navigate_Cache_Type renames 
Data.Navigate_Caches (Prev_Cache_Cur);
-                     begin
-                        if not Cache.Prev_Pos.Set then
-                           Cache.Prev_Pos := (True, Prev_Cache.Pos);
-                           if WisiToken.Trace_Action > Detail then
-                              Ada.Text_IO.Put_Line ("   " & Cache.Pos'Image & 
" prev to " & Cache.Prev_Pos.Item'Image);
-                           end if;
-                        end if;
-
-                        if not Prev_Cache.Next_Pos.Set then
-                           Prev_Cache.Next_Pos := (True, Cache.Pos);
-                           if WisiToken.Trace_Action > Detail then
-                              Ada.Text_IO.Put_Line
-                                ("   " & Prev_Cache.Pos'Image & " next to " & 
Prev_Cache.Next_Pos.Item'Image);
-                           end if;
-                        end if;
-                     end;
-                  end if;
-
-                  loop
-                     --  Set Prev_Cache_Cur to last motion cache in nonterm 
chain
-                     exit when not Data.Navigate_Caches 
(Cache_Cur).Next_Pos.Set;
-
-                     Cache_Cur := Find (Iter, Data.Navigate_Caches 
(Cache_Cur).Next_Pos.Item);
-                     pragma Assert (Has_Element (Cache_Cur)); --  otherwise 
there's a bug in this subprogram.
-
-                  end loop;
-                  Prev_Cache_Cur := Cache_Cur;
-               end if;
-            end;
-         end if;
-      end loop;
-   end Motion_Action;
-
-   procedure Face_Apply_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-
-      use Face_Cache_Trees;
-
-      Iter       : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur  : Cursor;
-      Suffix_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find (Iter, Token.Char_Region.First, Direction => 
Ascending);
-               if Has_Element (Cache_Cur) then
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                  begin
-                     case Cache.Class is
-                     when Prefix =>
-                        Cache.Face := (True, Param.Prefix_Face);
-
-                        --  Check for suffix
-                        Suffix_Cur := Next (Iter, Cache_Cur);
-                        if Has_Element (Suffix_Cur) then
-                           declare
-                              Suf_Cache : Face_Cache_Type renames 
Data.Face_Caches (Suffix_Cur);
-                           begin
-                              if Suffix = Suf_Cache.Class and
-                                Inside (Suf_Cache.Char_Region.First, 
Token.Char_Region)
-                              then
-                                 Suf_Cache.Face := (True, Param.Suffix_Face);
-                              end if;
-                           end;
-                        end if;
-
-                     when Suffix =>
-                        Cache.Face := (True, Param.Suffix_Face);
-                     end case;
-                  end;
-               else
-                  Data.Face_Caches.Insert ((Token.Char_Region, Suffix, (True, 
Param.Suffix_Face)));
-               end if;
-            end;
-         end if;
-      end loop;
-   end Face_Apply_Action;
-
-   procedure Face_Apply_List_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find_In_Range (Iter, Ascending, 
Token.Char_Region.First, Token.Char_Region.Last);
-               loop
-                  exit when not Has_Element (Cache_Cur) or else
-                    Data.Face_Caches (Cache_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                  begin
-                     case Cache.Class is
-                     when Prefix =>
-                        Cache.Face := (True, Param.Prefix_Face);
-
-                     when Suffix =>
-                        Cache.Face := (True, Param.Suffix_Face);
-                     end case;
-                  end;
-                  Cache_Cur := Next (Iter, Cache_Cur);
-               end loop;
-            end;
-         end if;
-      end loop;
-   end Face_Apply_List_Action;
-
-   procedure Face_Mark_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Mark_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find (Iter, Token.Char_Region.First, Direction => 
Ascending);
-               if Has_Element (Cache_Cur) then
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                     Other_Cur : Cursor := Find_In_Range
-                       (Iter, Ascending, Cache.Char_Region.Last + 1, 
Token.Char_Region.Last);
-                     Temp : Cursor;
-                  begin
-                     loop
-                        exit when not Has_Element (Other_Cur) or else
-                          Data.Face_Caches (Other_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                        Temp := Other_Cur;
-                        Other_Cur := Next (Iter, Other_Cur);
-                        Delete (Data.Face_Caches, Temp);
-                     end loop;
-
-                     Cache.Class            := Param.Class;
-                     Cache.Char_Region.Last := Token.Char_Region.Last;
-                  end;
-               else
-                  Data.Face_Caches.Insert ((Token.Char_Region, Param.Class, 
(Set => False)));
-               end if;
-            end;
-         end if;
-      end loop;
-   end Face_Mark_Action;
-
-   procedure Face_Remove_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Remove_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-      Temp      : Cursor;
-   begin
-      for I of Params loop
-         if Tree.Byte_Region (Tokens (I)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-            begin
-               Cache_Cur := Find_In_Range (Iter, Ascending, 
Token.Char_Region.First, Token.Char_Region.Last);
-               loop
-                  exit when not Has_Element (Cache_Cur) or else
-                    Data.Face_Caches (Cache_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                  Temp := Cache_Cur;
-                  Cache_Cur := Next (Iter, Cache_Cur);
-                  Delete (Data.Face_Caches, Temp);
-               end loop;
-            end;
-         end if;
-      end loop;
-   end Face_Remove_Action;
-
-   function "+" (Item : in Integer) return Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector do
-         Result.Append (Item);
-      end return;
-   end "+";
-
-   function "&" (List : in Indent_Arg_Arrays.Vector; Item : in Integer) return 
Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector := List do
-         Result.Append (Item);
-      end return;
-   end "&";
-
-   function "&" (Left, Right : in Integer) return Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector do
-         Result.Append (Left);
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   function Image (Item : in Simple_Indent_Param) return String
-   is begin
-      return "(" & Simple_Indent_Param_Label'Image (Item.Label) &
-        (case Item.Label is
-         when None => "",
-         when Int => Integer'Image (Item.Int_Delta),
-         when Anchored_Label => Positive_Index_Type'Image 
(Item.Anchored_Index) & "," &
-              Integer'Image (Item.Anchored_Delta),
-         when Language => "<language_function>") & ")";
-   end Image;
-
-   function Image (Item : in Indent_Param) return String
-   is begin
-      return "(" & Indent_Param_Label'Image (Item.Label) & ", " &
-        (case Item.Label is
-         when Simple => Image (Item.Param),
-         when Hanging_Label =>
-            Image (Item.Hanging_Delta_1) & ", "  & Image 
(Item.Hanging_Delta_2) & ")");
-   end Image;
-
-   function Image (Item : in Indent_Pair) return String
-   is begin
-      return "(" & Image (Item.Code_Delta) &
-        (if Item.Comment_Present
-         then ", " & Image (Item.Comment_Delta)
-         else "") & ")";
-   end Image;
-
-   procedure Indent_Action_0
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Indent_Param_Array)
-   is begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line (";; indent_action_0: " & Tree.Image (Nonterm, 
Data.Descriptor.all));
-      end if;
-
-      for I in Tokens'Range loop
-         if (Tree.Is_Virtual_Terminal (Tokens (I)) or
-               Tree.Byte_Region (Tokens (I)) /= Null_Buffer_Region) and
-           I in Params'Range -- in some translated EBNF, not every token has 
an indent param
-         then
-            declare
-               use all type SAL.Base_Peek_Type;
-               Tree_Token        : constant Valid_Node_Index := Tokens (I);
-               Token             : Aug_Token_Const_Ref renames 
Get_Aug_Token_Const_1 (Tree, Tree_Token);
-               Pair              : Indent_Pair renames Params (I);
-               Code_Delta        : Delta_Type;
-               Comment_Param     : Indent_Param;
-               Comment_Param_Set : Boolean                                := 
False;
-               Comment_Delta     : Delta_Type;
-            begin
-               if Trace_Action > Detail then
-                  Ada.Text_IO.Put_Line
-                    (";; indent_action_0 a: " & Tree.Image (Tree_Token, 
Data.Descriptor.all) & ": " & Image (Pair));
-               end if;
-
-               if Token.First_Indent_Line /= Invalid_Line_Number then
-                  Code_Delta := Indent_Compute_Delta
-                    (Data, Tree, Tokens, Pair.Code_Delta, Tree_Token, 
Indenting_Comment => False);
-
-                  Indent_Token_1 (Data, Tree, Token, Code_Delta, 
Indenting_Comment => False);
-               end if;
-
-               if Token.First_Trailing_Comment_Line /= Invalid_Line_Number then
-                  if Pair.Comment_Present then
-                     Comment_Param     := Pair.Comment_Delta;
-                     Comment_Param_Set := True;
-
-                  elsif I < Tokens'Last then
-                     Comment_Param     := Params (I + 1).Code_Delta;
-                     Comment_Param_Set := True;
-
-                  end if;
-
-                  if Comment_Param_Set then
-                     Comment_Delta := Indent_Compute_Delta
-                       (Data, Tree, Tokens, Comment_Param, Tree_Token, 
Indenting_Comment => True);
-
-                     Indent_Token_1 (Data, Tree, Token, Comment_Delta, 
Indenting_Comment => True);
-                  end if;
-               end if;
-            end;
-         end if;
-      end loop;
-   end Indent_Action_0;
-
-   procedure Indent_Action_1
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      N       : in     Positive_Index_Type;
-      Params  : in     Indent_Param_Array)
-   is
-      use all type Syntax_Trees.Node_Label;
-   begin
-      for I in Tokens'First .. N loop
-         declare
-            Aug : Aug_Token_Const_Ref renames Wisi.Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-         begin
-            if Tree.Label (Tokens (I)) /= Virtual_Terminal and then Aug.First 
then
-               Indent_Action_0 (Data, Tree, Nonterm, Tokens, Params);
-               return;
-            end if;
-         end;
-      end loop;
-   end Indent_Action_1;
-
-   function Indent_Hanging_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree;
-      Tokens            : in     Valid_Node_Index_Array;
-      Tree_Indenting    : in     Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Delta_1           : in     Simple_Indent_Param;
-      Delta_2           : in     Simple_Indent_Param;
-      Option            : in     Boolean;
-      Accumulate        : in     Boolean)
-     return Delta_Type
-   is
-      Indenting_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tree_Indenting);
-   begin
-      if Indenting_Comment then
-         return Indent_Compute_Delta
-           (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment);
-      else
-         return
-           (Hanging,
-            Hanging_First_Line  => Indenting_Token.Line,
-            Hanging_Paren_State => Indenting_Token.Paren_State,
-            Hanging_Delta_1     => Indent_Compute_Delta
-              (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment).Simple_Delta,
-            Hanging_Delta_2     =>
-              (if (not Option) or
-                 Indenting_Token.Line = Indenting_Token.First_Indent_Line -- 
first token in tok is first on line
-               then Indent_Compute_Delta
-                 (Data, Tree, Tokens, (Simple, Delta_2), Tree_Indenting, 
Indenting_Comment).Simple_Delta
-               else Indent_Compute_Delta
-                 (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment).Simple_Delta),
-            Hanging_Accumulate => Accumulate);
-      end if;
-   end Indent_Hanging_1;
-
-   procedure Put_Language_Action
-     (Data    : in Parse_Data_Type;
-      Content : in String)
-   is
-      pragma Unreferenced (Data);
-   begin
-      Ada.Text_IO.Put_Line ("[" & Language_Action_Code & Content & "]");
-   end Put_Language_Action;
-
-   procedure Put (Data : in out Parse_Data_Type; Parser : in 
Parse.Base_Parser'Class)
-   is
-      use all type Ada.Containers.Count_Type;
-
-      Last_Term : constant Node_Index := Parser.Tree.Last_Terminal 
(Parser.Tree.Root);
-
-      function Get_Last_Char_Pos return Buffer_Pos
-      is begin
-
-         if Last_Term = Invalid_Node_Index then
-            --  All comments, or empty
-            if Data.Leading_Non_Grammar.Length > 0 then
-               return Data.Leading_Non_Grammar 
(Data.Leading_Non_Grammar.Last_Index).Char_Region.Last;
-            else
-               return Buffer_Pos'First;
-            end if;
-         else
-            declare
-               Aug : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Parser.Tree, Last_Term);
-            begin
-               if Aug.Non_Grammar.Length = 0 then
-                  return Aug.Char_Region.Last;
-               else
-                  return Aug.Non_Grammar 
(Aug.Non_Grammar.Last_Index).Char_Region.Last;
-               end if;
-            end;
-         end if;
-      end Get_Last_Char_Pos;
-
-      Last_Char_Pos : constant Buffer_Pos := Get_Last_Char_Pos;
-
-      function Get_Last_Line return Line_Number_Type
-      is begin
-         for I in Data.Line_Begin_Char_Pos.First_Index .. 
Data.Line_Begin_Char_Pos.Last_Index loop
-            if Data.Line_Begin_Char_Pos (I) = Invalid_Buffer_Pos then
-               raise SAL.Programmer_Error with "line_begin_pos" & 
Line_Number_Type'Image (I) & " invalid";
-            end if;
-            if Data.Line_Begin_Char_Pos (I) > Last_Char_Pos then
-               if I > Line_Number_Type'First then
-                  return I - 1;
-               else
-                  return I;
-               end if;
-            end if;
-         end loop;
-         return Data.Line_Begin_Char_Pos.Last_Index;
-      end Get_Last_Line;
-
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line
-           (";; last_char_pos:" & Buffer_Pos'Image (Last_Char_Pos + 1) &
-              " last_line:" & Line_Number_Type'Image (Get_Last_Line));
-      end if;
-
-      --  +1 to match Emacs region
-      Ada.Text_IO.Put_Line ('[' & End_Code & Buffer_Pos'Image (Last_Char_Pos + 
1) & ']');
-
-      case Data.Post_Parse_Action is
-      when Navigate =>
-         for Cache of Data.Navigate_Caches loop
-            Put (Cache);
-         end loop;
-         for Cache of Data.Name_Caches loop
-            Put (Cache);
-         end loop;
-
-      when Face =>
-         for Cache of Data.Face_Caches loop
-            Put (Cache);
-         end loop;
-
-      when Indent =>
-
-         Resolve_Anchors (Data);
-
-         if Trace_Action > Outline then
-            Ada.Text_IO.Put_Line (";; indent leading non_grammar");
-         end if;
-         for Token of Data.Leading_Non_Grammar loop
-            if Token.First then
-               Put (Token.Line, (Int, Data.Begin_Indent));
-            end if;
-         end loop;
-
-         --  It may be that not all lines in Data.Indents were parsed.
-         if Trace_Action > Outline then
-            Ada.Text_IO.Put_Line (";; indent grammar");
-         end if;
-         for I in Data.Indents.First_Index .. Get_Last_Line loop
-            Put (I, Data.Indents (I));
-         end loop;
-      end case;
-   end Put;
-
-   procedure Put (Lexer_Errors : in Lexer.Error_Lists.List)
-   is begin
-      for Item of Lexer_Errors loop
-         Ada.Text_IO.Put_Line
-           ('[' & Lexer_Error_Code & Buffer_Pos'Image (Item.Char_Pos) &
-              " ""lexer error" &
-              (if Item.Recover_Char (1) = ASCII.NUL
-               then """"
-               elsif Item.Recover_Char (1) = '"'
-               then """ ?\"""
-               else """ ?" & Item.Recover_Char (1)) &
-              "]");
-         if Item.Recover_Char (2) /= ASCII.NUL then
-            raise SAL.Programmer_Error with "lexer error with non-ascii or 
multiple repair char";
-         end if;
-      end loop;
-   end Put;
-
-   procedure Put
-     (Data         : in Parse_Data_Type;
-      Lexer_Errors : in Lexer.Error_Lists.List;
-      Parse_Errors : in Parse.LR.Parse_Error_Lists.List;
-      Tree         : in Syntax_Trees.Tree)
-   is
-      use all type SAL.Base_Peek_Type;
-      use Ada.Text_IO;
-      use Semantic_Checks;
-
-      function Safe_Pos (Node : in Valid_Node_Index) return Buffer_Pos
-      is
-         --  Return a reasonable position for the error at Node.
-         --
-         --  In a successful parse with error recovery, Node is a terminal with
-         --  an augmented token in Data.Terminals, so that is the first
-         --  choice.
-         --
-         --  If this is an error due to a bad recovery, Node may be a virtual
-         --  token, with no position information, so we try to get information
-         --  from its parent.
-         use Syntax_Trees;
-
-         N : Node_Index := Node;
-      begin
-         loop
-            if Tree.Label (N) /= Virtual_Terminal then
-               declare
-                  Ref : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, N);
-               begin
-                  if Ref.Char_Region /= Null_Buffer_Region then
-                     return Ref.Element.Char_Region.First;
-                  end if;
-
-               end;
-            end if;
-            N := Tree.Parent (N);
-            exit when N = Invalid_Node_Index;
-         end loop;
-         return Buffer_Pos'First;
-      end Safe_Pos;
-
-      function Safe_Pos (Token : in Recover_Token) return Buffer_Pos
-      is begin
-         if Token.Name /= Null_Buffer_Region then
-            return Token.Name.First;
-
-         elsif Token.Byte_Region = Null_Buffer_Region then
-            return Buffer_Pos'First;
-
-         else
-            return Token.Byte_Region.First;
-         end if;
-      end Safe_Pos;
-
-   begin
-      Put (Lexer_Errors);
-
-      for Item of Parse_Errors loop
-         case Item.Label is
-         when Parse.LR.Action =>
-            Put_Line
-              ('[' & Parser_Error_Code & Buffer_Pos'Image (Safe_Pos 
(Item.Error_Token)) &
-                 " ""syntax error: expecting " & Image (Item.Expecting, 
Data.Descriptor.all) &
-                 ", found '" & Image (Tree.ID (Item.Error_Token), 
Data.Descriptor.all) & "'""]");
-
-         when Parse.LR.Check =>
-            Put_Line
-              ('[' & Check_Error_Code & Integer'Image
-                 (Semantic_Checks.Check_Status_Label'Pos 
(Item.Check_Status.Label)) &
-                 (case Item.Check_Status.Label is
-                  when Ok => "",
-                  when Error =>
-                     Buffer_Pos'Image (Safe_Pos 
(Item.Check_Status.Begin_Name)) &
-                       Buffer_Pos'Image (Safe_Pos 
(Item.Check_Status.End_Name)) &
-                       " ""block name error""]"));
-
-         when Parse.LR.Message =>
-            Put_Line
-              ('[' & Parser_Error_Code & Buffer_Pos'Image (Buffer_Pos'First) &
-                 " """ & (-Item.Msg) & """]");
-         end case;
-
-         if Item.Recover.Stack.Depth > 0 then
-            Put (Item.Recover, Data, Tree);
-         end if;
-      end loop;
-   end Put;
-
-   procedure Put_Error (Data : in Parse_Data_Type; Line_Number : in 
Line_Number_Type; Message : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("(error """ & Error_Message (Data.Lexer.File_Name, 
Line_Number, 0, Message) & """)");
-   end Put_Error;
-
-   ----------
-   --  Spec visible private subprograms, alphabetical
-
-   function Image (Item : in Simple_Delta_Type) return String
-   is begin
-      return "(" & Simple_Delta_Labels'Image (Item.Label) &
-        (case Item.Label is
-         when None => "",
-         when Int => Integer'Image (Item.Int_Delta),
-         when Anchored => Integer'Image (Item.Anchored_ID) & Integer'Image 
(Item.Anchored_Delta) & " " &
-              Boolean'Image (Item.Anchored_Accumulate))
-        & ")";
-   end Image;
-
-   function Image (Item : in Delta_Type) return String
-   is begin
-      return "(" & Delta_Labels'Image (Item.Label) &
-        (case Item.Label is
-         when Simple => " " & Image (Item.Simple_Delta),
-         when Hanging => Line_Number_Type'Image (Item.Hanging_First_Line) & 
Integer'Image (Item.Hanging_Paren_State) &
-              " " & Image (Item.Hanging_Delta_1) & " " & Image 
(Item.Hanging_Delta_2) & " " &
-              Boolean'Image (Item.Hanging_Accumulate)) & ")";
-   end Image;
-
-   function Current_Indent_Offset
-     (Data         : in Parse_Data_Type;
-      Anchor_Token : in Augmented_Token'Class;
-      Offset       : in Integer)
-     return Integer
-   is begin
-      return Offset + Integer (Anchor_Token.Char_Region.First - 
Data.Line_Begin_Char_Pos (Anchor_Token.Line));
-   end Current_Indent_Offset;
-
-   function First_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return Line_Number_Type
-   is begin
-      return
-        (if Indenting_Comment then
-           (if Token.First_Trailing_Comment_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.First_Trailing_Comment_Line)
-         else
-           (if Token.First_Indent_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.First_Indent_Line));
-   end First_Line;
-
-   function Get_Aug_Token_Const_1
-     (Tree       : in Syntax_Trees.Tree'Class;
-      Tree_Index : in Valid_Node_Index)
-     return Aug_Token_Const_Ref
-   is begin
-      return To_Aug_Token_Const_Ref (Tree.Augmented (Tree_Index));
-   end Get_Aug_Token_Const_1;
-
-   function Get_Aug_Token_Const
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Const_Ref
-   is begin
-      return Get_Aug_Token_Const_1 (Tree, Data.Terminals.all 
(Token).Tree_Index);
-   end Get_Aug_Token_Const;
-
-   function Get_Aug_Token_Var
-     (Tree       : in Syntax_Trees.Tree'Class;
-      Tree_Index : in Valid_Node_Index)
-     return Aug_Token_Var_Ref
-   is begin
-      return To_Aug_Token_Var_Ref (Tree.Augmented (Tree_Index));
-   end Get_Aug_Token_Var;
-
-   function Get_Aug_Token_Var
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Var_Ref
-   is begin
-      return Get_Aug_Token_Var (Tree, Data.Terminals.all (Token).Tree_Index);
-   end Get_Aug_Token_Var;
-
-   function Get_Text
-     (Data       : in Parse_Data_Type;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return String
-   is
-      use all type Syntax_Trees.Node_Label;
-   begin
-      case Tree.Label (Tree_Index) is
-      when Shared_Terminal | Nonterm =>
-         return Data.Lexer.Buffer_Text (Tree.Byte_Region (Tree_Index));
-
-      when Virtual_Terminal | Virtual_Identifier =>
-         raise SAL.Programmer_Error;
-
-      end case;
-   end Get_Text;
-
-   function Elisp_Escape_Quotes (Item : in String) return String
-   is
-      Result : String (Item'First .. Item'First + Item'Length * 2);
-      Last   : Integer := Item'First - 1;
-   begin
-      for I in Item'Range loop
-         if Item (I) = '"' then
-            Last := Last + 1;
-            Result (Last) := '\';
-         end if;
-         Last := Last + 1;
-         Result (Last) := Item (I);
-      end loop;
-      return Result (Result'First .. Last);
-   end Elisp_Escape_Quotes;
-
-   overriding
-   function Image
-     (Item       : in Augmented_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is
-      ID_Image : constant String := Image (Item.ID, Descriptor);
-   begin
-      if Item.Line /= Invalid_Line_Number then
-         return "(" & ID_Image &
-           Line_Number_Type'Image (Item.Line) & ":" & Trimmed_Image (Integer 
(Item.Column)) & ")";
-
-      elsif Item.Char_Region = Null_Buffer_Region then
-         if Item.Byte_Region = Null_Buffer_Region then
-            return "(" & ID_Image & ")";
-         else
-            return "(" & ID_Image & ", " & Image (Item.Byte_Region) & ")";
-         end if;
-      else
-         return "(" & ID_Image & ", " & Image (Item.Char_Region) & ")";
-      end if;
-   end Image;
-
-   function Indent_Anchored_2
-     (Data        : in out Parse_Data_Type;
-      Anchor_Line : in     Line_Number_Type;
-      Last_Line   : in     Line_Number_Type;
-      Offset      : in     Integer;
-      Accumulate  : in     Boolean)
-     return Delta_Type
-   is
-      --  Return an anchored delta
-      use Anchor_ID_Vectors;
-      --  We can't use a Reference here, because the Element in reference
-      --  types is constrained (as are all allocated objects of access
-      --  types; AARM 4.8 (6/3)), and we may need to change the Label.
-      Indent    : Indent_Type      := Data.Indents (Anchor_Line);
-      Anchor_ID : constant Integer := 1 + Max_Anchor_ID (Data, Anchor_Line, 
Last_Line);
-   begin
-      Data.Max_Anchor_ID := Integer'Max (Data.Max_Anchor_ID, Anchor_ID);
-
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Anchor_Nil, To_Vector (Anchor_ID, 1));
-
-         if Trace_Action > Extra then
-            Ada.Text_IO.Put_Line
-              (";; indent_anchored: " & Line_Number_Type'Image (Anchor_Line) & 
" => " & Image (Indent));
-         end if;
-
-      when Int =>
-         Indent := (Anchor_Int, To_Vector (Anchor_ID, 1), Indent.Int_Indent);
-
-         if Trace_Action > Extra then
-            Ada.Text_IO.Put_Line
-              (";; indent_anchored: " & Line_Number_Type'Image (Anchor_Line) & 
" => " & Image (Indent));
-         end if;
-
-      when Anchor_Nil =>
-         Indent.Anchor_Nil_IDs := Anchor_ID & Indent.Anchor_Nil_IDs;
-
-      when Anchor_Int =>
-         Indent.Anchor_Int_IDs := Anchor_ID & Indent.Anchor_Int_IDs;
-
-      when Anchored =>
-         Indent := (Anchor_Anchored, To_Vector (Anchor_ID, 1), 
Indent.Anchored_ID, Indent.Anchored_Delta);
-
-      when Anchor_Anchored =>
-         Indent.Anchor_Anchored_IDs := Anchor_ID & Indent.Anchor_Anchored_IDs;
-      end case;
-
-      Data.Indents.Replace_Element (Anchor_Line, Indent);
-
-      return (Simple, (Anchored, Anchor_ID, Offset, Accumulate));
-   end Indent_Anchored_2;
-
-   function Indent_Compute_Delta
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     Syntax_Trees.Tree;
-      Tokens            : in     Valid_Node_Index_Array;
-      Param             : in     Indent_Param;
-      Tree_Indenting    : in     Valid_Node_Index;
-      Indenting_Comment : in     Boolean)
-     return Delta_Type
-   is
-      Indenting_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tree_Indenting);
-   begin
-      --  Evaluate wisi-anchored*, wisi-hanging*.
-      case Param.Label is
-      when Simple =>
-         case Param.Param.Label is
-         when None =>
-            return (Simple, (Label => None));
-
-         when Int =>
-            return (Simple, (Int, Param.Param.Int_Delta));
-
-         when Anchored_Label =>
-            declare
-               Anchor_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1
-                 (Tree, Tokens (Param.Param.Anchored_Index));
-            begin
-               case Anchored_Label'(Param.Param.Label) is
-               when Anchored_0 =>
-                  --  [2] wisi-anchored
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Current_Indent_Offset (Data, Anchor_Token, 
Param.Param.Anchored_Delta),
-                     Accumulate  => True);
-
-               when Anchored_1 =>
-                  --  [2] wisi-anchored%
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Paren_In_Anchor_Line (Data, Tree, 
Anchor_Token, Param.Param.Anchored_Delta),
-                     Accumulate  => True);
-
-               when Anchored_2 =>
-                  --  [2] wisi-anchored%-
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Paren_In_Anchor_Line (Data, Tree, 
Anchor_Token, Param.Param.Anchored_Delta),
-                     Accumulate  => False);
-
-               when Anchored_3 =>
-                  --  [2] wisi-anchored*
-                  if Indenting_Token.First then
-                     return Indent_Anchored_2
-                       (Data,
-                        Anchor_Line => Anchor_Token.Line,
-                        Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                        Offset      => Current_Indent_Offset (Data, 
Anchor_Token, Param.Param.Anchored_Delta),
-                        Accumulate  => True);
-
-                  else
-                     return Null_Delta;
-                  end if;
-
-               when Anchored_4 =>
-                  --  [2] wisi-anchored*-
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Current_Indent_Offset (Data, Anchor_Token, 
Param.Param.Anchored_Delta),
-                     Accumulate  => False);
-
-               end case;
-            end;
-
-         when Language =>
-            return Param.Param.Function_Ptr
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Param.Args);
-         end case;
-
-      when Hanging_Label =>
-         case Hanging_Label'(Param.Label) is
-         when Hanging_0 => -- wisi-hanging
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => False, Accumulate => True);
-         when Hanging_1 => -- wisi-hanging-
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => False, Accumulate => False);
-         when Hanging_2 => -- wisi-hanging%
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => True, Accumulate => True);
-         when Hanging_3 => -- wisi-hanging%-
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => True, Accumulate => False);
-         end case;
-      end case;
-   end Indent_Compute_Delta;
-
-   procedure Indent_Token_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree;
-      Indenting_Token   : in     Augmented_Token'Class;
-      Delta_Indent      : in     Delta_Type;
-      Indenting_Comment : in     Boolean)
-   is
-      --  Aplly Delta_Indent to Indenting_Token
-      First_Line : constant Line_Number_Type := Indenting_Token.First_Line 
(Indenting_Comment);
-      Last_Line  : constant Line_Number_Type := Indenting_Token.Last_Line 
(Indenting_Comment);
-   begin
-      if Trace_Action > Detail then
-         Ada.Text_IO.Put_Line
-           (";; indent_token_1: " & Indenting_Token.Image 
(Data.Descriptor.all) & " " & Image (Delta_Indent) &
-              Line_Number_Type'Image (First_Line) & " .." & 
Line_Number_Type'Image (Last_Line) &
-              (if Indenting_Comment then " comment" else ""));
-      end if;
-
-      for Line in First_Line .. Last_Line loop
-         if Data.Indent_Comment_Col_0 then
-            declare
-               use all type Ada.Text_IO.Count;
-
-               function Containing_Token return Base_Token_Index
-               is
-                  --  Return token index of terminal containing non_grammer on 
Line;
-                  --  Invalid_Token_Index if none.
-                  I : Line_Number_Type := Line;
-                  J : Base_Token_Index;
-               begin
-                  if Line < Data.Line_Begin_Token.First_Index then
-                     --  Line is before first grammar token; 
Leading_Non_Grammar checked
-                     --  below.
-                     return Invalid_Token_Index;
-                  end if;
-
-                  loop
-                     exit when Data.Line_Begin_Token.all (I) /= 
Base_Token_Arrays.No_Index;
-                     --  No_Index means Line is in a multi-line token, which 
could be a block comment.
-                     I := I - 1;
-                  end loop;
-
-                  J := Data.Line_Begin_Token.all (I);
-                  declare
-                     Aug : Augmented_Token renames Get_Aug_Token_Const (Data, 
Tree, J);
-                  begin
-                     if Line in Aug.First_Trailing_Comment_Line .. 
Aug.Last_Trailing_Comment_Line then
-                        return J;
-                     else
-                        return Invalid_Token_Index;
-                     end if;
-                  end;
-               end Containing_Token;
-
-               Indent     : Boolean                   := True;
-               Containing : constant Base_Token_Index := Containing_Token;
-            begin
-               if Line < Data.Line_Begin_Token.First_Index then
-                  --  Line is before the first grammar token. We may be doing 
a partial
-                  --  parse where the initial indent is non-zero, so we still 
have to
-                  --  check for column 0.
-                  for Tok of Data.Leading_Non_Grammar loop
-                     if Tok.Line = Line and then
-                       Tok.ID in Data.First_Comment_ID .. Data.Last_Comment_ID 
and then
-                       Tok.Column = 0
-                     then
-                        Indent := False;
-                        exit;
-                     end if;
-                  end loop;
-
-               elsif Containing /= Invalid_Token_Index then
-                  for Tok of Get_Aug_Token_Const (Data, Tree, 
Containing).Non_Grammar loop
-                     if Tok.Line = Line and then
-                       Tok.ID in Data.First_Comment_ID .. Data.Last_Comment_ID 
and then
-                       Tok.Column = 0
-                     then
-                        Indent := False;
-                        exit;
-                     end if;
-                  end loop;
-               end if;
-
-               if Indent then
-                  Indent_Line (Data, Line, Delta_Indent);
-               else
-                  Indent_Line (Data, Line, (Simple, (Int, 0)));
-               end if;
-            end;
-         else
-            Indent_Line (Data, Line, Delta_Indent);
-         end if;
-      end loop;
-   end Indent_Token_1;
-
-   function Last_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return Line_Number_Type
-   is begin
-      return
-        (if Indenting_Comment then
-           (if Token.Last_Trailing_Comment_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.Last_Trailing_Comment_Line)
-         else
-           (if Token.Last_Indent_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.Last_Indent_Line));
-   end Last_Line;
-
-end Wisi;
diff --git a/packages/wisi/wisi.ads b/packages/wisi/wisi.ads
deleted file mode 100644
index e707ab8..0000000
--- a/packages/wisi/wisi.ads
+++ /dev/null
@@ -1,769 +0,0 @@
---  Abstract :
---
---  Ada implementation of wisi parser actions.
---
---  References
---
---  [1] wisi-parse-common.el - defines common stuff.
---
---  [2] wisi.texi - defines parse action functions.
---
---  [3] wisi-process-parse.el - defines elisp/process API
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Containers.Vectors;
-with SAL.Gen_Unbounded_Definite_Red_Black_Trees;
-with SAL.Gen_Unbounded_Definite_Vectors;
-with WisiToken.Parse.LR;
-with WisiToken.Lexer;
-with WisiToken.Syntax_Trees;
-package Wisi is
-   use all type WisiToken.Base_Buffer_Pos;
-
-   function Image (Aug : in WisiToken.Base_Token_Class_Access; Descriptor : in 
WisiToken.Descriptor) return String;
-   function Image (Action : in WisiToken.Syntax_Trees.Semantic_Action) return 
String;
-   --  For Syntax_Trees.Print_Tree, Parser.Execute_Action
-
-   type Post_Parse_Action_Type is (Navigate, Face, Indent);
-
-   type Parse_Data_Type
-     (Terminals        : not null access constant 
WisiToken.Base_Token_Arrays.Vector;
-      Line_Begin_Token : not null access constant 
WisiToken.Line_Begin_Token_Vectors.Vector)
-     is new WisiToken.Syntax_Trees.User_Data_Type with private;
-
-   procedure Initialize
-     (Data              : in out Parse_Data_Type;
-      Lexer             : in     WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : in     WisiToken.Base_Token_Array_Access;
-      Post_Parse_Action : in     Post_Parse_Action_Type;
-      Begin_Line        : in     WisiToken.Line_Number_Type;
-      End_Line          : in     WisiToken.Line_Number_Type;
-      Begin_Indent      : in     Integer;
-      Params            : in     String);
-   --  Begin_Line, Begin_Indent, Line_Count only used for Indent. Params
-   --  contains language-specific indent parameter values.
-
-   overriding procedure Reset (Data : in out Parse_Data_Type);
-   --  Reset for a new parse, with data from previous Initialize.
-
-   function Source_File_Name (Data : in Parse_Data_Type) return String;
-   function Post_Parse_Action (Data : in Parse_Data_Type) return 
Post_Parse_Action_Type;
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          Parse_Data_Type;
-      Tree  : in out          WisiToken.Syntax_Trees.Tree'Class;
-      Token : in              WisiToken.Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class);
-
-   overriding
-   procedure Insert_Token
-     (Data  : in out Parse_Data_Type;
-      Tree  : in out WisiToken.Syntax_Trees.Tree'Class;
-      Token : in     WisiToken.Valid_Node_Index);
-
-   overriding
-   procedure Delete_Token
-     (Data                : in out Parse_Data_Type;
-      Tree                : in out WisiToken.Syntax_Trees.Tree'Class;
-      Deleted_Token_Index : in     WisiToken.Token_Index);
-
-   overriding
-   procedure Reduce
-     (Data    : in out Parse_Data_Type;
-      Tree    : in out WisiToken.Syntax_Trees.Tree'Class;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array);
-
-   type Navigate_Class_Type is (Motion, Statement_End, Statement_Override, 
Statement_Start, Misc);
-   --  Matches [1] wisi-class-list.
-
-   type Index_Navigate_Class is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      Class : Navigate_Class_Type;
-   end record;
-
-   type Statement_Param_Array is array (Natural range <>) of 
Index_Navigate_Class;
-
-   procedure Statement_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Statement_Param_Array);
-   --  Implements [2] wisi-statement-action.
-
-   procedure Name_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Name    : in     WisiToken.Positive_Index_Type);
-   --  Implements [2] wisi-name-action.
-
-   type Index_ID is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      ID    : WisiToken.Token_ID;
-      --  If ID is not Invalid_Token_ID, it is the first token in the
-      --  nonterm that Index points to that should have a navigate cache for
-      --  Motion_Action to link to; an error is reported by Motion_Action if
-      --  it does not.
-      --
-      --  If ID is Invalid_Token_ID, and the token at Index is a
-      --  nonterminal, the first token in that nonterminal must have a
-      --  navigate cache; an error is reported by Motion_Action if not.
-   end record;
-
-   package Index_ID_Vectors is new Ada.Containers.Vectors 
(Ada.Containers.Count_Type, Index_ID);
-
-   subtype Motion_Param_Array is Index_ID_Vectors.Vector;
-
-   Invalid_Token_ID : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-   --  So Create_Parser can just use "Invalid_Token_ID".
-
-   procedure Motion_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Motion_Param_Array);
-   --  Implements [2] wisi-motion-action.
-
-   type Index_Faces is record
-      Index       : WisiToken.Positive_Index_Type; -- into Tokens
-      Prefix_Face : Integer; -- into grammar.Face_List
-      Suffix_Face : Integer; -- into grammar.Face_List
-   end record;
-
-   type Face_Apply_Param_Array is array (Natural range <>) of Index_Faces;
-
-   procedure Face_Apply_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array);
-   --  Implements [2] wisi-face-apply-action.
-
-   procedure Face_Apply_List_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array);
-   --  Implements [2] wisi-face-apply-list-action.
-
-   type Face_Class_Type is (Prefix, Suffix);
-
-   type Index_Face_Class is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      Class : Face_Class_Type;
-   end record;
-
-   type Face_Mark_Param_Array is array (Natural range <>) of Index_Face_Class;
-
-   procedure Face_Mark_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Mark_Param_Array);
-   --  Implements [2] wisi-face-mark-action.
-
-   type Face_Remove_Param_Array is array (Natural range <>) of 
WisiToken.Positive_Index_Type;
-
-   procedure Face_Remove_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Remove_Param_Array);
-   --  Implements [2] wisi-face-remove-action.
-
-   ----------
-   --  Indent
-   --
-   --  Indent functions are represented by the Indent_Param type.
-
-   type Simple_Indent_Param_Label is -- not hanging
-     (None,
-      Int,
-      Anchored_0, -- [2] wisi-anchored
-      Anchored_1, -- [2] wisi-anchored%
-      Anchored_2, -- [2] wisi-anchored%-
-      Anchored_3, -- [2] wisi-anchored*
-      Anchored_4, -- [2] wisi-anchored*-
-      Language    -- [2] language-specific function
-     );
-   subtype Anchored_Label is Simple_Indent_Param_Label range Anchored_0 .. 
Anchored_4;
-
-   --  Arguments to language-specific functions are integers; one of
-   --  delta, Token_Number, or Token_ID - the syntax does not distinguish
-   --  among these three types.
-
-   package Indent_Arg_Arrays is new Ada.Containers.Vectors 
(WisiToken.Positive_Index_Type, Integer);
-
-   function "+" (Item : in Integer) return Indent_Arg_Arrays.Vector;
-   function "&" (List : in Indent_Arg_Arrays.Vector; Item : in Integer) return 
Indent_Arg_Arrays.Vector;
-   function "&" (Left, Right : in Integer) return Indent_Arg_Arrays.Vector;
-
-   type Delta_Type (<>) is private;
-
-   type Language_Indent_Function is access function
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tree_Tokens       : in     WisiToken.Valid_Node_Index_Array;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Args              : in     Indent_Arg_Arrays.Vector)
-     return Delta_Type;
-
-   Null_Args : Indent_Arg_Arrays.Vector renames Indent_Arg_Arrays.Empty_Vector;
-
-   type Simple_Indent_Param (Label : Simple_Indent_Param_Label := None) is
-   record
-      case Label is
-      when None =>
-         null;
-
-      when Int =>
-         Int_Delta : Integer;
-
-      when Anchored_Label =>
-         Anchored_Index : WisiToken.Positive_Index_Type;
-         Anchored_Delta : Integer;
-
-      when Language =>
-         Function_Ptr : Language_Indent_Function;
-         Args         : Indent_Arg_Arrays.Vector;
-      end case;
-   end record;
-
-   function Image (Item : in Simple_Indent_Param) return String;
-
-   type Indent_Param_Label is
-     (Simple,
-      Hanging_0, -- [2] wisi-hanging
-      Hanging_1, -- [2] wisi-hanging-
-      Hanging_2, -- [2] wisi-hanging%
-      Hanging_3  -- [2] wisi-hanging%-
-     );
-   subtype Hanging_Label is Indent_Param_Label range Hanging_0 .. Hanging_3;
-
-   type Indent_Param (Label : Indent_Param_Label := Simple) is
-   record
-      case Label is
-      when Simple =>
-         Param : Simple_Indent_Param;
-
-      when Hanging_Label =>
-         Hanging_Delta_1 : Simple_Indent_Param;
-         Hanging_Delta_2 : Simple_Indent_Param;
-
-      end case;
-   end record;
-
-   function Image (Item : in Indent_Param) return String;
-
-   type Indent_Pair (Comment_Present : Boolean := False) is
-   record
-      Code_Delta : Indent_Param;
-      case Comment_Present is
-      when True =>
-         Comment_Delta : Indent_Param;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   function Image (Item : in Indent_Pair) return String;
-
-   type Indent_Param_Array is array (WisiToken.Positive_Index_Type range <>) 
of Indent_Pair;
-
-   procedure Indent_Action_0
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Indent_Param_Array);
-   --  Implements [2] wisi-indent-action.
-
-   procedure Indent_Action_1
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      N       : in     WisiToken.Positive_Index_Type;
-      Params  : in     Indent_Param_Array);
-   --  Implements [2] wisi-indent-action*.
-
-   function Indent_Hanging_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tokens            : in     WisiToken.Valid_Node_Index_Array;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Delta_1           : in     Simple_Indent_Param;
-      Delta_2           : in     Simple_Indent_Param;
-      Option            : in     Boolean;
-      Accumulate        : in     Boolean)
-     return Delta_Type;
-   --  Implements [2] wisi-hanging, wisi-hanging%, wisi-hanging%-.
-   --
-   --  Language specific child packages may override this to implement
-   --  language-specific cases.
-
-   ----------
-   --  Other
-
-   procedure Refactor
-     (Data       : in out Parse_Data_Type;
-      Tree       : in out WisiToken.Syntax_Trees.Tree;
-      Action     : in     Positive;
-      Edit_Begin : in     WisiToken.Buffer_Pos) is null;
-
-   type Arg_Index_Array is array (Positive range <>) of 
WisiToken.Positive_Index_Type;
-
-   procedure Put_Language_Action
-     (Data    : in Parse_Data_Type;
-      Content : in String);
-   --  Send a Language_Action message to Emacs.
-
-   procedure Put (Data : in out Parse_Data_Type; Parser : in 
WisiToken.Parse.Base_Parser'Class);
-   --  Perform additional post-parse actions, then put result to
-   --  Ada.Text_IO.Current_Output, as encoded responses as defined in [3]
-   --  wisi-process-parse--execute.
-
-   procedure Put (Lexer_Errors : in WisiToken.Lexer.Error_Lists.List);
-   procedure Put
-     (Data         : in Parse_Data_Type;
-      Lexer_Errors : in WisiToken.Lexer.Error_Lists.List;
-      Parse_Errors : in WisiToken.Parse.LR.Parse_Error_Lists.List;
-      Tree         : in WisiToken.Syntax_Trees.Tree);
-   --  Put Lexer_Errors and Parse_Errors to Ada.Text_IO.Current_Output,
-   --  as encoded error responses as defined in [3]
-   --  wisi-process-parse--execute.
-
-   procedure Put_Error (Data : in Parse_Data_Type; Line_Number : in 
WisiToken.Line_Number_Type; Message : in String);
-   --  Put an error elisp form to Ada.Text_IO.Standard_Output.
-
-private
-
-   type Non_Grammar_Token is new WisiToken.Base_Token with record
-      First : Boolean := False;
-   end record;
-
-   package Non_Grammar_Token_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Token_Index, Non_Grammar_Token, Default_Element => (others => 
<>));
-
-   type Augmented_Token is new WisiToken.Base_Token with record
-      --  Most fields are set by Lexer_To_Augmented at parse time; others
-      --  are set by Reduce for nonterminals.
-
-      Deleted : Boolean := False;
-      --  Set True by Parse_Data_Type.Delete_Token; Non_Grammar tokens are
-      --  moved to the previous non-deleted token.
-
-      --  The following fields are only needed for indent.
-
-      First : Boolean := False;
-      --  For a terminal, True if the token is first on a line.
-      --
-      --  For a nonterminal, True if some contained token's First is True.
-
-      Paren_State : Integer := 0;
-      --  Parenthesis nesting count, before token.
-
-      First_Terminals_Index : WisiToken.Base_Token_Index := 
WisiToken.Invalid_Token_Index;
-      --  For virtual tokens, Invalid_Token_Index
-      --
-      --  For terminal tokens, index of this token in Parser.Terminals.
-      --
-      --  For nonterminal tokens, index of first contained token in
-      --  Parser.Terminals.
-
-      Last_Terminals_Index : WisiToken.Base_Token_Index := 
WisiToken.Base_Token_Arrays.No_Index;
-      --  For non-virtual nonterminal tokens, index of last contained
-      --  token in Parser.Terminals.
-      --
-      --  For all others, same as First_Terminals_Index.
-
-      First_Indent_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      Last_Indent_Line  : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      --  Lines that need indenting; first token on these lines is contained
-      --  in this token. If First is False, these are Invalid_Line_Number.
-      --
-      --  First_, Last_Indent_Line include blank and comment lines between
-      --  grammar tokens, but exclude trailing blanks and comments after the
-      --  last token, so they can be indented differently.
-
-      First_Trailing_Comment_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      Last_Trailing_Comment_Line  : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      --  Trailing comment or blank lines (after the last contained grammar
-      --  token) that need indenting. Excludes comments following code on a
-      --  line. If there are no such lines, these are Invalid_Line_Number.
-
-      Non_Grammar : Non_Grammar_Token_Arrays.Vector;
-      --  For terminals, non-grammar tokens immediately following. For
-      --  nonterminals, empty.
-
-      Inserted_Before : WisiToken.Valid_Node_Index_Arrays.Vector;
-      --  Tokens inserted before this token by error recovery.
-
-   end record;
-   type Augmented_Token_Access is access all Augmented_Token;
-   type Augmented_Token_Access_Constant is access constant Augmented_Token;
-
-   type Aug_Token_Const_Ref (Element : not null access constant 
Augmented_Token) is null record with
-     Implicit_Dereference => Element;
-
-   function To_Aug_Token_Const_Ref (Item : in 
WisiToken.Base_Token_Class_Access) return Aug_Token_Const_Ref
-     is (Element => Augmented_Token_Access_Constant (Item));
-
-   type Aug_Token_Var_Ref (Element : not null access Augmented_Token) is null 
record with
-     Implicit_Dereference => Element;
-
-   function To_Aug_Token_Var_Ref (Item : in WisiToken.Base_Token_Class_Access) 
return Aug_Token_Var_Ref
-     is (Element => Augmented_Token_Access (Item));
-
-   overriding
-   function Image
-     (Item       : in Augmented_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-   --  Return a string for debug/test messages
-
-   function First_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return WisiToken.Line_Number_Type;
-   function Last_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return WisiToken.Line_Number_Type;
-   --  Return first and last line in Token's region.
-
-   package Line_Paren_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, Integer, Default_Element => Integer'Last);
-   package Line_Begin_Pos_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, WisiToken.Buffer_Pos, Default_Element => 
WisiToken.Invalid_Buffer_Pos);
-
-   type Nil_Buffer_Pos (Set : Boolean := False) is record
-      case Set is
-      when True =>
-         Item : WisiToken.Buffer_Pos;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   Nil : constant Nil_Buffer_Pos := (Set => False);
-
-   type Navigate_Cache_Type is record
-      Pos            : WisiToken.Buffer_Pos; -- implicit in [1] wisi-cache
-      Statement_ID   : WisiToken.Token_ID;   -- [1] wisi-cache-nonterm
-      ID             : WisiToken.Token_ID;   -- [1] wisi-cache-token
-      Length         : Natural;              -- [1] wisi-cache-last
-      Class          : Navigate_Class_Type;  -- [1] wisi-cache-class
-      Containing_Pos : Nil_Buffer_Pos;       -- [1] wisi-cache-containing
-      Prev_Pos       : Nil_Buffer_Pos;       -- [1] wisi-cache-prev
-      Next_Pos       : Nil_Buffer_Pos;       -- [1] wisi-cache-next
-      End_Pos        : Nil_Buffer_Pos;       -- [1] wisi-cache-end
-   end record;
-
-   function Key (Cache : in Navigate_Cache_Type) return WisiToken.Buffer_Pos 
is (Cache.Pos);
-
-   function Key_Compare (Left, Right : in WisiToken.Buffer_Pos) return 
SAL.Compare_Result is
-     (if Left > Right then SAL.Greater
-      elsif Left = Right then SAL.Equal
-      else SAL.Less);
-
-   package Navigate_Cache_Trees is new 
SAL.Gen_Unbounded_Definite_Red_Black_Trees
-     (Navigate_Cache_Type, WisiToken.Buffer_Pos);
-
-   function Key (Cache : in WisiToken.Buffer_Region) return 
WisiToken.Buffer_Pos is (Cache.First);
-
-   package Name_Cache_Trees is new SAL.Gen_Unbounded_Definite_Red_Black_Trees
-     (WisiToken.Buffer_Region, WisiToken.Buffer_Pos);
-
-   type Nil_Integer (Set : Boolean := False) is record
-      case Set is
-      when True =>
-         Item : Integer;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   type Face_Cache_Type is record
-      Char_Region : WisiToken.Buffer_Region;
-      Class       : Face_Class_Type;
-      Face        : Nil_Integer; -- not set, or index into 
*-process-faces-names
-   end record;
-
-   function Key (Cache : in Face_Cache_Type) return WisiToken.Buffer_Pos is 
(Cache.Char_Region.First);
-
-   package Face_Cache_Trees is new SAL.Gen_Unbounded_Definite_Red_Black_Trees 
(Face_Cache_Type, WisiToken.Buffer_Pos);
-
-   type Indent_Label is (Not_Set, Int, Anchor_Nil, Anchor_Int, Anchored, 
Anchor_Anchored);
-
-   package Anchor_ID_Vectors is new Ada.Containers.Vectors (Natural, Positive);
-
-   type Indent_Type (Label : Indent_Label := Not_Set) is record
-      --  Indent values may be negative while indents are being computed.
-      case Label is
-      when Not_Set =>
-         null;
-
-      when Int =>
-         Int_Indent : Integer;
-
-      when Anchor_Nil =>
-         Anchor_Nil_IDs : Anchor_ID_Vectors.Vector; --  Largest ID first.
-
-      when Anchor_Int =>
-         Anchor_Int_IDs    : Anchor_ID_Vectors.Vector; --  Largest ID first.
-         Anchor_Int_Indent : Integer; --  Indent for this token.
-
-      when Anchored =>
-         Anchored_ID    : Positive;
-         Anchored_Delta : Integer; -- added to Anchor_Indent of Anchor_ID
-
-      when Anchor_Anchored =>
-         Anchor_Anchored_IDs   : Anchor_ID_Vectors.Vector;
-         Anchor_Anchored_ID    : Natural;
-         Anchor_Anchored_Delta : Integer;
-      end case;
-   end record;
-   First_Anchor_ID : constant Positive := Positive'First;
-
-   package Indent_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, Indent_Type, Default_Element => (others => 
<>));
-   package Navigate_Cursor_Lists is new Ada.Containers.Doubly_Linked_Lists
-     (Navigate_Cache_Trees.Cursor, Navigate_Cache_Trees."=");
-
-   type Parse_Data_Type
-     (Terminals        : not null access constant 
WisiToken.Base_Token_Arrays.Vector;
-      Line_Begin_Token : not null access constant 
WisiToken.Line_Begin_Token_Vectors.Vector)
-     is new WisiToken.Syntax_Trees.User_Data_Type with
-   record
-      --  Aux token info
-      First_Comment_ID : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Last_Comment_ID  : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Left_Paren_ID    : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Right_Paren_ID   : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-
-      Embedded_Quote_Escape_Doubled : Boolean := False;
-
-      --  Data from parsing
-
-      --  All Augmented_Tokens are stored in the syntax tree.
-      Last_Terminal_Node : WisiToken.Node_Index := 
WisiToken.Invalid_Node_Index;
-
-      Leading_Non_Grammar : Non_Grammar_Token_Arrays.Vector;
-      --  non-grammar tokens before first grammar token.
-
-      Line_Begin_Char_Pos : Line_Begin_Pos_Vectors.Vector;
-      --  Character position at the start of the first token on each line.
-      --  Cached from Line_Begin_Token to simplify indent computations.
-
-      Line_Paren_State : Line_Paren_Vectors.Vector;
-      --  Parenthesis nesting state at the start of each line; used by
-      --  Indent. Set by Lexer_To_Augmented on New_Line_ID, updated by
-      --  Insert_Token, Delete_Token.
-
-      Current_Paren_State : Integer;
-      --  Current parenthesis nesting state; used by Indent. Set by
-      --  Lexer_To_Augmented on Left_Paren_ID, Right_Paren_ID.
-
-      --  Data for post-parse actions
-
-      Lexer             : WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : WisiToken.Base_Token_Array_Access;
-      Post_Parse_Action : Post_Parse_Action_Type;
-      Navigate_Caches   : Navigate_Cache_Trees.Tree;  -- Set by Navigate.
-      Name_Caches       : Name_Cache_Trees.Tree;      -- Set by Navigate.
-      End_Positions     : Navigate_Cursor_Lists.List; -- Dynamic data for 
Navigate.
-      Face_Caches       : Face_Cache_Trees.Tree;      -- Set by Face.
-      Indents           : Indent_Vectors.Vector;      -- Set by Indent.
-      Begin_Indent      : Integer;                    -- Indentation of line 
at start of parse.
-
-      --  Copied from language-specific parameters
-      Indent_Comment_Col_0 : Boolean := False;
-
-      --  Dynamic data for Indent
-      Max_Anchor_ID : Integer;
-   end record;
-
-   type Simple_Delta_Labels is (None, Int, Anchored);
-
-   --  subtype Non_Anchored_Delta_Labels is Simple_Delta_Labels range None .. 
Int;
-
-   --  type Non_Anchored_Delta (Label : Non_Anchored_Delta_Labels := None) is
-   --  record
-   --     case Label is
-   --     when None =>
-   --        null;
-   --     when Int =>
-   --        Int_Delta : Integer;
-   --     end case;
-   --  end record;
-
-   --  function Image (Item : in Non_Anchored_Delta) return String;
-   --  For debugging
-
-   type Simple_Delta_Type (Label : Simple_Delta_Labels := None) is
-   record
-      case Label is
-      when None =>
-         null;
-
-      when Int =>
-         Int_Delta : Integer;
-
-      when Anchored =>
-         Anchored_ID         : Natural;
-         Anchored_Delta      : Integer;
-         Anchored_Accumulate : Boolean;
-
-      end case;
-   end record;
-
-   function Image (Item : in Simple_Delta_Type) return String;
-   --  For debugging
-
-   type Delta_Labels is (Simple, Hanging);
-
-   type Delta_Type (Label : Delta_Labels := Simple) is
-   record
-      case Label is
-      when Simple =>
-         Simple_Delta : Simple_Delta_Type;
-
-      when Hanging =>
-         Hanging_First_Line  : WisiToken.Line_Number_Type;
-         Hanging_Paren_State : Integer;
-         Hanging_Delta_1     : Simple_Delta_Type; -- indentation of first line
-         Hanging_Delta_2     : Simple_Delta_Type; -- indentation of 
continuation lines
-         Hanging_Accumulate  : Boolean;
-      end case;
-   end record;
-
-   Null_Delta : constant Delta_Type := (Simple, (Label => None));
-
-   function Image (Item : in Delta_Type) return String;
-   --  For debugging
-
-   ----------
-   --  Utilities for language-specific child packages
-
-   function Current_Indent_Offset
-     (Data         : in Parse_Data_Type;
-      Anchor_Token : in Augmented_Token'Class;
-      Offset       : in Integer)
-     return Integer;
-   --  Return offset from beginning of first token on line containing
-   --  Anchor_Token, to beginning of Anchor_Token, plus Offset.
-
-   function Get_Aug_Token_Const_1
-     (Tree       : in WisiToken.Syntax_Trees.Tree'Class;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return Aug_Token_Const_Ref;
-   --  WORKAROUND: GNAT Community 2019 can't do the overload resolution
-   --  between the two Get_Aug_Token_Const without an explicit renames,
-   --  so we add _1 to this one.
-
-   function Get_Aug_Token_Const
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Const_Ref;
-
-   function Get_Aug_Token_Var
-     (Tree       : in WisiToken.Syntax_Trees.Tree'Class;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return Aug_Token_Var_Ref;
-
-   function Get_Aug_Token_Var
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Var_Ref;
-
-   --  function Get_First_Terminal
-   --    (Data  : in Parse_Data_Type;
-   --     Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-   --     Token : in WisiToken.Token_Index)
-   --    return Aug_Token_Const_Ref;
-   --  Return Augmented for first Token.Inserted_Before, or if that is
-   --  empty, for Token.
-
-   function Get_Text
-     (Data       : in Parse_Data_Type;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return String;
-   --  Return text contained by Tree_Index token in source file
-   --  (lexer.buffer).
-
-   function Elisp_Escape_Quotes (Item : in String) return String;
-   --  Prefix any '"' in Item with '\' for elisp.
-
-   function Indent_Anchored_2
-     (Data        : in out Parse_Data_Type;
-      Anchor_Line : in     WisiToken.Line_Number_Type;
-      Last_Line   : in     WisiToken.Line_Number_Type;
-      Offset      : in     Integer;
-      Accumulate  : in     Boolean)
-     return Delta_Type;
-
-   function Indent_Compute_Delta
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tokens            : in     WisiToken.Valid_Node_Index_Array;
-      Param             : in     Indent_Param;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean)
-     return Delta_Type;
-
-   procedure Indent_Token_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Indenting_Token   : in     Augmented_Token'Class;
-      Delta_Indent      : in     Delta_Type;
-      Indenting_Comment : in     Boolean);
-   --  Sets Data.Indents, so caller may not be in a renames for a
-   --  Data.Indents element.
-
-   --  Visible for language-specific children. Must match list in
-   --  [3] wisi-process-parse--execute.
-   Navigate_Cache_Code  : constant String := "1";
-   Face_Property_Code   : constant String := "2";
-   Indent_Code          : constant String := "3";
-   Lexer_Error_Code     : constant String := "4";
-   Parser_Error_Code    : constant String := "5";
-   Check_Error_Code     : constant String := "6";
-   Recover_Code         : constant String := "7 ";
-   End_Code             : constant String := "8";
-   Name_Property_Code   : constant String := "9";
-   Edit_Action_Code     : constant String := "10";
-   Language_Action_Code : constant String := "11 ";
-
-end Wisi;
diff --git a/packages/wisi/wisi.el b/packages/wisi/wisi.el
deleted file mode 100644
index a7b88ff..0000000
--- a/packages/wisi/wisi.el
+++ /dev/null
@@ -1,1725 +0,0 @@
-;;; wisi.el --- Utilities for implementing an indentation/navigation engine 
using a generalized LALR parser -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2012 - 2020  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Keywords: parser
-;;  indentation
-;;  navigation
-;; Version: 3.1.3
-;; package-requires: ((emacs "25.0") (seq "2.20"))
-;; URL: http://stephe-leake.org/ada/wisitoken.html
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-
-;;; Commentary:
-
-;;;; History: see NEWS-wisi.text
-;;
-;;;; Design:
-;;
-;; 'wisi' was originally short for "wisent indentation engine", but
-;; now is just a name. wisi was developed to support Emacs ada-mode
-;; 5.0 indentation, font-lock, and navigation, which are parser based.
-;;
-;; The approach to indenting a given token is to parse the buffer,
-;; computing a delta indent at each parse action.
-;;
-;; The parser actions also cache face and navigation information
-;; as text properties on tokens in statements.
-;;
-;; The three reasons to run the parser (indent, face, navigate) occur
-;; at different times (user indent, font-lock, user navigate), so only
-;; the relevant parser actions are run.
-;;
-;; Parsing can be noticeably slow in large files, so sometimes we do a
-;; partial parse, and keep a list of parsed regions.
-;;
-;; Since we have a cache (the text properties), we need to consider
-;; when to invalidate it.  Ideally, we invalidate only when a change
-;; to the buffer would change the result of a parse that crosses that
-;; change, or starts after that change.  Changes in whitespace
-;; (indentation and newlines) do not affect an Ada parse.  Other
-;; languages are sensitive to newlines (Bash for example) or
-;; indentation (Python).  Adding comments does not change a parse,
-;; unless code is commented out.
-;;
-;; For navigate, we expect fully accurate results, and can tolerate
-;; one initial delay, so we always parse the entire file.
-;;
-;; For font-lock, we only parse the portion of the file requested by
-;; font-lock, so we keep a list of regions, and edit that list when
-;; the buffer is changed..
-;;
-;; For indenting, we expect fast results, and can tolerate some
-;; inaccuracy until the editing is done, so we allow partial parse. We
-;; cache the indent for each line in a text property on the newline
-;; char preceding the line. `wisi-indent-region' sets the cache on all
-;; the lines computed (part of the buffer in large files), but
-;; performs the indent only on the lines in the indent
-;; region. Subsequent calls to `wisi-indent-region' apply the cached
-;; indents. Non-whitespace edits to the buffer invalidate the indent
-;; caches in the edited region and after. Since we can do partial
-;; parse, we keep a list of parsed regions.
-;;
-;; See `wisi--post-change' for the details of what we check for
-;; invalidating.
-;;
-;;;; Choice of grammar compiler and parser
-;;
-;; There are two other parsing engines available in Emacs:
-;;
-;; - SMIE
-;;
-;;   We don't use this because it is designed to parse small snippets
-;;   of code. For Ada indentation, we always need to parse the entire
-;;   buffer.
-;;
-;; - semantic
-;;
-;;   The Ada grammar as given in the Ada language reference manual is
-;;   not LALR(1). So we use a generalized parser. In addition, the
-;;   semantic lexer is more complex, and gives different information
-;;   than we need. Finally, the semantic parser does not support error
-;;   correction, and thus fails in most editing situations.
-;;
-;; We use the WisiToken tool wisi-bnf-generate to compile BNF or EBNF
-;; to Ada source, See ada-mode.info and wisi.info for more information
-;; on the developer tools used for ada-mode and wisi.
-;;
-;;; Code:
-
-(require 'cl-lib)
-(require 'compile)
-(require 'seq)
-(require 'semantic/lex)
-(require 'wisi-parse-common)
-(require 'wisi-fringe)
-(require 'xref)
-
-(defcustom wisi-size-threshold most-positive-fixnum
-  "Max size (in characters) for using wisi parser results for anything."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-size-threshold)
-
-(defcustom wisi-indent-context-lines 0
-  "Minimum number of lines before point to include in a parse for indent.
-Increasing this will give better results when in the middle of a
-deeply nested statement, but worse in some situations."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-
-(defcustom wisi-disable-face nil
-  "When non-nil, `wisi-setup' does not enable use of parser for font-lock.
-Useful when debugging parser or parser actions."
-  :type 'boolean
-  :group 'wisi
-  :safe 'booleanp)
-
-(defconst wisi-error-buffer-name "*wisi syntax errors*"
-  "Name of buffer for displaying syntax errors.")
-
-(defvar wisi-error-buffer nil
-  "Buffer for displaying syntax errors.")
-
-(defvar wisi-inhibit-parse nil
-  "When non-nil, don't run the parser.
-Language code can set this non-nil when syntax is known to be
-invalid temporarily, or when making lots of changes.")
-
-(defun wisi-safe-marker-pos (pos)
-  "Return an integer buffer position from POS, an integer or marker"
-  (cond
-   ((markerp pos)
-    (marker-position pos))
-
-   (t pos)))
-
-;;;; misc
-
-(defun wisi-in-paren-p (&optional parse-result)
-  "Return t if point is inside a pair of parentheses.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (> (nth 0 (or parse-result (syntax-ppss))) 0))
-
-(defun wisi-pos-in-paren-p (pos)
-  "Return t if POS is inside a pair of parentheses."
-  (save-excursion
-    (> (nth 0 (syntax-ppss pos)) 0)))
-
-(defun wisi-same-paren-depth-p (pos1 pos2)
-  "Return t if POS1 is at same parentheses depth as POS2."
-  (= (nth 0 (syntax-ppss pos1)) (nth 0 (syntax-ppss pos2))))
-
-(defun wisi-goto-open-paren (&optional offset parse-result)
-  "Move point to innermost opening paren surrounding current point, plus 
OFFSET.
-Throw error if not in paren.  If PARSE-RESULT is non-nil, use it
-instead of calling `syntax-ppss'."
-  (goto-char (+ (or offset 0) (nth 1 (or parse-result (syntax-ppss))))))
-
-(defun wisi-in-comment-p (&optional parse-result)
-  "Return t if inside a comment.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (nth 4 (or parse-result (syntax-ppss))))
-
-(defun wisi-in-string-p (&optional parse-result)
-  "Return t if point is inside a string.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (nth 3 (or parse-result (syntax-ppss))))
-
-(defun wisi-in-string-or-comment-p (&optional parse-result)
-  "Return t if inside a comment or string.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (setq parse-result (or parse-result (syntax-ppss)))
-  (or (wisi-in-string-p parse-result) (wisi-in-comment-p parse-result)))
-
-(defun wisi-indent-newline-indent ()
-  "insert a newline, indent the old and new lines."
-  (interactive "*")
-  ;; point may be in the middle of a word, so insert newline first,
-  ;; then go back and indent.
-  (insert "\n")
-  (forward-char -1)
-  (funcall indent-line-function)
-  (forward-char 1)
-  (funcall indent-line-function))
-
-;;;; token info cache
-
-(defvar-local wisi-parse-failed nil
-  "Non-nil when last parse failed - cleared when parse succeeds.")
-
-(defvar-local wisi--parse-try
-  (list
-   (cons 'face t)
-   (cons 'navigate t)
-   (cons 'indent t))
-  "Non-nil when parse is needed because text has changed - cleared when parse 
succeeds.")
-
-(defun wisi-parse-try (&optional parse-action)
-  (cdr (assoc (or parse-action wisi--parse-action) wisi--parse-try)))
-
-(defun wisi-set-parse-try (value &optional parse-action)
-  (setcdr (assoc (or parse-action wisi--parse-action) wisi--parse-try) value))
-
-(defvar-local wisi--last-parse-region
-  (list
-   (cons 'face nil)
-   (cons 'navigate nil)
-   (cons 'indent nil))
-  "Last region on which parse was requested.")
-
-(defun wisi-last-parse-region (&optional parse-action)
-  (cdr (assoc (or parse-action wisi--parse-action) wisi--last-parse-region)))
-
-(defun wisi-set-last-parse-region (begin end parse-action)
-  (setcdr (assoc parse-action wisi--last-parse-region) (cons begin end)))
-
-(defvar-local wisi--cached-regions
-  (list
-   (cons 'face nil)
-   (cons 'navigate nil)
-   (cons 'indent nil))
-  "Alist of lists of regions in buffer where parser text properties are valid.
-Regions in a list are in random order.")
-
-(defun wisi--contained-region (begin end region)
-  "Non-nil if BEGIN and END (buffer positions) are both contained in REGION (a 
cons of positions)."
-  ;; We assume begin < end
-  (and (<= (car region) begin)
-       (<= end (cdr region))))
-
-(defun wisi--contained-pos (pos region)
-  "Non-nil if POS (a buffer position) is contained in REGION (a cons of 
positions)."
-  (and (<= (car region) pos)
-       (<= pos (cdr region))))
-
-(defun wisi-cache-covers-region (begin end &optional parse-action)
-  "Non-nil if BEGIN END is contained in a parsed region."
-  (let ((region-list (cdr (assoc (or parse-action wisi--parse-action) 
wisi--cached-regions)))
-       region)
-    (while (and region-list
-               (marker-buffer (caar region-list)) ;; this can fail after 
editing during ediff-regions.
-               (marker-buffer (cdar region-list))
-               (not (wisi--contained-region begin end (car region-list))))
-      (pop region-list))
-
-    (when region-list
-      ;; return a nice value for verbosity in wisi-validate-cache
-      (setq region (car region-list))
-      (cons (marker-position (car region)) (marker-position (cdr region))))))
-
-(defun wisi-cache-covers-pos (parse-action pos)
-  "Non-nil if POS is contained in a PARSE-ACTION parsed region."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions))))
-    (while (and region-list
-               (not (wisi--contained-pos pos (car region-list))))
-      (pop region-list))
-
-    (when region-list
-      t)))
-
-(defun wisi-cache-contains-pos (parse-action pos)
-  "Non-nil if POS is at or before the end of any PARSE-ACTION parsed region."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions)))
-       result)
-    (while (and (not result) region-list)
-      (when (<= pos (cdr (car region-list)))
-       (setq result t))
-      (pop region-list))
-
-    result))
-
-(defun wisi-cache-set-region (region)
-  "Set the cached region list for `wisi--parse-action' to REGION."
-  (setcdr (assoc wisi--parse-action wisi--cached-regions)
-         (list (cons (copy-marker (car region))
-                     (copy-marker (cdr region))))))
-
-(defun wisi-cache-add-region (region)
-  "Add REGION to the cached region list for `wisi--parse-action'."
-  (push (cons (copy-marker (car region))
-             (copy-marker (cdr region)))
-       (cdr (assoc wisi--parse-action wisi--cached-regions))))
-
-(defun wisi-cache-delete-regions-after (parse-action pos)
-  "Delete any PARSE-ACTION parsed region at or after POS.
-Truncate any region that overlaps POS."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions)))
-       result)
-    (while (and (not result) region-list)
-      (cond
-       ((and (> pos (car (car region-list)))
-            (<= pos (cdr (car region-list))))
-       ;; region contains POS; keep truncated
-       (push (cons (car (car region-list)) (copy-marker pos)) result))
-
-       ((> pos (car (car region-list)))
-       ;; region is entirely before POS; keep
-       (push (car region-list) result))
-
-       ;; else region is entirely after POS; delete
-       )
-
-      (pop region-list))
-    (setcdr (assoc parse-action wisi--cached-regions) result)
-    ))
-
-(defun wisi--delete-face-cache (after)
-  (with-silent-modifications
-    (remove-text-properties after (point-max) '(font-lock-face nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'face wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'face after)))
-
-(defun wisi--delete-navigate-cache (after)
-  (with-silent-modifications
-    ;; This text property is 'wisi-cache', not 'wisi-navigate', for
-    ;; historical reasons.
-    (remove-text-properties after (point-max) '(wisi-cache nil wisi-name nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'navigate wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'navigate after)))
-
-(defun wisi--delete-indent-cache (after)
-  (with-silent-modifications
-    (remove-text-properties after (point-max) '(wisi-indent nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'indent wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'indent after)))
-
-(defun wisi-invalidate-cache (action after)
-  "Invalidate ACTION caches for the current buffer from AFTER to end of 
buffer."
-  (cond
-   ((= after (point-min))
-    (cond
-     ((eq 'face action)
-      (wisi--delete-face-cache after))
-
-     ((eq 'navigate action)
-      (wisi--delete-navigate-cache after))
-
-     ((eq 'indent action)
-      (wisi--delete-indent-cache after))
-     ))
-
-   ((wisi-cache-contains-pos action after)
-    (when (> wisi-debug 0) (message "wisi-invalidate-cache %s:%s:%d" action 
(current-buffer) after))
-    (cond
-     ((eq 'face action)
-      (wisi--delete-face-cache after))
-
-     ((eq 'navigate action)
-      (when (wisi-cache-covers-pos 'navigate after)
-       ;; We goto statement start to ensure that motion within nested
-       ;; structures is properly done (ie prev/next on ’elsif’ is not
-       ;; set by wisi-motion-action if already set by a lower level
-       ;; statement). We don’t do it for ’face or ’indent, because that
-       ;; might require a parse, and they don’t care about nested
-       ;; structures.
-       (save-excursion
-         (goto-char after)
-
-         ;; This is copied from ‘wisi-goto-statement-start’; we can’t
-         ;; call that because it would call ‘wisi-validate-cache’,
-         ;; which would call ‘wisi-invalidate-cache’; infinite loop.
-         ;; If this needed a navigate parse to succeed, we would not
-         ;; get here.
-         (let ((cache (or (wisi-get-cache (point))
-                          (wisi-backward-cache))))
-           (cond
-            ((null cache)
-             ;; at bob
-             nil)
-
-            ((eq 'statement-end (wisi-cache-class cache))
-             ;; If the change did affect part of a structure statement,
-             ;; this is a lower level statement. Otherwise, we are
-             ;; invalidating more than necessary; not a problem.
-             (wisi-goto-start cache)
-             (setq cache (wisi-backward-cache))
-             (when cache ;; else bob
-               (wisi-goto-start cache)))
-
-            (t
-             (wisi-goto-start cache))
-            ))
-
-         (setq after (point))))
-      (wisi--delete-navigate-cache after))
-
-     ((eq 'indent action)
-      ;; The indent cache is stored on newline before line being
-      ;; indented. We delete that, because changing text on a line can
-      ;; change the indent of that line.
-      (setq after
-           (save-excursion
-             (goto-char after)
-             (line-beginning-position)))
-      (wisi--delete-indent-cache (max 1 (1- after))))
-     )
-    )))
-
-(defun wisi-reset-parser ()
-  "Force a parse."
-  (interactive)
-  (syntax-ppss-flush-cache (point-min)) ;; necessary after edit during 
ediff-regions
-  (setq wisi--cached-regions ;; necessary instead of wisi-invalidate after 
ediff-regions
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-  (wisi-set-parse-try t 'indent)
-  (wisi-set-parse-try t 'face)
-  (wisi-set-parse-try t 'navigate)
-  (wisi-set-last-parse-region (point-min) (point-min) 'indent)
-  (wisi-set-last-parse-region (point-min) (point-min) 'face)
-  (wisi-set-last-parse-region (point-min) (point-min) 'navigate)
-  (wisi-fringe-clean))
-
-;; wisi--change-* keep track of buffer modifications.
-;; If wisi--change-end comes before wisi--change-beg, it means there were
-;; no modifications.
-(defvar-local wisi--change-beg most-positive-fixnum
-  "First position where a change may have taken place.")
-
-(defvar-local wisi--change-end nil
-  "Marker pointing to the last position where a change may have taken place.")
-
-(defvar-local wisi--deleted-syntax nil
-  "Worst syntax class of characters deleted in changes.
-One of:
-nil - no deletions since reset
-0   - only whitespace or comment deleted
-2   - some other syntax deleted
-
-Set by `wisi-before-change', used and reset by `wisi--post-change'.")
-
-(defvar-local wisi-indenting-p nil
-  "Non-nil when `wisi-indent-region' is actively indenting.
-Used to ignore whitespace changes in before/after change hooks.")
-
-(defvar-local wisi--last-parse-action nil
-  "Value of `wisi--parse-action' when `wisi-validate-cache' was last run.")
-
-(defun wisi-before-change (begin end)
-  "For `before-change-functions'."
-  ;; begin . (1- end) is range of text being deleted
-  (unless wisi-indenting-p
-    ;; We set wisi--change-beg, -end even if only inserting, so we
-    ;; don't have to do it again in wisi-after-change.
-    (setq wisi--change-beg (min wisi--change-beg begin))
-
-    ;; `buffer-base-buffer' deals with edits in indirect buffers
-    ;; created by ediff-regions-*
-
-    (cond
-     ((null wisi--change-end)
-      (setq wisi--change-end (make-marker))
-      (set-marker wisi--change-end end (or (buffer-base-buffer) 
(current-buffer))))
-
-     ((> end wisi--change-end)
-      (set-marker wisi--change-end end (or (buffer-base-buffer) 
(current-buffer))))
-     )
-
-    (unless (= begin end)
-      (cond
-       ((or (null wisi--deleted-syntax)
-           (= 0 wisi--deleted-syntax))
-       (save-excursion
-         (if (or (nth 4 (syntax-ppss begin)) ; in comment, moves point to begin
-                 (= end (skip-syntax-forward " " end)));; whitespace
-             (setq wisi--deleted-syntax 0)
-           (setq wisi--deleted-syntax 2))))
-
-       (t
-       ;; wisi--deleted-syntax is 2; no change.
-       )
-       ))))
-
-(defun wisi-after-change (begin end _length)
-  "For `after-change-functions'"
-  ;; begin . end is range of text being inserted (empty if equal);
-  ;; length is the size of the deleted text.
-
-  ;; Remove caches on inserted text, which could have caches from
-  ;; anywhere, and are in any case invalid.
-
-  ;; If the insertion changes a word that has wisi fontification,
-  ;; remove fontification from the entire word, so it is all
-  ;; refontified consistently.
-
-  (let (word-begin word-end)
-    (save-excursion
-      (goto-char end)
-      (skip-syntax-forward "w_")
-      (setq word-end (point))
-      (goto-char begin)
-      (skip-syntax-backward "w_")
-      (setq word-begin (point)))
-    (if (get-text-property word-begin 'font-lock-face)
-       (with-silent-modifications
-         (remove-text-properties
-          word-begin word-end
-          '(font-lock-face nil wisi-cache nil wisi-indent nil fontified nil)))
-
-      ;; No point in removing
-      ;; 'fontified here; that's already handled by jit-lock.
-      (with-silent-modifications
-       (remove-text-properties
-        begin end
-        '(font-lock-face nil wisi-cache nil wisi-indent nil))))
-    ))
-
-(defun wisi--post-change (begin end)
-  "Update wisi text properties for changes in region BEG END."
-  ;; (syntax-ppss-flush-cache begin) is in before-change-functions
-
-  (save-excursion
-    (let ((need-invalidate t)
-         (done nil)
-         ;; non-nil if require a parse because the syntax may have
-         ;; changed.
-
-         (begin-state (syntax-ppss begin))
-         (end-state (syntax-ppss end)))
-         ;; (info "(elisp)Parser State")
-         ;; syntax-ppss has moved point to "end"; might be eob.
-
-      ;; consider deletion
-      (cond
-       ((null wisi--deleted-syntax)
-       ;; no deletions
-       )
-
-       ((= 0 wisi--deleted-syntax)
-       ;; Only deleted whitespace; may have joined two words
-       (when
-           (and (= begin end) ;; no insertions
-                (or
-                 (= (point-min) begin)
-                 (= 0 (syntax-class (syntax-after (1- begin))))
-                 (= (point-max) end)
-                 (= 0 (syntax-class (syntax-after end)))))
-         ;; More whitespace on at least one side of deletion; did not
-         ;; join two words.
-         (setq need-invalidate nil)
-         (setq done t)
-         ))
-
-       (t
-       ;; wisi--deleted-syntax is 2; need invalidate and parse for all
-       ;; parse actions
-       (setq done t)
-       ))
-
-      (setq wisi--deleted-syntax nil)
-
-      (unless done
-       ;; consider insertion
-       (cond
-        ((= begin end)
-         ;; no insertions
-         nil)
-
-        ((and
-          (nth 3 begin-state);; in string
-          (nth 3 end-state)
-          (= (nth 8 begin-state) (nth 8 end-state)));; no intervening 
non-string
-         (setq need-invalidate nil))
-
-        ((and
-          (nth 4 begin-state) ;; in comment
-          (nth 4 end-state)
-          (= (nth 8 begin-state) (nth 8 end-state))) ;; no intervening 
non-comment
-
-         (if (and
-              (= 11 (car (syntax-after begin)))
-              (progn (goto-char begin)
-                     (skip-syntax-backward "<")
-                     (not (= (point) begin))))
-
-             ;; Either inserted last char of a multi-char comment
-             ;; start, or inserted extra comment-start chars.
-             (setq need-invalidate begin)
-           (setq need-invalidate nil)))
-
-        ((and
-          (or
-           (= (point-min) begin)
-           (= 0 (syntax-class (syntax-after (1- begin)))); whitespace
-           (= (point-max) end)
-           (= 0 (syntax-class (syntax-after end))))
-          (progn
-            (goto-char begin)
-            (= (- end begin) (skip-syntax-forward " " end))
-            ))
-         ;; Inserted only whitespace, there is more whitespace on at
-         ;; least one side, and we are not in a comment or string
-         ;; (checked above).  This may affect indentation, but not
-         ;; the indentation cache.
-         (setq need-invalidate nil))
-        ))
-
-      (when need-invalidate
-       (wisi-set-parse-try t 'face)
-       (wisi-set-parse-try t 'navigate)
-       (wisi-set-parse-try t 'indent)
-
-       (wisi-invalidate-cache 'face begin)
-       (wisi-invalidate-cache 'navigate begin)
-       (wisi-invalidate-cache 'indent begin))
-      )))
-
-(defun wisi-goto-error ()
-  "Move point to position in last error message (if any)."
-  (cond
-   ((wisi-parser-parse-errors wisi--parser)
-    (let ((data (car (wisi-parser-parse-errors wisi--parser))))
-      (cond
-       ((wisi--parse-error-pos data)
-       (push-mark)
-       (goto-char (wisi--parse-error-pos data)))
-
-       ((string-match ":\\([0-9]+\\):\\([0-9]+\\):" (wisi--parse-error-message 
data))
-       (let* ((msg (wisi--parse-error-message data))
-              (line (string-to-number (match-string 1 msg)))
-              (col (string-to-number (match-string 2 msg))))
-         (push-mark)
-         (goto-char (point-min))
-         (condition-case nil
-             (progn
-               ;; line can be wrong if parser screws up, or user edits buffer
-               (forward-line (1- line))
-               (forward-char col))
-           (error
-            ;; just stay at eob.
-            nil))))
-       )))
-   ((wisi-parser-lexer-errors wisi--parser)
-    (push-mark)
-    (goto-char (wisi--lexer-error-pos (car (wisi-parser-lexer-errors 
wisi--parser)))))
-   ))
-
-(defun wisi-show-parse-error ()
-  "Show current wisi-parse errors."
-  (interactive)
-  (cond
-   ((or (wisi-parser-lexer-errors wisi--parser)
-       (wisi-parser-parse-errors wisi--parser))
-    (if (and (= 1 (+ (length (wisi-parser-lexer-errors wisi--parser))
-                    (length (wisi-parser-parse-errors wisi--parser))))
-            (or (and (wisi-parser-parse-errors wisi--parser)
-                     (not (wisi--parse-error-repair (car 
(wisi-parser-parse-errors wisi--parser)))))
-                (and (wisi-parser-lexer-errors wisi--parser)
-                     (not (wisi--lexer-error-inserted (car 
(wisi-parser-lexer-errors wisi--parser)))))))
-       ;; There is exactly one error; if there is error correction
-       ;; information, use a ’compilation’ buffer, so
-       ;; *-fix-compiler-error will call
-       ;; wisi-repair-error. Otherwise, just position cursor at
-       ;; error.
-       (progn
-         (wisi-goto-error)
-         (message (or (and (wisi-parser-parse-errors wisi--parser)
-                           (wisi--parse-error-message (car 
(wisi-parser-parse-errors wisi--parser))))
-                      (and (wisi-parser-lexer-errors wisi--parser)
-                           (wisi--lexer-error-message (car 
(wisi-parser-lexer-errors wisi--parser)))))
-                  ))
-
-      ;; else show all errors in a ’compilation’ buffer
-      (setq wisi-error-buffer (get-buffer-create wisi-error-buffer-name))
-
-      (let ((lexer-errs (sort (cl-copy-seq (wisi-parser-lexer-errors 
wisi--parser))
-                             (lambda (a b) (< (wisi--parse-error-pos a) 
(wisi--parse-error-pos b)))))
-           (parse-errs (sort (cl-copy-seq (wisi-parser-parse-errors 
wisi--parser))
-                             (lambda (a b) (< (wisi--parse-error-pos a) 
(wisi--parse-error-pos b)))))
-           (dir default-directory))
-       (with-current-buffer wisi-error-buffer
-         (setq window-size-fixed nil)
-         (compilation-mode)
-         (setq-local compilation-search-path (list dir))
-         (setq default-directory dir)
-         (setq next-error-last-buffer (current-buffer))
-         (setq buffer-read-only nil)
-         (erase-buffer)
-         ;; compilation-nex-error-function assumes there is not an
-         ;; error at point-min, so we need a comment.
-         (insert "wisi syntax errors")
-         (newline)
-         (dolist (err lexer-errs)
-           (insert (wisi--lexer-error-message err))
-           (put-text-property (line-beginning-position) (1+ 
(line-beginning-position)) 'wisi-error-data err)
-           (newline 2))
-         (dolist (err parse-errs)
-           (insert (wisi--parse-error-message err))
-           (put-text-property (line-beginning-position) (1+ 
(line-beginning-position)) 'wisi-error-data err)
-           (newline 2))
-         (compilation--flush-parse (point-min) (point-max))
-         (compilation--ensure-parse (point-max))
-         (when compilation-filter-hook
-           (let ((compilation-filter-start (point-min)))
-             (run-hooks 'compilation-filter-hook)))
-
-         (setq buffer-read-only t)
-         (goto-char (point-min)))
-
-       (let ((win (display-buffer
-                   wisi-error-buffer
-                   (cons #'display-buffer-at-bottom
-                         (list (cons 'window-height 
#'shrink-window-if-larger-than-buffer))))))
-         (set-window-dedicated-p win t))
-
-       (with-current-buffer wisi-error-buffer
-         (setq window-size-fixed t))
-       (next-error))
-      ))
-
-   ((wisi-parse-try wisi--last-parse-action)
-    (message "need parse"))
-
-   (t
-    (message "parse succeeded"))
-   ))
-
-(defun wisi-kill-parser ()
-  "Kill the background process running the parser for the current buffer.
-Usefull if the parser appears to be hung."
-  (interactive)
-  (wisi-parse-kill wisi--parser)
-  ;; also force re-parse
-  (wisi-reset-parser)
-  )
-
-(defun wisi-partial-parse-p (begin end)
-  (and (wisi-process--parser-p wisi--parser)
-       (not (and (= begin (point-min))
-                (= end (point-max))))
-       (>= (point-max) wisi-partial-parse-threshold)))
-
-(defun wisi--run-parse (begin parse-end)
-  "Run the parser, on at least region BEGIN PARSE-END."
-  (unless (or (buffer-narrowed-p)
-             (= (point-min) (point-max))) ;; some parsers can’t handle an 
empty buffer.
-    (let* ((partial-parse-p (wisi-partial-parse-p begin parse-end))
-          (msg (when (> wisi-debug 0)
-                 (format "wisi: %sparsing %s %s:%d %d %d ..."
-                         (if partial-parse-p "partial " "")
-                         wisi--parse-action
-                         (buffer-name)
-                         begin
-                         (if (markerp parse-end) (marker-position parse-end) 
parse-end)
-                         (line-number-at-pos begin))))
-          (parsed-region nil))
-
-      (when msg
-       (message msg))
-
-      (setq wisi--last-parse-action wisi--parse-action)
-      (wisi-set-last-parse-region begin parse-end wisi--parse-action)
-
-      (unless (eq wisi--parse-action 'face)
-       (when (buffer-live-p wisi-error-buffer)
-         (with-current-buffer wisi-error-buffer
-           (setq buffer-read-only nil)
-           (erase-buffer)
-           (setq buffer-read-only t)
-           (when (get-buffer-window wisi-error-buffer)
-             (delete-window (get-buffer-window wisi-error-buffer))))))
-
-      (condition-case-unless-debug err
-         (save-excursion
-           (if partial-parse-p
-             (let ((send-region (wisi-parse-expand-region wisi--parser begin 
parse-end)))
-               (setq parsed-region (wisi-parse-current wisi--parser (car 
send-region) (cdr send-region) parse-end))
-               (wisi-cache-add-region parsed-region))
-
-             ;; parse full buffer
-             (setq parsed-region (cons (point-min) (point-max)))
-             (wisi-cache-set-region (wisi-parse-current wisi--parser 
(point-min) (point-max) (point-max))))
-
-           (when (> wisi-debug 0) (message "... parsed %s" parsed-region))
-           (setq wisi-parse-failed nil))
-       (wisi-parse-error
-        (cl-ecase wisi--parse-action
-          (face
-           ;; Caches set by failed elisp parse are ok, but some parse
-           ;; failures return 'nil' in parse-region.
-           (when (cdr parsed-region)
-             (wisi--delete-face-cache (cdr parsed-region))))
-
-          (navigate
-           ;; elisp parse partially resets caches
-           (wisi--delete-navigate-cache (point-min)))
-
-          (indent
-           ;; parse does not set caches; see `wisi-indent-region'
-           nil))
-        (setq wisi-parse-failed t)
-        ;; parser should have stored this error message in parser-error-msgs
-        (when (> wisi-debug 0)
-          (signal (car err) (cdr err)))
-        )
-       (error
-        ;; parser failed for other reason
-        (setq wisi-parse-failed t)
-        (signal (car err) (cdr err)))
-       )
-
-      (unless partial-parse-p
-       (wisi-fringe-display-errors
-        (append
-         (seq-map (lambda (err) (wisi--lexer-error-pos err)) 
(wisi-parser-lexer-errors wisi--parser))
-         (seq-map (lambda (err) (wisi--parse-error-pos err)) 
(wisi-parser-parse-errors wisi--parser)))))
-
-      (when (> wisi-debug 1)
-       (if (or (wisi-parser-lexer-errors wisi--parser)
-               (wisi-parser-parse-errors wisi--parser))
-           (progn
-             (message "%s error" msg)
-             (wisi-goto-error)
-             (error (or (and (wisi-parser-lexer-errors wisi--parser)
-                             (wisi--lexer-error-message (car 
(wisi-parser-lexer-errors wisi--parser))))
-                        (and (wisi-parser-parse-errors wisi--parser)
-                             (wisi--parse-error-message (car 
(wisi-parser-parse-errors wisi--parser))))
-                        )))
-
-         ;; no error
-         (message "%s done" msg))
-       ))))
-
-(defun wisi--check-change ()
-  "Process `wisi--change-beg', `wisi--change-end'.
-`wisi--parse-action' must be bound."
-  (when (and wisi--change-beg
-            wisi--change-end
-            (or (integerp wisi--change-beg)
-                (marker-buffer wisi--change-beg)) ;; this can fail after 
editing during ediff-regions.
-            (or (integerp wisi--change-end)
-                (marker-buffer wisi--change-end))
-            (<= wisi--change-beg wisi--change-end))
-    (wisi--post-change wisi--change-beg (marker-position wisi--change-end))
-    (setq wisi--change-beg most-positive-fixnum)
-    (move-marker wisi--change-end (point-min))
-    ))
-
-(defun wisi-validate-cache (begin end error-on-fail parse-action)
-  "Ensure cached data for PARSE-ACTION is valid in region BEGIN END in current 
buffer."
-  (if (and (not wisi-inhibit-parse)
-          (< (point-max) wisi-size-threshold))
-      (let ((wisi--parse-action parse-action))
-       (wisi--check-change)
-
-       ;; Now we can rely on wisi-cache-covers-region.
-       ;;
-       ;; If the last parse failed but was partial, and we are trying
-       ;; a different region, it may succeed. Otherwise, don't keep
-       ;; retrying a failed parse until the text changes again.
-       (cond
-        ((and (not wisi-parse-failed)
-              (wisi-cache-covers-region begin end))
-         (when (> wisi-debug 0)
-           (message "parse %s skipped: cache-covers-region %s %s.%s"
-                    parse-action
-                    (wisi-cache-covers-region begin end)
-                    begin end)))
-
-        ((and wisi-parse-failed
-              (equal (cons begin end) (wisi-last-parse-region parse-action))
-              (not (wisi-parse-try parse-action)))
-         (when (> wisi-debug 0)
-           (message "parse %s skipped: parse-failed" parse-action)))
-
-        (t
-         (progn
-           (wisi-set-parse-try nil)
-           (wisi--run-parse begin end))))
-
-       ;; We want this error even if we did not try to parse; it means
-       ;; the parse results are not valid.
-       (when (and error-on-fail wisi-parse-failed)
-         (error "parse %s failed" parse-action))
-       )
-    (when (> wisi-debug 0)
-      (message "parse %s skipped inihibit-parse %s wisi-size-threshold %d"
-              parse-action
-              wisi-inhibit-parse
-              wisi-size-threshold))))
-
-(defun wisi-fontify-region (begin end)
-  "For `jit-lock-functions'."
-  (wisi-validate-cache begin end nil 'face))
-
-(defun wisi-get-containing-cache (cache)
-  "Return cache from (wisi-cache-containing CACHE)."
-  (when cache
-    (let ((containing (wisi-cache-containing cache)))
-      (and containing
-          (wisi-get-cache containing)))))
-
-(defun wisi-cache-text (cache)
-  "Return property-less buffer substring designated by cache.
-Point must be at cache."
-  (buffer-substring-no-properties (point) (+ (point) (wisi-cache-last cache))))
-
-;;;; navigation
-
-(defun wisi-forward-find-class (class limit)
-  "Search at point or forward for a token that has a cache with CLASS.
-Return cache, or nil if at end of buffer.
-If LIMIT (a buffer position) is reached, throw an error."
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-forward-cache))))
-    (while (not (eq class (wisi-cache-class cache)))
-      (setq cache (wisi-forward-cache))
-      (when (>= (point) limit)
-       (error "cache with class %s not found" class)))
-    cache))
-
-(defun wisi-forward-find-cache-token (ids limit)
-  "Search forward for a cache with token in IDS (a list of token ids).
-Return cache, or nil if at LIMIT or end of buffer."
-  (let ((cache (wisi-forward-cache)))
-    (while (and (< (point) limit)
-               (not (eobp))
-               (not (memq (wisi-cache-token cache) ids)))
-      (setq cache (wisi-forward-cache)))
-    cache))
-
-(defun wisi-forward-find-nonterm (nonterm limit)
-  "Search forward for a token that has a cache with NONTERM.
-NONTERM may be a list; stop on any cache that has a member of the list.
-Return cache, or nil if at end of buffer.
-If LIMIT (a buffer position) is reached, throw an error."
-  (let ((nonterm-list (cond
-                      ((listp nonterm) nonterm)
-                      (t (list nonterm))))
-       (cache (wisi-forward-cache)))
-    (while (not (memq (wisi-cache-nonterm cache) nonterm-list))
-      (setq cache (wisi-forward-cache))
-      (when (>= (point) limit)
-       (error "cache with nonterm %s not found" nonterm)))
-    cache))
-
-(defun wisi-goto-cache-next (cache)
-  (goto-char (wisi-cache-next cache))
-  (wisi-get-cache (point))
-  )
-
-(defun wisi-forward-statement-keyword ()
-  "If not at a cached token, move forward to next
-cache. Otherwise move to cache-next, or cache-end, or next cache
-if both nil.  Return cache found."
-  (unless (eobp)
-    (wisi-validate-cache (point-min) (point-max) t 'navigate)
-    (let ((cache (wisi-get-cache (point))))
-      (if (and cache
-              (not (eq (wisi-cache-class cache) 'statement-end)))
-         (let ((next (or (wisi-cache-next cache)
-                         (wisi-cache-end cache))))
-           (if next
-               (goto-char next)
-             (wisi-forward-cache)))
-       (wisi-forward-cache))
-      )
-    (wisi-get-cache (point))
-    ))
-
-(defun wisi-backward-statement-keyword ()
-  "If not at a cached token, move backward to prev
-cache. Otherwise move to cache-prev, or prev cache if nil."
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (wisi-get-cache (point)))
-       prev)
-    (when cache
-      (setq prev (wisi-cache-prev cache))
-      (unless prev
-       (unless (eq 'statement-start (wisi-cache-class cache))
-         (setq prev (wisi-cache-containing cache)))))
-    (if prev
-       (goto-char prev)
-      (wisi-backward-cache))
-  ))
-
-(defun wisi-forward-sexp (&optional arg)
-  "For `forward-sexp-function'."
-  (interactive "^p")
-  (or arg (setq arg 1))
-  (cond
-   ((and (> arg 0) (= 4 (syntax-class (syntax-after (point)))))  ;; on open 
paren
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (< arg 0) (= 5 (syntax-class (syntax-after (1- (point)))))) ;; after 
close paren
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (> arg 0) (= 7 (syntax-class (syntax-after (point)))))  ;; on (open) 
string quote
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (< arg 0) (= 7 (syntax-class (syntax-after (1- (point)))))) ;; after 
(close) string quote
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   (t
-    (dotimes (_i (abs arg))
-      (if (> arg 0)
-         (wisi-forward-statement-keyword)
-       (wisi-backward-statement-keyword))))
-   ))
-
-(defun wisi-goto-containing (cache &optional error)
-  "Move point to containing token for CACHE, return cache at that point.
-If ERROR, throw error when CACHE has no container; else return nil."
-  (cond
-   ((and (markerp (wisi-cache-containing cache))
-
-        (not (= (wisi-cache-containing cache) (point))))
-    ;; This check is only needed if some cache points to itself as a
-    ;; container. Apparently that happend once that I caught in the
-    ;; debugger; emacs hung because we got here in the font-lock
-    ;; timer.
-
-    (goto-char (wisi-cache-containing cache))
-    (wisi-get-cache (point)))
-   (t
-    (when error
-      (error "already at outermost containing token")))
-   ))
-
-(defun wisi-goto-containing-paren (cache)
-  "Move point to just after the open-paren containing CACHE.
-Return cache for paren, or nil if no containing paren."
-  (while (and cache
-             (not (eq (wisi-cache-class cache) 'open-paren)))
-    (setq cache (wisi-goto-containing cache)))
-  (when cache
-    (forward-char 1))
-  cache)
-
-(defun wisi-goto-start (cache)
-  "Move point to containing ancestor of CACHE that has class statement-start.
-Return start cache."
-  ;; cache nil at bob, or on cache in partially parsed statement
-  (while (and cache
-             (not (eq (wisi-cache-class cache) 'statement-start)))
-    (setq cache (wisi-goto-containing cache)))
-  cache)
-
-(defun wisi-goto-end-1 (cache)
-  (goto-char (wisi-cache-end cache)))
-
-(defun wisi-goto-statement-start ()
-  "Move point to token at start of statement point is in or after.
-Return start cache."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (wisi-goto-start (or (wisi-get-cache (point))
-                      (wisi-backward-cache))))
-
-(defun wisi-goto-statement-end ()
-  "Move point to token at end of statement point is in or before."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-forward-cache))))
-    (when (wisi-cache-end cache)
-      ;; nil when cache is statement-end
-      (wisi-goto-end-1 cache))
-    ))
-
-(defun wisi-goto-containing-statement-start ()
-  "Move point to the start of the statement containing the current statement."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-backward-cache))))
-    (when cache
-      (setq cache (wisi-goto-start cache)))
-    (when cache
-      (setq cache (wisi-goto-containing cache nil)))
-    ))
-
-(defun wisi-next-statement-cache (cache)
-  "Move point to CACHE-next, return cache; error if nil."
-  (when (not (markerp (wisi-cache-next cache)))
-    (error "no next statement cache"))
-  (goto-char (wisi-cache-next cache))
-  (wisi-get-cache (point)))
-
-(defun wisi-prev-statement-cache (cache)
-  "Move point to CACHE-prev, return cache; error if nil."
-  (when (not (markerp (wisi-cache-prev cache)))
-    (error "no prev statement cache"))
-  (goto-char (wisi-cache-prev cache))
-  (wisi-get-cache (point)))
-
-;;;; indentation
-
-(defun wisi-comment-indent ()
-  "For `comment-indent-function'. Indent single line comment to
-the comment on the previous line."
-  ;; Called from `comment-indent', either to insert a new comment, or
-  ;; to indent the first line of an existing one.  In either case, the
-  ;; comment may be after code on the same line.  For an existing
-  ;; comment, point is at the start of the starting delimiter.
-  (or
-   (save-excursion
-     ;; Check for a preceding comment line; fail if comment follows code.
-     (when (forward-comment -1)
-       ;; For the case:
-       ;;
-       ;; code;-- comment
-       ;;
-       ;; point is on '--', and 'forward-comment' does not move point,
-       ;; returns nil.
-       (when (looking-at comment-start)
-         (current-column))))
-
-   (save-excursion
-     (back-to-indentation)
-     (if (looking-at comment-start)
-         ;; An existing comment, no code preceding comment, and
-         ;; no comment on preceding line. Return nil, so
-         ;; `comment-indent' will call `indent-according-to-mode'
-         nil
-
-       ;; A comment after code on the same line.
-       comment-column))
-   ))
-
-(defun wisi-indent-statement ()
-  "Indent region given by `wisi-goto-start', `wisi-cache-end'."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-
-  (save-excursion
-    (let ((cache (or (wisi-get-cache (point))
-                    (wisi-backward-cache))))
-      (when cache
-       ;; can be nil if in header comment
-       (let ((start (progn (wisi-goto-start cache) (point)))
-             (end (if (wisi-cache-end cache)
-                        ;; nil when cache is statement-end
-                        (wisi-cache-end cache)
-                      (point))))
-         (indent-region start end)
-         ))
-      )))
-
-(defun wisi-indent-containing-statement ()
-  "Indent region given by `wisi-goto-containing-statement-start', 
`wisi-cache-end'."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-
-  (save-excursion
-    (let ((cache (or (wisi-get-cache (point))
-                    (wisi-backward-cache))))
-      (when cache
-       ;; can be nil if in header comment
-       (let ((start (progn
-                      (setq cache (wisi-goto-containing (wisi-goto-start 
cache)))
-                      (point)))
-             (end (if (wisi-cache-end cache)
-                        ;; nil when cache is statement-end
-                        (wisi-cache-end cache)
-                      (point))))
-         (indent-region start end)
-         ))
-      )))
-
-(defvar-local wisi-indent-calculate-functions nil
-  "Functions to compute indentation special cases.
-Called with point at current indentation of a line; return
-indentation column, or nil if function does not know how to
-indent that line. Run after parser indentation, so other lines
-are indented correctly.")
-
-(defvar-local wisi-post-indent-fail-hook
-  "Function to reindent portion of buffer.
-Called from `wisi-indent-region' when a parse succeeds after
-failing; assumes user was editing code that is now syntactically
-correct. Must leave point at indentation of current line.")
-
-(defvar-local wisi-indent-failed nil
-  "Non-nil when wisi-indent-region fails due to parse failing; cleared when 
indent succeeds.")
-
-(defvar-local wisi-indent-region-fallback 'wisi-indent-region-fallback-default
-  "Function to compute indent for lines in region when wisi parse fails.
-Called with BEGIN END.")
-
-(defun wisi-indent-region-fallback-default (begin end)
-  ;; Assume there is no indent info at point; user is editing. Indent
-  ;; to previous lines.
-  (goto-char begin)
-  (forward-line -1);; safe at bob
-  (back-to-indentation)
-  (let ((col (current-column)))
-    (while (and (not (eobp))
-               (< (point) end))
-      (if (= 1 (forward-line 1))
-         (indent-line-to col)
-       ;; on last line of buffer; terminate loop
-       (goto-char (point-max)))
-      (when (bobp)
-       ;; single line in buffer; terminate loop
-       (goto-char (point-max))))))
-
-(defun wisi-list-memq (a b)
-  "Return non-nil if any member of A is a memq of B."
-  (let ((temp (copy-sequence a))
-       result)
-    (while (and (not result)
-               temp)
-      (when (memq (pop temp) b)
-       (setq result t)))
-    result))
-
-(defun wisi--get-cached-indent (begin end)
-  "Return cached indent for point (must be bol), after correcting
-for parse errors. BEGIN, END is the parsed region."
-  (let ((indent (get-text-property (1- (point)) 'wisi-indent)))
-    (if indent
-       (when (and (wisi-partial-parse-p begin end)
-                  (< 0 (length (wisi-parser-parse-errors wisi--parser))))
-         (dolist (err (wisi-parser-parse-errors wisi--parser))
-           (dolist (repair (wisi--parse-error-repair err))
-             ;; point is at bol; error pos may be at first token on same line.
-             (save-excursion
-               (back-to-indentation)
-               (when (>= (point) (wisi--parse-error-repair-pos repair))
-                 (setq indent (max 0 (wisi-parse-adjust-indent wisi--parser 
indent repair))))
-               ))))
-      ;; parse did not compute indent for point. Assume the error will
-      ;; go away soon as the user edits the code, so just return 0.
-      (if (= wisi-debug 0)
-         (setq indent 0)
-       (error "nil indent for line %d" (line-number-at-pos (point)))))
-
-    indent))
-
-(defun wisi-indent-region (begin end &optional indent-blank-lines)
-  "For `indent-region-function', using the wisi indentation engine.
-If INDENT-BLANK-LINES is non-nil, also indent blank lines (for use as
-`indent-line-function')."
-  (if wisi-inhibit-parse
-      (when (< 0 wisi-debug)
-       (message "wisi-indent-region %d %d skipped; wisi-inhibit-parse"
-                (wisi-safe-marker-pos begin)
-                (wisi-safe-marker-pos end)))
-
-    (let ((wisi--parse-action 'indent)
-         (parse-required nil)
-         (end-mark (copy-marker end))
-         (prev-indent-failed wisi-indent-failed))
-
-      (when (< 0 wisi-debug)
-       (message "wisi-indent-region %d %d"
-                (wisi-safe-marker-pos begin)
-                (wisi-safe-marker-pos end)))
-
-      (wisi--check-change)
-
-      ;; BEGIN is inclusive; END is exclusive.
-      (save-excursion
-       (goto-char begin)
-       (setq begin (line-beginning-position))
-
-       (when (bobp) (forward-line))
-       (while (and (not parse-required)
-                   (or (and (= begin end) (= (point) end))
-                       (< (point) end))
-                   (not (eobp)))
-         (unless (get-text-property (1- (point)) 'wisi-indent)
-           (setq parse-required t))
-         (forward-line))
-       )
-
-      ;; A parse either succeeds and sets the indent cache on all
-      ;; lines in the parsed region, or fails and leaves valid caches
-      ;; untouched.
-      (when (and parse-required
-                (or (not wisi-parse-failed)
-                    (wisi-parse-try 'indent)))
-
-       (wisi-set-parse-try nil)
-       (wisi--run-parse begin end)
-
-       ;; If there were errors corrected, the indentation is
-       ;; potentially ambiguous; see
-       ;; test/ada_mode-interactive_2.adb. Or it was a partial parse,
-       ;; where errors producing bad indent are pretty much expected.
-       (unless (wisi-partial-parse-p begin end)
-         (setq wisi-indent-failed (< 0 (+ (length (wisi-parser-lexer-errors 
wisi--parser))
-                                          (length (wisi-parser-parse-errors 
wisi--parser))))))
-       )
-
-      (if wisi-parse-failed
-         (progn
-           ;; primary indent failed
-           (setq wisi-indent-failed t)
-           (when (functionp wisi-indent-region-fallback)
-             (when (< 0 wisi-debug)
-               (message "wisi-indent-region fallback"))
-             (funcall wisi-indent-region-fallback begin end)))
-
-       (save-excursion
-         ;; Apply cached indents. Start from end, so indenting
-         ;; doesn't affect correcting for errors in
-         ;; wisi--get-cached-indent.
-         (goto-char (1- end)) ;; end is exclusive
-         (goto-char (line-beginning-position))
-         (let ((wisi-indenting-p t))
-           (while (and (not (bobp))
-                       (or (and (= begin end) (= (point) end))
-                           (>= (point) begin)))
-             (when (or indent-blank-lines (not (eolp)))
-               ;; ’indent-region’ doesn’t indent an empty line; ’indent-line’ 
does
-               (let ((indent (if (bobp) 0 (wisi--get-cached-indent begin 
end))))
-                 (indent-line-to indent))
-               )
-             (forward-line -1))
-
-           ;; Run wisi-indent-calculate-functions
-           (when wisi-indent-calculate-functions
-             (goto-char begin)
-             (while (and (not (eobp))
-                         (< (point) end-mark))
-               (back-to-indentation)
-               (let ((indent
-                      (run-hook-with-args-until-success 
'wisi-indent-calculate-functions)))
-                 (when indent
-                   (indent-line-to indent)))
-
-               (forward-line 1)))
-           )
-
-         (when
-             (and prev-indent-failed
-                  (not wisi-indent-failed))
-           ;; Previous parse failed or indent was potentially
-           ;; ambiguous, this one is not.
-           (goto-char end-mark)
-           (when (< 0 wisi-debug)
-             (message "wisi-indent-region post-parse-fail-hook"))
-           (run-hooks 'wisi-post-indent-fail-hook))
-         ))
-      )))
-
-(defun wisi-indent-line ()
-  "For `indent-line-function'."
-  (let ((savep (copy-marker (point)))
-       (to-indent nil))
-    (back-to-indentation)
-    (when (>= (point) savep)
-      (setq to-indent t))
-
-    (wisi-indent-region (line-beginning-position (1+ (- 
wisi-indent-context-lines))) (1+ (line-end-position)) t)
-
-    (goto-char savep)
-    (when to-indent (back-to-indentation))
-    ))
-
-(defun wisi-repair-error-1 (data)
-  "Repair error reported in DATA (a ’wisi--parse-error’ or 
’wisi--lexer-error’)"
-  (let ((wisi--parse-action 'navigate))
-    (cond
-     ((wisi--lexer-error-p data)
-      (goto-char (1+ (wisi--lexer-error-pos data)))
-      (insert (wisi--lexer-error-inserted data)))
-     ((wisi--parse-error-p data)
-      (dolist (repair (wisi--parse-error-repair data))
-       (goto-char (wisi--parse-error-repair-pos repair))
-       (when (< 0 (length (wisi--parse-error-repair-deleted repair)))
-         (delete-region (car (wisi--parse-error-repair-deleted-region repair))
-                        (cdr (wisi--parse-error-repair-deleted-region repair)))
-         (when (= ?  (char-after (point)))
-           (delete-char 1)))
-       (dolist (id (wisi--parse-error-repair-inserted repair))
-         (when (and (not (bobp))
-                    (not (= ?\( (char-before (point))))
-                    (member (syntax-class (syntax-after (1- (point)))) '(2 
3))) ;; word or symbol
-           (insert " "))
-         (insert (cdr (assoc id (wisi-parser-repair-image wisi--parser)))))
-       ))
-     )))
-
-(defun wisi-repair-error ()
-  "Repair the current error."
-  (interactive)
-  (let ((wisi-inhibit-parse t)) ;; don’t let the error list change while we 
are processing it.
-    (if (= 1 (+ (length (wisi-parser-lexer-errors wisi--parser))
-               (length (wisi-parser-parse-errors wisi--parser))))
-       (progn
-         (wisi-repair-error-1 (or (car (wisi-parser-lexer-errors wisi--parser))
-                                  (car (wisi-parser-parse-errors 
wisi--parser)))))
-      (if (buffer-live-p wisi-error-buffer)
-         (let ((err
-                (with-current-buffer wisi-error-buffer
-                  (get-text-property (point) 'wisi-error-data))))
-           (wisi-repair-error-1 err))
-       (error "no current error found")
-       ))))
-
-(defun wisi-repair-errors (&optional beg end)
-  "Repair errors reported by last parse.
-If non-nil, only repair errors in BEG END region."
-  (interactive)
-  (let ((wisi-inhibit-parse t)) ;; don’t let the error list change while we 
are processing it.
-    (dolist (data (wisi-parser-lexer-errors wisi--parser))
-      (when (or (null beg)
-               (and (not (= 0 (wisi--lexer-error-inserted data)))
-                    (wisi--lexer-error-pos data)
-                    (<= beg (wisi--lexer-error-pos data))
-                    (<= (wisi--lexer-error-pos data) end)))
-       (wisi-repair-error-1 data)))
-
-    (dolist (data (wisi-parser-parse-errors wisi--parser))
-      (when (or (null beg)
-               (and (wisi--parse-error-pos data)
-                    (<= beg (wisi--parse-error-pos data))
-                    (<= (wisi--parse-error-pos data) end)))
-       (wisi-repair-error-1 data)))
-    ))
-
-;;; xref integration
-
-(defun wisi-xref-identifier-at-point ()
-  (let ((ident (thing-at-point 'symbol)))
-    (when ident
-      (put-text-property
-       0 1
-       'xref-identifier
-       (list :file (buffer-file-name)
-            :line (line-number-at-pos)
-            :column (current-column))
-       ident)
-      ident)))
-
-(defun wisi-next-name-region ()
-  "Return the next region at or after point with text property 'wisi-name'."
-  (let* ((begin
-         (if (get-text-property (point) 'wisi-name)
-             (point)
-           (next-single-property-change (point) 'wisi-name)))
-        (end (next-single-property-change begin 'wisi-name)))
-    (cons begin end)))
-
-(defun wisi-prev-name-region ()
-  "Return the prev region at or before point with text property 'wisi-name'."
-  (let* ((end
-         (if (get-text-property (point) 'wisi-name)
-             (point)
-           (previous-single-property-change (point) 'wisi-name)))
-        (begin (previous-single-property-change end 'wisi-name)))
-    (cons begin end)))
-
-(defun wisi-next-name ()
-  "Return the text at or after point with text property 'wisi-name'."
-  (let ((region (wisi-next-name-region)))
-    (buffer-substring-no-properties (car region) (cdr region))))
-
-(defun wisi-prev-name ()
-  "Return the text at or before point with text property 'wisi-name'."
-  (let ((region (wisi-prev-name-region)))
-    (buffer-substring-no-properties (car region) (cdr region))))
-
-(defconst wisi-names-regexp "\\([^<]*\\)<\\([0-9]+\\)>"
-  "Match line number encoded into identifier by `wisi-names'.")
-
-(defun wisi-names (append-lines alist)
-  "List of names; each is text from one 'wisi-name property in current buffer.
-If APPEND-LINES is non-nil, each name has the line number it
-occurs on appended. If ALIST is non-nil, the result is an alist
-where the car is a list (FILE LINE COL)."
-  (when wisi--parser
-    ;; wisi--parser is nil in a non-language buffer, like Makefile
-    (wisi-validate-cache (point-min) (point-max) t 'navigate)
-    (let ((table nil)
-         (pos (point-min))
-         end-pos)
-      (while (setq pos (next-single-property-change pos 'wisi-name))
-       ;; We can’t store location data in a string text property -
-       ;; it does not survive completion. So we include the line
-       ;; number in the identifier string. This also serves to
-       ;; disambiguate overloaded identifiers in the user interface.
-       (setq end-pos (next-single-property-change pos 'wisi-name))
-       (let* ((line (line-number-at-pos pos))
-              (summary
-               (if append-lines
-                   (format "%s<%d>"
-                           (buffer-substring-no-properties pos end-pos)
-                           line)
-                 (buffer-substring-no-properties pos end-pos))))
-         (if alist
-             (save-excursion
-               (goto-char pos)
-               (push (cons summary (list (buffer-file-name) line 
(current-column)))
-                     table))
-           (push summary table)))
-       (setq pos end-pos)
-       )
-      table)))
-
-;;;; debugging
-
-(defun wisi-show-region ()
-  (interactive)
-  (cond
-   ((use-region-p)
-    (message "(%s . %s)" (region-beginning) (region-end)))
-   (t
-    (let ((string (read-from-minibuffer "region: ")))
-      (when (not (= ?\( (aref string 0)))
-       (setq string (concat "(" string ")")))
-
-      (let ((region (read string)))
-       (cond
-        ((consp (cdr region))
-         ;; region is a list; (begin end)
-         (set-mark  (nth 0 region))
-         (goto-char (nth 1 region)))
-
-        ((consp region)
-         ;; region is a cons; (begin . end)
-         (set-mark  (car region))
-         (goto-char (cdr region)))
-        ))))
-   ))
-
-(defun wisi-debug-keys ()
-  "Add debug key definitions to `global-map'."
-  (interactive)
-  (define-key global-map "\M-h" 'wisi-show-containing-or-previous-cache)
-  (define-key global-map "\M-i" 'wisi-show-indent)
-  (define-key global-map "\M-j" 'wisi-show-cache)
-  )
-
-(defun wisi-parse-buffer (&optional parse-action begin end)
-  (interactive)
-  (unless parse-action
-    (setq parse-action (wisi-read-parse-action)))
-  (if (use-region-p)
-      (progn
-       (setq begin (region-beginning))
-       (setq end   (region-end)))
-
-    (unless begin (setq begin (point-min)))
-    (unless end (setq end (point-max))))
-
-  (wisi-set-parse-try t parse-action)
-  (wisi-invalidate-cache parse-action begin)
-
-  (cl-ecase parse-action
-    (face
-     (with-silent-modifications
-       (remove-text-properties
-       begin end
-       (list
-        'font-lock-face nil
-        'fontified nil)))
-     (wisi-validate-cache begin end t parse-action)
-     (font-lock-ensure))
-
-    (navigate
-     (wisi-validate-cache begin end t parse-action))
-
-    (indent
-     (wisi-indent-region begin end))
-    ))
-
-(defun wisi-time (func count &optional report-wait-time)
-  "call FUNC COUNT times, show total time"
-  (interactive "afunction \nncount ")
-
-  (let ((start-time (float-time))
-       (start-gcs gcs-done)
-       (cum-wait-time 0.0)
-        (i 0)
-        diff-time
-       diff-gcs)
-    (while (not (eq (1+ count) (setq i (1+ i))))
-      (save-excursion
-        (funcall func))
-      (when report-wait-time
-       (setq cum-wait-time (+ cum-wait-time 
(wisi-process--parser-total-wait-time wisi--parser)))))
-    (setq diff-time (- (float-time) start-time))
-    (setq diff-gcs (- gcs-done start-gcs))
-    (if report-wait-time
-       (progn
-         (message "Total %f seconds, %d gcs; per iteration %f seconds %d gcs 
%d responses %f wait"
-                  diff-time
-                  diff-gcs
-                  (/ diff-time count)
-                  (/ (float diff-gcs) count)
-                  (wisi-process--parser-response-count wisi--parser)
-                  (/ cum-wait-time count)))
-
-      (message "Total %f seconds, %d gcs; per iteration %f seconds %d gcs"
-              diff-time
-              diff-gcs
-              (/ diff-time count)
-              (/ (float diff-gcs) count))
-      ))
-  nil)
-
-(defun wisi-time-indent-middle-line-cold-cache (count &optional 
report-wait-time)
-  (goto-char (point-min))
-  (forward-line (1- (/ (count-lines (point-min) (point-max)) 2)))
-  (let ((cum-wait-time 0.0))
-    (wisi-time
-     (lambda ()
-       (wisi-set-parse-try t 'indent)
-       (wisi-invalidate-cache 'indent (point-min))
-       (wisi-indent-line)
-       (when (wisi-process--parser-p wisi--parser)
-        (setq cum-wait-time (+ cum-wait-time 
(wisi-process--parser-total-wait-time wisi--parser)))))
-     count
-     report-wait-time)
-    ))
-
-(defun wisi-time-indent-middle-line-warm-cache (count)
-  (wisi-set-parse-try t 'indent)
-  (wisi-invalidate-cache 'indent (point-min))
-  (goto-char (point-min))
-  (forward-line (/ (count-lines (point-min) (point-max)) 2))
-  (wisi-indent-line)
-  (wisi-time #'wisi-indent-line count))
-
-(defun wisi-show-indent ()
-  "Show indent cache for current line."
-  (interactive)
-  (message "%s" (get-text-property (1- (line-beginning-position)) 
'wisi-indent)))
-
-(defun wisi-show-cache ()
-  "Show wisi text properties at point."
-  (interactive)
-  (message "%s:%s:%s:%s"
-          (wisi-get-cache (point))
-          (get-text-property (point) 'face)
-          (get-text-property (point) 'font-lock-face)
-          (get-text-property (point) 'wisi-name)
-          ))
-
-(defun wisi-show-containing-or-previous-cache ()
-  (interactive)
-  (let ((cache (wisi-get-cache (point))))
-    (push-mark)
-    (if cache
-       (message "containing %s" (wisi-goto-containing cache t))
-      (message "previous %s" (wisi-backward-cache)))
-    ))
-
-;;;;; setup
-
-(cl-defun wisi-setup (&key indent-calculate post-indent-fail parser)
-  "Set up a buffer for parsing files with wisi."
-  (when wisi--parser
-    (wisi-kill-parser))
-
-  (setq wisi--parser parser)
-  (setq wisi--cached-regions
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-
-  (setq wisi--parse-try
-       (list
-        (cons 'face t)
-        (cons 'navigate t)
-        (cons 'indent t)))
-
-  (setq wisi--last-parse-region
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-
-  (setq wisi-indent-calculate-functions (append 
wisi-indent-calculate-functions indent-calculate))
-  (set (make-local-variable 'indent-line-function) #'wisi-indent-line)
-  (set (make-local-variable 'indent-region-function) #'wisi-indent-region)
-  (set (make-local-variable 'forward-sexp-function) #'wisi-forward-sexp)
-
-  (setq wisi-post-indent-fail-hook post-indent-fail)
-  (setq wisi-indent-failed nil)
-
-  (add-hook 'before-change-functions #'wisi-before-change 'append t)
-  (add-hook 'after-change-functions #'wisi-after-change nil t)
-  (setq wisi--change-end (copy-marker (point-min) t))
-
-  (set (make-local-variable 'comment-indent-function) 'wisi-comment-indent)
-
-  (add-hook 'completion-at-point-functions #'wisi-completion-at-point -90 t)
-
-  (add-hook 'hack-local-variables-hook 'wisi-post-local-vars nil t)
-  )
-
-(defun wisi-post-local-vars ()
-  "See wisi-setup."
-  (remove-hook 'hack-local-variables-hook #'wisi-post-local-vars)
-
-  (unless wisi-disable-face
-    (jit-lock-register #'wisi-fontify-region)))
-
-
-(provide 'wisi)
-;;; wisi.el ends here
diff --git a/packages/wisi/wisi.gpr.gp b/packages/wisi/wisi.gpr.gp
deleted file mode 100644
index 1c17529..0000000
--- a/packages/wisi/wisi.gpr.gp
+++ /dev/null
@@ -1,64 +0,0 @@
---  Abstract :
---
---  Make installed and source ELPA package wisi Ada code available for
---  other projects.
---
---  Copyright (C) 2017, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-with "gnatcoll";
-with "standard_common";
-#if ELPA="no"
-with "sal";
-with "wisitoken";
-#end if;
-project Wisi is
-
-   for Source_Dirs use (".");
-
-   case Standard_Common.Profile is
-   when "On" =>
-      for Object_Dir use "obj_pro";
-      for Exec_Dir use "exec_pro";
-
-   when "Off" =>
-      for Object_Dir use "obj";
-      for Exec_Dir use ".";
-   end case;
-
-   for Languages use ("Ada", "C"); -- C needed for wisitoken-bnf-generate; 
wisitoken_grammar_re2c.c
-
-   package Compiler is
-
-      case Standard_Common.Build is
-      when "Debug" =>
-         for Default_Switches ("Ada") use
-           Standard_Common.Compiler.Common_Switches &
-           Standard_Common.Compiler.Style_Checks &
-           Standard_Common.Compiler.Debug_Switches;
-
-         for Default_Switches ("C") use 
Standard_Common.Compiler.Debug_Switches_C;
-
-      when "Normal" =>
-         for Default_Switches ("Ada") use
-           Standard_Common.Compiler.Common_Switches &
-           Standard_Common.Compiler.Style_Checks &
-           Standard_Common.Compiler.Release_Switches;
-
-         for Default_Switches ("C") use 
Standard_Common.Compiler.Release_Switches_C;
-      end case;
-
-   end Compiler;
-
-end Wisi;
diff --git a/packages/wisi/wisi.info b/packages/wisi/wisi.info
deleted file mode 100644
index e24dcee..0000000
--- a/packages/wisi/wisi.info
+++ /dev/null
@@ -1,1294 +0,0 @@
-This is wisi.info, produced by makeinfo version 6.7 from wisi.texi.
-
-Copyright (C) 1999 - 2020 Free Software Foundation, Inc.
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU Free Documentation License,
-     Version 1.3 or any later version published by the Free Software
-     Foundation; with no Invariant Sections, with the Front-Cover texts
-     being "A GNU Manual", and with the Back-Cover Texts as in (a)
-     below.  A copy of the license is included in the section entitled
-     "GNU Free Documentation License".
-
-     (a) The FSF's Back-Cover Text is: "You have the freedom to copy and
-     modify this GNU manual.  Buying copies from the FSF supports it in
-     developing GNU and promoting software freedom."
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Wisi: (wisi).         Error-correcting LR parsers and project integration.
-END-INFO-DIR-ENTRY
-
-
-File: wisi.info,  Node: Top,  Next: Overview,  Up: (dir)
-
-Top
-***
-
-Wisi Version 3.1.2
-
-* Menu:
-
-* Overview::
-* Grammar actions::
-* Project extension::
-* GNU Free Documentation License::
-* Index::
-
-
-File: wisi.info,  Node: Overview,  Next: Grammar actions,  Prev: Top,  Up: Top
-
-1 Overview
-**********
-
-"wisi" used to be an acronym, but now it's just a name.
-
-   The wisi package provides an elisp interface to an external parser.
-It assumes the parser generator package WisiToken
-(<http://stephe-leake.org/ada/wisitoken.html>, implemented in Ada), but
-can use any parser that meets the same API. wisi provides several
-grammar actions, to implement indentation, navigating, and syntax
-highlighting (fontification).
-
-   wisi also provides an extension to Emacs 'project.el', providing
-operations useful for compilation and cross-reference.
-
-
-File: wisi.info,  Node: Grammar actions,  Next: Project extension,  Prev: 
Overview,  Up: Top
-
-2 Grammar Actions
-*****************
-
-Grammar actions are specified in the grammar file, in a nonterminal
-declaration.  We assume the user is familiar with parser grammars and
-grammar actions.  For example, a simple "if" statement can be declared
-as:
-
-     if_statement
-       : IF expression THEN statements elsif_list ELSE statements END IF 
SEMICOLON
-         %((wisi-statement-action [1 statement-start 3 motion 6 motion 10 
statement-end])
-           (wisi-motion-action [1 3 5 6 10])
-           (wisi-indent-action [nil
-                                [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                                 ada-indent-broken]
-                                nil
-                                [ada-indent ada-indent] nil nil
-                                [ada-indent ada-indent] nil nil nil]))%
-
-   The item before ':' is the "left hand side", or "nonterminal".  The
-list of tokens after ':' is the "right hand side"; in general there can
-be more than one right hand side for each nonterminal (separated by
-'|').
-
-   The items enclosed in "%()%" are the grammar actions.  They are
-specified as list of elisp forms; an earlier version of the wisi package
-generated an elisp parser.  We keep the elisp form because it is
-compact, and easier to read and write than the equivalent Ada code.  The
-'wisi-bnf-generate' tool converts the elisp into the required Ada
-statements.
-
-   There are two classes of actions; in-parse and post-parse.  WisiToken
-calls these "semantic checks" and "user actions".  The in-parse actions
-are done as parsing procedes; they provide extra checks that can cause
-the parse to fail.  Currently the only one provided is 'match-names'; it
-is used to check that the declaration and end names in named Ada blocks
-are the same (which can aid significantly in error correction).  In the
-grammar file, in-parse actions are specified in a second '%()%' block,
-which can be omitted if empty.  In this document, the term "action"
-means "post-parse action", we use "in-parse action" unless the meaning
-is clear from context.
-
-   Executing the wisi grammar actions creates text properties in the
-source file; those text properties are then used by elisp code for
-various purposes.
-
-   The text properties applied are:
-
-'wisi-cache'
-     This should be named 'wisi-navigate', but isn't for historical
-     reasons (there used to be only one kind of text property).
-
-     The property contains a 'wisi-cache' object, containing:
-
-     'nonterm'
-          The nonterminal in the grammar production that specified the
-          action that produced this text property.
-
-     'token'
-          A token identifier naming a token in the production right hand
-          side containing the text this text property is applied to.
-
-     'last'
-          The position of the last character in the token, relative to
-          the first character (0 indexed).  The text property is only
-          applied to the first character in the token (mostly for
-          historical reasons).
-
-     'class'
-          A token class; see the list of possible values in
-          'wisi-statement-action' below.
-
-     'containing'
-          A marker pointing to the start of the containing token for
-          this token; only 'nil' for the outermost containing token in a
-          file.
-
-     'prev'
-          A marker pointing to the previous "motion token" in the
-          statement or declaration.  These are normally language
-          keywords, but can be other things.
-
-     'next'
-          A marker pointing to the next "motion token" in the statement
-          or declaration.
-
-     'end'
-          A marker pointing to the end of the statement or declaration.
-
-     wisi provides motion commands for going to the various markers.
-
-'wisi-name'
-     Contains no data, applied to a "name" of some sort.  wisi provides
-     commands for finding the next/previous name, and returning the
-     text.  Useful for the names of subprograms, which can then be used
-     to build a completion table; see
-     'wisi-xref-identifier-completion-table'.
-
-'font-lock-face'
-     The standard font-lock property, specifying the face for the text.
-
-     Some major modes do not use this for simple keywords; they use
-     font-lock regular expressions instead.  One reason for this is so
-     keywords are still highlighted when the parser fails, which can
-     happen if there are severe syntax errors.
-
-     Other items, like function and package names, are typically marked
-     with 'font-lock-face' by the parser.
-
-'fontified'
-     Another standard font-lock text property; applied whenever
-     'font-lock-face' is.
-
-'wisi-indent'
-     Contains the indent (in characters) for the next line; applied to
-     the newline character on the preceding line.  The first line in a
-     buffer is assumed to have indent 0.
-
-   Each action is classified as one of 'navigate, face, indent,
-in-parse'; when actions are executed, only one of the first three
-classes is executed (in-parse is always executed).  This reflects the
-reasons the parser is run; to figure out how to go somehere (end of
-current statement, start of current procedure, etc), to apply faces for
-syntax highlighting, or to indent the code.
-
-* Menu:
-
-* Navigate actions::
-* Face actions::
-* Indent actions::
-* In-parse actions::
-
-
-File: wisi.info,  Node: Navigate actions,  Next: Face actions,  Up: Grammar 
actions
-
-2.1 Navigate actions
-====================
-
-'wisi-statement-action [TOKEN CLASS ...]'
-     The argument is a vector; alternating items are a token index (an
-     integer or label indicating a token in the right hand side) and a
-     "token class"; one of:
-
-     'motion'
-          Create a 'wisi-cache' text property on the token, for use in a
-          subsequent 'wisi-motion-action'.
-
-     'statement-end'
-          Create a 'wisi-cache' text property on the token, enter a
-          pointer to it in the other 'wisi-cache' objects in the
-          statement or declaration.
-
-     'statement-start'
-          Create a 'wisi-cache' text property on the token, enter a
-          pointer to it in the other 'wisi-cache' objects (in the
-          'containing' slot) in the statement or declaration.
-
-     'statement-override'
-          Same as 'statement-start'; marks the token to be used as the
-          statement start if the first token is optional.
-
-     'misc'
-          Create a 'wisi-cache' text property on the token, to be used
-          for some other purpose.  It is good style to indicate the
-          purpose in a comment.
-
-          For example, ada-mode uses a 'misc' property on left
-          parentheses that start a subprogram parameter list; this
-          distinquishes them from other left parentheses, and makes it
-          possible to automatically call 'ada-format-paramlist' to
-          format the parameter list, instead of using the standard Emacs
-          'align'.
-
-'wisi-motion-action [TOKEN ...]'
-     The argument is a vector, where each element is either a token
-     index or a vector [INDEX ID].
-
-     Each terminal token must already have a 'wisi-cache' created by a
-     'wisi-statement-action' (this is checked at action execution, not
-     during grammar generation).  This action sets the 'prev, next'
-     slots for the chain of tokens, creating a chain of motion tokens.
-
-     If TOKEN is a nonterminal without an ID specified, the 'wisi-cache'
-     must be on the first token in the nonterminal, and it is assumed to
-     have a valid pointer in the 'next' slot, indicating a chain of
-     motion tokens.  That chain is linked into the chain for the current
-     right hand side.
-
-     If TOKEN is a nonterminal with an ID, the region contained by the
-     nonterminal is searched for all 'wisi-cache' with that token ID,
-     and for each one where prev/next is not already set, it is linked
-     into the motion chain.
-
-     Note that the "search" described here is done in the parser
-     process, on a tree data structure containing the data that will
-     eventually be stored in Emacs text properties.
-
-'wisi-name-action TOKEN'
-     TOKEN is a token index.  Create a 'wisi-name' text property on the
-     token.
-
-
-File: wisi.info,  Node: Face actions,  Next: Indent actions,  Prev: Navigate 
actions,  Up: Grammar actions
-
-2.2 Face actions
-================
-
-'wisi-face-mark-action [INDEX CLASS ...]'
-     The argument is a vector; alternating elements form pairs of INDEX
-     CLASS, where class is one of 'prefix, suffix'.
-
-     Mark the tokens as part of a compound name, for use by later face
-     actions.
-
-'wisi-face-apply-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]'
-     The argument is a vector; triples of items specify TOKEN,
-     PREFIX-FACE, SUFFIX-FACE. The faces are the elisp names of face
-     objects (which must declared by an '%elisp_face' declaration).
-
-     If the token is a nonterminal, and it has been marked by a previous
-     'wisi-face-mark-action', the specified faces are applied to the
-     prefix and suffix in the token as 'font-lock-face' text properties.
-
-     If the token is a terminal, or a non-terminal with no face mark,
-     the suffix face is applied to the entire text contained by the
-     token.
-
-'wisi-face-apply-list-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]'
-     Similar to ’wisi-face-apply-action’, but applies faces to all
-     tokens marked by 'wisi-face-mark-action' in each indicated
-     production token, and does not apply a face if there are no such
-     marks.
-
-
-File: wisi.info,  Node: Indent actions,  Next: In-parse actions,  Prev: Face 
actions,  Up: Grammar actions
-
-2.3 Indent actions
-==================
-
-Indents are computed for each line in a cumulative way as the grammar
-actions are executed.  Initially, each indent is set to 'nil', which
-means "not computed"; this is not the same as the value '0'.  The
-grammar actions are executed in a bottom-up fashion; low level
-productions are executed before higher level ones.  In general, the
-indent action for a production specifies a "delta indent"; the indent is
-incremented by that amount.  When all productions have been processed,
-the indent has been computed for all lines.
-
-   Indents are often given as a function call; the arguments to the
-function can be other function calls, or integer expressions.
-'wisitoken-bnf-generate' supports only simple integer expressions; those
-using integers, integer-valued variables, parenthesis, + (plus), -
-(minus), and * (multiply).
-
-'wisi-indent-action [INDENT ...]'
-     The argument is a vector, giving an indent for each token in the
-     production right-hand side.
-
-     For terminals, the indents only have meaning, and are only
-     computed, if the token is the first on a line.  For nonterminals
-     where the indent is not a variant of 'wisi-hanging', the indent is
-     only computed if the first terminal token in the nonterminal is the
-     first on a line.  See 'wisi-hanging' in *note Indent functions::
-     for the remaining case.
-
-     An indent can have several forms.  In the descriptions below, the
-     "current token" is given by the position of the indent expression
-     in the 'wisi-indent-action' argument list.
-
-     An integer
-          This gives a delta indent; it is added to the total indent for
-          the line.
-
-     A variable name
-          The name is translated to an Ada identifier by replacing "-"
-          with "_", and applying 'Camel_Case'.  The translated name must
-          identify a directly visible run-time Ada integer variable;
-          this is checked at Ada compile time.  It provides an integer
-          delta indent.
-
-          For example, in Ada two indent variable names are 'ada-indent'
-          and 'ada-indent-broken', giving the basic ident, and the
-          continuation line indent.  They are runtime variables so
-          different projects can specify them as part of a coding
-          standard.
-
-     A function call
-          A function that computes a delta indent.  See *note Indent
-          functions::.
-
-     [CODE-INDENT , COMMENT-INDENT]
-          A vector giving separate indents for code and comments.
-
-          Normally, the indent for trailing comments (on lines with no
-          code, after all code in the token) is given by the indent of
-          the following token in the production.  When the current token
-          is the last, or the following tokens may be empty, or the
-          indent of the following token would be wrong for some reason
-          (for example, it is a block end), the comment indent may be
-          specified separately.  If it is not specified, and the indent
-          from the next token is not available, the indent for the
-          current token is used for code and comments.
-
-          Comment lines that are not trailing are indented by
-          CODE-INDENT.
-
-     (label . INDENT)
-          If token labels are used in a right hand side, they must be
-          given explicitly in the indent arguments, using he lisp "cons"
-          syntax.  Labels are normally only used with EBNF grammars,
-          which expand into multiple right hand sides, with optional
-          tokens simply left out.  Explicit labels on the indent
-          arguments allow them to be left out as well.
-
-* Menu:
-
-* Indent functions::
-* Indent example::
-
-
-File: wisi.info,  Node: Indent functions,  Next: Indent example,  Up: Indent 
actions
-
-2.3.1 Indent functions
-----------------------
-
-'wisi-anchored TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET (an integer
-     expression) from the start of TOKEN (a token index); the current
-     token is "anchored to" TOKEN.
-
-'wisi-anchored* TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET from the start
-     of TOKEN, but only if TOKEN is the first token on a line; otherwise
-     no indent
-
-'wisi-anchored*- TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET from the start
-     of TOKEN, but only if TOKEN is the first token on a line and the
-     indent for the current token accumulated so far is nil.
-
-'wisi-anchored% TOKEN OFFSET'
-     If there is an opening parenthesis containing TOKEN in the line
-     containing TOKEN, set the current indent to OFFSET from that
-     parenthesis.  Otherwise, OFFSET gives an indent delta.
-
-'wisi-anchored%- TOKEN OFFSET'
-     Same as 'wisi-anchored%', but only if the current token accumulated
-     indent is nil.
-
-'wisi-hanging DELTA-1 DELTA-2'
-     The current token is assumed to be a nonterminal.  If the text it
-     contains spans multiple lines, use DELTA-1 for the first line,
-     DELTA-2 for the rest.  If the current token is only on one line,
-     use DELTA-1.
-
-     DELTA-1 and DELTA-2 can be any IDENT expression, except a variant
-     of 'wisi-hanging'.
-
-'wisi-hanging% DELTA-1 DELTA-2'
-     Similar to 'wisi-hanging'; if the first terminal token in the
-     current nonterminal is the first token on the first line, use
-     DELTA-1 for the first line and DELTA-2 for the rest.  Otherwise,
-     use DELTA-1 for all lines.
-
-'wisi-hanging%- DELTA-1 DELTA-2'
-     Same as 'wisi-hanging%', except applied only if the current token
-     accumulated indent is nil.
-
-'Language-specific function'
-     Language-specific indent functions are specified by an
-     '%elisp_indent' declaration in the grammar file.  Each function
-     specifies how many arguments it accepts; this is checked at action
-     runtime, not during grammar generation.  Each argument is an INDENT
-     as described above, or a token ID prefixed by ''' (to allow
-     distinguishing token IDs from variable names).
-
-
-File: wisi.info,  Node: Indent example,  Prev: Indent functions,  Up: Indent 
actions
-
-2.3.2 Indent example
---------------------
-
-The example 'if_statement' grammar nonterminal is:
-
-     if_statement
-       : IF expression THEN statements elsif_list ELSE statements END IF 
SEMICOLON
-         %((wisi-indent-action [nil
-                                [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                                 ada-indent-broken]
-                                nil
-                                [ada-indent ada-indent] nil nil
-                                [ada-indent ada-indent] nil nil nil]))%
-
-   We trace how the indent is computed for this sample Ada code:
-
-      1: if A < B and
-      2:   C < D
-      3:   --  comment on expression
-      4: then
-      5:    if E then
-      6:       Do_E;
-      7:       -- comment on statement
-      8:    elsif F then
-      9:       G := A + Compute_Something
-     10:         (arg_1, arg_2);
-     11:    end if;
-     12: end if;
-
-   First, the indent for the lower-level nonterminals ('expression,
-statements, elsif_list') are computed.  Assume they set the indent for
-line 10 to 2 (for the hanging expression) and leave the rest at nil.
-
-   Next, the action for the inner 'if_statement' is executed.  Most of
-the tokens specify an indent of 'nil', which means the current
-accumulated indent is not changed.  For the others, the action is as
-follows:
-
-'expression:'
-     The expression 'E' is contained on one line, and it is not the
-     first token on that line, so the indent for line 5 is not changed.
-
-'statements: [ada-indent ada-indent]'
-     This specifies separate indents for code and trailing comments,
-     because otherwise the trailing comments would be indented with the
-     following 'THEN'; instead they are indented with the expression
-     code; see the comment on line 7.
-
-     Here 'ada-indent' is 3, so the indent for lines 6 and 7 (for the
-     first occurence of 'statments') is incremented from 'nil' to '3'.
-
-     For the second occurence of 'statements', line 9 is incremented
-     from 'nil' to '3', and line 10 from '2' to '5'.
-
-   At this point, the accumulated indents are (the indent is given after
-the line number):
-      1: nil : if A < B and
-      2: nil :   C < D
-      3: nil :   --  comment on expression
-      4: nil : then
-      5: nil :    if E then
-      6:   3 :       Do_E;
-      7:   3 :       -- comment on statement
-      8: nil :    elsif F then
-      9:   3 :       G := A + Compute_Something
-     10:   5 :         (arg_1, arg_2);
-     11: nil :    end if;
-     12: nil : end if;
-
-   Then the action is executed for the outer 'if_statement':
-
-'expression: [(wisi-hanging% ada-indent-broken (* 2 ada-indent-broken)) 
ada-indent-broken]'
-     This specifies separate indents for code and trailing comments,
-     because otherwise the trailing comments would be indented with the
-     following 'THEN'; instead they are indented with the expression
-     code; see the comment on line 3.
-
-     In this case, 'wisi-hanging%' returns DELTA-1, which is
-     'ada-indent-broken', which is 2.  So the indent for line 2 is
-     incremented from 'nil' to '2'.
-
-     The indent for line 3 is also incremented from 'nil' to '2'.
-
-'statements: [ada-indent ada-indent]'
-     Here there is only one statement; the nested 'if_statement'.  The
-     indent for lines 5 ..  11 are each incremented by 3.
-
-   The final result is:
-      1: nil : if A < B and
-      2:   2 :   C < D
-      3:   2 :   --  comment on expression
-      4: nil : then
-      5:   3 :    if E then
-      6:   6 :       Do_E;
-      7:   6 :       -- comment on statement
-      8:   3 :    elsif F then
-      9:   6 :       G := A + Compute_Something
-     10:   8 :         (arg_1, arg_2);
-     11:   6 :    end if;
-     12: nil : end if;
-
-   In a full grammar, the top production should specify an indent of 0,
-not nil, for tokens that are not indented; then every line will have a
-non-nil indent.  However, in normal operation a nil indent is treated as
-0; the 'wisi-indent' text property is not set for lines that have nil
-indent, and 'wisi-indent-region' detects that and uses 0 for the indent.
-You can set the variable 'wisi-debug' to a value > 0 to signal an error
-for nil indents; this is useful to catch indent errors during grammar
-development.
-
-
-File: wisi.info,  Node: In-parse actions,  Prev: Indent actions,  Up: Grammar 
actions
-
-2.4 In-parse actions
-====================
-
-'wisi-propagate-name TOKEN'
-     The argument is a token index.  Set the 'name' component of the
-     left-hand-side parse-time token object to the 'name' component of
-     the identified token, if it is not empty.  Otherwise use the
-     'byte_region' component.
-
-'wisi-merge-name FIRST-TOKEN, LAST-TOKEN'
-     The arguments are token indices, giving a range of tokens.
-     LAST-TOKEN may be omitted if it is the same as FIRST-TOKEN.
-
-     Set the 'name' component of the left-hand-side to the merger of the
-     'name' or 'byte-region' components of the identified tokens.
-
-'wisi-match-name START-TOKEN END-TOKEN'
-     The arguments are token indices.  Compare the text contained by the
-     'name' (or 'byte_region' if 'name' is empty) token components for
-     START-TOKEN and END-TOKEN; signal a parse error if they are
-     different.
-
-     The behavior when a name is missing is determined by the runtime
-     language variable given in the '%end_names_optional_option'
-     declaration; if True, a missing name that is supposed to match a
-     present name is an error.  Both names missing is not an error
-     (assuming that is allowed by the grammar).
-
-
-File: wisi.info,  Node: Project extension,  Next: GNU Free Documentation 
License,  Prev: Grammar actions,  Up: Top
-
-3 Project extension
-*******************
-
-wisi defines the 'cl-defstuct' 'wisi-prj', with operations suitable for
-compilation and cross-reference.
-
-   In order to use wisi projects, the user must write project files and
-customize 'project-find-functions' and 'xref-backend-functions'.
-
-* Menu:
-
-* Project files::
-* Selecting projects::
-* Casing exception files::
-* Other project functions::
-
-
-File: wisi.info,  Node: Project files,  Next: Selecting projects,  Up: Project 
extension
-
-3.1 Project files
-=================
-
-Project file names must have an extension given by
-'wisi-prj-file-extensions' (default '.adp, .prj').
-
-   Project files have a simple syntax; they may be edited directly.
-Each line specifies a project variable name and its value, separated by
-"=":
-
-     src_dir=/Projects/my_project/src_1
-     src_dir=/Projects/my_project/src_2
-
-   There must be no space between the variable name and "=", and no
-trailing spaces after the value.
-
-   Any line that does not have an "=" is a comment.
-
-   Some variables (like 'src_dir') are lists; each line in the project
-file specifies one element of the list.  The value on the last line is
-the last element in the list.
-
-   A variable name that starts with '$' is set as a process environment
-variable, for processes launched from Emacs for the project.
-
-   In values, process environment variables can be referenced using the
-normal '$var' syntax.
-
-   In values, relative file names are expanded relative to the directory
-containing the project file.
-
-   Here is the list of project variables defined by wisi; major modes
-may add more.
-
-'casing' [slot: 'case-exception-files']
-     List of files containing casing exceptions.  *Note Casing exception
-     files::.
-
-'src_dir' [slot: 'source-path']
-     A list of directories to search for source files.
-
-
-File: wisi.info,  Node: Selecting projects,  Next: Casing exception files,  
Prev: Project files,  Up: Project extension
-
-3.2 Selecting projects
-======================
-
-The current project can either be indicated by a global variable (called
-a "selected project"), or depend on the current buffer.
-
-   In addition, the project file can be parsed each time it is needed,
-or the result cached to improve response time,
-
-   One reason to use a selected project is to handle a hierarchy of
-projects; if projects B and C both depend on library project A, then
-when in a file of project A, there is no way to determine which of the
-three projects to return.  So the user must indicate which is active, by
-using one of 'wisi-prj-select-file' or 'wisi-prj-select-cache'.
-
-   In addition, if changing from one project to another requires setting
-global resources that must also be unset (such as a syntax propertize
-hook or compilation filter hook), then the project should define
-'wisi-prj-deselect' in addition to 'wisi-prj-select'.  Such projects
-require having a selected current project, so it can be deselected
-before a new one is selected.  One example of such projects is ada-mode.
-
-   One way to declare each project is to add a Local Variables section
-in the main Makefile for the project; when the Makefile is first
-visited, the project is declared.  In the examples here, we assume that
-approach is used; each gives an :eval line.
-
-   Note that 'wisi-prj-current-parse' and 'wisi-prj-current-cached'
-always succeed after some project is selected; no functions after them
-on 'project-find-functions' will be called.  That's why the depth is 90
-for those in the examples.
-
-No caching, current project depends on current buffer
-
-          (add-hook 'project-find-functions #'wisi-prj-find-dominating-parse 0)
-
-          :eval (wisi-prj-set-dominating "foo.prj" (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-set-dominating' declares the name of a project file with
-     a default project object, and ensures that the current buffer file
-     name is in 'wisi-prj--dominating'.
-
-     'wisi-prj-find-dominating-parse' looks for the filenames in
-     'wisi-prj--dominiating' in the parent directories of the current
-     buffer.  When one is found, the associated project file is parsed,
-     using the default project object to dispatch to the appropriate
-     parsers.  Then the final project object is returned.
-
-Caching, current project depends on current buffer
-
-          (add-hook 'project-find-functions #'wisi-prj-find-dominating-cached 
0)
-
-          :eval (wisi-prj-cache-dominating "foo.prj" (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-cache-dominating' declares the project file, parses it,
-     and saves the project object in a cache indexed by the absolute
-     project file name.
-
-     'wisi-prj-find-dominating-cached' finds the dominating project
-     file, and retrieves the object from the cache.
-
-No caching, last selected project is current
-
-          (add-hook 'project-find-functions #'wisi-prj-current-parse 90)
-
-          :eval: (wisi-prj-select-file <prj-file> (foo-prj-default "prj-name"))
-
-     'wisi-prj-select-file' sets the project file as the current
-     project, and saves the default project object.
-
-     'wisi-prj-current-parse' parses the current project file, using the
-     saved default project object, and returns the project object.
-
-Caching, last selected project is current
-
-          (add-hook 'project-find-functions #'wisi-prj-current-cached 90)
-
-          :eval: (wisi-prj-select-cache <prj-file> (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-select-cache' parses the project file, caches the project
-     object.
-
-     'wisi-prj-current-cached' returns the cached current project
-     object.
-
-   In addition, the user should set 'xref-backend-functions'.
-Currently, there is only one choice for wisi projects:
-
-     (add-to-list 'xref-backend-functions #'wisi-prj-xref-backend 90)
-
-   'wisi-prj-xref-backend' returns the current wisi project object.
-
-
-File: wisi.info,  Node: Casing exception files,  Next: Other project 
functions,  Prev: Selecting projects,  Up: Project extension
-
-3.3 Casing exception files
-==========================
-
-Each line in a case exception file specifies the casing of one word or
-word fragment.  If an exception is defined in multiple files, the first
-occurrence is used.
-
-   If the word starts with an asterisk ('*'), it defines the casing of a
-word fragment (or "substring"); part of a word between two underscores
-or word boundary.
-
-   For example:
-
-     DOD
-     *IO
-     GNAT
-
-   The word fragment '*IO' applies to any word containing "_io";
-'Text_IO', 'Hardware_IO', etc.
-
-
-File: wisi.info,  Node: Other project functions,  Prev: Casing exception 
files,  Up: Project extension
-
-3.4 Other project functions
-===========================
-
-'wisi-refresh-prj-cache (not-full)'
-     Refreshes all cached data in the project, and re-selects the
-     project.  If NOT-FULL is non-nil, slow refresh operations are
-     skipped.
-
-     This reparses the project file, and any cross reference
-     information.
-
-'wisi-prj-select-dominating (dominating-file)'
-     Find a wisi-prj matching DOMINATING-FILE (defaults to the current
-     buffer file).  If the associated project is current, do nothing.
-     If it is not current, select it.
-
-     This is useful before running 'compilation-start', to ensure the
-     correct project is current.
-
-
-File: wisi.info,  Node: GNU Free Documentation License,  Next: Index,  Prev: 
Project extension,  Up: Top
-
-Appendix A GNU Free Documentation License
-*****************************************
-
-                     Version 1.3, 3 November 2008
-
-     Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009 Free Software 
Foundation, Inc.
-     <http://fsf.org/>
-
-     Everyone is permitted to copy and distribute verbatim copies
-     of this license document, but changing it is not allowed.
-
-  0. PREAMBLE
-
-     The purpose of this License is to make a manual, textbook, or other
-     functional and useful document "free" in the sense of freedom: to
-     assure everyone the effective freedom to copy and redistribute it,
-     with or without modifying it, either commercially or
-     noncommercially.  Secondarily, this License preserves for the
-     author and publisher a way to get credit for their work, while not
-     being considered responsible for modifications made by others.
-
-     This License is a kind of "copyleft", which means that derivative
-     works of the document must themselves be free in the same sense.
-     It complements the GNU General Public License, which is a copyleft
-     license designed for free software.
-
-     We have designed this License in order to use it for manuals for
-     free software, because free software needs free documentation: a
-     free program should come with manuals providing the same freedoms
-     that the software does.  But this License is not limited to
-     software manuals; it can be used for any textual work, regardless
-     of subject matter or whether it is published as a printed book.  We
-     recommend this License principally for works whose purpose is
-     instruction or reference.
-
-  1. APPLICABILITY AND DEFINITIONS
-
-     This License applies to any manual or other work, in any medium,
-     that contains a notice placed by the copyright holder saying it can
-     be distributed under the terms of this License.  Such a notice
-     grants a world-wide, royalty-free license, unlimited in duration,
-     to use that work under the conditions stated herein.  The
-     "Document", below, refers to any such manual or work.  Any member
-     of the public is a licensee, and is addressed as "you".  You accept
-     the license if you copy, modify or distribute the work in a way
-     requiring permission under copyright law.
-
-     A "Modified Version" of the Document means any work containing the
-     Document or a portion of it, either copied verbatim, or with
-     modifications and/or translated into another language.
-
-     A "Secondary Section" is a named appendix or a front-matter section
-     of the Document that deals exclusively with the relationship of the
-     publishers or authors of the Document to the Document's overall
-     subject (or to related matters) and contains nothing that could
-     fall directly within that overall subject.  (Thus, if the Document
-     is in part a textbook of mathematics, a Secondary Section may not
-     explain any mathematics.)  The relationship could be a matter of
-     historical connection with the subject or with related matters, or
-     of legal, commercial, philosophical, ethical or political position
-     regarding them.
-
-     The "Invariant Sections" are certain Secondary Sections whose
-     titles are designated, as being those of Invariant Sections, in the
-     notice that says that the Document is released under this License.
-     If a section does not fit the above definition of Secondary then it
-     is not allowed to be designated as Invariant.  The Document may
-     contain zero Invariant Sections.  If the Document does not identify
-     any Invariant Sections then there are none.
-
-     The "Cover Texts" are certain short passages of text that are
-     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
-     that says that the Document is released under this License.  A
-     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
-     be at most 25 words.
-
-     A "Transparent" copy of the Document means a machine-readable copy,
-     represented in a format whose specification is available to the
-     general public, that is suitable for revising the document
-     straightforwardly with generic text editors or (for images composed
-     of pixels) generic paint programs or (for drawings) some widely
-     available drawing editor, and that is suitable for input to text
-     formatters or for automatic translation to a variety of formats
-     suitable for input to text formatters.  A copy made in an otherwise
-     Transparent file format whose markup, or absence of markup, has
-     been arranged to thwart or discourage subsequent modification by
-     readers is not Transparent.  An image format is not Transparent if
-     used for any substantial amount of text.  A copy that is not
-     "Transparent" is called "Opaque".
-
-     Examples of suitable formats for Transparent copies include plain
-     ASCII without markup, Texinfo input format, LaTeX input format,
-     SGML or XML using a publicly available DTD, and standard-conforming
-     simple HTML, PostScript or PDF designed for human modification.
-     Examples of transparent image formats include PNG, XCF and JPG.
-     Opaque formats include proprietary formats that can be read and
-     edited only by proprietary word processors, SGML or XML for which
-     the DTD and/or processing tools are not generally available, and
-     the machine-generated HTML, PostScript or PDF produced by some word
-     processors for output purposes only.
-
-     The "Title Page" means, for a printed book, the title page itself,
-     plus such following pages as are needed to hold, legibly, the
-     material this License requires to appear in the title page.  For
-     works in formats which do not have any title page as such, "Title
-     Page" means the text near the most prominent appearance of the
-     work's title, preceding the beginning of the body of the text.
-
-     The "publisher" means any person or entity that distributes copies
-     of the Document to the public.
-
-     A section "Entitled XYZ" means a named subunit of the Document
-     whose title either is precisely XYZ or contains XYZ in parentheses
-     following text that translates XYZ in another language.  (Here XYZ
-     stands for a specific section name mentioned below, such as
-     "Acknowledgements", "Dedications", "Endorsements", or "History".)
-     To "Preserve the Title" of such a section when you modify the
-     Document means that it remains a section "Entitled XYZ" according
-     to this definition.
-
-     The Document may include Warranty Disclaimers next to the notice
-     which states that this License applies to the Document.  These
-     Warranty Disclaimers are considered to be included by reference in
-     this License, but only as regards disclaiming warranties: any other
-     implication that these Warranty Disclaimers may have is void and
-     has no effect on the meaning of this License.
-
-  2. VERBATIM COPYING
-
-     You may copy and distribute the Document in any medium, either
-     commercially or noncommercially, provided that this License, the
-     copyright notices, and the license notice saying this License
-     applies to the Document are reproduced in all copies, and that you
-     add no other conditions whatsoever to those of this License.  You
-     may not use technical measures to obstruct or control the reading
-     or further copying of the copies you make or distribute.  However,
-     you may accept compensation in exchange for copies.  If you
-     distribute a large enough number of copies you must also follow the
-     conditions in section 3.
-
-     You may also lend copies, under the same conditions stated above,
-     and you may publicly display copies.
-
-  3. COPYING IN QUANTITY
-
-     If you publish printed copies (or copies in media that commonly
-     have printed covers) of the Document, numbering more than 100, and
-     the Document's license notice requires Cover Texts, you must
-     enclose the copies in covers that carry, clearly and legibly, all
-     these Cover Texts: Front-Cover Texts on the front cover, and
-     Back-Cover Texts on the back cover.  Both covers must also clearly
-     and legibly identify you as the publisher of these copies.  The
-     front cover must present the full title with all words of the title
-     equally prominent and visible.  You may add other material on the
-     covers in addition.  Copying with changes limited to the covers, as
-     long as they preserve the title of the Document and satisfy these
-     conditions, can be treated as verbatim copying in other respects.
-
-     If the required texts for either cover are too voluminous to fit
-     legibly, you should put the first ones listed (as many as fit
-     reasonably) on the actual cover, and continue the rest onto
-     adjacent pages.
-
-     If you publish or distribute Opaque copies of the Document
-     numbering more than 100, you must either include a machine-readable
-     Transparent copy along with each Opaque copy, or state in or with
-     each Opaque copy a computer-network location from which the general
-     network-using public has access to download using public-standard
-     network protocols a complete Transparent copy of the Document, free
-     of added material.  If you use the latter option, you must take
-     reasonably prudent steps, when you begin distribution of Opaque
-     copies in quantity, to ensure that this Transparent copy will
-     remain thus accessible at the stated location until at least one
-     year after the last time you distribute an Opaque copy (directly or
-     through your agents or retailers) of that edition to the public.
-
-     It is requested, but not required, that you contact the authors of
-     the Document well before redistributing any large number of copies,
-     to give them a chance to provide you with an updated version of the
-     Document.
-
-  4. MODIFICATIONS
-
-     You may copy and distribute a Modified Version of the Document
-     under the conditions of sections 2 and 3 above, provided that you
-     release the Modified Version under precisely this License, with the
-     Modified Version filling the role of the Document, thus licensing
-     distribution and modification of the Modified Version to whoever
-     possesses a copy of it.  In addition, you must do these things in
-     the Modified Version:
-
-       A. Use in the Title Page (and on the covers, if any) a title
-          distinct from that of the Document, and from those of previous
-          versions (which should, if there were any, be listed in the
-          History section of the Document).  You may use the same title
-          as a previous version if the original publisher of that
-          version gives permission.
-
-       B. List on the Title Page, as authors, one or more persons or
-          entities responsible for authorship of the modifications in
-          the Modified Version, together with at least five of the
-          principal authors of the Document (all of its principal
-          authors, if it has fewer than five), unless they release you
-          from this requirement.
-
-       C. State on the Title page the name of the publisher of the
-          Modified Version, as the publisher.
-
-       D. Preserve all the copyright notices of the Document.
-
-       E. Add an appropriate copyright notice for your modifications
-          adjacent to the other copyright notices.
-
-       F. Include, immediately after the copyright notices, a license
-          notice giving the public permission to use the Modified
-          Version under the terms of this License, in the form shown in
-          the Addendum below.
-
-       G. Preserve in that license notice the full lists of Invariant
-          Sections and required Cover Texts given in the Document's
-          license notice.
-
-       H. Include an unaltered copy of this License.
-
-       I. Preserve the section Entitled "History", Preserve its Title,
-          and add to it an item stating at least the title, year, new
-          authors, and publisher of the Modified Version as given on the
-          Title Page.  If there is no section Entitled "History" in the
-          Document, create one stating the title, year, authors, and
-          publisher of the Document as given on its Title Page, then add
-          an item describing the Modified Version as stated in the
-          previous sentence.
-
-       J. Preserve the network location, if any, given in the Document
-          for public access to a Transparent copy of the Document, and
-          likewise the network locations given in the Document for
-          previous versions it was based on.  These may be placed in the
-          "History" section.  You may omit a network location for a work
-          that was published at least four years before the Document
-          itself, or if the original publisher of the version it refers
-          to gives permission.
-
-       K. For any section Entitled "Acknowledgements" or "Dedications",
-          Preserve the Title of the section, and preserve in the section
-          all the substance and tone of each of the contributor
-          acknowledgements and/or dedications given therein.
-
-       L. Preserve all the Invariant Sections of the Document, unaltered
-          in their text and in their titles.  Section numbers or the
-          equivalent are not considered part of the section titles.
-
-       M. Delete any section Entitled "Endorsements".  Such a section
-          may not be included in the Modified Version.
-
-       N. Do not retitle any existing section to be Entitled
-          "Endorsements" or to conflict in title with any Invariant
-          Section.
-
-       O. Preserve any Warranty Disclaimers.
-
-     If the Modified Version includes new front-matter sections or
-     appendices that qualify as Secondary Sections and contain no
-     material copied from the Document, you may at your option designate
-     some or all of these sections as invariant.  To do this, add their
-     titles to the list of Invariant Sections in the Modified Version's
-     license notice.  These titles must be distinct from any other
-     section titles.
-
-     You may add a section Entitled "Endorsements", provided it contains
-     nothing but endorsements of your Modified Version by various
-     parties--for example, statements of peer review or that the text
-     has been approved by an organization as the authoritative
-     definition of a standard.
-
-     You may add a passage of up to five words as a Front-Cover Text,
-     and a passage of up to 25 words as a Back-Cover Text, to the end of
-     the list of Cover Texts in the Modified Version.  Only one passage
-     of Front-Cover Text and one of Back-Cover Text may be added by (or
-     through arrangements made by) any one entity.  If the Document
-     already includes a cover text for the same cover, previously added
-     by you or by arrangement made by the same entity you are acting on
-     behalf of, you may not add another; but you may replace the old
-     one, on explicit permission from the previous publisher that added
-     the old one.
-
-     The author(s) and publisher(s) of the Document do not by this
-     License give permission to use their names for publicity for or to
-     assert or imply endorsement of any Modified Version.
-
-  5. COMBINING DOCUMENTS
-
-     You may combine the Document with other documents released under
-     this License, under the terms defined in section 4 above for
-     modified versions, provided that you include in the combination all
-     of the Invariant Sections of all of the original documents,
-     unmodified, and list them all as Invariant Sections of your
-     combined work in its license notice, and that you preserve all
-     their Warranty Disclaimers.
-
-     The combined work need only contain one copy of this License, and
-     multiple identical Invariant Sections may be replaced with a single
-     copy.  If there are multiple Invariant Sections with the same name
-     but different contents, make the title of each such section unique
-     by adding at the end of it, in parentheses, the name of the
-     original author or publisher of that section if known, or else a
-     unique number.  Make the same adjustment to the section titles in
-     the list of Invariant Sections in the license notice of the
-     combined work.
-
-     In the combination, you must combine any sections Entitled
-     "History" in the various original documents, forming one section
-     Entitled "History"; likewise combine any sections Entitled
-     "Acknowledgements", and any sections Entitled "Dedications".  You
-     must delete all sections Entitled "Endorsements."
-
-  6. COLLECTIONS OF DOCUMENTS
-
-     You may make a collection consisting of the Document and other
-     documents released under this License, and replace the individual
-     copies of this License in the various documents with a single copy
-     that is included in the collection, provided that you follow the
-     rules of this License for verbatim copying of each of the documents
-     in all other respects.
-
-     You may extract a single document from such a collection, and
-     distribute it individually under this License, provided you insert
-     a copy of this License into the extracted document, and follow this
-     License in all other respects regarding verbatim copying of that
-     document.
-
-  7. AGGREGATION WITH INDEPENDENT WORKS
-
-     A compilation of the Document or its derivatives with other
-     separate and independent documents or works, in or on a volume of a
-     storage or distribution medium, is called an "aggregate" if the
-     copyright resulting from the compilation is not used to limit the
-     legal rights of the compilation's users beyond what the individual
-     works permit.  When the Document is included in an aggregate, this
-     License does not apply to the other works in the aggregate which
-     are not themselves derivative works of the Document.
-
-     If the Cover Text requirement of section 3 is applicable to these
-     copies of the Document, then if the Document is less than one half
-     of the entire aggregate, the Document's Cover Texts may be placed
-     on covers that bracket the Document within the aggregate, or the
-     electronic equivalent of covers if the Document is in electronic
-     form.  Otherwise they must appear on printed covers that bracket
-     the whole aggregate.
-
-  8. TRANSLATION
-
-     Translation is considered a kind of modification, so you may
-     distribute translations of the Document under the terms of section
-     4.  Replacing Invariant Sections with translations requires special
-     permission from their copyright holders, but you may include
-     translations of some or all Invariant Sections in addition to the
-     original versions of these Invariant Sections.  You may include a
-     translation of this License, and all the license notices in the
-     Document, and any Warranty Disclaimers, provided that you also
-     include the original English version of this License and the
-     original versions of those notices and disclaimers.  In case of a
-     disagreement between the translation and the original version of
-     this License or a notice or disclaimer, the original version will
-     prevail.
-
-     If a section in the Document is Entitled "Acknowledgements",
-     "Dedications", or "History", the requirement (section 4) to
-     Preserve its Title (section 1) will typically require changing the
-     actual title.
-
-  9. TERMINATION
-
-     You may not copy, modify, sublicense, or distribute the Document
-     except as expressly provided under this License.  Any attempt
-     otherwise to copy, modify, sublicense, or distribute it is void,
-     and will automatically terminate your rights under this License.
-
-     However, if you cease all violation of this License, then your
-     license from a particular copyright holder is reinstated (a)
-     provisionally, unless and until the copyright holder explicitly and
-     finally terminates your license, and (b) permanently, if the
-     copyright holder fails to notify you of the violation by some
-     reasonable means prior to 60 days after the cessation.
-
-     Moreover, your license from a particular copyright holder is
-     reinstated permanently if the copyright holder notifies you of the
-     violation by some reasonable means, this is the first time you have
-     received notice of violation of this License (for any work) from
-     that copyright holder, and you cure the violation prior to 30 days
-     after your receipt of the notice.
-
-     Termination of your rights under this section does not terminate
-     the licenses of parties who have received copies or rights from you
-     under this License.  If your rights have been terminated and not
-     permanently reinstated, receipt of a copy of some or all of the
-     same material does not give you any rights to use it.
-
-  10. FUTURE REVISIONS OF THIS LICENSE
-
-     The Free Software Foundation may publish new, revised versions of
-     the GNU Free Documentation License from time to time.  Such new
-     versions will be similar in spirit to the present version, but may
-     differ in detail to address new problems or concerns.  See
-     <http://www.gnu.org/copyleft/>.
-
-     Each version of the License is given a distinguishing version
-     number.  If the Document specifies that a particular numbered
-     version of this License "or any later version" applies to it, you
-     have the option of following the terms and conditions either of
-     that specified version or of any later version that has been
-     published (not as a draft) by the Free Software Foundation.  If the
-     Document does not specify a version number of this License, you may
-     choose any version ever published (not as a draft) by the Free
-     Software Foundation.  If the Document specifies that a proxy can
-     decide which future versions of this License can be used, that
-     proxy's public statement of acceptance of a version permanently
-     authorizes you to choose that version for the Document.
-
-  11. RELICENSING
-
-     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
-     World Wide Web server that publishes copyrightable works and also
-     provides prominent facilities for anybody to edit those works.  A
-     public wiki that anybody can edit is an example of such a server.
-     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
-     site means any set of copyrightable works thus published on the MMC
-     site.
-
-     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
-     license published by Creative Commons Corporation, a not-for-profit
-     corporation with a principal place of business in San Francisco,
-     California, as well as future copyleft versions of that license
-     published by that same organization.
-
-     "Incorporate" means to publish or republish a Document, in whole or
-     in part, as part of another Document.
-
-     An MMC is "eligible for relicensing" if it is licensed under this
-     License, and if all works that were first published under this
-     License somewhere other than this MMC, and subsequently
-     incorporated in whole or in part into the MMC, (1) had no cover
-     texts or invariant sections, and (2) were thus incorporated prior
-     to November 1, 2008.
-
-     The operator of an MMC Site may republish an MMC contained in the
-     site under CC-BY-SA on the same site at any time before August 1,
-     2009, provided the MMC is eligible for relicensing.
-
-ADDENDUM: How to use this License for your documents
-====================================================
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and license
-notices just after the title page:
-
-       Copyright (C)  YEAR  YOUR NAME.
-       Permission is granted to copy, distribute and/or modify this document
-       under the terms of the GNU Free Documentation License, Version 1.3
-       or any later version published by the Free Software Foundation;
-       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
-       Texts.  A copy of the license is included in the section entitled ``GNU
-       Free Documentation License''.
-
-   If you have Invariant Sections, Front-Cover Texts and Back-Cover
-Texts, replace the "with...Texts."  line with this:
-
-         with the Invariant Sections being LIST THEIR TITLES, with
-         the Front-Cover Texts being LIST, and with the Back-Cover Texts
-         being LIST.
-
-   If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-   If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of free
-software license, such as the GNU General Public License, to permit
-their use in free software.
-
-
-File: wisi.info,  Node: Index,  Prev: GNU Free Documentation License,  Up: Top
-
-Index
-*****
-
-
-
-Tag Table:
-Node: Top920
-Node: Overview1119
-Node: Grammar actions1761
-Node: Navigate actions7174
-Node: Face actions10027
-Node: Indent actions11338
-Node: Indent functions15148
-Node: Indent example17443
-Node: In-parse actions21781
-Node: Project extension23077
-Node: Project files23586
-Node: Selecting projects25006
-Node: Casing exception files29008
-Node: Other project functions29666
-Node: GNU Free Documentation License30424
-Node: Index55580
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/packages/wisi/wisi.texi b/packages/wisi/wisi.texi
deleted file mode 100644
index 3a7d3b3..0000000
--- a/packages/wisi/wisi.texi
+++ /dev/null
@@ -1,812 +0,0 @@
-\input texinfo  @c -*-texinfo-*-
-@settitle Wisi
-
-@copying
-Copyright @copyright{} 1999 - 2020  Free Software Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below.  A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.  Buying copies from the FSF supports it in
-developing GNU and promoting software freedom.''
-@end quotation
-@end copying
-
-@dircategory Emacs
-@direntry
-* Wisi: (wisi).         Error-correcting LR parsers and project integration.
-@end direntry
-
-@titlepage
-@sp 10
-@title Wisi Version 3.1.2
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top
-@top Top
-
-Wisi Version 3.1.2
-@end ifnottex
-
-@menu
-* Overview::
-* Grammar actions::
-* Project extension::
-* GNU Free Documentation License::
-* Index::
-@end menu
-
-@node Overview
-@chapter Overview
-``wisi'' used to be an acronym, but now it's just a name.
-
-The wisi package provides an elisp interface to an external parser. It
-assumes the parser generator package WisiToken
-(@url{http://stephe-leake.org/ada/wisitoken.html}, implemented in
-Ada), but can use any parser that meets the same API. wisi provides
-several grammar actions, to implement indentation, navigating, and
-syntax highlighting (fontification).
-
-wisi also provides an extension to Emacs @file{project.el}, providing
-operations useful for compilation and cross-reference.
-
-@node Grammar actions
-@chapter Grammar Actions
-
-Grammar actions are specified in the grammar file, in a nonterminal
-declaration. We assume the user is familiar with parser grammars and
-grammar actions. For example, a simple ``if'' statement can be
-declared as:
-
-@example
-if_statement
-  : IF expression THEN statements elsif_list ELSE statements END IF SEMICOLON
-    %((wisi-statement-action [1 statement-start 3 motion 6 motion 10 
statement-end])
-      (wisi-motion-action [1 3 5 6 10])
-      (wisi-indent-action [nil
-                           [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                            ada-indent-broken]
-                           nil
-                           [ada-indent ada-indent] nil nil
-                           [ada-indent ada-indent] nil nil nil]))%
-@end example
-
-The item before @code{:} is the ``left hand side'', or
-``nonterminal''. The list of tokens after @code{:} is the ``right hand
-side''; in general there can be more than one right hand side for each
-nonterminal (separated by @code{|}).
-
-The items enclosed in ``%()%'' are the grammar actions. They are
-specified as list of elisp forms; an earlier version of the wisi
-package generated an elisp parser. We keep the elisp form because it
-is compact, and easier to read and write than the equivalent Ada
-code. The @code{wisi-bnf-generate} tool converts the elisp into the
-required Ada statements.
-
-There are two classes of actions; in-parse and post-parse. WisiToken
-calls these ``semantic checks'' and ``user actions''. The in-parse
-actions are done as parsing procedes; they provide extra checks that
-can cause the parse to fail. Currently the only one provided is
-@code{match-names}; it is used to check that the declaration and end
-names in named Ada blocks are the same (which can aid significantly in
-error correction). In the grammar file, in-parse actions are specified
-in a second @code{%()%} block, which can be omitted if empty. In this
-document, the term ``action'' means ``post-parse action'', we use
-``in-parse action'' unless the meaning is clear from context.
-
-Executing the wisi grammar actions creates text properties in the
-source file; those text properties are then used by elisp code for
-various purposes.
-
-The text properties applied are:
-
-@table @code
-@item wisi-cache
-This should be named @code{wisi-navigate}, but isn't for historical
-reasons (there used to be only one kind of text property).
-
-The property contains a @code{wisi-cache} object, containing:
-
-@table @code
-@item nonterm
-The nonterminal in the grammar production that specified the action
-that produced this text property.
-
-@item token
-A token identifier naming a token in the production right hand side
-containing the text this text property is applied to.
-
-@item last
-The position of the last character in the token, relative to the first
-character (0 indexed). The text property is only applied to the first
-character in the token (mostly for historical reasons).
-
-@item class
-A token class; see the list of possible values in
-@code{wisi-statement-action} below.
-
-@item containing
-A marker pointing to the start of the containing token for this token;
-only @code{nil} for the outermost containing token in a file.
-
-@item prev
-A marker pointing to the previous ``motion token'' in the statement or
-declaration. These are normally language keywords, but can be other
-things.
-
-@item next
-A marker pointing to the next ``motion token'' in the statement or
-declaration.
-
-@item end
-A marker pointing to the end of the statement or declaration.
-
-@end table
-
-wisi provides motion commands for going to the various markers.
-
-@item wisi-name
-Contains no data, applied to a ``name'' of some sort. wisi provides
-commands for finding the next/previous name, and returning the
-text. Useful for the names of subprograms, which can then be used to
-build a completion table; see @code{wisi-xref-identifier-completion-table}.
-
-@item font-lock-face
-The standard font-lock property, specifying the face for the
-text.
-
-Some major modes do not use this for simple keywords; they use
-font-lock regular expressions instead. One reason for this
-is so keywords are still highlighted when the parser fails, which
-can happen if there are severe syntax errors.
-
-Other items, like function and package names, are typically marked
-with @code{font-lock-face} by the parser.
-
-@item fontified
-Another standard font-lock text property; applied whenever
-@code{font-lock-face} is.
-
-@item wisi-indent
-Contains the indent (in characters) for the next line; applied to
-the newline character on the preceding line. The first line in a
-buffer is assumed to have indent 0.
-
-@end table
-
-Each action is classified as one of @code{navigate, face, indent,
-in-parse}; when actions are executed, only one of the first three classes
-is executed (in-parse is always executed). This reflects the reasons
-the parser is run; to figure out how to go somehere (end of current
-statement, start of current procedure, etc), to apply faces for syntax
-highlighting, or to indent the code.
-
-@menu
-* Navigate actions::
-* Face actions::
-* Indent actions::
-* In-parse actions::
-@end menu
-
-@node Navigate actions
-@section Navigate actions
-@table @code
-@item wisi-statement-action [TOKEN CLASS ...]
-The argument is a vector; alternating items are a token index (an
-integer or label indicating a token in the right hand side) and a
-``token class''; one of:
-
-@table @code
-@item motion
-Create a @code{wisi-cache} text property on the token, for use in a
-subsequent @code{wisi-motion-action}.
-
-@item statement-end
-Create a @code{wisi-cache} text property on the token, enter a pointer
-to it in the other @code{wisi-cache} objects in the statement or
-declaration.
-
-@item statement-start
-Create a @code{wisi-cache} text property on the token, enter a pointer
-to it in the other @code{wisi-cache} objects (in the @code{containing}
-slot) in the statement or declaration.
-
-@item statement-override
-Same as @code{statement-start}; marks the token to be used as the
-statement start if the first token is optional.
-
-@item misc
-Create a @code{wisi-cache} text property on the token, to be used for
-some other purpose. It is good style to indicate the purpose in a
-comment.
-
-For example, ada-mode uses a 'misc' property on left parentheses that
-start a subprogram parameter list; this distinquishes them from other
-left parentheses, and makes it possible to automatically call
-@code{ada-format-paramlist} to format the
-parameter list, instead of using the standard Emacs @code{align}.
-
-@end table
-
-@item wisi-motion-action [TOKEN ...]
-The argument is a vector, where each element is either a token index
-or a vector [INDEX ID].
-
-Each terminal token must already have a @code{wisi-cache} created by a
-@code{wisi-statement-action} (this is checked at action execution, not
-during grammar generation). This action sets the @code{prev, next}
-slots for the chain of tokens, creating a chain of motion tokens.
-
-If TOKEN is a nonterminal without an ID specified, the @code{wisi-cache}
-must be on the first token in the nonterminal, and it is assumed to
-have a valid pointer in the @code{next} slot, indicating a chain of
-motion tokens. That chain is linked into the chain for the current
-right hand side.
-
-If TOKEN is a nonterminal with an ID, the region contained by the
-nonterminal is searched for all @code{wisi-cache} with that token ID,
-and for each one where prev/next is not already set, it is linked into
-the motion chain.
-
-Note that the ``search'' described here is done in the parser process, on
-a tree data structure containing the data that will eventually be
-stored in Emacs text properties.
-
-@item wisi-name-action TOKEN
-TOKEN is a token index. Create a @code{wisi-name} text property on the
-token.
-
-@end table
-
-@node Face actions
-@section Face actions
-@table @code
-@item wisi-face-mark-action [INDEX CLASS ...]
-The argument is a vector; alternating elements form pairs of INDEX
-CLASS, where class is one of @code{prefix, suffix}.
-
-Mark the tokens as part of a compound name, for use by later face
-actions.
-
-@item wisi-face-apply-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]
-The argument is a vector; triples of items specify TOKEN,
-PREFIX-FACE, SUFFIX-FACE. The faces are the elisp names of face
-objects (which must declared by an @code{%elisp_face} declaration).
-
-If the token is a nonterminal, and it has been marked by a previous
-@code{wisi-face-mark-action}, the specified faces are applied to the
-prefix and suffix in the token as @code{font-lock-face} text
-properties.
-
-If the token is a terminal, or a non-terminal with no face mark, the
-suffix face is applied to the entire text contained by the token.
-
-@item wisi-face-apply-list-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]
-Similar to ’wisi-face-apply-action’, but applies faces to all tokens
-marked by @code{wisi-face-mark-action} in each indicated production
-token, and does not apply a face if there are no such marks.
-
-@end table
-
-@node Indent actions
-@section Indent actions
-
-Indents are computed for each line in a cumulative way as the grammar
-actions are executed. Initially, each indent is set to @code{nil},
-which means ``not computed''; this is not the same as the value
-@code{0}. The grammar actions are executed in a bottom-up fashion; low
-level productions are executed before higher level ones. In general,
-the indent action for a production specifies a ``delta indent''; the
-indent is incremented by that amount. When all productions have been
-processed, the indent has been computed for all lines.
-
-Indents are often given as a function call; the arguments to the
-function can be other function calls, or integer
-expressions. @code{wisitoken-bnf-generate} supports only simple integer
-expressions; those using integers, integer-valued variables,
-parenthesis, + (plus), - (minus), and * (multiply).
-
-@table @code
-@item wisi-indent-action [INDENT ...]
-The argument is a vector, giving an indent for each token in the
-production right-hand side.
-
-For terminals, the indents only have meaning, and are only computed,
-if the token is the first on a line. For nonterminals where the indent
-is not a variant of @code{wisi-hanging}, the indent is only computed
-if the first terminal token in the nonterminal is the first on a
-line. See @code{wisi-hanging} in @ref{Indent functions} for the
-remaining case.
-
-An indent can have several forms.  In the descriptions below, the
-``current token'' is given by the position of the indent expression in
-the @code{wisi-indent-action} argument list.
-
-@table @asis
-@item An integer
-This gives a delta indent; it is added to the total indent for the
-line.
-
-@item A variable name
-The name is translated to an Ada identifier by replacing ``-'' with
-``_'', and applying @code{Camel_Case}. The translated name must
-identify a directly visible run-time Ada integer variable; this is
-checked at Ada compile time. It provides an integer delta indent.
-
-For example, in Ada two indent variable names are @code{ada-indent}
-and @code{ada-indent-broken}, giving the basic ident, and the
-continuation line indent. They are runtime variables so different
-projects can specify them as part of a coding standard.
-
-@item A function call
-A function that computes a delta indent. See @ref{Indent functions}.
-
-@item [CODE-INDENT , COMMENT-INDENT]
-A vector giving separate indents for code and comments.
-
-Normally, the indent for trailing comments (on lines with no code,
-after all code in the token) is given by the indent of the following
-token in the production. When the current token is the last, or the
-following tokens may be empty, or the indent of the following token
-would be wrong for some reason (for example, it is a block end), the
-comment indent may be specified separately. If it is not specified,
-and the indent from the next token is not available, the indent for
-the current token is used for code and comments.
-
-Comment lines that are not trailing are indented by CODE-INDENT.
-
-@item (label . INDENT)
-If token labels are used in a right hand side, they must be given
-explicitly in the indent arguments, using he lisp ``cons''
-syntax. Labels are normally only used with EBNF grammars, which expand
-into multiple right hand sides, with optional tokens simply left
-out. Explicit labels on the indent arguments allow them to be left out
-as well.
-
-@end table
-
-@end table
-
-@menu
-* Indent functions::
-* Indent example::
-@end menu
-
-@node Indent functions
-@subsection Indent functions
-@table @code
-@item wisi-anchored TOKEN OFFSET
-Sets the indent for the current token to be OFFSET (an integer
-expression) from the start of TOKEN (a token index); the
-current token is ``anchored to'' TOKEN.
-
-@item wisi-anchored* TOKEN OFFSET
-Sets the indent for the current token to be OFFSET from the start of
-TOKEN, but only if TOKEN is the first token on a line; otherwise no indent
-
-@item wisi-anchored*- TOKEN OFFSET
-Sets the indent for the current token to be OFFSET from the start of
-TOKEN, but only if TOKEN is the first token on a line and the indent
-for the current token accumulated so far is nil.
-
-@item wisi-anchored% TOKEN OFFSET
-If there is an opening parenthesis containing TOKEN in the line
-containing TOKEN, set the current indent to OFFSET from that
-parenthesis. Otherwise, OFFSET gives an indent delta.
-
-@item wisi-anchored%- TOKEN OFFSET
-Same as @code{wisi-anchored%}, but only if the current token
-accumulated indent is nil.
-
-@item wisi-hanging DELTA-1 DELTA-2
-The current token is assumed to be a nonterminal. If the text it
-contains spans multiple lines, use DELTA-1 for the first line, DELTA-2
-for the rest. If the current token is only on one line, use DELTA-1.
-
-DELTA-1 and DELTA-2 can be any IDENT expression, except a variant of
-@code{wisi-hanging}.
-
-@item wisi-hanging% DELTA-1 DELTA-2
-Similar to @code{wisi-hanging}; if the first terminal token in the
-current nonterminal is the first token on the first line, use DELTA-1
-for the first line and DELTA-2 for the rest. Otherwise, use DELTA-1
-for all lines.
-
-@item wisi-hanging%- DELTA-1 DELTA-2
-Same as @code{wisi-hanging%}, except applied only if the current token
-accumulated indent is nil.
-
-@item Language-specific function
-Language-specific indent functions are specified by an
-@code{%elisp_indent} declaration in the grammar file. Each function
-specifies how many arguments it accepts; this is checked at action
-runtime, not during grammar generation. Each argument is an INDENT as
-described above, or a token ID prefixed by @code{'} (to allow
-distinguishing token IDs from variable names).
-@end table
-
-@node Indent example
-@subsection Indent example
-
-The example @code{if_statement} grammar nonterminal is:
-
-@example
-if_statement
-  : IF expression THEN statements elsif_list ELSE statements END IF SEMICOLON
-    %((wisi-indent-action [nil
-                           [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                            ada-indent-broken]
-                           nil
-                           [ada-indent ada-indent] nil nil
-                           [ada-indent ada-indent] nil nil nil]))%
-@end example
-
-We trace how the indent is computed for this sample Ada code:
-
-@example
- 1: if A < B and
- 2:   C < D
- 3:   --  comment on expression
- 4: then
- 5:    if E then
- 6:       Do_E;
- 7:       -- comment on statement
- 8:    elsif F then
- 9:       G := A + Compute_Something
-10:         (arg_1, arg_2);
-11:    end if;
-12: end if;
-@end example
-
-First, the indent for the lower-level nonterminals (@code{expression,
-statements, elsif_list}) are computed. Assume they set the indent for
-line 10 to 2 (for the hanging expression) and leave the rest at nil.
-
-Next, the action for the inner @code{if_statement} is executed. Most
-of the tokens specify an indent of @code{nil}, which means the current
-accumulated indent is not changed. For the others, the action is as
-follows:
-
-@table @code
-@item expression:
-The expression @code{E} is contained on one line, and it is not the
-first token on that line, so the indent for line 5 is not changed.
-
-@item statements: [ada-indent ada-indent]
-This specifies separate indents for code and trailing comments,
-because otherwise the trailing comments would be indented with the
-following @code{THEN}; instead they are indented with the expression
-code; see the comment on line 7.
-
-Here @code{ada-indent} is 3, so the indent for lines 6 and 7 (for the
-first occurence of @code{statments}) is
-incremented from @code{nil} to @code{3}.
-
-For the second occurence of @code{statements}, line 9 is incremented
-from @code{nil} to @code{3}, and line 10 from @code{2} to @code{5}.
-@end table
-
-At this point, the accumulated indents are (the indent is given after
-the line number):
-@example
- 1: nil : if A < B and
- 2: nil :   C < D
- 3: nil :   --  comment on expression
- 4: nil : then
- 5: nil :    if E then
- 6:   3 :       Do_E;
- 7:   3 :       -- comment on statement
- 8: nil :    elsif F then
- 9:   3 :       G := A + Compute_Something
-10:   5 :         (arg_1, arg_2);
-11: nil :    end if;
-12: nil : end if;
-@end example
-
-Then the action is executed for the outer @code{if_statement}:
-
-@table @code
-@item expression: [(wisi-hanging% ada-indent-broken (* 2 ada-indent-broken)) 
ada-indent-broken]
-This specifies separate indents for code and trailing comments,
-because otherwise the trailing comments would be indented with the
-following @code{THEN}; instead they are indented with the expression
-code; see the comment on line 3.
-
-In this case, @code{wisi-hanging%} returns DELTA-1, which is
-@code{ada-indent-broken}, which is 2. So the indent for line 2 is
-incremented from @code{nil} to @code{2}.
-
-The indent for line 3 is also incremented from @code{nil} to @code{2}.
-
-@item statements: [ada-indent ada-indent]
-Here there is only one statement; the nested @code{if_statement}. The
-indent for lines 5 .. 11 are each incremented by 3.
-@end table
-
-The final result is:
-@example
- 1: nil : if A < B and
- 2:   2 :   C < D
- 3:   2 :   --  comment on expression
- 4: nil : then
- 5:   3 :    if E then
- 6:   6 :       Do_E;
- 7:   6 :       -- comment on statement
- 8:   3 :    elsif F then
- 9:   6 :       G := A + Compute_Something
-10:   8 :         (arg_1, arg_2);
-11:   6 :    end if;
-12: nil : end if;
-@end example
-
-In a full grammar, the top production should specify an indent of 0,
-not nil, for tokens that are not indented; then every line will have a
-non-nil indent. However, in normal operation a nil indent is treated
-as 0; the @code{wisi-indent} text property is not set for lines that
-have nil indent, and @code{wisi-indent-region} detects that and uses 0
-for the indent. You can set the variable @code{wisi-debug} to a value
-> 0 to signal an error for nil indents; this is useful to catch indent
-errors during grammar development.
-
-@node In-parse actions
-@section In-parse actions
-@table @code
-
-@item wisi-propagate-name TOKEN
-The argument is a token index. Set the @code{name} component of the
-left-hand-side parse-time token object to the @code{name} component of
-the identified token, if it is not empty. Otherwise use the
-@code{byte_region} component.
-
-@item wisi-merge-name FIRST-TOKEN, LAST-TOKEN
-The arguments are token indices, giving a range of
-tokens. LAST-TOKEN may be omitted if it is the same as FIRST-TOKEN.
-
-Set the @code{name} component of the left-hand-side to the merger of
-the @code{name} or @code{byte-region} components of the identified tokens.
-
-@item wisi-match-name START-TOKEN END-TOKEN
-The arguments are token indices. Compare the text contained by the
-@code{name} (or @code{byte_region} if @code{name} is empty) token
-components for START-TOKEN and END-TOKEN; signal a parse error if they
-are different.
-
-The behavior when a name is missing is determined by the runtime
-language variable given in the @code{%end_names_optional_option}
-declaration; if True, a missing name that is supposed to match a
-present name is an error. Both names missing is not an error (assuming
-that is allowed by the grammar).
-
-@end table
-
-@node Project extension
-@chapter Project extension
-wisi defines the @code{cl-defstuct} @code{wisi-prj}, with operations
-suitable for compilation and cross-reference.
-
-In order to use wisi projects, the user must write project files and
-customize @code{project-find-functions} and
-@code{xref-backend-functions}.
-
-@menu
-* Project files::
-* Selecting projects::
-* Casing exception files::
-* Other project functions::
-@end menu
-
-@node Project files
-@section Project files
-
-Project file names must have an extension given by
-@code{wisi-prj-file-extensions} (default @file{.adp, .prj}).
-
-Project files have a simple syntax; they may be edited directly. Each
-line specifies a project variable name and its value, separated by
-``='':
-
-@example
-src_dir=/Projects/my_project/src_1
-src_dir=/Projects/my_project/src_2
-@end example
-
-There must be no space between the variable name and ``='', and no
-trailing spaces after the value.
-
-Any line that does not have an ``='' is a comment.
-
-Some variables (like @code{src_dir}) are lists; each line in the
-project file specifies one element of the list. The value on the last
-line is the last element in the list.
-
-A variable name that starts with @code{$} is set as a process
-environment variable, for processes launched from Emacs for the
-project.
-
-In values, process environment variables can be referenced
-using the normal @code{$var} syntax.
-
-In values, relative file names are expanded relative to the
-directory containing the project file.
-
-Here is the list of project variables defined by wisi; major modes may
-add more.
-
-@table @asis
-@item @code{casing}         [slot: @code{case-exception-files}]
-List of files containing casing exceptions. @xref{Casing exception files}.
-
-@item @code{src_dir}        [slot: @code{source-path}]
-A list of directories to search for source files.
-
-@end table
-
-@node Selecting projects
-@section Selecting projects
-The current project can either be indicated by a global variable
-(called a ``selected project''), or depend on the current buffer.
-
-In addition, the project file can be parsed each time it is needed, or
-the result cached to improve response time,
-
-One reason to use a selected project is to handle a hierarchy of
-projects; if projects B and C both depend on library project A, then
-when in a file of project A, there is no way to determine which of the
-three projects to return. So the user must indicate which is active,
-by using one of @code{wisi-prj-select-file} or
-@code{wisi-prj-select-cache}.
-
-In addition, if changing from one project to another requires setting
-global resources that must also be unset (such as a syntax propertize
-hook or compilation filter hook), then the project should define
-@code{wisi-prj-deselect} in addition to @code{wisi-prj-select}. Such
-projects require having a selected current project, so it can be
-deselected before a new one is selected. One example of such projects
-is ada-mode.
-
-One way to declare each project is to add a Local Variables section
-in the main Makefile for the project; when the Makefile is first
-visited, the project is declared. In the examples here, we assume
-that approach is used; each gives an :eval line.
-
-Note that @code{wisi-prj-current-parse} and
-@code{wisi-prj-current-cached} always succeed after some project is
-selected; no functions after them on @code{project-find-functions} will
-be called. That's why the depth is 90 for those in the examples.
-
-@table @asis
-@item No caching, current project depends on current buffer
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-find-dominating-parse 0)
-
-:eval (wisi-prj-set-dominating "foo.prj" (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-set-dominating} declares the name of a project file with a
-default project object, and ensures that the current buffer file name
-is in @code{wisi-prj--dominating}.
-
-@code{wisi-prj-find-dominating-parse} looks for the filenames in
-@code{wisi-prj--dominiating} in the parent directories of the current
-buffer. When one is found, the associated project file is parsed,
-using the default project object to dispatch to the appropriate
-parsers. Then the final project object is returned.
-
-@item Caching, current project depends on current buffer
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-find-dominating-cached 0)
-
-:eval (wisi-prj-cache-dominating "foo.prj" (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-cache-dominating} declares the project file, parses it,
-and saves the project object in a cache indexed by the absolute
-project file name.
-
-@code{wisi-prj-find-dominating-cached} finds the dominating
-project file, and retrieves the object from the cache.
-
-@item No caching, last selected project is current
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-current-parse 90)
-
-:eval: (wisi-prj-select-file <prj-file> (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-select-file} sets the project file as the current
-project, and saves the default project object.
-
-@code{wisi-prj-current-parse} parses the current project file, using
-the saved default project object, and returns the project object.
-
-@item Caching, last selected project is current
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-current-cached 90)
-
-:eval: (wisi-prj-select-cache <prj-file> (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-select-cache} parses the project file, caches the
-project object.
-
-@code{wisi-prj-current-cached} returns the cached current project
-object.
-
-@end table
-
-In addition, the user should set @code{xref-backend-functions}. Currently,
-there is only one choice for wisi projects:
-
-@example
-(add-to-list 'xref-backend-functions #'wisi-prj-xref-backend 90)
-@end example
-
-@code{wisi-prj-xref-backend} returns the current wisi project object.
-
-@node Casing exception files
-@section Casing exception files
-Each line in a case exception
-file specifies the casing of one word or word fragment. If an
-exception is defined in multiple files, the first occurrence is used.
-
-If the word starts with an asterisk (@code{*}), it defines the casing
-of a word fragment (or ``substring''); part of a word between two
-underscores or word boundary.
-
-For example:
-
-@example
-DOD
-*IO
-GNAT
-@end example
-
-The word fragment @code{*IO} applies to any word containing ``_io'';
-@code{Text_IO}, @code{Hardware_IO}, etc.
-
-@node Other project functions
-@section Other project functions
-
-@table @code
-@item wisi-refresh-prj-cache (not-full)
-Refreshes all cached data in the project, and re-selects the
-project. If NOT-FULL is non-nil, slow refresh operations are skipped.
-
-This reparses the project file, and any cross reference information.
-
-@item wisi-prj-select-dominating (dominating-file)
-  Find a wisi-prj matching DOMINATING-FILE (defaults to the current
-buffer file). If the associated project is current, do nothing. If it
-is not current, select it.
-
-This is useful before running `compilation-start', to ensure the correct
-project is current.
-
-@end table
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@node Index,  , GNU Free Documentation License, Top
-@unnumbered Index
-
-@printindex fn
-
-@bye
diff --git a/packages/wisi/wisitoken-bnf-generate.adb 
b/packages/wisi/wisitoken-bnf-generate.adb
deleted file mode 100644
index 821ef6f..0000000
--- a/packages/wisi/wisitoken-bnf-generate.adb
+++ /dev/null
@@ -1,634 +0,0 @@
---  Abstract :
---
---  Parser for Wisi grammar files, producing Ada source
---  files for a parser.
---
---  Copyright (C) 2012 - 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Fixed;
-with Ada.Strings.Maps;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.BNF.Output_Ada;
-with WisiToken.BNF.Output_Ada_Common;
-with WisiToken.BNF.Output_Ada_Emacs;
-with WisiToken.BNF.Output_Elisp_Common;
-with WisiToken.Generate.LR.LALR_Generate;
-with WisiToken.Generate.LR.LR1_Generate;
-with WisiToken.Generate.Packrat;
-with WisiToken.Parse.LR.Parser_No_Recover; -- for reading BNF file
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-with WisiToken.Text_IO_Trace;
-with WisiToken_Grammar_Runtime;
-with Wisitoken_Grammar_Actions;
-with Wisitoken_Grammar_Main;
-procedure WisiToken.BNF.Generate
-is
-   procedure Put_Usage
-   is
-      use Ada.Text_IO;
-      First : Boolean := True;
-   begin
-      Put_Line (Standard_Error, "version 2.1"); -- matches release version in 
Docs/wisitoken.html
-      Put_Line (Standard_Error, "wisitoken-bnf-generate [options] {wisi 
grammar file}");
-      Put_Line (Standard_Error, "Generate source code implementing a parser 
for the grammar.");
-      New_Line (Standard_Error);
-      Put_Line (Standard_Error, "The following grammar file directives control 
parser generation:");
-      Put_Line (Standard_Error,
-                "%generate <algorithm> <output language> [<lexer>] 
[<interface>] [text_rep]");
-      Put_Line (Standard_Error, "   specify one of each generate parameter. 
May be repeated.");
-      Put (Standard_Error, "   algorithm: ");
-      for I of Generate_Algorithm_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-
-      Put (Standard_Error, "   output language: ");
-      First := True;
-      for I of Output_Language_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-
-      Put_Line (Standard_Error, "   interface: interface Process | Module");
-      Put_Line (Standard_Error, "      only valid with Ada_Emacs:");
-      Put_Line (Standard_Error, "      Process is for an external subprocess 
communicating with Emacs.");
-      Put_Line (Standard_Error, "      Module  is for a dynamically loaded 
Emacs module.");
-      Put (Standard_Error, "   lexer: ");
-      First := True;
-      for I of Output_Language_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-      Put_Line
-        (Standard_Error, "   text_rep: output LR parse table in a text file, 
not as source code; for large tables");
-
-      New_Line (Standard_Error);
-      Put_Line (Standard_Error, "options:");
-      Put_Line (Standard_Error, "  --help: show this help");
-
-      --  verbosity meaning is actually determined by output choice;
-      --  they should be consistent with this description.
-      Put_Line
-        (Standard_Error, "  -v <EBNF level> <Table level> <Minimal_Complete 
level>: sets verbosity (default 0):");
-      Put_Line (Standard_Error, "     0 - only error messages to standard 
error");
-      Put_Line (Standard_Error, "     1 - add diagnostics to standard out");
-      Put_Line (Standard_Error, "     2 - more diagnostics to standard out, 
ignore unused tokens, unknown conflicts");
-      Put_Line (Standard_Error, "  --generate ...: override grammar file 
%generate directive");
-      Put_Line (Standard_Error, "  --output_bnf <file_name> : output 
translated BNF source to file_name");
-      Put_Line (Standard_Error, "  --suffix <string>; appended to grammar file 
name");
-      Put_Line (Standard_Error, "  --ignore_conflicts; ignore excess/unknown 
conflicts");
-      Put_Line (Standard_Error,
-                "  --test_main; generate standalone main program for running 
the generated parser, modify file names");
-      Put_Line (Standard_Error, "  --time; output execution time of various 
stages");
-
-   end Put_Usage;
-
-   Language_Name         : Ada.Strings.Unbounded.Unbounded_String; -- The 
language the grammar defines
-   Output_File_Name_Root : Ada.Strings.Unbounded.Unbounded_String;
-   Suffix                : Ada.Strings.Unbounded.Unbounded_String;
-   BNF_File_Name         : Ada.Strings.Unbounded.Unbounded_String;
-   Output_BNF            : Boolean := False;
-   Ignore_Conflicts      : Boolean := False;
-   Test_Main             : Boolean := False;
-
-   Command_Generate_Set : Generate_Set_Access; -- override grammar file 
declarations
-
-   Trace          : aliased WisiToken.Text_IO_Trace.Trace 
(Wisitoken_Grammar_Actions.Descriptor'Access);
-   Input_Data     : aliased WisiToken_Grammar_Runtime.User_Data_Type;
-   Grammar_Parser : WisiToken.Parse.LR.Parser_No_Recover.Parser;
-
-   procedure Use_Input_File (File_Name : in String)
-   is
-      use Ada.Strings.Unbounded;
-      use Ada.Text_IO;
-   begin
-      Output_File_Name_Root := +Ada.Directories.Base_Name (File_Name) & Suffix;
-
-      Wisitoken_Grammar_Main.Create_Parser
-        (Parser    => Grammar_Parser,
-         Trace     => Trace'Unchecked_Access,
-         User_Data => Input_Data'Unchecked_Access);
-
-      Grammar_Parser.Lexer.Reset_With_File (File_Name);
-
-      declare
-         Language_Name_Dir   : constant Integer := Ada.Strings.Fixed.Index
-           (File_Name, Ada.Strings.Maps.To_Set ("/\"), Going => 
Ada.Strings.Backward);
-         Language_Name_Ext   : constant Integer := Ada.Strings.Fixed.Index 
(File_Name, ".wy");
-      begin
-         Language_Name := +WisiToken.BNF.Output_Elisp_Common.Elisp_Name_To_Ada
-           (File_Name
-              ((if Language_Name_Dir = 0
-                then File_Name'First
-                else Language_Name_Dir + 1) ..
-                 Language_Name_Ext - 1),
-            Append_ID => False,
-            Trim      => 0);
-      end;
-   exception
-   when Name_Error | Use_Error =>
-      raise Name_Error with "input file '" & File_Name & "' could not be 
opened.";
-   end Use_Input_File;
-
-begin
-   declare
-      use Ada.Command_Line;
-      Arg_Next : Integer := 1;
-   begin
-      loop
-         exit when Argument (Arg_Next)(1) /= '-';
-
-         --   --help, -v first, then alphabetical
-
-         if Argument (Arg_Next) = "--help" then
-            Put_Usage;
-            return;
-
-         elsif Argument (Arg_Next) = "-v" then
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_EBNF := Integer'Value (Argument 
(Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_Table := Integer'Value (Argument 
(Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_Minimal_Complete := Integer'Value 
(Argument (Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--ignore_conflicts" then
-            Ignore_Conflicts := True;
-            Arg_Next         := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--generate" then
-            Arg_Next  := Arg_Next + 1;
-            declare
-               Tuple : Generate_Tuple;
-               Done  : Boolean := False;
-            begin
-               begin
-                  Tuple.Gen_Alg := Generate_Algorithm'Value (Argument 
(Arg_Next));
-                  Arg_Next     := Arg_Next + 1;
-               exception
-               when Constraint_Error =>
-                  raise User_Error with "invalid value for 
generator_algorithm: '" & Argument (Arg_Next) & ";";
-               end;
-               if Tuple.Gen_Alg /= None then
-                  begin
-                     Tuple.Out_Lang := To_Output_Language (Argument 
(Arg_Next));
-                     Arg_Next       := Arg_Next + 1;
-                  end;
-
-                  loop
-                     exit when Done;
-                     declare
-                        Text : constant String := Argument (Arg_Next);
-                     begin
-                        if Text = "text_rep" then
-                           Tuple.Text_Rep := True;
-                           Arg_Next := Arg_Next + 1;
-
-                        elsif (for some I of Lexer_Image => To_Lower (Text) =  
I.all) then
-                           Tuple.Lexer := To_Lexer (Text);
-                           Arg_Next := Arg_Next + 1;
-
-                        elsif (for some I in Valid_Interface =>
-                                 To_Lower (Text) = To_Lower 
(Valid_Interface'Image (I)))
-                        then
-                           Tuple.Interface_Kind := 
WisiToken.BNF.Valid_Interface'Value (Text);
-                           Arg_Next := Arg_Next + 1;
-
-                        else
-                           Done := True;
-                        end if;
-                     end;
-                  end loop;
-               end if;
-               Add (Command_Generate_Set, Tuple);
-            end;
-
-         elsif Argument (Arg_Next) = "--output_bnf" then
-            Output_BNF    := True;
-            Arg_Next      := Arg_Next + 1;
-            BNF_File_Name := +Argument (Arg_Next);
-            Arg_Next      := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--suffix" then
-            Arg_Next := Arg_Next + 1;
-            Suffix   := +Argument (Arg_Next);
-            Arg_Next := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--test_main" then
-            Arg_Next  := Arg_Next + 1;
-            Test_Main := True;
-
-         elsif Argument (Arg_Next) = "--time" then
-            Arg_Next := Arg_Next + 1;
-            WisiToken.Trace_Time := True;
-
-         else
-            raise User_Error with "invalid argument '" & Argument (Arg_Next) & 
"'";
-         end if;
-      end loop;
-
-      Use_Input_File (Argument (Arg_Next));
-
-      if Arg_Next /= Argument_Count then
-         raise User_Error with "arg count" & Integer'Image (Argument_Count) &
-           " different from expected count" & Integer'Image (Arg_Next);
-      end if;
-   end;
-
-   begin
-      Grammar_Parser.Parse;
-   exception
-   when WisiToken.Syntax_Error =>
-      Grammar_Parser.Put_Errors;
-      raise;
-   when E : WisiToken.Parse_Error =>
-      WisiToken.Generate.Put_Error (Ada.Exceptions.Exception_Message (E));
-      raise;
-   end;
-
-   declare
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-      use Ada.Text_IO;
-
-      Generate_Set    : Generate_Set_Access;
-      Multiple_Tuples : Boolean;
-
-      Lexer_Done : Lexer_Set := (others => False);
-
-      --  In general, all of the data in Generate_Utils.Generate_Data
-      --  depends on the generate tuple parameters. However, if
-      --  'If_Lexer_Present' is false, then they don't depend on the lexer,
-      --  and if 'If_Parser_Present' is false, then they don't depend on the
-      --  Gen_Alg, except for the parser table. But it's not worth trying to
-      --  cache results in those cases; they only happen in test grammars,
-      --  which are small.
-
-      procedure Parse_Check
-        (Lexer  : in Lexer_Type;
-         Parser : in Generate_Algorithm;
-         Phase  : in WisiToken_Grammar_Runtime.Action_Phase)
-      is
-         use all type Ada.Containers.Count_Type;
-         use all type WisiToken_Grammar_Runtime.Action_Phase;
-         use all type WisiToken_Grammar_Runtime.Meta_Syntax;
-      begin
-         Input_Data.User_Parser := Parser;
-         Input_Data.User_Lexer  := Lexer;
-         --  Specifying the parser and lexer can change the parsed grammar, due
-         --  to %if {parser | lexer}.
-
-         Input_Data.Reset; -- only resets Other data
-
-         Input_Data.Phase := Phase;
-         Grammar_Parser.Execute_Actions;
-
-         case Phase is
-         when Meta =>
-            case Input_Data.Meta_Syntax is
-            when Unknown =>
-               Input_Data.Meta_Syntax := BNF_Syntax;
-
-            when BNF_Syntax =>
-               null;
-
-            when EBNF_Syntax =>
-               declare
-                  Tree  : WisiToken.Syntax_Trees.Tree renames 
Grammar_Parser.Parsers.First_State_Ref.Tree;
-               begin
-                  if Trace_Generate_EBNF > Outline then
-                     Ada.Text_IO.Put_Line ("Translate EBNF tree to BNF");
-                  end if;
-
-                  if Trace_Generate_EBNF > Detail then
-                     Ada.Text_IO.Put_Line ("EBNF tree:");
-                     Tree.Print_Tree
-                       (Wisitoken_Grammar_Actions.Descriptor,
-                        Image_Action => 
WisiToken_Grammar_Runtime.Image_Grammar_Action'Access);
-                  end if;
-
-                  WisiToken_Grammar_Runtime.Translate_EBNF_To_BNF (Tree, 
Input_Data);
-
-                  if Trace_Generate_EBNF > Detail then
-                     Ada.Text_IO.New_Line;
-                     Ada.Text_IO.Put_Line ("BNF tree:");
-                     Tree.Print_Tree
-                       (Wisitoken_Grammar_Actions.Descriptor,
-                        Image_Action => 
WisiToken_Grammar_Runtime.Image_Grammar_Action'Access);
-                  end if;
-
-                  if Output_BNF then
-                     WisiToken_Grammar_Runtime.Print_Source (-BNF_File_Name, 
Tree, Input_Data);
-                  end if;
-
-                  if WisiToken.Generate.Error then
-                     raise WisiToken.Grammar_Error with "errors during 
translating EBNF to BNF: aborting";
-                  end if;
-               end;
-            end case;
-
-         when Other =>
-            if Input_Data.Rule_Count = 0 or Input_Data.Tokens.Rules.Length = 0 
then
-               raise WisiToken.Grammar_Error with "no rules";
-            end if;
-         end case;
-      exception
-      when E : WisiToken.Syntax_Error | WisiToken.Parse_Error =>
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, 
Ada.Exceptions.Exception_Message (E));
-         Grammar_Parser.Put_Errors;
-         raise;
-      end Parse_Check;
-
-   begin
-      --  Get the the input file quads, translate EBNF
-      Parse_Check (None, None, WisiToken_Grammar_Runtime.Meta);
-
-      if Command_Generate_Set = null then
-         if Input_Data.Generate_Set = null then
-            raise User_Error with
-              WisiToken.Generate.Error_Message
-                (Input_Data.Grammar_Lexer.File_Name, 1,
-                 "generate algorithm, output_language, lexer, interface not 
specified");
-         end if;
-
-         Generate_Set := Input_Data.Generate_Set;
-      else
-         Generate_Set := Command_Generate_Set;
-      end if;
-
-      Multiple_Tuples := Generate_Set'Length > 1;
-
-      for Tuple of Generate_Set.all loop
-         Parse_Check
-           (Lexer  => Tuple.Lexer,
-            Parser => Tuple.Gen_Alg,
-            Phase  => WisiToken_Grammar_Runtime.Other);
-
-         declare
-            use Ada.Real_Time;
-
-            Time_Start : Time;
-            Time_End   : Time;
-
-            Generate_Data : aliased WisiToken.BNF.Generate_Utils.Generate_Data 
:=
-              WisiToken.BNF.Generate_Utils.Initialize (Input_Data, 
Ignore_Conflicts);
-
-            Packrat_Data : WisiToken.Generate.Packrat.Data
-              (Generate_Data.Descriptor.First_Terminal, 
Generate_Data.Descriptor.First_Nonterminal,
-               Generate_Data.Descriptor.Last_Nonterminal);
-
-            Parse_Table_File_Name : constant String :=
-              (if WisiToken.Trace_Generate_Table = 0 and Tuple.Gen_Alg in LALR 
.. Packrat_Proc
-               then -Output_File_Name_Root & "_" & To_Lower 
(Generate_Algorithm'Image (Tuple.Gen_Alg)) &
-                 (if Input_Data.If_Lexer_Present
-                  then "_" & Lexer_Image (Input_Data.User_Lexer).all
-                  else "") &
-                  ".parse_table"
-               else "");
-
-            procedure Parse_Table_Append_Stats
-            is
-               Parse_Table_File : File_Type;
-            begin
-               Open (Parse_Table_File, Append_File, Parse_Table_File_Name);
-               Set_Output (Parse_Table_File);
-               Generate_Data.Parser_State_Count :=
-                 Generate_Data.LR_Parse_Table.State_Last - 
Generate_Data.LR_Parse_Table.State_First + 1;
-               WisiToken.BNF.Generate_Utils.Put_Stats (Input_Data, 
Generate_Data);
-               Set_Output (Standard_Output);
-               Close (Parse_Table_File);
-            end Parse_Table_Append_Stats;
-
-         begin
-            if not Lexer_Done (Input_Data.User_Lexer) then
-               Lexer_Done (Input_Data.User_Lexer) := True;
-               case Input_Data.User_Lexer is
-               when re2c_Lexer =>
-                  WisiToken.BNF.Output_Ada_Common.Create_re2c
-                    (Input_Data, Tuple, Generate_Data, -Output_File_Name_Root);
-               when others =>
-                  null;
-               end case;
-            end if;
-
-            case Tuple.Gen_Alg is
-            when None =>
-               --  Just translate EBNF to BNF, done in Parse_Check
-               null;
-
-            when LALR =>
-
-               Time_Start := Clock;
-
-               if Generate_Data.Grammar 
(Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
-                  WisiToken.Generate.Put_Error
-                    (WisiToken.Generate.Error_Message
-                       (Grammar_Parser.Lexer.File_Name, 1,
-                        "%start token not specified or not found; no LALR 
parse table generated"));
-               else
-                  Generate_Data.LR_Parse_Table := 
WisiToken.Generate.LR.LALR_Generate.Generate
-                    (Generate_Data.Grammar,
-                     Generate_Data.Descriptor.all,
-                     Generate_Utils.To_Conflicts
-                       (Generate_Data, Input_Data.Conflicts, 
Input_Data.Grammar_Lexer.File_Name),
-                     Generate_Utils.To_McKenzie_Param (Generate_Data, 
Input_Data.McKenzie_Recover),
-                     Parse_Table_File_Name,
-                     Include_Extra     => Test_Main,
-                     Ignore_Conflicts  => Ignore_Conflicts,
-                     Partial_Recursion => 
Input_Data.Language_Params.Partial_Recursion);
-
-                  if WisiToken.Trace_Time then
-                     Time_End := Clock;
-
-                     Put_Line
-                       (Standard_Error,
-                        "LALR " & Lexer_Image (Tuple.Lexer).all & " generate 
time:" &
-                          Duration'Image (To_Duration (Time_End - 
Time_Start)));
-                  end if;
-
-                  if Parse_Table_File_Name /= "" then
-                     Parse_Table_Append_Stats;
-                  end if;
-               end if;
-
-            when LR1 =>
-               Time_Start := Clock;
-
-               if Generate_Data.Grammar 
(Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
-                  WisiToken.Generate.Put_Error
-                    (WisiToken.Generate.Error_Message
-                       (Grammar_Parser.Lexer.File_Name, 1,
-                        "%start token not specified or not found; no LALR 
parse table generated"));
-               else
-                  Generate_Data.LR_Parse_Table := 
WisiToken.Generate.LR.LR1_Generate.Generate
-                    (Generate_Data.Grammar,
-                     Generate_Data.Descriptor.all,
-                     Generate_Utils.To_Conflicts
-                       (Generate_Data, Input_Data.Conflicts, 
Input_Data.Grammar_Lexer.File_Name),
-                     Generate_Utils.To_McKenzie_Param (Generate_Data, 
Input_Data.McKenzie_Recover),
-                     Parse_Table_File_Name,
-                     Include_Extra     => Test_Main,
-                     Ignore_Conflicts  => Ignore_Conflicts,
-                     Partial_Recursion => 
Input_Data.Language_Params.Partial_Recursion);
-
-                  if Trace_Time then
-                     Time_End := Clock;
-
-                     Put_Line
-                       (Standard_Error,
-                        "LR1 " & Lexer_Image (Tuple.Lexer).all & " generate 
time:" &
-                          Duration'Image (To_Duration (Time_End - 
Time_Start)));
-                  end if;
-
-                  if Parse_Table_File_Name /= "" then
-                     Parse_Table_Append_Stats;
-                  end if;
-               end if;
-
-            when Packrat_Generate_Algorithm =>
-               --  The only significant computation done for Packrat is First, 
done
-               --  in Initialize; not worth timing.
-
-               Packrat_Data := WisiToken.Generate.Packrat.Initialize
-                 (Input_Data.Grammar_Lexer.File_Name, Generate_Data.Grammar, 
Generate_Data.Source_Line_Map,
-                  Generate_Data.Descriptor.First_Terminal);
-
-               if Parse_Table_File_Name /= "" then
-                  declare
-                     Parse_Table_File : File_Type;
-                  begin
-                     Create (Parse_Table_File, Out_File, 
Parse_Table_File_Name);
-                     Set_Output (Parse_Table_File);
-                     Put_Line ("Tokens:");
-                     WisiToken.Put_Tokens (Generate_Data.Descriptor.all);
-                     New_Line;
-                     Put_Line ("Productions:");
-                     WisiToken.Productions.Put (Generate_Data.Grammar, 
Generate_Data.Descriptor.all);
-                     Set_Output (Standard_Output);
-                     Close (Parse_Table_File);
-                  end;
-               end if;
-
-               Packrat_Data.Check_All (Generate_Data.Descriptor.all);
-
-            when External =>
-               null;
-            end case;
-
-            if WisiToken.Generate.Error then
-               raise WisiToken.Grammar_Error with "errors: aborting";
-            end if;
-
-            case Tuple.Gen_Alg is
-            when LR_Generate_Algorithm =>
-               if Tuple.Text_Rep then
-                  WisiToken.Generate.LR.Put_Text_Rep
-                    (Generate_Data.LR_Parse_Table.all,
-                     -Output_File_Name_Root & "_" &
-                       To_Lower (Generate_Algorithm_Image (Tuple.Gen_Alg).all) 
&
-                       "_parse_table.txt",
-                     Generate_Data.Action_Names.all, 
Generate_Data.Check_Names.all);
-               end if;
-
-            when others =>
-               null;
-            end case;
-
-            if Tuple.Gen_Alg /= None then
-               case Tuple.Out_Lang is
-               when Ada_Lang =>
-                  WisiToken.BNF.Output_Ada
-                    (Input_Data, -Output_File_Name_Root, Generate_Data, 
Packrat_Data, Tuple, Test_Main,
-                     Multiple_Tuples);
-
-               when Ada_Emacs_Lang =>
-                  WisiToken.BNF.Output_Ada_Emacs
-                    (Input_Data, -Output_File_Name_Root, Generate_Data, 
Packrat_Data, Tuple,
-                     Test_Main, Multiple_Tuples, -Language_Name);
-
-               end case;
-               if WisiToken.Generate.Error then
-                  raise WisiToken.Grammar_Error with "errors: aborting";
-               end if;
-            end if;
-         end;
-      end loop;
-   end;
-exception
-when WisiToken.Syntax_Error | WisiToken.Parse_Error =>
-   --  error message already output
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-
-when E : User_Error =>
-   declare
-      use Ada.Command_Line;
-      use Ada.Exceptions;
-      use Ada.Text_IO;
-   begin
-      Put_Line (Standard_Error, Exception_Message (E));
-      Put_Command_Line (Ada_Comment);
-      Set_Exit_Status (Failure);
-      Put_Usage;
-   end;
-
-when E : WisiToken.Grammar_Error =>
-   --  error message not already output
-   declare
-      use Ada.Command_Line;
-      use Ada.Exceptions;
-      use Ada.Text_IO;
-   begin
-      Put_Line (Standard_Error, Exception_Message (E));
-      Set_Exit_Status (Failure);
-   end;
-
-when E :  others =>
-   --  IMPROVEME: for some exceptions, Error message already output via 
wisi.utils.Put_Error
-   declare
-      use Ada.Text_IO;
-      use Ada.Exceptions;
-      use Ada.Command_Line;
-   begin
-      Put_Line (Standard_Error, Exception_Name (E) & ": " & Exception_Message 
(E));
-      Put_Line (Standard_Error, GNAT.Traceback.Symbolic.Symbolic_Traceback 
(E));
-      Set_Exit_Status (Failure);
-   end;
-
-end WisiToken.BNF.Generate;
diff --git a/packages/wisi/wisitoken-bnf-generate_grammar.adb 
b/packages/wisi/wisitoken-bnf-generate_grammar.adb
deleted file mode 100644
index cd165c4..0000000
--- a/packages/wisi/wisitoken-bnf-generate_grammar.adb
+++ /dev/null
@@ -1,86 +0,0 @@
---  Abstract :
---
---  Output Ada source code to recreate Grammar.
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO; use Ada.Text_IO;
-with WisiToken.Generate;
-with WisiToken.Productions;
-procedure WisiToken.BNF.Generate_Grammar
-  (Grammar      : in WisiToken.Productions.Prod_Arrays.Vector;
-   Action_Names : in WisiToken.Names_Array_Array)
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings.Unbounded;
-   use WisiToken.Generate;
-   use WisiToken.Productions;
-   Text : Unbounded_String;
-   Need_Comma : Boolean := False;
-begin
-   Indent_Line
-     ("Grammar.Set_First_Last (" & Trimmed_Image (Grammar.First_Index) & ", " &
-        Trimmed_Image (Grammar.Last_Index) & ");");
-
-   for Prod of Grammar loop
-      Indent_Line ("declare");
-      Indent_Line ("   Prod : Instance;");
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-      Indent_Line ("Prod.LHS := " & Trimmed_Image (Prod.LHS) & ";");
-      Indent_Line ("Prod.RHSs.Set_First_Last (0, " & Trimmed_Image 
(Prod.RHSs.Last_Index) & ");");
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Right_Hand_Side renames Prod.RHSs (RHS_Index);
-         begin
-            Indent_Line ("declare");
-            Indent_Line ("   RHS : Right_Hand_Side;");
-            Indent_Line ("begin");
-            Indent := Indent + 3;
-            if RHS.Tokens.Length > 0 then
-               Indent_Line
-                 ("RHS.Tokens.Set_First_Last (1, " & Trimmed_Image (Prod.RHSs 
(RHS_Index).Tokens.Last_Index) & ");");
-
-               if RHS.Tokens.Length = 1 then
-                  Indent_Line ("To_Vector ((1 => " & Trimmed_Image (RHS.Tokens 
(1)) & "), RHS.Tokens);");
-               else
-                  Need_Comma := False;
-                  Text := +"To_Vector ((";
-                  for ID of RHS.Tokens  loop
-                     if Need_Comma then
-                        Text := Text & ", ";
-                     else
-                        Need_Comma := True;
-                     end if;
-                     Text := Text & Trimmed_Image (ID);
-                  end loop;
-                  Text := Text & "), RHS.Tokens);";
-                  Indent_Wrap (-Text);
-               end if;
-            end if;
-            if Action_Names (Prod.LHS) /= null and then Action_Names 
(Prod.LHS)(RHS_Index) /= null then
-               Indent_Line ("RHS.Action     := " & Action_Names 
(Prod.LHS)(RHS_Index).all & "'Access;");
-            end if;
-            Indent_Line ("Prod.RHSs (" & Trimmed_Image (RHS_Index) & ") := 
RHS;");
-            Indent := Indent - 3;
-            Indent_Line ("end;");
-         end;
-      end loop;
-      Indent_Line ("Grammar (" & Trimmed_Image (Prod.LHS) & ") := Prod;");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-   end loop;
-end WisiToken.BNF.Generate_Grammar;
diff --git a/packages/wisi/wisitoken-bnf-generate_packrat.adb 
b/packages/wisi/wisitoken-bnf-generate_packrat.adb
deleted file mode 100644
index b4592e5..0000000
--- a/packages/wisi/wisitoken-bnf-generate_packrat.adb
+++ /dev/null
@@ -1,333 +0,0 @@
---  Abstract :
---
---  Generate Ada code for a Packrat parser.
---
---  References:
---
---  See wisitoken-parse-packrat.ads.
---
---  Copyright (C) 2018, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO; use Ada.Text_IO;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.Generate.Packrat;
-with WisiToken.Productions;
-procedure WisiToken.BNF.Generate_Packrat
-  (Data          : in WisiToken.Generate.Packrat.Data;
-   Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-is
-   use WisiToken.Generate;
-
-   Descriptor   : WisiToken.Descriptor renames Generate_Data.Descriptor.all;
-   Action_Names : Names_Array_Array renames Generate_Data.Action_Names.all;
-
-   subtype Terminal is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-
-   --  FIXME: optimize memoizing? small productions not worth the memory cost?
-   --  or just use langkit space optimization.
-
-   function Parser_Name (Nonterm : in Token_ID) return String
-   is begin
-      return "Parse_" & Image (Nonterm, Descriptor);
-   end Parser_Name;
-
-   procedure Put_Parser_Spec (Name : in String)
-   is begin
-      Indent_Line ("function " & Name);
-      Indent_Start ("  (Parser : in out Generated.Parser; Last_Pos : in 
Base_Token_Index) return Result_Type");
-   end Put_Parser_Spec;
-
-   function Var_Suffix (I, J : in Integer) return String
-   is begin
-      return Trimmed_Image (I) & '_' & Trimmed_Image (J);
-   end Var_Suffix;
-
-   procedure Generate_Parser_Body (Prod : in Productions.Instance)
-   is
-      use all type Ada.Containers.Count_Type;
-
-      Result_ID : constant String := Trimmed_Image (Prod.LHS);
-   begin
-      --  We use gotos and function scope vars rather than nested if/declare
-      --  to avoid excessive indenting for long productions.
-
-      Put_Parser_Spec (Parser_Name (Prod.LHS)); New_Line;
-      Indent_Line ("is");
-      Indent := Indent + 3;
-
-      Indent_Line ("Descriptor : WisiToken.Descriptor renames 
Parser.Trace.Descriptor.all;");
-      Indent_Line ("Start_Pos  : constant Token_Index := Last_Pos + 1; --  
first token in current nonterm");
-      Indent_Line ("Pos        : Base_Token_Index := Last_Pos; --  last token 
parsed.");
-
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Productions.Right_Hand_Side renames Prod.RHSs (RHS_Index);
-         begin
-            for Token_Index in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index 
loop
-               if RHS.Tokens (Token_Index) in Descriptor.First_Terminal .. 
Descriptor.Last_Terminal then
-                  Indent_Line ("Pos_" & Var_Suffix (RHS_Index, Token_Index) & 
"  : Token_Index;");
-               else
-                  Indent_Line ("Memo_" & Var_Suffix (RHS_Index, Token_Index) & 
" : Memo_Entry;");
-               end if;
-            end loop;
-         end;
-      end loop;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("Pos_Recurse_Last : Base_Token_Index := Last_Pos;");
-         Indent_Line ("Result_Recurse   : Memo_Entry;");
-      end if;
-
-      Indent := Indent - 3;
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-
-      Indent_Line ("if Pos = Parser.Terminals.Last_Index then");
-      Indent_Line ("   return (State => Failure);");
-      Indent_Line ("end if;");
-      Indent_Line ("declare");
-      Indent_Line ("   Memo : Memo_Entry renames Parser.Derivs (" & Result_ID 
& ")(Start_Pos);");
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-      Indent_Line ("case Memo.State is");
-      Indent_Line ("when Success =>");
-      Indent_Line ("   return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      Indent_Line ("when Failure =>");
-
-      --  FIXME: Could simplify this when not doing left recursion
-      Indent_Line ("   goto RHS_" & Trimmed_Image (Prod.RHSs.Last_Index) & 
"_Fail;");
-
-      Indent_Line ("when No_Result =>");
-      Indent_Line ("   if Memo.Recursive then");
-      Indent_Start ("      raise Recursive with Image (" & Result_ID & ", 
Descriptor) &");
-      Put_Line (" Token_Index'Image (Start_Pos) & "": recursive"";");
-      Indent_Line ("   end if;");
-      Indent_Line ("   Memo.Recursive := True;");
-      Indent_Line ("end case;");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-      New_Line;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         --  This is the top of the 'while' loop in [warth 2008] figure 3 
Grow-LR.
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, (State => Failure));");
-         Indent_Line ("<<Recurse_Start>>");
-      end if;
-
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Productions.Right_Hand_Side renames Prod.RHSs (RHS_Index);
-
-            procedure Finish
-            is begin
-               if Data.Direct_Left_Recursive (Prod.LHS) then
-                  Indent_Line ("Result_Recurse :=");
-                  Indent := Indent + 2;
-               else
-                  Indent_Line ("Parser.Derivs (" & Result_ID & 
").Replace_Element");
-                  Indent_Line ("  (Start_Pos,");
-                  Indent := Indent + 3;
-               end if;
-               Indent_Line ("(State              => Success,");
-               Indent_Line (" Result             => Parser.Tree.Add_Nonterm");
-
-               Indent := Indent + 3;
-               Indent_Line ("(Production      => (" & Result_ID & ", " & 
Trimmed_Image (RHS_Index) & "),");
-               Indent_Line
-                 (" Action          => " &
-                    (if Action_Names (Prod.LHS) = null or else Action_Names 
(Prod.LHS)(RHS_Index) = null
-                     then "null,"
-                     else Action_Names (Prod.LHS)(RHS_Index).all & 
"'Access,"));
-
-               if RHS.Tokens.Length = 0 then
-                  Indent_Line (" Children        => (1 .. 0 => 
Invalid_Node_Index),");
-
-               elsif RHS.Tokens.Length = 1 then
-                  Indent_Start (" Children        => ");
-                  if RHS.Tokens (RHS.Tokens.First_Index) in Terminal then
-                     Put ("(1 => Tree_Index (Pos_" & Var_Suffix (RHS_Index, 
RHS.Tokens.First_Index) & ")),");
-                  else
-                     Put ("(1 => Memo_" & Var_Suffix (RHS_Index, 
RHS.Tokens.First_Index) & ".Result),");
-                  end if;
-
-               else
-                  Indent_Line (" Children        =>");
-
-                  for Token_Index in RHS.Tokens.First_Index .. 
RHS.Tokens.Last_Index loop
-                     if RHS.Tokens (Token_Index) in Terminal then
-                        Indent_Start
-                          ((if Token_Index = RHS.Tokens.First_Index
-                            then "  ("
-                            else "   ") &
-                             "Tree_Index (Pos_" & Var_Suffix (RHS_Index, 
Token_Index) & ")");
-                     else
-                        Indent_Start
-                          ((if Token_Index = RHS.Tokens.First_Index
-                            then "  ("
-                            else "   ") &
-                             "Memo_" & Var_Suffix (RHS_Index, Token_Index) & 
".Result");
-                     end if;
-                     if Token_Index = RHS.Tokens.Last_Index then
-                        Put_Line ("),");
-                     else
-                        Put_Line (",");
-                     end if;
-                  end loop;
-               end if;
-
-               Indent_Line (" Default_Virtual => False),");
-               Indent := Indent - 3;
-               Indent_Start (" Last_Token      => Pos)");
-
-               if Data.Direct_Left_Recursive (Prod.LHS) then
-                  Put_Line (";");
-                  Indent := Indent - 2;
-                  Indent_Line ("goto Finish;");
-               else
-                  Put_Line (");");
-                  Indent := Indent - 3;
-                  Indent_Line ("goto Succeed;");
-               end if;
-            end Finish;
-
-         begin
-            Indent_Wrap_Comment (Productions.Image (Prod.LHS, RHS_Index, 
RHS.Tokens, Descriptor), Ada_Comment);
-            Indent_Line ("Pos := Last_Pos;");
-
-            if RHS.Tokens.Length = 0 then
-               Finish;
-            else
-               for Token_Index in RHS.Tokens.First_Index .. 
RHS.Tokens.Last_Index loop
-                  declare
-                     ID      : constant String := Trimmed_Image (RHS.Tokens 
(Token_Index));
-                     Var_Suf : constant String := Var_Suffix (RHS_Index, 
Token_Index);
-                  begin
-                     if RHS.Tokens (Token_Index) in Terminal then
-                        Indent_Line ("if Parser.Terminals (Pos + 1).ID = " & 
ID & " then");
-                        Indent := Indent + 3;
-                        Indent_Line ("Pos := Pos + 1;");
-                        Indent_Line ("Pos_" & Var_Suf & " := Pos;");
-                        if Token_Index = RHS.Tokens.Last_Index then
-                           Finish;
-                        end if;
-                        Indent := Indent - 3;
-                        Indent_Line ("else");
-                        Indent_Line ("   goto RHS_" & Trimmed_Image 
(RHS_Index) & "_Fail;");
-                        Indent_Line ("end if;");
-
-                     else -- nonterminal
-                        Indent_Line
-                          ("Memo_" & Var_Suf & " := Parse_" & Image 
(RHS.Tokens (Token_Index), Descriptor) &
-                             " (Parser, Pos);");
-                        Indent_Line ("case Result_States'(Memo_" & Var_Suf & 
".State) is");
-                        Indent_Line ("when Success =>");
-                        Indent := Indent + 3;
-                        Indent_Line ("Pos := Memo_" & Var_Suf & 
".Last_Token;");
-                        if Token_Index = RHS.Tokens.Last_Index then
-                           Finish;
-                        end if;
-                        Indent := Indent - 3;
-                        Indent_Line ("when Failure =>");
-                        Indent_Line ("   goto RHS_" & Trimmed_Image 
(RHS_Index) & "_Fail;");
-                        Indent_Line ("end case;");
-                     end if;
-                  end;
-               end loop;
-            end if;
-
-            Indent_Line ("<<RHS_" & Trimmed_Image (RHS_Index) & "_Fail>>");
-            New_Line;
-         end;
-      end loop;
-
-      --  We get here if the last alternative fails.
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("Result_Recurse := (State => Failure);");
-      else
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, (State => Failure));");
-         Indent_Line ("return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      end if;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("<<Finish>>");
-         Indent_Line ("if Result_Recurse.State = Success then");
-         Indent := Indent + 3;
-         Indent_Line ("if Pos > Pos_Recurse_Last then");
-         --  made progress, try again
-         Indent := Indent + 3;
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, Result_Recurse);");
-         Indent_Line ("Pos_Recurse_Last := Pos;");
-         Indent_Line ("if WisiToken.Trace_Parse > Detail then");
-         Indent_Line ("   Parser.Trace.Put_Line");
-         Indent_Line
-           ("     (Parser.Tree.Image (Result_Recurse.Result, Descriptor, 
Include_Children => True));");
-         Indent_Line ("end if;");
-         Indent_Line ("goto Recurse_Start;");
-         Indent := Indent - 3;
-         Indent_Line
-           ("elsif Pos = Pos_Recurse_Last and then " &
-              "Parser.Tree.Buffer_Region_Is_Empty (Result_Recurse.Result) 
then");
-         --  Parse succeeded producing an empty nonterm; don't try again. This
-         --  special case is not in [warth 2008].
-         Indent_Line ("   Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, Result_Recurse);");
-         Indent_Line ("end if;");
-         Indent := Indent - 3;
-         Indent_Line ("end if;");
-      end if;
-      New_Line;
-
-      if not Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("<<Succeed>>");
-         Indent_Line ("if WisiToken.Trace_Parse > Detail then");
-         Indent := Indent + 3;
-         Indent_Line ("Parser.Trace.Put_Line");
-         Indent_Line ("  (Parser.Tree.Image");
-         Indent_Line
-           ("    (Parser.Derivs (" & Result_ID & ")(Start_Pos).Result, 
Descriptor, Include_Children => True));");
-         Indent := Indent - 3;
-         Indent_Line ("end if;");
-      end if;
-
-      Indent_Line ("return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      Indent := Indent - 3;
-      Indent_Line ("end " & Parser_Name (Prod.LHS) & ";");
-      New_Line;
-   end Generate_Parser_Body;
-
-begin
-   Indent_Line ("use WisiToken;");
-   Indent_Line ("use WisiToken.Parse.Packrat;");
-   Indent_Line ("use WisiToken.Parse.Packrat.Generated;");
-
-   for Prod of Data.Grammar loop
-      Put_Parser_Spec (Parser_Name (Prod.LHS)); Put_Line (";");
-   end loop;
-   New_Line;
-
-   for Prod of Data.Grammar loop
-      Generate_Parser_Body (Prod);
-   end loop;
-
-   Indent_Line ("function Parse_wisitoken_accept_1");
-   Indent_Line
-     --  WORKAROUND: using Parse.Packrat.Parser'Class here generates GNAT bug 
box with GPL 2018
-     ("  (Parser : in out WisiToken.Parse.Base_Parser'Class; Last_Pos : in 
Base_Token_Index) return Result_Type");
-   Indent_Line ("is begin");
-   Indent_Line ("   return Parse_wisitoken_accept (Generated.Parser (Parser), 
Last_Pos);");
-   Indent_Line ("end Parse_wisitoken_accept_1;");
-   New_Line;
-
-end WisiToken.BNF.Generate_Packrat;
diff --git a/packages/wisi/wisitoken-bnf-generate_utils.adb 
b/packages/wisi/wisitoken-bnf-generate_utils.adb
deleted file mode 100644
index b5622d0..0000000
--- a/packages/wisi/wisitoken-bnf-generate_utils.adb
+++ /dev/null
@@ -1,724 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2014, 2015, 2017 - 2020  All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Exceptions;
-with Ada.Text_IO;
-with WisiToken.Generate; use WisiToken.Generate;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Ada;
-package body WisiToken.BNF.Generate_Utils is
-
-   --  For Constant_Reference
-   Aliased_EOI_Name              : aliased constant 
Ada.Strings.Unbounded.Unbounded_String := +EOI_Name;
-   Aliased_WisiToken_Accept_Name : aliased constant 
Ada.Strings.Unbounded.Unbounded_String :=
-     +WisiToken_Accept_Name;
-
-   --  body specs, as needed.
-
-   ----------
-   --  Body subprograms
-
-   function Find_Kind (Data : aliased Generate_Data; Target_Kind : in String) 
return Token_ID
-   is begin
-      for Cursor in All_Tokens (Data).Iterate loop
-         if Kind (Cursor) = Target_Kind then
-            return ID (Cursor);
-         end if;
-      end loop;
-      return Invalid_Token_ID;
-   end Find_Kind;
-
-   function Name_1 (Cursor : in Token_Cursor) return String
-   is begin
-      --   This function is used to compute Descriptor.Image
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Name;
-
-      when Terminals_Keywords =>
-         return -Cursor.Data.Tokens.Keywords (Cursor.Keyword).Name;
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Name;
-
-      when EOI =>
-         return EOI_Name;
-
-      when WisiToken_Accept =>
-         return WisiToken_Accept_Name;
-
-      when Nonterminal =>
-         return -Cursor.Data.Tokens.Rules (Cursor.Nonterminal).Left_Hand_Side;
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Name_1;
-
-   procedure To_Grammar
-     (Data             : aliased in out Generate_Data;
-      Source_File_Name :         in     String;
-      Start_Token      :         in     String)
-   is
-      use WisiToken.Wisi_Ada;
-      Descriptor : WisiToken.Descriptor renames Data.Descriptor.all;
-   begin
-      Data.Grammar.Set_First_Last (Descriptor.First_Nonterminal, 
Descriptor.Last_Nonterminal);
-      Data.Source_Line_Map.Set_First_Last (Descriptor.First_Nonterminal, 
Descriptor.Last_Nonterminal);
-
-      Data.Action_Names := new Names_Array_Array (Descriptor.First_Nonterminal 
.. Descriptor.Last_Nonterminal);
-      Data.Check_Names  := new Names_Array_Array (Descriptor.First_Nonterminal 
.. Descriptor.Last_Nonterminal);
-
-      pragma Assert (Descriptor.Accept_ID = Descriptor.First_Nonterminal);
-
-      Data.Source_Line_Map (Descriptor.Accept_ID).Line := 
Line_Number_Type'First;
-      Data.Source_Line_Map (Descriptor.Accept_ID).RHS_Map.Set_First_Last (0, 
0);
-      Data.Source_Line_Map (Descriptor.Accept_ID).RHS_Map (0) := 
Line_Number_Type'First;
-
-      if Start_Token = "" then
-         Put_Error (Error_Message (Source_File_Name, 1, "%start not 
specified"));
-      else
-         begin
-            Data.Grammar (Descriptor.Accept_ID) :=
-              Descriptor.Accept_ID <= Only
-                (Find_Token_ID (Data, Start_Token) & Descriptor.EOI_ID + 
WisiToken.Syntax_Trees.Null_Action);
-         exception
-         when Not_Found =>
-            Put_Error
-              (Error_Message
-                 (Source_File_Name, 1,
-                  "start token '" & (Start_Token) & "' not found"));
-         end;
-      end if;
-
-      for Rule of Data.Tokens.Rules loop
-         declare
-            RHS_Index        : Natural := 0;
-            RHSs             : WisiToken.Productions.RHS_Arrays.Vector;
-            LHS              : Token_ID; -- not initialized for exception 
handler
-            Action_Names     : Names_Array (0 .. Integer 
(Rule.Right_Hand_Sides.Length) - 1);
-            Action_All_Empty : Boolean := True;
-            Check_Names      : Names_Array (0 .. Integer 
(Rule.Right_Hand_Sides.Length) - 1);
-            Check_All_Empty  : Boolean := True;
-         begin
-            LHS := Find_Token_ID (Data, -Rule.Left_Hand_Side);
-
-            RHSs.Set_First_Last (RHS_Index, Natural 
(Rule.Right_Hand_Sides.Length) - 1);
-
-            Data.Source_Line_Map (LHS).Line := Rule.Source_Line;
-            Data.Source_Line_Map (LHS).RHS_Map.Set_First_Last 
(RHSs.First_Index, RHSs.Last_Index);
-
-            for Right_Hand_Side of Rule.Right_Hand_Sides loop
-               declare
-                  use Ada.Strings.Unbounded;
-                  use all type Ada.Containers.Count_Type;
-                  Tokens : WisiToken.Token_ID_Arrays.Vector;
-                  I      : Integer := 1;
-               begin
-                  if Right_Hand_Side.Tokens.Length > 0 then
-                     Tokens.Set_First_Last (I, Integer 
(Right_Hand_Side.Tokens.Length));
-                     for Token of Right_Hand_Side.Tokens loop
-                        Tokens (I) := Find_Token_ID (Data, -Token.Identifier);
-                        I := I + 1;
-                     end loop;
-                  end if;
-                  RHSs (RHS_Index) :=
-                    (Tokens => Tokens, Action => null, Check => null, 
Recursion => <>);
-                  if Length (Right_Hand_Side.Action) > 0 then
-                     Action_All_Empty := False;
-                     Action_Names (RHS_Index) := new String'
-                       (-Rule.Left_Hand_Side & '_' & WisiToken.Trimmed_Image 
(RHS_Index));
-                  end if;
-                  if Length (Right_Hand_Side.Check) > 0 then
-                     Check_All_Empty := False;
-                     Check_Names (RHS_Index) := new String'
-                       (-Rule.Left_Hand_Side & '_' & WisiToken.Trimmed_Image 
(RHS_Index) & "_check");
-                  end if;
-
-                  Data.Source_Line_Map (LHS).RHS_Map (RHS_Index) := 
Right_Hand_Side.Source_Line;
-               exception
-               when E : Not_Found =>
-                  --  From "&"
-                  Put_Error
-                    (Error_Message
-                       (Source_File_Name, Right_Hand_Side.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-               end;
-               RHS_Index := RHS_Index + 1;
-            end loop;
-
-            Data.Grammar (LHS) := LHS <= RHSs;
-            if not Action_All_Empty then
-               Data.Action_Names (LHS) := new Names_Array'(Action_Names);
-            end if;
-            if not Check_All_Empty then
-               Data.Check_Names (LHS) := new Names_Array'(Check_Names);
-            end if;
-
-         exception
-         when E : Not_Found =>
-            --  From Find_Token_ID (left_hand_side)
-            Put_Error
-              (Error_Message
-                 (Source_File_Name, Rule.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-         end;
-      end loop;
-
-      WisiToken.Generate.Check_Consistent (Data.Grammar, Descriptor, 
Source_File_Name);
-   end To_Grammar;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   function Initialize
-     (Input_Data       : aliased in WisiToken_Grammar_Runtime.User_Data_Type;
-      Ignore_Conflicts :         in Boolean := False)
-     return Generate_Data
-   is
-      EOI_ID : constant Token_ID := Token_ID
-        (Count (Input_Data.Tokens.Non_Grammar) + Count 
(Input_Data.Tokens.Tokens)) + Token_ID
-          (Input_Data.Tokens.Keywords.Length) + Token_ID'First;
-   begin
-      return Result : aliased Generate_Data :=
-        (Tokens => Input_Data.Tokens'Access,
-
-         Descriptor => new WisiToken.Descriptor
-           (First_Terminal    =>
-              (if Count (Input_Data.Tokens.Non_Grammar) > 0
-               then Token_ID (Count (Input_Data.Tokens.Non_Grammar)) + 
Token_ID'First
-               else Token_ID'First),
-            Last_Terminal     => EOI_ID,
-            EOI_ID            => EOI_ID,
-            Accept_ID         => EOI_ID + 1,
-            First_Nonterminal => EOI_ID + 1,
-            Last_Nonterminal  => EOI_ID + 1 + Token_ID 
(Input_Data.Tokens.Rules.Length)),
-
-         others => <>)
-      do
-         Result.Descriptor.Case_Insensitive := 
Input_Data.Language_Params.Case_Insensitive;
-         Result.Descriptor.New_Line_ID      := Find_Kind (Result, "new-line");
-         Result.Descriptor.String_1_ID      := Find_Kind (Result, 
"string-single");
-         Result.Descriptor.String_2_ID      := Find_Kind (Result, 
"string-double");
-
-         --  Image set in loop below, which also updates these widths.
-         Result.Descriptor.Terminal_Image_Width := 0;
-         Result.Descriptor.Image_Width          := 0;
-
-         Result.Descriptor.Last_Lookahead       :=
-           (case (Input_Data.User_Parser) is
-            when None                                  => Invalid_Token_ID,
-            when LR1                                   => 
Result.Descriptor.Last_Terminal,
-            when LALR                                  => 
Result.Descriptor.First_Nonterminal,
-            when Packrat_Generate_Algorithm | External => Invalid_Token_ID);
-
-         for Cursor in All_Tokens (Result).Iterate loop
-            Result.Descriptor.Image (ID (Cursor)) := new String'(Name_1 
(Cursor));
-         end loop;
-
-         for ID in Result.Descriptor.Image'Range loop
-            if ID in Result.Descriptor.First_Terminal .. 
Result.Descriptor.Last_Terminal then
-               if Result.Descriptor.Image (ID).all'Length > 
Result.Descriptor.Terminal_Image_Width then
-                  Result.Descriptor.Terminal_Image_Width := 
Result.Descriptor.Image (ID).all'Length;
-               end if;
-            end if;
-
-            if Result.Descriptor.Image (ID).all'Length > 
Result.Descriptor.Image_Width then
-               Result.Descriptor.Image_Width := Result.Descriptor.Image 
(ID).all'Length;
-            end if;
-         end loop;
-
-         To_Grammar (Result, Input_Data.Grammar_Lexer.File_Name, 
-Input_Data.Language_Params.Start_Token);
-         Result.Ignore_Conflicts := Ignore_Conflicts;
-      end return;
-   end Initialize;
-
-   function Find_Token_ID (Data : aliased in Generate_Data; Token : in String) 
return Token_ID
-   is begin
-      for Cursor in All_Tokens (Data).Iterate loop
-         if Name (Cursor) = Token then
-            return ID (Cursor);
-         end if;
-      end loop;
-      raise Not_Found with "token '" & Token & "' not found";
-   end Find_Token_ID;
-
-   function All_Tokens (Data : aliased in Generate_Data) return Token_Container
-   is begin
-      return (Data => Data'Access);
-   end All_Tokens;
-
-   function Constant_Reference
-     (Container : aliased in Token_Container'Class;
-      Cursor    :         in Token_Cursor)
-     return Token_Constant_Reference_Type
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return
-           (Element => Container.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens (Cursor.Token_Item).Name'Access);
-
-      when Terminals_Keywords =>
-         return (Element => Container.Data.Tokens.Keywords 
(Cursor.Keyword).Name'Access);
-
-      when Terminals_Others =>
-         return (Element => Container.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens (Cursor.Token_Item).Name'Access);
-
-      when EOI =>
-         return (Element => Aliased_EOI_Name'Access);
-
-      when WisiToken_Accept =>
-         return (Element => Aliased_WisiToken_Accept_Name'Access);
-
-      when Nonterminal =>
-         return (Element => Container.Data.Tokens.Rules 
(Cursor.Nonterminal).Left_Hand_Side'Access);
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Constant_Reference;
-
-   type Iterator (Container : not null access constant Token_Container)
-   is new Iterator_Interfaces.Forward_Iterator with record
-      Non_Grammar  : Boolean;
-      Nonterminals : Boolean;
-   end record;
-
-   overriding function First (Object : Iterator) return Token_Cursor;
-   overriding function Next (Object : Iterator; Position : Token_Cursor) 
return Token_Cursor;
-
-   overriding function First (Object : Iterator) return Token_Cursor
-   is begin
-      return First (Object.Container.Data.all, Object.Non_Grammar, 
Object.Nonterminals);
-   end First;
-
-   overriding function Next (Object  : Iterator; Position : Token_Cursor) 
return Token_Cursor
-   is
-      Next_Position : Token_Cursor := Position;
-   begin
-      Next (Next_Position, Object.Nonterminals);
-      return Next_Position;
-   end Next;
-
-   function Iterate
-     (Container    : aliased    Token_Container;
-      Non_Grammar  :         in Boolean := True;
-      Nonterminals :         in Boolean := True)
-     return Iterator_Interfaces.Forward_Iterator'Class
-   is begin
-      return Iterator'(Container'Access, Non_Grammar, Nonterminals);
-   end Iterate;
-
-   function Next_Kind_Internal
-     (Cursor       : in out Token_Cursor;
-      Nonterminals : in     Boolean)
-     return Boolean
-   is begin
-      --  Advance Cursor to the next kind; return True if any of that
-      --  kind exist, or kind is Done; False otherwise.
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Terminals_Keywords,
-            ID          => Cursor.Data.Descriptor.First_Terminal,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => Cursor.Data.Tokens.Keywords.First,
-            Nonterminal => Rule_Lists.No_Element);
-
-         return String_Pair_Lists.Has_Element (Cursor.Keyword);
-
-      when Terminals_Keywords =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Terminals_Others,
-            ID          => Cursor.ID,
-            Token_Kind  => Cursor.Data.Tokens.Tokens.First,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Rule_Lists.No_Element);
-
-         if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-            Cursor.Token_Item := Cursor.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens.First;
-            return WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item);
-         else
-            return False;
-         end if;
-
-      when Terminals_Others =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => EOI,
-            ID          => Cursor.ID,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Rule_Lists.No_Element);
-
-         return True;
-
-      when EOI =>
-         if Nonterminals then
-            if Rule_Lists.Has_Element (Cursor.Data.Tokens.Rules.First) then
-               Cursor :=
-                 (Data        => Cursor.Data,
-                  Kind        => WisiToken_Accept,
-                  ID          => Cursor.ID,
-                  Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-                  Token_Item  => String_Triple_Lists.No_Element,
-                  Keyword     => String_Pair_Lists.No_Element,
-                  Nonterminal => Rule_Lists.No_Element);
-            else
-               Cursor.Kind := Done;
-            end if;
-            return True;
-         else
-            Cursor.Kind := Done;
-            return True;
-         end if;
-
-      when WisiToken_Accept =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Nonterminal,
-            ID          => Cursor.ID,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Cursor.Data.Tokens.Rules.First);
-
-         --  Can't get here with no rules
-         return True;
-
-      when Nonterminal =>
-         Cursor.Kind := Done;
-         return True;
-
-      when Done =>
-         return True;
-      end case;
-   end Next_Kind_Internal;
-
-   function First
-     (Data         : aliased in Generate_Data;
-      Non_Grammar  :         in Boolean;
-      Nonterminals :         in Boolean)
-     return Token_Cursor
-   is
-      Cursor : Token_Cursor :=
-        (Data        => Data'Access,
-         Kind        => Non_Grammar_Kind,
-         ID          => Token_ID'First,
-         Token_Kind  => Data.Tokens.Non_Grammar.First,
-         Token_Item  => String_Triple_Lists.No_Element,
-         Keyword     => String_Pair_Lists.No_Element,
-         Nonterminal => Rule_Lists.No_Element);
-   begin
-      if Non_Grammar then
-         if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-            Cursor.Token_Item := Cursor.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens.First;
-            if WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item) then
-               return Cursor;
-            end if;
-         end if;
-      end if;
-
-      --  There are no non_grammar tokens, or Non_Grammar false
-      loop
-         exit when Next_Kind_Internal (Cursor, Nonterminals);
-      end loop;
-      return Cursor;
-   end First;
-
-   procedure Next (Cursor : in out Token_Cursor; Nonterminals : in Boolean)
-   is begin
-      Cursor.ID := Cursor.ID + 1;
-
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         String_Triple_Lists.Next (Cursor.Token_Item);
-         if String_Triple_Lists.Has_Element (Cursor.Token_Item) then
-            return;
-         else
-            WisiToken.BNF.Token_Lists.Next (Cursor.Token_Kind);
-
-            if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-               Cursor.Token_Item := Cursor.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens.First;
-               if String_Triple_Lists.Has_Element (Cursor.Token_Item) then
-                  return;
-               end if;
-            end if;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Terminals_Keywords =>
-         --  Keywords before other terminals, so they have precedence over 
Identifiers
-
-         String_Pair_Lists.Next (Cursor.Keyword);
-         if String_Pair_Lists.Has_Element (Cursor.Keyword) then
-            return;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Terminals_Others =>
-         WisiToken.BNF.String_Triple_Lists.Next (Cursor.Token_Item);
-         if WisiToken.BNF.String_Triple_Lists.Has_Element (Cursor.Token_Item) 
then
-            return;
-         else
-            WisiToken.BNF.Token_Lists.Next (Cursor.Token_Kind);
-            if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-               Cursor.Token_Item := Cursor.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens.First;
-               if WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item) then
-                  return;
-               end if;
-            end if;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when EOI =>
-         if Next_Kind_Internal (Cursor, Nonterminals) then
-            return;
-         else
-            raise SAL.Programmer_Error;
-         end if;
-
-      when WisiToken_Accept =>
-         if Next_Kind_Internal (Cursor, Nonterminals) then
-            return;
-         else
-            raise SAL.Programmer_Error;
-         end if;
-
-      when Nonterminal =>
-         Rule_Lists.Next (Cursor.Nonterminal);
-         if Rule_Lists.Has_Element (Cursor.Nonterminal) then
-            return;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Done =>
-         null;
-      end case;
-   end Next;
-
-   function Is_Done (Cursor : in Token_Cursor) return Boolean
-   is begin
-      return Cursor.Kind = Done;
-   end Is_Done;
-
-   function ID (Cursor : in Token_Cursor) return Token_ID
-   is begin
-      return Cursor.ID;
-   end ID;
-
-   function Name (Cursor : in Token_Cursor) return String
-   is begin
-      return Cursor.Data.Descriptor.Image (Cursor.ID).all;
-   end Name;
-
-   function Kind (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Kind;
-
-      when Terminals_Keywords =>
-         return "keyword";
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Kind;
-
-      when EOI =>
-         return "EOI";
-
-      when WisiToken_Accept =>
-         return "accept";
-
-      when Nonterminal =>
-         return "nonterminal";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Kind;
-
-   function Value (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Value;
-
-      when Terminals_Keywords =>
-         return -Cursor.Data.Tokens.Keywords (Cursor.Keyword).Value;
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Value;
-
-      when EOI | WisiToken_Accept | Nonterminal =>
-            return "";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Value;
-
-   function Repair_Image (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Repair_Image;
-
-      when Terminals_Keywords =>
-         return "";
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Repair_Image;
-
-      when EOI | WisiToken_Accept | Nonterminal =>
-            return "";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Repair_Image;
-
-   function To_Conflicts
-     (Data             : aliased in out Generate_Data;
-      Conflicts        :         in     WisiToken.BNF.Conflict_Lists.List;
-      Source_File_Name :         in     String)
-     return WisiToken.Generate.LR.Conflict_Lists.List
-   is
-      use WisiToken.Generate.LR;
-      Result   : WisiToken.Generate.LR.Conflict_Lists.List;
-      Conflict : WisiToken.Generate.LR.Conflict;
-   begin
-      for Item of Conflicts loop
-         begin
-            Conflict :=
-              (Conflict_Parse_Actions'Value (-Item.Action_A),
-               Find_Token_ID (Data, -Item.LHS_A),
-               Conflict_Parse_Actions'Value (-Item.Action_B),
-               Find_Token_ID (Data, -Item.LHS_B),
-               -1,
-               Find_Token_ID (Data, -Item.On));
-
-            Result.Append (Conflict);
-         exception
-         when E : Not_Found =>
-            if not Data.Ignore_Conflicts then
-               Put_Error
-                 (Error_Message
-                    (Source_File_Name, Item.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-            end if;
-         end;
-      end loop;
-      return Result;
-   end To_Conflicts;
-
-   function To_Nonterminal_ID_Set
-     (Data : aliased in Generate_Data;
-      Item :         in String_Lists.List)
-     return Token_ID_Set
-   is
-      Result : Token_ID_Set := (Data.Descriptor.First_Nonterminal .. 
Data.Descriptor.Last_Nonterminal => False);
-   begin
-      for Token of Item loop
-         Result (Find_Token_ID (Data, Token)) := True;
-      end loop;
-      return Result;
-   end To_Nonterminal_ID_Set;
-
-   function To_McKenzie_Param
-     (Data : aliased in Generate_Data;
-      Item :         in McKenzie_Recover_Param_Type)
-     return WisiToken.Parse.LR.McKenzie_Param_Type
-   is
-      use Ada.Strings.Unbounded;
-
-      Result : WisiToken.Parse.LR.McKenzie_Param_Type :=
-        --  We use an aggregate, and overwrite some below, so the compiler
-        --  reminds us to change this when we modify McKenzie_Param_Type.
-        (Data.Descriptor.First_Terminal,
-         Data.Descriptor.Last_Terminal,
-         Data.Descriptor.First_Nonterminal,
-         Data.Descriptor.Last_Nonterminal,
-         Insert                      => (others => Item.Default_Insert),
-         Delete                      => (others => 
Item.Default_Delete_Terminal),
-         Push_Back                   => (others => Item.Default_Push_Back),
-         Undo_Reduce                 => (others => Item.Default_Push_Back), -- 
no separate default for undo_reduce
-         Minimal_Complete_Cost_Delta => Item.Minimal_Complete_Cost_Delta,
-         Fast_Forward                => Item.Fast_Forward,
-         Matching_Begin              => Item.Matching_Begin,
-         Ignore_Check_Fail           => Item.Ignore_Check_Fail,
-         Task_Count                  => 0,
-         Check_Limit                 => Item.Check_Limit,
-         Check_Delta_Limit           => Item.Check_Delta_Limit,
-         Enqueue_Limit               => Item.Enqueue_Limit);
-   begin
-      for Pair of Item.Delete loop
-         Result.Delete (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Insert loop
-         Result.Insert (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Push_Back loop
-         Result.Push_Back (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Undo_Reduce loop
-         Result.Undo_Reduce (Find_Token_ID (Data, -Pair.Name)) := 
Natural'Value (-Pair.Value);
-      end loop;
-
-      return Result;
-   end To_McKenzie_Param;
-
-   procedure Put_Stats
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in Generate_Utils.Generate_Data)
-   is
-      use Ada.Text_IO;
-   begin
-      New_Line;
-      Put_Line
-        (Integer'Image (Input_Data.Rule_Count) & " rules," &
-           Integer'Image (Input_Data.Action_Count) & " user actions," &
-           Integer'Image (Input_Data.Check_Count) & " checks," &
-           WisiToken.State_Index'Image (Generate_Data.Parser_State_Count) & " 
states");
-   end Put_Stats;
-
-end WisiToken.BNF.Generate_Utils;
diff --git a/packages/wisi/wisitoken-bnf-generate_utils.ads 
b/packages/wisi/wisitoken-bnf-generate_utils.ads
deleted file mode 100644
index a2f31a2..0000000
--- a/packages/wisi/wisitoken-bnf-generate_utils.ads
+++ /dev/null
@@ -1,174 +0,0 @@
---  Abstract :
---
---  Utilities for translating input file structures to WisiToken
---  structures needed for LALR.Generate.
---
---  Copyright (C) 2014, 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Iterator_Interfaces;
-with WisiToken.Generate.LR;
-with WisiToken.Parse.LR;
-with WisiToken.Productions;
-with WisiToken_Grammar_Runtime;
-package WisiToken.BNF.Generate_Utils is
-
-   EOI_Name : constant String := "Wisi_EOI";
-   --  EOI_Name is used for Descriptor.EOI_ID token; it must match Emacs 
ada-mode
-   --  wisi.el wisi-eoi-term. It must be a valid Ada identifier when
-   --  "_ID" is appended.
-
-   WisiToken_Accept_Name : constant String := "wisitoken_accept";
-
-   type Generate_Data (Tokens : not null access constant WisiToken.BNF.Tokens) 
is limited record
-      Descriptor : WisiToken.Descriptor_Access;
-      Grammar    : WisiToken.Productions.Prod_Arrays.Vector;
-
-      Action_Names : Names_Array_Array_Access;
-      Check_Names  : Names_Array_Array_Access;
-      --  Names of subprograms for each grammar semantic action and check;
-      --  non-null only if there is an action or check in the grammar.
-
-      Start_ID        : WisiToken.Token_ID;
-      Source_Line_Map : WisiToken.Productions.Source_Line_Maps.Vector;
-
-      --  The following fields are LR specific; so far, it's not worth
-      --  splitting them out.
-
-      Ignore_Conflicts   : Boolean                       := False;
-      Conflicts          : WisiToken.Generate.LR.Conflict_Lists.List;
-      LR_Parse_Table     : WisiToken.Parse.LR.Parse_Table_Ptr;
-      Parser_State_Count : WisiToken.Unknown_State_Index := 0;
-   end record;
-
-   function Initialize
-     (Input_Data       : aliased in WisiToken_Grammar_Runtime.User_Data_Type;
-      Ignore_Conflicts :         in Boolean := False)
-     return Generate_Data;
-
-   function Find_Token_ID (Data : aliased in Generate_Data; Token : in String) 
return Token_ID;
-
-   type Token_Container (Data : not null access constant Generate_Data) is 
tagged null record
-   with
-     Constant_Indexing => Constant_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Ada.Strings.Unbounded.Unbounded_String;
-   --  We need a container type to define an iterator; the actual data is
-   --  in Data.Tokens. The Iterator_Element is given by Token_Name below.
-
-   function All_Tokens (Data : aliased in Generate_Data) return 
Token_Container;
-
-   type Token_Constant_Reference_Type
-     (Element : not null access constant 
Ada.Strings.Unbounded.Unbounded_String)
-     is null record
-   with Implicit_Dereference => Element;
-
-   type Token_Cursor (<>) is private;
-   --  Iterate thru Keywords, Tokens, Rules in a canonical order:
-   --
-   --  1. Non_Grammar
-   --  2. Keywords
-   --  3. other terminal tokens, in declaration order
-   --  4. EOI
-   --  5. Accept
-   --  6. Nonterminals
-   --
-   --  Within each group, tokens occur in the order they were declared in
-   --  the grammar file.
-
-   function Constant_Reference
-     (Container : aliased in Token_Container'Class;
-      Cursor    :         in Token_Cursor)
-     return Token_Constant_Reference_Type;
-
-   function Is_Done (Cursor : in Token_Cursor) return Boolean;
-   function Has_Element (Cursor : in Token_Cursor) return Boolean is (not 
Is_Done (Cursor));
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Token_Cursor, 
Has_Element);
-   function Iterate
-     (Container    : aliased    Token_Container;
-      Non_Grammar  :         in Boolean := True;
-      Nonterminals :         in Boolean := True)
-     return Iterator_Interfaces.Forward_Iterator'Class;
-
-   function First
-     (Data         : aliased in Generate_Data;
-      Non_Grammar  :         in Boolean;
-      Nonterminals :         in Boolean)
-     return Token_Cursor;
-   procedure Next (Cursor : in out Token_Cursor; Nonterminals : in Boolean);
-
-   function ID (Cursor : in Token_Cursor) return Token_ID;
-
-   function Name (Cursor : in Token_Cursor) return String;
-   --  Return the token name from the .wy file:
-   --  Keywords: Keywords (i).name
-   --  Tokens  : Tokens (i).Tokens (j).name
-   --  Rules   : Rules (i).Left_Hand_Side
-
-   function Kind (Cursor : in Token_Cursor) return String;
-   --  Return the token kind from the .wy file:
-   --  Keywords: "keyword"
-   --  Tokens  : Tokens (i).Kind
-   --  Rules   : "nonterminal"
-
-   function Value (Cursor : in Token_Cursor) return String;
-   --  Return the token value from the .wy file:
-   --  Keywords: Keywords (i).value
-   --  Tokens  : Tokens (i).Tokens (j).Value
-   --  Rules   : empty string (they have no Value)
-
-   function Repair_Image (Cursor : in Token_Cursor) return String;
-   --  Return the token repair image from the .wy file:
-   --  Keywords: empty string
-   --  Tokens  : Tokens (i).Tokens (j).Repair_Image
-   --  Rules   : empty string
-
-   function To_Conflicts
-     (Data             : aliased in out Generate_Data;
-      Conflicts        :         in     WisiToken.BNF.Conflict_Lists.List;
-      Source_File_Name :         in     String)
-     return WisiToken.Generate.LR.Conflict_Lists.List;
-   --  Not included in Initialize because algorithms have no conflicts.
-
-   function To_Nonterminal_ID_Set
-     (Data : aliased in Generate_Data;
-      Item :         in String_Lists.List)
-     return Token_ID_Set;
-
-   function To_McKenzie_Param
-     (Data : aliased in Generate_Data;
-      Item :         in McKenzie_Recover_Param_Type)
-     return WisiToken.Parse.LR.McKenzie_Param_Type;
-
-   procedure Put_Stats
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in Generate_Utils.Generate_Data);
-
-private
-
-   type Token_Cursor_Kind is
-     (Non_Grammar_Kind, Terminals_Keywords, Terminals_Others, EOI, 
WisiToken_Accept, Nonterminal, Done);
-
-   type Token_Cursor (Data : not null access constant Generate_Data) is record
-      Kind        : Token_Cursor_Kind;
-      ID          : Token_ID;
-      Token_Kind  : WisiToken.BNF.Token_Lists.Cursor; -- Non_Grammar or 
Tokens, depending on Kind
-      Token_Item  : String_Triple_Lists.Cursor;
-      Keyword     : String_Pair_Lists.Cursor;
-      Nonterminal : Rule_Lists.Cursor;
-   end record;
-
-end WisiToken.BNF.Generate_Utils;
diff --git a/packages/wisi/wisitoken-bnf-output_ada.adb 
b/packages/wisi/wisitoken-bnf-output_ada.adb
deleted file mode 100644
index 3857a0f..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada.adb
+++ /dev/null
@@ -1,512 +0,0 @@
---  Abstract :
---
---  Output Ada code implementing the grammar defined by input
---  parameters, and a parser for that grammar. The grammar parser
---  actions must be Ada.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Regexp;
-with WisiToken.BNF.Generate_Packrat;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.BNF.Output_Ada_Common; use WisiToken.BNF.Output_Ada_Common;
-with WisiToken.Generate.Packrat;
-with WisiToken_Grammar_Runtime;
-procedure WisiToken.BNF.Output_Ada
-  (Input_Data            :         in WisiToken_Grammar_Runtime.User_Data_Type;
-   Output_File_Name_Root :         in String;
-   Generate_Data         : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data;
-   Packrat_Data          :         in WisiToken.Generate.Packrat.Data;
-   Tuple                 :         in Generate_Tuple;
-   Test_Main             :         in Boolean;
-   Multiple_Tuples       :         in Boolean)
-is
-   Common_Data : Output_Ada_Common.Common_Data := 
WisiToken.BNF.Output_Ada_Common.Initialize
-     (Input_Data, Tuple, Output_File_Name_Root, Check_Interface => False);
-
-   Gen_Alg_Name : constant String :=
-     (if Test_Main or Multiple_Tuples
-      then "_" & Generate_Algorithm_Image (Common_Data.Generate_Algorithm).all
-      else "");
-
-   function Symbol_Regexp (Item : in String) return String
-   is begin
-      --  Return a regular expression string that matches Item as a symbol;
-      --  it must be preceded and followed by non-symbol characters.
-      --
-      --  GNAT.Regexp does not have a char for 'end of string', so we hope
-      --  that doesn't occur. Sigh.
-      return ".*[ (\.]" & Item & "[ );\.,].*";
-   end Symbol_Regexp;
-
-   procedure Create_Ada_Actions_Body
-     (Action_Names : not null access WisiToken.Names_Array_Array;
-      Check_Names  : not null access WisiToken.Names_Array_Array;
-      Label_Count  : in              Ada.Containers.Count_Type;
-      Package_Name : in              String)
-   is
-      use all type Ada.Containers.Count_Type;
-      use GNAT.Regexp;
-      use Generate_Utils;
-      use WisiToken.Generate;
-
-      File_Name : constant String := Output_File_Name_Root & "_actions.adb";
-
-      User_Data_Regexp : constant Regexp := Compile (Symbol_Regexp 
("User_Data"), Case_Sensitive => False);
-      Tree_Regexp      : constant Regexp := Compile (Symbol_Regexp ("Tree"), 
Case_Sensitive      => False);
-      Nonterm_Regexp   : constant Regexp := Compile (Symbol_Regexp 
("Nonterm"), Case_Sensitive   => False);
-      Tokens_Regexp    : constant Regexp := Compile (Symbol_Regexp ("Tokens"), 
Case_Sensitive    => False);
-
-      Body_File : File_Type;
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Context));
-      New_Line;
-
-      if Label_Count > 0 then
-         Put_Line ("with SAL;");
-      end if;
-
-      Put_Line ("package body " & Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      if Input_Data.Check_Count > 0 then
-         Indent_Line ("use WisiToken.Semantic_Checks;");
-         New_Line;
-      end if;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Pre));
-
-      --  generate Action and Check subprograms.
-
-      for Rule of Input_Data.Tokens.Rules loop
-         --  No need for a Token_Cursor here, since we only need the
-         --  nonterminals.
-         declare
-            use Ada.Strings.Unbounded;
-
-            LHS_ID    : constant WisiToken.Token_ID := Find_Token_ID 
(Generate_Data, -Rule.Left_Hand_Side);
-            RHS_Index : Integer                     := 0;
-
-            function Is_Elisp (Action : in Unbounded_String) return Boolean
-            is begin
-               return Length (Action) >= 6 and then
-                 (Slice (Action, 1, 6) = "(progn" or
-                    Slice (Action, 1, 5) = "wisi-");
-            end Is_Elisp;
-
-            procedure Put_Labels (RHS : in RHS_Type; Line : in String)
-            is
-               Output : array (Rule.Labels.First_Index .. 
Rule.Labels.Last_Index) of Boolean := (others => False);
-
-               procedure Update_Output (Label : in String)
-               is begin
-                  for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index 
loop
-                     if Label = Rule.Labels (I) then
-                        Output (I) := True;
-                     end if;
-                  end loop;
-               end Update_Output;
-            begin
-               for I in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index loop
-                  if Length (RHS.Tokens (I).Label) > 0 then
-                     declare
-                        Label : constant String := -RHS.Tokens (I).Label;
-                     begin
-                        if Match (Line, Compile (Symbol_Regexp (Label), 
Case_Sensitive => False)) then
-                           Indent_Line
-                             (Label & " : constant SAL.Peek_Type :=" & 
SAL.Peek_Type'Image (I) & ";");
-                           Update_Output (Label);
-                        end if;
-                     end;
-                  end if;
-               end loop;
-
-               for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index loop
-                  if not Output (I) and
-                    Match (Line, Compile (Symbol_Regexp (-Rule.Labels (I)), 
Case_Sensitive => False))
-                  then
-                     Indent_Line (-Rule.Labels (I) & " : constant 
SAL.Base_Peek_Type := SAL.Base_Peek_Type'First;");
-                  end if;
-               end loop;
-            end Put_Labels;
-
-         begin
-            for RHS of Rule.Right_Hand_Sides loop
-               if Length (RHS.Action) > 0 and then not Is_Elisp (RHS.Action) 
then
-                  declare
-                     Line : constant String := -RHS.Action;
-                     --  Actually multiple lines; we assume the formatting is 
adequate.
-
-                     Name : constant String := Action_Names 
(LHS_ID)(RHS_Index).all;
-
-                     Unref_User_Data : Boolean := True;
-                     Unref_Tree      : Boolean := True;
-                     Unref_Nonterm   : Boolean := True;
-                     Unref_Tokens    : Boolean := True;
-                     Need_Comma      : Boolean := False;
-
-                     procedure Check_Unref (Line : in String)
-                     is begin
-                        if Match (Line, User_Data_Regexp) then
-                           Unref_User_Data := False;
-                        end if;
-                        if Match (Line, Tree_Regexp) then
-                           Unref_Tree := False;
-                        end if;
-                        if Match (Line, Nonterm_Regexp) then
-                           Unref_Nonterm := False;
-                        end if;
-                        if Match (Line, Tokens_Regexp) then
-                           Unref_Tokens := False;
-                        end if;
-                     end Check_Unref;
-                  begin
-                     Check_Unref (Line);
-                     Indent_Line ("procedure " & Name);
-                     Indent_Line (" (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class;");
-                     Indent_Line ("  Tree      : in out 
WisiToken.Syntax_Trees.Tree;");
-                     Indent_Line ("  Nonterm   : in     
WisiToken.Valid_Node_Index;");
-                     Indent_Line ("  Tokens    : in     
WisiToken.Valid_Node_Index_Array)");
-                     Indent_Line ("is");
-
-                     Indent := Indent + 3;
-                     if Unref_User_Data or Unref_Tree or Unref_Nonterm or 
Unref_Tokens then
-                        Indent_Start ("pragma Unreferenced (");
-
-                        if Unref_User_Data then
-                           Put ("User_Data");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tree then
-                           Put ((if Need_Comma then ", " else "") & "Tree");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Nonterm then
-                           Put ((if Need_Comma then ", " else "") & "Nonterm");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tokens then
-                           Put ((if Need_Comma then ", " else "") & "Tokens");
-                           Need_Comma := True;
-                        end if;
-                        Put_Line (");");
-                     end if;
-
-                     Put_Labels (RHS, Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("begin");
-                     Indent := Indent + 3;
-
-                     Indent_Line (Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("end " & Name & ";");
-                     New_Line;
-                  end;
-               end if;
-
-               if Length (RHS.Check) > 0 and then not Is_Elisp (RHS.Check) then
-                  declare
-                     use Ada.Strings.Fixed;
-                     Line          : constant String  := -RHS.Check;
-                     Name          : constant String  := Check_Names 
(LHS_ID)(RHS_Index).all;
-                     Unref_Lexer   : constant Boolean := 0 = Index (Line, 
"Lexer");
-                     Unref_Nonterm : constant Boolean := 0 = Index (Line, 
"Nonterm");
-                     Unref_Tokens  : constant Boolean := 0 = Index (Line, 
"Tokens");
-                     Unref_Recover : constant Boolean := 0 = Index (Line, 
"Recover_Active");
-                     Need_Comma    : Boolean          := False;
-                  begin
-                     Indent_Line ("function " & Name);
-                     Indent_Line (" (Lexer          : access constant 
WisiToken.Lexer.Instance'Class;");
-                     Indent_Line ("  Nonterm        : in out 
WisiToken.Recover_Token;");
-                     Indent_Line ("  Tokens         : in     
WisiToken.Recover_Token_Array;");
-                     Indent_Line ("  Recover_Active : in     Boolean)");
-                     Indent_Line (" return 
WisiToken.Semantic_Checks.Check_Status");
-                     Indent_Line ("is");
-
-                     Indent := Indent + 3;
-                     if Unref_Lexer or Unref_Nonterm or Unref_Tokens or 
Unref_Recover then
-                        Indent_Start ("pragma Unreferenced (");
-
-                        if Unref_Lexer then
-                           Put ("Lexer");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Nonterm then
-                           Put ((if Need_Comma then ", " else "") & "Nonterm");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tokens then
-                           Put ((if Need_Comma then ", " else "") & "Tokens");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Recover then
-                           Put ((if Need_Comma then ", " else "") & 
"Recover_Active");
-                           Need_Comma := True;
-                        end if;
-                        Put_Line (");");
-                     end if;
-
-                     Put_Labels (RHS, Line);
-                     Indent := Indent - 3;
-
-                     Indent_Line ("begin");
-                     Indent := Indent + 3;
-                     Indent_Line (Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("end " & Name & ";");
-                     New_Line;
-                  end;
-               end if;
-
-               RHS_Index := RHS_Index + 1;
-            end loop;
-         end;
-      end loop;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Post));
-
-      Put_Line ("end " & Package_Name & ";");
-      Close (Body_File);
-
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Actions_Body;
-
-   procedure Create_Ada_Main_Body
-     (Actions_Package_Name : in String;
-      Main_Package_Name    : in String)
-   is
-      use WisiToken.Generate;
-
-      File_Name         : constant String := To_Lower (Main_Package_Name) & 
".adb";
-      re2c_Package_Name : constant String := -Common_Data.Lower_File_Name_Root 
& "_re2c_c";
-
-      Body_File : File_Type;
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if (case Common_Data.Generate_Algorithm is
-          when LR_Generate_Algorithm => Input_Data.Action_Count > 0 or 
Input_Data.Check_Count > 0,
-          when Packrat_Generate_Algorithm | External => 
Input_Data.Action_Count > 0)
-      then
-         Put_Line ("with " & Actions_Package_Name & "; use " & 
Actions_Package_Name & ";");
-      end if;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Put_Line ("with WisiToken.Lexer.re2c;");
-         Put_Line ("with " & re2c_Package_Name & ";");
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         null;
-
-      when Packrat_Gen =>
-         Put_Line ("with WisiToken.Parse.Packrat.Generated;");
-
-      when Packrat_Proc =>
-         Put_Line ("with WisiToken.Parse.Packrat.Procedural;");
-         Put_Line ("with WisiToken.Productions;");
-
-      when External =>
-         null;
-      end case;
-
-      Put_Line ("package body " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Indent_Line ("package Lexer is new WisiToken.Lexer.re2c");
-         Indent_Line ("  (" & re2c_Package_Name & ".New_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Free_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Reset_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Next_Token);");
-         New_Line;
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         LR_Create_Create_Parser (Input_Data, Common_Data, Generate_Data);
-
-      when Packrat_Gen =>
-         WisiToken.BNF.Generate_Packrat (Packrat_Data, Generate_Data);
-
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when Packrat_Proc =>
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when External =>
-         External_Create_Create_Grammar (Generate_Data);
-      end case;
-
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Body_File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Main_Body;
-
-   procedure Create_Ada_Test_Main
-     (Actions_Package_Name : in String;
-      Main_Package_Name    : in String)
-   is
-      use WisiToken.Generate;
-
-      Generic_Package_Name : constant String :=
-        (case Common_Data.Generate_Algorithm is
-         when LR_Generate_Algorithm =>
-           (if Input_Data.Language_Params.Error_Recover then
-              (if Common_Data.Text_Rep
-               then "Gen_LR_Text_Rep_Parser_Run"
-               else "Gen_LR_Parser_Run")
-            else
-              (if Common_Data.Text_Rep
-               then "Gen_LR_Text_Rep_Parser_No_Recover_Run"
-               else "Gen_LR_Parser_No_Recover_Run")),
-
-         when Packrat_Generate_Algorithm => "Gen_Packrat_Parser_Run",
-         when External => raise SAL.Programmer_Error);
-
-      Unit_Name : constant String := File_Name_To_Ada (Output_File_Name_Root) &
-        "_" & Generate_Algorithm'Image (Common_Data.Generate_Algorithm) & 
"_Run";
-
-      Default_Language_Runtime_Package : constant String := 
"WisiToken.Parse.LR.McKenzie_Recover." & File_Name_To_Ada
-        (Output_File_Name_Root);
-
-      File_Name : constant String := To_Lower (Unit_Name) & ".ads";
-
-      File : File_Type;
-   begin
-      Create (File, Out_File, File_Name);
-      Set_Output (File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      --  no Copyright_License; just a test file
-      New_Line;
-
-      Put_Line ("with " & Generic_Package_Name & ";");
-      Put_Line ("with " & Actions_Package_Name & ";");
-      Put_Line ("with " & Main_Package_Name & ";");
-      if Input_Data.Language_Params.Error_Recover and
-        Input_Data.Language_Params.Use_Language_Runtime
-      then
-         declare
-            Pkg : constant String :=
-              (if -Input_Data.Language_Params.Language_Runtime_Name = ""
-               then Default_Language_Runtime_Package
-               else -Input_Data.Language_Params.Language_Runtime_Name);
-         begin
-            --  For language-specific names in actions, checks.
-            Put_Line ("with " & Pkg & ";");
-            Put_Line ("use " & Pkg & ";");
-         end;
-      end if;
-
-      Put_Line ("procedure " & Unit_Name & " is new " & Generic_Package_Name);
-      Put_Line ("  (" & Actions_Package_Name & ".Descriptor,");
-      if Common_Data.Text_Rep then
-         Put_Line ("   """ & Output_File_Name_Root & "_" &
-                     To_Lower (Generate_Algorithm_Image (Tuple.Gen_Alg).all) &
-                     "_parse_table.txt"",");
-      end if;
-      if Input_Data.Language_Params.Error_Recover then
-         if Input_Data.Language_Params.Use_Language_Runtime then
-            Put_Line ("Fixes'Access, Matching_Begin_Tokens'Access, 
String_ID_Set'Access,");
-         else
-            Put_Line ("null, null, null,");
-         end if;
-      end if;
-      Put_Line (Main_Package_Name & ".Create_Parser);");
-      Close (File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Test_Main;
-
-begin
-   case Common_Data.Lexer is
-   when None | re2c_Lexer =>
-      null;
-
-   when Elisp_Lexer =>
-      raise User_Error with WisiToken.Generate.Error_Message
-        (Input_Data.Grammar_Lexer.File_Name, 1, "Ada output language does not 
support " & Lexer_Image
-           (Common_Data.Lexer).all & " lexer");
-   end case;
-
-   case Tuple.Interface_Kind is
-   when None  =>
-      null;
-
-   when Module | Process =>
-      raise User_Error with WisiToken.Generate.Error_Message
-        (Input_Data.Grammar_Lexer.File_Name, 1, "Ada output language does not 
support setting Interface");
-   end case;
-
-   declare
-      Main_Package_Name    : constant String := File_Name_To_Ada 
(Output_File_Name_Root & Gen_Alg_Name) & "_Main";
-      Actions_Package_Name : constant String := File_Name_To_Ada 
(Output_File_Name_Root) & "_Actions";
-   begin
-      if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
-         --  Some WisiToken tests have no actions or checks.
-         Create_Ada_Actions_Body
-           (Generate_Data.Action_Names, Generate_Data.Check_Names, 
Input_Data.Label_Count, Actions_Package_Name);
-      end if;
-
-      Create_Ada_Actions_Spec
-        (Output_File_Name_Root & "_actions.ads", Actions_Package_Name, 
Input_Data, Common_Data, Generate_Data);
-
-      if Tuple.Gen_Alg = External then
-         Create_External_Main_Spec (Main_Package_Name, Tuple, Input_Data);
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-      else
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-
-         Create_Ada_Main_Spec (To_Lower (Main_Package_Name) & ".ads", 
Main_Package_Name, Input_Data, Common_Data);
-
-         if Test_Main then
-            Create_Ada_Test_Main (Actions_Package_Name, Main_Package_Name);
-         end if;
-      end if;
-   end;
-
-exception
-when others =>
-   Set_Output (Standard_Output);
-   raise;
-end WisiToken.BNF.Output_Ada;
diff --git a/packages/wisi/wisitoken-bnf-output_ada_common.adb 
b/packages/wisi/wisitoken-bnf-output_ada_common.adb
deleted file mode 100644
index 3a594bb..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada_common.adb
+++ /dev/null
@@ -1,1392 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with System.Multiprocessors;
-with WisiToken.BNF.Generate_Grammar;
-with WisiToken.BNF.Utils;
-with WisiToken.Generate; use WisiToken.Generate;
-with WisiToken.Parse.LR;
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-package body WisiToken.BNF.Output_Ada_Common is
-
-   --  Body subprograms, alphabetical
-
-   function Duplicate_Reduce (State : in Parse.LR.Parse_State) return Boolean
-   is
-      use Parse.LR;
-      Action_Node : Parse_Action_Node_Ptr;
-      First       : Boolean := True;
-      Action      : Reduce_Action_Rec;
-   begin
-      for Node of State.Action_List loop
-         Action_Node := Node.Actions;
-         if Action_Node.Next /= null then
-            --  conflict
-            return False;
-         elsif Action_Node.Item.Verb /= Reduce then
-            return False;
-         end if;
-
-         if First then
-            Action    := Action_Node.Item;
-            First     := False;
-         else
-            if not Equal (Action, Action_Node.Item) then
-               return False;
-            end if;
-         end if;
-      end loop;
-      return True;
-   end Duplicate_Reduce;
-
-   function Image (Item : in Boolean) return String
-     is (if Item then "True" else "False");
-
-   function Symbols_Image (State : in Parse.LR.Parse_State) return String
-   is
-      use all type Ada.Containers.Count_Type;
-      use Ada.Strings.Unbounded;
-
-      Result     : Unbounded_String;
-      Need_Comma : Boolean := False;
-   begin
-      if State.Action_List.Length = 1 then
-         return "(1 => " & Token_ID'Image (State.Action_List (1).Symbol) & ")";
-      else
-         Result := +"(";
-         for Node of State.Action_List loop
-            Result := Result &
-              (if Need_Comma then ", " else "") &
-              Trimmed_Image (Node.Symbol);
-            Need_Comma := True;
-         end loop;
-         Result := Result & ")";
-         return -Result;
-      end if;
-   end Symbols_Image;
-
-   ----------
-   --  Public subprograms in alphabetical order
-
-   procedure Create_Ada_Actions_Spec
-     (Output_File_Name :         in String;
-      Package_Name     :         in String;
-      Input_Data       :         in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data      :         in Output_Ada_Common.Common_Data;
-      Generate_Data    : aliased in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use Generate_Utils;
-
-      Descriptor  : WisiToken.Descriptor renames Generate_Data.Descriptor.all;
-      Spec_File : File_Type;
-      Paren_Done  : Boolean      := False;
-      Cursor      : Token_Cursor := First (Generate_Data, Non_Grammar => True, 
Nonterminals => True);
-   begin
-      Create (Spec_File, Out_File, Output_File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header
-        (Ada_Comment, Use_Tuple => True, Tuple =>
-           (Common_Data.Generate_Algorithm, Common_Data.Output_Language, 
Common_Data.Lexer, Common_Data.Interface_Kind,
-            Common_Data.Text_Rep));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if not (Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0) then
-         Put_Line ("with WisiToken;");
-      end if;
-      if Input_Data.Action_Count > 0 then
-         Put_Line ("with WisiToken.Syntax_Trees;");
-      end if;
-      if Input_Data.Check_Count > 0 then
-         Put_Line ("with WisiToken.Lexer;");
-         Put_Line ("with WisiToken.Semantic_Checks;");
-      end if;
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Context));
-      Put_Line ("package " & Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Pre));
-
-      Indent_Line ("Descriptor : aliased WisiToken.Descriptor :=");
-      Indent_Line ("  (First_Terminal    =>" & WisiToken.Token_ID'Image 
(Descriptor.First_Terminal) & ",");
-      Indent := Indent + 3;
-      Indent_Line ("Last_Terminal     =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Terminal) & ",");
-      Indent_Line ("First_Nonterminal =>" & WisiToken.Token_ID'Image 
(Descriptor.First_Nonterminal) & ",");
-      Indent_Line ("Last_Nonterminal  =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Nonterminal) & ",");
-      Indent_Line ("EOI_ID            =>" & WisiToken.Token_ID'Image 
(Descriptor.EOI_ID) & ",");
-      Indent_Line ("Accept_ID         =>" & WisiToken.Token_ID'Image 
(Descriptor.Accept_ID) & ",");
-      Indent_Line ("Case_Insensitive  => " & Image 
(Input_Data.Language_Params.Case_Insensitive) & ",");
-      Indent_Line ("New_Line_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.New_Line_ID) & ",");
-      Indent_Line ("String_1_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.String_1_ID) & ",");
-      Indent_Line ("String_2_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.String_2_ID) & ",");
-      Indent_Line ("Image             =>");
-      Indent_Start ("  (");
-      Indent := Indent + 3;
-      loop
-         exit when Is_Done (Cursor);
-         if Paren_Done then
-            Indent_Start ("new String'(""" & (Name (Cursor)));
-         else
-            Put ("new String'(""" & (Name (Cursor)));
-            Paren_Done := True;
-         end if;
-         Next (Cursor, Nonterminals => True);
-         if Is_Done (Cursor) then
-            Put_Line (""")),");
-         else
-            Put_Line ("""),");
-         end if;
-      end loop;
-
-      Indent := Indent - 3;
-      Indent_Line ("Terminal_Image_Width =>" & Integer'Image 
(Descriptor.Terminal_Image_Width) & ",");
-      Indent_Line ("Image_Width          =>" & Integer'Image 
(Descriptor.Image_Width) & ",");
-      Indent_Line ("Last_Lookahead       =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Lookahead) & ");");
-      Indent := Indent - 3;
-      New_Line;
-
-      if Input_Data.Language_Params.Declare_Enums then
-         Paren_Done := False;
-
-         Cursor := First (Generate_Data, Non_Grammar => True, Nonterminals => 
True);
-         Indent_Line ("type Token_Enum_ID is");
-         Indent_Start ("  (");
-         Indent := Indent + 3;
-         loop
-            exit when Is_Done (Cursor);
-            if Paren_Done then
-               Indent_Start (To_Token_Ada_Name (Name (Cursor)));
-            else
-               Put (To_Token_Ada_Name (Name (Cursor)));
-               Paren_Done := True;
-            end if;
-            Next (Cursor, Nonterminals => True);
-            if Is_Done (Cursor) then
-               Put_Line (");");
-            else
-               Put_Line (",");
-            end if;
-         end loop;
-
-         Indent := Indent - 3;
-         New_Line;
-
-         Indent_Line ("type Token_Enum_ID_Array is array (Positive range <>) 
of Token_Enum_ID;");
-         Indent_Line ("use all type WisiToken.Token_ID;");
-         Indent_Line ("function ""+"" (Item : in Token_Enum_ID) return 
WisiToken.Token_ID");
-         Indent_Line ("  is (WisiToken.Token_ID'First + Token_Enum_ID'Pos 
(Item));");
-
-         Indent_Line ("function To_Token_Enum (Item : in WisiToken.Token_ID) 
return Token_Enum_ID");
-         Indent_Line ("  is (Token_Enum_ID'Val (Item - 
WisiToken.Token_ID'First));");
-         Indent_Line ("function ""-"" (Item : in WisiToken.Token_ID) return 
Token_Enum_ID renames To_Token_Enum;");
-         New_Line;
-
-      end if;
-
-      for Name_List of Generate_Data.Action_Names.all loop
-         if Name_List /= null then
-            for Name of Name_List.all loop
-               if Name /= null then
-                  Indent_Line ("procedure " & Name.all);
-                  Indent_Line (" (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class;");
-                  Indent_Line ("  Tree      : in out 
WisiToken.Syntax_Trees.Tree;");
-                  Indent_Line ("  Nonterm   : in     
WisiToken.Valid_Node_Index;");
-                  Indent_Line ("  Tokens    : in     
WisiToken.Valid_Node_Index_Array);");
-               end if;
-            end loop;
-         end if;
-      end loop;
-
-      for Name_List of Generate_Data.Check_Names.all loop
-         if Name_List /= null then
-            for Name of Name_List.all loop
-               if Name /= null then
-                  Indent_Line ("function " & Name.all);
-                  Indent_Line (" (Lexer          : access constant 
WisiToken.Lexer.Instance'Class;");
-                  Indent_Line ("  Nonterm        : in out 
WisiToken.Recover_Token;");
-                  Indent_Line ("  Tokens         : in     
WisiToken.Recover_Token_Array;");
-                  Indent_Line ("  Recover_Active : in     Boolean)");
-                  Indent_Line (" return 
WisiToken.Semantic_Checks.Check_Status;");
-               end if;
-            end loop;
-         end if;
-      end loop;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Post));
-
-      Put_Line ("end " & Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Actions_Spec;
-
-   procedure Create_Ada_Main_Spec
-     (Output_File_Name  : in String;
-      Main_Package_Name : in String;
-      Input_Data        : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data       : in Output_Ada_Common.Common_Data)
-   is
-      Lower_Package_Name : constant String := To_Lower (Main_Package_Name);
-
-      Spec_File : File_Type;
-
-      procedure LR_Process
-      is begin
-         Indent_Line ("procedure Create_Parser");
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser.Parser;");
-            Indent_Line ("   Language_Fixes                 : in     
WisiToken.Parse.LR.Parser.Language_Fixes_Access;");
-            Indent_Line ("   Language_Matching_Begin_Tokens : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;");
-            Indent_Line ("   Language_String_ID_Set         : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;");
-         else
-            Indent_Line ("  (Parser                       :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;");
-            Indent_Line ("   --  no error recovery");
-         end if;
-         Indent_Line ("   Trace                        : not null access 
WisiToken.Trace'Class;");
-         Indent_Start ("   User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access");
-
-         if Common_Data.Text_Rep then
-            Put_Line (";");
-            Indent_Line ("   Text_Rep_File_Name : in String);");
-         else
-            Put_Line (");");
-         end if;
-         New_Line;
-      end LR_Process;
-
-      procedure Packrat_Process
-      is begin
-         Indent_Line ("function Create_Parser");
-         Indent_Line ("  (Trace     : not null access WisiToken.Trace'Class;");
-         Indent_Line ("   User_Data : in     
WisiToken.Syntax_Trees.User_Data_Access)");
-         Indent_Line ("  return WisiToken.Parse.Base_Parser'Class;");
-         New_Line;
-      end Packrat_Process;
-
-   begin
-      if Common_Data.Generate_Algorithm = External then
-         raise SAL.Programmer_Error;
-      end if;
-
-      Create (Spec_File, Out_File, Output_File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header
-        (Ada_Comment, Use_Tuple => True, Tuple =>
-           (Common_Data.Generate_Algorithm, Common_Data.Output_Language, 
Common_Data.Lexer, Common_Data.Interface_Kind,
-            Common_Data.Text_Rep));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      case Common_Data.Output_Language is
-      when Ada_Lang =>
-         Put_Line ("with WisiToken.Syntax_Trees;");
-
-      when Ada_Emacs_Lang =>
-         case Common_Data.Interface_Kind is
-         when Process =>
-            Put_Line ("with WisiToken.Syntax_Trees;");
-
-         when Module =>
-            Put_Line ("with Emacs_Module_Aux;");
-            Put_Line ("with emacs_module_h;");
-            Put_Line ("with Interfaces.C;");
-            Put_Line ("with WisiToken.Semantic_State;");
-         end case;
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         if Input_Data.Language_Params.Error_Recover then
-            Put_Line ("with WisiToken.Parse.LR.Parser;");
-         else
-            Put_Line ("with WisiToken.Parse.LR.Parser_No_Recover;");
-         end if;
-
-      when Packrat_Generate_Algorithm =>
-         Put_Line ("with WisiToken.Parse;");
-
-      when External =>
-         null;
-      end case;
-
-      Put_Line ("package " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      case Common_Data.Output_Language is
-      when Ada_Lang =>
-         case Common_Data.Generate_Algorithm is
-         when LR_Generate_Algorithm =>
-            LR_Process;
-         when Packrat_Generate_Algorithm =>
-            Packrat_Process;
-         when External =>
-            null;
-         end case;
-
-      when Ada_Emacs_Lang =>
-         case Common_Data.Interface_Kind is
-         when Process =>
-            case Common_Data.Generate_Algorithm is
-            when LR_Generate_Algorithm =>
-               LR_Process;
-            when Packrat_Generate_Algorithm =>
-               Packrat_Process;
-            when External =>
-               null;
-            end case;
-
-         when Module =>
-            Indent_Line ("function Parse (Env : 
Emacs_Module_Aux.Emacs_Env_Access) return emacs_module_h.emacs_value;");
-            Indent_Line ("pragma Export (C, Parse, """ & Lower_Package_Name & 
"_wisi_module_parse"");");
-            Indent_Line ("function Init (Env : 
Emacs_Module_Aux.Emacs_Env_Access) return Interfaces.C.int;");
-            Indent_Line ("pragma Export (C, Init, """ & Lower_Package_Name & 
"_wisi_module_parse_init"");");
-            New_Line;
-
-         end case;
-      end case;
-
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Main_Spec;
-
-   procedure Create_External_Main_Spec
-     (Main_Package_Name    : in String;
-      Tuple                : in Generate_Tuple;
-      Input_Data           : in WisiToken_Grammar_Runtime.User_Data_Type)
-   is
-      File_Name : constant String := To_Lower (Main_Package_Name) & ".ads";
-      Spec_File : File_Type;
-   begin
-      Create (Spec_File, Out_File, File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      Put_Line ("with WisiToken.Productions;");
-      Put_Line ("package " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      Indent_Line ("function Create_Grammar return 
WisiToken.Productions.Prod_Arrays.Vector;");
-
-      Indent := Indent - 3;
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-   end Create_External_Main_Spec;
-
-   procedure Create_LR_Parser_Core_1
-     (Common_Data   : in Output_Ada_Common.Common_Data;
-      Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use Ada.Strings.Unbounded;
-
-      subtype Nonterminal_ID is Token_ID range
-        Generate_Data.Grammar.First_Index .. Generate_Data.Grammar.Last_Index;
-
-      Table : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-      Line  : Unbounded_String;
-
-      procedure Append (Item : in String)
-      is begin
-         Line := Line & Item;
-      end Append;
-
-      procedure Put (Label : in String; Item : in Token_ID_Array_Natural)
-      is begin
-         Indent_Line (Label & " =>");
-         Indent_Start ("  (");
-         Indent := Indent + 3;
-         Line := +"";
-         for I in Item'Range loop
-            Append (Trimmed_Image (Item (I)));
-
-            if I = Item'Last then
-               Append ("),");
-
-            else
-               Append (", ");
-            end if;
-         end loop;
-         Indent_Wrap (-Line);
-         Indent := Indent - 3;
-      end Put;
-
-   begin
-      Indent_Line ("McKenzie_Param : constant McKenzie_Param_Type :=");
-      Indent_Line ("  (First_Terminal    =>" & Token_ID'Image 
(Table.McKenzie_Param.First_Terminal) & ",");
-      Indent := Indent + 3;
-      Indent_Line ("Last_Terminal     =>" & Token_ID'Image 
(Table.McKenzie_Param.Last_Terminal) & ",");
-      Indent_Line ("First_Nonterminal =>" & Token_ID'Image 
(Table.McKenzie_Param.First_Nonterminal) & ",");
-      Indent_Line ("Last_Nonterminal  =>" & Token_ID'Image 
(Table.McKenzie_Param.Last_Nonterminal) & ",");
-      Put ("Insert", Table.McKenzie_Param.Insert);
-      Put ("Delete", Table.McKenzie_Param.Delete);
-      Put ("Push_Back", Table.McKenzie_Param.Push_Back);
-      Put ("Undo_Reduce", Table.McKenzie_Param.Undo_Reduce);
-      Indent_Line
-        ("Minimal_Complete_Cost_Delta => " & Integer'Image 
(Table.McKenzie_Param.Minimal_Complete_Cost_Delta) & ",");
-      Indent_Line ("Fast_Forward => " & Integer'Image 
(Table.McKenzie_Param.Fast_Forward) & ",");
-      Indent_Line ("Matching_Begin => " & Integer'Image 
(Table.McKenzie_Param.Matching_Begin) & ",");
-      Indent_Line ("Ignore_Check_Fail  =>" & Integer'Image 
(Table.McKenzie_Param.Ignore_Check_Fail) & ",");
-      Indent_Line ("Task_Count  =>" & System.Multiprocessors.CPU_Range'Image
-                     (Table.McKenzie_Param.Task_Count) & ",");
-      Indent_Line ("Check_Limit =>" & Token_Index'Image 
(Table.McKenzie_Param.Check_Limit) & ",");
-      Indent_Line ("Check_Delta_Limit =>" & Integer'Image 
(Table.McKenzie_Param.Check_Delta_Limit) & ",");
-      Indent_Line ("Enqueue_Limit =>" & Integer'Image 
(Table.McKenzie_Param.Enqueue_Limit) & ");");
-      Indent := Indent - 3;
-      New_Line;
-
-      if Common_Data.Text_Rep then
-         Indent_Line ("function Actions return 
WisiToken.Parse.LR.Semantic_Action_Array_Arrays.Vector");
-         Indent_Line ("is begin");
-         Indent := Indent + 3;
-         Indent_Line ("return Acts : 
WisiToken.Parse.LR.Semantic_Action_Array_Arrays.Vector do");
-         Indent := Indent + 3;
-         Indent_Line
-           ("Acts.Set_First_Last (" & Trimmed_Image 
(Generate_Data.Grammar.First_Index) & ", " &
-              Trimmed_Image (Generate_Data.Grammar.Last_Index) & ");");
-
-         for I in Nonterminal_ID loop
-            declare
-               P : Productions.Instance renames Generate_Data.Grammar (I);
-            begin
-               if Generate_Data.Action_Names (P.LHS) /= null or 
Generate_Data.Check_Names (P.LHS) /= null then
-                  Indent_Line
-                    ("Acts (" & Trimmed_Image (P.LHS) & ").Set_First_Last (0," 
&
-                       Integer'Image (P.RHSs.Last_Index) & ");");
-
-                  for J in P.RHSs.First_Index .. P.RHSs.Last_Index loop
-                     if (Generate_Data.Action_Names (P.LHS) /= null and then
-                           Generate_Data.Action_Names (P.LHS)(J) /= null)
-                       or
-                       (Generate_Data.Check_Names (P.LHS) /= null and then
-                          Generate_Data.Check_Names (P.LHS) /= null)
-                     then
-                        Indent_Wrap
-                          ("Acts (" & Trimmed_Image (P.LHS) & ")(" & 
Trimmed_Image (J) & ") := (" &
-                             (if Generate_Data.Action_Names (P.LHS) = null 
then "null"
-                              elsif Generate_Data.Action_Names (P.LHS)(J) = 
null then "null"
-                              else Generate_Data.Action_Names (P.LHS)(J).all & 
"'Access") & ", " &
-                             (if Generate_Data.Check_Names (P.LHS) = null then 
"null"
-                              elsif Generate_Data.Check_Names (P.LHS)(J) = 
null then "null"
-                              else Generate_Data.Check_Names (P.LHS)(J).all & 
"'Access") & ");");
-                     end if;
-                  end loop;
-               end if;
-            end;
-         end loop;
-         Indent := Indent - 3;
-         Indent_Line ("end return;");
-         Indent := Indent - 3;
-         Indent_Line ("end Actions;");
-         New_Line;
-      end if;
-   end Create_LR_Parser_Core_1;
-
-   procedure Create_LR_Parser_Table
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use all type Ada.Containers.Count_Type;
-      use WisiToken.Parse.LR;
-      use Ada.Strings.Unbounded;
-
-      Table            : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-      Lines_Per_Subr   : constant := 1000;
-      Subr_Count       : Integer  := 1;
-      Last_Subr_Closed : Boolean  := False;
-      Line             : Unbounded_String;
-
-      procedure Append (Item : in String)
-      is begin
-         Line := Line & Item;
-      end Append;
-   begin
-      --  Optimize source structure for GNAT compile time; one subroutine
-      --  with thousands of "Table.States (*) := ..." takes forever to
-      --  compile (apparently depending on available memory). But hundreds
-      --  of subroutines, containing the same lines in chunks of 1000,
-      --  compiles in acceptable time.
-
-      Indent_Line ("declare");
-      Indent := Indent + 3;
-
-      Indent_Line ("procedure Subr_" & Trimmed_Image (Subr_Count));
-      Indent_Line ("is begin");
-      Indent     := Indent + 3;
-      Line_Count := 0;
-
-      Declare_Subroutines :
-      for State_Index in Table.States'Range loop
-         Actions :
-         declare
-            use Ada.Containers;
-            Base_Indent : constant Ada.Text_IO.Count := Indent;
-         begin
-            Indent_Line
-              ("Table.States (" & Trimmed_Image (State_Index) & 
").Action_List.Set_Capacity (" &
-                 Trimmed_Image (Table.States (State_Index).Action_List.Length) 
& ");");
-
-            if Duplicate_Reduce (Table.States (State_Index)) then
-               if Table.States (State_Index).Action_List.Length > 0 then
-                  --  We only get here with Length = 0 when there's a bug in 
LALR_Generate.
-                  declare
-                     Node   : Action_Node renames Table.States 
(State_Index).Action_List (1);
-                     Action : constant Reduce_Action_Rec := Node.Actions.Item;
-                  begin
-                     Set_Col (Indent);
-                     Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                       Symbols_Image (Table.States (State_Index)) & ", " &
-                       Image (Action.Production) & ", " &
-                       Count_Type'Image (Action.Token_Count) & ", ";
-
-                     Append
-                       ((if Generate_Data.Action_Names (Action.Production.LHS) 
= null then "null"
-                         elsif Generate_Data.Action_Names
-                           (Action.Production.LHS)(Action.Production.RHS) = 
null then "null"
-                         else Generate_Data.Action_Names
-                           (Action.Production.LHS)(Action.Production.RHS).all 
& "'Access"));
-                     Append (", ");
-                     Append
-                       ((if Generate_Data.Check_Names (Action.Production.LHS) 
= null then "null"
-                         elsif Generate_Data.Check_Names
-                           (Action.Production.LHS)(Action.Production.RHS) = 
null then "null"
-                         else Generate_Data.Check_Names
-                           (Action.Production.LHS)(Action.Production.RHS).all 
& "'Access"));
-
-                     Indent_Wrap (-Line & ");");
-                     Line_Count := Line_Count + 1;
-                     Indent     := Base_Indent;
-                  end;
-               end if;
-
-            else
-               for Node of Table.States (State_Index).Action_List loop
-                  Set_Col (Indent);
-                  declare
-                     Action_Node : Parse_Action_Node_Ptr := Node.Actions;
-                  begin
-                     case Action_Node.Item.Verb is
-                     when Shift =>
-                        Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                          Trimmed_Image (Node.Symbol) & ", ";
-                        Append (Image (Action_Node.Item.Production) & ", ");
-                        Append (Trimmed_Image (Action_Node.Item.State));
-                        Append (");");
-
-                     when Reduce | Accept_It =>
-                        Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                          Trimmed_Image (Node.Symbol);
-                        if Action_Node.Item.Verb = Reduce then
-                           Append (", Reduce");
-                        else
-                           Append (", Accept_It");
-                        end if;
-                        Append (", ");
-                        Append (Image (Action_Node.Item.Production) & ", ");
-                        Append (Count_Type'Image 
(Action_Node.Item.Token_Count) & ", ");
-                        Append
-                          ((if Generate_Data.Action_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                            elsif Generate_Data.Action_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                            then "null"
-                            else Generate_Data.Action_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                               "'Access"));
-                        Append (", ");
-                        Append
-                          ((if Generate_Data.Check_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                            elsif Generate_Data.Check_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                            then "null"
-                            else Generate_Data.Check_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                               "'Access"));
-                        Append (");");
-
-                     when Parse.LR.Error =>
-                        raise SAL.Programmer_Error;
-                     end case;
-                     Indent_Wrap (-Line);
-                     Line_Count := Line_Count + 1;
-
-                     loop
-                        Action_Node := Action_Node.Next;
-                        exit when Action_Node = null;
-                        --  There is a conflict; must be Shift/{Reduce|Accept} 
or Reduce/{Reduce|Accept}.
-                        --  The added parameters are the same in either case.
-                        case Action_Node.Item.Verb is
-                        when Reduce | Accept_It =>
-                           Line := +"Add_Conflict (Table.States (" & 
Trimmed_Image (State_Index) & "), " &
-                             Trimmed_Image (Node.Symbol) & ", ";
-                           Append (Image (Action_Node.Item.Production) & ", ");
-                           Append (Count_Type'Image 
(Action_Node.Item.Token_Count) & ", ");
-                           Append
-                             ((if Generate_Data.Action_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                               elsif Generate_Data.Action_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                               then "null"
-                               else Generate_Data.Action_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                                  "'Access"));
-                           Append (", ");
-                           Append
-                             ((if Generate_Data.Check_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                               elsif Generate_Data.Check_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                               then "null"
-                               else Generate_Data.Check_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                                  "'Access"));
-                           Indent_Wrap (-Line & ");");
-                           Line_Count := Line_Count + 1;
-
-                        when others =>
-                           raise SAL.Programmer_Error with "invalid conflict 
action verb: " &
-                             Parse.LR.Parse_Action_Verbs'Image 
(Action_Node.Item.Verb);
-                        end case;
-                     end loop;
-                  end;
-                  Indent := Base_Indent;
-               end loop;
-            end if;
-         end Actions;
-
-         if Table.States (State_Index).Goto_List.Length > 0 then
-            Indent_Line
-              ("Table.States (" & Trimmed_Image (State_Index) & 
").Goto_List.Set_Capacity (" &
-                 Trimmed_Image (Table.States (State_Index).Goto_List.Length) & 
");");
-         end if;
-         Gotos :
-         for Node of Table.States (State_Index).Goto_List loop
-            Set_Col (Indent);
-            Put ("Add_Goto (Table.States (" & Trimmed_Image (State_Index) & 
"), ");
-            Put_Line (Trimmed_Image (Node.Symbol) & ", " & Trimmed_Image 
(Node.State) & ");");
-            Line_Count := Line_Count + 1;
-         end loop Gotos;
-
-         if Input_Data.Language_Params.Error_Recover then
-            if Table.States (State_Index).Kernel.Length > 0 then
-               Indent_Wrap
-                 ("Table.States (" & Trimmed_Image (State_Index) & ").Kernel 
:= To_Vector (" &
-                    Image (Table.States (State_Index).Kernel, Strict => True) 
& ");");
-            end if;
-            if Table.States (State_Index).Minimal_Complete_Actions.Length > 0 
then
-               Indent_Wrap
-                 ("Table.States (" & Trimmed_Image (State_Index) & 
").Minimal_Complete_Actions := To_Vector (" &
-                    Strict_Image (Table.States 
(State_Index).Minimal_Complete_Actions, Strict => True) & ");");
-            end if;
-         end if;
-
-         if Line_Count > Lines_Per_Subr then
-            Line_Count := 0;
-            Indent := Indent - 3;
-            Indent_Line ("end Subr_" & Trimmed_Image (Subr_Count) & ";");
-
-            if State_Index < Table.States'Last then
-               Subr_Count := Subr_Count + 1;
-               Last_Subr_Closed := False;
-               Indent_Line ("procedure Subr_" & Trimmed_Image (Subr_Count));
-               Indent_Line ("is begin");
-               Indent := Indent + 3;
-            else
-               Last_Subr_Closed := True;
-            end if;
-         end if;
-
-      end loop Declare_Subroutines;
-
-      if not Last_Subr_Closed then
-         Indent := Indent - 3;
-         Indent_Line ("end Subr_" & Trimmed_Image (Subr_Count) & ";");
-      end if;
-
-      Indent := Indent - 3;
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-
-      for Subr in 1 .. Subr_Count loop
-         Indent_Line ("Subr_" & Trimmed_Image (Subr) & ";");
-      end loop;
-      Indent_Line ("Table.Error_Action := new Parse_Action_Node'((Verb => 
Error, others => <>), null);");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-   end Create_LR_Parser_Table;
-
-   procedure LR_Create_Create_Parser
-     (Input_Data    :         in     WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      Table : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-   begin
-      Indent_Line ("procedure Create_Parser");
-      case Common_Data.Interface_Kind is
-      when Process =>
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser.Parser;");
-            Indent_Line ("   Language_Fixes                 : in     
WisiToken.Parse.LR.Parser.Language_Fixes_Access;");
-            Indent_Line ("   Language_Matching_Begin_Tokens : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;");
-            Indent_Line
-              ("   Language_String_ID_Set       : in     
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;");
-         else
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;");
-         end if;
-         Indent_Line ("   Trace                        : not null access 
WisiToken.Trace'Class;");
-         Indent_Start ("   User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access");
-
-      when Module =>
-         Indent_Line ("  (Parser              :    out 
WisiToken.Parse.LR.Parser.Parser;");
-         Indent_Line ("   Env                 : in     Emacs_Env_Access;");
-         Indent_Start ("   Lexer_Elisp_Symbols : in     
Lexers.Elisp_Array_Emacs_Value");
-      end case;
-
-      if Common_Data.Text_Rep then
-         Put_Line (";");
-         Indent_Line ("   Text_Rep_File_Name : in String)");
-      else
-         Put_Line (")");
-      end if;
-
-      Indent_Line ("is");
-      Indent := Indent + 3;
-
-      Indent_Line ("use WisiToken.Parse.LR;");
-
-      if Common_Data.Text_Rep then
-         Create_LR_Parser_Core_1 (Common_Data, Generate_Data);
-         Indent_Line ("Table : constant Parse_Table_Ptr := Get_Text_Rep");
-         Indent_Line ("  (Text_Rep_File_Name, McKenzie_Param, Actions);");
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-
-      else
-         if Input_Data.Language_Params.Error_Recover then
-            Create_LR_Parser_Core_1 (Common_Data, Generate_Data);
-         end if;
-
-         Indent_Line ("Table : constant Parse_Table_Ptr := new Parse_Table");
-         Indent_Line ("  (State_First       => 0,");
-         Indent := Indent + 3;
-         Indent_Line ("State_Last        =>" & State_Index'Image 
(Table.State_Last) & ",");
-         Indent_Line ("First_Terminal    =>" & Token_ID'Image 
(Table.First_Terminal) & ",");
-         Indent_Line ("Last_Terminal     =>" & Token_ID'Image 
(Table.Last_Terminal) & ",");
-         Indent_Line ("First_Nonterminal =>" & Token_ID'Image 
(Table.First_Nonterminal) & ",");
-         Indent_Line ("Last_Nonterminal  =>" & Token_ID'Image 
(Table.Last_Nonterminal) & ");");
-         Indent := Indent - 3;
-
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("Table.McKenzie_Param := McKenzie_Param;");
-         end if;
-         Create_LR_Parser_Table (Input_Data, Generate_Data);
-         New_Line;
-      end if;
-
-      if Input_Data.Language_Params.Error_Recover then
-         Indent_Line ("WisiToken.Parse.LR.Parser.New_Parser");
-      else
-         Indent_Line ("WisiToken.Parse.LR.Parser_No_Recover.New_Parser");
-      end if;
-      Indent_Line ("  (Parser,");
-      case Common_Data.Interface_Kind is
-      when Process =>
-         Indent_Line ("   Trace,");
-         Indent_Line ("   Lexer.New_Lexer (Trace.Descriptor),");
-         Indent_Line ("   Table,");
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("   Language_Fixes,");
-            Indent_Line ("   Language_Matching_Begin_Tokens,");
-            Indent_Line ("   Language_String_ID_Set,");
-         end if;
-         Indent_Line ("   User_Data,");
-         Indent_Line ("   Max_Parallel         => 15,");
-         Indent_Line ("   Terminate_Same_State => True);");
-
-      when Module =>
-         Indent_Line ("   Lexer.New_Lexer (Env, Lexer_Elisp_Symbols),");
-         Indent_Line ("   Table, Max_Parallel => 15, Terminate_Same_State => 
True);");
-
-      end case;
-      Indent := Indent - 3;
-      Indent_Line ("end Create_Parser;");
-   end LR_Create_Create_Parser;
-
-   procedure Packrat_Create_Create_Parser
-     (Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data;
-      Packrat_Data  :         in     WisiToken.Generate.Packrat.Data)
-   is
-      use Ada.Strings.Unbounded;
-
-      Text     : Unbounded_String;
-      Need_Bar : Boolean := True;
-   begin
-      Indent_Line ("function Create_Parser");
-      Indent_Line ("  (Trace     : not null access WisiToken.Trace'Class;");
-      Indent_Line ("   User_Data : in     
WisiToken.Syntax_Trees.User_Data_Access)");
-      Indent_Line ("  return WisiToken.Parse.Base_Parser'Class");
-
-      case Packrat_Generate_Algorithm'(Common_Data.Generate_Algorithm) is
-      when Packrat_Gen =>
-         Indent_Line ("is begin");
-         Indent := Indent + 3;
-         Indent_Line ("return Parser : 
WisiToken.Parse.Packrat.Generated.Parser do");
-         Indent := Indent + 3;
-         Indent_Line ("Parser.Trace := Trace;");
-         Indent_Line ("Parser.Lexer := Lexer.New_Lexer (Trace.Descriptor);");
-         Indent_Line ("Parser.User_Data := User_Data;");
-         Indent_Line ("Parser.Parse_WisiToken_Accept := 
Parse_wisitoken_accept_1'Access;");
-         Indent := Indent - 3;
-         Indent_Line ("end return;");
-
-      when Packrat_Proc =>
-         Indent_Line ("is");
-         Indent := Indent + 3;
-         Indent_Line ("use WisiToken;");
-         Indent_Line ("use WisiToken.Productions;");
-         Indent_Line ("Grammar               : Prod_Arrays.Vector;");
-         Indent_Line
-           ("Direct_Left_Recursive : constant WisiToken.Token_ID_Set (" &
-              Trimmed_Image (Generate_Data.Grammar.First_Index) & " .. " &
-              Trimmed_Image (Generate_Data.Grammar.Last_Index) & ") :=");
-
-         Need_Bar := False;
-         if Any (Packrat_Data.Direct_Left_Recursive) then
-            for I in Packrat_Data.Direct_Left_Recursive'Range loop
-               if Packrat_Data.Direct_Left_Recursive (I) then
-                  if Need_Bar then
-                     Text := Text & " | ";
-                  else
-                     Need_Bar := True;
-                  end if;
-                  Text := Text & Trimmed_Image (I);
-               end if;
-            end loop;
-            Indent_Start ("  (");
-            Indent := Indent + 3;
-            Indent_Wrap (-Text & " => True,");
-            Indent_Line ("others => False);");
-            Indent := Indent - 3;
-         else
-            Indent_Line ("  (others => False);");
-         end if;
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-         WisiToken.BNF.Generate_Grammar (Generate_Data.Grammar, 
Generate_Data.Action_Names.all);
-
-         Indent_Line ("return WisiToken.Parse.Packrat.Procedural.Create");
-         Indent_Line
-           ("  (Grammar, Direct_Left_Recursive, " & Trimmed_Image 
(Generate_Data.Descriptor.Accept_ID) &
-              ", Trace, Lexer.New_Lexer (Trace.Descriptor), User_Data);");
-      end case;
-      Indent := Indent - 3;
-      Indent_Line ("end Create_Parser;");
-      New_Line;
-   end Packrat_Create_Create_Parser;
-
-   procedure External_Create_Create_Grammar
-     (Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is begin
-      Indent_Line ("function Create_Grammar return 
WisiToken.Productions.Prod_Arrays.Vector");
-      Indent_Line ("is");
-      Indent_Line ("   use WisiToken;");
-      Indent_Line ("   use WisiToken.Productions;");
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-      Indent_Line ("return Grammar : WisiToken.Productions.Prod_Arrays.Vector 
do");
-      Indent := Indent + 3;
-      WisiToken.BNF.Generate_Grammar (Generate_Data.Grammar, 
Generate_Data.Action_Names.all);
-      Indent := Indent - 3;
-      Indent_Line ("end return;");
-      Indent := Indent - 3;
-      Indent_Line ("end Create_Grammar;");
-   end External_Create_Create_Grammar;
-
-   procedure Create_re2c
-     (Input_Data            :         in 
WisiToken_Grammar_Runtime.User_Data_Type;
-      Tuple                 :         in Generate_Tuple;
-      Generate_Data         : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data;
-      Output_File_Name_Root :         in String)
-   is
-      use Ada.Strings.Fixed;
-      use Generate_Utils;
-      use WisiToken.BNF.Utils;
-      File : File_Type;
-   begin
-      Create (File, Out_File, Output_File_Name_Root & ".re2c");
-      Set_Output (File);
-      Indent := 1;
-
-      Put_File_Header (C_Comment, " -*- mode: C -*-", Use_Tuple => True, Tuple 
=> Tuple);
-      Put_Raw_Code (C_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      Indent_Line ("#include <stddef.h>"); -- size_t
-      Indent_Line ("#include <stdio.h>"); -- printf
-      Indent_Line ("#include <stdlib.h>"); -- malloc
-      New_Line;
-
-      Indent_Line ("typedef struct wisi_lexer");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("unsigned char* buffer;           // input text, in utf-8 
encoding");
-      Indent_Line ("unsigned char* buffer_last;      // last byte in buffer");
-      Indent_Line ("unsigned char* cursor;           // current byte");
-      Indent_Line ("unsigned char* byte_token_start; // byte position at start 
of current token");
-      Indent_Line ("size_t         char_pos;         // character position of 
current character");
-      Indent_Line ("size_t         char_token_start; // character position at 
start of current token");
-      Indent_Line ("int            line;             // 1 indexed");
-      Indent_Line ("int            line_token_start; // line at start of 
current token");
-      Indent_Line ("unsigned char* marker;           // saved cursor");
-      Indent_Line ("size_t         marker_pos;       // saved character 
position");
-      Indent_Line ("size_t         marker_line;      // saved line");
-      Indent_Line ("unsigned char* context;          // saved cursor");
-      Indent_Line ("size_t         context_pos;      // saved character 
position");
-      Indent_Line ("int            context_line;     // saved line");
-      Indent_Line ("int            verbosity;");
-      New_Line;
-      Indent := Indent - 3;
-      Indent_Line ("} wisi_lexer;");
-      New_Line;
-      Indent_Line ("#define YYCTYPE unsigned char");
-      New_Line;
-
-      --  Status values:
-      Indent_Line ("#define NO_ERROR 0");
-      Indent_Line ("#define ERROR_unrecognized_character 1");
-
-      ----------
-      --  new_lexer, free_lexer, reset_lexer
-
-      --  It's normal to increment lexer->cursor one past the end of input,
-      --  but not to read that character. To support memory mapped files, we
-      --  enforce this strictly; YYPEEK returns EOT (end of text) when
-      --  reading past end of buffer; that's how we recognize the end of
-      --  text token.
-
-      Indent_Line ("wisi_lexer* " & Output_File_Name_Root & "_new_lexer");
-      Indent_Line ("   (unsigned char* input, size_t length, int verbosity)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("wisi_lexer* result        = malloc (sizeof 
(wisi_lexer));");
-      Indent_Line ("result->buffer            = input;");
-      Indent_Line ("result->buffer_last       = input + length - 1;");
-      Indent_Line ("result->cursor            = input;");
-      Indent_Line ("result->byte_token_start  = input;");
-      Indent_Line ("result->char_pos          = 1; /* match 
WisiToken.Buffer_Region */");
-      Indent_Line ("result->char_token_start  = 1;");
-      Indent_Line ("result->line              = (*result->cursor == 0x0A) ? 2 
: 1;");
-      Indent_Line ("result->line_token_start  = result->line;");
-      Indent_Line ("result->verbosity         = verbosity;");
-      Indent_Line ("return result;");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      New_Line;
-
-      Indent_Line ("void");
-      Indent_Line (Output_File_Name_Root & "_free_lexer(wisi_lexer** lexer)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("free(*lexer);");
-      Indent_Line ("*lexer = 0;");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      New_Line;
-
-      Indent_Line ("void");
-      Indent_Line (Output_File_Name_Root & "_reset_lexer(wisi_lexer* lexer)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("lexer->cursor   = lexer->buffer;");
-      Indent_Line ("lexer->char_pos = 1;");
-      Indent_Line ("lexer->line     = (*lexer->cursor == 0x0A) ? 2 : 1;");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      New_Line;
-
-      ----------
-      --  next_token utils
-
-      Indent_Line ("static void debug(wisi_lexer* lexer, int state, unsigned 
char ch)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("if (lexer->verbosity > 0)");
-      Indent_Line ("   {");
-      Indent_Line ("   if (ch < ' ')");
-      Indent_Line ("      printf (""lexer: %d, 0x%x\n"", state, ch);");
-      Indent_Line ("   else");
-      Indent_Line ("      printf (""lexer: %d, '%c' 0x%x\n"", state, ch, 
ch);");
-      Indent_Line ("   }");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      Indent_Line ("#define YYDEBUG(state, ch) debug(lexer, state, ch)");
-
-      --  YYCURSOR is only used in calls of YYDEBUG; we can't define it as
-      --  YYPEEK because it is used as '*YYCURSOR'.
-      Indent_Line ("#define YYCURSOR lexer->cursor");
-      New_Line;
-
-      Indent_Line ("#define YYPEEK() (lexer->cursor <= lexer->buffer_last) ? 
*lexer->cursor : 4");
-      New_Line;
-
-      Indent_Line ("static void skip(wisi_lexer* lexer)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("if (lexer->cursor <= lexer->buffer_last)");
-      Indent_Line ("   ++lexer->cursor;");
-      Indent_Line ("if (lexer->cursor <= lexer->buffer_last)");
-      Indent_Line ("{");
-      Indent_Line ("   /* UFT-8 encoding: 
https://en.wikipedia.org/wiki/UTF-8#Description */");
-      Indent_Line ("   if (*lexer->cursor == 0x0A && lexer->cursor > 
lexer->buffer && *(lexer->cursor - 1) == 0x0D)");
-      Indent_Line ("     {/* second byte of DOS line ending */");
-      Indent_Line ("     }");
-      Indent_Line ("   else if ((*lexer->cursor & 0x80) == 0x80 && 
(*lexer->cursor & 0xC0) != 0xC0)");
-      Indent_Line ("     {/* byte 2, 3 or 4 of multi-byte UTF-8 char */");
-      Indent_Line ("     }");
-      Indent_Line ("   else");
-      Indent_Line ("     ++lexer->char_pos;");
-      Indent_Line ("   if (*lexer->cursor == 0x0A) ++lexer->line;");
-      Indent_Line ("}");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      Indent_Start ("#define YYSKIP() skip(lexer)");
-      New_Line;
-
-      Indent_Line ("#define YYBACKUP() lexer->marker = lexer->cursor; 
lexer->marker_pos = lexer->char_pos;" &
-                     "lexer->marker_line = lexer->line");
-      Indent_Line ("#define YYRESTORE() lexer->cursor = lexer->marker; 
lexer->char_pos = lexer->marker_pos;" &
-                     "lexer->line = lexer->marker_line");
-      Indent_Line ("#define YYBACKUPCTX() lexer->context = lexer->cursor; 
lexer->context_pos = lexer->char_pos;" &
-                     "lexer->context_line = lexer->line");
-      Indent_Line ("#define YYRESTORECTX() lexer->cursor = lexer->context; 
lexer->char_pos = lexer->context_pos;" &
-                     "lexer->line = lexer->context_line");
-      New_Line;
-
-      if Is_In (Input_Data.Tokens.Tokens, "delimited-text") then
-         Indent_Line ("static void skip_to(wisi_lexer* lexer, char* target)");
-         Indent_Line ("{");
-         Indent_Line ("  int i;");
-         New_Line;
-         Indent_Line ("  while (lexer->cursor <= lexer->buffer_last)");
-         Indent_Line ("    {");
-         Indent_Line ("      if (*lexer->cursor == target[0])");
-         Indent_Line ("      {");
-         Indent_Line ("        i = 0;");
-         Indent_Line ("        do");
-         Indent_Line ("          i++;");
-         Indent_Line ("        while (0 != target[i] &&");
-         Indent_Line ("               lexer->cursor + i <= lexer->buffer_last 
&&");
-         Indent_Line ("               *(lexer->cursor + i) == target[i]);");
-         New_Line;
-         Indent_Line ("        if (0 == target[i])");
-         Indent_Line ("          {");
-         Indent_Line ("            for (i = 0; 0 != target[i]; i++)");
-         Indent_Line ("               skip(lexer);");
-         Indent_Line ("            break;");
-         Indent_Line ("          }");
-         Indent_Line ("      }");
-         Indent_Line ("      skip(lexer);");
-         Indent_Line ("    };");
-         Indent_Line ("}");
-         New_Line;
-      end if;
-
-      ----------
-      --  next_token
-      Indent_Line ("int " & Output_File_Name_Root & "_next_token");
-      Indent_Line ("  (wisi_lexer* lexer,");
-      Indent_Line ("   int* id,");
-      Indent_Line ("   size_t* byte_position,");
-      Indent_Line ("   size_t* byte_length,");
-      Indent_Line ("   size_t* char_position,");
-      Indent_Line ("   size_t* char_length,");
-      Indent_Line ("   int*    line_start)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-
-      Indent_Line ("int status = NO_ERROR;");
-      Indent_Line ("*id = -1;"); --  Token_ID'First = 0; see dragon_4_43.wy
-
-      Indent_Line ("if (lexer->cursor > lexer->buffer_last)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-      Indent_Line ("*id            =" & WisiToken.Token_ID'Image 
(Generate_Data.Descriptor.EOI_ID) & ";");
-      Indent_Line ("*byte_position = lexer->buffer_last - lexer->buffer + 1;");
-      Indent_Line ("*byte_length   = 0;");
-      Indent_Line ("*char_position = lexer->char_token_start;");
-      Indent_Line ("*char_length   = 0;");
-      Indent_Line ("*line_start    = lexer->line;");
-      Indent_Line ("return status;");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-      New_Line;
-
-      Indent_Line ("lexer->byte_token_start = lexer->cursor;");
-      Indent_Line ("lexer->char_token_start = lexer->char_pos;");
-      Indent_Line ("if (*lexer->cursor == 0x0A)");
-      Indent_Line ("   lexer->line_token_start = lexer->line-1;");
-      Indent_Line ("else");
-      Indent_Line ("   lexer->line_token_start = lexer->line;");
-      New_Line;
-
-      Indent_Line ("while (*id == -1 && status == 0)");
-      Indent_Line ("{");
-      Indent := Indent + 3;
-
-      Put_Line ("/*!re2c");
-      Indent_Line ("re2c:yyfill:enable   = 0;");
-      Indent_Line ("re2c:sentinel   = 4;");
-      New_Line;
-
-      --  Regexps used in definitions
-      for Pair of Input_Data.Tokens.re2c_Regexps loop
-         Indent_Line (-Pair.Name & " = " & (-Pair.Value) & ";");
-      end loop;
-      New_Line;
-
-      --  definitions
-      for I in All_Tokens (Generate_Data).Iterate (Non_Grammar => True, 
Nonterminals => False) loop
-
-         if 0 /= Index (Source => Value (I), Pattern => "/") then
-            --  trailing context syntax; forbidden in definitions
-            null;
-
-         elsif Kind (I) = "EOI" then
-            Indent_Line (Name (I) & " = [\x04];");
-
-         elsif Kind (I) = "delimited-text" then
-            --  not declared in definitions
-            null;
-
-         elsif Kind (I) = "keyword" and 
Input_Data.Language_Params.Case_Insensitive then
-            --  This assumes re2c regular expression syntax, where single quote
-            --  means case insensitive.
-            Indent_Line (Name (I) & " = '" & Strip_Quotes (Value (I)) & "';");
-
-         else
-            --  Other kinds have values that are regular expressions, in re2c 
syntax
-            Indent_Line (Name (I) & " = " & Value (I) & ";");
-         end if;
-      end loop;
-      New_Line;
-
-      --  lexer rules
-      for I in All_Tokens (Generate_Data).Iterate (Non_Grammar => True, 
Nonterminals => False) loop
-         declare
-            Val : constant String := Value (I);
-         begin
-
-            if Kind (I) = "non-reporting" then
-               Indent_Line (Name (I) & " { lexer->byte_token_start = 
lexer->cursor;");
-               Indent_Line ("    lexer->char_token_start = lexer->char_pos;");
-               Indent_Line ("    if (*lexer->cursor == 0x0A)");
-               Indent_Line ("       lexer->line_token_start = lexer->line-1;");
-               Indent_Line ("    else");
-               Indent_Line ("       lexer->line_token_start = lexer->line;");
-               Indent_Line ("    continue; }");
-
-            elsif Kind (I) = "delimited-text" then
-               Indent_Line
-                    (Val & " {*id = " & WisiToken.Token_ID'Image (ID (I)) &
-                       "; skip_to(lexer, " & Repair_Image (I) & "); 
continue;}");
-
-            elsif 0 /= Index (Source => Val, Pattern => "/") then
-               Indent_Line (Val & " {*id = " & WisiToken.Token_ID'Image (ID 
(I)) & "; continue;}");
-
-            else
-               Indent_Line (Name (I) & " {*id = " & WisiToken.Token_ID'Image 
(ID (I)) & "; continue;}");
-            end if;
-         end;
-      end loop;
-      New_Line;
-
-      --  Default action.
-      Indent_Line ("* {status = ERROR_unrecognized_character; continue;}");
-
-      Put_Line ("*/");
-      Indent := Indent - 3;
-      Indent_Line ("}");
-
-      Indent_Line ("/* lexer->cursor and lexer ->char_pos are one char past 
end of token */");
-      Indent_Line ("*byte_position = lexer->byte_token_start - lexer->buffer + 
1;");
-      Indent_Line ("*byte_length   = lexer->cursor - 
lexer->byte_token_start;");
-      Indent_Line ("*char_position = lexer->char_token_start;");
-      Indent_Line ("*char_length   = lexer->char_pos - 
lexer->char_token_start;");
-      Indent_Line ("*line_start    = lexer->line_token_start;");
-      Indent_Line ("return status;");
-      Indent_Line ("}");
-      Indent := Indent - 3;
-      Set_Output (Standard_Output);
-      Close (File);
-
-      declare
-         Ada_Name : constant String := Output_File_Name_Root & "_re2c_c";
-         --  Output_File_Name_Root is the file name of the grammar file -
-         --  assume it is a legal Ada name.
-      begin
-         Create (File, Out_File, Output_File_Name_Root & "_re2c_c.ads");
-         Set_Output (File);
-         Indent := 1;
-         Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-         Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-         New_Line;
-
-         Put_Line ("with Interfaces.C;");
-         Put_Line ("with WisiToken;");
-         Put_Line ("with System;");
-         Put_Line ("package " & Ada_Name & " is");
-         Indent := Indent + 3;
-         New_Line;
-
-         Indent_Line ("function New_Lexer");
-         Indent_Line ("  (Buffer    : in System.Address;");
-         Indent_Line ("   Length    : in Interfaces.C.size_t;");
-         Indent_Line ("   Verbosity : in Interfaces.C.int)");
-         Indent_Line ("  return System.Address");
-         Indent_Line ("with Import        => True,");
-         Indent_Line ("     Convention    => C,");
-         Indent_Line ("     External_Name => """ & Output_File_Name_Root & 
"_new_lexer"";");
-         Indent_Line ("--  Create the lexer object, passing it the full text 
to process.");
-         New_Line;
-         Indent_Line ("procedure Free_Lexer (Lexer : in out System.Address)");
-         Indent_Line ("with Import        => True,");
-         Indent_Line ("     Convention    => C,");
-         Indent_Line ("     External_Name => """ & Output_File_Name_Root & 
"_free_lexer"";");
-         Indent_Line ("--  Free the lexer object");
-         New_Line;
-
-         Indent_Line ("procedure Reset_Lexer (Lexer : in System.Address)");
-         Indent_Line ("with Import        => True,");
-         Indent_Line ("     Convention    => C,");
-         Indent_Line ("     External_Name => """ & Output_File_Name_Root & 
"_reset_lexer"";");
-         New_Line;
-
-         Indent_Line ("function Next_Token");
-         Indent_Line ("  (Lexer         : in     System.Address;");
-         Indent_Line ("   ID            :    out WisiToken.Token_ID;");
-         Indent_Line ("   Byte_Position :    out Interfaces.C.size_t;");
-         Indent_Line ("   Byte_Length   :    out Interfaces.C.size_t;");
-         Indent_Line ("   Char_Position :    out Interfaces.C.size_t;");
-         Indent_Line ("   Char_Length   :    out Interfaces.C.size_t;");
-         Indent_Line ("   Line_Start    :    out Interfaces.C.int)");
-         Indent_Line ("  return Interfaces.C.int");
-         Indent_Line ("with Import        => True,");
-         Indent_Line ("     Convention    => C,");
-         Indent_Line ("     External_Name => """ & Output_File_Name_Root & 
"_next_token"";");
-         New_Line;
-
-         Indent := Indent - 3;
-         Put_Line ("end " & Ada_Name & ";");
-         Set_Output (Standard_Output);
-         Close (File);
-      end;
-   end Create_re2c;
-
-   function File_Name_To_Ada (File_Name : in String) return String
-   is
-      Result : String := File_Name;
-   begin
-      Result (Result'First) := To_Upper (Result (Result'First));
-      for I in Result'Range loop
-         if Result (I) = '-' then
-            Result (I) := '.';
-            Result (I + 1) := To_Upper (Result (I + 1));
-         elsif Result (I) = '_' then
-            Result (I + 1) := To_Upper (Result (I + 1));
-         end if;
-      end loop;
-      return Result;
-   end File_Name_To_Ada;
-
-   function Initialize
-     (Input_Data        : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Tuple             : in Generate_Tuple;
-      Output_File_Root  : in String;
-      Check_Interface   : in Boolean)
-     return Common_Data
-   is begin
-      return Data : Common_Data do
-         Data.Generate_Algorithm := Tuple.Gen_Alg;
-
-         Data.Output_Language := Ada_Output_Language (Tuple.Out_Lang);
-
-         if Tuple.Gen_Alg = External or else Input_Data.User_Lexer in 
Valid_Lexer then
-            Data.Lexer := Input_Data.User_Lexer;
-         else
-            raise SAL.Programmer_Error with "tuple.alg " & 
Generate_Algorithm'Image (Tuple.Gen_Alg) &
-              " input_data.user_lexer " & Lexer_Image 
(Input_Data.User_Lexer).all;
-         end if;
-
-         if Check_Interface then
-            if Tuple.Interface_Kind in Valid_Interface then
-               Data.Interface_Kind := Valid_Interface (Tuple.Interface_Kind);
-            else
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, 1, "Interface_Kind 
not set"));
-            end if;
-         else
-            Data.Interface_Kind := Process;
-         end if;
-
-         Data.Text_Rep := Tuple.Text_Rep;
-
-         Data.Lower_File_Name_Root := +To_Lower (Output_File_Root);
-      end return;
-   end Initialize;
-
-   function To_Token_Ada_Name (WY_Name : in String) return String
-   is
-      --  Convert WY_Name to a valid Ada identifier:
-      --
-      --  Add "_ID" to avoid collision with Ada reserved words
-      --
-      --  Replace '-' with '_'
-      Image : String := WY_Name;
-   begin
-      for I in Image'Range loop
-         if Image (I) = '-' then
-            Image (I) := '_';
-         end if;
-      end loop;
-      return Image & "_ID";
-   end To_Token_Ada_Name;
-
-end WisiToken.BNF.Output_Ada_Common;
diff --git a/packages/wisi/wisitoken-bnf-output_ada_common.ads 
b/packages/wisi/wisitoken-bnf-output_ada_common.ads
deleted file mode 100644
index 44d7a63..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada_common.ads
+++ /dev/null
@@ -1,90 +0,0 @@
---  Abstract :
---
---  Types and operations shared by Ada and Ada_Emacs outputs.
---
---  Copyright (C) 2017, 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.Generate.Packrat;
-with WisiToken_Grammar_Runtime;
-package WisiToken.BNF.Output_Ada_Common is
-
-   function To_Token_Ada_Name (WY_Name : in String) return String;
-
-   type Common_Data is limited record
-      --  Validated versions of Tuple values
-      Generate_Algorithm : WisiToken.BNF.Valid_Generate_Algorithm;
-      Lexer              : Lexer_Type; --  'none' valid for Libadalang
-      Output_Language    : Ada_Output_Language;
-      Interface_Kind     : Valid_Interface;
-      Text_Rep           : Boolean;
-
-      Lower_File_Name_Root : Standard.Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   function Initialize
-     (Input_Data        : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Tuple             : in Generate_Tuple;
-      Output_File_Root  : in String;
-      Check_Interface   : in Boolean)
-     return Common_Data;
-
-   function File_Name_To_Ada (File_Name : in String) return String;
-
-   procedure Create_Ada_Actions_Spec
-     (Output_File_Name :         in String;
-      Package_Name     :         in String;
-      Input_Data       :         in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data      :         in Output_Ada_Common.Common_Data;
-      Generate_Data    : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data);
-
-   procedure Create_Ada_Main_Spec
-     (Output_File_Name  : in String;
-      Main_Package_Name : in String;
-      Input_Data        : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data       : in Output_Ada_Common.Common_Data)
-   with Pre => Common_Data.Generate_Algorithm /= External;
-
-   procedure Create_External_Main_Spec
-     (Main_Package_Name    : in String;
-      Tuple                : in Generate_Tuple;
-      Input_Data           : in WisiToken_Grammar_Runtime.User_Data_Type);
-
-   procedure LR_Create_Create_Parser
-     (Input_Data    :         in     WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data);
-   --  If not Common_Data.Text_Rep, includes LR parse table in generated
-   --  source. Otherwise, includes call to LR.Get_Text_Rep; caller must
-   --  call Put_Text_Rep to create file.
-
-   procedure Packrat_Create_Create_Parser
-     (Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data;
-      Packrat_Data  :         in     WisiToken.Generate.Packrat.Data);
-
-   procedure External_Create_Create_Grammar
-     (Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data);
-
-   procedure Create_re2c
-     (Input_Data            :         in 
WisiToken_Grammar_Runtime.User_Data_Type;
-      Tuple                 :         in Generate_Tuple;
-      Generate_Data         : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data;
-      Output_File_Name_Root :         in String);
-   --  Create_re2c is called from wisitoken-bnf-generate, which does not 
declare
-   --  Common_Data.
-
-end WisiToken.BNF.Output_Ada_Common;
diff --git a/packages/wisi/wisitoken-bnf-output_ada_emacs.adb 
b/packages/wisi/wisitoken-bnf-output_ada_emacs.adb
deleted file mode 100644
index c0e91c2..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada_emacs.adb
+++ /dev/null
@@ -1,1916 +0,0 @@
---  Abstract :
---
---  Output Ada code implementing the grammar defined by input
---  parameters, and a parser for that grammar. The parser actions
---  assume the Emacs Ada mode wisi indentation engine
---
---  If run in a separate process communicating over pipes with the
---  Emacs process, the parser actions output encoded elisp actions;
---  the protocol is documented in Emacs Ada mode wisi-process-parse.el,
---  function wisi-process-parse-execute.
---
---  If run in an Emacs dynamically loaded module, the parser actions
---  call the elisp actions directly.
---
---  Copyright (C) 2012 - 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Strings.Maps;
-with Ada.Text_IO; use Ada.Text_IO;
-with WisiToken.BNF.Generate_Packrat;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.BNF.Output_Ada_Common; use WisiToken.BNF.Output_Ada_Common;
-with WisiToken.BNF.Output_Elisp_Common; use WisiToken.BNF.Output_Elisp_Common;
-with WisiToken.Generate.Packrat;
-with WisiToken_Grammar_Runtime;
-procedure WisiToken.BNF.Output_Ada_Emacs
-  (Input_Data            :         in WisiToken_Grammar_Runtime.User_Data_Type;
-   Output_File_Name_Root :         in String;
-   Generate_Data         : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data;
-   Packrat_Data          :         in WisiToken.Generate.Packrat.Data;
-   Tuple                 :         in Generate_Tuple;
-   Test_Main             :         in Boolean;
-   Multiple_Tuples       :         in Boolean;
-   Language_Name         :         in String)
-is
-   use all type Ada.Containers.Count_Type;
-
-   Default_Language_Runtime_Package : constant String := "Wisi." & 
Language_Name;
-
-   Blank_Set : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set (" ");
-   Numeric   : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set ("0123456789");
-
-   Common_Data : Output_Ada_Common.Common_Data := 
WisiToken.BNF.Output_Ada_Common.Initialize
-     (Input_Data, Tuple, Output_File_Name_Root, Check_Interface => True);
-
-   Gen_Alg_Name : constant String :=
-     (if Test_Main or Multiple_Tuples
-      then "_" & WisiToken.BNF.Generate_Algorithm_Image 
(Common_Data.Generate_Algorithm).all
-      else "");
-
-   function Split_Sexp
-     (Item            : in String;
-      Input_File_Name : in String;
-      Source_Line     : in WisiToken.Line_Number_Type)
-     return String_Lists.List
-   is
-      --  Return one sexp per element. Remove comments, newlines, and outer 
'(progn )'.
-
-      use WisiToken.Generate;
-
-      Progn_Index : constant Integer := Ada.Strings.Fixed.Index (Item, 
"(progn");
-
-      Item_I : Integer := Item'First;
-
-      Buffer       : String (Item'First .. Item'Last);
-      Buffer_J     : Integer := Buffer'First;
-      Buffer_First : Integer := Buffer'First;
-      Paren_Count  : Integer := 0;
-      In_Comment   : Boolean := False;
-      Result       : String_Lists.List;
-
-      Delete_Last_Paren : Boolean := False;
-   begin
-      --  Loop thru Item, copying chars to Buffer, ignoring comments, newlines.
-
-      if 0 /= Progn_Index then
-         Item_I := Progn_Index + 6;
-
-         Delete_Last_Paren := True;
-      end if;
-
-      loop
-         exit when Item_I > Item'Last;
-
-         if In_Comment then
-            if Item (Item_I) in ASCII.CR | ASCII.LF then
-               In_Comment := False;
-            end if;
-         else
-            if Item (Item_I) = '(' then
-               if Paren_Count = 0 then
-                  Buffer_First := Buffer_J;
-               end if;
-               Paren_Count := Paren_Count + 1;
-
-               Buffer (Buffer_J) := Item (Item_I);
-               Buffer_J := Buffer_J + 1;
-
-            elsif Item (Item_I) = ')' then
-               Paren_Count := Paren_Count - 1;
-               if Paren_Count = 0 then
-                  Buffer (Buffer_J) := Item (Item_I);
-                  Result.Append (Buffer (Buffer_First .. Buffer_J));
-                  Buffer_First := Buffer'First;
-                  Buffer_J     := Buffer'First;
-
-               elsif Paren_Count = -1 then
-                  if Delete_Last_Paren then
-                     --  all done
-                     return Result;
-                  else
-                     Put_Error (Error_Message (Input_File_Name, Source_Line, 
"mismatched parens"));
-                     return String_Lists.Empty_List;
-                  end if;
-               else
-                  Buffer (Buffer_J) := Item (Item_I);
-                  Buffer_J := Buffer_J + 1;
-               end if;
-
-            elsif Item (Item_I) in ASCII.CR | ASCII.LF then
-               null;
-
-            elsif Item (Item_I) = ';' and then Item_I < Item'Last and then 
Item (Item_I + 1) = ';' then
-               In_Comment := True;
-
-            else
-               Buffer (Buffer_J) := Item (Item_I);
-               Buffer_J := Buffer_J + 1;
-            end if;
-         end if;
-         Item_I := Item_I + 1;
-      end loop;
-      if Paren_Count /= 0 then
-         Put_Error
-           (Error_Message
-              (Input_File_Name, Source_Line, "mismatched parens"));
-      end if;
-      return Result;
-   end Split_Sexp;
-
-   procedure Create_Ada_Action
-     (Name          : in String;
-      RHS           : in RHS_Type;
-      Prod_ID       : in WisiToken.Production_ID;
-      Unsplit_Lines : in Ada.Strings.Unbounded.Unbounded_String;
-      Labels        : in String_Arrays.Vector;
-      Check         : in Boolean)
-   is
-      --  Create Action (if Check = False; Lines must be RHS.Action) or
-      --  Check (if Check = True; Lines must be RHS.Check) subprogram named
-      --  Name for RHS.
-
-      use Ada.Strings;
-      use Ada.Strings.Fixed;
-      use Ada.Strings.Unbounded;
-      use WisiToken.Generate;
-
-      Sexps : constant String_Lists.List := Split_Sexp
-        (-Unsplit_Lines, Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line);
-
-      use all type Ada.Strings.Maps.Character_Set;
-
-      Space_Paren_Set : constant Ada.Strings.Maps.Character_Set :=
-        Ada.Strings.Maps.To_Set ("])") or Blank_Set;
-
-      Navigate_Lines     : String_Lists.List;
-      Face_Line          : Unbounded_String;
-      Indent_Action_Line : Unbounded_String;
-      Check_Line         : Unbounded_String;
-
-      Label_Needed   : array (Labels.First_Index .. Labels.Last_Index) of 
Boolean := (others => False);
-      Nonterm_Needed : Boolean := False;
-
-      function Label_Used (Label : in String) return Boolean
-      is
-         Found : Boolean := False;
-      begin
-         for Tok of RHS.Tokens loop
-            if -Tok.Label = Label then
-               Found := True;
-               exit;
-            end if;
-         end loop;
-
-         if not Found then
-            return False;
-         end if;
-
-         for I in Labels.First_Index .. Labels.Last_Index loop
-            if Label = Labels (I) then
-               Label_Needed (I) := True;
-               return True;
-            end if;
-         end loop;
-         raise SAL.Programmer_Error;
-      end Label_Used;
-
-      function Count_Label_Needed return Ada.Containers.Count_Type
-      is
-         use Ada.Containers;
-         Result : Count_Type := 0;
-      begin
-         for B of Label_Needed loop
-            if B then Result := Result + 1; end if;
-         end loop;
-         return Result;
-      end Count_Label_Needed;
-
-      function Find_Token_Index (I : in Base_Identifier_Index) return 
SAL.Base_Peek_Type
-      is
-         Rule_Label : constant String := -Labels (I);
-      begin
-         for I in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index loop
-            if Length (RHS.Tokens (I).Label) > 0 and then
-              -RHS.Tokens (I).Label = Rule_Label
-            then
-               return I;
-            end if;
-         end loop;
-         return SAL.Base_Peek_Type'First;
-      end Find_Token_Index;
-
-      function Statement_Params (Params : in String) return String
-      is
-         --  Input looks like: [1 function 2 other ...]
-         --  Numbers can be token labels.
-
-         Last       : Integer := Index_Non_Blank (Params); -- skip [
-         First      : Integer;
-         Second     : Integer;
-         Need_Comma : Boolean := False;
-         Result     : Unbounded_String;
-         Count      : Integer := 0;
-      begin
-         loop
-            First  := Last + 1;
-            Second := Index (Params, Blank_Set, First);
-            exit when Second = 0;
-
-            Last := Index (Params, Space_Paren_Set, Second + 1);
-
-            declare
-               Label : constant String := Params (First .. Second - 1);
-            begin
-               if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                  Count := Count + 1;
-                  Result := Result & (if Need_Comma then ", " else "") &
-                    "(" & Label & ", " &
-                    Elisp_Name_To_Ada (Params (Second + 1 .. Last - 1), 
Append_ID => False, Trim => 0) & ")";
-
-                  Need_Comma := True;
-               --  else skip
-               end if;
-            end;
-         end loop;
-         Nonterm_Needed := True;
-         return " (Parse_Data, Tree, Nonterm, Tokens, " &
-           (case Count is
-            when 0 => "(1 .. 0 => (1, Motion)))",
-            when 1 => "(1 => " & (-Result) & "))",
-            when others =>  "(" & (-Result) & "))");
-      end Statement_Params;
-
-      function Motion_Params (Params : in String) return String
-      is
-         --  Input looks like: [1 [2 EXCEPTION] 3 ...]
-         --  Result: (..., Motion_Param_Array'((1, Invalid_Token_ID) & (2, 3) 
& (3, Invalid_Token_ID))
-         use Generate_Utils;
-         use Ada.Strings.Maps;
-
-         Delim : constant Character_Set := To_Set ("]") or Blank_Set;
-
-         Last   : Integer          := Index_Non_Blank (Params); -- skip [
-         First  : Integer;
-         Vector : Boolean;
-         Result : Unbounded_String;
-
-         Index_First  : Integer;
-         Index_Last   : Integer;
-         ID           : Unbounded_String;
-         Need_Comma : Boolean := False;
-         Count      : Integer          := 0;
-      begin
-         loop
-            if not (Last in Params'First .. Params'Last) then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line,
-                     "Missing ']' or ')'"));
-               exit;
-            end if;
-            Last := Index_Non_Blank (Params, Integer'Min (Params'Last, Last + 
1));
-
-            exit when Params (Last) = ']' or Params (Last) = ')';
-
-            Vector := Params (Last) = '[';
-            if Vector then
-               Index_First := Last + 1;
-               Last        := Index (Params, Delim, Index_First);
-               Index_Last  := Last - 1;
-               First       := Last + 1;
-               Last        := Index (Params, Delim, First);
-               begin
-                  ID := +Trimmed_Image (Find_Token_ID (Generate_Data, Params 
(First .. Last - 1)));
-               exception
-               when E : Not_Found =>
-                  Put_Error
-                    (Error_Message
-                       (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line,
-                        Ada.Exceptions.Exception_Message (E)));
-               end;
-
-               declare
-                  Label : constant String := Params (Index_First .. 
Index_Last);
-               begin
-                  if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                     Result := Result & (if Need_Comma then " & " else "") & 
"(" &
-                       Label & ", " & ID & ")";
-                     Need_Comma := True;
-                     Count  := Count + 1;
-                  end if;
-               end;
-               if Params (Last) /= ']' then
-                  Put_Error
-                    (Error_Message
-                       (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line,
-                        "too many token IDs in motion action"));
-                  return -Result & "))";
-               end if;
-
-            else
-               First  := Index_Non_Blank (Params, Last);
-               Last   := Index (Params, Delim, First);
-               declare
-                  Label : constant String := Params (First .. Last - 1);
-               begin
-                  if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                     Result := Result & (if Need_Comma then " & " else "") & 
"(" & Label & ", Invalid_Token_ID)";
-                     Need_Comma := True;
-                     Count  := Count + 1;
-                  end if;
-               end;
-            end if;
-         end loop;
-         if Count <= 1 then
-            --  No point in calling Motion_Action with only one param.
-            return "";
-         else
-            Nonterm_Needed := True;
-            return " (Parse_Data, Tree, Nonterm, Tokens, (" & (-Result) & "))";
-         end if;
-      end Motion_Params;
-
-      function Face_Apply_Params (Params : in String) return String
-      is
-         --  Params is a vector of triples: [1 nil font-lock-keyword-face 3 
nil font-lock-function-name-face ...]
-         --  Each triple is <token_number> <prefix-face> <suffix-face>.
-         --  The token_number can be a label; faces are "nil" or an elisp name.
-         --  Result: ((1, 3, 1), (3, 3, 2), ...)
-         use Ada.Strings.Maps;
-         Delim : constant Character_Set := To_Set ("]") or Blank_Set;
-
-         Last       : Integer          := Index_Non_Blank (Params); -- skip [
-         First      : Integer;
-         Result     : Unbounded_String;
-         Need_Comma : Boolean          := False;
-         Count      : Integer          := 0;
-
-         procedure Elisp_Param (Skip : in Boolean)
-         is begin
-            if Params (Last) = ']' then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"invalid wisi-face-apply argument"));
-               return;
-            end if;
-
-            First  := Index_Non_Blank (Params, Last + 1);
-            Last   := Index (Params, Delim, First);
-            if not Skip then
-               Result := Result & ',' & Integer'Image
-                 (Find_Elisp_ID (Input_Data.Tokens.Faces, Params (First .. 
Last - 1)));
-            end if;
-         end Elisp_Param;
-
-      begin
-         loop
-            Last := Index_Non_Blank (Params, Last + 1);
-
-            exit when Params (Last) = ']' or Params (Last) = ')';
-
-            First := Last;
-            Last  := Index (Params, Delim, First);
-            declare
-               Label : constant String := Params (First .. Last - 1);
-            begin
-               if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                  Count  := Count + 1;
-                  Result := Result & (if Need_Comma then ", (" else "(") & 
Label;
-                  Need_Comma := True;
-                  Elisp_Param (Skip => False);
-                  Elisp_Param (Skip => False);
-                  Result := Result  & ")";
-               else
-                  Elisp_Param (Skip => True);
-                  Elisp_Param (Skip => True);
-               end if;
-            end;
-         end loop;
-         if Count = 0 then
-            return "";
-         elsif Count = 1 then
-               Nonterm_Needed := True;
-            return " (Parse_Data, Tree, Nonterm, Tokens, (1 => " & (-Result) & 
"))";
-         else
-               Nonterm_Needed := True;
-            return " (Parse_Data, Tree, Nonterm, Tokens, (" & (-Result) & "))";
-         end if;
-      exception
-      when E : others =>
-         Put_Error
-           (Error_Message
-              (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, "invalid 
syntax: " &
-              Ada.Exceptions.Exception_Message (E)));
-         return "";
-      end Face_Apply_Params;
-
-      function Face_Mark_Params (Params : in String) return String
-      is
-         --  Params is a vector of pairs: [1 prefix 3 suffix ...]
-         --  The token_number can be a label; faces are "nil" or an elisp name.
-         --  Result: ((1, Prefix), (3, Suffix), ...)
-         use Ada.Strings.Maps;
-         Delim : constant Character_Set := To_Set ("]") or Blank_Set;
-
-         Last       : Integer := Index_Non_Blank (Params); -- skip [
-         First      : Integer;
-         Result     : Unbounded_String;
-         Need_Comma : Boolean := False;
-         Count      : Integer := 0;
-         Skip       : Boolean;
-      begin
-         loop
-            Last := Index_Non_Blank (Params, Last + 1);
-
-            exit when Params (Last) = ']' or Params (Last) = ')';
-
-            First := Last;
-            Last  := Index (Params, Delim, First);
-            declare
-               Label : constant String := Params (First .. Last - 1);
-            begin
-               if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                  Count  := Count + 1;
-                  Skip   := False;
-                  Result := Result & (if Need_Comma then ", (" else "(") & 
Label;
-               else
-                  Skip := True;
-               end if;
-            end;
-
-            if Params (Last) = ']' then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"invalid wisi-face-mark argument"));
-               exit;
-            end if;
-
-            First  := Index_Non_Blank (Params, Last + 1);
-            Last   := Index (Params, Delim, First);
-            if not Skip then
-               Result := Result & ", " & Elisp_Name_To_Ada (Params (First .. 
Last - 1), False, 0) & ")";
-               Need_Comma := True;
-            end if;
-         end loop;
-         Nonterm_Needed := True;
-         return " (Parse_Data, Tree, Nonterm, Tokens, " &
-           (case Count is
-            when 0 => "(1 .. 0 => (1, Prefix))",
-            when 1 => "(1 => " & (-Result) & "))",
-            when others => "(" & (-Result) & "))");
-      exception
-      when E : others =>
-         Put_Error
-           (Error_Message
-            (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, "invalid 
syntax: " &
-              Ada.Exceptions.Exception_Message (E)));
-         return "";
-      end Face_Mark_Params;
-
-      function Face_Remove_Params (Params : in String) return String
-      is
-         --  Params is a vector of token numbers: [1 3 ...]
-         --  Result: (1, 3, ...)
-         use Ada.Strings.Maps;
-         Delim : constant Character_Set := To_Set ("]") or Blank_Set;
-
-         Last       : Integer          := Index_Non_Blank (Params); -- skip [
-         First      : Integer;
-         Result     : Unbounded_String;
-         Need_Comma : Boolean          := False;
-         Count      : Integer          := 0;
-      begin
-         loop
-            Last := Index_Non_Blank (Params, Last + 1);
-
-            exit when Params (Last) = ']' or Params (Last) = ')';
-
-            Count  := Count + 1;
-            First  := Last;
-            Last   := Index (Params, Delim, First);
-            Result := Result & (if Need_Comma then ", " else "") & Params 
(First .. Last - 1);
-
-            Need_Comma := True;
-         end loop;
-         Nonterm_Needed := True;
-         if Count = 1 then
-            return " (Parse_Data, Tree, Nonterm, Tokens, (1 => " & (-Result) & 
"))";
-         else
-            return " (Parse_Data, Tree, Nonterm, Tokens, (" & (-Result) & "))";
-         end if;
-      exception
-      when E : others =>
-         Put_Error
-           (Error_Message
-            (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, "invalid 
syntax: " &
-              Ada.Exceptions.Exception_Message (E)));
-         return "";
-      end Face_Remove_Params;
-
-      function Indent_Params (Params : in String; N : in String := "") return 
String
-      is
-         --  If N is non-empty, it is the first arg in wisi-indent-action*, 
followed by ','.
-         --
-         --  Params is a vector, one item for each token in Tokens. Each item 
is one of:
-         --
-         --  - an integer; copy to output
-         --
-         --  - a symbol; convert to Ada name syntax, except 'nil' => None
-         --
-         --  - a lisp function call with arbitrary args; convert to 
Indent_Param type
-         --
-         --  - a vector with two elements [code_indent comment_indent]; 
convert to Indent_Pair.
-         --
-         --  - a cons of a token label with any of the above.
-
-         use Ada.Strings.Maps;
-         use Ada.Containers;
-
-         Delim : constant Character_Set := To_Set ("])") or Blank_Set;
-
-         subtype Digit is Character range '0' .. '9';
-
-         Last          : Integer         := Index_Non_Blank (Params); -- skip [
-         Prefix        : constant String := " (Parse_Data, Tree, Nonterm, 
Tokens, " & N & "(";
-         Result        : Unbounded_String;
-         Need_Comma    : Boolean         := False;
-         Param_Count   : Count_Type      := 0;            -- in Params
-
-         function Indent_Function (Elisp_Name : in String) return String
-         is begin
-            if    Elisp_Name = "wisi-anchored"   then return "Anchored_0";
-            elsif Elisp_Name = "wisi-anchored%"  then return "Anchored_1";
-            elsif Elisp_Name = "wisi-anchored%-" then return "Anchored_2";
-            elsif Elisp_Name = "wisi-anchored*"  then return "Anchored_3";
-            elsif Elisp_Name = "wisi-anchored*-" then return "Anchored_4";
-            elsif Elisp_Name = "wisi-hanging"    then return "Hanging_0";
-            elsif Elisp_Name = "wisi-hanging-"   then return "Hanging_1";
-            elsif Elisp_Name = "wisi-hanging%"   then return "Hanging_2";
-            elsif Elisp_Name = "wisi-hanging%-"  then return "Hanging_3";
-            else
-               Put_Error
-                 (Error_Message
-                  (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"unrecognized wisi indent function: '" &
-                    Elisp_Name & "'"));
-               return "";
-            end if;
-         end Indent_Function;
-
-         function Check_Cons return Integer
-         is
-            --  Params (Last) = '('; check for "(label .", return label'last
-            Blank : constant Integer := Index (Params, " ", Last);
-         begin
-            if Blank = 0 then return 0; end if;
-            if Params'Last > Blank + 1 and then Params (Blank + 1) = '.' then
-               return Blank - 1;
-            else
-               return 0;
-            end if;
-         end Check_Cons;
-
-         function Ensure_Simple_Indent (Item : in String) return String
-         is begin
-            --  Return an aggregate for Simple_Indent_Param. Item can be 
anything
-            --  Expression returns except Hanging.
-
-            if Item (Item'First) = '(' then
-               --  Anchored or Language
-               return Item;
-
-            elsif Item = "nil" then
-               return "(Label => None)";
-
-            else
-               --  simple integer
-               return "(Int, " & Item & ")";
-            end if;
-         end Ensure_Simple_Indent;
-
-         function Expression (Param_First : in Integer) return String
-         is
-            --  Return a simple integer expression, or an aggregate for
-            --  Simple_Indent_Param or Indent_Param.
-            --
-            --  Handles this syntax:
-            --
-            --  nil => nil
-            --
-            --  integer literal:
-            --  2 => 2
-            --  -1 => -1
-            --
-            --  variable name:
-            --  ada-indent => Ada_Indent
-            --
-            --  token_id literal:
-            --  'TYPE => 13
-            --
-            --  simple expression with + - * :
-            --  (- ada-indent) => -Ada_Indent
-            --  (- ada-indent-when ada-indent) => Ada_Indent_When - Ada_Indent
-            --
-            --  if expression:
-            --  (if c a b) => (if c then a else b)
-            --
-            --  function call with expression args:
-            --  (wisi-hanging (wisi-anchored% 1 ada-indent)
-            --                (wisi-anchored% 1 (+ ada-indent 
ada-indent-broken)))
-
-            use Generate_Utils;
-
-            First : Integer := Index_Non_Blank (Params, Param_First);
-
-            Function_Name : Unbounded_String;
-            Args          : Unbounded_String;
-            Arg_Count     : Count_Type      := 0;
-         begin
-            if Params (First) in Digit or Params (First) = '-' then
-               Last := Index (Params, Delim, First);
-               return Params (First .. Last - 1);
-
-            elsif Params (First) = ''' then
-               Last := Index (Params, Delim, First);
-               return WisiToken.Trimmed_Image (Find_Token_ID (Generate_Data, 
Params (First + 1 .. Last - 1)));
-
-            elsif Params (First) = '(' then
-               First  := First + 1;
-               Last   := Index (Params, Delim, First);
-               Function_Name := +Params (First .. Last - 1);
-
-               if Length (Function_Name) = 1 then
-                  --  - + *
-                  Last := Index (Params, Delim, Last + 1);
-                  if Params (Last) = ')' then
-                     return Result : constant String := -Function_Name & 
Expression (First + 1)
-                     do
-                        Last := Last + 1; -- get past ')'
-                     end return;
-                  else
-                     Args := +Expression (First + 1);
-                     Args := Args & ' ' & Function_Name & ' ' & Expression 
(Last + 1);
-
-                     Last := Last + 1; -- get past ')'
-                     return -Args;
-                  end if;
-
-               elsif -Function_Name = "if" then
-                  Args := +Expression (Last + 1);
-                  Args := +"(if " & Args & " then " & Expression (Last + 1);
-                  Args := Args & " else " & Expression (Last + 1) & ')';
-
-                  Last := Last + 1; -- get past ')'
-                  return -Args;
-
-               elsif Is_Present (Input_Data.Tokens.Indents, -Function_Name) 
then
-                  --  Language-specific function call
-                  Function_Name := +Value (Input_Data.Tokens.Indents, 
-Function_Name);
-                  Arg_Count     := 0;
-                  loop
-                     exit when Params (Last) = ')';
-
-                     First := Last + 1;
-                     if Arg_Count = 0 then
-                        Args := +Expression (First);
-                     else
-                        Args := Args & " & " & Expression (First);
-                     end if;
-                     Arg_Count := Arg_Count + 1;
-                  end loop;
-
-                  Last := Last + 1; -- get past ')'
-
-                  return "(Language, " & (-Function_Name) & "'Access, " &
-                    (if Arg_Count = 0 then "Null_Args"
-                     elsif Arg_Count = 1 then '+' & (-Args)
-                     else -Args)
-                    & ')';
-
-               else
-                  --  wisi lisp function call
-                  Function_Name := +Indent_Function (-Function_Name);
-                  if Length (Function_Name) = 0 then
-                     --  not a recognized function
-                     Last := 1 + Index (Params, ")", Last);
-                     return "";
-
-                  elsif Slice (Function_Name, 1, 4) = "Hang" then
-                     --  Arguments are 2 Simple_Indent_Param
-                     Args := +Ensure_Simple_Indent (Expression (Last + 1));
-                     Args := Args & ", " & Ensure_Simple_Indent (Expression 
(Last + 1));
-                     Last := Last + 1; -- get past ')'
-                     return "(" & (-(Function_Name & ", " & Args)) & ")";
-                  else
-                     --  Arguments are 2 simple integer expressions
-                     Args := +Expression (Last + 1);
-                     Args := Args & ", " & Expression (Last + 1);
-                     Last := Last + 1; -- get past ')'
-                     return "(" & (-(Function_Name & ", " & Args)) & ")";
-                  end if;
-               end if;
-
-            else
-               --  Assume it is 'nil' or a language-specific integer indent 
option,
-               --  like "ada-indent", declared in Language_Runtime_Package, 
which is
-               --  use-visible.
-               Last  := Index (Params, Delim, First);
-               if Params (First .. Last - 1) = "nil" then
-                  return "nil";
-               else
-                  return Elisp_Name_To_Ada (Params (First .. Last - 1), False, 
0);
-               end if;
-            end if;
-         exception
-         when E : others =>
-            Put_Error
-              (Error_Message
-                 (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-            return "";
-         end Expression;
-
-         procedure Skip_Expression (Param_First : in Integer)
-         is
-            Junk : constant String := Expression (Param_First);
-            pragma Unreferenced (Junk);
-         begin
-            null;
-         end Skip_Expression;
-
-         function Ensure_Indent_Param (Item : in String) return String
-         is begin
-            --  Return an aggregate for Indent_Param. Item can be anything
-            --  Expression returns.
-            if Item'Length = 0 then
-               --  Expression could not find an indent function
-               return Item;
-
-            elsif Item'Length >= 5 and then Item (Item'First .. Item'First + 
4) = "(Hang" then
-               return Item;
-
-            elsif Item (Item'First) = '(' then
-               --  Anchored or Language
-               return "(Simple, " & Item & ")";
-
-            elsif Item = "nil" then
-               return "(Simple, (Label => None))";
-
-            else
-               --  simple integer
-               return "(Simple, (Int, " & Item & "))";
-            end if;
-         end Ensure_Indent_Param;
-
-         procedure One_Param (Prefix : in Boolean := False; Skip : in Boolean 
:= False)
-         is
-            procedure Comma
-            is begin
-               if Need_Comma then
-                  if not Prefix then
-                     Result := Result & ", ";
-                  end if;
-               else
-                  Need_Comma := True;
-               end if;
-            end Comma;
-         begin
-            case Params (Last) is
-            when '(' =>
-               --  cons or function
-               declare
-                  Label_Last : constant Integer := Check_Cons;
-               begin
-                  if Label_Last > 0 then
-                     declare
-                        Label : constant String := Params (Last + 1 .. 
Label_Last);
-                     begin
-                        Last := Index_Non_Blank (Params, Label_Last + 3);
-                        if Label_Used (Label) then
-                           Comma;
-                           Result := Result & Label & " => ";
-                           One_Param (Prefix => True);
-                        else
-                           --  This token is not present in this RHS; skip 
this param
-                           One_Param (Skip => True);
-                        end if;
-                        if Params (Last) /= ')' then
-                           Put_Error
-                             (Error_Message
-                                (Input_Data.Grammar_Lexer.File_Name,
-                                 RHS.Source_Line, "invalid indent syntax; 
missing ')'"));
-                        end if;
-                        Last := Last + 1;
-                     end;
-                  else
-                     if Skip then
-                        Skip_Expression (Last);
-                     else
-                        Comma;
-                        Result := Result & "(False, " & Ensure_Indent_Param 
(Expression (Last)) & ')';
-                     end if;
-                  end if;
-               end;
-
-            when '[' =>
-               --  vector
-               if Skip then
-                  Skip_Expression (Last + 1);
-                  Skip_Expression (Last + 1);
-               else
-                  Comma;
-                  Result := Result & "(True, " & Ensure_Indent_Param 
(Expression (Last + 1));
-                  Result := Result & ", " & Ensure_Indent_Param (Expression 
(Last + 1)) & ')';
-               end if;
-               if Params (Last) /= ']' then
-                  Put_Error
-                    (Error_Message
-                       (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"indent missing ']'"));
-               end if;
-               Last := Last + 1;
-
-            when others =>
-               --  integer or symbol
-               if Skip then
-                  Skip_Expression (Last);
-               else
-                  Comma;
-                  Result := Result & "(False, " & Ensure_Indent_Param 
(Expression (Last)) & ')';
-               end if;
-            end case;
-         end One_Param;
-
-      begin
-         loop
-            if Params (Last) /= ']' then
-               Last := Index_Non_Blank (Params, Last + 1);
-               if Last = 0 then
-                  Put_Error (Error_Message 
(Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, "indent missing ']'"));
-                  return -Result;
-               end if;
-            end if;
-
-            exit when Params (Last) = ']';
-
-            One_Param;
-
-            Param_Count := Param_Count + 1;
-         end loop;
-
-         --  In translated EBNF, token counts vary in each RHS; require each
-         --  parameter to be labeled if any are, both for catching errors, and
-         --  becase that would produce mixed positional and named association
-         --  in the Ada action subprogram.
-         if Param_Count /= RHS.Tokens.Length then
-            if Labels.Length = 0 then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
Image (Prod_ID) &
-                       ": indent parameters count of" & Count_Type'Image 
(Param_Count) &
-                       " /= production token count of" & Count_Type'Image 
(RHS.Tokens.Length)));
-
-            elsif Count_Label_Needed /= RHS.Tokens.Length then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
Image (Prod_ID) &
-                       ": indent parameter(s) not labeled"));
-            else
-               --  all parameters labeled
-               null;
-            end if;
-         end if;
-
-         Nonterm_Needed := True;
-         if Param_Count = 1 then
-            Result := Prefix & "1 => " & Result;
-         else
-            Result := Prefix & Result;
-         end if;
-
-         return -(Result & "))");
-      end Indent_Params;
-
-      function Merge_Names_Params (Params : in String) return String
-      is
-         --  Input looks like "1 2)"
-         First             : constant Integer := Index_Non_Blank (Params);
-         Second            : constant Integer := Index (Params, Blank_Set, 
First);
-         Label_First       : constant String  := Params (First .. Second - 1);
-         Label_Used_First  : constant Boolean := 0 = Index (Label_First, 
Numeric, Outside) or else
-           Label_Used (Label_First);
-         Label_Second      : constant String  := Params (Second + 1 .. 
Params'Last - 1);
-         Label_Used_Second : constant Boolean := 0 = Index (Label_Second, 
Numeric, Outside) or else
-           Label_Used (Label_Second);
-      begin
-         Nonterm_Needed := True;
-
-         if Label_Used_First and Label_Used_Second then
-            return " (Nonterm, Tokens, " & Label_First & ", " & Label_Second & 
")";
-
-         elsif (not Label_Used_First) and Label_Used_Second then
-            --  A copied EBNF RHS; see subprograms.wy Name
-            return " (Nonterm, Tokens, " & Label_Second & ")";
-         else
-            Put_Error
-              (Error_Message
-                 (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"merge_names token label error"));
-            return " (Nonterm, Tokens)";
-         end if;
-      end Merge_Names_Params;
-
-      function Match_Names_Params (Params : in String) return String
-      is
-         --  Input looks like: 1 2)
-         First  : constant Integer := Index_Non_Blank (Params);
-         Second : constant Integer := Index (Params, Blank_Set, First);
-      begin
-         return " (Lexer, Descriptor, Tokens, " &
-           Params (First .. Second - 1) & ',' &
-           Params (Second .. Params'Last - 1) & ", " &
-           (if Length (Input_Data.Language_Params.End_Names_Optional_Option) > 0
-            then -Input_Data.Language_Params.End_Names_Optional_Option
-            else "False") & ")";
-      end Match_Names_Params;
-
-      function Language_Action_Params (Params : in String; Action_Name : in 
String) return String
-      is
-         --  Input looks like: [1 2 ...])
-         Result      : Unbounded_String;
-         Need_Comma  : Boolean := False;
-         Param_Count : Integer := 0;
-         First       : Integer;
-         Last        : Integer := Params'First; --  '['
-      begin
-         loop
-            First := Index_Non_Blank (Params, Last + 1);
-            Last  := Index (Params, Space_Paren_Set, First);
-            declare
-               Label : constant String  := Params (First .. Last - 1);
-            begin
-               if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                  Param_Count := Param_Count + 1;
-                  if Need_Comma then
-                     Result := Result & ", ";
-                  else
-                     Need_Comma := True;
-                  end if;
-                  Result := Result & Label;
-               end if;
-               exit when Params (Last) = ']';
-               if Last = Params'Last then
-                  Put_Error
-                    (Error_Message
-                       (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
Action_Name & " missing ']'"));
-                  exit;
-               end if;
-            end;
-         end loop;
-         if Param_Count = 0 then
-            return "";
-         elsif Param_Count = 1 then
-            return "(1 => " & (-Result) & ")";
-         else
-            return "(" & (-Result) & ")";
-         end if;
-      end Language_Action_Params;
-
-      procedure Translate_Sexp (Line : in String)
-      is
-         Last       : constant Integer := Index (Line, Blank_Set);
-         Elisp_Name : constant String  := Line (Line'First + 1 .. (if Last = 0 
then Line'Last else Last) - 1);
-
-         procedure Assert_Face_Empty
-         is begin
-            if Length (Face_Line) > 0 then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"multiple face actions"));
-            end if;
-         end Assert_Face_Empty;
-
-         procedure Assert_Indent_Empty
-         is begin
-            if Length (Indent_Action_Line) > 0 then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"multiple indent actions"));
-            end if;
-         end Assert_Indent_Empty;
-
-         procedure Assert_Check_Empty
-         is begin
-            if Length (Check_Line) > 0 then
-               Put_Error
-                 (Error_Message
-                    (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"multiple check actions"));
-            end if;
-         end Assert_Check_Empty;
-
-      begin
-         --  wisi action/check functions, in same order as typically used in
-         --  .wy files; Navigate, Face, Indent, Check.
-         if Elisp_Name = "wisi-statement-action" then
-            declare
-               Params : constant String := Statement_Params (Line (Last + 1 .. 
Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Navigate_Lines.Append (Elisp_Name_To_Ada (Elisp_Name, False, 
5) & Params & ";");
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-name-action" then
-            declare
-               First : constant Integer := Index_Non_Blank (Line, Last + 1);
-               Last  : constant Integer := Index (Line, Space_Paren_Set, 
First);
-               Label : constant String  := Line (First .. Last - 1);
-            begin
-               if 0 = Index (Label, Numeric, Outside) or else Label_Used 
(Label) then
-                  Nonterm_Needed := True;
-                  Navigate_Lines.Append
-                    ("Name_Action (Parse_Data, Tree, Nonterm, Tokens, " & Line 
(First .. Line'Last) & ";");
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-motion-action" then
-            declare
-               Params : constant String := Motion_Params (Line (Last + 1 .. 
Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Navigate_Lines.Append (Elisp_Name_To_Ada (Elisp_Name, False, 
Trim => 5) & Params & ";");
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-face-apply-action" then
-            Assert_Face_Empty;
-            declare
-               Params : constant String := Face_Apply_Params (Line (Last + 1 
.. Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Face_Line := +Elisp_Name_To_Ada (Elisp_Name, False, Trim => 
5) & Params & ";";
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-face-apply-list-action" then
-            Assert_Face_Empty;
-            declare
-               Params : constant String := Face_Apply_Params (Line (Last + 1 
.. Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Face_Line := +Elisp_Name_To_Ada (Elisp_Name, False, Trim => 
5) & Params & ";";
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-face-mark-action" then
-            Assert_Face_Empty;
-            declare
-               Params : constant String := Face_Mark_Params (Line (Last + 1 .. 
Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Face_Line := +Elisp_Name_To_Ada (Elisp_Name, False, Trim => 
5) & Params & ";";
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-face-remove-action" then
-            Assert_Face_Empty;
-            declare
-               Params : constant String := Face_Remove_Params (Line (Last + 1 
.. Line'Last));
-            begin
-               if Params'Length > 0 then
-                  Face_Line := +Elisp_Name_To_Ada (Elisp_Name, False, Trim => 
5) & Params & ";";
-               end if;
-            end;
-
-         elsif Elisp_Name = "wisi-indent-action" then
-            Assert_Indent_Empty;
-            Indent_Action_Line := +"Indent_Action_0" & Indent_Params (Line 
(Last + 1 .. Line'Last)) & ";";
-
-         elsif Elisp_Name = "wisi-indent-action*" then
-            Assert_Indent_Empty;
-            declare
-               Temp : constant Integer := Index (Line, Blank_Set, Last + 1);
-            begin
-               Indent_Action_Line := +"Indent_Action_1" &
-                 Indent_Params (Line (Temp + 1 .. Line'Last), Line (Last + 1 
.. Temp - 1) & ", ") & ";";
-            end;
-
-         elsif Elisp_Name = "wisi-propagate-name" then
-            Assert_Check_Empty;
-            Nonterm_Needed := True;
-            Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, 
Trim => 5) &
-              " (Nonterm, Tokens, " & Line (Last + 1 .. Line'Last) & ";";
-
-         elsif Elisp_Name = "wisi-merge-names" then
-            Assert_Check_Empty;
-            Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, 
Trim => 5) &
-              Merge_Names_Params (Line (Last + 1 .. Line'Last)) & ";";
-
-         elsif Elisp_Name = "wisi-match-names" then
-            Assert_Check_Empty;
-            Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, 
Trim => 5) &
-              Match_Names_Params (Line (Last + 1 .. Line'Last)) & ";";
-
-         elsif Elisp_Name = "wisi-terminate-partial-parse" then
-            Assert_Check_Empty;
-            Nonterm_Needed := True;
-            Check_Line := +"return Terminate_Partial_Parse 
(Partial_Parse_Active, Partial_Parse_Byte_Goal, " &
-              "Recover_Active, Nonterm);";
-
-         elsif Is_Present (Input_Data.Tokens.Actions, Elisp_Name) then
-            --  Language-specific action (used in wisitoken grammar mode for
-            --  wisi-check-parens).
-            declare
-               Item   : Elisp_Action_Type renames Input_Data.Tokens.Actions
-                 (Input_Data.Tokens.Actions.Find (+Elisp_Name));
-               Params : constant String := Language_Action_Params (Line (Last 
+ 1 .. Line'Last), Elisp_Name);
-               Code   : constant String := -Item.Ada_Name &
-                 " (Wisi.Parse_Data_Type'Class (User_Data), Tree, Tokens, " & 
Params & ");";
-            begin
-               if Params'Length > 0 then
-                  if "navigate" = -Item.Action_Label then
-                     Navigate_Lines.Append (Code);
-
-                  elsif "face" = -Item.Action_Label then
-                     Assert_Face_Empty;
-                     Face_Line := +Code;
-
-                  elsif "indent" = -Item.Action_Label then
-                     Assert_Indent_Empty;
-                     Indent_Action_Line := +Code;
-
-                  else
-                     Put_Error
-                       (Error_Message
-                          (Input_Data.Grammar_Lexer.File_Name, 
RHS.Source_Line, "unrecognized action label: '" &
-                             (-Item.Action_Label) & "'"));
-                  end if;
-
-                  --  else skip
-               end if;
-            end;
-         else
-            Put_Error
-              (Error_Message
-                 (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
"unrecognized elisp action: '" &
-                    Elisp_Name & "'"));
-         end if;
-      end Translate_Sexp;
-
-   begin
-      for Sexp of Sexps loop
-         begin
-            Translate_Sexp (Sexp);
-         exception
-         when E : Not_Found =>
-            Put_Error
-              (Error_Message
-                 (Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-         end;
-      end loop;
-
-      if Check then
-         --  in a check
-         Indent_Line ("function " & Name);
-         Indent_Line (" (Lexer          : access constant 
WisiToken.Lexer.Instance'Class;");
-         Indent_Line ("  Nonterm        : in out WisiToken.Recover_Token;");
-         Indent_Line ("  Tokens         : in     
WisiToken.Recover_Token_Array;");
-         Indent_Line ("  Recover_Active : in     Boolean)");
-         Indent_Line (" return WisiToken.Semantic_Checks.Check_Status");
-         declare
-            Unref_Lexer   : constant Boolean := 0 = Index (Check_Line, 
"Lexer");
-            Unref_Nonterm : constant Boolean := 0 = Index (Check_Line, 
"Nonterm");
-            Unref_Tokens  : constant Boolean := 0 = Index (Check_Line, 
"Tokens");
-            Unref_Recover : constant Boolean := 0 = Index (Check_Line, 
"Recover_Active");
-            Need_Comma    : Boolean          := False;
-         begin
-            if Unref_Lexer or Unref_Nonterm or Unref_Tokens or Unref_Recover or
-              (for some I of Label_Needed => I)
-            then
-               Indent_Line ("is");
-
-               Indent := Indent + 3;
-               if Unref_Lexer or Unref_Nonterm or Unref_Tokens or 
Unref_Recover then
-                  Indent_Start ("pragma Unreferenced (");
-
-                  if Unref_Lexer then
-                     Put ((if Need_Comma then ", " else "") & "Lexer");
-                     Need_Comma := True;
-                  end if;
-                  if Unref_Nonterm then
-                     Put ((if Need_Comma then ", " else "") & "Nonterm");
-                     Need_Comma := True;
-                  end if;
-                  if Unref_Tokens then
-                     Put ((if Need_Comma then ", " else "") & "Tokens");
-                     Need_Comma := True;
-                  end if;
-                  if Unref_Recover then
-                     Put ((if Need_Comma then ", " else "") & 
"Recover_Active");
-                     Need_Comma := True;
-                  end if;
-                  Put_Line (");");
-               end if;
-
-               for I in Label_Needed'Range loop
-                  if Label_Needed (I) then
-                     Indent_Line
-                       (-Labels (I) & " : constant SAL.Peek_Type :=" &
-                          SAL.Peek_Type'Image (Find_Token_Index (I)) & ";");
-                  end if;
-               end loop;
-               Indent := Indent - 3;
-
-               Indent_Line ("begin");
-            else
-               Indent_Line ("is begin");
-            end if;
-         end;
-         Indent := Indent + 3;
-         Indent_Line (-Check_Line);
-      else
-         --  In an action
-         Indent_Line ("procedure " & Name);
-         Indent_Line (" (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class;");
-         Indent_Line ("  Tree      : in out WisiToken.Syntax_Trees.Tree;");
-         Indent_Line ("  Nonterm   : in     WisiToken.Valid_Node_Index;");
-         Indent_Line ("  Tokens    : in     
WisiToken.Valid_Node_Index_Array)");
-         Indent_Line ("is");
-
-         Indent := Indent + 3;
-         Indent_Line ("Parse_Data : Wisi.Parse_Data_Type renames 
Wisi.Parse_Data_Type (User_Data);");
-
-         if not Nonterm_Needed then
-            --  Language_Action may not use this
-            Indent_Line ("pragma Unreferenced (Nonterm);");
-         end if;
-
-         for I in Label_Needed'Range loop
-            if Label_Needed (I) then
-               Indent_Line
-                 (-Labels (I) & " : constant SAL.Peek_Type :=" &
-                    SAL.Peek_Type'Image (Find_Token_Index (I)) & ";");
-            end if;
-         end loop;
-
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-
-         Indent_Line ("case Parse_Data.Post_Parse_Action is");
-         Indent_Line ("when Navigate =>");
-         if Navigate_Lines.Length > 0 then
-            Indent := Indent + 3;
-            for Line of Navigate_Lines loop
-               Indent_Wrap (Line);
-            end loop;
-            Indent := Indent - 3;
-         else
-            Indent_Line ("   null;");
-         end if;
-
-         Indent_Line ("when Face =>");
-         if Length (Face_Line) > 0 then
-            Indent := Indent + 3;
-            Indent_Wrap (-Face_Line);
-            Indent := Indent - 3;
-         else
-            Indent_Line ("   null;");
-         end if;
-
-         Indent_Line ("when Indent =>");
-         if Length (Indent_Action_Line) > 0 then
-            Indent := Indent + 3;
-            Indent_Wrap (-Indent_Action_Line);
-            Indent := Indent - 3;
-         else
-            Indent_Line ("   null;");
-         end if;
-         Indent_Line ("end case;");
-      end if;
-
-      Indent := Indent - 3;
-      Indent_Line ("end " & Name & ";");
-      New_Line;
-
-   end Create_Ada_Action;
-
-   function Any_Motion_Actions return Boolean
-   is begin
-      for Rule of Input_Data.Tokens.Rules loop
-         for RHS of Rule.Right_Hand_Sides loop
-            for Sexp of Split_Sexp (-RHS.Action, 
Input_Data.Grammar_Lexer.File_Name, RHS.Source_Line) loop
-               declare
-                  Last       : constant Integer := Ada.Strings.Fixed.Index 
(Sexp, Blank_Set);
-                  Elisp_Name : constant String  := Sexp (Sexp'First + 1 .. 
Last - 1);
-               begin
-                  if Elisp_Name = "wisi-motion-action" then
-                     return True;
-                  end if;
-               end;
-            end loop;
-         end loop;
-      end loop;
-      return False;
-   end Any_Motion_Actions;
-
-   procedure Create_Ada_Actions_Body
-     (Action_Names : not null access WisiToken.Names_Array_Array;
-      Check_Names  : not null access WisiToken.Names_Array_Array;
-      Label_Count  : in              Ada.Containers.Count_Type;
-      Package_Name : in              String)
-   is
-      use Ada.Strings.Unbounded;
-      use Generate_Utils;
-      use WisiToken.Generate;
-
-      File_Name : constant String := Output_File_Name_Root &
-        (case Common_Data.Interface_Kind is
-         when Process => "_process_actions",
-         when Module  => "_module_actions") &
-        ".adb";
-
-      Motion_Actions : constant Boolean := Any_Motion_Actions;
-
-      Body_File : File_Type;
-
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if Label_Count > 0 then
-         Put_Line ("with SAL;");
-      end if;
-
-      Put_Line ("with Wisi; use Wisi;");
-      if Input_Data.Language_Params.Use_Language_Runtime then
-         declare
-            Pkg : constant String :=
-              (if -Input_Data.Language_Params.Language_Runtime_Name = ""
-               then Default_Language_Runtime_Package
-               else -Input_Data.Language_Params.Language_Runtime_Name);
-         begin
-            --  For language-specific names in actions, checks.
-            Put_Line ("with " & Pkg & "; use " & Pkg & ";");
-         end;
-      end if;
-
-      case Common_Data.Interface_Kind is
-      when Process =>
-         null;
-
-      when Module =>
-         Put_Line ("with Emacs_Module_Aux; use Emacs_Module_Aux;");
-         Put_Line ("with Ada.Exceptions;");
-         Put_Line ("with Ada.Strings.Unbounded;");
-      end case;
-
-      Put_Line ("package body " & Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      if Input_Data.Check_Count > 0 then
-         Indent_Line ("use WisiToken.Semantic_Checks;");
-      end if;
-      if Motion_Actions then
-         Indent_Line ("use all type Motion_Param_Array;");
-      end if;
-      New_Line;
-
-      --  generate Action and Check subprograms.
-
-      for Rule of Input_Data.Tokens.Rules loop
-         --  No need for a Token_Cursor here, since we only need the
-         --  nonterminals.
-         declare
-            LHS_ID    : constant WisiToken.Token_ID := Find_Token_ID 
(Generate_Data, -Rule.Left_Hand_Side);
-            RHS_Index : Integer                     := 0; -- Semantic_Action 
defines RHS_Index as zero-origin
-         begin
-            for RHS of Rule.Right_Hand_Sides loop
-               if Length (RHS.Action) > 0 then
-                  declare
-                     Name : constant String := Action_Names 
(LHS_ID)(RHS_Index).all;
-                  begin
-                     Create_Ada_Action (Name, RHS, (LHS_ID, RHS_Index), 
RHS.Action, Rule.Labels, Check => False);
-                  end;
-               end if;
-
-               if Length (RHS.Check) > 0 then
-                  declare
-                     Name : constant String := Check_Names 
(LHS_ID)(RHS_Index).all;
-                  begin
-                     Create_Ada_Action (Name, RHS, (LHS_ID, RHS_Index), 
RHS.Check, Rule.Labels, Check => True);
-                  end;
-               end if;
-               RHS_Index := RHS_Index + 1;
-            end loop;
-         end;
-      end loop;
-
-      Put_Line ("end " & Package_Name & ";");
-      Close (Body_File);
-
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Actions_Body;
-
-   procedure Create_Ada_Main_Body
-     (Actions_Package_Name : in String;
-      Main_Package_Name    : in String)
-   is
-      use WisiToken.Generate;
-
-      File_Name : constant String := To_Lower (Main_Package_Name) & ".adb";
-      Body_File : File_Type;
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
-         Put_Line ("with " & Actions_Package_Name & "; use " & 
Actions_Package_Name & ";");
-      end if;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Put_Line ("with WisiToken.Lexer.re2c;");
-         Put_Line ("with " & Output_File_Name_Root & "_re2c_c;");
-
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         null;
-
-      when Packrat_Generate_Algorithm =>
-         Put_Line ("with WisiToken.Parse;");
-
-      when External =>
-         null;
-      end case;
-
-      Put_Line ("package body " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Indent_Line ("package Lexer is new WisiToken.Lexer.re2c");
-         Indent_Line ("  (" & Output_File_Name_Root & "_re2c_c.New_Lexer,");
-         Indent_Line ("   " & Output_File_Name_Root & "_re2c_c.Free_Lexer,");
-         Indent_Line ("   " & Output_File_Name_Root & "_re2c_c.Reset_Lexer,");
-         Indent_Line ("   " & Output_File_Name_Root & "_re2c_c.Next_Token);");
-         New_Line;
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         LR_Create_Create_Parser (Input_Data, Common_Data, Generate_Data);
-
-      when Packrat_Gen =>
-         WisiToken.BNF.Generate_Packrat (Packrat_Data, Generate_Data);
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when Packrat_Proc =>
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when External =>
-         External_Create_Create_Grammar (Generate_Data);
-      end case;
-
-      case Common_Data.Interface_Kind is
-      when Process =>
-         null;
-      when Module =>
-         Indent_Line ("Parser : LR_Parser.Instance;");
-         New_Line;
-
-         Indent_Line ("function Parse (Env : Emacs_Env_Access) return 
emacs_module_h.emacs_value");
-         Indent_Line ("is begin");
-         Indent := Indent + 3;
-         Indent_Line ("WisiToken.Trace_Parse := To_Integer (Env, Symbol_Value 
(Env, Elisp_Symbols (Wisi_Debug_ID)));");
-         Indent_Line ("Wisi_Cache_Max := To_Integer (Env, Symbol_Value (Env, 
Elisp_Symbols (Wisi_Cache_Max_ID)));");
-         Indent_Line ("Parser.Reset;");
-         Indent_Line ("Parser.Parse;");
-         Indent_Line ("return Env.Qnil;");
-         Indent := Indent - 3;
-         Indent_Line ("exception");
-         Indent_Line ("when E : WisiToken.Parse_Error | WisiToken.Syntax_Error 
=>");
-         Indent_Line ("   return To_Emacs (Env, 
Ada.Exceptions.Exception_Message (E));");
-         Indent_Line ("when E : others =>");
-         Indent_Line ("   declare");
-         Indent_Line ("      use Ada.Exceptions;");
-         Indent_Line ("   begin");
-         Indent_Line ("      return To_Emacs (Env, Exception_Name (E) & "": "" 
& Exception_Message (E));");
-         Indent_Line ("   end;");
-         Indent_Line ("end Parse;");
-         New_Line;
-
-         Indent_Line ("function Init (Env : Emacs_Env_Access) return 
Interfaces.C.int");
-         Indent_Line ("is");
-         Indent_Line ("   Lexer_Elisp_Symbols : 
Lexers.Elisp_Array_Emacs_Value;");
-         Indent_Line ("begin");
-         Indent_Line ("   " & Main_Package_Name & ".Env := Env;");
-         Indent_Line ("   Emacs_Module_Aux.Init (Env);");
-         Indent_Line ("   for I in Token_Symbols'Range loop");
-         Indent_Line ("      Token_Symbols (I) := Intern_Soft (Env, 
Token_Images (I).all);");
-         Indent_Line ("   end loop;");
-         Indent_Line ("   for I in Elisp_Symbols'Range loop");
-         Indent_Line ("      Elisp_Symbols (I) := Intern_Soft (Env, User_Names 
(I).all);");
-         Indent_Line ("   end loop;");
-         Indent_Line ("   for I in Elisp_Numbers'Range loop");
-         Indent_Line ("      Elisp_Numbers (I) := Env.make_fixnum (Env, 
emacs_module_h.int64_t (I));");
-         Indent_Line ("   end loop;");
-         Indent_Line ("   for I in Lexer_Elisp_Symbols'Range loop");
-         Indent_Line ("      Lexer_Elisp_Symbols (I) := Intern_Soft (Env, 
Lexers.Tokens (I).all);");
-         Indent_Line ("   end loop;");
-         Indent_Line ("   Parser := Create_Parser (Env, 
Lexer_Elisp_Symbols);");
-         Indent_Line ("   return 0;");
-         Indent_Line ("exception");
-         Indent_Line ("when E : others =>");
-         Indent_Line
-           ("   Signal_Error (Env, " &
-              "Ada.Exceptions.Exception_Name (E) & "": "" & 
Ada.Exceptions.Exception_Message (E), Env.Qnil);");
-         Indent_Line ("   return 1;");
-         Indent_Line ("end Init;");
-         New_Line;
-      end case;
-
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Body_File);
-
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Main_Body;
-
-   procedure Create_Process_Elisp
-   is
-      use Generate_Utils;
-      use WisiToken.Generate;
-
-      File : File_Type;
-
-      Paren_1_Done : Boolean := False;
-   begin
-      Create (File, Out_File, Output_File_Name_Root & "-process.el");
-      Set_Output (File);
-      Indent := 1;
-
-      Put_Line
-        (";;; " & Output_File_Name_Root & "-process.el --- Generated parser 
support file  -*- lexical-binding:t -*-");
-      Put_Command_Line (Elisp_Comment & "  ", Use_Tuple => True, Tuple => 
Tuple);
-      Put_Raw_Code (Elisp_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-      Put_Line ("(require 'wisi-process-parse)");
-      New_Line;
-
-      Indent_Line  ("(defconst " & Output_File_Name_Root & 
"-process-token-table");
-      Indent_Start ("  [");
-      Indent := Indent + 3;
-      for Cursor in All_Tokens (Generate_Data).Iterate loop
-         if Paren_1_Done then
-            Indent_Line (Name (Cursor));
-         else
-            Paren_1_Done := True;
-            Put_Line (Name (Cursor));
-         end if;
-
-      end loop;
-      Indent_Line ("])");
-      Indent := Indent - 3;
-      New_Line;
-
-      Output_Elisp_Common.Indent_Name_Table
-        (Output_File_Name_Root, "process-face-table", Input_Data.Tokens.Faces);
-
-      --  We need -repair-image for wisi-repair-error
-      New_Line;
-      Output_Elisp_Common.Indent_Repair_Image (Output_File_Name_Root, 
"process", Input_Data.Tokens);
-
-      New_Line;
-      Put_Line ("(provide '" & Output_File_Name_Root & "-process)");
-      Set_Output (Standard_Output);
-      Close (File);
-
-   end Create_Process_Elisp;
-
-   procedure Create_Module_Elisp
-   is
-      use Ada.Strings.Unbounded;
-      use Generate_Utils;
-      use WisiToken.Generate;
-
-      Lower_Package_Name_Root : constant String := To_Lower (File_Name_To_Ada 
(Output_File_Name_Root));
-
-      function To_ID_Image (Name : in Ada.Strings.Unbounded.Unbounded_String) 
return String
-      is begin
-         --  Ada 'Val is 0 origin; Token_ID is 1 origin
-         return Token_ID'Image (-1 + Find_Token_ID (Generate_Data, -Name));
-      end To_ID_Image;
-
-      File : File_Type;
-   begin
-      Create (File, Out_File, Output_File_Name_Root & "-module.el");
-      Set_Output (File);
-      Indent := 1;
-
-      Put_Line (";; generated by WisiToken Wisi from " & 
Input_Data.Grammar_Lexer.File_Name);
-      Put_Command_Line (";; ", Use_Tuple => True, Tuple => Tuple);
-      Put_Line (";;");
-
-      --  don't need the prologue here
-
-      Put_Line ("(require 'wisi-parse-common)");
-      New_Line;
-
-      --  Lexer tables; also contain terminals for wisi-tokens
-      Indent_Keyword_Table (Output_File_Name_Root, "elisp", 
Input_Data.Tokens.Keywords, To_String'Access);
-      Indent_Keyword_Table (Output_File_Name_Root, "module", 
Input_Data.Tokens.Keywords, To_ID_Image'Access);
-      Indent_Token_Table (Output_File_Name_Root, "elisp", 
Input_Data.Tokens.Tokens, To_String'Access);
-      Indent_Token_Table (Output_File_Name_Root, "module", 
Input_Data.Tokens.Tokens, To_ID_Image'Access);
-
-      --  non-terminals. We only need the ones that actually have
-      --  actions, and thus will appear in a call to To_Emacs. But
-      --  Token_Symbols must be indexed by Token_ID, so we declare
-      --  all of them.
-      Indent_Line ("(defconst " & Output_File_Name_Root & "-module-nonterms");
-      Indent_Line (" '(");
-      Indent := Indent + 3;
-      Indent_Line (WisiToken_Accept_Name);
-      for Rule of Input_Data.Tokens.Rules loop
-         Indent_Line (-Rule.Left_Hand_Side);
-      end loop;
-      Indent_Line ("))");
-      Indent := Indent - 3;
-      New_Line;
-
-      Indent_Line
-        ("(cl-defstruct (" & Lower_Package_Name_Root &
-           "-wisi-module-parser (:include wisi-parser)))");
-      New_Line;
-      Indent_Line ("(defun " & Lower_Package_Name_Root & 
"-wisi-module-parser-make (dll-name)");
-      Indent_Line ("  (module-load dll-name)");
-      Indent_Line ("  (make-" & Lower_Package_Name_Root & 
"-wisi-module-parser))");
-      New_Line;
-
-      Indent_Line ("(defvar " & Lower_Package_Name_Root & "-module-lexer 
nil)");
-      Indent_Line
-        ("(declare-function " &
-           Lower_Package_Name_Root &
-           "-wisi-module-parse """ &
-           Lower_Package_Name_Root &
-           "-wisi-module-parse.c"")");
-      New_Line;
-
-      Indent_Line
-        ("(cl-defmethod wisi-parse-current ((parser " &
-           Lower_Package_Name_Root &
-           "-wisi-module-parser))");
-      Indent := Indent + 2;
-      Indent_Line ("(let* ((wisi-lexer " & Lower_Package_Name_Root & 
"-module-lexer)");
-      Indent_Line ("       (result (" & Lower_Package_Name_Root & 
"-wisi-module-parse)))");
-      --  Result is nil for no errors, a string for some error.
-      --  Ada code has already added line:column, but not file name
-      Indent_Line ("  (when result");
-      Indent_Line ("    (signal 'wisi-parse-error (format ""%s:%s"" 
(buffer-name) result)))))");
-      New_Line;
-      Indent := Indent - 2;
-
-      Indent_Line ("(provide '" & Output_File_Name_Root & "-module)");
-      Set_Output (Standard_Output);
-      Close (File);
-
-   end Create_Module_Elisp;
-
-   procedure Create_Module_Aux
-   is
-      use WisiToken.Generate;
-
-      Package_Name_Root       : constant String := File_Name_To_Ada 
(Output_File_Name_Root);
-      Lower_Package_Name_Root : constant String := To_Lower 
(Package_Name_Root);
-
-      File : File_Type;
-   begin
-      Create (File, Out_File, Output_File_Name_Root & 
"_wisi_module_parse.gpr");
-      Set_Output (File);
-      Indent := 1;
-      Put_Line ("-- generated by WisiToken Wisi from " & 
Input_Data.Grammar_Lexer.File_Name);
-      Put_Command_Line ("-- ", Use_Tuple => True, Tuple => Tuple);
-      Indent_Line ("with ""wisi_module_parse_common"";");
-      Indent_Line ("library project " & Package_Name_Root & 
"_Wisi_Module_Parse is");
-      New_Line;
-      Indent := Indent + 3;
-      Indent_Line ("for Languages use (""Ada"");");
-      Indent_Line ("for Source_Dirs use (""../.."", ""."");");
-      New_Line;
-      Indent_Line ("for Source_Files use");
-      Indent_Line ("  (");
-      Indent := Indent + 3;
-      Indent_Line ("""emacs_module_aux.ads"",");
-      Indent_Line ("""emacs_module_aux.adb"",");
-      Indent_Line ("""emacs_module_h.ads"",");
-      Indent_Line ("""fasttoken-lexer-wisi_elisp.adb"",");
-      Indent_Line ("""fasttoken-lexer-wisi_elisp.ads"",");
-      Indent_Line ("""" & Lower_Package_Name_Root & "_module.adb"",");
-      Indent_Line ("""" & Lower_Package_Name_Root & "_module.ads""");
-      Indent := Indent - 3;
-      Indent_Line ("  );");
-      New_Line;
-      Indent_Line ("for Object_Dir use ""libobjsjlj"";");
-      Indent_Line ("for Library_Name use """ & Lower_Package_Name_Root & 
"_wisi_module_parse"";");
-      Indent_Line ("for Library_Dir use ""libsjlj"";");
-      --  This library is linked with *_wisi_module_parse_wrapper.c to
-      --  make a dynamic library
-      Indent_Line ("for Library_Kind use ""static"";");
-      New_Line;
-      Indent_Line ("package Compiler is");
-      Indent := Indent + 3;
-      Indent_Line
-        ("for Default_Switches (""Ada"") use 
Wisi_Module_Parse_Common.Compiler'Default_Switches (""Ada"");");
-
-      --  Grammar files can get very large, so they need some special switches:
-      --
-      --  'Wisi_Module_Parse_Common.Compiler'Default_Switches' includes 
'gnatn', but that hangs
-      Indent_Line ("case Wisi_Module_Parse_Common.Build is");
-      Indent_Line ("when ""Debug"" =>");
-      Indent_Line ("   for Switches (""" & Lower_Package_Name_Root & 
"_module.adb"") use");
-      Indent_Line ("     Wisi_Module_Parse_Common.Compiler.Common_Switches &");
-      Indent_Line ("     Wisi_Module_Parse_Common.Compiler.Standard_Style &");
-      Indent_Line ("     (""-O0"");");
-      Indent_Line ("when ""Normal"" =>");
-      Indent_Line ("   for Switches (""" & Lower_Package_Name_Root & 
"_module.adb"") use");
-      Indent_Line ("     Wisi_Module_Parse_Common.Compiler.Common_Switches &");
-      Indent_Line ("     Wisi_Module_Parse_Common.Compiler.Standard_Style &");
-      Indent_Line ("     (""-O2"");");
-      Indent_Line ("end case;");
-
-      Indent := Indent - 3;
-      Indent_Line ("end Compiler;");
-      New_Line;
-      Indent_Line ("package Builder is");
-      Indent_Line
-        ("   for Default_Switches (""Ada"") use 
Wisi_Module_Parse_Common.Builder'Default_Switches (""Ada"");");
-      Indent_Line ("end Builder;");
-      Indent := Indent - 3;
-      New_Line;
-      Indent_Line ("end " & Package_Name_Root & "_Wisi_Module_Parse;");
-      Set_Output (Standard_Output);
-      Close (File);
-
-      Create (File, Out_File, Output_File_Name_Root & 
"_wisi_module_parse_agg.gpr");
-      Set_Output (File);
-      Indent := 1;
-      Put_Line ("-- generated by WisiToken Wisi from " & 
Input_Data.Grammar_Lexer.File_Name);
-      Put_Command_Line ("-- ", Use_Tuple => True, Tuple => Tuple);
-      Indent_Line ("aggregate project " & Package_Name_Root & 
"_Wisi_Module_Parse_Agg is");
-      Indent_Line ("   for Project_Path use (external (""WISI_FASTTOKEN""));");
-      Indent_Line ("   for Project_files use (""" & Lower_Package_Name_Root & 
"_wisi_module_parse.gpr"");");
-      Indent_Line ("end " & Package_Name_Root & "_Wisi_Module_Parse_Agg;");
-      Set_Output (Standard_Output);
-      Close (File);
-
-      Create (File, Out_File, Output_File_Name_Root & 
"_wisi_module_parse_wrapper.c");
-      Set_Output (File);
-      Indent := 1;
-      Put_Line ("// generated by WisiToken Wisi from " & 
Input_Data.Grammar_Lexer.File_Name);
-      Put_Command_Line ("// ", Use_Tuple => True, Tuple => Tuple);
-      Indent_Line ("//  This file is just a wrapper around the Ada code in");
-      Indent_Line ("//  *_wisi_module_parse.adb; it is needed to call 
adainit.");
-      Indent_Line ("#include <emacs_module.h>");
-      Indent_Line ("int plugin_is_GPL_compatible;");
-      Indent_Line ("extern void adainit(void);");
-      Indent_Line ("extern int " & Lower_Package_Name_Root & 
"_wisi_module_parse_init (emacs_env *env);");
-      Indent_Line ("/* Parse current buffer, using parser in current module. 
*/");
-      Indent_Line ("extern emacs_value " & Lower_Package_Name_Root & 
"_wisi_module_parse (emacs_env *env);");
-      Indent_Line ("static emacs_value Fparse (emacs_env *env, int nargs, 
emacs_value args[])");
-      Indent_Line ("{");
-      Indent_Line ("  return " & Lower_Package_Name_Root & "_wisi_module_parse 
(env);");
-      Indent_Line ("}");
-      New_Line;
-      Indent_Line ("int emacs_module_init (struct emacs_runtime *ert)");
-      Indent_Line ("{");
-      Indent_Line ("  emacs_env *env = ert->get_environment (ert);");
-      Indent_Line
-        ("  env->bind_function (env, """ & Lower_Package_Name_Root &
-           "-wisi-module-parse"", env->make_function (env, 1, 1, Fparse));");
-      Indent_Line ("  adainit();");
-      Indent_Line ("  return " & Lower_Package_Name_Root & 
"_wisi_module_parse_init (env);");
-      Indent_Line ("}");
-      Set_Output (Standard_Output);
-      Close (File);
-   end Create_Module_Aux;
-
-begin
-   case Common_Data.Lexer is
-   when None | re2c_Lexer =>
-      null;
-
-   when Elisp_Lexer =>
-      raise User_Error with WisiToken.Generate.Error_Message
-        (Input_Data.Grammar_Lexer.File_Name, 1, "Ada_Emacs output language 
does not support " &
-           Lexer_Image (Common_Data.Lexer).all & " lexer");
-   end case;
-
-   declare
-      Actions_Package_Name : constant String := File_Name_To_Ada 
(Output_File_Name_Root) &
-        (case Common_Data.Interface_Kind is
-         when Process => "_Process_Actions",
-         when Module  => "_Module_Actions");
-
-      Main_Package_Name : constant String := File_Name_To_Ada 
(Output_File_Name_Root) &
-        (case Common_Data.Interface_Kind is
-         when Process => "_Process",
-         when Module  => "_Module") &
-        Gen_Alg_Name & "_Main";
-   begin
-      if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
-         --  We typically have no actions when just getting started with a new 
language.
-         Create_Ada_Actions_Body
-           (Generate_Data.Action_Names, Generate_Data.Check_Names, 
Input_Data.Label_Count, Actions_Package_Name);
-      end if;
-
-      Create_Ada_Actions_Spec
-        (Output_File_Name => Output_File_Name_Root &
-           (case Common_Data.Interface_Kind is
-            when Process  => "_process_actions.ads",
-            when Module   => "_module_actions.ads"),
-         Package_Name     => Actions_Package_Name,
-         Input_Data       => Input_Data,
-         Common_Data      => Common_Data,
-         Generate_Data    => Generate_Data);
-
-      if Tuple.Gen_Alg = External then
-         Create_External_Main_Spec (Main_Package_Name, Tuple, Input_Data);
-
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-      else
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-
-         Create_Ada_Main_Spec
-           (Output_File_Name  => Output_File_Name_Root & "_" &
-              To_Lower (Interface_Type'Image (Common_Data.Interface_Kind)) &
-              To_Lower (Gen_Alg_Name) & "_main.ads",
-            Main_Package_Name => Main_Package_Name,
-            Common_Data       => Common_Data,
-            Input_Data        => Input_Data);
-      end if;
-   end;
-
-   case Common_Data.Interface_Kind is
-   when Process =>
-      Create_Process_Elisp;
-
-   when Module =>
-      Create_Module_Elisp;
-      Create_Module_Aux;
-   end case;
-exception
-when others =>
-   Set_Output (Standard_Output);
-   raise;
-end WisiToken.BNF.Output_Ada_Emacs;
diff --git a/packages/wisi/wisitoken-bnf-output_elisp_common.adb 
b/packages/wisi/wisitoken-bnf-output_elisp_common.adb
deleted file mode 100644
index 2260955..0000000
--- a/packages/wisi/wisitoken-bnf-output_elisp_common.adb
+++ /dev/null
@@ -1,212 +0,0 @@
---  Abstract :
---
---  See spec
---
---  Copyright (C) 2012, 2013, 2015, 2017 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Text_IO;
-with WisiToken.Generate;
-package body WisiToken.BNF.Output_Elisp_Common is
-
-   function Find_Elisp_ID (List : in String_Lists.List; Elisp_Name : in 
String) return Integer
-   is
-      I : Integer := 0; -- match elisp array
-   begin
-      for Name of List loop
-         if Name = Elisp_Name then
-            return I;
-         end if;
-         I := I + 1;
-      end loop;
-      raise Not_Found with "unknown elisp name: '" & Elisp_Name & "'";
-   end Find_Elisp_ID;
-
-   function Elisp_Name_To_Ada
-     (Elisp_Name : in String;
-      Append_ID  : in Boolean;
-      Trim       : in Integer)
-     return String
-   is
-      Result : String := Elisp_Name (Elisp_Name'First + Trim .. 
Elisp_Name'Last);
-   begin
-      Result (Result'First) := To_Upper (Result (Result'First));
-      for I in Result'Range loop
-         if Result (I) = '-' then
-            Result (I) := '_';
-            Result (I + 1) := To_Upper (Result (I + 1));
-         elsif Result (I) = '_' then
-            Result (I + 1) := To_Upper (Result (I + 1));
-         end if;
-      end loop;
-      if Append_ID then
-         return Result & "_ID"; -- Some elisp names may be Ada reserved words;
-      else
-         return Result;
-      end if;
-   end Elisp_Name_To_Ada;
-
-   procedure Indent_Keyword_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Keywords         : in     String_Pair_Lists.List;
-      Image            : access function (Name : in 
Ada.Strings.Unbounded.Unbounded_String) return String)
-   is
-      use Ada.Text_IO;
-      use WisiToken.Generate;
-   begin
-      Indent_Line ("(defconst " & Output_File_Root & "-" & Label & 
"-keyword-table-raw");
-      Indent_Line ("  '(");
-      Indent := Indent + 3;
-      for Pair of Keywords loop
-         Indent_Line ("(" & (-Pair.Value) & " . " & Image (Pair.Name) & ")");
-      end loop;
-      Indent_Line ("))");
-      Indent := Indent - 3;
-   end Indent_Keyword_Table;
-
-   procedure Indent_Token_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Tokens           : in     Token_Lists.List;
-      Image            : access function (Name : in 
Ada.Strings.Unbounded.Unbounded_String) return String)
-   is
-      use Ada.Strings.Unbounded;
-      use Ada.Text_IO;
-      use WisiToken.Generate;
-
-      function To_Double_Quotes (Item : in String) return String
-      is
-         Result : String := Item;
-      begin
-         if Result (Result'First) = ''' then
-            Result (Result'First) := '"';
-         end if;
-         if Result (Result'Last) = ''' then
-            Result (Result'Last) := '"';
-         end if;
-         return Result;
-      end To_Double_Quotes;
-
-   begin
-      Indent_Line ("(defconst " & Output_File_Root & "-" & Label & 
"-token-table-raw");
-      Indent_Line ("  '(");
-      Indent := Indent + 3;
-      for Kind of Tokens loop
-         if not (-Kind.Kind = "line_comment" or -Kind.Kind = "whitespace") then
-            Indent_Line ("(""" & (-Kind.Kind) & """");
-            Indent := Indent + 1;
-            for Token of Kind.Tokens loop
-               if 0 = Length (Token.Value) then
-                  Indent_Line ("(" & Image (Token.Name) & ")");
-               else
-                  if -Kind.Kind = "number" then
-                     --  allow for (<token> <number-p> <require>)
-                     Indent_Line ("(" & Image (Token.Name) & " " & 
(-Token.Value) & ")");
-                  elsif -Kind.Kind = "symbol" or
-                    -Kind.Kind = "string-double" or
-                    -Kind.Kind = "string-single"
-                  then
-                     --  value not used by elisp
-                     Indent_Line ("(" & Image (Token.Name) & " . """")");
-                  else
-                     Indent_Line ("(" & Image (Token.Name) & " . " & 
To_Double_Quotes (-Token.Value) & ")");
-                  end if;
-               end if;
-            end loop;
-            Indent_Line (")");
-            Indent := Indent - 1;
-         end if;
-      end loop;
-      Indent_Line ("))");
-      Indent := Indent - 3;
-   end Indent_Token_Table;
-
-   procedure Indent_Name_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Names            : in     String_Lists.List)
-   is
-      use Ada.Text_IO;
-      use WisiToken.Generate;
-   begin
-      Indent_Line ("(defconst " & Output_File_Root & "-" & Label);
-      Indent_Line ("  [");
-      Indent := Indent + 3;
-      for Name of Names loop
-         Indent_Line (Name);
-      end loop;
-      Indent_Line ("])");
-      Indent := Indent - 3;
-   end Indent_Name_Table;
-
-   procedure Indent_Repair_Image
-     (Output_File_Root : in String;
-      Label            : in String;
-      Tokens           : in WisiToken.BNF.Tokens)
-   is
-      use all type Ada.Text_IO.Count;
-      use Ada.Strings.Unbounded;
-      use WisiToken.Generate;
-
-      function re2c_To_Elisp (Item : in String) return String
-      is
-         Result : String (1 .. Item'Length * 2);
-         Last : Integer := Result'First - 1;
-      begin
-         --  Convert re2c case-insensitive string '...' to elisp string "...",
-         --  with '"' escaped.
-         if Item (Item'First) /= ''' then
-            return Item;
-         end if;
-
-         for C of Item loop
-            if C = ''' then
-               Result (Last + 1) := '"';
-               Last := Last + 1;
-            elsif C = '"' then
-               Result (Last + 1) := '\';
-               Result (Last + 2) := '"';
-               Last := Last + 2;
-            else
-               Result (Last + 1) := C;
-               Last := Last + 1;
-            end if;
-         end loop;
-         return Result (1 .. Last);
-      end re2c_To_Elisp;
-
-   begin
-      Indent_Line ("(defconst " & Output_File_Root & "-" & Label & 
"-repair-image");
-      Indent_Line ("  '(");
-      Indent := Indent + 3;
-      for Pair of Tokens.Keywords loop
-         Indent_Line ("(" & (-Pair.Name) & " . " & (-Pair.Value) & ")");
-      end loop;
-      for Kind of Tokens.Tokens loop
-         for Token of Kind.Tokens loop
-            if Length (Token.Repair_Image) > 0 then
-               Indent_Line ("(" & (-Token.Name) & " . " & re2c_To_Elisp 
(-Token.Repair_Image) & ")");
-            else
-               Indent_Line ("(" & (-Token.Name) & " . " & (-Token.Value) & 
")");
-            end if;
-         end loop;
-      end loop;
-      Indent_Line ("))");
-      Indent := Indent - 3;
-   end Indent_Repair_Image;
-
-end WisiToken.BNF.Output_Elisp_Common;
diff --git a/packages/wisi/wisitoken-bnf-output_elisp_common.ads 
b/packages/wisi/wisitoken-bnf-output_elisp_common.ads
deleted file mode 100644
index 03a655e..0000000
--- a/packages/wisi/wisitoken-bnf-output_elisp_common.ads
+++ /dev/null
@@ -1,54 +0,0 @@
---  Abstract :
---
---  Subprograms common to Output_Elisp and Output_Ada_Emacs
---
---  Copyright (C) 2012, 2013, 2015, 2017, 2018, 2019 Free Software Foundation, 
Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package WisiToken.BNF.Output_Elisp_Common is
-
-   function Find_Elisp_ID (List : in WisiToken.BNF.String_Lists.List; 
Elisp_Name : in String) return Integer;
-
-   function Elisp_Name_To_Ada
-     (Elisp_Name : in String;
-      Append_ID  : in Boolean;
-      Trim       : in Integer)
-     return String;
-   --  Drop Trim chars from beginning of Elisp_Name, capitalize.
-
-   procedure Indent_Keyword_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Keywords         : in     String_Pair_Lists.List;
-      Image            : access function (Name : in 
Ada.Strings.Unbounded.Unbounded_String) return String);
-
-   procedure Indent_Token_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Tokens           : in     Token_Lists.List;
-      Image            : access function (Name : in 
Ada.Strings.Unbounded.Unbounded_String) return String);
-
-   procedure Indent_Name_Table
-     (Output_File_Root : in     String;
-      Label            : in     String;
-      Names            : in     String_Lists.List);
-
-   procedure Indent_Repair_Image
-     (Output_File_Root : in String;
-      Label            : in String;
-      Tokens           : in WisiToken.BNF.Tokens);
-
-end WisiToken.BNF.Output_Elisp_Common;
diff --git a/packages/wisi/wisitoken-bnf-utils.adb 
b/packages/wisi/wisitoken-bnf-utils.adb
deleted file mode 100644
index 71e340f..0000000
--- a/packages/wisi/wisitoken-bnf-utils.adb
+++ /dev/null
@@ -1,45 +0,0 @@
---  Abstract :
---
---  See spec
---
---  Copyright (C) 2012, 2013, 2015, 2017, 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-package body WisiToken.BNF.Utils is
-
-   function Strip_Quotes (Item : in String) return String
-   is begin
-      if Item'Length < 2 then
-         return Item;
-      else
-         return Item
-           ((if Item (Item'First) = '"' then Item'First + 1 else Item'First) ..
-              (if Item (Item'Last) = '"' then Item'Last - 1 else Item'Last));
-      end if;
-   end Strip_Quotes;
-
-   function Strip_Parens (Item : in String) return String
-   is begin
-      if Item'Length < 2 then
-         return Item;
-      else
-         return Item
-           ((if Item (Item'First) = '(' then Item'First + 1 else Item'First) ..
-              (if Item (Item'Last) = ')' then Item'Last - 1 else Item'Last));
-      end if;
-   end Strip_Parens;
-
-end WisiToken.BNF.Utils;
diff --git a/packages/wisi/wisitoken-bnf-utils.ads 
b/packages/wisi/wisitoken-bnf-utils.ads
deleted file mode 100644
index 6062ff9..0000000
--- a/packages/wisi/wisitoken-bnf-utils.ads
+++ /dev/null
@@ -1,29 +0,0 @@
---  Abstract :
---
---  Utilities for generating source code from BNF source files
---
---  Copyright (C) 2012, 2013, 2015, 2017, 2018 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package WisiToken.BNF.Utils is
-
-   function Strip_Quotes (Item : in String) return String;
-   --  Remove leading and trailing '"', if any.
-
-   function Strip_Parens (Item : in String) return String;
-   --  Remove leading and trailing '()', if any.
-
-end WisiToken.BNF.Utils;
diff --git a/packages/wisi/wisitoken-bnf.adb b/packages/wisi/wisitoken-bnf.adb
deleted file mode 100644
index 29e4f60..0000000
--- a/packages/wisi/wisitoken-bnf.adb
+++ /dev/null
@@ -1,355 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2012 - 2015, 2017 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This program is distributed in the
---  hope that it will be useful, but WITHOUT ANY WARRANTY; without even
---  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
---  PURPOSE. See the GNU General Public License for more details. You
---  should have received a copy of the GNU General Public License
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Text_IO;
-with Ada.Strings.Fixed;
-package body WisiToken.BNF is
-
-   procedure Add
-     (Set   : in out Generate_Set_Access;
-      Tuple : in     Generate_Tuple)
-   is
-      Prev : Generate_Set_Access := Set;
-      Last : constant Integer    := (if Prev = null then 1 else 
Prev.all'Length + 1);
-   begin
-      Set := new Generate_Set (1 .. Last);
-      for I in 1 .. Last - 1 loop
-         Set (I) := Prev (I);
-      end loop;
-      Set (Last) := Tuple;
-      Free (Prev);
-   end Add;
-
-   function To_Generate_Algorithm (Item : in String) return Generate_Algorithm
-   is begin
-      for I in Generate_Algorithm loop
-         if To_Lower (Generate_Algorithm_Image (I).all) = To_Lower (Item) then
-            return I;
-         end if;
-      end loop;
-      raise User_Error with "invalid generate algorithm name: '" & Item & "'";
-   end To_Generate_Algorithm;
-
-   function To_Output_Language (Item : in String) return Output_Language
-   is begin
-      for I in Output_Language loop
-         if To_Lower (Output_Language_Image (I).all) = To_Lower (Item) then
-            return I;
-         end if;
-      end loop;
-      raise User_Error with "invalid output language name: '" & Item & "'";
-   end To_Output_Language;
-
-   function To_Lexer (Item : in String) return Lexer_Type
-   is begin
-      for I in Valid_Lexer loop
-         if Lexer_Image (I).all = To_Lower (Item) then
-            return I;
-         end if;
-      end loop;
-      raise User_Error with "invalid lexer name: '" & Item & "'";
-   end To_Lexer;
-
-   function Split_Lines (Item : in String) return String_Lists.List
-   is
-      CR : Character renames ASCII.CR;
-      LF : Character renames ASCII.LF;
-
-      Result    : WisiToken.BNF.String_Lists.List;
-      I         : Integer   := Item'First;
-      First     : Integer   := Item'First;
-      Last_Char : Character := ' ';
-   begin
-      loop
-         exit when I > Item'Last;
-         if Item (I) = LF then
-            Result.Append (Item (First .. I - (if Last_Char = CR then 2 else 
1)));
-            First := I + 1;
-
-         elsif I = Item'Last then
-            Result.Append (Item (First .. I));
-         end if;
-
-         Last_Char := Item (I);
-
-         I := I + 1;
-      end loop;
-      return Result;
-   end Split_Lines;
-
-   function Trim (Item : in String_Lists.List; Comment_Start : in String) 
return String_Lists.List
-   is
-      use Ada.Strings;
-      use Ada.Strings.Fixed;
-      Result : String_Lists.List;
-      Comment : Integer;
-
-      procedure Maybe_Append (Line : in String)
-      is begin
-         if Line'Length > 0 then
-            Result.Append (Line);
-         end if;
-      end Maybe_Append;
-
-   begin
-      for Line of Item loop
-         Comment := Index (Line, Comment_Start, Going => Backward);
-         if Comment /= 0 then
-            Maybe_Append (Trim (Line (Line'First .. Comment - 1), Both));
-         else
-            Maybe_Append (Trim (Line, Both));
-         end if;
-      end loop;
-      return Result;
-   end Trim;
-
-   procedure Put_Raw_Code
-     (Comment_Syntax : in String_2;
-      Code           : in String_Lists.List;
-      Comment_Only   : in Boolean := False)
-   is
-      use Ada.Text_IO;
-      Real_Comment_Only : Boolean := Comment_Only;
-   begin
-      for Line of Code loop
-         if Line'Length >= 2 and then
-           ((Line (Line'First) = Line (Line'First + 1)) and
-              Line (Line'First) /= ' ')
-         then
-            --  The line is a comment.
-            Real_Comment_Only := Real_Comment_Only or Line (Line'First .. 
Line'First + 1) /= Comment_Syntax;
-
-            Put_Line (Comment_Syntax & Line (Line'First + 2 .. Line'Last));
-
-         elsif Comment_Syntax = Elisp_Comment and (Line'Length > 0 and then 
Line (Line'First) /= '(') then
-            null;
-
-         elsif not Comment_Only then
-            Put_Line (Line);
-         end if;
-      end loop;
-   end Put_Raw_Code;
-
-   procedure Put_File_Header
-     (Comment_Syntax : in String_2;
-      Emacs_Mode     : in String         := "";
-      Use_Tuple      : in Boolean        := False;
-      Tuple          : in Generate_Tuple := (others => <>))
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line (Comment_Syntax & "  generated parser support file." & 
Emacs_Mode);
-      Put_Command_Line  (Comment_Syntax & "  ", Use_Tuple, Tuple);
-      Put_Line (Comment_Syntax);
-   end Put_File_Header;
-
-   function Is_Present (List : in WisiToken.BNF.String_Pair_Lists.List; Name : 
in String) return Boolean
-   is
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-   begin
-      for Pair of List loop
-         if Pair.Name = Name then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Is_Present;
-
-   function Value (List : in WisiToken.BNF.String_Pair_Lists.List; Name : in 
String) return String
-   is
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-   begin
-      for Pair of List loop
-         if Pair.Name = Name then
-            return -Pair.Value;
-         end if;
-      end loop;
-      raise Not_Found;
-   end Value;
-
-   function Is_Present (List : in Elisp_Action_Maps.Map; Name : in String) 
return Boolean
-   is
-      use Elisp_Action_Maps;
-   begin
-      return No_Element /= List.Find (+Name);
-   end Is_Present;
-
-   function Count (Tokens : in Token_Lists.List) return Integer
-   is
-      Result : Integer := 0;
-   begin
-      for Kind of Tokens loop
-         Result := Result + Integer (Kind.Tokens.Length);
-      end loop;
-      return Result;
-   end Count;
-
-   procedure Add_Token
-     (Tokens       : in out Token_Lists.List;
-      Kind         : in     String;
-      Name         : in     String;
-      Value        : in     String;
-      Repair_Image : in     String := "")
-   is
-      use type Ada.Strings.Unbounded.Unbounded_String;
-   begin
-      for Token_Kind of Tokens loop
-         if Token_Kind.Kind = Kind then
-            Token_Kind.Tokens.Append ((+Name, +Value, +Repair_Image));
-            return;
-         end if;
-      end loop;
-
-      --  Kind not found; add it
-      declare
-         Temp : String_Triple_Lists.List;
-      begin
-         Temp.Append ((+Name, +Value, +Repair_Image));
-         Tokens.Append ((+Kind, Temp));
-      end;
-   end Add_Token;
-
-   function Is_In (Tokens : in Token_Lists.List; Kind : in String) return 
Boolean
-   is begin
-      for Token of Tokens loop
-         if -Token.Kind = Kind then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Is_In;
-
-   function Is_In
-     (Tokens : in Token_Lists.List;
-      Kind   : in String;
-      Value  : in String)
-     return Boolean
-   is begin
-      for Token of Tokens loop
-         if -Token.Kind = Kind then
-            for Item of Token.Tokens loop
-               if -Item.Value = Value then
-                  return True;
-               end if;
-            end loop;
-         end if;
-      end loop;
-      return False;
-   end Is_In;
-
-   function Is_Present (Rules : in Rule_Lists.List; LHS : in String) return 
Boolean
-   is
-      use Rule_Lists;
-
-      Found : Boolean := False;
-
-      procedure Process (Position : in Cursor)
-      is begin
-         if -Rules (Position).Left_Hand_Side = LHS then
-            Found := True;
-         end if;
-      end Process;
-
-   begin
-      Rules.Iterate (Process'Access);
-      return Found;
-   end Is_Present;
-
-   function "+" (List : in String_Lists.List; Item : in String) return 
String_Lists.List
-   is
-      Result : String_Lists.List := List;
-   begin
-      Result.Append (Item);
-      return Result;
-   end "+";
-
-   function String_To_String_List (Item : in String) return String_Lists.List
-   is
-      Result : String_Lists.List;
-   begin
-      Result.Append (Item);
-      return Result;
-   end String_To_String_List;
-
-   function RHS_To_RHS_List (Item : in RHS_Type) return RHS_Lists.List
-   is
-      Result : RHS_Lists.List;
-   begin
-      Result.Append (Item);
-      return Result;
-   end RHS_To_RHS_List;
-
-   function "+" (List : in RHS_Lists.List; Item : in RHS_Type) return 
RHS_Lists.List
-   is
-      Result : RHS_Lists.List := List;
-   begin
-      Result.Append (Item);
-      return Result;
-   end "+";
-
-   procedure Put_Command_Line
-     (Comment_Prefix : in String;
-      Use_Tuple      : in Boolean        := False;
-      Tuple          : in Generate_Tuple := (others => <>))
-   is
-      use Ada.Command_Line;
-      use Ada.Text_IO;
-
-      Max_Line_Length : constant := 120;
-      Col : Integer := 0;
-
-      procedure Put (Item : in String; Leading_Space : in Boolean)
-      is begin
-         if Col > 0 and Col + Item'Length + 1 > Max_Line_Length then
-            New_Line;
-            Col := Comment_Prefix'Length;
-            Put (Comment_Prefix);
-         else
-            if Leading_Space then
-               Put (" ");
-               Col := Col + 1;
-            end if;
-         end if;
-
-         Col := Col + Item'Length;
-         Put (Item);
-      end Put;
-   begin
-      Put (Comment_Prefix & "command line:", False);
-      Put (Ada.Directories.Simple_Name (Command_Name), True);
-      if Use_Tuple then
-         Put (" --generate " & Generate_Algorithm'Image (Tuple.Gen_Alg) & " " &
-                Output_Language_Image (Tuple.Out_Lang).all &
-                (if Tuple.Lexer /= None then " " & Lexer_Image 
(Tuple.Lexer).all else "") &
-                (if Tuple.Interface_Kind /= None then " " & 
Interface_Type'Image (Tuple.Interface_Kind) else "") &
-                (if Tuple.Text_Rep then " text_rep" else "") &
-                " " & Argument (Argument_Count), --  .wy file
-              True);
-      else
-         for I in 1 .. Argument_Count loop
-            Put (Argument (I), True);
-         end loop;
-      end if;
-      New_Line;
-   end Put_Command_Line;
-
-end WisiToken.BNF;
diff --git a/packages/wisi/wisitoken-bnf.ads b/packages/wisi/wisitoken-bnf.ads
deleted file mode 100644
index 5263008..0000000
--- a/packages/wisi/wisitoken-bnf.ads
+++ /dev/null
@@ -1,358 +0,0 @@
---  Abstract :
---
---  Root package for generating a parser from a BNF source file; see [2]
---
---  The input file syntax is based on BNF syntax [1] with declarations
---  and grammar actions.
---
---  The Elisp and Ada_Emacs output languages are for use with the
---  Emacs wisi package.
---
---  Reference :
---
---  [1] https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form
---  [2] http://www.nongnu.org/ada-mode/wisi/wisi-user_guide.html, (info 
"(wisi-user_guide)Top")
---
---  Copyright (C) 2012 - 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Characters.Handling;
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Containers.Indefinite_Doubly_Linked_Lists;
-with Ada.Containers.Ordered_Maps;
-with Ada.Containers.Vectors;
-with Ada.Strings.Unbounded;
-with Ada.Unchecked_Deallocation;
-with WisiToken.Parse.LR;
-package WisiToken.BNF is
-
-   --  See also WisiToken exceptions
-
-   Not_Found : exception;
-   --  something not found; should be handled and converted to Syntax_ or 
Grammar_Error
-
-   type Generate_Algorithm is (None, LALR, LR1, Packrat_Gen, Packrat_Proc, 
External);
-   subtype Valid_Generate_Algorithm is Generate_Algorithm range LALR .. 
Generate_Algorithm'Last;
-   subtype LR_Generate_Algorithm is Generate_Algorithm range LALR .. LR1;
-   subtype Packrat_Generate_Algorithm is Generate_Algorithm range Packrat_Gen 
.. Packrat_Proc;
-
-   Generate_Algorithm_Image : constant array (Generate_Algorithm) of 
String_Access_Constant :=
-     (None         => new String'("None"),
-      LALR         => new String'("LALR"),
-      LR1          => new String'("LR1"),
-      Packrat_Gen  => new String'("Packrat_Gen"),
-      Packrat_Proc => new String'("Packrat_Proc"),
-      External     => new String'("External"));
-   --  Suitable for Ada package names.
-
-   function To_Generate_Algorithm (Item : in String) return Generate_Algorithm;
-   --  Raises User_Error for invalid Item
-
-   type Generate_Algorithm_Set is array (Generate_Algorithm) of Boolean;
-   type Generate_Algorithm_Set_Access is access Generate_Algorithm_Set;
-
-   type Output_Language is (Ada_Lang, Ada_Emacs_Lang);
-   subtype Ada_Output_Language is Output_Language range Ada_Lang .. 
Ada_Emacs_Lang;
-   --  _Lang to avoid colliding with the standard package Ada and
-   --  WisiToken packages named *.Ada. In the grammar file, they
-   --  are named by (case insensitive):
-   Output_Language_Image : constant array (Output_Language) of 
String_Access_Constant :=
-     (Ada_Lang       => new String'("Ada"),
-      Ada_Emacs_Lang => new String'("Ada_Emacs"));
-
-   function To_Output_Language (Item : in String) return Output_Language;
-   --  Raises User_Error for invalid Item
-
-   type Lexer_Type is (None, Elisp_Lexer, re2c_Lexer);
-   subtype Valid_Lexer is Lexer_Type range Elisp_Lexer .. Lexer_Type'Last;
-   --  We append "_Lexer" to these names to avoid colliding with the
-   --  similarly-named WisiToken packages. In the grammar file, they
-   --  are named by:
-   Lexer_Image : constant array (Lexer_Type) of String_Access_Constant :=
-     (None        => new String'("none"),
-      Elisp_Lexer => new String'("elisp"),
-      re2c_Lexer  => new String'("re2c"));
-
-   function To_Lexer (Item : in String) return Lexer_Type;
-   --  Raises User_Error for invalid Item
-
-   type Lexer_Set is array (Lexer_Type) of Boolean;
-
-   type Lexer_Generate_Algorithm_Set is array (Lexer_Type) of 
Generate_Algorithm_Set;
-   --  %if lexer change change the generated parse table
-
-   type Interface_Type is (None, Process, Module);
-   subtype Valid_Interface is Interface_Type range Process .. Module;
-
-   type Generate_Tuple is record
-      Gen_Alg        : Generate_Algorithm := None;
-      Out_Lang       : Output_Language    := Ada_Lang;
-      Lexer          : Lexer_Type         := None;
-      Interface_Kind : Interface_Type     := None;
-      Text_Rep       : Boolean            := False;
-   end record;
-
-   type Generate_Set is array (Natural range <>) of Generate_Tuple;
-   type Generate_Set_Access is access Generate_Set;
-   procedure Free is new Ada.Unchecked_Deallocation (Generate_Set, 
Generate_Set_Access);
-
-   procedure Add
-     (Set   : in out Generate_Set_Access;
-      Tuple : in     Generate_Tuple);
-
-   package String_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists 
(String);
-
-   package String_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Identifier_Index, Ada.Strings.Unbounded.Unbounded_String,
-      Default_Element => Ada.Strings.Unbounded.Null_Unbounded_String);
-
-   type Language_Param_Type is record
-      --  Set by grammar file declarations or command line options. Error
-      --  recover parameters are in McKenzie_Recover_Param_Type below.
-      Case_Insensitive          : Boolean := False;
-      End_Names_Optional_Option : Ada.Strings.Unbounded.Unbounded_String;
-      Use_Language_Runtime      : Boolean := True;
-      Language_Runtime_Name     : Ada.Strings.Unbounded.Unbounded_String;
-      Declare_Enums             : Boolean := True;
-      Error_Recover             : Boolean := False;
-      Start_Token               : Ada.Strings.Unbounded.Unbounded_String;
-      Partial_Recursion         : Boolean := False;
-   end record;
-
-   type Raw_Code_Location is
-     (Copyright_License,
-      Actions_Spec_Context, Actions_Spec_Pre, Actions_Spec_Post,
-      Actions_Body_Context, Actions_Body_Pre, Actions_Body_Post);
-   --  So far we have not needed raw code other than license in the main
-   --  package.
-
-   type Raw_Code is array (Raw_Code_Location) of String_Lists.List;
-
-   subtype String_2 is String (1 .. 2);
-
-   Ada_Comment   : constant String_2 := "--";
-   C_Comment     : constant String_2 := "//";
-   Elisp_Comment : constant String_2 := ";;";
-
-   function Split_Lines (Item : in String) return String_Lists.List;
-
-   function Trim (Item : in String_Lists.List; Comment_Start : in String) 
return String_Lists.List;
-   --  From each element, delete trailing comments starting with
-   --  Comment_Start; delete leading and trailing spaces.
-
-   procedure Put_Raw_Code
-     (Comment_Syntax : in String_2;
-      Code           : in String_Lists.List;
-      Comment_Only   : in Boolean := False);
-   --  Output Code to Ada.Text_IO.Current_Output.
-   --
-   --  If first two characters of a line are the same and not ' ', it is
-   --  assumed to be a comment; ensure the output line has
-   --  Comment_Syntax.
-   --
-   --  If Comment_Only is True, or if the comment syntax used in Code
-   --  does not equal Comment_Syntax, only output comment lines.
-   --
-   --  If Comment_Syntax is Elisp_Comment, only output lines that are
-   --  valid elisp comments or forms (ie start with ';;' or '(').
-   --
-   --  Otherwise output all lines.
-
-   procedure Put_File_Header
-     (Comment_Syntax : in String_2;
-      Emacs_Mode     : in String         := "";
-      Use_Tuple      : in Boolean        := False;
-      Tuple          : in Generate_Tuple := (others => <>));
-   --  Output "parser support file <emacs_mode> /n command line: " comment to 
Ada.Text_IO.Current_Output.
-
-   type String_Pair_Type is record
-      Name  : aliased Ada.Strings.Unbounded.Unbounded_String;
-      Value : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   package String_Pair_Lists is new Ada.Containers.Doubly_Linked_Lists 
(String_Pair_Type);
-   function Is_Present (List : in String_Pair_Lists.List; Name : in String) 
return Boolean;
-   function Value (List : in String_Pair_Lists.List; Name : in String) return 
String;
-
-   type String_Triple_Type is record
-      Name         : aliased Ada.Strings.Unbounded.Unbounded_String;
-      Value        : Ada.Strings.Unbounded.Unbounded_String;
-      Repair_Image : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   package String_Triple_Lists is new Ada.Containers.Doubly_Linked_Lists 
(String_Triple_Type);
-
-   type Elisp_Action_Type is record
-      --  Elisp name is the key
-      Action_Label : Ada.Strings.Unbounded.Unbounded_String;
-      Ada_Name     : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   package Elisp_Action_Maps is new Ada.Containers.Ordered_Maps
-     (Ada.Strings.Unbounded.Unbounded_String, Elisp_Action_Type, 
Ada.Strings.Unbounded."<");
-
-   function Is_Present (List : in Elisp_Action_Maps.Map; Name : in String) 
return Boolean;
-
-   type McKenzie_Recover_Param_Type is record
-      Source_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      --  Of the %mckenzie_cost_default declaration; we assume the others
-      --  are near.
-
-      Default_Insert                        : Natural               := 0;
-      Default_Delete_Terminal               : Natural               := 0;
-      Default_Push_Back                     : Natural               := 0; -- 
also default for undo_reduce
-      Delete                                : String_Pair_Lists.List;
-      Insert                                : String_Pair_Lists.List;
-      Push_Back                             : String_Pair_Lists.List;
-      Undo_Reduce                           : String_Pair_Lists.List;
-      Minimal_Complete_Cost_Delta           : Integer               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Minimal_Complete_Cost_Delta;
-      Fast_Forward                          : Integer               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Fast_Forward;
-      Matching_Begin                        : Integer               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Matching_Begin;
-      Ignore_Check_Fail                     : Natural               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Ignore_Check_Fail;
-      Check_Limit                           : WisiToken.Token_Index :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Check_Limit;
-      Check_Delta_Limit                     : Natural               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Check_Delta_Limit;
-      Enqueue_Limit                         : Natural               :=
-        WisiToken.Parse.LR.Default_McKenzie_Param.Enqueue_Limit;
-   end record;
-
-   type Token_Kind_Type is record
-      Kind   : Ada.Strings.Unbounded.Unbounded_String;
-      Tokens : String_Triple_Lists.List;
-   end record;
-
-   package Token_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Token_Kind_Type);
-
-   function Count (Tokens : in Token_Lists.List) return Integer;
-   --  Count of all leaves.
-
-   procedure Add_Token
-     (Tokens       : in out Token_Lists.List;
-      Kind         : in     String;
-      Name         : in     String;
-      Value        : in     String;
-      Repair_Image : in     String := "");
-   --  Add Name, Value, Repair_Image to Kind list in Tokens.
-
-   function Is_In (Tokens : in Token_Lists.List; Kind : in String) return 
Boolean;
-   function Is_In
-     (Tokens : in Token_Lists.List;
-      Kind   : in String;
-      Value  : in String)
-     return Boolean;
-
-   type Conflict is record
-      Source_Line : WisiToken.Line_Number_Type;
-      Action_A    : Ada.Strings.Unbounded.Unbounded_String;
-      LHS_A       : Ada.Strings.Unbounded.Unbounded_String;
-      Action_B    : Ada.Strings.Unbounded.Unbounded_String;
-      LHS_B       : Ada.Strings.Unbounded.Unbounded_String;
-      On          : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   package Conflict_Lists is new Ada.Containers.Doubly_Linked_Lists (Conflict);
-
-   type Labeled_Token is record
-      Label      : Ada.Strings.Unbounded.Unbounded_String;
-      Identifier : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-
-   package Labeled_Token_Arrays is new Ada.Containers.Vectors 
(Positive_Index_Type, Labeled_Token);
-   --  Index matches Syntax_Trees.Valid_Node_Index_Array, used for Tokens
-   --  in call to post parse grammar action.
-
-   type RHS_Type is record
-      Tokens      : Labeled_Token_Arrays.Vector;
-      Action      : Ada.Strings.Unbounded.Unbounded_String;
-      Check       : Ada.Strings.Unbounded.Unbounded_String;
-      Source_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-   end record;
-   package RHS_Lists is new Ada.Containers.Doubly_Linked_Lists (RHS_Type, "=");
-
-   type Rule_Type is record
-      Left_Hand_Side   : aliased Ada.Strings.Unbounded.Unbounded_String;
-      Right_Hand_Sides : RHS_Lists.List;
-      Labels           : String_Arrays.Vector;
-      Source_Line      : WisiToken.Line_Number_Type;
-   end record;
-
-   package Rule_Lists is new Ada.Containers.Doubly_Linked_Lists (Rule_Type);
-
-   function Is_Present (Rules : in Rule_Lists.List; LHS : in String) return 
Boolean;
-
-   type Tokens is record
-      Non_Grammar : Token_Lists.List;
-      Keywords    : String_Pair_Lists.List;
-      Tokens      : Token_Lists.List;
-      Rules       : Rule_Lists.List;
-      --  Rules included here because they define the nonterminal tokens, as
-      --  well as the productions.
-
-      Virtual_Identifiers : String_Arrays.Vector;
-      --  Nonterminals and terminals introduced by translating from EBNF to
-      --  BNF.
-
-      --  The following are specified in grammar file declarations and used
-      --  in other declarations or actions. Faces, Indents only used if .wy
-      --  action language is elisp and output language is not elisp.
-
-      re2c_Regexps : String_Pair_Lists.List; -- %re2c_regexp
-      Faces        : String_Lists.List;      -- %elisp_face
-      Indents      : String_Pair_Lists.List; -- %elisp_indent
-      Actions      : Elisp_Action_Maps.Map;  -- %elisp_action
-   end record;
-
-   function "+" (Item : in String) return 
Ada.Strings.Unbounded.Unbounded_String
-     renames Ada.Strings.Unbounded.To_Unbounded_String;
-
-   function "-" (Item : in Ada.Strings.Unbounded.Unbounded_String) return 
String
-     renames Ada.Strings.Unbounded.To_String;
-
-   function To_Lower (Item : in String) return String
-     renames Ada.Characters.Handling.To_Lower;
-
-   function To_Upper (Item : in String) return String
-     renames Ada.Characters.Handling.To_Upper;
-
-   function To_Upper (Item : in Character) return Character
-     renames Ada.Characters.Handling.To_Upper;
-
-   function "+" (List : in String_Lists.List; Item : in String) return 
String_Lists.List;
-
-   function String_To_String_List (Item : in String) return String_Lists.List;
-   function "+" (Item : in String) return String_Lists.List renames 
String_To_String_List;
-
-   function RHS_To_RHS_List (Item : in RHS_Type) return RHS_Lists.List;
-   function "+" (Item : in RHS_Type) return RHS_Lists.List renames 
RHS_To_RHS_List;
-
-   function "+" (List : in RHS_Lists.List; Item : in RHS_Type) return 
RHS_Lists.List;
-
-   function Image (Item : in Boolean) return String
-     is (if Item then "True" else "False");
-   --  Match casing in Standard.
-
-   procedure Put_Command_Line
-     (Comment_Prefix : in String;
-      Use_Tuple      : in Boolean        := False;
-      Tuple          : in Generate_Tuple := (others => <>));
-   --  Put command line to current output; indicate current tuple.
-
-end WisiToken.BNF;
diff --git a/packages/wisi/wisitoken-followed_by.adb 
b/packages/wisi/wisitoken-followed_by.adb
deleted file mode 100644
index e254bb6..0000000
--- a/packages/wisi/wisitoken-followed_by.adb
+++ /dev/null
@@ -1,207 +0,0 @@
---  Abstract :
---
---  Show productions where a token is followed by another token
---
---  Copyright (C) 2020 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.Generate;
-with WisiToken.Parse.LR.Parser_No_Recover;
-with WisiToken.Productions;
-with WisiToken.Text_IO_Trace;
-with WisiToken_Grammar_Runtime;
-with Wisitoken_Grammar_Actions;
-with Wisitoken_Grammar_Main;
-procedure WisiToken.Followed_By
-is
-   use all type WisiToken_Grammar_Runtime.Meta_Syntax;
-
-   procedure Put_Usage
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("wisitoken-followed_by <grammar file> <token a> <token b>");
-   end Put_Usage;
-
-   function Last
-     (Grammar              : in Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First_Terminal       : in Token_ID)
-     return Token_Array_Token_Set
-   is
-      function Last
-        (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-         Has_Empty_Production : in Token_ID_Set;
-         First_Terminal       : in Token_ID;
-         Non_Terminal         : in Token_ID)
-        return Token_ID_Set
-      is
-         Search_Tokens : Token_ID_Set := (Grammar.First_Index .. 
Grammar.Last_Index => False);
-      begin
-         Search_Tokens (Non_Terminal) := True;
-
-         return Result : Token_ID_Set := (First_Terminal .. Grammar.Last_Index 
=> False) do
-            while Any (Search_Tokens) loop
-               declare
-                  Added_Tokens   : Token_ID_Set := (First_Terminal .. 
Grammar.Last_Index      => False);
-                  Added_Nonterms : Token_ID_Set := (Grammar.First_Index .. 
Grammar.Last_Index => False);
-               begin
-                  for Prod of Grammar loop
-                     if Search_Tokens (Prod.LHS) then
-                        for RHS of Prod.RHSs loop
-                           for ID of reverse RHS.Tokens loop
-                              if not Result (ID) then
-                                 Added_Tokens (ID) := True;
-                                 if ID in Added_Nonterms'Range then
-                                    Added_Nonterms (ID) := True;
-                                 end if;
-                              end if;
-
-                              if ID in Has_Empty_Production'Range and then 
Has_Empty_Production (ID) then
-                                 null;
-                              else
-                                 exit;
-                              end if;
-                           end loop;
-                        end loop;
-                     end if;
-                  end loop;
-
-                  Result        := Result or Added_Tokens;
-                  Search_Tokens := Added_Nonterms;
-               end;
-            end loop;
-         end return;
-      end Last;
-
-      procedure Set_Slice (Result : in out Token_Array_Token_Set; I : 
Token_ID; Value : in Token_ID_Set)
-      is begin
-         for J in Result'Range (2) loop
-            Result (I, J) := Value (J);
-         end loop;
-      end Set_Slice;
-
-   begin
-      return Result : Token_Array_Token_Set :=
-        (Grammar.First_Index .. Grammar.Last_Index =>
-           (First_Terminal .. Grammar.Last_Index => False))
-      do
-         for I in Result'Range loop
-            Set_Slice (Result, I, Last (Grammar, Has_Empty_Production, 
First_Terminal, I));
-         end loop;
-      end return;
-   end Last;
-
-   Trace          : aliased WisiToken.Text_IO_Trace.Trace 
(Wisitoken_Grammar_Actions.Descriptor'Access);
-   Input_Data     : aliased WisiToken_Grammar_Runtime.User_Data_Type;
-   Grammar_Parser : WisiToken.Parse.LR.Parser_No_Recover.Parser;
-
-   Token_A_Name : Ada.Strings.Unbounded.Unbounded_String;
-   Token_B_Name : Ada.Strings.Unbounded.Unbounded_String;
-begin
-   Wisitoken_Grammar_Main.Create_Parser
-     (Parser    => Grammar_Parser,
-      Trace     => Trace'Unchecked_Access,
-      User_Data => Input_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-   begin
-      if Argument_Count /= 3 then
-         Put_Usage;
-      end if;
-
-      Grammar_Parser.Lexer.Reset_With_File (Argument (1));
-
-      Token_A_Name := +Argument (2);
-      Token_B_Name := +Argument (3);
-   end;
-
-   Grammar_Parser.Parse;
-   Grammar_Parser.Execute_Actions; -- Meta phase.
-
-   if Input_Data.Meta_Syntax = WisiToken_Grammar_Runtime.EBNF_Syntax then
-      WisiToken_Grammar_Runtime.Translate_EBNF_To_BNF 
(Grammar_Parser.Parsers.First_State_Ref.Tree, Input_Data);
-      if WisiToken.Generate.Error then
-         raise WisiToken.Grammar_Error with "errors during translating EBNF to 
BNF: aborting";
-      end if;
-   end if;
-
-   Input_Data.Reset;
-   Input_Data.Phase := WisiToken_Grammar_Runtime.Other;
-   Grammar_Parser.Execute_Actions; -- populates Input_Data.Tokens
-
-   declare
-      use Ada.Text_IO;
-
-      Generate_Data : aliased WisiToken.BNF.Generate_Utils.Generate_Data :=
-        WisiToken.BNF.Generate_Utils.Initialize (Input_Data, Ignore_Conflicts 
=> True);
-      --  Builds Generate_Data.Descriptor, Generate_Data.Grammar
-
-      Nullable : constant Token_Array_Production_ID := 
WisiToken.Generate.Nullable (Generate_Data.Grammar);
-      Has_Empty_Production : constant Token_ID_Set := 
WisiToken.Generate.Has_Empty_Production (Nullable);
-
-      First_Nonterm_Set : constant Token_Array_Token_Set := 
WisiToken.Generate.First
-        (Generate_Data.Grammar, Has_Empty_Production, 
Generate_Data.Descriptor.First_Terminal);
-
-      Last_Nonterm_Set : constant Token_Array_Token_Set := Last
-        (Generate_Data.Grammar, Has_Empty_Production, 
Generate_Data.Descriptor.First_Terminal);
-
-      Token_A    : constant Token_ID := BNF.Generate_Utils.Find_Token_ID 
(Generate_Data, -Token_A_Name);
-      Token_B    : constant Token_ID := BNF.Generate_Utils.Find_Token_ID 
(Generate_Data, -Token_B_Name);
-      Need_Comma : Boolean           := False;
-
-      procedure Put (LHS : in Token_ID; RHS : in Natural)
-      is
-      begin
-         if Need_Comma then
-            Put (", ");
-         else
-            Need_Comma := True;
-         end if;
-         Put (Trimmed_Image ((LHS, RHS)));
-      end Put;
-
-   begin
-      for LHS in Generate_Data.Grammar.First_Index .. 
Generate_Data.Grammar.Last_Index loop
-         declare
-            use WisiToken.Productions;
-            Prod : Instance renames Generate_Data.Grammar (LHS);
-         begin
-            for I in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-               declare
-                  Tokens : Token_ID_Arrays.Vector renames Prod.RHSs (I).Tokens;
-               begin
-                  for J in Tokens.First_Index .. Tokens.Last_Index loop
-                     if Tokens (J) = Token_A or
-                       (Tokens (J) in Last_Nonterm_Set'Range (1) and then
-                          Last_Nonterm_Set (Tokens (J), Token_A))
-                     then
-                        if J < Tokens.Last_Index then
-                           if Tokens (J + 1) in First_Nonterm_Set'Range (1) 
then
-                              if First_Nonterm_Set (Tokens (J + 1), Token_B) 
then
-                                 Put (LHS, I);
-                              end if;
-                           elsif Tokens (J + 1) = Token_B then
-                              Put (LHS, I);
-                           end if;
-                        end if;
-                     end if;
-                  end loop;
-               end;
-            end loop;
-         end;
-      end loop;
-   end;
-
-end WisiToken.Followed_By;
diff --git a/packages/wisi/wisitoken-gen_token_enum.adb 
b/packages/wisi/wisitoken-gen_token_enum.adb
deleted file mode 100644
index 0b17832..0000000
--- a/packages/wisi/wisitoken-gen_token_enum.adb
+++ /dev/null
@@ -1,133 +0,0 @@
---  Abstract :
---
---  See spec
---
---  Copyright (C) 2017, 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (GPL);
-
-with Ada.Characters.Handling;
-with WisiToken.Wisi_Ada;
-package body WisiToken.Gen_Token_Enum is
-
-   function Token_Enum_Image return Token_ID_Array_String
-   is
-      use Ada.Characters.Handling;
-      Result : Token_ID_Array_String (Token_ID'First .. +Last_Nonterminal);
-   begin
-      for I in Token_Enum_ID loop
-         if I <= Last_Terminal then
-            Result (+I) := new String'(Token_Enum_ID'Image (I));
-         else
-            Result (+I) := new String'(To_Lower (Token_Enum_ID'Image (I)));
-         end if;
-      end loop;
-      return Result;
-   end Token_Enum_Image;
-
-   function To_Syntax (Item : in Enum_Syntax) return 
WisiToken.Lexer.Regexp.Syntax
-   is
-      Result : WisiToken.Lexer.Regexp.Syntax (Token_ID'First .. 
+Last_Terminal);
-   begin
-      for I in Result'Range loop
-         Result (I) := Item (-I);
-      end loop;
-      return Result;
-   end To_Syntax;
-
-   function "&" (Left, Right : in Token_Enum_ID) return Token_ID_Arrays.Vector
-   is begin
-      return Result : Token_ID_Arrays.Vector do
-         Result.Append (+Left);
-         Result.Append (+Right);
-      end return;
-   end "&";
-
-   function "&"
-     (Left  : in Token_ID_Arrays.Vector;
-      Right : in Token_Enum_ID)
-     return Token_ID_Arrays.Vector
-   is begin
-      return Result : Token_ID_Arrays.Vector := Left do
-         Result.Append (+Right);
-      end return;
-   end "&";
-
-   function "+"
-     (Left  : in Token_Enum_ID;
-      Right : in WisiToken.Syntax_Trees.Semantic_Action)
-     return WisiToken.Productions.Right_Hand_Side
-   is begin
-      return WisiToken.Wisi_Ada."+" (+Left, Right);
-   end "+";
-
-   function "<="
-     (Left  : in Token_Enum_ID;
-      Right : in WisiToken.Productions.Right_Hand_Side)
-     return WisiToken.Productions.Instance
-   is begin
-      return WisiToken.Wisi_Ada."<=" (+Left, Productions.RHS_Arrays.To_Vector 
(Right, 1));
-   end "<=";
-
-   function To_Nonterminal_Array_Token_Set
-     (Item : in Nonterminal_Array_Token_Set)
-     return WisiToken.Token_Array_Token_Set
-   is
-      Result : Token_Array_Token_Set :=
-        (LR1_Descriptor.First_Nonterminal .. LR1_Descriptor.Last_Nonterminal =>
-           (LR1_Descriptor.First_Terminal .. LR1_Descriptor.Last_Nonterminal 
=> False));
-   begin
-      for I in Item'Range (1) loop
-         for J in Item'Range (2) loop
-            Result (+I, +J) := Item (I, J);
-         end loop;
-      end loop;
-      return Result;
-   end To_Nonterminal_Array_Token_Set;
-
-   function To_Nonterminal_Array_Terminal_Set
-     (Item : in Nonterminal_Array_Terminal_Set)
-     return WisiToken.Token_Array_Token_Set
-   is
-      Result : Token_Array_Token_Set :=
-        (LR1_Descriptor.First_Nonterminal .. LR1_Descriptor.Last_Nonterminal =>
-           (LR1_Descriptor.First_Terminal .. LR1_Descriptor.Last_Terminal => 
False));
-   begin
-      for I in Item'Range (1) loop
-         for J in Item'Range (2) loop
-            Result (+I, +J) := Item (I, J);
-         end loop;
-      end loop;
-      return Result;
-   end To_Nonterminal_Array_Terminal_Set;
-
-   function "+" (Item : in Token_Array) return WisiToken.Token_ID_Set
-   is
-      Result : Token_ID_Set := (LR1_Descriptor.First_Terminal .. 
LR1_Descriptor.Last_Terminal => False);
-   begin
-      for I in Item'Range loop
-         Result (+Item (I)) := True;
-      end loop;
-      return Result;
-   end "+";
-
-   function "+" (Item : in Token_Enum_ID) return WisiToken.Token_ID_Set
-   is begin
-      return +Token_Array'(1 => Item);
-   end "+";
-
-begin
-   LR1_Descriptor.Image := Token_Enum_Image;
-   LALR_Descriptor.Image := LR1_Descriptor.Image;
-end WisiToken.Gen_Token_Enum;
diff --git a/packages/wisi/wisitoken-gen_token_enum.ads 
b/packages/wisi/wisitoken-gen_token_enum.ads
deleted file mode 100644
index 05bdb99..0000000
--- a/packages/wisi/wisitoken-gen_token_enum.ads
+++ /dev/null
@@ -1,122 +0,0 @@
---  Abstract :
---
---  Support for an enumerated token type
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (GPL);
-
-with WisiToken.Lexer.Regexp;
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-generic
-   type Token_Enum_ID is (<>);
-   First_Terminal    : Token_Enum_ID;
-   Last_Terminal     : Token_Enum_ID;
-   First_Nonterminal : Token_Enum_ID;
-   Last_Nonterminal  : Token_Enum_ID;
-   EOF_ID            : Token_Enum_ID;
-   Accept_ID         : Token_Enum_ID;
-   Case_Insensitive  : Boolean;
-package WisiToken.Gen_Token_Enum is
-
-   function "+" (Item : in Token_Enum_ID) return Token_ID
-     is (Token_ID'First + Token_Enum_ID'Pos (Item));
-
-   function "-" (Item : in Token_ID) return Token_Enum_ID
-     is (Token_Enum_ID'Val (Item - Token_ID'First));
-
-   function Token_Enum_Image return Token_ID_Array_String;
-
-   subtype Terminal_Enum_ID is Token_Enum_ID range First_Terminal .. 
Last_Terminal;
-   subtype Nonterminal_Enum_ID is Token_Enum_ID range First_Nonterminal .. 
Last_Nonterminal;
-
-   LR1_Descriptor : aliased WisiToken.Descriptor :=
-     (First_Terminal       => +First_Terminal,
-      Last_Terminal        => +Last_Terminal,
-      First_Nonterminal    => +First_Nonterminal,
-      Last_Nonterminal     => +Last_Nonterminal,
-      EOI_ID               => +EOF_ID,
-      Accept_ID            => +Accept_ID,
-      Case_Insensitive     => Case_Insensitive,
-      New_Line_ID          => Invalid_Token_ID,
-      String_1_ID          => Invalid_Token_ID,
-      String_2_ID          => Invalid_Token_ID,
-      Image                => (others => null), --  set in body elaboration 
time code
-      Terminal_Image_Width => Terminal_Enum_ID'Width,
-      Image_Width          => Token_Enum_ID'Width,
-      Last_Lookahead       => +Last_Terminal);
-
-   LALR_Descriptor : aliased WisiToken.Descriptor :=
-     (First_Terminal       => +First_Terminal,
-      Last_Terminal        => +Last_Terminal,
-      First_Nonterminal    => +First_Nonterminal,
-      Last_Nonterminal     => +Last_Nonterminal,
-      EOI_ID               => +EOF_ID,
-      Accept_ID            => +Accept_ID,
-      Case_Insensitive     => Case_Insensitive,
-      New_Line_ID          => Invalid_Token_ID,
-      String_1_ID          => Invalid_Token_ID,
-      String_2_ID          => Invalid_Token_ID,
-      Image                => (others => null),
-      Terminal_Image_Width => Terminal_Enum_ID'Width,
-      Image_Width          => Token_Enum_ID'Width,
-      Last_Lookahead       => +First_Nonterminal);
-
-   type Enum_Syntax is array (Token_Enum_ID range Token_Enum_ID'First .. 
Last_Terminal) of
-     WisiToken.Lexer.Regexp.Syntax_Item;
-
-   function To_Syntax (Item : in Enum_Syntax) return 
WisiToken.Lexer.Regexp.Syntax;
-
-   function "&" (Left, Right : in Token_Enum_ID) return Token_ID_Arrays.Vector;
-
-   function "&"
-     (Left  : in Token_ID_Arrays.Vector;
-      Right : in Token_Enum_ID)
-     return Token_ID_Arrays.Vector;
-
-   function "+" (Left : in Token_Enum_ID; Right : in 
Syntax_Trees.Semantic_Action) return Productions.Right_Hand_Side;
-
-   function "<="
-     (Left  : in Token_Enum_ID;
-      Right : in WisiToken.Productions.Right_Hand_Side)
-     return WisiToken.Productions.Instance;
-
-   ----------
-   --  For unit tests
-
-   subtype Terminal_ID is Token_Enum_ID range First_Terminal .. Last_Terminal;
-   subtype Nonterminal_ID is Token_Enum_ID range First_Nonterminal .. 
Last_Nonterminal;
-   subtype Grammar_ID is Token_Enum_ID range First_Terminal .. 
Last_Nonterminal;
-
-   type Nonterminal_Array_Token_Set is array (Nonterminal_ID, Grammar_ID) of 
Boolean;
-
-   function To_Nonterminal_Array_Token_Set
-     (Item : in Nonterminal_Array_Token_Set)
-     return WisiToken.Token_Array_Token_Set;
-
-   type Nonterminal_Array_Terminal_Set is array (Nonterminal_ID, Terminal_ID) 
of Boolean;
-
-   function To_Nonterminal_Array_Terminal_Set
-     (Item : in Nonterminal_Array_Terminal_Set)
-     return WisiToken.Token_Array_Token_Set;
-
-   type Nonterminal_ID_Set is array (Nonterminal_ID) of Boolean;
-
-   type Token_Array is array (Positive range <>) of Token_Enum_ID;
-
-   function "+" (Item : in Token_Array) return WisiToken.Token_ID_Set;
-   function "+" (Item : in Token_Enum_ID) return WisiToken.Token_ID_Set;
-
-end WisiToken.Gen_Token_Enum;
diff --git a/packages/wisi/wisitoken-generate-lr-lalr_generate.adb 
b/packages/wisi/wisitoken-generate-lr-lalr_generate.adb
deleted file mode 100644
index e544078..0000000
--- a/packages/wisi/wisitoken-generate-lr-lalr_generate.adb
+++ /dev/null
@@ -1,611 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Text_IO;
-with SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
-package body WisiToken.Generate.LR.LALR_Generate is
-
-   type Item_ID is record
-      State : Unknown_State_Index                   := Unknown_State;
-      LHS   : Token_ID                              := Invalid_Token_ID;
-      RHS   : Productions.RHS_Arrays.Extended_Index := 
Productions.RHS_Arrays.No_Index;
-      Dot   : Token_ID_Arrays.Extended_Index        := 
Token_ID_Arrays.No_Index;
-   end record;
-
-   function Image (Item : in Item_ID) return String
-     is ("(" & Item.State'Image & ", " & Trimmed_Image ((Item.LHS, Item.RHS)) 
& ")");
-
-   function Compare (Left, Right : in Item_ID) return SAL.Compare_Result
-     is (if Left.State < Right.State then SAL.Less
-         elsif Left.State > Right.State then SAL.Greater
-         elsif Left.LHS < Right.LHS then SAL.Less
-         elsif Left.LHS > Right.LHS then SAL.Greater
-         elsif Left.RHS < Right.RHS then SAL.Less
-         elsif Left.RHS > Right.RHS then SAL.Greater
-         elsif Left.Dot < Right.Dot then SAL.Less
-         elsif Left.Dot > Right.Dot then SAL.Greater
-         else SAL.Equal);
-
-   package Item_ID_Lists is new SAL.Gen_Definite_Doubly_Linked_Lists_Sorted 
(Item_ID, Compare);
-
-   type Item_Map is record
-      From : Item_ID;
-      To   : Item_ID_Lists.List;
-   end record;
-
-   function Compare (Left, Right : in Item_Map) return SAL.Compare_Result
-     is (Compare (Left.From, Right.From));
-
-   package Propagation_Lists is new 
SAL.Gen_Definite_Doubly_Linked_Lists_Sorted (Item_Map, Compare);
-
-   function Item_Ref
-     (Kernels : in out LR1_Items.Item_Set_List;
-      ID      : in     Item_ID)
-     return LR1_Items.Item_Lists.Variable_Reference_Type
-     is (LR1_Items.Item_Lists.Variable_Ref
-           (LR1_Items.Find (Prod => (ID.LHS, ID.RHS), Dot => ID.Dot, Set => 
Kernels (ID.State))));
-
-   function Propagate_Lookahead (Descriptor : in WisiToken.Descriptor) return 
Token_ID_Set_Access
-   is begin
-      return new Token_ID_Set'(LR1_Items.To_Lookahead 
(Descriptor.Last_Lookahead, Descriptor));
-   end Propagate_Lookahead;
-
-   function Null_Lookahead (Descriptor : in WisiToken.Descriptor) return 
Token_ID_Set_Access
-   is begin
-      return new Token_ID_Set'(Descriptor.First_Terminal .. 
Descriptor.Last_Lookahead => False);
-   end Null_Lookahead;
-
-   ----------
-   --  Debug output
-
-   procedure Put (Propagations : in Propagation_Lists.List)
-   is
-      use Item_ID_Lists;
-   begin
-      for Map of Propagations loop
-         Ada.Text_IO.Put_Line ("From " & Image (Map.From));
-
-         for ID of Map.To loop
-            Ada.Text_IO.Put_Line ("To   " & Image (ID));
-         end loop;
-      end loop;
-   end Put;
-
-   ----------
-   --  Generate utils
-
-   function LALR_Goto_Transitions
-     (Kernel            : in LR1_Items.Item_Set;
-      Symbol            : in Token_ID;
-      First_Nonterm_Set : in Token_Array_Token_Set;
-      Grammar           : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor        : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set
-   is
-      use Token_ID_Arrays;
-      use LR1_Items;
-      use LR1_Items.Item_Lists;
-
-      Goto_Set : Item_Set;
-   begin
-      for Item of Kernel.Set loop
-
-         if Item.Dot /= No_Index then
-
-            declare
-               Dot      : constant Token_ID_Arrays.Cursor := 
Productions.Constant_Ref_RHS
-                 (Grammar, Item.Prod).Tokens.To_Cursor (Item.Dot);
-               Dot_ID   : constant Token_ID               := Element (Dot);
-               Next_Dot : constant Token_ID_Arrays.Cursor := Next (Dot);
-            begin
-               --  If Symbol = EOF_Token, this is the start symbol accept
-               --  production; don't need a kernel with dot after EOF.
-
-               if (Dot_ID = Symbol and Symbol /= Descriptor.EOI_ID) and then
-                 not Has_Element (Find (Item, Goto_Set))
-               then
-                  Goto_Set.Set.Insert
-                    ((Prod       => Item.Prod,
-                      Dot        => To_Index (Next_Dot),
-                      Lookaheads => new Token_ID_Set'(Item.Lookaheads.all)));
-
-                  if Trace_Generate_Table > Detail then
-                     Ada.Text_IO.Put_Line ("LALR_Goto_Transitions 1 " & Image 
(Symbol, Descriptor));
-                     Put (Grammar, Descriptor, Goto_Set);
-                  end if;
-               end if;
-
-               if Dot_ID in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal and then
-                 First_Nonterm_Set (Dot_ID, Symbol)
-               then
-                  --  Find the production(s) that create Dot_ID with first 
token Symbol
-                  --  and put them in.
-                  for Prod of Grammar loop
-                     for RHS_2_I in Prod.RHSs.First_Index .. 
Prod.RHSs.Last_Index loop
-                        declare
-                           P_ID       : constant Production_ID          := 
(Prod.LHS, RHS_2_I);
-                           Tokens     : Token_ID_Arrays.Vector renames 
Prod.RHSs (RHS_2_I).Tokens;
-                           Dot_2      : constant Token_ID_Arrays.Cursor := 
Tokens.First;
-                           Next_Dot_2 : constant Token_ID_Arrays.Cursor := 
Next (Dot_2);
-                        begin
-                           if (Dot_ID = Prod.LHS or First_Nonterm_Set (Dot_ID, 
Prod.LHS)) and
-                             (Has_Element (Dot_2) and then Element (Dot_2) = 
Symbol)
-                           then
-                              if not Has_Element (Find (P_ID, To_Index 
(Next_Dot_2), Goto_Set)) then
-                                 Goto_Set.Set.Insert
-                                   ((Prod       => P_ID,
-                                     Dot        => To_Index (Next_Dot_2),
-                                     Lookaheads => Null_Lookahead 
(Descriptor)));
-
-                                 --  else already in goto set
-                              end if;
-                           end if;
-                        end;
-                     end loop;
-                  end loop;
-                  if Trace_Generate_Table > Detail then
-                     Ada.Text_IO.Put_Line ("LALR_Goto_Transitions 2 " & Image 
(Symbol, Descriptor));
-                     Put (Grammar, Descriptor, Goto_Set);
-                  end if;
-               end if;
-            end;
-         end if; -- item.dot /= null
-      end loop;
-
-      return Goto_Set;
-   end LALR_Goto_Transitions;
-
-   function LALR_Kernels
-     (Grammar           : in WisiToken.Productions.Prod_Arrays.Vector;
-      First_Nonterm_Set : in Token_Array_Token_Set;
-      Descriptor        : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set_List
-   is
-      use all type Ada.Containers.Count_Type;
-      use LR1_Items;
-
-      First_State_Index : constant State_Index := 0;
-      Kernels           : LR1_Items.Item_Set_List;
-      Kernel_Tree       : LR1_Items.Item_Set_Trees.Tree; -- for fast find
-      States_To_Check   : State_Index_Queues.Queue;
-      Checking_State    : State_Index;
-   begin
-      Kernels.Set_First_Last (First_State_Index, First_State_Index - 1);
-
-      Add (Grammar,
-           (Set               => Item_Lists.To_List
-              ((Prod          => (Grammar.First_Index, 0),
-                Dot           => Grammar (Grammar.First_Index).RHSs 
(0).Tokens.First_Index,
-                Lookaheads    => Null_Lookahead (Descriptor))),
-            Goto_List         => <>,
-            Dot_IDs           => <>,
-            State             => First_State_Index),
-           Kernels,
-           Kernel_Tree,
-           Descriptor,
-           Include_Lookaheads => False);
-
-      States_To_Check.Put (First_State_Index);
-      loop
-         exit when States_To_Check.Is_Empty;
-         Checking_State := States_To_Check.Get;
-
-         if Trace_Generate_Table > Detail then
-            Ada.Text_IO.Put ("Checking ");
-            Put (Grammar, Descriptor, Kernels (Checking_State));
-         end if;
-
-         for Symbol in Descriptor.First_Terminal .. 
Descriptor.Last_Nonterminal loop
-            --  LALR_Goto_Transitions does _not_ ignore Symbol if it is not in
-            --  Item_Set.Dot_IDs, so we can't iterate on that here as we do in
-            --  LR1_Generate.
-
-            declare
-               New_Item_Set : Item_Set := LALR_Goto_Transitions
-                 (Kernels (Checking_State), Symbol, First_Nonterm_Set, 
Grammar, Descriptor);
-               Found_State : Unknown_State_Index;
-            begin
-               if New_Item_Set.Set.Length > 0 then
-
-                  Found_State := Find (New_Item_Set, Kernel_Tree, 
Match_Lookaheads => False);
-
-                  if Found_State = Unknown_State then
-                     New_Item_Set.State := Kernels.Last_Index + 1;
-
-                     States_To_Check.Put (New_Item_Set.State);
-
-                     Add (Grammar, New_Item_Set, Kernels, Kernel_Tree, 
Descriptor, Include_Lookaheads => False);
-
-                     if Trace_Generate_Table > Detail then
-                        Ada.Text_IO.Put_Line ("  adding state" & 
Unknown_State_Index'Image (Kernels.Last_Index));
-
-                        Ada.Text_IO.Put_Line
-                          ("  state" & Unknown_State_Index'Image 
(Checking_State) &
-                             " adding goto on " & Image (Symbol, Descriptor) & 
" to state" &
-                             Unknown_State_Index'Image (Kernels.Last_Index));
-                     end if;
-
-                     Kernels (Checking_State).Goto_List.Insert ((Symbol, 
Kernels.Last_Index));
-                  else
-
-                     --  If there's not already a goto entry between these two 
sets, create one.
-                     if not Is_In ((Symbol, Found_State), Kernels 
(Checking_State).Goto_List) then
-                        if Trace_Generate_Table > Detail then
-                           Ada.Text_IO.Put_Line
-                             ("  state" & Unknown_State_Index'Image 
(Checking_State) &
-                                " adding goto on " & Image (Symbol, 
Descriptor) & " to state" &
-                                Unknown_State_Index'Image (Found_State));
-
-                        end if;
-
-                        Kernels (Checking_State).Goto_List.Insert ((Symbol, 
Found_State));
-                     end if;
-                  end if;
-               end if;
-            end;
-         end loop;
-      end loop;
-
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.New_Line;
-      end if;
-
-      return Kernels;
-   end LALR_Kernels;
-
-   --  Add a propagation entry (if it doesn't already exist) from From in
-   --  From_Set to To_Item.
-   procedure Add_Propagation
-     (From_Item    : in     LR1_Items.Item;
-      From_State   : in     State_Index;
-      To_Item      : in     LR1_Items.Item_Lists.Cursor;
-      To_State     : in     State_Index;
-      Propagations : in out Propagation_Lists.List)
-   is
-      use Propagation_Lists;
-      use LR1_Items;
-      use LR1_Items.Item_Lists;
-      use Item_ID_Lists;
-
-      To_Item_Ref : constant LR1_Items.Item_Lists.Constant_Reference_Type := 
Constant_Ref (To_Item);
-
-      From_ID : constant Item_ID := (From_State, From_Item.Prod.LHS, 
From_Item.Prod.RHS, From_Item.Dot);
-      To_ID   : constant Item_ID := (To_State, To_Item_Ref.Prod.LHS, 
To_Item_Ref.Prod.RHS, To_Item_Ref.Dot);
-
-      From_Match : constant Propagation_Lists.Cursor := Propagations.Find 
((From_ID, Item_ID_Lists.Empty_List));
-   begin
-      if not Has_Element (From_Match) then
-         Propagations.Insert ((From_ID, To_List (To_ID)));
-
-      else
-         declare
-            To_Match : constant Item_ID_Lists.Cursor := Constant_Ref 
(From_Match).To.Find (To_ID);
-         begin
-            if not Has_Element (To_Match) then
-               Variable_Ref (From_Match).To.Insert (To_ID);
-            end if;
-         end;
-      end if;
-   end Add_Propagation;
-
-   --  Calculate the lookaheads from Closure_Item for Source_Item.
-   --  Source_Item must be one of the kernel items in Source_Set.
-   --  Closure_Item must be an item in the lookahead closure of Source_Item 
for #.
-   --
-   --  Spontaneous lookaheads are put in Source_Item.Lookahead,
-   --  propagated lookaheads in Propagations.
-   --
-   --  Set Used_Tokens = True for all tokens in lookaheads.
-   procedure Generate_Lookahead_Info
-     (Source_Item  : in     LR1_Items.Item;
-      Source_Set   : in     LR1_Items.Item_Set;
-      Closure_Item : in     LR1_Items.Item;
-      Propagations : in out Propagation_Lists.List;
-      Descriptor   : in     WisiToken.Descriptor;
-      Grammar      : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Kernels      : in out LR1_Items.Item_Set_List)
-   is
-      use LR1_Items;
-      use LR1_Items.Item_Lists;
-      use Token_ID_Arrays;
-
-      Spontaneous_Count : Integer := 0;
-   begin
-      if Trace_Generate_Table > Outline then
-         Ada.Text_IO.Put_Line ("  closure_item: ");
-         LR1_Items.Put (Grammar, Descriptor, Closure_Item);
-         Ada.Text_IO.New_Line;
-      end if;
-
-      if Closure_Item.Dot = No_Index then
-         return;
-      end if;
-
-      declare
-         Dot        : constant Token_ID_Arrays.Cursor := 
Productions.Constant_Ref_RHS
-           (Grammar, Closure_Item.Prod).Tokens.To_Cursor (Closure_Item.Dot);
-         ID         : constant Token_ID               := Element (Dot);
-         Next_Dot   : constant Token_ID_Arrays.Cursor := Next (Dot);
-         Goto_State : constant Unknown_State_Index    := LR1_Items.Goto_State 
(Source_Set, ID);
-      begin
-         if Goto_State /= Unknown_State then
-            declare
-               To_Item : constant Item_Lists.Cursor :=
-                 LR1_Items.Find (Closure_Item.Prod, To_Index (Next_Dot), 
Kernels (Goto_State));
-            begin
-               if Closure_Item.Lookaheads (Descriptor.Last_Lookahead) then
-                  Add_Propagation
-                    (From_Item    => Source_Item,
-                     From_State   => Source_Set.State,
-                     To_Item      => To_Item,
-                     To_State     => Goto_State,
-                     Propagations => Propagations);
-               end if;
-
-               if Trace_Generate_Table > Outline then
-                  Spontaneous_Count := Spontaneous_Count + 1;
-                  Ada.Text_IO.Put_Line ("  spontaneous: " & Lookahead_Image 
(Closure_Item.Lookaheads.all, Descriptor));
-               end if;
-
-               LR1_Items.Include (Variable_Ref (To_Item), 
Closure_Item.Lookaheads.all, Descriptor);
-            end;
-         end if;
-      end;
-   end Generate_Lookahead_Info;
-
-   procedure Propagate_Lookaheads
-     (Propagations : in     Propagation_Lists.List;
-      Kernels      : in out LR1_Items.Item_Set_List;
-      Descriptor   : in     WisiToken.Descriptor)
-   is
-      --  In Propagations, update all To lookaheads from From lookaheads,
-      --  recursively.
-      More_To_Check : Boolean := True;
-      Added_One     : Boolean;
-   begin
-      while More_To_Check loop
-
-         More_To_Check := False;
-         for Map of Propagations loop
-            for ID of Map.To loop
-               LR1_Items.Include
-                 (Item_Ref (Kernels, ID), Item_Ref (Kernels, 
Map.From).Lookaheads.all, Added_One, Descriptor);
-
-               More_To_Check := More_To_Check or Added_One;
-            end loop;
-         end loop;
-      end loop;
-   end Propagate_Lookaheads;
-
-   --  Calculate the LALR(1) lookaheads for Grammar.
-   --  Kernels should be the sets of LR(0) kernels on input, and will
-   --  become the set of LALR(1) kernels on output.
-   procedure Fill_In_Lookaheads
-     (Grammar                 : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production    : in     Token_ID_Set;
-      First_Terminal_Sequence : in     Token_Sequence_Arrays.Vector;
-      Kernels                 : in out LR1_Items.Item_Set_List;
-      Descriptor              : in     WisiToken.Descriptor)
-   is
-      Closure : LR1_Items.Item_Set;
-      Propagations : Propagation_Lists.List;
-   begin
-      for Kernel of Kernels loop
-         if Trace_Generate_Table > Outline then
-            Ada.Text_IO.Put ("Adding lookaheads for ");
-            LR1_Items.Put (Grammar, Descriptor, Kernel);
-         end if;
-
-         for Kernel_Item of Kernel.Set loop
-            Closure := LR1_Items.Closure
-              ((Set            => LR1_Items.Item_Lists.To_List
-                  ((Prod       => Kernel_Item.Prod,
-                    Dot        => Kernel_Item.Dot,
-                    Lookaheads => Propagate_Lookahead (Descriptor))),
-                Goto_List      => <>,
-                Dot_IDs        => <>,
-                State          => <>),
-               Has_Empty_Production, First_Terminal_Sequence, Grammar, 
Descriptor);
-
-            for Closure_Item of Closure.Set loop
-               Generate_Lookahead_Info
-                 (Kernel_Item, Kernel, Closure_Item, Propagations, Descriptor, 
Grammar, Kernels);
-            end loop;
-         end loop;
-      end loop;
-
-      if Trace_Generate_Table > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("Propagations:");
-         Put (Propagations);
-         Ada.Text_IO.New_Line;
-      end if;
-
-      Propagate_Lookaheads (Propagations, Kernels, Descriptor);
-   end Fill_In_Lookaheads;
-
-   --  Add actions for all Kernels to Table.
-   procedure Add_Actions
-     (Kernels                 : in     LR1_Items.Item_Set_List;
-      Grammar                 : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production    : in     Token_ID_Set;
-      First_Nonterm_Set       : in     Token_Array_Token_Set;
-      First_Terminal_Sequence : in     Token_Sequence_Arrays.Vector;
-      Conflict_Counts         :    out Conflict_Count_Lists.List;
-      Conflicts               :    out Conflict_Lists.List;
-      Table                   : in out Parse_Table;
-      Descriptor              : in     WisiToken.Descriptor)
-   is
-      Closure : LR1_Items.Item_Set;
-   begin
-      for Kernel of Kernels loop
-         --  IMPROVEME: there are three "closure" computations that could
-         --  probably be refactored to save computation; in
-         --  LALR_Goto_Transitions, Fill_In_Lookaheads, and here.
-         Closure := LR1_Items.Closure (Kernel, Has_Empty_Production, 
First_Terminal_Sequence, Grammar, Descriptor);
-
-         Add_Actions
-           (Closure, Table, Grammar, Has_Empty_Production, First_Nonterm_Set,
-            Conflict_Counts, Conflicts, Descriptor);
-      end loop;
-
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.New_Line;
-      end if;
-   end Add_Actions;
-
-   function Generate
-     (Grammar               : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor            : in     WisiToken.Descriptor;
-      Known_Conflicts       : in     Conflict_Lists.List := 
Conflict_Lists.Empty_List;
-      McKenzie_Param        : in     McKenzie_Param_Type := 
Default_McKenzie_Param;
-      Parse_Table_File_Name : in     String              := "";
-      Include_Extra         : in     Boolean             := False;
-      Ignore_Conflicts      : in     Boolean             := False;
-      Partial_Recursion     : in     Boolean             := True)
-     return Parse_Table_Ptr
-   is
-      use all type Ada.Containers.Count_Type;
-
-      Ignore_Unused_Tokens     : constant Boolean := 
WisiToken.Trace_Generate_Table > Detail;
-      Ignore_Unknown_Conflicts : constant Boolean := Ignore_Conflicts or 
WisiToken.Trace_Generate_Table > Detail;
-      Unused_Tokens            : constant Boolean := 
WisiToken.Generate.Check_Unused_Tokens (Descriptor, Grammar);
-
-      Table : Parse_Table_Ptr;
-
-      Nullable : constant Token_Array_Production_ID := 
WisiToken.Generate.Nullable (Grammar);
-      Has_Empty_Production : constant Token_ID_Set := 
WisiToken.Generate.Has_Empty_Production (Nullable);
-
-      Recursions : constant WisiToken.Generate.Recursions :=
-        (if Partial_Recursion
-         then WisiToken.Generate.Compute_Partial_Recursion (Grammar, 
Descriptor)
-         else WisiToken.Generate.Compute_Full_Recursion (Grammar, Descriptor));
-      Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
-        Compute_Minimal_Terminal_Sequences (Descriptor, Grammar);
-
-      Minimal_Terminal_First : constant Token_Array_Token_ID :=
-        Compute_Minimal_Terminal_First (Descriptor, 
Minimal_Terminal_Sequences);
-
-      First_Nonterm_Set : constant Token_Array_Token_Set := 
WisiToken.Generate.First
-        (Grammar, Has_Empty_Production, Descriptor.First_Terminal);
-
-      First_Terminal_Sequence : constant Token_Sequence_Arrays.Vector :=
-        WisiToken.Generate.To_Terminal_Sequence_Array (First_Nonterm_Set, 
Descriptor);
-
-      Kernels : LR1_Items.Item_Set_List := LALR_Kernels (Grammar, 
First_Nonterm_Set, Descriptor);
-
-      Conflict_Counts      : Conflict_Count_Lists.List;
-      Unknown_Conflicts    : Conflict_Lists.List;
-      Known_Conflicts_Edit : Conflict_Lists.List := Known_Conflicts;
-
-   begin
-      WisiToken.Generate.Error := False; -- necessary in unit tests; some 
previous test might have encountered an error.
-
-      if Trace_Generate_Table + Trace_Generate_Minimal_Complete > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("LALR_Generate");
-      end if;
-
-      Fill_In_Lookaheads (Grammar, Has_Empty_Production, 
First_Terminal_Sequence, Kernels, Descriptor);
-
-      if Unused_Tokens then
-         WisiToken.Generate.Error := not Ignore_Unused_Tokens;
-         Ada.Text_IO.New_Line;
-      end if;
-
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("LR(1) Kernels:");
-         LR1_Items.Put (Grammar, Descriptor, Kernels, Show_Lookaheads => True);
-      end if;
-
-      Table := new Parse_Table
-        (State_First       => Kernels.First_Index,
-         State_Last        => Kernels.Last_Index,
-         First_Terminal    => Descriptor.First_Terminal,
-         Last_Terminal     => Descriptor.Last_Terminal,
-         First_Nonterminal => Descriptor.First_Nonterminal,
-         Last_Nonterminal  => Descriptor.Last_Nonterminal);
-
-      if McKenzie_Param = Default_McKenzie_Param then
-         --  Descriminants in Default are wrong
-         Table.McKenzie_Param :=
-           (First_Terminal              => Descriptor.First_Terminal,
-            Last_Terminal               => Descriptor.Last_Terminal,
-            First_Nonterminal           => Descriptor.First_Nonterminal,
-            Last_Nonterminal            => Descriptor.Last_Nonterminal,
-            Insert                      => (others => 0),
-            Delete                      => (others => 0),
-            Push_Back                   => (others => 0),
-            Undo_Reduce                 => (others => 0),
-            Minimal_Complete_Cost_Delta => 
Default_McKenzie_Param.Minimal_Complete_Cost_Delta,
-            Fast_Forward                => Default_McKenzie_Param.Fast_Forward,
-            Matching_Begin              => 
Default_McKenzie_Param.Matching_Begin,
-            Ignore_Check_Fail           => 
Default_McKenzie_Param.Ignore_Check_Fail,
-            Task_Count                  => Default_McKenzie_Param.Task_Count,
-            Check_Limit                 => Default_McKenzie_Param.Check_Limit,
-            Check_Delta_Limit           => 
Default_McKenzie_Param.Check_Delta_Limit,
-            Enqueue_Limit               => 
Default_McKenzie_Param.Enqueue_Limit);
-      else
-         Table.McKenzie_Param := McKenzie_Param;
-      end if;
-
-      Add_Actions
-        (Kernels, Grammar, Has_Empty_Production, First_Nonterm_Set, 
First_Terminal_Sequence, Conflict_Counts,
-         Unknown_Conflicts, Table.all, Descriptor);
-
-      for State in Table.States'Range loop
-         if Trace_Generate_Minimal_Complete > Extra then
-            Ada.Text_IO.Put_Line ("Set_Minimal_Complete_Actions:" & 
State_Index'Image (State));
-         end if;
-         WisiToken.Generate.LR.Set_Minimal_Complete_Actions
-           (Table.States (State), Kernels (State), Descriptor, Grammar, 
Nullable, Minimal_Terminal_Sequences,
-            Minimal_Terminal_First);
-      end loop;
-
-      if Parse_Table_File_Name /= "" then
-         WisiToken.Generate.LR.Put_Parse_Table
-           (Table, Parse_Table_File_Name, "LALR", Grammar, Recursions, 
Kernels, Conflict_Counts, Descriptor,
-            Include_Extra);
-      end if;
-
-      Delete_Known (Unknown_Conflicts, Known_Conflicts_Edit);
-
-      if Unknown_Conflicts.Length > 0 then
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Current_Error, "unknown 
conflicts:");
-         Put (Unknown_Conflicts, Ada.Text_IO.Current_Error, Descriptor);
-         Ada.Text_IO.New_Line (Ada.Text_IO.Current_Error);
-         WisiToken.Generate.Error := WisiToken.Generate.Error or not 
Ignore_Unknown_Conflicts;
-      end if;
-
-      if Known_Conflicts_Edit.Length > 0 then
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Current_Error, "excess known 
conflicts:");
-         Put (Known_Conflicts_Edit, Ada.Text_IO.Current_Error, Descriptor);
-         Ada.Text_IO.New_Line (Ada.Text_IO.Current_Error);
-         WisiToken.Generate.Error := WisiToken.Generate.Error or not 
Ignore_Unknown_Conflicts;
-      end if;
-
-      return Table;
-   end Generate;
-
-end WisiToken.Generate.LR.LALR_Generate;
diff --git a/packages/wisi/wisitoken-generate-lr-lalr_generate.ads 
b/packages/wisi/wisitoken-generate-lr-lalr_generate.ads
deleted file mode 100644
index 7527a9c..0000000
--- a/packages/wisi/wisitoken-generate-lr-lalr_generate.ads
+++ /dev/null
@@ -1,87 +0,0 @@
---  Abstract :
---
---  Generalized LALR parse table generator.
---
---  Copyright (C) 2002 - 2003, 2009 - 2010, 2013 - 2015, 2017 - 2020 Free 
Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Generate.LR1_Items;
-with WisiToken.Productions;
-package WisiToken.Generate.LR.LALR_Generate is
-
-   function Generate
-     (Grammar               : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor            : in     WisiToken.Descriptor;
-      Known_Conflicts       : in     Conflict_Lists.List := 
Conflict_Lists.Empty_List;
-      McKenzie_Param        : in     McKenzie_Param_Type := 
Default_McKenzie_Param;
-      Parse_Table_File_Name : in     String              := "";
-      Include_Extra         : in     Boolean             := False;
-      Ignore_Conflicts      : in     Boolean             := False;
-      Partial_Recursion     : in     Boolean             := True)
-     return Parse_Table_Ptr
-   with Pre =>
-     Descriptor.Last_Lookahead = Descriptor.First_Nonterminal and
-     Descriptor.First_Nonterminal = Descriptor.Accept_ID;
-   --  Generate a generalized LALR parse table for Grammar. The
-   --  grammar start symbol is the LHS of the first production in
-   --  Grammar.
-   --
-   --  Unless Ignore_Unused_Tokens is True, raise Grammar_Error if
-   --  there are unused tokens.
-   --
-   --  Unless Ignore_Unknown_Conflicts is True, raise Grammar_Error if there
-   --  are unknown conflicts.
-
-   ----------
-   --  Visible for unit tests
-
-   function LALR_Goto_Transitions
-     (Kernel            : in LR1_Items.Item_Set;
-      Symbol            : in Token_ID;
-      First_Nonterm_Set : in Token_Array_Token_Set;
-      Grammar           : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor        : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set;
-   --  Return the Item_Set that is the goto for Symbol from Kernel.
-   --  If there is no such Item_Set, Result.Set is null.
-
-   function LALR_Kernels
-     (Grammar           : in WisiToken.Productions.Prod_Arrays.Vector;
-      First_Nonterm_Set : in Token_Array_Token_Set;
-      Descriptor        : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set_List;
-
-   procedure Fill_In_Lookaheads
-     (Grammar                 : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production    : in     Token_ID_Set;
-      First_Terminal_Sequence : in     Token_Sequence_Arrays.Vector;
-      Kernels                 : in out LR1_Items.Item_Set_List;
-      Descriptor              : in     WisiToken.Descriptor);
-
-   procedure Add_Actions
-     (Kernels                 : in     LR1_Items.Item_Set_List;
-      Grammar                 : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production    : in     Token_ID_Set;
-      First_Nonterm_Set       : in     Token_Array_Token_Set;
-      First_Terminal_Sequence : in     Token_Sequence_Arrays.Vector;
-      Conflict_Counts         :    out Conflict_Count_Lists.List;
-      Conflicts               :    out Conflict_Lists.List;
-      Table                   : in out Parse_Table;
-      Descriptor              : in     WisiToken.Descriptor);
-
-end WisiToken.Generate.LR.LALR_Generate;
diff --git a/packages/wisi/wisitoken-generate-lr-lr1_generate.adb 
b/packages/wisi/wisitoken-generate-lr-lr1_generate.adb
deleted file mode 100644
index 8f688c9..0000000
--- a/packages/wisi/wisitoken-generate-lr-lr1_generate.adb
+++ /dev/null
@@ -1,343 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Text_IO;
-with WisiToken.Generate;
-package body WisiToken.Generate.LR.LR1_Generate is
-
-   function LR1_Goto_Transitions
-     (Set                     : in LR1_Items.Item_Set;
-      Symbol                  : in Token_ID;
-      Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set
-   is
-      use all type Ada.Containers.Count_Type;
-      use Token_ID_Arrays;
-      use LR1_Items;
-
-      Goto_Set : Item_Set;
-   begin
-      for Item of Set.Set loop
-         if Item.Dot /= No_Index then
-            declare
-               Dot : constant Token_ID_Arrays.Cursor := 
Productions.Constant_Ref_RHS
-                 (Grammar, Item.Prod).Tokens.To_Cursor (Item.Dot);
-            begin
-               if Element (Dot) = Symbol and
-                 --  We don't need a state with dot after EOI in the
-                 --  accept production. EOI should only appear in the
-                 --  accept production.
-                 Symbol /= Descriptor.EOI_ID
-               then
-                  Goto_Set.Set.Insert
-                    ((Item.Prod,
-                      To_Index (Next (Dot)),
-                      new Token_ID_Set'(Item.Lookaheads.all)));
-               end if;
-            end;
-         end if;
-      end loop;
-
-      if Goto_Set.Set.Length > 0 then
-         return Closure (Goto_Set, Has_Empty_Production, 
First_Terminal_Sequence, Grammar, Descriptor);
-      else
-         return Goto_Set;
-      end if;
-   end LR1_Goto_Transitions;
-
-   function LR1_Item_Sets
-     (Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set_List
-   is
-      use all type Ada.Containers.Count_Type;
-
-      --  [dragon] algorithm 4.9 pg 231; figure 4.38 pg 232; procedure
-      --  "items", with some optimizations.
-
-      use LR1_Items;
-
-      First_State_Index : constant State_Index := 0;
-
-      C               : LR1_Items.Item_Set_List;       -- result
-      C_Tree          : LR1_Items.Item_Set_Trees.Tree; -- for fast find
-      States_To_Check : State_Index_Queues.Queue;
-      --  [dragon] specifies 'until no more items can be added', but we use
-      --  a queue to avoid checking unecessary states. Ada LR1 has over
-      --  100,000 states, so this is a significant gain (reduced time from
-      --  600 seconds to 40).
-
-      I       : State_Index;
-      Dot_IDs : Token_ID_Arrays.Vector;
-
-      New_Item_Set : Item_Set := Closure
-        ((Set            => Item_Lists.To_List
-            ((Prod       => (Grammar.First_Index, 0),
-              Dot        => Grammar (Grammar.First_Index).RHSs 
(0).Tokens.First_Index,
-              Lookaheads => new Token_ID_Set'(To_Lookahead (Descriptor.EOI_ID, 
Descriptor)))),
-          Goto_List      => <>,
-          Dot_IDs        => <>,
-          State          => First_State_Index),
-        Has_Empty_Production, First_Terminal_Sequence, Grammar, Descriptor);
-
-      Found_State  : Unknown_State_Index;
-
-   begin
-      C.Set_First_Last (First_State_Index, First_State_Index - 1);
-
-      Add (Grammar, New_Item_Set, C, C_Tree, Descriptor, Include_Lookaheads => 
True);
-
-      States_To_Check.Put (First_State_Index);
-      loop
-         exit when States_To_Check.Is_Empty;
-         I := States_To_Check.Get;
-
-         if Trace_Generate_Table > Outline then
-            Ada.Text_IO.Put ("Checking ");
-            Put (Grammar, Descriptor, C (I), Show_Lookaheads => True, 
Show_Goto_List => True);
-         end if;
-
-         Dot_IDs := C (I).Dot_IDs;
-         --  We can't iterate on C (I).Dot_IDs when the loop adds items to C;
-         --  it might be reallocated to grow.
-
-         for Symbol of Dot_IDs loop
-            --  [dragon] has 'for each grammar symbol X', but 
LR1_Goto_Transitions
-            --  rejects Symbol that is not in Dot_IDs, so we iterate over that.
-
-            New_Item_Set := LR1_Goto_Transitions
-              (C (I), Symbol, Has_Empty_Production, First_Terminal_Sequence, 
Grammar, Descriptor);
-
-            if New_Item_Set.Set.Length > 0 then -- 'goto (I, X) not empty'
-
-               Found_State := Find (New_Item_Set, C_Tree, Match_Lookaheads => 
True); -- 'not in C'
-
-               if Found_State = Unknown_State then
-                  New_Item_Set.State := C.Last_Index + 1;
-
-                  States_To_Check.Put (New_Item_Set.State);
-
-                  Add (Grammar, New_Item_Set, C, C_Tree, Descriptor, 
Include_Lookaheads => True);
-
-                  if Trace_Generate_Table > Outline then
-                     Ada.Text_IO.Put_Line
-                       ("  adding state" & Unknown_State_Index'Image 
(C.Last_Index) & ": from state" &
-                          Unknown_State_Index'Image (I) & " on " & Image 
(Symbol, Descriptor));
-                     Put (Grammar, Descriptor, New_Item_Set, Show_Lookaheads 
=> True);
-                  end if;
-
-                  C (I).Goto_List.Insert ((Symbol, C.Last_Index));
-               else
-
-                  --  If there's not already a goto entry between these two 
sets, create one.
-                  if not Is_In ((Symbol, Found_State), Goto_List => C 
(I).Goto_List) then
-                     if Trace_Generate_Table > Outline then
-                        Ada.Text_IO.Put_Line
-                          ("  adding goto on " & Image (Symbol, Descriptor) & 
" to state" &
-                             Unknown_State_Index'Image (Found_State));
-
-                     end if;
-
-                     C (I).Goto_List.Insert ((Symbol, Found_State));
-                  end if;
-               end if;
-            end if;
-         end loop;
-      end loop;
-
-      if Trace_Generate_Table > Outline then
-         Ada.Text_IO.New_Line;
-      end if;
-
-      return C;
-   end LR1_Item_Sets;
-
-   procedure Add_Actions
-     (Item_Sets            : in     LR1_Items.Item_Set_List;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      :    out Conflict_Count_Lists.List;
-      Conflicts            :    out Conflict_Lists.List;
-      Table                : in out Parse_Table;
-      Descriptor           : in     WisiToken.Descriptor)
-   is
-      --  Add actions for all Item_Sets to Table.
-   begin
-      for Item_Set of Item_Sets loop
-         Add_Actions
-           (Item_Set, Table, Grammar, Has_Empty_Production, First_Nonterm_Set, 
Conflict_Counts, Conflicts, Descriptor);
-      end loop;
-
-      if Trace_Generate_Table > Outline then
-         Ada.Text_IO.New_Line;
-      end if;
-   end Add_Actions;
-
-   function Generate
-     (Grammar               : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor            : in     WisiToken.Descriptor;
-      Known_Conflicts       : in     Conflict_Lists.List := 
Conflict_Lists.Empty_List;
-      McKenzie_Param        : in     McKenzie_Param_Type := 
Default_McKenzie_Param;
-      Parse_Table_File_Name : in     String              := "";
-      Include_Extra         : in     Boolean             := False;
-      Ignore_Conflicts      : in     Boolean             := False;
-      Partial_Recursion     : in     Boolean             := True)
-     return Parse_Table_Ptr
-   is
-      use type Ada.Containers.Count_Type;
-
-      Ignore_Unused_Tokens     : constant Boolean := 
WisiToken.Trace_Generate_Table > Detail;
-      Ignore_Unknown_Conflicts : constant Boolean := Ignore_Conflicts or 
WisiToken.Trace_Generate_Table > Detail;
-      Unused_Tokens            : constant Boolean := 
WisiToken.Generate.Check_Unused_Tokens (Descriptor, Grammar);
-
-      Table : Parse_Table_Ptr;
-
-      Nullable : constant Token_Array_Production_ID := 
WisiToken.Generate.Nullable (Grammar);
-      Has_Empty_Production : constant Token_ID_Set := 
WisiToken.Generate.Has_Empty_Production (Nullable);
-
-      Recursions : constant WisiToken.Generate.Recursions :=
-        (if Partial_Recursion
-         then WisiToken.Generate.Compute_Partial_Recursion (Grammar, 
Descriptor)
-         else WisiToken.Generate.Compute_Full_Recursion (Grammar, Descriptor));
-      Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
-        Compute_Minimal_Terminal_Sequences (Descriptor, Grammar);
-
-      Minimal_Terminal_First : constant Token_Array_Token_ID :=
-        Compute_Minimal_Terminal_First (Descriptor, 
Minimal_Terminal_Sequences);
-
-      First_Nonterm_Set : constant Token_Array_Token_Set := 
WisiToken.Generate.First
-        (Grammar, Has_Empty_Production, Descriptor.First_Terminal);
-
-      First_Terminal_Sequence : constant Token_Sequence_Arrays.Vector :=
-        WisiToken.Generate.To_Terminal_Sequence_Array (First_Nonterm_Set, 
Descriptor);
-
-      Item_Sets : constant LR1_Items.Item_Set_List := LR1_Item_Sets
-        (Has_Empty_Production, First_Terminal_Sequence, Grammar, Descriptor);
-
-      Conflict_Counts      : Conflict_Count_Lists.List;
-      Unknown_Conflicts    : Conflict_Lists.List;
-      Known_Conflicts_Edit : Conflict_Lists.List := Known_Conflicts;
-   begin
-      if Trace_Generate_Table + Trace_Generate_Minimal_Complete > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("LR1_Generate:");
-         if Trace_Generate_Table > Outline then
-            Ada.Text_IO.Put_Line ("Item_Sets:");
-            LR1_Items.Put (Grammar, Descriptor, Item_Sets);
-         end if;
-      end if;
-
-      Table := new Parse_Table
-        (State_First       => Item_Sets.First_Index,
-         State_Last        => Item_Sets.Last_Index,
-         First_Terminal    => Descriptor.First_Terminal,
-         Last_Terminal     => Descriptor.Last_Terminal,
-         First_Nonterminal => Descriptor.First_Nonterminal,
-         Last_Nonterminal  => Descriptor.Last_Nonterminal);
-
-      if McKenzie_Param = Default_McKenzie_Param then
-         --  Descriminants in Default are wrong
-         Table.McKenzie_Param :=
-           (First_Terminal              => Descriptor.First_Terminal,
-            Last_Terminal               => Descriptor.Last_Terminal,
-            First_Nonterminal           => Descriptor.First_Nonterminal,
-            Last_Nonterminal            => Descriptor.Last_Nonterminal,
-            Insert                      => (others => 0),
-            Delete                      => (others => 0),
-            Push_Back                   => (others => 0),
-            Undo_Reduce                 => (others => 0),
-            Minimal_Complete_Cost_Delta => 
Default_McKenzie_Param.Minimal_Complete_Cost_Delta,
-            Fast_Forward                => Default_McKenzie_Param.Fast_Forward,
-            Matching_Begin              => 
Default_McKenzie_Param.Matching_Begin,
-            Ignore_Check_Fail           => 
Default_McKenzie_Param.Ignore_Check_Fail,
-            Task_Count                  => Default_McKenzie_Param.Task_Count,
-            Check_Limit                 => Default_McKenzie_Param.Check_Limit,
-            Check_Delta_Limit           => 
Default_McKenzie_Param.Check_Delta_Limit,
-            Enqueue_Limit               => 
Default_McKenzie_Param.Enqueue_Limit);
-      else
-         Table.McKenzie_Param := McKenzie_Param;
-      end if;
-
-      Add_Actions
-        (Item_Sets, Grammar, Has_Empty_Production, First_Nonterm_Set,
-         Conflict_Counts, Unknown_Conflicts, Table.all, Descriptor);
-
-      for State in Table.States'Range loop
-         if Trace_Generate_Minimal_Complete > Extra then
-            Ada.Text_IO.Put_Line ("Set_Minimal_Complete_Actions:" & 
State_Index'Image (State));
-         end if;
-         WisiToken.Generate.LR.Set_Minimal_Complete_Actions
-           (Table.States (State),
-            LR1_Items.Filter (Item_Sets (State), Grammar, Descriptor, 
LR1_Items.In_Kernel'Access),
-            Descriptor, Grammar, Nullable, Minimal_Terminal_Sequences, 
Minimal_Terminal_First);
-      end loop;
-
-      if Parse_Table_File_Name /= "" then
-         WisiToken.Generate.LR.Put_Parse_Table
-           (Table, Parse_Table_File_Name, "LR1", Grammar, Recursions, 
Item_Sets, Conflict_Counts, Descriptor,
-            Include_Extra);
-      end if;
-
-      if Trace_Generate_Table > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("Has_Empty_Production: " & Image 
(Has_Empty_Production, Descriptor));
-
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("Minimal_Terminal_First:");
-         for ID in Minimal_Terminal_First'Range loop
-            Ada.Text_IO.Put_Line
-              (Image (ID, Descriptor) & " =>" &
-                 (if Minimal_Terminal_First (ID) = Invalid_Token_ID
-                  then ""
-                  else ' ' & Image (Minimal_Terminal_First (ID), Descriptor)));
-         end loop;
-      end if;
-
-      Delete_Known (Unknown_Conflicts, Known_Conflicts_Edit);
-
-      if Unknown_Conflicts.Length > 0 then
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Current_Error, "unknown 
conflicts:");
-         Put (Unknown_Conflicts, Ada.Text_IO.Current_Error, Descriptor);
-         Ada.Text_IO.New_Line (Ada.Text_IO.Current_Error);
-         WisiToken.Generate.Error := WisiToken.Generate.Error or not 
Ignore_Unknown_Conflicts;
-      end if;
-
-      if Known_Conflicts_Edit.Length > 0 then
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Current_Error, "excess known 
conflicts:");
-         Put (Known_Conflicts_Edit, Ada.Text_IO.Current_Error, Descriptor);
-         Ada.Text_IO.New_Line (Ada.Text_IO.Current_Error);
-         WisiToken.Generate.Error := WisiToken.Generate.Error or not 
Ignore_Unknown_Conflicts;
-      end if;
-
-      WisiToken.Generate.Error := WisiToken.Generate.Error or (Unused_Tokens 
and not Ignore_Unused_Tokens);
-
-      return Table;
-   end Generate;
-
-end WisiToken.Generate.LR.LR1_Generate;
diff --git a/packages/wisi/wisitoken-generate-lr-lr1_generate.ads 
b/packages/wisi/wisitoken-generate-lr-lr1_generate.ads
deleted file mode 100644
index d0f2d9f..0000000
--- a/packages/wisi/wisitoken-generate-lr-lr1_generate.ads
+++ /dev/null
@@ -1,91 +0,0 @@
---  Abstract :
---
---  LR1 (Left-to-right scanning 1 look-ahead) parser table generator.
---
---  References:
---
---  [dragon] "Compilers Principles, Techniques, and Tools" by Aho,
---  Sethi, and Ullman (aka: "The [Red] Dragon Book").
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Generate.LR1_Items;
-with WisiToken.Productions;
-package WisiToken.Generate.LR.LR1_Generate is
-
-   function Generate
-     (Grammar               : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor            : in     WisiToken.Descriptor;
-      Known_Conflicts       : in     Conflict_Lists.List := 
Conflict_Lists.Empty_List;
-      McKenzie_Param        : in     McKenzie_Param_Type := 
Default_McKenzie_Param;
-      Parse_Table_File_Name : in     String              := "";
-      Include_Extra         : in     Boolean             := False;
-      Ignore_Conflicts      : in     Boolean             := False;
-      Partial_Recursion     : in     Boolean             := True)
-     return Parse_Table_Ptr
-   with Pre => Descriptor.First_Nonterminal = Descriptor.Accept_ID;
-   --  Generate a generalized LR1 parse table for Grammar. The
-   --  grammar start symbol is the LHS of the first production in
-   --  Grammar.
-   --
-   --  Sets Recursive components in Grammar.
-   --
-   --  If Trace, output debug info to Standard_Error about generation
-   --  process. We don't use WisiToken.Trace here; we often want to
-   --  see a trace of the parser execution without the parser
-   --  generation.
-   --
-   --  Unless Ignore_Unused_Tokens is True, raise Grammar_Error if
-   --  there are unused tokens.
-   --
-   --  Unless Ignore_Unknown_Conflicts is True, raise Grammar_Error if there
-   --  are unknown conflicts.
-
-   ----------
-   --  visible for unit test
-
-   function LR1_Goto_Transitions
-     (Set                     : in LR1_Items.Item_Set;
-      Symbol                  : in Token_ID;
-      Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set;
-   --  'goto' from [dragon] algorithm 4.9
-
-   function LR1_Item_Sets
-     (Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return LR1_Items.Item_Set_List;
-   --  [dragon] algorithm 4.9 pg 231; figure 4.38 pg 232; procedure "items"
-
-   procedure Add_Actions
-     (Item_Sets            : in     LR1_Items.Item_Set_List;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      :    out Conflict_Count_Lists.List;
-      Conflicts            :    out Conflict_Lists.List;
-      Table                : in out Parse_Table;
-      Descriptor           : in     WisiToken.Descriptor);
-
-end WisiToken.Generate.LR.LR1_Generate;
diff --git a/packages/wisi/wisitoken-generate-lr.adb 
b/packages/wisi/wisitoken-generate-lr.adb
deleted file mode 100644
index d66746d..0000000
--- a/packages/wisi/wisitoken-generate-lr.adb
+++ /dev/null
@@ -1,1510 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Text_IO;
-with System.Multiprocessors;
-with WisiToken.Generate;
-package body WisiToken.Generate.LR is
-
-   package RHS_Set is new SAL.Gen_Unbounded_Definite_Vectors (Natural, 
Boolean, Default_Element => False);
-
-   type LHS_RHS_Set is array (Token_ID range <>) of RHS_Set.Vector;
-
-   ----------
-   --  Body subprograms, alphabetical
-
-   function Min
-     (Item    : in RHS_Sequence_Arrays.Vector;
-      RHS_Set : in LR.RHS_Set.Vector)
-     return Integer
-   is
-      use all type Ada.Containers.Count_Type;
-      Min_Length : Ada.Containers.Count_Type := Ada.Containers.Count_Type'Last;
-      Min_RHS    : Natural                   := Natural'Last;
-   begin
-      for RHS in Item.First_Index .. Item.Last_Index loop
-         if RHS_Set (RHS) and then Min_Length > Item (RHS).Length then
-               Min_Length := Item (RHS).Length;
-               Min_RHS    := RHS;
-         end if;
-      end loop;
-      if Min_RHS = Natural'Last then
-         raise SAL.Programmer_Error with "nonterm has no minimum terminal 
sequence";
-      else
-         return Min_RHS;
-      end if;
-   end Min;
-
-   function Image
-     (Nonterm    : in Token_ID;
-      Sequences  : in Minimal_Sequence_Array;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is begin
-      return Trimmed_Image (Nonterm) & " " & Image (Nonterm, Descriptor) & " 
==> (" &
-        Sequences (Nonterm).Min_RHS'Image & ", " & Image (Sequences 
(Nonterm).Sequence, Descriptor) & ")";
-   end Image;
-
-   procedure Terminal_Sequence
-     (Grammar       : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor    : in     WisiToken.Descriptor;
-      All_Sequences : in out Minimal_Sequence_Array;
-      All_Seq_Set   : in out Token_ID_Set;
-      RHS_Seq_Set   : in out LHS_RHS_Set;
-      Recursing     : in out Token_ID_Set;
-      Nonterm       : in     Token_ID)
-   is
-      use Ada.Containers;
-      use Token_ID_Arrays;
-
-      subtype Terminals is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-
-      Prod : Productions.Instance renames Grammar (Nonterm);
-
-      Skipped_Recursive : Boolean := False;
-
-      procedure Init_All_Sequences (LHS : in Token_ID)
-      is
-         Prod : Productions.Instance renames Grammar (LHS);
-      begin
-         if All_Sequences (LHS).Sequence.Length = 0 then
-            All_Sequences (LHS).Sequence.Set_First_Last 
(Prod.RHSs.First_Index, Prod.RHSs.Last_Index);
-         end if;
-         if RHS_Seq_Set (LHS).Length = 0 then
-            RHS_Seq_Set (LHS).Set_First_Last (Prod.RHSs.First_Index, 
Prod.RHSs.Last_Index);
-         end if;
-      end Init_All_Sequences;
-
-   begin
-      --  We get here because All_Sequences (Nonterm) has not been fully
-      --  computed yet (All_Seq_Set (Nonterm) is False). Attempt to
-      --  compute All_Sequences (Nonterm); it may not succeed due to
-      --  recursion. If successful, set All_Seq_Set (Nonterm).
-      --
-      --  In a useful grammar, all direct and indirect recursive nonterms
-      --  have a non-recursive minimal terminal sequence; finding it will
-      --  break the recursion, allowing this algorithm to complete. This is
-      --  checked in Compute_Minimal_Terminal_Sequences.
-
-      Init_All_Sequences (Nonterm);
-
-      for RHS in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         if not RHS_Seq_Set (Nonterm)(RHS) then
-            if Trace_Generate_Minimal_Complete > Extra then
-               Ada.Text_IO.Put_Line (Trimmed_Image ((Nonterm, RHS)) & " " & 
Image (Nonterm, Descriptor) & " compute");
-            end if;
-            if Prod.RHSs (RHS).Tokens.Length = 0 then
-               RHS_Seq_Set (Nonterm)(RHS) := True;
-               if Trace_Generate_Minimal_Complete > Extra then
-                  Ada.Text_IO.Put_Line (Trimmed_Image (Production_ID'(Nonterm, 
RHS)) & " => () empty");
-               end if;
-
-            else
-               for I in Prod.RHSs (RHS).Tokens.First_Index .. Prod.RHSs 
(RHS).Tokens.Last_Index loop
-                  declare
-                     ID : Token_ID renames Prod.RHSs (RHS).Tokens (I);
-                  begin
-                     if ID in Terminals then
-                        All_Sequences (Nonterm).Sequence (RHS).Append (ID);
-
-                     else
-                        if (for some RHS of RHS_Seq_Set (ID) => RHS) then
-                           --  There is a minimal sequence for ID; use it
-                           null;
-                        else
-                           if ID = Nonterm or Recursing (ID) then
-                              --  Clear partial minimal sequence; we are 
starting over.
-                              All_Sequences (Nonterm).Sequence (RHS).Clear;
-                              goto Skip;
-
-                           else
-                              Recursing (ID) := True;
-                              Terminal_Sequence
-                                (Grammar, Descriptor, All_Sequences, 
All_Seq_Set, RHS_Seq_Set, Recursing, ID);
-                              Recursing (ID) := False;
-
-                              if All_Seq_Set (ID) or else (for some RHS of 
RHS_Seq_Set (ID) => RHS) then
-                                 --  Found a minimal sequence for ID; use it
-                                 null;
-                              else
-                                 All_Sequences (Nonterm).Sequence (RHS).Clear;
-                                 goto Skip;
-                              end if;
-                           end if;
-                        end if;
-                        declare
-                           Min_RHS : constant Integer := Min (All_Sequences 
(ID).Sequence, RHS_Seq_Set (ID));
-                        begin
-                           All_Sequences (ID).Min_RHS := Min_RHS;
-
-                           All_Sequences (Nonterm).Sequence (RHS).Append 
(All_Sequences (ID).Sequence (Min_RHS));
-                        end;
-                     end if;
-                  end;
-               end loop;
-               RHS_Seq_Set (Nonterm)(RHS) := True;
-               if Trace_Generate_Minimal_Complete > Extra then
-                  Ada.Text_IO.Put_Line
-                    (Trimmed_Image (Production_ID'(Nonterm, RHS)) & " => " &
-                       Image (All_Sequences (Nonterm).Sequence (RHS), 
Descriptor));
-               end if;
-            end if;
-         end if;
-         <<Skip>>
-         Skipped_Recursive := True;
-      end loop;
-
-      if Skipped_Recursive then
-         if (for some RHS of RHS_Seq_Set (Nonterm) => not RHS) then
-            --  Some RHSs are have unresolved recursion; we will
-            --  eventually try again when the recursion is resolved.
-            if Trace_Generate_Minimal_Complete > Extra then
-               Ada.Text_IO.Put_Line
-                 (Trimmed_Image (Nonterm) & " " & Image (Nonterm, Descriptor) 
& " skipped some recursive");
-            end if;
-            return;
-         end if;
-      end if;
-
-      All_Seq_Set (Nonterm) := True;
-
-      if Trace_Generate_Minimal_Complete > Extra then
-         Ada.Text_IO.Put_Line (Image (Nonterm, All_Sequences, Descriptor));
-      end if;
-   end Terminal_Sequence;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   procedure Put
-     (Item       : in Conflict_Lists.List;
-      File       : in Ada.Text_IO.File_Type;
-      Descriptor : in WisiToken.Descriptor)
-   is begin
-      for Conflict of Item loop
-         Ada.Text_IO.Put_Line (File, Image (Conflict, Descriptor));
-      end loop;
-   end Put;
-
-   procedure Add_Action
-     (Symbol               : in     Token_ID;
-      Action               : in     Parse_Action_Rec;
-      Action_List          : in out Action_Arrays.Vector;
-      Closure              : in     LR1_Items.Item_Set;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Descriptor           : in     WisiToken.Descriptor)
-   is
-      Matching_Action : constant Action_Arrays.Find_Reference_Type := 
Action_List.Find (Symbol);
-   begin
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.Put (Image (Symbol, Descriptor) & " => ");
-         Put (Descriptor, Action);
-         Ada.Text_IO.New_Line;
-      end if;
-
-      if Matching_Action.Element /= null then
-         if Is_In (Action, Matching_Action.Actions) then
-            --  Action is already in the list.
-            if Trace_Generate_Table > Detail then
-               Ada.Text_IO.Put_Line (" - already present");
-            end if;
-            return;
-         else
-            --  There is a conflict. Report it and add it, so the
-            --  generalized parser can follow all paths
-            declare
-               --  Enforce canonical Shift/Reduce or Accept/Reduce order, to 
simplify
-               --  searching and code generation. There can be only one Shift 
in the
-               --  list of conflicting actions, so we keep it the first item 
in the
-               --  list; no order in the rest of the list.
-               Action_A : constant Parse_Action_Rec :=
-                 (if Action.Verb in Shift | Accept_It then Action else 
Matching_Action.Actions.Item);
-
-               Action_B : constant Parse_Action_Rec :=
-                 (if Action.Verb in Shift | Accept_It then 
Matching_Action.Actions.Item else Action);
-
-               New_Conflict : constant Conflict :=
-                 (Action_A    => Action_A.Verb,
-                  Action_B    => Action_B.Verb,
-                  LHS_A       => Find
-                    (Closure, Action_A, Symbol, Grammar, Has_Empty_Production, 
First_Nonterm_Set, Descriptor),
-                  LHS_B       => Find
-                    (Closure, Action_B, Symbol, Grammar, Has_Empty_Production, 
First_Nonterm_Set, Descriptor),
-                  State_Index => Closure.State,
-                  On          => Symbol);
-
-               Counts : Conflict_Count_Lists.Cursor;
-            begin
-               for Cur in Conflict_Counts.Iterate loop
-                  if Conflict_Counts (Cur).State = Closure.State then
-                     Counts := Cur;
-                     exit;
-                  end if;
-               end loop;
-
-               if not Conflict_Count_Lists.Has_Element (Counts) then
-                  Conflict_Counts.Append ((Closure.State, others => 0));
-                  Counts := Conflict_Counts.Last;
-               end if;
-
-               declare
-                  use Conflict_Count_Lists;
-                  Counts_Ref : constant Reference_Type := Reference 
(Conflict_Counts, Counts);
-               begin
-                  case Action_A.Verb is
-                  when Shift =>
-                     case Action_B.Verb is
-                     when Shift | Accept_It | WisiToken.Parse.LR.Error =>
-                        raise SAL.Programmer_Error;
-                     when Reduce =>
-                        Counts_Ref.Shift_Reduce := Counts_Ref.Shift_Reduce + 1;
-                     end case;
-                  when Reduce =>
-                     case Action_B.Verb is
-                     when Shift | Accept_It | WisiToken.Parse.LR.Error =>
-                        raise SAL.Programmer_Error;
-                     when Reduce =>
-                        Counts_Ref.Reduce_Reduce := Counts_Ref.Reduce_Reduce + 
1;
-                     end case;
-                  when Accept_It =>
-                     case Action_B.Verb is
-                     when Shift | Accept_It | WisiToken.Parse.LR.Error =>
-                        raise SAL.Programmer_Error;
-                     when Reduce =>
-                        Counts_Ref.Accept_Reduce := Counts_Ref.Accept_Reduce + 
1;
-                     end case;
-                  when WisiToken.Parse.LR.Error =>
-                     raise SAL.Programmer_Error;
-                  end case;
-               end;
-
-               if not Is_Present (New_Conflict, Conflicts) then
-                  --  The same conflict may occur in a different
-                  --  item set. Only add it to conflicts once.
-                  Conflicts.Append (New_Conflict);
-
-                  if Trace_Generate_Table > Detail then
-                     Ada.Text_IO.Put_Line (" - conflict added: " & Image 
(New_Conflict, Descriptor));
-                  end if;
-               else
-                  if Trace_Generate_Table > Detail then
-                     Ada.Text_IO.Put_Line (" - conflict duplicate: " & Image 
(New_Conflict, Descriptor));
-                  end if;
-               end if;
-
-               if Action.Verb = Shift then
-                  Matching_Action.Actions := new Parse_Action_Node'(Action, 
Matching_Action.Actions);
-               else
-                  Matching_Action.Actions.Next := new 
Parse_Action_Node'(Action, Matching_Action.Actions.Next);
-               end if;
-            end;
-         end if;
-      else
-         WisiToken.Parse.LR.Add (Action_List, Symbol, Action);
-      end if;
-   end Add_Action;
-
-   procedure Add_Actions
-     (Closure              : in     LR1_Items.Item_Set;
-      Table                : in out Parse_Table;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Descriptor           : in     WisiToken.Descriptor)
-   is
-      use Token_ID_Arrays;
-
-      State : constant State_Index := Closure.State;
-   begin
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.Put_Line ("adding actions for state" & State_Index'Image 
(State));
-      end if;
-
-      for Item of Closure.Set loop
-         declare
-            Dot : constant Token_ID_Arrays.Cursor := 
Productions.Constant_Ref_RHS
-              (Grammar, Item.Prod).Tokens.To_Cursor (Item.Dot);
-         begin
-            if not Has_Element (Dot) then
-               Add_Lookahead_Actions
-                 (Item, Table.States (State).Action_List, Grammar, 
Has_Empty_Production, First_Nonterm_Set,
-                  Conflict_Counts, Conflicts, Closure, Descriptor);
-
-            elsif Element (Dot) in
-              Descriptor.First_Terminal .. Descriptor.Last_Terminal
-            then
-               --  Dot is before a terminal token.
-               declare
-                  use all type Ada.Containers.Count_Type;
-
-                  P_ID : constant Production_ID := Item.Prod;
-
-                  Dot_ID : constant Token_ID := Element (Dot);
-                  --  ID of token after Item.Dot
-
-                  Goto_State : constant Unknown_State_Index := 
LR1_Items.Goto_State (Closure, Dot_ID);
-               begin
-                  if Dot_ID = Descriptor.EOI_ID then
-                     --  This is the start symbol production with dot before 
EOF.
-                     declare
-                        RHS  : Productions.Right_Hand_Side renames Grammar 
(P_ID.LHS).RHSs (P_ID.RHS);
-                     begin
-                        Add_Action
-                          (Dot_ID,
-                           (Accept_It, P_ID, RHS.Action, RHS.Check, 
RHS.Tokens.Length - 1),
-                           --  EOF is not pushed on stack in parser, because 
the action for EOF
-                           --  is Accept, not Shift.
-                           Table.States (State).Action_List, Closure,
-                           Grammar, Has_Empty_Production, First_Nonterm_Set, 
Conflict_Counts, Conflicts, Descriptor);
-                     end;
-                  else
-                     if Goto_State /= Unknown_State then
-                        Add_Action
-                          (Dot_ID,
-                           (Shift, P_ID, Goto_State),
-                           Table.States (State).Action_List,
-                           Closure, Grammar, Has_Empty_Production, 
First_Nonterm_Set,
-                           Conflict_Counts, Conflicts, Descriptor);
-                     end if;
-                  end if;
-               end;
-            else
-               --  Dot is before a non-terminal token; no action.
-               if Trace_Generate_Table > Detail then
-                  Ada.Text_IO.Put_Line (Image (Element (Dot), Descriptor) & " 
=> no action");
-               end if;
-            end if;
-         end;
-      end loop;
-
-      --  We don't place a default error action at the end of every state;
-      --  Parse.LR.Action_For returns Table.Error_Action when Symbol is not 
found.
-      Table.Error_Action := new Parse_Action_Node'((Verb => 
WisiToken.Parse.LR.Error, others => <>), null);
-
-      for Item of Closure.Goto_List loop
-         if Item.Symbol in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal then
-            --  FIXME: Goto_List has terminals; either don't need to add 
those, or can use that instead of above code.
-            Add_Goto (Table.States (State), Item.Symbol, Item.State); -- note 
list is already sorted.
-         end if;
-      end loop;
-   end Add_Actions;
-
-   procedure Add_Lookahead_Actions
-     (Item                 : in     LR1_Items.Item;
-      Action_List          : in out Action_Arrays.Vector;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Closure              : in     LR1_Items.Item_Set;
-      Descriptor           : in     WisiToken.Descriptor)
-   is
-      Prod   : Productions.Instance renames Grammar (Item.Prod.LHS);
-      RHS    : Productions.Right_Hand_Side renames Prod.RHSs (Item.Prod.RHS);
-      Action : constant Parse_Action_Rec := (Reduce, Item.Prod, RHS.Action, 
RHS.Check, RHS.Tokens.Length);
-   begin
-      if Trace_Generate_Table > Detail then
-         Ada.Text_IO.Put_Line ("processing lookaheads");
-      end if;
-
-      --  We ignore propagate lookaheads here.
-      for Lookahead in Item.Lookaheads'Range loop
-         if Item.Lookaheads (Lookahead) then
-            if Lookahead = Descriptor.First_Nonterminal then
-               null;
-            else
-               Add_Action
-                 (Lookahead, Action, Action_List, Closure, Grammar,
-                  Has_Empty_Production, First_Nonterm_Set, Conflict_Counts, 
Conflicts, Descriptor);
-            end if;
-         end if;
-      end loop;
-   end Add_Lookahead_Actions;
-
-   procedure Delete_Known
-     (Conflicts       : in out Conflict_Lists.List;
-      Known_Conflicts : in out Conflict_Lists.List)
-   is
-      --  Delete all elements in Conflicts that match an element in
-      --  Known_Conflicts. There can be more than one Conflict that
-      --  match one Known_Conflict.
-      use Conflict_Lists;
-      Known      : Cursor  := Known_Conflicts.First;
-      Next_Known : Cursor;
-   begin
-      loop
-         exit when Known = No_Element;
-         Next_Known := Next (Known);
-         declare
-            I      : Cursor  := Conflicts.First;
-            Next_I : Cursor;
-            Used   : Boolean := False;
-         begin
-            loop
-               exit when I = No_Element;
-               Next_I := Next (I);
-               if Match (Element (Known), Conflicts.Constant_Reference (I)) 
then
-                  Delete (Conflicts, I);
-                  Used := True;
-               end if;
-               I := Next_I;
-            end loop;
-
-            if Used then
-               Delete (Known_Conflicts, Known);
-            end if;
-         end;
-         Known := Next_Known;
-      end loop;
-   end Delete_Known;
-
-   function Find
-     (Closure              : in LR1_Items.Item_Set;
-      Action               : in Parse_Action_Rec;
-      Lookahead            : in Token_ID;
-      Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First                : in Token_Array_Token_Set;
-      Descriptor           : in WisiToken.Descriptor)
-     return Token_ID
-   is
-      use WisiToken.Token_ID_Arrays;
-   begin
-      case Action.Verb is
-      when Reduce | Accept_It =>
-         --  If the nonterm produced by the reduce is the LHS of the state
-         --  production, use it.
-         for Item of Closure.Set loop
-            if LR1_Items.In_Kernel (Grammar, Descriptor, Item) and
-              Action.Production.LHS = Item.Prod.LHS
-            then
-               return Item.Prod.LHS;
-            end if;
-         end loop;
-
-         --  The reduce nonterm is after Dot in a state production; find which
-         --  one, use that.
-         for Item of Closure.Set loop
-            if LR1_Items.In_Kernel (Grammar, Descriptor, Item) then
-               declare
-                  Dot : Token_ID_Arrays.Cursor := Productions.Constant_Ref_RHS
-                    (Grammar, Item.Prod).Tokens.To_Cursor (Item.Dot);
-               begin
-                  loop
-                     if not Has_Element (Dot) then
-                        if Item.Lookaheads (Lookahead) then
-                           return Item.Prod.LHS;
-                        end if;
-                     else
-                        declare
-                           Dot_ID : constant Token_ID := Element (Dot);
-                        begin
-                           if Dot_ID = Lookahead or
-                             (Dot_ID in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal and then
-                                First (Dot_ID, Lookahead))
-                           then
-                              return Item.Prod.LHS;
-                           end if;
-                           exit when Dot_ID in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal and then
-                             not Has_Empty_Production (Dot_ID);
-                        end;
-                     end if;
-
-                     exit when not Has_Element (Dot);
-                     Next (Dot);
-                  end loop;
-               end;
-            end if;
-         end loop;
-
-      when Shift =>
-
-         for Item of Closure.Set loop
-            --  Lookahead (the token shifted) is starting a nonterm in a state
-            --  production; it is in First of that nonterm.
-            if LR1_Items.In_Kernel (Grammar, Descriptor, Item) then
-               declare
-                  Dot : Token_ID_Arrays.Cursor := Productions.Constant_Ref_RHS
-                    (Grammar, Item.Prod).Tokens.To_Cursor (Item.Dot);
-               begin
-                  loop
-                     exit when not Has_Element (Dot);
-                     declare
-                        Dot_ID : constant Token_ID := Element (Dot);
-                     begin
-                        if Dot_ID = Lookahead or
-                          (Dot_ID in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal and then
-                             First (Dot_ID, Lookahead))
-                        then
-                           return Item.Prod.LHS;
-                        end if;
-
-                        exit when Dot_ID in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal and then
-                          not Has_Empty_Production (Dot_ID);
-                     end;
-
-                     Next (Dot);
-                  end loop;
-               end;
-            end if;
-         end loop;
-
-      when WisiToken.Parse.LR.Error =>
-         raise SAL.Programmer_Error;
-      end case;
-
-      Ada.Text_IO.Put_Line
-        ("item for " & Image (Action, Descriptor) & " on " & Image (Lookahead, 
Descriptor) & " not found in");
-      LR1_Items.Put (Grammar, Descriptor, Closure, Kernel_Only => True);
-      raise SAL.Programmer_Error;
-   end Find;
-
-   function Image (Item : in Conflict; Descriptor : in WisiToken.Descriptor) 
return String
-   is begin
-      return
-        ("%conflict " &
-           Conflict_Parse_Actions'Image (Item.Action_A) & "/" &
-           Conflict_Parse_Actions'Image (Item.Action_B) & " in state " &
-           Image (Item.LHS_A, Descriptor) & ", " &
-           Image (Item.LHS_B, Descriptor) &
-           " on token " & Image (Item.On, Descriptor) &
-           " (" & State_Index'Image (Item.State_Index) & ")"); -- state number 
last for easier delete
-   end Image;
-
-   function Is_Present (Item : in Conflict; Conflicts : in 
Conflict_Lists.List) return Boolean
-   is
-      use Conflict_Lists;
-      I : Cursor := Conflicts.First;
-   begin
-      loop
-         exit when I = No_Element;
-         if Match (Item, Conflicts.Constant_Reference (I)) then
-            return True;
-         end if;
-         I := Next (I);
-      end loop;
-      return False;
-   end Is_Present;
-
-   function Match (Known : in Conflict; Item : in 
Conflict_Lists.Constant_Reference_Type) return Boolean
-   is begin
-      --  Ignore State_Index. Actions are in canonical order; enforced
-      --  in Add_Action above. For reduce/reduce, LHS_A, LHS_B are not
-      --  in canonical order.
-      return
-        Known.Action_A = Item.Action_A and
-        Known.Action_B = Item.Action_B and
-        ((Known.LHS_A = Item.LHS_A and Known.LHS_B = Item.LHS_B) or
-           (Known.LHS_B = Item.LHS_A and Known.LHS_A = Item.LHS_B)) and
-        Known.On = Item.On;
-   end Match;
-
-   ----------
-   --  Minimal terminal sequences.
-
-   function Min_Length (Item : in RHS_Sequence_Arrays.Vector) return 
Ada.Containers.Count_Type
-   is
-      use Ada.Containers;
-      Min : Count_Type := Count_Type'Last;
-   begin
-      for RHS of Item loop
-         if RHS.Length < Min then
-            Min := RHS.Length;
-         end if;
-      end loop;
-      return Min;
-   end Min_Length;
-
-   function Min (Item : in RHS_Sequence_Arrays.Vector) return 
Token_ID_Arrays.Vector
-   is
-      use all type Ada.Containers.Count_Type;
-      Min_Length : Ada.Containers.Count_Type := Ada.Containers.Count_Type'Last;
-      Min_RHS    : Natural                   := Natural'Last;
-   begin
-      --  This version assumes all RHS are computed.
-      for RHS in Item.First_Index .. Item.Last_Index loop
-         if Min_Length > Item (RHS).Length then
-            Min_Length := Item (RHS).Length;
-            Min_RHS    := RHS;
-         end if;
-      end loop;
-      if Min_RHS = Natural'Last then
-         raise Grammar_Error with "nonterm has no minimum terminal sequence";
-      else
-         return Item (Min_RHS);
-      end if;
-   end Min;
-
-   function Compute_Minimal_Terminal_Sequences
-     (Descriptor : in WisiToken.Descriptor;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector)
-     return Minimal_Sequence_Array
-   is
-      --  Result (ID).Sequence.Length = 0 is a valid result (ie the
-      --  nonterminal can be empty), so we use an auxilliary array to track
-      --  whether Result (ID) has been computed.
-
-      All_Seq_Set : Token_ID_Set := (Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal => False);
-      Recursing   : Token_ID_Set := (Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal => False);
-
-      RHS_Seq_Set : LHS_RHS_Set :=
-        (Descriptor.First_Nonterminal .. Descriptor.Last_Nonterminal => 
RHS_Set.Empty_Vector);
-
-      Last_Seq_Count : Integer := 0;
-      This_Count     : Integer;
-      Pass_Count     : Integer := 0;
-   begin
-      return Result : Minimal_Sequence_Array (Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal) do
-         loop
-            exit when (for all B of All_Seq_Set => B);
-            Pass_Count := Pass_Count + 1;
-            if Trace_Generate_Minimal_Complete > Detail then
-               if Trace_Generate_Minimal_Complete > Extra then
-                  Ada.Text_IO.New_Line;
-               end if;
-               Ada.Text_IO.Put_Line ("Compute_Minimal_Terminal_Sequences pass" 
& Integer'Image (Pass_Count));
-            end if;
-            for P of Grammar loop
-               Terminal_Sequence (Grammar, Descriptor, Result, All_Seq_Set, 
RHS_Seq_Set, Recursing, P.LHS);
-            end loop;
-            This_Count := Count (All_Seq_Set);
-            if This_Count = Last_Seq_Count then
-               Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, Image 
(All_Seq_Set, Descriptor, Inverted => True));
-               raise Grammar_Error with "sequences not resolved";
-            end if;
-            Last_Seq_Count := This_Count;
-         end loop;
-
-         if Trace_Generate_Minimal_Complete > Detail then
-            Ada.Text_IO.Put_Line ("Minimal_Terminal_Sequences:");
-            for LHS in Result'Range loop
-               Ada.Text_IO.Put_Line (Image (LHS, Result, Descriptor));
-            end loop;
-         end if;
-      end return;
-   end Compute_Minimal_Terminal_Sequences;
-
-   function Compute_Minimal_Terminal_First
-     (Descriptor                 : in WisiToken.Descriptor;
-      Minimal_Terminal_Sequences : in Minimal_Sequence_Array)
-     return Token_Array_Token_ID
-   is
-      use Token_ID_Arrays;
-   begin
-      return Result : Token_Array_Token_ID (Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal) do
-         for ID in Result'Range loop
-            declare
-               use all type Ada.Containers.Count_Type;
-               Min_Seq : Token_ID_Arrays.Vector renames Min 
(Minimal_Terminal_Sequences (ID).Sequence);
-            begin
-               if Min_Seq.Length = 0 then
-                  Result (ID) := Invalid_Token_ID;
-               else
-                  Result (ID) := Element (Min_Seq.First);
-               end if;
-            end;
-         end loop;
-      end return;
-   end Compute_Minimal_Terminal_First;
-
-   procedure Set_Minimal_Complete_Actions
-     (State                      : in out Parse_State;
-      Kernel                     : in     LR1_Items.Item_Set;
-      Descriptor                 : in     WisiToken.Descriptor;
-      Grammar                    : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Nullable                   : in     Token_Array_Production_ID;
-      Minimal_Terminal_Sequences : in     Minimal_Sequence_Array;
-      Minimal_Terminal_First     : in     Token_Array_Token_ID)
-   is
-      use all type Ada.Containers.Count_Type;
-      use LR1_Items.Item_Lists;
-      use Token_ID_Arrays;
-
-      subtype Terminals is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-
-      function Find_Action (List : in Action_Arrays.Vector; ID : in Token_ID) 
return Minimal_Action
-      is begin
-         --  ID is a terminal after Dot in an item in a kernel that has List as
-         --  the actions; return the appropriate action.
-         for Node of List loop
-            if Node.Symbol = ID then
-               case Node.Actions.Item.Verb is
-               when Shift =>
-                  return (Shift, Node.Actions.Item.Production, ID, 
Node.Actions.Item.State);
-               when Reduce =>
-                  --  Item.Dot is a nonterm that starts with a nullable 
nonterm; reduce
-                  --  to that first. After any more such reductions, the 
action will be
-                  --  Shift ID.
-                  return (Reduce, Node.Actions.Item.Production, 0);
-               when Accept_It | WisiToken.Parse.LR.Error =>
-                  raise SAL.Programmer_Error;
-               end case;
-            end if;
-         end loop;
-         raise SAL.Programmer_Error;
-      end Find_Action;
-
-      function Compute_Action (ID : in Token_ID) return Minimal_Action
-      is begin
-         if ID in Terminals then
-            return Find_Action (State.Action_List, ID);
-
-         else
-            if Minimal_Terminal_First (ID) = Invalid_Token_ID then
-               --  Item.Dot is a nullable nonterm; include a reduce to the null
-               --  nonterm, rather than a shift of the following terminal; 
recover
-               --  must do the reduce first.
-               return (Reduce, (ID, Minimal_Terminal_Sequences (ID).Min_RHS), 
Token_Count => 0);
-
-            else
-               return Find_Action (State.Action_List, Minimal_Terminal_First 
(ID));
-            end if;
-         end if;
-      end Compute_Action;
-
-      function Length_After_Dot (Item : in LR1_Items.Item) return 
Ada.Containers.Count_Type
-      is
-         use Ada.Containers;
-         Prod   : constant Production_ID := Item.Prod;
-         Result : Count_Type             := 0;
-         Tokens : Vector renames Grammar (Prod.LHS).RHSs (Prod.RHS).Tokens;
-         I      : Token_ID_Arrays.Cursor := Tokens.To_Cursor (Item.Dot);
-      begin
-         if not Has_Element (I) then
-            --  Can only compute this at runtime.
-            return 0;
-         end if;
-
-         loop
-            exit when not Has_Element (I);
-
-            if Element (I) in Terminals then
-               Result := Result + 1;
-            else
-               Result := Result + Min_Length (Minimal_Terminal_Sequences 
(Tokens (I)).Sequence);
-            end if;
-            Next (I);
-         end loop;
-         return Result;
-      end Length_After_Dot;
-
-   begin
-      if Kernel.State = 0 then
-         --  State 0 has dot before all tokens, which is never needed in the
-         --  Minimal_Complete_Action algorithm.
-         return;
-
-      elsif (for some Item of Kernel.Set =>
-               Item.Prod.LHS = Descriptor.Accept_ID and
-               (Item.Dot /= No_Index and then Productions.Constant_Ref_RHS
-                  (Grammar, Item.Prod).Tokens (Item.Dot) = Descriptor.EOI_ID))
-      then
-         --  No actions
-         return;
-      end if;
-
-      --  Set State.Kernel, and delete Items from Working_Set that are known
-      --  to be non-minimal.
-      declare
-         use Ada.Containers;
-
-         function Before_Dot (Item : in LR1_Items.Item) return Token_ID
-         is
-            Tokens : Token_ID_Arrays.Vector renames Grammar 
(Item.Prod.LHS).RHSs (Item.Prod.RHS).Tokens;
-         begin
-            if Item.Dot = Token_ID_Arrays.No_Index then
-               return Tokens (Tokens.Last_Index);
-            else
-               return Tokens (Item.Dot - 1);
-            end if;
-         end Before_Dot;
-
-         type State_Label is (Unknown, Keep_Always, Keep_If_Minimal, Drop);
-         type Item_State (Label : State_Label := Unknown)
-         is record
-            case Label is
-            when Keep_Always | Keep_If_Minimal =>
-               Minimal_Action : WisiToken.Parse.LR.Minimal_Action;
-               --  Minimal_Action.Production = Invalid_Production_ID (the 
default) if it is unknown.
-            when Unknown | Drop =>
-               null;
-            end case;
-         end record;
-
-         subtype Kernel_Index is Count_Type range 1 .. Kernel.Set.Length;
-         Item_States : array (Kernel_Index) of Item_State;
-         I           : Kernel_Index := Kernel_Index'First;
-         Min_Length  : Count_Type := Count_Type'Last;
-      begin
-         State.Kernel.Set_First_Last (Kernel_Index'First, Kernel_Index'Last);
-         for Item of Kernel.Set loop
-            declare
-               RHS    : WisiToken.Productions.Right_Hand_Side renames
-                 Grammar (Item.Prod.LHS).RHSs (Item.Prod.RHS);
-               Dot_ID : constant Token_ID :=
-                 (if Item.Dot = No_Index
-                  then Invalid_Token_ID
-                  else RHS.Tokens (Item.Dot));
-
-               --  Kernel components
-               Length_After_Dot  : constant Count_Type := 
Set_Minimal_Complete_Actions.Length_After_Dot (Item);
-               Reduce_Production : constant Production_ID :=
-                 (if Length_After_Dot = 0
-                  then (if Dot_ID in Nullable'Range then Nullable (Dot_ID) 
else Item.Prod)
-                  else Invalid_Production_ID);
-               Reduce_Count : constant Count_Type :=
-                 (if Reduce_Production = Invalid_Production_ID
-                  then 0
-                  else Grammar (Reduce_Production.LHS).RHSs 
(Reduce_Production.RHS).Tokens.Length);
-            begin
-               --  Here we must compute Item_State (I).Label and 
.Minimal_Action,
-               --  considering recursion.
-               --
-               --  Insert_Minimal_Complete_Actions does not need any recursion
-               --  information at runtim, because we elminate all cases where 
it
-               --  might here.
-               --
-               --  The strategy in Insert_Minimal_Complete_Actions when
-               --  Item.Length_After_Dot = 0 is to compute Length_After_Dot by 
doing
-               --  Reduce until a Shift is encountered, and using 
Length_After_Dot
-               --  for that item.               --
-               --
-               --  Consider these kernel items with possible recursion (from
-               --  ada_lite_lalr.parse_table - not listed in state order here, 
to
-               --  group related productions). The recursion of each 
production is
-               --  shown after ';', if not all None.
-               --
-               --  State 2:
-               --       86.0:exit_statement <= EXIT ^ identifier_opt WHEN 
expression_opt SEMICOLON
-               --       86.1:exit_statement <= EXIT ^ identifier_opt SEMICOLON
-               --
-               --  State 43:
-               --     103.2:name <= IDENTIFIER ^
-               --
-               --  State 30:
-               --     103.3:name <= selected_component ^ ; ( 1 => Other_Left)
-               --
-               --  State 47:
-               --      103.0:name <= name ^ LEFT_PAREN range_list RIGHT_PAREN 
; ( 1 => Direct_Left,  3 => Other)
-               --      103.1:name <= name ^ actual_parameter_part ; ( 1 => 
Direct_Left,  2 => Other)
-               --      113.2:primary <= name ^  ; ( 1 => Other_Left)
-               --      124.0:selected_component <= name ^ DOT IDENTIFIER ; ( 1 
=> Other_Left)
-               --
-               --  State 68:
-               --       95.1:generic_instantiation <= PROCEDURE name ^ IS NEW 
name SEMICOLON
-               --      103.0:name <= name ^ LEFT_PAREN range_list RIGHT_PAREN 
; ( 1 => Direct_Left,  3 => Other)
-               --      103.1:name <= name ^ actual_parameter_part ; ( 1 => 
Direct_Left,  2 => Other)
-               --      115.0:procedure_specification <= PROCEDURE name ^ 
parameter_profile_opt
-               --      124.0:selected_component <= name ^ DOT IDENTIFIER ; ( 1 
=> Other_Left)
-               --
-               --  State 50:
-               --       87.1:expression <= relation_and_list ^ ; ( 1 => 
Other_Left)
-               --      119.0:relation_and_list <= relation_and_list ^ AND 
relation ; ( 1 => Direct_Left,  3 => Other)
-               --
-               --
-               --  State 77:
-               --       57.0:actual_parameter_part <= LEFT_PAREN ^ 
association_list RIGHT_PAREN ; ( 2 => Other)
-               --      103.0:name <= name LEFT_PAREN ^ range_list RIGHT_PAREN 
; ( 1 => Direct_Left,  3 => Other)
-               --
-               --  State 154:
-               --      103.0:name <= name LEFT_PAREN range_list ^ RIGHT_PAREN
-               --      118.0:range_list <= range_list ^ COMMA range_g
-               --
-               --  State 251:
-               --      110.0:parameter_specification <= IDENTIFIER COLON 
IDENTIFIER ^ COLON_EQUAL expression_opt
-               --      110.1:parameter_specification <= IDENTIFIER COLON 
IDENTIFIER ^
-               --
-               --  From java_enum_ch19_lr1.parse_table:
-               --
-               --  State 8:
-               --       9.1:EnumConstantList <= EnumConstantList COMMA ^ 
EnumConstant ; (1 => Direct_Left, 3 => Other)
-               --      11.0:EnumBody <= LEFT_CURLY_BRACKET EnumConstantList 
COMMA ^ RIGHT_CURLY_BRACKET
-               --
-               --  From empty_production_2_lalar.parse_table:
-               --
-               --  State 5:
-               --        8.0:declarations <= declarations ^ declaration
-               --        9.0:body <= IS declarations ^ BEGIN SEMICOLON
-
-               --  case 0: In states 43 and 30, there is only one possible 
action, so
-               --  recursion is not considered. Minimal_Action is
-               --  computed by Compute_Minimal_Action, Label is Keep_Always.
-               --
-               --  In the following, we only consider kernels where there is 
more
-               --  than one item.
-               --
-               --  case 1: In state 47 production 113.2, Length_After_Dot is 
0, so
-               --  recursion is not considered. We set Label to Keep_Always, 
since
-               --  the true Length_After_Dot must be computed at runtime.
-               --  Minimal_Action is Reduce_Production.
-               --
-               --  Similarly in state 68 production 115.0, Length_After_Dot is 0
-               --  because parameter_profile_opt is nullable, and we set Label 
to
-               --  Keep_Always, Minimal_Action to Reduce_Production.
-               --
-               --  case 2: In state 47, if LEFT_PAREN or First
-               --  (actual_parameter_part) is inserted, a recursion cycle is 
followed
-               --  via 103.0 or 103.1; these have Direct_Left recursion, can 
never be
-               --  minimal, and we set Label to Drop. 113.2 breaks the 
recursion; it
-               --  has Length_After_Dot = 0 and is covered by case 1. 124.0 has
-               --  Other_Left; since Length_After_Dot is > 0, it follows the
-               --  recursion cycle and is never minimal, so it is the same as
-               --  Direct_Left. Similarly, in java_enum_ch19_lr1.parse_table 
state 8
-               --  production 9.1, inserting EnumConstant continues the 
recursion
-               --  cycle; left recursion applies even when it is not just 
before the
-               --  parse point. On the other hand, in ada_lite state 154, both
-               --  productions are left recursive; 103.0 could be preserved. 
In the
-               --  current algorithm, both are dropped.
-               --
-               --  It is possible for both case 1 and case 2 to apply; see
-               --  empty_production_2_lalar.parse_table State 5 above and
-               --  ada_lite_ebnf_lalr.parse_table state 46. case 1 has 
precedence if
-               --  Dot = No_Element.
-               --
-               --  case 3: In state 251, there is no recursion, and 
Length_After_Dot
-               --  is correct; Label is set to Keep_If_Minimal, Minimal_Action 
to
-               --  Compute_Minimal_Action. In State 77, Dot_ID is 
association_list
-               --  which has Other recursion; we say "there is recursion at 
the parse
-               --  point". However, Length_After_Dot is correct; it assumes the
-               --  recursion-breaking case for the expansion of 
association_list. So
-               --  this is the same as no recursion at the parse point
-               --
-               --  It is possible for both case 2 and 3 to be true; see
-               --  empty_production_2_lalr.parse_table state 5. Case 2 has
-               --  precedence (left recursion is worse).
-
-               if Item_States'Length = 1 then
-                  --  case 0
-                  Item_States (I) :=
-                    (Keep_Always,
-                     (if Length_After_Dot = 0
-                      then (Reduce, Reduce_Production, Reduce_Count)
-                      else Compute_Action (Dot_ID)));
-
-               elsif Length_After_Dot = 0 then
-                  if Item.Dot /= No_Index and RHS.Recursion (1) in Direct_Left 
| Other_Left then
-                     --  case 2
-                     Item_States (I) := (Label => Drop);
-                  else
-                     --  case 1
-                     Item_States (I) :=
-                       (Label          => Keep_Always,
-                        Minimal_Action => (Reduce, Reduce_Production, 
Reduce_Count));
-                  end if;
-
-               elsif RHS.Recursion (1) in Direct_Left | Other_Left then
-                  --  case 2
-                  Item_States (I) := (Label => Drop);
-
-               else
-                  --  case 3
-                  Item_States (I) := (Keep_If_Minimal, Compute_Action 
(Dot_ID));
-               end if;
-
-               State.Kernel (I) :=
-                 (Production        => Item.Prod,
-                  Before_Dot        => Before_Dot (Item),
-                  Length_After_Dot  => Length_After_Dot,
-                  Reduce_Production => Reduce_Production,
-                  Reduce_Count      => Reduce_Count);
-
-               if Item_States (I).Label = Keep_If_Minimal then
-                  if Length_After_Dot < Min_Length then
-                     Min_Length := Length_After_Dot;
-                  end if;
-               end if;
-
-               if Trace_Generate_Minimal_Complete > Extra then
-                  Ada.Text_IO.Put_Line
-                    ("kernel" & I'Image & " " & Strict_Image (State.Kernel 
(I)) &
-                       " ; " & Item_States (I).Label'Image &
-                       " " & State.Kernel (I).Length_After_Dot'Image);
-               end if;
-
-               if I < Kernel_Index'Last then
-                  I := I + 1;
-               end if;
-            end;
-         end loop;
-
-         --  It is tempting to Assert that if all items are dropped, there is a
-         --  grammar recursion cycle with no exit. But that is not true; see
-         --  java_expressions_ch19_lr1.parse_table, state 8. However, that
-         --  state should never be encountered during Insert_Minimal_Complete,
-         --  because it is never minimal. So we set Minimal_Actions to empty.
-
-         --  Update State_Items based on Min_Length
-         for I in Item_States'Range loop
-
-            case Item_States (I).Label is
-            when Unknown =>
-               null;
-
-            when Keep_Always =>
-               pragma Assert (Item_States (I).Minimal_Action.Production /= 
Invalid_Production_ID);
-
-            when Keep_If_Minimal =>
-               if State.Kernel (I).Length_After_Dot = Min_Length then
-                  null;
-               else
-                  Item_States (I) := (Label => Drop);
-               end if;
-
-            when Drop =>
-               null;
-            end case;
-         end loop;
-
-         --  Set State.Minimal_Actions
-         for Item_State of Item_States loop
-            case Item_State.Label is
-            when Unknown | Drop =>
-               null;
-
-            when Keep_Always | Keep_If_Minimal =>
-               if (for some A of State.Minimal_Complete_Actions => A = 
Item_State.Minimal_Action) then
-                  --  Duplicate action; see 
three_action_conflict_lalr.parse_table state
-                  --  3 or lalr_generator_bug_01_lalr.parse_table state 28
-                  null;
-               else
-                  pragma Assert (Item_State.Minimal_Action.Production /= 
Invalid_Production_ID);
-                  State.Minimal_Complete_Actions.Append 
(Item_State.Minimal_Action);
-               end if;
-            end case;
-         end loop;
-
-         if Trace_Generate_Minimal_Complete > Extra then
-            Ada.Text_IO.Put_Line (Image (State.Minimal_Complete_Actions, 
Descriptor));
-         end if;
-      end;
-   end Set_Minimal_Complete_Actions;
-
-   ----------
-   --  Parse table output
-
-   procedure Put_Text_Rep
-     (Table        : in Parse_Table;
-      File_Name    : in String;
-      Action_Names : in Names_Array_Array;
-      Check_Names  : in Names_Array_Array)
-   is
-      use all type SAL.Base_Peek_Type;
-      use Ada.Containers;
-      use Ada.Text_IO;
-      File : File_Type;
-   begin
-      --  Only space, semicolon, newline delimit object values. Bounds of
-      --  arrays output before each array, unless known from discriminants.
-      --  End of lists indicated by semicolon. Action, Check subprograms are
-      --  represented by True if present, False if not.
-
-      Create (File, Out_File, File_Name);
-
-      --  First the discriminants
-      Put (File,
-           Trimmed_Image (Table.State_First) & State_Index'Image 
(Table.State_Last) &
-             Token_ID'Image (Table.First_Terminal) & Token_ID'Image 
(Table.Last_Terminal) &
-             Token_ID'Image (Table.First_Nonterminal) & Token_ID'Image 
(Table.Last_Nonterminal));
-      New_Line (File);
-
-      for State of Table.States loop
-         Put (File, Trimmed_Image (State.Action_List.Length) & ' ');
-         for I in State.Action_List.First_Index .. 
State.Action_List.Last_Index loop
-            --  Action first, for historical reasons
-            declare
-               Node_I : Action_Node renames State.Action_List (I);
-               Node_J : Parse_Action_Node_Ptr := Node_I.Actions;
-            begin
-               loop
-                  Put (File, Node_J.Item.Verb'Image);
-                  Put (File, Node_J.Item.Production.LHS'Image & 
Node_J.Item.Production.RHS'Image);
-
-                  case Node_J.Item.Verb is
-                  when Shift =>
-                     Put (File, State_Index'Image (Node_J.Item.State));
-
-                  when Reduce | Accept_It =>
-                     if Action_Names (Node_J.Item.Production.LHS) /= null and 
then
-                       Action_Names 
(Node_J.Item.Production.LHS)(Node_J.Item.Production.RHS) /= null
-                     then
-                        Put (File, " true");
-                     else
-                        Put (File, " false");
-                     end if;
-                     if Check_Names (Node_J.Item.Production.LHS) /= null and 
then
-                       Check_Names 
(Node_J.Item.Production.LHS)(Node_J.Item.Production.RHS) /= null
-                     then
-                        Put (File, " true");
-                     else
-                        Put (File, " false");
-                     end if;
-
-                     Put (File, Ada.Containers.Count_Type'Image 
(Node_J.Item.Token_Count));
-
-                  when Parse.LR.Error =>
-                     raise SAL.Programmer_Error;
-                  end case;
-
-                  Node_J := Node_J.Next;
-                  exit when Node_J = null;
-                  Put (File, ' ');
-               end loop;
-               Put (File, ';');
-               Put (File, Token_ID'Image (Node_I.Symbol));
-            end;
-            if I = State.Action_List.Last_Index then
-               Put_Line (File, ";");
-            else
-               New_Line (File);
-            end if;
-         end loop;
-
-         if State.Goto_List.Length > 0 then
-            Put (File, Trimmed_Image (State.Goto_List.Length));
-            for Node of State.Goto_List loop
-               Put (File, Node.Symbol'Image & Node.State'Image);
-            end loop;
-         end if;
-         Put (File, ';');
-         New_Line (File);
-
-         if State.Kernel.Length = 0 then
-            --  Kernel not set for state 0
-            Put_Line (File, "0 -1");
-
-         else
-            Put (File, Count_Type'Image (State.Kernel.First_Index));
-            Put (File, Count_Type'Image (State.Kernel.Last_Index));
-            for Item of State.Kernel loop
-               Put (File, Token_ID'Image (Item.Production.LHS) & 
Item.Production.RHS'Image);
-               Put (File, Item.Before_Dot'Image);
-               Put (File, Count_Type'Image (Item.Length_After_Dot));
-               Put (File, Token_ID'Image (Item.Reduce_Production.LHS) & 
Item.Reduce_Production.RHS'Image);
-               Put (File, Item.Reduce_Count'Image);
-            end loop;
-            New_Line (File);
-         end if;
-
-         if State.Minimal_Complete_Actions.Length = 0 then
-            null;
-         else
-            Put (File, Count_Type'Image 
(State.Minimal_Complete_Actions.First_Index));
-            Put (File, Count_Type'Image 
(State.Minimal_Complete_Actions.Last_Index));
-            for Action of State.Minimal_Complete_Actions loop
-               Put (File, " ");
-               Put (File, Action.Verb'Image);
-               Put (File, Action.Production.LHS'Image & 
Action.Production.RHS'Image);
-               case Action.Verb is
-               when Shift =>
-                  Put (File, Token_ID'Image (Action.ID) & State_Index'Image 
(Action.State));
-               when Reduce =>
-                  Put (File, Action.Token_Count'Image);
-               end case;
-            end loop;
-         end if;
-         Put_Line (File, ";");
-      end loop;
-      Close (File);
-   end Put_Text_Rep;
-
-   procedure Put (Item : in Parse_Action_Rec; Descriptor : in 
WisiToken.Descriptor)
-   is
-      use Ada.Containers;
-      use Ada.Text_IO;
-   begin
-      case Item.Verb is
-      when Shift =>
-         Put ("shift and goto state" & State_Index'Image (Item.State));
-
-      when Reduce =>
-         Put
-           ("reduce" & Count_Type'Image (Item.Token_Count) & " tokens to " &
-              Image (Item.Production.LHS, Descriptor));
-      when Accept_It =>
-         Put ("accept it");
-      when Parse.LR.Error =>
-         Put ("ERROR");
-      end case;
-   end Put;
-
-   procedure Put (Item : in McKenzie_Param_Type; Descriptor : in 
WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("(Insert =>");
-      for I in Item.Insert'Range loop
-         Put (" " & Padded_Image (I, Descriptor) & " =>" & Natural'Image 
(Item.Insert (I)));
-         if I = Item.Insert'Last then
-            Put_Line (")");
-         else
-            Put_Line (",");
-         end if;
-      end loop;
-      Put_Line ("(Delete =>");
-      for I in Item.Delete'Range loop
-         Put (" " & Padded_Image (I, Descriptor) & " =>" & Natural'Image 
(Item.Delete (I)));
-         if I = Item.Delete'Last then
-            Put_Line (")");
-         else
-            Put_Line (",");
-         end if;
-      end loop;
-      Put_Line ("(Push_Back =>");
-      for I in Item.Push_Back'Range loop
-         Put (" " & Padded_Image (I, Descriptor) & " =>" & Natural'Image 
(Item.Push_Back (I)));
-         if I = Item.Push_Back'Last then
-            Put_Line (")");
-         else
-            Put_Line (",");
-         end if;
-      end loop;
-      Put_Line ("(Undo_Reduce =>");
-      for I in Item.Undo_Reduce'Range loop
-         Put (" " & Padded_Image (I, Descriptor) & " =>" & Natural'Image 
(Item.Undo_Reduce (I)));
-         if I = Item.Undo_Reduce'Last then
-            Put_Line (")");
-         else
-            Put_Line (",");
-         end if;
-      end loop;
-      Put_Line ("Minimal_Complete_Cost_Delta => " & Integer'Image 
(Item.Minimal_Complete_Cost_Delta));
-      Put_Line ("Fast_Forward      => " & Integer'Image (Item.Fast_Forward));
-      Put_Line ("Matching_Begin    => " & Integer'Image (Item.Matching_Begin));
-      Put_Line ("Ignore_Check_Fail =>" & Integer'Image 
(Item.Ignore_Check_Fail));
-      Put_Line ("Task_Count        =>" & 
System.Multiprocessors.CPU_Range'Image (Item.Task_Count));
-      Put_Line ("Check_Limit       =>" & Token_Index'Image (Item.Check_Limit));
-      Put_Line ("Check_Delta_Limit =>" & Integer'Image 
(Item.Check_Delta_Limit));
-      Put_Line ("Enqueue_Limit     =>" & Integer'Image (Item.Enqueue_Limit));
-   end Put;
-
-   procedure Put (Descriptor : in WisiToken.Descriptor; Item : in 
Parse_Action_Rec)
-   is
-      use Ada.Containers;
-      use Ada.Text_IO;
-   begin
-      case Item.Verb is
-      when Shift =>
-         Put ("shift and goto state" & State_Index'Image (Item.State));
-         Put (" " & Trimmed_Image (Item.Production));
-
-      when Reduce =>
-         Put
-           ("reduce" & Count_Type'Image (Item.Token_Count) & " tokens to " &
-              Image (Item.Production.LHS, Descriptor));
-         Put (" " & Trimmed_Image (Item.Production));
-
-      when Accept_It =>
-         Put ("accept it");
-         Put (" " & Trimmed_Image (Item.Production));
-
-      when Parse.LR.Error =>
-         Put ("ERROR");
-      end case;
-   end Put;
-
-   procedure Put (Descriptor : in WisiToken.Descriptor; Action : in 
Parse_Action_Node_Ptr)
-   is
-      use Ada.Text_IO;
-      Ptr    : Parse_Action_Node_Ptr   := Action;
-      Column : constant Positive_Count := Col;
-   begin
-      loop
-         Put (Descriptor, Ptr.Item);
-         Ptr := Ptr.Next;
-         exit when Ptr = null;
-         Put_Line (",");
-         Set_Col (Column);
-      end loop;
-   end Put;
-
-   procedure Put (Descriptor : in WisiToken.Descriptor; State : in Parse_State)
-   is
-      use all type Ada.Containers.Count_Type;
-      use Ada.Text_IO;
-      use Ada.Strings.Fixed;
-   begin
-      for Action of State.Action_List loop
-         Put ("   " & Image (Action.Symbol, Descriptor) &
-                (Descriptor.Image_Width - Image (Action.Symbol, 
Descriptor)'Length) * ' '
-                & " => ");
-         Put (Descriptor, Action.Actions);
-         New_Line;
-      end loop;
-
-      --  The error line is redundant, but we keep it to match existing good 
parse tables.
-      Put_Line ("   default" & (Descriptor.Image_Width - 7) * ' ' & " => 
ERROR");
-
-      if State.Goto_List.Length > 0 then
-         New_Line;
-      end if;
-
-      for Item of State.Goto_List loop
-         Put_Line
-           ("   " & Image (Item.Symbol, Descriptor) &
-              (Descriptor.Image_Width - Image (Item.Symbol, 
Descriptor)'Length) * ' ' &
-              " goto state" & Item.State'Image);
-      end loop;
-
-      New_Line;
-      Put ("   Minimal_Complete_Action => "); --  No trailing 's' for 
compatibility with previous good parse tables.
-      case State.Minimal_Complete_Actions.Length is
-      when 0 =>
-         null;
-      when 1 =>
-         --  No () here for compatibity with previous known good parse tables.
-         declare
-            Action : Minimal_Action renames State.Minimal_Complete_Actions 
(State.Minimal_Complete_Actions.First_Index);
-         begin
-            case Action.Verb is
-            when Shift =>
-               Put (Image (Action.ID, Descriptor));
-            when Reduce =>
-               Put (Image (Action.Production.LHS, Descriptor));
-            end case;
-            Put (" " & Trimmed_Image (Action.Production));
-         end;
-      when others =>
-         Put ("(");
-         for I in State.Minimal_Complete_Actions.First_Index .. 
State.Minimal_Complete_Actions.Last_Index loop
-            declare
-               Action : Minimal_Action renames State.Minimal_Complete_Actions 
(I);
-            begin
-               case Action.Verb is
-               when Shift =>
-                  Put (Image (Action.ID, Descriptor));
-               when Reduce =>
-                  Put (Image (Action.Production.LHS, Descriptor));
-               end case;
-               Put (" " & Trimmed_Image (Action.Production));
-            end;
-            if I < State.Minimal_Complete_Actions.Last_Index then
-               Put (", ");
-            end if;
-         end loop;
-         Put (")");
-      end case;
-      New_Line;
-   end Put;
-
-   procedure Put_Parse_Table
-     (Table                 : in Parse_Table_Ptr;
-      Parse_Table_File_Name : in String;
-      Title                 : in String;
-      Grammar               : in WisiToken.Productions.Prod_Arrays.Vector;
-      Recursions            : in Generate.Recursions;
-      Kernels               : in LR1_Items.Item_Set_List;
-      Conflicts             : in Conflict_Count_Lists.List;
-      Descriptor            : in WisiToken.Descriptor;
-      Include_Extra         : in Boolean := False)
-   is
-      use all type Ada.Containers.Count_Type;
-      use Ada.Text_IO;
-      Parse_Table_File : File_Type;
-   begin
-      Create (Parse_Table_File, Out_File, Parse_Table_File_Name);
-      Set_Output (Parse_Table_File);
-      Put_Line ("Tokens:");
-      WisiToken.Put_Tokens (Descriptor);
-
-      New_Line;
-      Put_Line ("Productions:");
-      WisiToken.Productions.Put (Grammar, Descriptor);
-
-      if Include_Extra then
-         New_Line;
-         Put_Line ((if Recursions.Full then "Recursions:" else "Partial 
recursions:"));
-         for I in Recursions.Recursions.First_Index .. 
Recursions.Recursions.Last_Index loop
-            Put_Line (Trimmed_Image (I) & " => " & Grammar_Graphs.Image 
(Recursions.Recursions (I)));
-         end loop;
-      end if;
-
-      if Table.McKenzie_Param.Check_Limit /= 
Default_McKenzie_Param.Check_Limit or
-        Table.McKenzie_Param.Check_Delta_Limit /= 
Default_McKenzie_Param.Check_Delta_Limit or
-        Table.McKenzie_Param.Enqueue_Limit /= 
Default_McKenzie_Param.Enqueue_Limit
-      then
-         New_Line;
-         Put_Line ("McKenzie:");
-         Put (Table.McKenzie_Param, Descriptor);
-      end if;
-
-      New_Line;
-      Put_Line (Title & " Parse Table:");
-
-      for State_Index in Table.States'Range loop
-         Put_Line ("State" & Unknown_State_Index'Image (State_Index) & ":");
-
-         declare
-            use WisiToken.Generate.LR1_Items;
-         begin
-            for Item of Kernels (State_Index).Set loop
-               if In_Kernel (Grammar, Descriptor, Item) then
-                  Put ("  " & Image (Grammar, Descriptor, Item, 
Show_Lookaheads => False));
-                  New_Line;
-               end if;
-            end loop;
-         end;
-         New_Line;
-         Put (Descriptor, Table.States (State_Index));
-
-         if State_Index /= Table.States'Last then
-            New_Line;
-         end if;
-      end loop;
-
-      if Conflicts.Length > 0 then
-         declare
-            use Ada.Strings.Unbounded;
-            Line          : Unbounded_String := +"States with conflicts:";
-            Accept_Reduce : Integer          := 0;
-            Shift_Reduce  : Integer          := 0;
-            Reduce_Reduce : Integer          := 0;
-         begin
-            for Count of Conflicts loop
-               Line          := Line & State_Index'Image (Count.State);
-               Accept_Reduce := Accept_Reduce + Count.Accept_Reduce;
-               Shift_Reduce  := Shift_Reduce + Count.Shift_Reduce;
-               Reduce_Reduce := Reduce_Reduce + Count.Reduce_Reduce;
-            end loop;
-
-            New_Line;
-            Indent_Wrap (-Line);
-
-            New_Line;
-            Put_Line
-              (Integer'Image (Accept_Reduce) & " accept/reduce conflicts," &
-                 Integer'Image (Shift_Reduce) & " shift/reduce conflicts," &
-                 Integer'Image (Reduce_Reduce) & " reduce/reduce conflicts");
-         end;
-      else
-         New_Line;
-         Put_Line (" 0 accept/reduce conflicts, 0 shift/reduce conflicts, 0 
reduce/reduce conflicts");
-      end if;
-      Set_Output (Standard_Output);
-      Close (Parse_Table_File);
-   end Put_Parse_Table;
-
-end WisiToken.Generate.LR;
diff --git a/packages/wisi/wisitoken-generate-lr.ads 
b/packages/wisi/wisitoken-generate-lr.ads
deleted file mode 100644
index 00257fe..0000000
--- a/packages/wisi/wisitoken-generate-lr.ads
+++ /dev/null
@@ -1,214 +0,0 @@
---  Abstract :
---
---  Common utilities for LR parser table generators.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with WisiToken.Generate.LR1_Items;
-with WisiToken.Parse.LR;
-with WisiToken.Productions;
-package WisiToken.Generate.LR is
-   use WisiToken.Parse.LR;
-
-   subtype Conflict_Parse_Actions is Parse_Action_Verbs range Shift .. 
Accept_It;
-   type Conflict is record
-      --  A typical conflict is:
-      --
-      --  SHIFT/REDUCE in state: 11 on token IS
-      --
-      --  State numbers change with minor changes in the grammar, so we
-      --  attempt to identify the state by the LHS of the two productions
-      --  involved; this is _not_ guarranteed to be unique, but is good
-      --  enough for our purposes. We also store the state number for
-      --  generated conflicts (not for known conflicts from the grammar
-      --  definition file), for debugging.
-      Action_A    : Conflict_Parse_Actions;
-      LHS_A       : Token_ID;
-      Action_B    : Conflict_Parse_Actions;
-      LHS_B       : Token_ID;
-      State_Index : Unknown_State_Index;
-      On          : Token_ID;
-   end record;
-
-   package Conflict_Lists is new Ada.Containers.Doubly_Linked_Lists (Conflict);
-
-   type Conflict_Count is record
-      State : State_Index;
-      Accept_Reduce : Integer             := 0;
-      Shift_Reduce  : Integer             := 0;
-      Reduce_Reduce : Integer             := 0;
-   end record;
-
-   package Conflict_Count_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Conflict_Count);
-
-   procedure Put
-     (Item       : in Conflict_Lists.List;
-      File       : in Ada.Text_IO.File_Type;
-      Descriptor : in WisiToken.Descriptor);
-
-   procedure Add_Action
-     (Symbol               : in     Token_ID;
-      Action               : in     Parse_Action_Rec;
-      Action_List          : in out Action_Arrays.Vector;
-      Closure              : in     LR1_Items.Item_Set;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Descriptor           : in     WisiToken.Descriptor);
-   --  Add (Symbol, Action) to Action_List; check for conflicts
-   --
-   --  Closure .. Conflicts are for conflict reporting
-
-   procedure Add_Actions
-     (Closure              : in     LR1_Items.Item_Set;
-      Table                : in out Parse_Table;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Descriptor           : in     WisiToken.Descriptor);
-   --  Add actions for Closure to Table. Has_Empty_Production, First,
-   --  Conflicts used for conflict reporting.
-
-   procedure Add_Lookahead_Actions
-     (Item                 : in     LR1_Items.Item;
-      Action_List          : in out Action_Arrays.Vector;
-      Grammar              : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in     Token_ID_Set;
-      First_Nonterm_Set    : in     Token_Array_Token_Set;
-      Conflict_Counts      : in out Conflict_Count_Lists.List;
-      Conflicts            : in out Conflict_Lists.List;
-      Closure              : in     LR1_Items.Item_Set;
-      Descriptor           : in     WisiToken.Descriptor);
-   --  Add actions for Item.Lookaheads to Action_List
-   --  Closure must be from the item set containing Item.
-   --  Has_Empty_Production .. Closure used for conflict reporting.
-
-   procedure Delete_Known
-     (Conflicts       : in out Conflict_Lists.List;
-      Known_Conflicts : in out Conflict_Lists.List);
-   --  Delete Known_Conflicts from Conflicts.
-
-   function Find
-     (Closure              : in LR1_Items.Item_Set;
-      Action               : in Parse_Action_Rec;
-      Lookahead            : in Token_ID;
-      Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First                : in Token_Array_Token_Set;
-      Descriptor           : in WisiToken.Descriptor)
-     return Token_ID;
-   --  Return the LHS of a production in kernel of Closure, for an Action
-   --  conflict on Lookahead; for naming a Conflict object.
-
-   function Image (Item : in Conflict; Descriptor : in WisiToken.Descriptor) 
return String;
-
-   function Is_Present (Item : in Conflict; Conflicts : in 
Conflict_Lists.List) return Boolean;
-
-   function Match (Known : in Conflict; Item : in 
Conflict_Lists.Constant_Reference_Type) return Boolean;
-
-   ----------
-   --  Minimal terminal sequences.
-
-   package RHS_Sequence_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Natural, Token_ID_Arrays.Vector, Default_Element => 
Token_ID_Arrays.Empty_Vector);
-
-   function Image is new RHS_Sequence_Arrays.Gen_Image_Aux (Descriptor, 
Trimmed_Image, Image_No_Assoc);
-
-   function Min_Length (Item : in RHS_Sequence_Arrays.Vector) return 
Ada.Containers.Count_Type;
-   --  Return minimum length of elements of Item.
-
-   function Min (Item : in RHS_Sequence_Arrays.Vector) return 
Token_ID_Arrays.Vector;
-   --  Return element of Item with minimum length;
-
-   type Minimal_Sequence_Item is record
-      Min_RHS  : Natural := Natural'Last;
-      Sequence : RHS_Sequence_Arrays.Vector;
-   end record;
-
-   type Minimal_Sequence_Array is array (Token_ID range <>) of 
Minimal_Sequence_Item;
-
-   function Compute_Minimal_Terminal_Sequences
-     (Descriptor : in WisiToken.Descriptor;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector)
-     return Minimal_Sequence_Array;
-   --  For each production in Grammar, compute the minimal sequence of
-   --  terminals that will complete it. Result is an empty sequence if
-   --  the production may be empty.
-
-   function Compute_Minimal_Terminal_First
-     (Descriptor                 : in WisiToken.Descriptor;
-      Minimal_Terminal_Sequences : in Minimal_Sequence_Array)
-      return Token_Array_Token_ID;
-   --  For each nonterminal in Grammar, return the first of the minimal
-   --  sequence of terminals that will complete it; Invalid_Token_ID if
-   --  the minimal sequence is empty.
-
-   procedure Set_Minimal_Complete_Actions
-     (State                      : in out Parse_State;
-      Kernel                     : in     LR1_Items.Item_Set;
-      Descriptor                 : in     WisiToken.Descriptor;
-      Grammar                    : in     
WisiToken.Productions.Prod_Arrays.Vector;
-      Nullable                   : in     Token_Array_Production_ID;
-      Minimal_Terminal_Sequences : in     Minimal_Sequence_Array;
-      Minimal_Terminal_First     : in     Token_Array_Token_ID);
-   --  Set State.Minimal_Complete_Actions to the set of actions that will
-   --  most quickly complete the productions in Kernel (which must be for
-   --  State). Useful in error correction.
-   --
-   --  The Minimal_Complete_Actions will be empty in a state where there
-   --  is nothing useful to do; the accept state, or one where all
-   --  productions are recursive.
-   --
-   --  Also set State.Kernels; used to resolve multiple reduce actions at
-   --  runtime.
-
-   ----------
-   --  Parse table output
-
-   procedure Put_Text_Rep
-     (Table        : in Parse_Table;
-      File_Name    : in String;
-      Action_Names : in Names_Array_Array;
-      Check_Names  : in Names_Array_Array);
-   --  Write machine-readable text format of Table.States to a file
-   --  File_Name, to be read by the parser executable at startup, using
-   --  WisiToken.Parse.LR.Get_Text_Rep.
-
-   procedure Put (Item : in Parse_Action_Rec; Descriptor : in 
WisiToken.Descriptor);
-   procedure Put (Item : in McKenzie_Param_Type; Descriptor : in 
WisiToken.Descriptor);
-   procedure Put (Descriptor : in WisiToken.Descriptor; Item : in 
Parse_Action_Rec);
-   procedure Put (Descriptor : in WisiToken.Descriptor; Action : in 
Parse_Action_Node_Ptr);
-   procedure Put (Descriptor : in WisiToken.Descriptor; State : in 
Parse_State);
-   --  Put Item to Ada.Text_IO.Current_Output in parse table format.
-
-   procedure Put_Parse_Table
-     (Table                 : in Parse_Table_Ptr;
-      Parse_Table_File_Name : in String;
-      Title                 : in String;
-      Grammar               : in WisiToken.Productions.Prod_Arrays.Vector;
-      Recursions            : in Generate.Recursions;
-      Kernels               : in LR1_Items.Item_Set_List;
-      Conflicts             : in Conflict_Count_Lists.List;
-      Descriptor            : in WisiToken.Descriptor;
-      Include_Extra         : in Boolean := False);
-   --  "Extra" is recursions.
-
-end WisiToken.Generate.LR;
diff --git a/packages/wisi/wisitoken-generate-lr1_items.adb 
b/packages/wisi/wisitoken-generate-lr1_items.adb
deleted file mode 100644
index 37e6f0e..0000000
--- a/packages/wisi/wisitoken-generate-lr1_items.adb
+++ /dev/null
@@ -1,553 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2002, 2003, 2008, 2009, 2012 - 2015, 2017 - 2020 Free 
Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO;
-with Ada.Strings.Unbounded;
-package body WisiToken.Generate.LR1_Items is
-   use type Ada.Strings.Unbounded.Unbounded_String;
-
-   ----------
-   --  body subprograms
-
-   function Get_Dot_IDs
-     (Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-      Set        : in Item_Lists.List;
-      Descriptor : in WisiToken.Descriptor)
-     return Token_ID_Arrays.Vector
-   is
-      use Item_Lists;
-      IDs : Token_ID_Set (Descriptor.First_Terminal .. 
Descriptor.Last_Nonterminal) := (others => False);
-   begin
-      for Item of Set loop
-         declare
-            use Token_ID_Arrays;
-            Dot : constant Token_ID_Arrays.Cursor :=
-              WisiToken.Productions.Constant_Ref_RHS (Grammar, 
Item.Prod).Tokens.To_Cursor (Item.Dot);
-         begin
-            if Has_Element (Dot) then
-               if Element (Dot) /= Descriptor.EOI_ID then
-                  IDs (Element (Dot)) := True;
-               end if;
-            end if;
-         end;
-      end loop;
-      return To_Array (IDs);
-   end Get_Dot_IDs;
-
-   function Merge
-     (Prod         : in     Production_ID;
-      Dot          : in     Token_ID_Arrays.Extended_Index;
-      Lookaheads   : in     Lookahead;
-      Existing_Set : in out Item_Set)
-     return Boolean
-   is
-      --  Merge item into Existing_Set. Return True if Existing_Set
-      --  is modified.
-
-      use Item_Lists;
-
-      Found    : constant Item_Lists.Cursor := Find (Prod, Dot, Existing_Set);
-      Modified : Boolean                    := False;
-   begin
-      if not Has_Element (Found) then
-         Existing_Set.Set.Insert ((Prod, Dot, new Token_ID_Set'(Lookaheads)));
-
-         Modified := True;
-      else
-         Include (Variable_Ref (Found), Lookaheads, Modified);
-      end if;
-
-      return Modified;
-   end Merge;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   function To_Lookahead (Item : in Token_ID; Descriptor : in 
WisiToken.Descriptor) return Lookahead
-   is begin
-      return Result : Token_ID_Set := (Descriptor.First_Terminal .. 
Descriptor.Last_Lookahead => False) do
-         Result (Item) := True;
-      end return;
-   end To_Lookahead;
-
-   function Lookahead_Image (Item : in Lookahead; Descriptor : in 
WisiToken.Descriptor) return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String := Null_Unbounded_String;
-   begin
-      for I in Item'Range loop
-         if Item (I) then
-            if Length (Result) > 0 then
-               Result := Result & "/";
-            end if;
-            Result := Result & Image (I, Descriptor);
-         end if;
-      end loop;
-      return To_String (Result);
-   end Lookahead_Image;
-
-   function Item_Compare (Left, Right : in Item) return SAL.Compare_Result
-     is (if Left.Prod.LHS > Right.Prod.LHS then SAL.Greater
-         elsif Left.Prod.LHS < Right.Prod.LHS then SAL.Less
-         elsif Left.Prod.RHS > Right.Prod.RHS then SAL.Greater
-         elsif Left.Prod.RHS < Right.Prod.RHS then SAL.Less
-         elsif Left.Dot > Right.Dot then SAL.Greater
-         elsif Left.Dot < Right.Dot then SAL.Less
-         else SAL.Equal);
-
-   procedure Include
-     (Item  : in out LR1_Items.Item;
-      Value : in     Lookahead;
-      Added :    out Boolean)
-   is begin
-      Added := False;
-
-      for I in Item.Lookaheads'Range loop
-         if Value (I) then
-            Added := Added or not Item.Lookaheads (I);
-            Item.Lookaheads (I) := True;
-         end if;
-      end loop;
-   end Include;
-
-   procedure Include
-     (Item       : in out LR1_Items.Item;
-      Value      : in     Lookahead;
-      Descriptor : in     WisiToken.Descriptor)
-   is
-      Added : Boolean;
-      pragma Unreferenced (Added);
-   begin
-      Include (Item, Value, Added, Descriptor);
-   end Include;
-
-   procedure Include
-     (Item       : in out LR1_Items.Item;
-      Value      : in     Lookahead;
-      Added      :    out Boolean;
-      Descriptor : in     WisiToken.Descriptor)
-   is begin
-      Added := False;
-
-      for I in Item.Lookaheads'Range loop
-         if I = Descriptor.Last_Lookahead then
-            null;
-         else
-            if Value (I) then
-               Added := Added or not Item.Lookaheads (I);
-               Item.Lookaheads (I) := True;
-            end if;
-         end if;
-      end loop;
-   end Include;
-
-   function Filter
-     (Set        : in     Item_Set;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor;
-      Include    : access function
-        (Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-         Descriptor : in WisiToken.Descriptor;
-         Item       : in LR1_Items.Item)
-        return Boolean)
-     return Item_Set
-   is begin
-      return Result : Item_Set := (Set => <>, Goto_List => Set.Goto_List, 
Dot_IDs => Set.Dot_IDs, State => Set.State)
-      do
-         for Item of Set.Set loop
-            if Include (Grammar, Descriptor, Item) then
-               Result.Set.Insert (Item);
-            end if;
-         end loop;
-      end return;
-   end Filter;
-
-   function In_Kernel
-     (Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor;
-      Item       : in LR1_Items.Item)
-     return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-      use Token_ID_Arrays;
-      Prod : WisiToken.Productions.Instance renames Grammar (Item.Prod.LHS);
-      RHS  : WisiToken.Productions.Right_Hand_Side renames Prod.RHSs 
(Item.Prod.RHS);
-   begin
-      return
-        RHS.Tokens.Length > 0 and
-        (Item.Dot = No_Index or else
-           ((Prod.LHS = Descriptor.Accept_ID and
-               Item.Dot = RHS.Tokens.First_Index)
-              -- Start symbol production with dot before first token.
-              or
-              Item.Dot /= RHS.Tokens.First_Index));
-   end In_Kernel;
-
-   function Find
-     (Item : in LR1_Items.Item;
-      Set  : in Item_Set)
-     return Item_Lists.Cursor
-   is begin
-      return Find (Item.Prod, Item.Dot, Set);
-   end Find;
-
-   function Find
-     (Prod : in Production_ID;
-      Dot : in Token_ID_Arrays.Extended_Index;
-      Set  : in Item_Set)
-     return Item_Lists.Cursor
-   is begin
-      return Set.Set.Find ((Prod, Dot, null));
-   end Find;
-
-   function To_Item_Set_Tree_Key
-     (Item_Set           : in LR1_Items.Item_Set;
-      Include_Lookaheads : in Boolean)
-     return Item_Set_Tree_Key
-   is
-      use Interfaces;
-      use Item_Lists;
-      Cur : Item_Lists.Cursor := Item_Set.Set.First;
-   begin
-      return Result : Item_Set_Tree_Key do
-         Result.Append (Integer_16 (Item_Set.Set.Length));
-         --  Int_Arrays."<" compares length, but only after everything else; we
-         --  want it to compare first, since it is most likely to be different.
-
-         loop
-            exit when not Has_Element (Cur);
-            declare
-               Item_1 : Item renames Item_Set.Set (Cur);
-            begin
-               Result.Append (Integer_16 (Item_1.Prod.LHS));
-               Result.Append (Integer_16 (Item_1.Prod.RHS));
-               Result.Append (Integer_16 (Item_1.Dot));
-               if Include_Lookaheads then
-                  for ID in Item_1.Lookaheads'Range loop
-                     if Item_1.Lookaheads (ID) then
-                        Result.Append (Integer_16 (ID));
-                     end if;
-                  end loop;
-               end if;
-            end;
-            Next (Cur);
-         end loop;
-      end return;
-   end To_Item_Set_Tree_Key;
-
-   function Find
-     (New_Item_Set     : in Item_Set;
-      Item_Set_Tree    : in Item_Set_Trees.Tree;
-      Match_Lookaheads : in Boolean)
-     return Unknown_State_Index
-   is
-      use all type Item_Set_Trees.Cursor;
-
-      Tree_It    : constant Item_Set_Trees.Iterator := Item_Set_Trees.Iterate 
(Item_Set_Tree);
-      Key        : constant Item_Set_Tree_Key       := To_Item_Set_Tree_Key
-        (New_Item_Set, Include_Lookaheads => Match_Lookaheads);
-      Found_Tree : constant Item_Set_Trees.Cursor   := Tree_It.Find (Key);
-   begin
-      if Found_Tree = Item_Set_Trees.No_Element then
-         return Unknown_State;
-      else
-         return Item_Set_Tree (Found_Tree).State;
-      end if;
-   end Find;
-
-   procedure Add
-     (Grammar            : in     WisiToken.Productions.Prod_Arrays.Vector;
-      New_Item_Set       : in     Item_Set;
-      Item_Set_Vector    : in out Item_Set_List;
-      Item_Set_Tree      : in out Item_Set_Trees.Tree;
-      Descriptor         : in     WisiToken.Descriptor;
-      Include_Lookaheads : in     Boolean)
-   is
-      use Item_Set_Trees;
-      Key : constant Item_Set_Tree_Key := To_Item_Set_Tree_Key (New_Item_Set, 
Include_Lookaheads);
-   begin
-      Item_Set_Vector.Append (New_Item_Set);
-      Item_Set_Vector (Item_Set_Vector.Last_Index).Dot_IDs := Get_Dot_IDs 
(Grammar, New_Item_Set.Set, Descriptor);
-      Item_Set_Tree.Insert ((Key, New_Item_Set.State));
-   end Add;
-
-   function Is_In
-     (Item      : in Goto_Item;
-      Goto_List : in Goto_Item_Lists.List)
-     return Boolean
-   is begin
-      for List_Item of Goto_List loop
-         if List_Item = Item then
-            return True;
-         end if;
-      end loop;
-
-      return False;
-   end Is_In;
-
-   function Goto_State
-     (From   : in Item_Set;
-      Symbol : in Token_ID)
-     return Unknown_State_Index
-   is begin
-      for Item of From.Goto_List loop
-         if Item.Symbol = Symbol then
-            return Item.State;
-         end if;
-      end loop;
-
-      return Unknown_State;
-   end Goto_State;
-
-   function Closure
-     (Set                     : in Item_Set;
-      Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return Item_Set
-   is
-      use all type Item_Lists.Cursor;
-      use Token_ID_Arrays;
-
-      --  [dragon] algorithm 4.9 pg 231; figure 4.38 pg 232; procedure 
"closure"
-      --
-      --  Taken literally, the algorithm modifies its input; we make a
-      --  copy instead.
-
-      I : Item_Set := Set; --  The result.
-
-      Item_I     : Item_Lists.Cursor := I.Set.First; -- iterator 'for each 
item in I'
-      Added_Item : Boolean := False;  -- 'until no more items can be added'
-   begin
-      loop
-         declare
-            Item : LR1_Items.Item renames I.Set (Item_I);
-            Dot  : constant Token_ID_Arrays.Cursor :=
-              WisiToken.Productions.Constant_Ref_RHS (Grammar, 
Item.Prod).Tokens.To_Cursor (Item.Dot);
-         begin
-            --  An item has the structure [A -> alpha Dot B Beta, a].
-            --
-            --  If B is a nonterminal, find its productions and place
-            --  them in the set with lookaheads from FIRST(Beta a).
-            if Has_Element (Dot) and then
-              Element (Dot) in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal
-            then
-               declare
-                  Prod : WisiToken.Productions.Instance renames Grammar 
(Element (Dot));
-               begin
-                  For_Each_RHS :
-                  for J in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-                     declare
-                        RHS  : WisiToken.Productions.Right_Hand_Side renames 
Prod.RHSs (J);
-                        P_ID : constant Production_ID := (Prod.LHS, J);
-                        Beta : Token_ID_Arrays.Cursor := Next (Dot); -- tokens 
after nonterminal, possibly null
-                     begin
-                        --  Compute FIRST (<tail of right hand side> a); loop
-                        --  until find a terminal, a nonterminal that
-                        --  cannot be empty, or end of production, adding
-                        --  items on the way.
-
-                        First_Tail :
-                        loop
-                           if not Has_Element (Beta) then
-                              --  Use FIRST (a); a = Item.Lookaheads.
-                              --  Lookaheads are all terminals, so
-                              --  FIRST (a) = a.
-                              Added_Item := Added_Item or
-                                Merge (P_ID, To_Index (RHS.Tokens.First), 
Item.Lookaheads.all, I);
-                              exit First_Tail;
-
-                           elsif Element (Beta) in Descriptor.First_Terminal 
.. Descriptor.Last_Terminal then
-                              --  FIRST (Beta) = Beta
-                              Added_Item := Added_Item or Merge
-                                (P_ID, To_Index (RHS.Tokens.First), 
To_Lookahead (Element (Beta), Descriptor), I);
-                              exit First_Tail;
-
-                           else
-                              --  Beta is a nonterminal; use FIRST (Beta)
-                              for Terminal of First_Terminal_Sequence (Element 
(Beta)) loop
-                                 Added_Item := Added_Item or
-                                   Merge (P_ID, To_Index (RHS.Tokens.First), 
To_Lookahead (Terminal, Descriptor), I);
-                              end loop;
-
-                              if Has_Empty_Production (Element (Beta)) then
-                                 --  Process the next token in the tail, or "a"
-                                 Beta := Next (Beta);
-                              else
-                                 exit First_Tail;
-                              end if;
-                           end if;
-                        end loop First_Tail;
-                     end;
-                  end loop For_Each_RHS;
-               end;
-            end if; -- Dot is at non-terminal
-         end;
-
-         if not Has_Element (Item_Lists.Next (Item_I)) then
-            exit when not Added_Item;
-
-            Item_I := I.Set.First;
-            Added_Item := False;
-
-            if Trace_Generate_Table > Extra then
-               Ada.Text_IO.Put_Line ("  closure:");
-               Put (Grammar, Descriptor, I);
-            end if;
-         else
-            Item_I := Item_Lists.Next (Item_I);
-         end if;
-      end loop;
-
-      return I;
-   end Closure;
-
-   function Productions (Set : in Item_Set) return Production_ID_Arrays.Vector
-   is begin
-      return Result : Production_ID_Arrays.Vector do
-         for Item of Set.Set loop
-            Result.Append (Item.Prod);
-         end loop;
-      end return;
-   end Productions;
-
-   function Image
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in LR1_Items.Item;
-      Show_Lookaheads : in Boolean)
-     return String
-   is
-      use Token_ID_Arrays;
-
-      Prod   : WisiToken.Productions.Instance renames Grammar (Item.Prod.LHS);
-      RHS    : WisiToken.Productions.Right_Hand_Side renames Prod.RHSs 
(Item.Prod.RHS);
-      Result : Ada.Strings.Unbounded.Unbounded_String :=
-        +Padded_Image (Item.Prod, Width => Prod_ID_Image_Width) & ":" & Image 
(Prod.LHS, Descriptor) & " <=";
-
-      I : Cursor := RHS.Tokens.First;
-   begin
-      while Has_Element (I) loop
-         if To_Index (I) = Item.Dot then
-            Result := Result & " ^ ";
-         else
-            Result := Result & " ";
-         end if;
-         Result := Result & Image (Element (I), Descriptor);
-         Next (I);
-      end loop;
-
-      if Item.Dot = No_Index then
-         Result := Result & " ^";
-      end if;
-
-      if Show_Lookaheads then
-         Result := Result & ", " & Lookahead_Image (Item.Lookaheads.all, 
Descriptor);
-      end if;
-
-      return Ada.Strings.Unbounded.To_String (Result);
-   end Image;
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in LR1_Items.Item;
-      Show_Lookaheads : in Boolean := True)
-   is begin
-      Ada.Text_IO.Put (Image (Grammar, Descriptor, Item, Show_Lookaheads => 
Show_Lookaheads));
-   end Put;
-
-   procedure Put
-     (Descriptor : in WisiToken.Descriptor;
-      List       : in Goto_Item_Lists.List)
-   is
-      use Ada.Text_IO;
-   begin
-      for Item of List loop
-         Put_Line
-           ("      on " & Image (Item.Symbol, Descriptor) &
-              " => State" & Unknown_State_Index'Image (Item.State));
-      end loop;
-   end Put;
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Lists.List;
-      Show_Lookaheads : in Boolean := True;
-      Kernel_Only     : in Boolean := False)
-   is begin
-      for It of Item loop
-         if not Kernel_Only or else
-           In_Kernel (Grammar, Descriptor, It)
-         then
-            Ada.Text_IO.Put_Line
-              ("  " & Image (Grammar, Descriptor, It, Show_Lookaheads => 
Show_Lookaheads));
-         end if;
-      end loop;
-   end Put;
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Set;
-      Show_Lookaheads : in Boolean := True;
-      Kernel_Only     : in Boolean := False;
-      Show_Goto_List  : in Boolean := False)
-   is
-      use Ada.Text_IO;
-   begin
-      if Item.State /= Unknown_State then
-         Put_Line ("State" & Unknown_State_Index'Image (Item.State) & ":");
-      end if;
-
-      Put (Grammar, Descriptor, Item.Set, Show_Lookaheads, Kernel_Only);
-
-      if Show_Goto_List then
-         Put (Descriptor, Item.Goto_List);
-      end if;
-   end Put;
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Set_List;
-      Show_Lookaheads : in Boolean := True)
-   is
-      use Ada.Text_IO;
-   begin
-      for Set of Item loop
-         Put (Grammar, Descriptor, Set, Show_Lookaheads);
-         Put_Line ("   Goto:");
-         Put (Descriptor, Set.Goto_List);
-      end loop;
-   end Put;
-
-end WisiToken.Generate.LR1_Items;
diff --git a/packages/wisi/wisitoken-generate-lr1_items.ads 
b/packages/wisi/wisitoken-generate-lr1_items.ads
deleted file mode 100644
index 43e2939..0000000
--- a/packages/wisi/wisitoken-generate-lr1_items.ads
+++ /dev/null
@@ -1,335 +0,0 @@
---  Abstract :
---
---  Types and operatorion for LR(1) items.
---
---  Copyright (C) 2003, 2008, 2013 - 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Interfaces;
-with SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
-with SAL.Gen_Unbounded_Definite_Red_Black_Trees;
-with SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable;
-with WisiToken.Productions;
-package WisiToken.Generate.LR1_Items is
-
-   use all type Interfaces.Integer_16;
-
-   subtype Lookahead is Token_ID_Set;
-   --  Picking a type for Lookahead is not straight-forward. The
-   --  operations required are (called numbers are for LR1 generate
-   --  ada_lite):
-   --
-   --  to_lookahead (token_id)
-   --     Requires allocating memory dynamically:
-   --        an unconstrained array range (first_terminal .. last_terminal) 
for (1),
-   --        a smaller unconstrained array for (2), that grows as items are 
added
-   --        individual list elements for (3).
-   --
-   --     lr1_items.to_lookahead        called 4_821_256 times in (2)
-   --     sorted_token_id_lists.to_list called 4_821_256 times in (3)
-   --
-   --  for tok_id of lookaheads loop
-   --     sorted_token_id_lists__iterate called 5_687 times in (3)
-   --
-   --  if lookaheads.contains (tok_id) then
-   --     token_id_arrays__contains called 22_177_109 in (2)
-   --
-   --  new_item := (... , lookaheads => old_item.lookaheads)
-   --  new_item := (... , lookaheads => null_lookaheads)
-   --  new_item := (... , lookaheads => propagate_lookahead)
-   --     token_id_arrays.adjust called 8_437_967 times in (2)
-   --     sorted_token_id_lists.adjust  8_435_797 times in (3)
-   --
-   --  include: add tok_id to lookaheads
-   --
-   --      keep sorted in token_id order, so rest of algorithm is
-   --      stable/faster
-   --
-   --      lr1_items.include called 6_818_725 times in (2)
-   --
-   --  lookaheads /= lookaheads
-   --     if using a container, container must override "="
-   --
-   --  We've tried:
-   --
-   --  (1) Token_ID_Set (unconstrained array of boolean, allocated directly) - 
fastest
-   --
-   --     Allocates more memory than (2), but everything else is fast,
-   --     and it's not enough memory to matter.
-   --
-   --     Loop over lookaheads is awkward:
-   --     for tok_id in lookaheads'range loop
-   --        if lookaheads (tok_id) then
-   --           ...
-   --     But apparently it's fast enough.
-   --
-   --  (2) Instantiation of SAL.Gen_Unbounded_Definite_Vectors 
(token_id_arrays) - slower than (1).
-   --
-   --      Productions RHS is also token_id_arrays, so gprof numbers are
-   --      hard to sort out. Could be improved with a custom container, that
-   --      does sort and insert internally. Insert is inherently slow.
-   --
-   --  (3) Instantiation of SAL.Gen_Definite_Doubly_Linked_Lists_Sorted - 
slower than (2)
-
-   type Item is record
-      Prod       : Production_ID;
-      Dot        : Token_ID_Arrays.Extended_Index := Token_ID_Arrays.No_Index; 
-- token after item Dot
-      Lookaheads : Token_ID_Set_Access := null;
-      --  Programmer must remember to copy Item.Lookaheads.all, not
-      --  Item.Lookaheads. Wrapping this in Ada.Finalization.Controlled
-      --  would just slow it down.
-      --
-      --  We don't free Lookaheads; we assume the user is running
-      --  wisi-generate, and not keeping LR1_Items around.
-   end record;
-
-   function To_Lookahead (Item : in Token_ID; Descriptor : in 
WisiToken.Descriptor) return Lookahead;
-
-   function Contains (Item : in Lookahead; ID : in Token_ID) return Boolean
-     is (Item (ID));
-
-   function Lookahead_Image (Item : in Lookahead; Descriptor : in 
WisiToken.Descriptor) return String;
-   --  Returns the format used in parse table output.
-
-   function Image
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in LR1_Items.Item;
-      Show_Lookaheads : in Boolean)
-     return String;
-
-   function Item_Compare (Left, Right : in Item) return SAL.Compare_Result;
-   --  Sort Item_Lists in ascending order of Prod.Nonterm, Prod.RHS, Dot;
-   --  ignores Lookaheads.
-   --
-   --  In an LALR kernel there can be only one Item with Prod, but that
-   --  is not true in an Item_Set produced by Closure.
-
-   package Item_Lists is new SAL.Gen_Definite_Doubly_Linked_Lists_Sorted 
(Item, Item_Compare);
-
-   procedure Include
-     (Item  : in out LR1_Items.Item;
-      Value : in     Lookahead;
-      Added :    out Boolean);
-   --  Add Value to Item.Lookahead, if not already present.
-   --
-   --  Added is True if Value was not already present.
-   --
-   --  Does not exclude Propagate_ID.
-
-   procedure Include
-     (Item       : in out LR1_Items.Item;
-      Value      : in     Lookahead;
-      Descriptor : in     WisiToken.Descriptor);
-   --  Add Value to Item.Lookahead. Does not check if already present.
-   --  Excludes Propagate_ID.
-
-   procedure Include
-     (Item       : in out LR1_Items.Item;
-      Value      : in     Lookahead;
-      Added      :    out Boolean;
-      Descriptor : in     WisiToken.Descriptor);
-   --  Add Value to Item.Lookahead.
-
-   type Goto_Item is record
-      Symbol : Token_ID;
-      --  If Symbol is a terminal, this is a shift and goto state action.
-      --  If Symbol is a non-terminal, this is a post-reduce goto state action.
-      State  : State_Index;
-   end record;
-
-   function Goto_Item_Compare (Left, Right : in Goto_Item) return 
SAL.Compare_Result is
-     (if Left.Symbol > Right.Symbol then SAL.Greater
-      elsif Left.Symbol < Right.Symbol then SAL.Less
-      else SAL.Equal);
-   --  Sort Goto_Item_Lists in ascending order of Symbol.
-
-   package Goto_Item_Lists is new SAL.Gen_Definite_Doubly_Linked_Lists_Sorted
-     (Goto_Item, Goto_Item_Compare);
-
-   type Item_Set is record
-      Set       : Item_Lists.List;
-      Goto_List : Goto_Item_Lists.List;
-      Dot_IDs   : Token_ID_Arrays.Vector;
-      State     : Unknown_State_Index := Unknown_State;
-   end record;
-
-   function Filter
-     (Set        : in     Item_Set;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor;
-      Include    : access function
-        (Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-         Descriptor : in WisiToken.Descriptor;
-         Item       : in LR1_Items.Item)
-        return Boolean)
-     return Item_Set;
-   --  Return a deep copy of Set, including only items for which Include 
returns True.
-
-   function In_Kernel
-     (Grammar    : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor;
-      Item       : in LR1_Items.Item)
-     return Boolean;
-   --  For use with Filter; [dragon] sec 4.7 pg 240
-
-   function Find
-     (Item : in LR1_Items.Item;
-      Set  : in Item_Set)
-     return Item_Lists.Cursor;
-   --  Return an item from Set that matches Item.Prod, Item.Dot.
-   --
-   --  Return No_Element if not found.
-
-   function Find
-     (Prod : in Production_ID;
-      Dot : in Token_ID_Arrays.Extended_Index;
-      Set  : in Item_Set)
-     return Item_Lists.Cursor;
-   --  Return an item from Set that matches Prod, Dot.
-   --
-   --  Return No_Element if not found.
-
-   package Item_Set_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (State_Index, Item_Set, Default_Element => (others => <>));
-   subtype Item_Set_List is Item_Set_Arrays.Vector;
-
-   package Int_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive, Interfaces.Integer_16, Default_Element => 
Interfaces.Integer_16'Last);
-   function Compare_Integer_16 (Left, Right : in Interfaces.Integer_16) return 
SAL.Compare_Result is
-     (if Left > Right then SAL.Greater
-      elsif Left < Right then SAL.Less
-      else SAL.Equal);
-
-   package Int_Arrays_Comparable is new Int_Arrays.Gen_Comparable 
(Compare_Integer_16);
-
-   subtype Item_Set_Tree_Key is Int_Arrays_Comparable.Vector;
-   --  We want a key that is fast to compare, and has enough info to
-   --  significantly speed the search for an item set. So we convert all
-   --  relevant data in an item into a string of integers. We need 16 bit
-   --  because Ada token_ids max is 332. LR1 keys include lookaheads,
-   --  LALR keys do not.
-
-   type Item_Set_Tree_Node is record
-      Key   : Item_Set_Tree_Key;
-      State : Unknown_State_Index;
-   end record;
-
-   function To_Item_Set_Tree_Key
-     (Item_Set           : in LR1_Items.Item_Set;
-      Include_Lookaheads : in Boolean)
-     return Item_Set_Tree_Key;
-
-   function To_Item_Set_Tree_Key (Node : in Item_Set_Tree_Node) return 
Item_Set_Tree_Key is
-     (Node.Key);
-
-   package Item_Set_Trees is new SAL.Gen_Unbounded_Definite_Red_Black_Trees
-     (Element_Type => Item_Set_Tree_Node,
-      Key_Type     => Item_Set_Tree_Key,
-      Key          => To_Item_Set_Tree_Key,
-      Key_Compare  => Int_Arrays_Comparable.Compare);
-   --  Item_Set_Arrays.Vector holds state item sets indexed by state, for
-   --  iterating in state order. Item_Set_Trees.Tree holds lists of state
-   --  indices sorted by LR1 item info, for fast Find in LR1_Item_Sets
-   --  and LALR_Kernels.
-
-   function Find
-     (New_Item_Set     : in Item_Set;
-      Item_Set_Tree    : in Item_Set_Trees.Tree;
-      Match_Lookaheads : in Boolean)
-     return Unknown_State_Index;
-   --  Return the State of an element in Item_Set_Tree matching
-   --  New_Item_Set, Unknown_State if not found.
-   --
-   --  Match_Lookaheads is True in LR1_Generate.
-
-   procedure Add
-     (Grammar            : in     WisiToken.Productions.Prod_Arrays.Vector;
-      New_Item_Set       : in     Item_Set;
-      Item_Set_Vector    : in out Item_Set_List;
-      Item_Set_Tree      : in out Item_Set_Trees.Tree;
-      Descriptor         : in     WisiToken.Descriptor;
-      Include_Lookaheads : in     Boolean);
-   --  Set New_Item_Set.Dot_IDs, add New_Item_Set to Item_Set_Vector, 
Item_Set_Tree
-
-   function Is_In
-     (Item      : in Goto_Item;
-      Goto_List : in Goto_Item_Lists.List)
-     return Boolean;
-   --  Return True if a goto on Symbol to State is found in Goto_List
-
-   function Goto_State
-     (From   : in Item_Set;
-      Symbol : in Token_ID)
-     return Unknown_State_Index;
-   --  Return state from From.Goto_List where the goto symbol is
-   --  Symbol; Unknown_State if not found.
-
-   function Closure
-     (Set                     : in Item_Set;
-      Has_Empty_Production    : in Token_ID_Set;
-      First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
-      Grammar                 : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor              : in WisiToken.Descriptor)
-     return Item_Set;
-   --  Return the closure of Set over Grammar. First must be the
-   --  result of First above. Makes a deep copy of Goto_List.
-   --  Implements 'closure' from [dragon] algorithm 4.9 pg 232, but
-   --  allows merging lookaheads into one item..
-
-   function Productions (Set : in Item_Set) return Production_ID_Arrays.Vector;
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in LR1_Items.Item;
-      Show_Lookaheads : in Boolean := True);
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Lists.List;
-      Show_Lookaheads : in Boolean := True;
-      Kernel_Only     : in Boolean := False);
-
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Set;
-      Show_Lookaheads : in Boolean := True;
-      Kernel_Only     : in Boolean := False;
-      Show_Goto_List  : in Boolean := False);
-
-   procedure Put
-     (Descriptor : in WisiToken.Descriptor;
-      List       : in Goto_Item_Lists.List);
-   procedure Put
-     (Grammar         : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor      : in WisiToken.Descriptor;
-      Item            : in Item_Set_List;
-      Show_Lookaheads : in Boolean := True);
-   --  Put Item to Ada.Text_IO.Standard_Output. Does not end with New_Line.
-
-end WisiToken.Generate.LR1_Items;
diff --git a/packages/wisi/wisitoken-generate-packrat.adb 
b/packages/wisi/wisitoken-generate-packrat.adb
deleted file mode 100644
index c50b1ed..0000000
--- a/packages/wisi/wisitoken-generate-packrat.adb
+++ /dev/null
@@ -1,247 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Generate.Packrat is
-
-   function Potential_Direct_Right_Recursive
-     (Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
-      Empty   : in Token_ID_Set)
-     return Token_ID_Set
-   is
-      subtype Nonterminal is Token_ID range Grammar.First_Index .. 
Grammar.Last_Index;
-   begin
-      return Result : Token_ID_Set (Nonterminal) := (others => False) do
-         for Prod of Grammar loop
-            RHS_Loop :
-            for RHS of Prod.RHSs loop
-               ID_Loop :
-               for I in reverse RHS.Tokens.First_Index + 1 .. 
RHS.Tokens.Last_Index loop
-                  declare
-                     ID : constant Token_ID := RHS.Tokens (I);
-                  begin
-                     if ID = Prod.LHS then
-                        Result (ID) := True;
-                        exit RHS_Loop;
-                     elsif not (ID in Nonterminal) then
-                        exit ID_Loop;
-                     elsif not Empty (ID) then
-                        exit ID_Loop;
-                     end if;
-                  end;
-               end loop ID_Loop;
-            end loop RHS_Loop;
-         end loop;
-      end return;
-   end Potential_Direct_Right_Recursive;
-
-   procedure Indirect_Left_Recursive (Data : in out Packrat.Data)
-   is
-   begin
-      for Prod_I of Data.Grammar loop
-         for Prod_J of Data.Grammar loop
-            Data.Involved (Prod_I.LHS, Prod_J.LHS) :=
-              Data.First (Prod_I.LHS, Prod_J.LHS) and
-              Data.First (Prod_J.LHS, Prod_I.LHS);
-         end loop;
-      end loop;
-   end Indirect_Left_Recursive;
-
-   ----------
-   --  Public subprograms
-
-   function Initialize
-     (Source_File_Name : in String;
-      Grammar          : in WisiToken.Productions.Prod_Arrays.Vector;
-      Source_Line_Map  : in Productions.Source_Line_Maps.Vector;
-      First_Terminal   : in Token_ID)
-     return Packrat.Data
-   is
-      Empty : constant Token_ID_Set := WisiToken.Generate.Has_Empty_Production 
(Grammar);
-   begin
-      return Result : Packrat.Data :=
-        (First_Terminal        => First_Terminal,
-         First_Nonterminal     => Grammar.First_Index,
-         Last_Nonterminal      => Grammar.Last_Index,
-         Source_File_Name      => +Source_File_Name,
-         Grammar               => Grammar,
-         Source_Line_Map       => Source_Line_Map,
-         Empty                 => Empty,
-         Direct_Left_Recursive => Potential_Direct_Left_Recursive (Grammar, 
Empty),
-         First                 => WisiToken.Generate.First (Grammar, Empty, 
First_Terminal => First_Terminal),
-         Involved              => (others => (others => False)))
-      do
-         Indirect_Left_Recursive (Result);
-      end return;
-   end Initialize;
-
-   procedure Check_Recursion (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor)
-   is
-      Right_Recursive : constant Token_ID_Set := 
Potential_Direct_Right_Recursive (Data.Grammar, Data.Empty);
-   begin
-      for Prod of Data.Grammar loop
-         if Data.Direct_Left_Recursive (Prod.LHS) and Right_Recursive 
(Prod.LHS) then
-            --  We only implement the simplest left recursion solution ([warth
-            --  2008] figure 3); [tratt 2010] section 6.3 gives this condition 
for
-            --  that to be valid.
-            --  FIXME: not quite? definite direct right recursive ok?
-            --  FIXME: for indirect left recursion, need potential indirect 
right recursive check?
-            Put_Error
-              (Error_Message
-                 (-Data.Source_File_Name, Data.Source_Line_Map 
(Prod.LHS).Line, "'" & Image (Prod.LHS, Descriptor) &
-                    "' is both left and right recursive; not supported."));
-         end if;
-
-         for I in Data.Involved'Range (2) loop
-            if Prod.LHS /= I and then Data.Involved (Prod.LHS, I) then
-               Put_Error
-                 (Error_Message
-                    (-Data.Source_File_Name, Data.Source_Line_Map 
(Prod.LHS).Line, "'" & Image (Prod.LHS, Descriptor) &
-                       "' is indirect recursive with " & Image (I, Descriptor) 
& ", not supported"));
-            end if;
-         end loop;
-      end loop;
-   end Check_Recursion;
-
-   procedure Check_RHS_Order (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      for Prod of Data.Grammar loop
-         --  Empty must be last
-         for I in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index - 1 loop
-            if Prod.RHSs (I).Tokens.Length = 0 then
-               Put_Error
-                 (Error_Message
-                    (-Data.Source_File_Name, Data.Source_Line_Map 
(Prod.LHS).RHS_Map (I),
-                     "right hand side" & Integer'Image (I) & " in " & Image 
(Prod.LHS, Descriptor) &
-                       " is empty, but not last; no later right hand side will 
match."));
-               WisiToken.Generate.Error := True;
-            end if;
-         end loop;
-
-         for I in Prod.RHSs.First_Index + 1 .. Prod.RHSs.Last_Index loop
-            declare
-               Cur : Token_ID_Arrays.Vector renames Prod.RHSs (I).Tokens;
-            begin
-               --  Shared prefix; longer must be first
-               for J in Prod.RHSs.First_Index .. I - 1 loop
-                  declare
-                     Prev : Token_ID_Arrays.Vector renames Prod.RHSs 
(J).Tokens;
-                     K    : constant Natural := Shared_Prefix (Prev, Cur);
-                  begin
-                     if K > 0 and Prev.Length < Cur.Length then
-                        Put_Error
-                          (Error_Message
-                             (-Data.Source_File_Name, Data.Source_Line_Map 
(Prod.LHS).RHS_Map (I),
-                              "right hand side" & Integer'Image (I) & " in " & 
Image (Prod.LHS, Descriptor) &
-                                " may never match; it shares a prefix with a 
shorter previous rhs" &
-                                Integer'Image (J) & "."));
-                     end if;
-                  end;
-               end loop;
-
-               --  recursion; typical LALR list is written:
-               --
-               --  statement_list
-               --    : statement
-               --    | statement_list statement
-               --    ;
-               --  association_list
-               --    : association
-               --    | association_list COMMA association
-               --    ;
-               --
-               --  a different recursive definition:
-               --
-               --  name
-               --    : IDENTIFIER
-               --    | name LEFT_PAREN range_list RIGHT_PAREN
-               --    | name actual_parameter_part
-               --    ...
-               --    ;
-               --
-               --  For packrat, the recursive RHSs must come before others:
-               --
-               --  statement_list
-               --    : statement_list statement
-               --    | statement
-               --    ;
-               --  association_list
-               --    : association_list COMMA association
-               --    | association
-               --    ;
-               --  name
-               --    : name LEFT_PAREN range_list RIGHT_PAREN
-               --    | name actual_parameter_part
-               --    | IDENTIFIER
-               --    ...
-               --    ;
-               declare
-                  Prev : Token_ID_Arrays.Vector renames Prod.RHSs (I - 
1).Tokens;
-               begin
-                  if Cur.Length > 0 and then Prev.Length > 0 and then
-                    Cur (1) = Prod.LHS and then Prev (1) /= Prod.LHS
-                  then
-                     Put_Error
-                       (Error_Message
-                          (-Data.Source_File_Name, Data.Source_Line_Map 
(Prod.LHS).Line,
-                           "recursive right hand sides must be before 
others."));
-                  end if;
-               end;
-            end;
-         end loop;
-      end loop;
-   end Check_RHS_Order;
-
-   procedure Check_All (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor)
-   is begin
-      Check_Recursion (Data, Descriptor);
-      Check_RHS_Order (Data, Descriptor);
-   end Check_All;
-
-   function Potential_Direct_Left_Recursive
-     (Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
-      Empty   : in Token_ID_Set)
-     return Token_ID_Set
-   is
-      subtype Nonterminal is Token_ID range Grammar.First_Index .. 
Grammar.Last_Index;
-   begin
-      --  FIXME: this duplicates the computation of First; if keep First,
-      --  change this to use it.
-      return Result : Token_ID_Set (Nonterminal) := (others => False) do
-         for Prod of Grammar loop
-            RHS_Loop :
-            for RHS of Prod.RHSs loop
-               ID_Loop :
-               for ID of RHS.Tokens loop
-                  if ID = Prod.LHS then
-                     Result (ID) := True;
-                     exit RHS_Loop;
-                  elsif not (ID in Nonterminal) then
-                     exit ID_Loop;
-                  elsif not Empty (ID) then
-                     exit ID_Loop;
-                  end if;
-               end loop ID_Loop;
-            end loop RHS_Loop;
-         end loop;
-      end return;
-   end Potential_Direct_Left_Recursive;
-
-end WisiToken.Generate.Packrat;
diff --git a/packages/wisi/wisitoken-generate-packrat.ads 
b/packages/wisi/wisitoken-generate-packrat.ads
deleted file mode 100644
index 17bf03e..0000000
--- a/packages/wisi/wisitoken-generate-packrat.ads
+++ /dev/null
@@ -1,75 +0,0 @@
---  Abstract :
---
---  Types and operations for computing grammar properties used in
---  generating a packrat parser.
---
---  We use the terminology in [tratt 2010] for recursion in
---  productions.
---
---  References :
---
---  See wisitoken-parse-packrat.ads.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package WisiToken.Generate.Packrat is
-
-   type Data (First_Terminal, First_Nonterminal, Last_Nonterminal : Token_ID) 
is tagged
-   record
-      --  Data needed to check a grammar and generate code. Tagged to allow
-      --  Object.Method syntax. Descriptor not included to avoid duplicating
-      --  lots of discriminants.
-      Source_File_Name      : Ada.Strings.Unbounded.Unbounded_String;
-      Grammar               : WisiToken.Productions.Prod_Arrays.Vector;
-      Source_Line_Map       : Productions.Source_Line_Maps.Vector;
-      Empty                 : Token_ID_Set (First_Nonterminal .. 
Last_Nonterminal);
-      Direct_Left_Recursive : Token_ID_Set (First_Nonterminal .. 
Last_Nonterminal);
-      First                 : Token_Array_Token_Set
-        (First_Nonterminal .. Last_Nonterminal, First_Terminal .. 
Last_Nonterminal);
-      Involved              : Token_Array_Token_Set
-        (First_Nonterminal .. Last_Nonterminal, First_Nonterminal .. 
Last_Nonterminal);
-   end record;
-
-   function Initialize
-     (Source_File_Name : in String;
-      Grammar          : in WisiToken.Productions.Prod_Arrays.Vector;
-      Source_Line_Map  : in Productions.Source_Line_Maps.Vector;
-      First_Terminal   : in Token_ID)
-     return Packrat.Data;
-
-   procedure Check_Recursion (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor);
-   --  Check that any rule recursion present is supported.
-
-   procedure Check_RHS_Order (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor);
-   --  For each production, check that right hand sides that share
-   --  prefixes have the longest right hand side first, and that any
-   --  empty right hand side is last.
-   --
-   --  Violations output a message to Ada.Text_IO.Standard_Error, and
-   --  set WisiToken.Generate.Error True.
-
-   procedure Check_All  (Data : in Packrat.Data; Descriptor : in 
WisiToken.Descriptor);
-   --  Run all the above checks.
-   --
-   --  Note that WisiToken.Generate.Check_Consistent is run in
-   --  wisi-gen_generate_utils.To_Grammar.
-
-   function Potential_Direct_Left_Recursive
-     (Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
-      Empty   : in Token_ID_Set)
-     return Token_ID_Set;
-
-end WisiToken.Generate.Packrat;
diff --git a/packages/wisi/wisitoken-generate.adb 
b/packages/wisi/wisitoken-generate.adb
deleted file mode 100644
index c14077d..0000000
--- a/packages/wisi/wisitoken-generate.adb
+++ /dev/null
@@ -1,665 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Directories;
-with Ada.Real_Time;
-with Ada.Strings.Fixed;
-with Ada.Text_IO;
-package body WisiToken.Generate is
-
-   function Error_Message
-     (File_Name : in String;
-      File_Line : in Line_Number_Type;
-      Message   : in String)
-     return String
-   is
-      use Ada.Directories;
-      use Ada.Strings.Fixed;
-      use Ada.Strings;
-   begin
-      return Simple_Name (File_Name) & ":" &
-        Trim (Line_Number_Type'Image (File_Line), Left) & ":0: " & Message;
-   end Error_Message;
-
-   procedure Put_Error (Message : in String)
-   is begin
-      Error := True;
-      Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, Message);
-   end Put_Error;
-
-   procedure Check_Consistent
-     (Grammar          : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor       : in WisiToken.Descriptor;
-      Source_File_Name : in String)
-   is begin
-      if Descriptor.Accept_ID /= Descriptor.First_Nonterminal then
-         Put_Error
-           (Error_Message
-              (Source_File_Name, Line_Number_Type'First,
-               "Descriptor.Accept_ID /= Descriptor.First_Nonterminal"));
-      end if;
-      if Grammar.First_Index /= Descriptor.First_Nonterminal then
-         Put_Error
-           (Error_Message
-              (Source_File_Name, Line_Number_Type'First,
-               "Grammar.First_Index /= Descriptor.First_Nonterminal"));
-      end if;
-      if Grammar.Last_Index /= Descriptor.Last_Nonterminal then
-         Put_Error
-           (Error_Message
-              (Source_File_Name, Line_Number_Type'First,
-               "Grammar.Last_Index /= Descriptor.Last_Nonterminal"));
-      end if;
-
-      for Nonterm in Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal loop
-         if Grammar (Nonterm).LHS /= Nonterm then
-            Put_Error
-              (Error_Message
-                 (Source_File_Name, Line_Number_Type'First,
-                  "Grammar (" & Image (Nonterm, Descriptor) & ").LHS = " &
-                    Image (Grammar (Nonterm).LHS, Descriptor) & " /= " &
-                    Image (Nonterm, Descriptor)));
-         end if;
-      end loop;
-   end Check_Consistent;
-
-   function Check_Unused_Tokens
-     (Descriptor : in WisiToken.Descriptor;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector)
-     return Boolean
-   is
-      subtype Terminals    is Token_ID range Descriptor.First_Terminal    .. 
Descriptor.Last_Terminal;
-      subtype Nonterminals is Token_ID range Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal;
-
-      Used_Tokens : Token_ID_Set := (Descriptor.First_Terminal .. 
Descriptor.Last_Nonterminal => False);
-
-      Changed        : Boolean := False;
-      Abort_Generate : Boolean := False;
-      Unused_Tokens  : Boolean := False;
-   begin
-      Used_Tokens (Descriptor.Accept_ID) := True;
-
-      --  First mark all nonterminals that occur in used nonterminals as
-      --  used.
-      loop
-         for Prod of Grammar loop
-            if Used_Tokens (Prod.LHS) then
-               for RHS of Prod.RHSs loop
-                  for J of RHS.Tokens loop
-                     if J in Nonterminals then
-                        Changed         := Changed or else not Used_Tokens (J);
-                        Used_Tokens (J) := True;
-                     end if;
-                  end loop;
-               end loop;
-            end if;
-         end loop;
-         exit when not Changed;
-         Changed := False;
-      end loop;
-
-      --  Now mark terminals used in used nonterminals
-      for Prod of Grammar loop
-         if Used_Tokens (Prod.LHS) then
-            for RHS of Prod.RHSs loop
-               for J of RHS.Tokens loop
-                  if not (J in Used_Tokens'Range) then
-                     WisiToken.Generate.Put_Error
-                       ("non-grammar token " & Image (J, Descriptor) & " used 
in grammar");
-
-                     --  This causes lots of problems with token_id not in 
terminal or
-                     --  nonterminal range, so abort early.
-                     Abort_Generate := True;
-                  end if;
-
-                  if J in Terminals then
-                     Used_Tokens (J) := True;
-                  end if;
-               end loop;
-            end loop;
-         end if;
-      end loop;
-
-      for I in Used_Tokens'Range loop
-         if not Used_Tokens (I) then
-            if not Unused_Tokens then
-               WisiToken.Generate.Put_Error ("Unused tokens:");
-               Unused_Tokens := True;
-            end if;
-            WisiToken.Generate.Put_Error (Image (I, Descriptor));
-         end if;
-      end loop;
-
-      if Abort_Generate then
-         raise Grammar_Error;
-      end if;
-
-      return Unused_Tokens;
-   end Check_Unused_Tokens;
-
-   function Nullable (Grammar : in WisiToken.Productions.Prod_Arrays.Vector) 
return Token_Array_Production_ID
-   is
-      use all type Ada.Containers.Count_Type;
-
-      subtype Nonterminal is Token_ID range Grammar.First_Index .. 
Grammar.Last_Index;
-
-      Result  : Token_Array_Production_ID := (Nonterminal => 
Invalid_Production_ID);
-      Changed : Boolean                   := True;
-   begin
-      loop
-         exit when not Changed;
-         Changed := False;
-
-         for Prod of Grammar loop
-            if Result (Prod.LHS) = Invalid_Production_ID then
-               for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index 
loop
-                  declare
-                     RHS : WisiToken.Productions.Right_Hand_Side renames 
Prod.RHSs (RHS_Index);
-                  begin
-                     if RHS.Tokens.Length = 0 or else
-                       (RHS.Tokens (1) in Nonterminal and then Result 
(RHS.Tokens (1)) /= Invalid_Production_ID)
-                     then
-                        Result (Prod.LHS) := (Prod.LHS, RHS_Index);
-                        Changed := True;
-                     end if;
-                  end;
-               end loop;
-            end if;
-         end loop;
-      end loop;
-      return Result;
-   end Nullable;
-
-   function Has_Empty_Production (Nullable : in Token_Array_Production_ID) 
return Token_ID_Set
-   is begin
-      return Result : Token_ID_Set := (Nullable'First .. Nullable'Last => 
False) do
-         for I in Result'Range loop
-            Result (I) := Nullable (I) /= Invalid_Production_ID;
-         end loop;
-      end return;
-   end Has_Empty_Production;
-
-   function Has_Empty_Production (Grammar : in 
WisiToken.Productions.Prod_Arrays.Vector) return Token_ID_Set
-   is
-      use all type Ada.Containers.Count_Type;
-
-      subtype Nonterminal is Token_ID range Grammar.First_Index .. 
Grammar.Last_Index;
-
-      Result  : Token_ID_Set := (Nonterminal => False);
-      Changed : Boolean      := True;
-   begin
-      loop
-         exit when not Changed;
-         Changed := False;
-
-         for Prod of Grammar loop
-            for RHS of Prod.RHSs loop
-               if (RHS.Tokens.Length = 0 or else
-                     (RHS.Tokens (1) in Nonterminal and then Result 
(RHS.Tokens (1)))) and
-                 not Result (Prod.LHS)
-               then
-                  Result (Prod.LHS) := True;
-                  Changed := True;
-               end if;
-            end loop;
-         end loop;
-      end loop;
-      return Result;
-   end Has_Empty_Production;
-
-   function First
-     (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First_Terminal       : in Token_ID;
-      Non_Terminal         : in Token_ID)
-     return Token_ID_Set
-   is
-      Search_Tokens : Token_ID_Set := (Grammar.First_Index .. 
Grammar.Last_Index => False);
-   begin
-      Search_Tokens (Non_Terminal) := True;
-
-      return Derivations : Token_ID_Set := (First_Terminal .. 
Grammar.Last_Index => False) do
-         while Any (Search_Tokens) loop
-            declare
-               Added_Tokens   : Token_ID_Set := (First_Terminal .. 
Grammar.Last_Index      => False);
-               Added_Nonterms : Token_ID_Set := (Grammar.First_Index .. 
Grammar.Last_Index => False);
-            begin
-               for Prod of Grammar loop
-                  if Search_Tokens (Prod.LHS) then
-                     for RHS of Prod.RHSs loop
-                        for Derived_Token of RHS.Tokens loop
-                           if not Derivations (Derived_Token) then
-                              Added_Tokens (Derived_Token) := True;
-                              if Derived_Token in Added_Nonterms'Range then
-                                 Added_Nonterms (Derived_Token) := True;
-                              end if;
-                           end if;
-
-                           if Derived_Token in Has_Empty_Production'Range and 
then
-                             Has_Empty_Production (Derived_Token)
-                           then
-                              null;
-                           else
-                              exit;
-                           end if;
-                        end loop;
-                     end loop;
-                  end if;
-               end loop;
-               Derivations   := Derivations or Added_Tokens;
-               Search_Tokens := Added_Nonterms;
-            end;
-         end loop;
-      end return;
-   end First;
-
-   function First
-     (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First_Terminal       : in Token_ID)
-     return Token_Array_Token_Set
-   is
-      Matrix : Token_Array_Token_Set :=
-        (Grammar.First_Index .. Grammar.Last_Index =>
-           (First_Terminal .. Grammar.Last_Index => False));
-
-      procedure Set_Slice (Matrix : in out Token_Array_Token_Set; I : 
Token_ID; Value : in Token_ID_Set)
-      is begin
-         for J in Matrix'Range (2) loop
-            Matrix (I, J) := Value (J);
-         end loop;
-      end Set_Slice;
-
-   begin
-      for NT_Index in Matrix'Range loop
-         Set_Slice (Matrix, NT_Index, First (Grammar, Has_Empty_Production, 
First_Terminal, NT_Index));
-      end loop;
-
-      return Matrix;
-   end First;
-
-   function To_Terminal_Sequence_Array
-     (First      : in Token_Array_Token_Set;
-      Descriptor : in WisiToken.Descriptor)
-     return Token_Sequence_Arrays.Vector
-   is
-      subtype Terminal is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-   begin
-      return Result : Token_Sequence_Arrays.Vector do
-         Result.Set_First_Last (First'First (1), First'Last (1));
-
-         for I in First'Range (1) loop
-            declare
-               Row : Token_ID_Arrays.Vector renames Result (I);
-            begin
-               for J in First'Range (2) loop
-                  if First (I, J) and then J in Terminal then
-                     Row.Append (J);
-                  end if;
-               end loop;
-            end;
-         end loop;
-      end return;
-   end To_Terminal_Sequence_Array;
-
-   function Follow
-     (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor           : in WisiToken.Descriptor;
-      First                : in Token_Array_Token_Set;
-      Has_Empty_Production : in Token_ID_Set)
-     return Token_Array_Token_Set
-   is
-      subtype Terminal    is Token_ID range Descriptor.First_Terminal    .. 
Descriptor.Last_Terminal;
-      subtype Nonterminal is Token_ID range Descriptor.First_Nonterminal .. 
Descriptor.Last_Nonterminal;
-
-      Prev_Result : Token_Array_Token_Set := (Nonterminal => (Terminal => 
False));
-      Result      : Token_Array_Token_Set := (Nonterminal => (Terminal => 
False));
-
-      ID : Token_ID;
-   begin
-      --  [dragon] pgp 189:
-      --
-      --  Rule 1 Follow (S, EOF) = True; EOF is explicit in the
-      --  start symbol production, so this is covered by Rule 2.
-      --
-      --  Rule 2: If A => alpha B Beta, add First (Beta) to Follow (B)
-      --
-      --  Rule 3; if A => alpha B, or A -> alpha B Beta and Beta
-      --  can be null, add Follow (A) to Follow (B)
-      --
-      --  We don't assume any order in the productions list, so we
-      --  have to keep applying rule 3 until nothing changes.
-
-      for B in Nonterminal loop
-         for Prod of Grammar loop
-            for A of Prod.RHSs loop
-               for I in A.Tokens.First_Index .. A.Tokens.Last_Index loop
-                  if A.Tokens (I) = B then
-                     if I < A.Tokens.Last_Index then
-                        --  Rule 1
-                        ID := A.Tokens (1 + I);
-                        if ID in Terminal then
-                           Result (B, ID) := True;
-                        else
-                           Or_Slice (Result, B, Slice (First, ID));
-                        end if;
-                     end if;
-                  end if;
-               end loop;
-            end loop;
-         end loop;
-      end loop;
-
-      Prev_Result := Result;
-      loop
-         for B in Nonterminal loop
-            for Prod of Grammar loop
-               for A of Prod.RHSs loop
-                  for I in A.Tokens.First_Index .. A.Tokens.Last_Index loop
-                     if A.Tokens (I) = B then
-                        if I = A.Tokens.Last_Index or else
-                          (A.Tokens (1 + I) in Nonterminal and then
-                             Has_Empty_Production (A.Tokens (1 + I)))
-                        then
-                           --  rule 3
-                           Or_Slice (Result, B, Slice (Result, Prod.LHS));
-                        end if;
-                     end if;
-                  end loop;
-               end loop;
-            end loop;
-         end loop;
-
-         exit when Prev_Result = Result;
-         Prev_Result := Result;
-      end loop;
-      return Result;
-   end Follow;
-
-   function To_Graph (Grammar : in WisiToken.Productions.Prod_Arrays.Vector) 
return Grammar_Graphs.Graph
-   is
-      subtype Nonterminals is Token_ID range Grammar.First_Index .. 
Grammar.Last_Index;
-      Graph : Grammar_Graphs.Graph;
-      J     : Integer := 1;
-   begin
-      if Trace_Generate_Minimal_Complete > Outline then
-         Ada.Text_IO.Put_Line ("grammar graph:");
-      end if;
-
-      for LHS in Grammar.First_Index .. Grammar.Last_Index loop
-         declare
-            Prod : WisiToken.Productions.Instance renames Grammar (LHS);
-         begin
-            for RHS in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-               declare
-                  Tokens : Token_ID_Arrays.Vector renames Prod.RHSs 
(RHS).Tokens;
-               begin
-                  for I in Tokens.First_Index .. Tokens.Last_Index loop
-                     if Tokens (I) in Nonterminals then
-                        if Trace_Generate_Minimal_Complete > Detail then
-                           Ada.Text_IO.Put_Line
-                             ("(" & Trimmed_Image (LHS) & ", " & Trimmed_Image 
(Tokens (I)) & ","  & J'Image & ")");
-                           J := J + 1;
-                        end if;
-                        Graph.Add_Edge (LHS, Tokens (I), (RHS, I));
-                     end if;
-                  end loop;
-               end;
-            end loop;
-         end;
-      end loop;
-
-      if Trace_Generate_Minimal_Complete > Outline then
-         Ada.Text_IO.Put_Line ("..." & Graph.Count_Nodes'Image & " nodes" & 
Graph.Count_Edges'Image & " edges.");
-      end if;
-      return Graph;
-   end To_Graph;
-
-   function Recursion
-     (LHS         : in Token_ID;
-      Token_Index : in Positive;
-      Tokens      : in Token_ID_Arrays.Vector)
-     return Recursion_Class
-   is begin
-      return
-        (if Token_Index = Tokens.First_Index then
-           (if LHS = Tokens (Tokens.First_Index)
-            then Direct_Left
-            else Other_Left)
-         elsif Token_Index = Tokens.Last_Index then
-           (if LHS = Tokens (Tokens.Last_Index)
-            then Direct_Right
-            else Other_Right)
-         else Other);
-   end Recursion;
-
-   procedure Set_Grammar_Recursions
-     (Recursions : in     WisiToken.Generate.Recursions;
-      Grammar    : in out WisiToken.Productions.Prod_Arrays.Vector)
-   is begin
-      for LHS of Grammar loop
-         for RHS of LHS.RHSs loop
-            RHS.Recursion.Set_First_Last (RHS.Tokens.First_Index, 
RHS.Tokens.Last_Index);
-         end loop;
-      end loop;
-
-      for Path of Recursions.Recursions loop
-         declare
-            use WisiToken.Productions;
-            Previous_Item_LHS : Token_ID :=
-              (if Recursions.Full then Path (Path'Last).Vertex else 
Token_ID'Last);
-         begin
-            for Item of Path loop
-               for Edge of Item.Edges loop
-                  declare
-                     LHS : constant Token_ID := (if Recursions.Full then 
Previous_Item_LHS else Item.Vertex);
-                     RHS : Right_Hand_Side renames Grammar (LHS).RHSs 
(Edge.Data.RHS);
-                  begin
-                     RHS.Recursion (Edge.Data.Token_Index) := Recursion
-                       (LHS         => LHS,
-                        Token_Index => Edge.Data.Token_Index,
-                        Tokens      => RHS.Tokens);
-                  end;
-               end loop;
-               Previous_Item_LHS := Item.Vertex;
-            end loop;
-         end;
-      end loop;
-   end Set_Grammar_Recursions;
-
-   function Compute_Full_Recursion
-     (Grammar    : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor)
-     return Recursions
-   is
-      Time_Start : constant Ada.Real_Time.Time := Ada.Real_Time.Clock;
-
-      Graph : constant Grammar_Graphs.Graph := To_Graph (Grammar);
-   begin
-      return Result : Recursions :=
-        (Full       => True,
-         Recursions => Graph.Find_Cycles)
-      do
-         Grammar_Graphs.Sort_Paths.Sort (Result.Recursions);
-
-         Set_Grammar_Recursions (Result, Grammar);
-
-         if Trace_Time then
-            declare
-               use Ada.Real_Time;
-               Time_End : constant Time := Clock;
-            begin
-               Ada.Text_IO.Put_Line
-                 (Ada.Text_IO.Standard_Error, "compute partial recursion 
time:" &
-                    Duration'Image (To_Duration (Time_End - Time_Start)));
-            end;
-         end if;
-
-         if Trace_Generate_Minimal_Complete > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Productions:");
-            WisiToken.Productions.Put (Grammar, Descriptor);
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("full recursions:");
-            for I in Result.Recursions.First_Index .. 
Result.Recursions.Last_Index loop
-               Ada.Text_IO.Put_Line (Trimmed_Image (I) & " => " & 
Grammar_Graphs.Image (Result.Recursions (I)));
-            end loop;
-         end if;
-      end return;
-   end Compute_Full_Recursion;
-
-   function Compute_Partial_Recursion
-     (Grammar    : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor)
-     return Recursions
-   is
-      use Grammar_Graphs;
-      Time_Start : constant Ada.Real_Time.Time := Ada.Real_Time.Clock;
-
-      Graph      : constant Grammar_Graphs.Graph := To_Graph (Grammar);
-      Components : constant Component_Lists.List := 
Strongly_Connected_Components
-        (To_Adjancency (Graph), Non_Trivial_Only => True);
-      Loops      : constant Vertex_Lists.List    := Graph.Loops;
-   begin
-      return Result : Recursions do
-         Result.Full := False;
-         for Comp of Components loop
-            declare
-               Path : Recursion_Cycle (1 .. Integer (Comp.Length));
-               Last : Integer := Path'First - 1;
-            begin
-               for V of Comp loop
-                  Last := Last + 1;
-                  Path (Last) := (V, Graph.Edges (V));
-               end loop;
-               Result.Recursions.Append (Path);
-            end;
-         end loop;
-
-         declare
-            Path : Recursion_Cycle (1 .. Integer (Loops.Length));
-            Last : Integer := Path'First - 1;
-         begin
-            for V of Loops loop
-               Last := Last + 1;
-               Path (Last) := (V, Graph.Edges (V));
-            end loop;
-            Result.Recursions.Append (Path);
-         end;
-
-         Set_Grammar_Recursions (Result, Grammar);
-
-         if Trace_Time then
-            declare
-               use Ada.Real_Time;
-               Time_End : constant Time := Clock;
-            begin
-               Ada.Text_IO.Put_Line
-                 (Ada.Text_IO.Standard_Error, "compute full recursion time:" &
-                    Duration'Image (To_Duration (Time_End - Time_Start)));
-            end;
-         end if;
-
-         if Trace_Generate_Minimal_Complete > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Productions:");
-            WisiToken.Productions.Put (Grammar, Descriptor);
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("partial recursions:");
-            for I in Result.Recursions.First_Index .. 
Result.Recursions.Last_Index loop
-               Ada.Text_IO.Put_Line (Trimmed_Image (I) & " => " & 
Grammar_Graphs.Image (Result.Recursions (I)));
-            end loop;
-         end if;
-      end return;
-   end Compute_Partial_Recursion;
-
-   ----------
-   --  Indented text output
-
-   procedure Indent_Line (Text : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Set_Col (Indent);
-      Put_Line (Text);
-      Line_Count := Line_Count + 1;
-   end Indent_Line;
-
-   procedure Indent_Start (Text : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Set_Col (Indent);
-      Put (Text);
-   end Indent_Start;
-
-   procedure Indent_Wrap (Text : in String)
-   is
-      use all type Ada.Text_IO.Count;
-      use Ada.Strings;
-      use Ada.Strings.Fixed;
-      I     : Natural;
-      First : Integer := Text'First;
-   begin
-      if Text'Length + Indent <= Max_Line_Length then
-         Indent_Line (Text);
-      else
-         loop
-            I := Text'Last;
-            loop
-               I := Index (Text (First .. Text'Last), " ", From => I, Going => 
Backward);
-               exit when I - First + Integer (Indent) <= Max_Line_Length;
-               I := I - 1;
-            end loop;
-            Indent_Line (Trim (Text (First .. I - 1), Right));
-            First := I + 1;
-            exit when Text'Last - First + Integer (Indent) <= Max_Line_Length;
-         end loop;
-         Indent_Line (Text (First .. Text'Last));
-      end if;
-   end Indent_Wrap;
-
-   procedure Indent_Wrap_Comment (Text : in String; Comment_Syntax : in String)
-   is
-      use all type Ada.Text_IO.Count;
-      use Ada.Strings;
-      use Ada.Strings.Fixed;
-      Prefix : constant String := Comment_Syntax & "  ";
-      I      : Natural;
-      First  : Integer         := Text'First;
-   begin
-      if Text'Length + Indent <= Max_Line_Length - 4 then
-         Indent_Line (Prefix & Text);
-      else
-         loop
-            I := Text'Last;
-            loop
-               I := Index (Text (First .. Text'Last), " ", From => I, Going => 
Backward);
-               exit when I - First + Integer (Indent) <= Max_Line_Length - 4;
-               I := I - 1;
-            end loop;
-            Indent_Line (Prefix & Text (First .. I - 1));
-            First := I + 1;
-            exit when Text'Last - First + Integer (Indent) <= Max_Line_Length 
- 4;
-         end loop;
-         Indent_Line (Prefix & Text (First .. Text'Last));
-      end if;
-   end Indent_Wrap_Comment;
-
-end WisiToken.Generate;
diff --git a/packages/wisi/wisitoken-generate.ads 
b/packages/wisi/wisitoken-generate.ads
deleted file mode 100644
index a9c4e5a..0000000
--- a/packages/wisi/wisitoken-generate.ads
+++ /dev/null
@@ -1,200 +0,0 @@
---  Abstract :
---
---  Types and operations for generating parsers, common to all parser
---  types.
---
---  The wisi* packages deal with reading *.wy files and generating
---  source code files. The wisitoken-generate* packages deal with
---  computing parser properties from the grammar. (For historical
---  reasons, not all packages follow this naming convention yet).
---
---  References :
---
---  See wisitoken.ads
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image;
-with SAL.Gen_Graphs;
-with WisiToken.Productions;
-package WisiToken.Generate is
-
-   Error : Boolean := False;
-   --  Set True by errors during grammar generation
-
-   function Error_Message
-     (File_Name : in String;
-      File_Line : in WisiToken.Line_Number_Type;
-      Message   : in String)
-     return String;
-
-   procedure Put_Error (Message : in String);
-   --  Set Error True, output Message to Standard_Error
-
-   procedure Check_Consistent
-     (Grammar          : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor       : in WisiToken.Descriptor;
-      Source_File_Name : in String);
-   --  Check requirements on Descriptor values.
-
-   function Check_Unused_Tokens
-     (Descriptor : in WisiToken.Descriptor;
-      Grammar    : in WisiToken.Productions.Prod_Arrays.Vector)
-     return Boolean;
-   --  Return False if there is a terminal or nonterminal that is not
-   --  used in the grammar.
-   --
-   --  Raises Grammar_Error if there is a non-grammar token used in the
-   --  grammar.
-
-   function Nullable (Grammar : in WisiToken.Productions.Prod_Arrays.Vector) 
return Token_Array_Production_ID;
-   --  If ID is nullable, Result (ID) is the production that should be
-   --  reduced to produce the null. Otherwise Result (ID) is
-   --  Invalid_Production_ID.
-
-   function Has_Empty_Production (Nullable : in Token_Array_Production_ID) 
return Token_ID_Set;
-   function Has_Empty_Production (Grammar : in 
WisiToken.Productions.Prod_Arrays.Vector) return Token_ID_Set;
-   --  Result (ID) is True if any production for ID can be an empty
-   --  production, recursively.
-
-   function First
-     (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Has_Empty_Production : in Token_ID_Set;
-      First_Terminal       : in Token_ID)
-     return Token_Array_Token_Set;
-   --  For each nonterminal in Grammar, find the set of tokens
-   --  (terminal or nonterminal) that any string derived from it can
-   --  start with. Together with Has_Empty_Production, implements
-   --  algorithm FIRST from [dragon], augmented with nonterminals.
-   --
-   --  LALR, LR1 generate want First as both Token_Sequence_Arrays.Vector
-   --  and Token_Array_Token_Set, Packrat wants Token_Array_Token_Set,
-   --  existing tests all use Token_Array_Token_Set. So for LR1 we use
-   --  To_Terminal_Sequence_Array.
-
-   function To_Terminal_Sequence_Array
-     (First      : in Token_Array_Token_Set;
-      Descriptor : in WisiToken.Descriptor)
-     return Token_Sequence_Arrays.Vector;
-   --  Only includes terminals.
-
-   function Follow
-     (Grammar              : in WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor           : in WisiToken.Descriptor;
-      First                : in Token_Array_Token_Set;
-      Has_Empty_Production : in Token_ID_Set)
-     return Token_Array_Token_Set;
-   --  For each nonterminal in Grammar, find the set of terminal
-   --  tokens that can follow it. Implements algorithm FOLLOW from
-   --  [dragon] pg 189.
-
-   ----------
-   --  Recursion
-
-   --  Recursion is the result of a cycle in the grammar. We can form a
-   --  graph representing the grammar by taking the nonterminals as the
-   --  graph vertices, and the occurrence of a nonterminal in a
-   --  production right hand side as a directed edge from the left hand
-   --  side of the production to that nonterminal. Then recursion is
-   --  represented by a cycle in the graph.
-
-   type Edge_Data is record
-      --  The edge leading to this node.
-      RHS         : Natural  := Natural'Last;
-      Token_Index : Positive := Positive'Last;
-   end record;
-
-   function Edge_Image (Edge : in Edge_Data) return String is (Trimmed_Image 
(Edge.RHS));
-
-   type Base_Recursion_Index is range 0 .. Integer'Last;
-   subtype Recursion_Index is Base_Recursion_Index range 1 .. 
Base_Recursion_Index'Last;
-   Invalid_Recursion_Index : constant Base_Recursion_Index := 0;
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Base_Recursion_Index);
-
-   package Grammar_Graphs is new SAL.Gen_Graphs
-     (Edge_Data         => Generate.Edge_Data,
-      Default_Edge_Data => (others => <>),
-      Vertex_Index      => Token_ID,
-      Invalid_Vertex    => Invalid_Token_ID,
-      Path_Index        => Recursion_Index,
-      Edge_Image        => Edge_Image);
-
-   subtype Recursion_Cycle is Grammar_Graphs.Path;
-   --  A recursion, with lowest numbered production first. If there is
-   --  only one element, the recursion is direct; otherwise indirect.
-
-   subtype Recursion_Array is Grammar_Graphs.Path_Arrays.Vector;
-   --  For the collection of all cycles.
-
-   type Recursions is record
-      Full       : Boolean;
-      Recursions : Recursion_Array;
-      --  If Full, elements are paths; edges at path (I) are to path (I). If
-      --  not Full, elements are strongly connected components; edges at
-      --  path (I) are from path (I).
-   end record;
-
-   package Recursion_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Recursion_Index);
-   function Image is new SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-     (Recursion_Index, "=", Recursion_Lists, Trimmed_Image);
-
-   function To_Graph (Grammar : in WisiToken.Productions.Prod_Arrays.Vector) 
return Grammar_Graphs.Graph;
-
-   function Compute_Full_Recursion
-     (Grammar    : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor)
-     return Recursions;
-   --  Each element of result is a cycle in the grammar. Also sets
-   --  Recursive components in Grammar.
-
-   function Compute_Partial_Recursion
-     (Grammar    : in out WisiToken.Productions.Prod_Arrays.Vector;
-      Descriptor : in     WisiToken.Descriptor)
-     return Recursions;
-   --  Each element of the result contains all members of a non-trivial
-   --  strongly connected component in the grammar, in arbitrary order.
-   --  This is an approximation to the full recursion, when that is too
-   --  hard to compute (ie for Java).
-   --
-   --  Also sets Recursive components in Grammar.
-
-   ----------
-   --  Indented text output. Mostly used for code generation in wisi,
-   --  also used in outputing the parse_table and other debug stuff.
-
-   Max_Line_Length : constant := 120;
-
-   Indent     : Standard.Ada.Text_IO.Positive_Count := 1;
-   Line_Count : Integer;
-
-   procedure Indent_Line (Text : in String);
-   --  Put Text, indented to Indent, to Current_Output, with newline.
-
-   procedure Indent_Start (Text : in String);
-   --  Put Text indented to Indent to Current_Output, without newline.
-   --  Should be followed by Put_Line, not Indent_Line.
-
-   procedure Indent_Wrap (Text : in String);
-   --  Put Text, indented to Indent, wrapped at Max_Line_Length, to
-   --  Current_Output, ending with newline.
-
-   procedure Indent_Wrap_Comment (Text : in String; Comment_Syntax : in 
String);
-   --  Put Text, prefixed by Comment_Syntax and two spaces, indented to
-   --  Indent, wrapped at Max_Line_Length, to Current_Output, ending with
-   --  newline.
-
-end WisiToken.Generate;
diff --git a/packages/wisi/wisitoken-lexer-re2c.adb 
b/packages/wisi/wisitoken-lexer-re2c.adb
deleted file mode 100644
index 46cccb6..0000000
--- a/packages/wisi/wisitoken-lexer-re2c.adb
+++ /dev/null
@@ -1,307 +0,0 @@
---  Abstract:
---
---  see spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Directories;
-with Ada.Strings.Unbounded;
-with GNATCOLL.Mmap;
-package body WisiToken.Lexer.re2c is
-
-   overriding procedure Finalize (Object : in out Instance)
-   is
-      use all type System.Address;
-   begin
-      if Object.Lexer /= System.Null_Address then
-         Free_Lexer (Object.Lexer);
-         Object.Lexer := System.Null_Address;
-      end if;
-
-      Finalize (Object.Source);
-   end Finalize;
-
-   type Instance_Access is access Instance; --  silence compiler warning
-
-   function New_Lexer
-     (Descriptor  : not null access constant WisiToken.Descriptor)
-     return Handle
-   is begin
-      return Handle (Instance_Access'(new Instance (Descriptor)));
-   end New_Lexer;
-
-   overriding procedure Reset_With_String
-     (Lexer      : in out Instance;
-      Input      : in     String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-   is begin
-      Finalize (Lexer);
-
-      --  We assume Input is in UTF-8 encoding
-      Lexer.Source :=
-        (Label                     => String_Label,
-         File_Name                 => +"",
-         Buffer_Nominal_First_Byte => Base_Buffer_Pos (Input'First),
-         Buffer_Nominal_First_Char => Begin_Char,
-         Line_Nominal_First        => Begin_Line,
-         Buffer                    => new String'(Input),
-         User_Buffer               => False);
-
-      Lexer.Lexer := New_Lexer
-        (Buffer    => Lexer.Source.Buffer.all'Address,
-         Length    => Interfaces.C.size_t (Input'Length),
-         Verbosity => Interfaces.C.int (if Trace_Parse > 3 then Trace_Parse - 
3 else 0));
-
-      Reset (Lexer);
-   end Reset_With_String;
-
-   overriding procedure Reset_With_String_Access
-     (Lexer      : in out Instance;
-      Input      : in     Ada.Strings.Unbounded.String_Access;
-      File_Name  : in     Ada.Strings.Unbounded.Unbounded_String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-   is begin
-      Finalize (Lexer);
-
-      --  We assume Input is in UTF-8 encoding
-      Lexer.Source :=
-        (Label       => String_Label,
-         File_Name   =>
-           +(if Ada.Strings.Unbounded.Length (File_Name) = 0 then ""
-             else Ada.Directories.Simple_Name (-File_Name)),
-         Buffer_Nominal_First_Byte => Base_Buffer_Pos (Input'First),
-         Buffer_Nominal_First_Char => Begin_Char,
-         Line_Nominal_First        => Begin_Line,
-         Buffer                    => Input,
-         User_Buffer               => True);
-
-      Lexer.Lexer := New_Lexer
-        (Buffer    => Lexer.Source.Buffer.all'Address,
-         Length    => Interfaces.C.size_t (Input'Length),
-         Verbosity => Interfaces.C.int (if Trace_Parse > 3 then Trace_Parse - 
3 else 0));
-
-      Reset (Lexer);
-   end Reset_With_String_Access;
-
-   overriding procedure Reset_With_File
-     (Lexer          : in out Instance;
-      File_Name      : in     String;
-      Begin_Byte_Pos : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      End_Byte_Pos   : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      Begin_Char     : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line     : in     Line_Number_Type := Line_Number_Type'First)
-   is
-      use GNATCOLL.Mmap;
-      Length : Buffer_Pos;
-   begin
-      Finalize (Lexer);
-
-      --  We assume the file is in UTF-8 encoding
-      Lexer.Source :=
-        (File_Label, +Ada.Directories.Simple_Name (File_Name),
-         Buffer_Nominal_First_Byte => Buffer_Pos'First, -- overwritten below,
-         Buffer_Nominal_First_Char => Begin_Char,
-         Line_Nominal_First        => Line_Number_Type'First, -- overwritten 
below
-         File                      => Open_Read (File_Name),
-         Region                    => Invalid_Mapped_Region,
-         Buffer_Last               => 1);
-
-      if Begin_Byte_Pos = Invalid_Buffer_Pos then
-         Lexer.Source.Region := Read (Lexer.Source.File);
-         Length              := Buffer_Pos (Last (Lexer.Source.Region));
-      else
-         Length := End_Byte_Pos - Begin_Byte_Pos + 1;
-
-         Lexer.Source.Buffer_Nominal_First_Byte := Begin_Byte_Pos;
-         Lexer.Source.Line_Nominal_First        := Begin_Line;
-
-         Lexer.Source.Region := Read
-           (Lexer.Source.File,
-            Offset => File_Size (Begin_Byte_Pos - 1), -- Offset is 0 indexed, 
Begin_Byte_Pos is 1 indexed
-            Length => File_Size (Length));
-      end if;
-
-      Lexer.Source.Buffer_Last := Last (Lexer.Source.Region);
-
-      Lexer.Lexer := New_Lexer
-        (Buffer    => Data (Lexer.Source.Region).all'Address,
-         Length    => Interfaces.C.size_t (Length),
-         Verbosity => Interfaces.C.int (if Trace_Parse > 3 then Trace_Parse - 
3 else 0));
-
-      Reset (Lexer);
-   end Reset_With_File;
-
-   overriding procedure Reset (Lexer : in out Instance)
-   is begin
-      Reset_Lexer (Lexer.Lexer);
-      Lexer.Line            := 1;
-      Lexer.Char_Line_Start := 1;
-      Lexer.ID :=
-        --  First token is assumed to be first on a line.
-        (if Lexer.Descriptor.New_Line_ID = Invalid_Token_ID
-         then Invalid_Token_ID
-         else Lexer.Descriptor.New_Line_ID);
-      Lexer.Prev_ID := Invalid_Token_ID;
-   end Reset;
-
-   overriding function Find_Next
-     (Lexer : in out Instance;
-      Token :    out Base_Token)
-     return Boolean
-   is
-      use Interfaces.C;
-
-      procedure Build_Token
-      is begin
-         Token :=
-           (ID         => Lexer.ID,
-            Tree_Index => Invalid_Node_Index,
-
-            Byte_Region =>
-              (if Lexer.ID = Lexer.Descriptor.EOI_ID and then 
Lexer.Byte_Position = Integer (Base_Buffer_Pos'First)
-               then
-                  --  EOF in empty buffer
-                 (Lexer.Source.Buffer_Nominal_First_Byte,
-                  Lexer.Source.Buffer_Nominal_First_Byte - 1)
-               else
-                 (Base_Buffer_Pos (Lexer.Byte_Position) + 
Lexer.Source.Buffer_Nominal_First_Byte - Buffer_Pos'First,
-                  Base_Buffer_Pos (Lexer.Byte_Position + Lexer.Byte_Length - 
1) +
-                    Lexer.Source.Buffer_Nominal_First_Byte - 
Buffer_Pos'First)),
-
-            Line => Lexer.Line + Lexer.Source.Line_Nominal_First - 
Line_Number_Type'First,
-
-            Column =>
-              (if Lexer.ID = Lexer.Descriptor.New_Line_ID or
-                 Lexer.ID = Lexer.Descriptor.EOI_ID
-               then 0
-               else Ada.Text_IO.Count (Lexer.Char_Position - 
Lexer.Char_Line_Start)),
-
-            Char_Region =>
-              (if Lexer.ID = Lexer.Descriptor.EOI_ID and then 
Lexer.Byte_Position = Integer (Base_Buffer_Pos'First)
-               then
-                  --  EOF in empty buffer
-                 (Lexer.Source.Buffer_Nominal_First_Byte,
-                  Lexer.Source.Buffer_Nominal_First_Byte - 1)
-               else
-                 (To_Char_Pos (Lexer.Source, Lexer.Char_Position),
-                  To_Char_Pos (Lexer.Source, Lexer.Char_Position + 
Lexer.Char_Length - 1))));
-      end Build_Token;
-
-   begin
-      Lexer.Prev_ID := Lexer.ID;
-      loop
-         declare
-            Status : constant int := Next_Token
-              (Lexer.Lexer, Lexer.ID,
-               Byte_Position => Interfaces.C.size_t (Lexer.Byte_Position),
-               Byte_Length   => Interfaces.C.size_t (Lexer.Byte_Length),
-               Char_Position => Interfaces.C.size_t (Lexer.Char_Position),
-               Char_Length   => Interfaces.C.size_t (Lexer.Char_Length),
-               Line_Start    => Interfaces.C.int (Lexer.Line));
-         begin
-            case Status is
-            when 0 =>
-               if Lexer.ID = Lexer.Descriptor.New_Line_ID then
-                  Lexer.Char_Line_Start := Lexer.Char_Position + 1;
-               end if;
-
-               Build_Token;
-               return False;
-
-            when 1 =>
-               --  Unrecognized character from lexer. Handle missing quotes by
-               --  inserting a virtual quote at the existing quote, and 
telling the
-               --  lexer to skip the char.
-               declare
-                  Buffer : constant GNATCOLL.Mmap.Str_Access := 
WisiToken.Lexer.Buffer (Lexer.Source);
-               begin
-                  if Trace_Parse > Lexer_Debug then
-                     --  We don't have a visible Trace object here.
-                     Ada.Text_IO.Put_Line ("lexer error char " & Buffer 
(Lexer.Byte_Position));
-                  end if;
-
-                  if Buffer (Lexer.Byte_Position) = ''' then
-                     --  Lexer has read to next new-line (or eof), then 
backtracked to next
-                     --  char after '.
-                     Lexer.Errors.Append
-                       ((To_Char_Pos (Lexer.Source, Lexer.Char_Position),
-                         Invalid_Token_Index,
-                         (1 => ''', others => ASCII.NUL)));
-
-                     Lexer.ID := Lexer.Descriptor.String_1_ID;
-                     Build_Token;
-                     return True;
-
-                  elsif Buffer (Lexer.Byte_Position) = '"' then
-                     --  Lexer has read to next new-line (or eof), then 
backtracked to next
-                     --  char after ".
-                     Lexer.Errors.Append
-                       ((To_Char_Pos (Lexer.Source, Lexer.Char_Position),
-                         Invalid_Token_Index,
-                         (1 => '"', others => ASCII.NUL)));
-
-                     Lexer.ID := Lexer.Descriptor.String_2_ID;
-                     Build_Token;
-                     return True;
-
-                  else
-                     --  Just skip the character; call Next_Token again.
-                     Lexer.Errors.Append
-                       ((To_Char_Pos (Lexer.Source, Lexer.Char_Position), 
Invalid_Token_Index, (others => ASCII.NUL)));
-                  end if;
-               end;
-
-            when others =>
-               raise Fatal_Error with " lexer returned unrecognized status 
code" & int'Image (Status);
-            end case;
-         end;
-      end loop;
-   end Find_Next;
-
-   overriding function First (Lexer : in Instance) return Boolean
-   is begin
-      return Lexer.Descriptor.New_Line_ID /= Invalid_Token_ID and then
-           Lexer.Prev_ID = Lexer.Descriptor.New_Line_ID;
-   end First;
-
-   overriding function Buffer_Text (Lexer : in Instance; Byte_Bounds : in 
Buffer_Region) return String
-   is
-      First : constant Integer := Integer
-        (Byte_Bounds.First - Lexer.Source.Buffer_Nominal_First_Byte + 
Buffer_Pos'First);
-      Last  : constant Integer := Integer
-        (Byte_Bounds.Last - Lexer.Source.Buffer_Nominal_First_Byte + 
Buffer_Pos'First);
-   begin
-      return String (Buffer (Lexer.Source) (First .. Last));
-   end Buffer_Text;
-
-   overriding function File_Name (Lexer : in Instance) return String
-   is begin
-      return File_Name (Lexer.Source);
-   end File_Name;
-
-end WisiToken.Lexer.re2c;
diff --git a/packages/wisi/wisitoken-lexer-re2c.ads 
b/packages/wisi/wisitoken-lexer-re2c.ads
deleted file mode 100644
index b871e9c..0000000
--- a/packages/wisi/wisitoken-lexer-re2c.ads
+++ /dev/null
@@ -1,144 +0,0 @@
---  Abstract:
---
---  WisiToken wrapper around the re2c lexer
---
---  References:
---
---  [1] http://re2c.org/
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-pragma License (GPL); -- GNATCOLL.Mmap
-
-pragma Warnings (Off, "license of withed unit ""GNATCOLL.Mmap"" may be 
inconsistent");
-
-pragma Warnings (On);
-with Interfaces.C;
-with System;
-generic
-   --  These subprograms are provided by generated source code.
-
-   with function New_Lexer
-     (Buffer    : in System.Address;
-      Length    : in Interfaces.C.size_t;
-      Verbosity : in Interfaces.C.int)
-     return System.Address;
-   --  Create the re2c lexer object, passing it the full text to process.
-   --  Length is buffer length in 8 bit bytes.
-   --
-   --  The C lexer does not know about Buffer_Nominal_First,
-   --  Line_Nominal_First; its buffer positions and lines start at 1.
-
-   with procedure Free_Lexer (Lexer : in out System.Address);
-   --  Destruct the re2c lexer object
-
-   with procedure Reset_Lexer (Lexer : in System.Address);
-   --  Restart lexing, with previous input buffer.
-
-   with function Next_Token
-     (Lexer         : in     System.Address;
-      ID            :    out Token_ID;
-      Byte_Position :    out Interfaces.C.size_t;
-      Byte_Length   :    out Interfaces.C.size_t;
-      Char_Position :    out Interfaces.C.size_t;
-      Char_Length   :    out Interfaces.C.size_t;
-      Line_Start    :    out Interfaces.C.int)
-     return Interfaces.C.int;
-   --  *_Position and *_Length give the position and length in bytes and
-   --  characters of the token from the start of the buffer, 0 indexed.
-   --
-   --  Line_Start gives the line number in the source file that the first
-   --  character of the token is in, 1 indexed.
-   --
-   --  Result values:
-   --
-   --  0 - no error
-   --  1 - there is an unrecognized character at Position.
-
-package WisiToken.Lexer.re2c is
-
-   Invalid_Input : exception;
-
-   type Instance is new WisiToken.Lexer.Instance with private;
-
-   overriding procedure Finalize (Object : in out Instance);
-
-   function New_Lexer
-     (Descriptor  : not null access constant WisiToken.Descriptor)
-     return WisiToken.Lexer.Handle;
-   --  If the tokens do not include a reporting New_Line token, set
-   --  New_Line_ID to Invalid_Token_ID.
-
-   overriding procedure Reset_With_String
-     (Lexer      : in out Instance;
-      Input      : in     String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First);
-   --  Copies Input to internal buffer.
-
-   overriding procedure Reset_With_String_Access
-     (Lexer      : in out Instance;
-      Input      : in     Ada.Strings.Unbounded.String_Access;
-      File_Name  : in     Ada.Strings.Unbounded.Unbounded_String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First);
-
-   overriding procedure Reset_With_File
-     (Lexer          : in out Instance;
-      File_Name      : in     String;
-      Begin_Byte_Pos : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      End_Byte_Pos   : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      Begin_Char     : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line     : in     Line_Number_Type := Line_Number_Type'First);
-   --  Uses memory mapped file; no copies.
-
-   overriding procedure Discard_Rest_Of_Input (Lexer : in out Instance) is 
null;
-
-   overriding procedure Reset (Lexer : in out Instance);
-
-   overriding function Buffer_Text (Lexer : in Instance; Byte_Bounds : in 
Buffer_Region) return String;
-
-   overriding function First (Lexer : in Instance) return Boolean;
-
-   overriding
-   function Find_Next
-     (Lexer : in out Instance;
-      Token :    out Base_Token)
-     return Boolean;
-
-   overriding function File_Name (Lexer : in Instance) return String;
-
-private
-
-   type Instance is new WisiToken.Lexer.Instance with
-   record
-      Lexer         : System.Address := System.Null_Address;
-      Source        : WisiToken.Lexer.Source;
-      ID            : Token_ID; --  Last token read by find_next
-      Byte_Position : Natural;  --  We don't use Buffer_Pos here, because 
Source.Buffer is indexed by Integer
-      Byte_Length   : Natural;
-      Char_Position : Natural;
-      Char_Length   : Natural;
-      --  Position and length in bytes and characters of last token from
-      --  start of Managed.Buffer, 1 indexed.
-
-      Line            : Line_Number_Type; -- after last (or current) New_Line 
token
-      Char_Line_Start : Natural;          -- Character position after last 
New_Line token, lexer origin.
-      Prev_ID         : Token_ID;         -- previous token_id
-   end record;
-
-end WisiToken.Lexer.re2c;
diff --git a/packages/wisi/wisitoken-lexer-regexp.adb 
b/packages/wisi/wisitoken-lexer-regexp.adb
deleted file mode 100644
index d464289..0000000
--- a/packages/wisi/wisitoken-lexer-regexp.adb
+++ /dev/null
@@ -1,259 +0,0 @@
---  Abstract:
---
---  See spec
---
---  Copyright (C) 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Characters.Latin_1;
-with SAL;
-package body WisiToken.Lexer.Regexp is
-
-   function Find_Best_Match (Lexer : in out Instance) return Boolean
-   is
-      --  Find the longest matching character sequence in the buffer that
-      --  matches a token.
-      --
-      --  Return True if a token is matched, False if not.
-
-      use WisiToken.Regexp;
-
-      Current_Char         : Integer := Lexer.Buffer_Head;
-      Current_State        : Match_State;
-      Current_Match_Length : Integer := 0;
-      Best_Match_ID        : Token_ID;
-      Best_Match_Length    : Natural := 0;
-      Still_Matching       : Boolean := False;
-   begin
-      --  We only support Reset_With_String.
-
-      if Current_Char > Lexer.Source.Buffer'Last then
-         Lexer.ID := Lexer.Descriptor.EOI_ID;
-         Lexer.Lexeme_Head := Lexer.Buffer_Head;
-         Lexer.Lexeme_Tail := Lexer.Buffer_Head - 1;
-         return True;
-      end if;
-
-      for I in Lexer.Syntax'Range loop
-         Clear (Lexer.Syntax (I).Regexp);
-      end loop;
-
-      loop
-         Still_Matching := False;
-
-         for I in Lexer.Syntax'Range loop
-            if State (Lexer.Syntax (I).Regexp) /= WisiToken.Regexp.Error then
-               Current_State := Match
-                 (Lexer.Syntax (I).Regexp,
-                  Lexer.Source.Buffer (Lexer.Buffer_Head .. 
Lexer.Source.Buffer'Last),
-                  Current_Char);
-
-               case Current_State is
-               when Matching =>
-                  Still_Matching := True;
-
-               when Final =>
-                  Still_Matching := True;
-
-                  Current_Match_Length := Current_Char - Lexer.Buffer_Head + 1;
-
-                  if Best_Match_Length < Current_Match_Length then
-                     Best_Match_ID  := I;
-                     Best_Match_Length := Current_Match_Length;
-                  end if;
-
-               when WisiToken.Regexp.Error =>
-                  null;
-               end case;
-            end if;
-         end loop;
-
-         exit when (not Still_Matching) or else (Current_Char = 
Lexer.Source.Buffer'Last);
-
-         if Best_Match_Length = Lexer.Source.Buffer'Length then
-            raise SAL.Programmer_Error with
-              "token larger than buffer size of" & Integer'Image 
(Lexer.Source.Buffer'Length);
-         end if;
-
-         Current_Char := Current_Char + 1;
-      end loop;
-
-      if Best_Match_Length > 0 then
-         Lexer.Lexeme_Head := Lexer.Buffer_Head;
-         Lexer.Lexeme_Tail := Lexer.Buffer_Head + Best_Match_Length - 1;
-         Lexer.ID          := Best_Match_ID;
-
-         if Lexer.Lexeme_Head = Lexer.Source.Buffer'Last and
-           Lexer.Source.Buffer (Lexer.Lexeme_Head) = Ada.Characters.Latin_1.EOT
-         then
-            --  matched EOF; repeat that next time
-            null;
-         else
-            Lexer.Buffer_Head := Lexer.Lexeme_Tail + 1;
-         end if;
-         return True;
-
-      elsif Current_Char = Lexer.Source.Buffer'Last then
-         Lexer.ID := Lexer.Descriptor.EOI_ID;
-         Lexer.Buffer_Head := Lexer.Buffer_Head + 1;
-         return True;
-
-      else
-         return False;
-      end if;
-
-   end Find_Best_Match;
-
-   ----------
-   --  Public subprograms
-
-   function Get
-     (Regexp         : in String;
-      Case_Sensitive : in Boolean := True;
-      Report         : in Boolean := True)
-      return Syntax_Item
-   is begin
-      return (WisiToken.Regexp.Compile (Regexp, Case_Sensitive), Report);
-   end Get;
-
-   type Instance_Access is access Instance; --  silence compiler warning
-
-   function New_Lexer
-     (Descriptor : not null access constant WisiToken.Descriptor;
-      Syntax     : in              WisiToken.Lexer.Regexp.Syntax)
-     return WisiToken.Lexer.Handle
-   is
-      New_Lexer : constant Instance_Access := new Instance (Descriptor, 
Syntax'Last);
-   begin
-      New_Lexer.Syntax := Syntax;
-
-      return Handle (New_Lexer);
-   end New_Lexer;
-
-   overriding procedure Finalize (Object : in out Instance)
-   is begin
-      Finalize (Object.Source);
-   end Finalize;
-
-   overriding procedure Reset_With_String
-     (Lexer      : in out Instance;
-      Input      : in     String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-   is begin
-      Finalize (Lexer);
-
-      Lexer.Source :=
-        (Label                     => String_Label,
-         File_Name                 => +"",
-         Buffer_Nominal_First_Byte => Base_Buffer_Pos (Input'First),
-         Buffer_Nominal_First_Char => Begin_Char,
-         Line_Nominal_First        => Begin_Line,
-         Buffer                    => new String'(Input),
-         User_Buffer               => False);
-
-      Reset (Lexer);
-   end Reset_With_String;
-
-   overriding procedure Reset_With_String_Access
-     (Lexer      : in out Instance;
-      Input      : in     Ada.Strings.Unbounded.String_Access;
-      File_Name  : in     Ada.Strings.Unbounded.Unbounded_String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-   is begin
-      Finalize (Lexer);
-
-      Lexer.Source :=
-        (Label       => String_Label,
-         File_Name   => File_Name,
-         Buffer_Nominal_First_Byte => Base_Buffer_Pos (Input'First),
-         Buffer_Nominal_First_Char => Begin_Char,
-         Line_Nominal_First        => Begin_Line,
-         Buffer      => Input,
-         User_Buffer => True);
-
-      Reset (Lexer);
-   end Reset_With_String_Access;
-
-   overriding procedure Reset_With_File
-     (Lexer          : in out Instance;
-      File_Name      : in     String;
-      Begin_Byte_Pos : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      End_Byte_Pos   : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      Begin_Char     : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line     : in     Line_Number_Type := Line_Number_Type'First)
-   is
-      pragma Unreferenced (File_Name, Begin_Byte_Pos, End_Byte_Pos, 
Begin_Char, Begin_Line);
-   begin
-      Finalize (Lexer);
-
-      raise SAL.Not_Implemented;
-   end Reset_With_File;
-
-   overriding procedure Reset
-     (Lexer : in out Instance)
-   is begin
-      Lexer.Lexeme_Head := Lexer.Source.Buffer'First;
-      Lexer.Lexeme_Tail := Lexer.Source.Buffer'First - 1;
-      Lexer.ID          := Invalid_Token_ID;
-      Lexer.Buffer_Head := Lexer.Source.Buffer'First;
-   end Reset;
-
-   overriding function Find_Next
-     (Lexer : in out Instance;
-      Token :    out Base_Token)
-     return Boolean
-   is begin
-      loop
-         if not Find_Best_Match (Lexer) then
-            if Lexer.Buffer_Head > Lexer.Source.Buffer'Last then
-               raise Syntax_Error with "Unrecognized EOF";
-            else
-               raise Syntax_Error with "Unrecognized character '" & 
Lexer.Source.Buffer (Lexer.Buffer_Head) & "'";
-            end if;
-         end if;
-
-         exit when Lexer.Syntax (Lexer.ID).Report;
-
-      end loop;
-
-      Token :=
-        (ID          => Lexer.ID,
-         Tree_Index  => Invalid_Node_Index,
-         Byte_Region => (Buffer_Pos (Lexer.Lexeme_Head), Buffer_Pos 
(Lexer.Lexeme_Tail)),
-         Line        => Invalid_Line_Number,
-         Column      => Ada.Text_IO.Count (Lexer.Lexeme_Head),
-         Char_Region => (Buffer_Pos (Lexer.Lexeme_Head), Buffer_Pos 
(Lexer.Lexeme_Tail)));
-
-      return False;
-   end Find_Next;
-
-   overriding function Buffer_Text (Lexer : in Instance; Byte_Region : in 
Buffer_Region) return String
-   is begin
-      return Lexer.Source.Buffer (Integer (Byte_Region.First) .. Integer 
(Byte_Region.Last));
-   end Buffer_Text;
-
-end WisiToken.Lexer.Regexp;
diff --git a/packages/wisi/wisitoken-lexer-regexp.ads 
b/packages/wisi/wisitoken-lexer-regexp.ads
deleted file mode 100644
index da55448..0000000
--- a/packages/wisi/wisitoken-lexer-regexp.ads
+++ /dev/null
@@ -1,114 +0,0 @@
---  Abstract:
---
---  WisiToken lexer using compiled regular expressions interpreted at runtime.
---
---  This is slower, but easier to use, than the Aflex lexer; it is
---  used in most of the WisiToken unit tests. Since it uses regexp, it
---  is easy to convert to an Aflex lexer.
---
---  Copyright (C) 2015, 2017 - 2019 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Unchecked_Deallocation;
-with WisiToken.Regexp;
-package WisiToken.Lexer.Regexp is
-
-   type Syntax_Item is record
-      Regexp : WisiToken.Regexp.Regexp;
-      Report : Boolean;
-   end record;
-
-   function Get
-     (Regexp         : in String;
-      Case_Sensitive : in Boolean := True;
-      Report         : in Boolean := True)
-     return Syntax_Item;
-   --  Compiles Regexp with Case_Sensitive.
-
-   type Syntax is array (Token_ID range <>) of Syntax_Item;
-
-   type Instance
-     (Descriptor    : not null access constant WisiToken.Descriptor;
-      Last_Terminal : Token_ID)
-     is new WisiToken.Lexer.Instance with private;
-
-   function New_Lexer
-     (Descriptor : not null access constant WisiToken.Descriptor;
-      Syntax     : in              WisiToken.Lexer.Regexp.Syntax)
-     return WisiToken.Lexer.Handle;
-
-   overriding procedure Finalize (Object : in out Instance);
-   overriding procedure Reset_With_String
-     (Lexer      : in out Instance;
-      Input      : in     String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First);
-   overriding procedure Reset_With_String_Access
-     (Lexer      : in out Instance;
-      Input      : in     Ada.Strings.Unbounded.String_Access;
-      File_Name  : in     Ada.Strings.Unbounded.Unbounded_String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First);
-   overriding procedure Reset_With_File
-     (Lexer          : in out Instance;
-      File_Name      : in     String;
-      Begin_Byte_Pos : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      End_Byte_Pos   : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      Begin_Char     : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line     : in     Line_Number_Type := Line_Number_Type'First);
-   overriding procedure Reset (Lexer : in out Instance);
-
-   overriding procedure Discard_Rest_Of_Input (Lexer : in out Instance) is 
null;
-
-   overriding function Find_Next
-     (Lexer : in out Instance;
-      Token :    out Base_Token)
-     return Boolean;
-
-   overriding function Buffer_Text (Lexer : in Instance; Byte_Region : in 
Buffer_Region) return String;
-
-   overriding function First (Lexer : in Instance) return Boolean is (False);
-
-   overriding function File_Name (Lexer : in Instance) return String is ("");
-
-private
-
-   type String_Access is access String;
-   procedure Free is new Ada.Unchecked_Deallocation (String, String_Access);
-
-   type Instance
-     (Descriptor    : not null access constant WisiToken.Descriptor;
-      Last_Terminal : Token_ID)
-     is new WisiToken.Lexer.Instance (Descriptor => Descriptor) with
-   record
-      ID          : Token_ID; --  last token read by find_next
-      Syntax      : WisiToken.Lexer.Regexp.Syntax (Token_ID'First .. 
Last_Terminal);
-      Source      : Lexer.Source;
-      Buffer_Head : Integer;
-      Lexeme_Head : Integer;
-      Lexeme_Tail : Integer;
-   end record;
-
-end WisiToken.Lexer.Regexp;
diff --git a/packages/wisi/wisitoken-lexer.adb 
b/packages/wisi/wisitoken-lexer.adb
deleted file mode 100644
index f73d517..0000000
--- a/packages/wisi/wisitoken-lexer.adb
+++ /dev/null
@@ -1,61 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with GNAT.Strings;
-package body WisiToken.Lexer is
-
-   procedure Finalize (Object : in out Source)
-   is begin
-      case Object.Label is
-      when String_Label =>
-         if not Object.User_Buffer then
-            Ada.Strings.Unbounded.Free (Object.Buffer);
-         end if;
-
-      when File_Label =>
-         GNATCOLL.Mmap.Free (Object.Region);
-         GNATCOLL.Mmap.Close (Object.File);
-      end case;
-   end Finalize;
-
-   function Buffer (Source : in Lexer.Source) return GNATCOLL.Mmap.Str_Access
-   is
-      use GNATCOLL.Mmap;
-   begin
-      case Source.Label is
-      when String_Label =>
-         return Short.To_Str_Access (GNAT.Strings.String_Access 
(Source.Buffer));
-
-      when File_Label =>
-         return Data (Source.Region);
-      end case;
-
-   end Buffer;
-
-   function File_Name (Source : in Lexer.Source) return String
-   is begin
-      return -Source.File_Name;
-   end File_Name;
-
-   function To_Char_Pos (Source : in Lexer.Source; Lexer_Char_Pos : in 
Integer) return Base_Buffer_Pos
-   is begin
-      return Base_Buffer_Pos (Lexer_Char_Pos) + 
Source.Buffer_Nominal_First_Char - Buffer_Pos'First;
-   end To_Char_Pos;
-
-end WisiToken.Lexer;
diff --git a/packages/wisi/wisitoken-lexer.ads 
b/packages/wisi/wisitoken-lexer.ads
deleted file mode 100644
index 3de31c7..0000000
--- a/packages/wisi/wisitoken-lexer.ads
+++ /dev/null
@@ -1,187 +0,0 @@
---  Abstract :
---
---  An abstract lexer interface.
---
---  Copyright (C) 2014 - 2015, 2017 - 2019 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-pragma Warnings (Off, "license of withed unit ""GNATCOLL.Mmap"" may be 
inconsistent");
-
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Finalization;
-with Ada.Strings.Unbounded;
-with GNATCOLL.Mmap;
-package WisiToken.Lexer is
-
-   type Error is record
-      Char_Pos : Buffer_Pos := Invalid_Buffer_Pos;
-      --  Character at that position is not recognized as part of a token.
-
-      Recover_Token : Base_Token_Index := Invalid_Token_Index;
-      --  If the error was corrected by inserting a missing quote, the token
-      --  (in shared parser Terminals) that was returned.
-
-      Recover_Char : String (1 .. 4) := (others => ASCII.NUL);
-      --  If the error was corrected, the character (in UTF-8 encoding) that
-      --  was inserted; unused trailing bytes set to ASCII.NUL. Otherwise,
-      --  all ASCII.Nul.
-   end record;
-
-   package Error_Lists is new Ada.Containers.Doubly_Linked_Lists (Error);
-
-   type Instance (Descriptor  : not null access constant WisiToken.Descriptor)
-   is abstract new Ada.Finalization.Limited_Controlled with record
-      Errors : Error_Lists.List;
-   end record;
-
-   subtype Class is Instance'Class;
-
-   type Handle is access all Class;
-
-   procedure Reset_With_String
-     (Lexer      : in out Instance;
-      Input      : in     String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-     is abstract;
-   --  Reset Lexer to start a new parse, reading from Input.
-
-   procedure Reset_With_String_Access
-     (Lexer      : in out Instance;
-      Input      : in     Ada.Strings.Unbounded.String_Access;
-      File_Name  : in     Ada.Strings.Unbounded.Unbounded_String;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-     is abstract;
-   --  Reset Lexer to start a new parse, reading from Input. File_Name is
-   --  used for error messages.
-
-   procedure Reset_With_File
-     (Lexer      : in out Instance;
-      File_Name  : in     String;
-      Begin_Pos  : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      End_Pos    : in     Buffer_Pos       := Invalid_Buffer_Pos;
-      Begin_Char : in     Buffer_Pos       := Buffer_Pos'First;
-      Begin_Line : in     Line_Number_Type := Line_Number_Type'First)
-     is abstract;
-   --  Reset Lexer to start a new parse, reading from File_Name. If
-   --  Begin_Pos, End_Pos /= Invalid_Buffer_Pos, only parse that portion
-   --  of the file.
-   --
-   --  Raises Ada.IO_Exceptions.Name_Error if File_Name cannot be opened.
-
-   procedure Reset (Lexer : in out Instance) is abstract;
-   --  Reset Lexer, read from previous source.
-
-   procedure Discard_Rest_Of_Input (Lexer : in out Instance) is abstract;
-   --  If reading input from a stream, abort reading (or force it to
-   --  complete); Find_Next will not be called before another Reset.
-
-   function Buffer_Text (Lexer : in Instance; Byte_Region : in Buffer_Region) 
return String is abstract;
-   --  Return text from internal buffer, given region in byte position.
-
-   function First (Lexer : in Instance) return Boolean is abstract;
-   --  True if most recent token is first on a line.
-
-   function Find_Next
-     (Lexer : in out Instance;
-      Token :    out Base_Token)
-     return Boolean is abstract;
-   --  Set Token to the next token from the input stream.
-   --
-   --  If there is a recovered error, adds an entry to Lexer.Errors (with
-   --  Recover_Token invalid). Unrecognized characters are skipped;
-   --  missing quotes are inserted at the found quote. There can be more
-   --  than one error entry for one call to Find_Next, if several
-   --  unrecognized characters are skipped. If the recovery inserted a
-   --  missing quote, it is the last entry in Errors, the returned token
-   --  is an empty string literal, and Find_Next returns True.
-   --
-   --  If there is a non-recoverable error, raises Fatal_Error with an
-   --  appropriate message.
-   --
-   --  Otherwise returns False.
-   --
-   --  Token.Char_Region, Token.Byte_Region are the character and byte
-   --  position of the start and end of token, in the internal buffer,
-   --  1-indexed. Char_Region and Byte_Region differ when text is UTF-8
-   --  or other multi-byte encoding, and when line endings are two byte.
-   --
-   --  Token.Line is the line number in which recent token starts.
-   --  If the underlying text feeder does not support the notion of
-   --  'line', returns Invalid_Line_Number.
-   --
-   --  Token.Column is the column number of the start of the token, 1
-   --  indexed. If the underlying text feeder does not support the notion
-   --  of 'line', returns byte position in internal buffer.
-
-   function File_Name (Lexer : in Instance) return String is abstract;
-   --  Return input file name; empty string if there is no file.
-
-private
-
-   type Source_Labels is (String_Label, File_Label);
-
-   type Source (Label : Source_Labels := Source_Labels'First) is record
-      File_Name : Ada.Strings.Unbounded.Unbounded_String;
-      --  Not saved in Mapped_File, may be empty for String_Label
-
-      Buffer_Nominal_First_Byte : Buffer_Pos;
-      Buffer_Nominal_First_Char : Buffer_Pos;
-      Line_Nominal_First        : Line_Number_Type;
-
-      case Label is
-      when String_Label =>
-         Buffer      : Ada.Strings.Unbounded.String_Access;
-         User_Buffer : Boolean := False;
-         --  If User_Buffer is True, user provided buffer and will deallocate
-         --  it. Otherwise we must deallocate it.
-
-         --  Buffer_Nominal_First, Line_Nominal_First are 1.
-      when File_Label =>
-
-         --  The input is memory mapped from the following, which must be 
closed:
-         File        : GNATCOLL.Mmap.Mapped_File;
-         Region      : GNATCOLL.Mmap.Mapped_Region;
-         Buffer_Last : Positive;
-         --  Region always has first character at offset 0.
-
-         --  Buffer_Nominal_First is Begin_Pos. Line_Nominal_First is
-         --  Begin_Line.
-      end case;
-   end record;
-
-   procedure Finalize (Object : in out Source);
-
-   function Buffer (Source : in Lexer.Source) return GNATCOLL.Mmap.Str_Access;
-   --  The bounds on the result are not present; 'First, 'Last are not
-   --  reliable. If Source_Label is String_label, actual bounds are
-   --  Source.Buffer'First, 'Last. Otherwise, actual bounds are 1 ..
-   --  Source.Buffer_Last. Indexing is reliable.
-
-   function File_Name (Source : in Lexer.Source) return String;
-   function To_Char_Pos (Source : in Lexer.Source; Lexer_Char_Pos : in 
Integer) return Base_Buffer_Pos;
-
-end WisiToken.Lexer;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.adb 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.adb
deleted file mode 100644
index 344461b..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.adb
+++ /dev/null
@@ -1,451 +0,0 @@
---  Abstract :
---
---  Base utilities for McKenzie_Recover
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with GNAT.Traceback.Symbolic;
-package body WisiToken.Parse.LR.McKenzie_Recover.Base is
-
-   function Get_Barrier
-     (Parsers                 : not null access Parser_Lists.List;
-      Parser_Status           : in              Parser_Status_Array;
-      Min_Success_Check_Count : in              Natural;
-      Total_Enqueue_Count     : in              Natural;
-      Check_Delta_Limit       : in              Natural;
-      Enqueue_Limit           : in              Natural)
-     return Boolean
-   is
-      Done_Count : SAL.Base_Peek_Type := 0;
-      Skip : Boolean;
-   begin
-      --  Return True if all parsers are done, or if any parser has a config
-      --  available to check.
-      for P_Status of Parser_Status loop
-         Skip := False;
-
-         case P_Status.Recover_State is
-         when Active | Ready =>
-            if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then
-               if P_Status.Parser_State.Recover.Check_Count - 
Check_Delta_Limit >= Min_Success_Check_Count then
-                  --  fail; another parser succeeded, this one taking too long.
-                  Done_Count := Done_Count + 1;
-                  Skip := True;
-
-               elsif Total_Enqueue_Count + 
P_Status.Parser_State.Recover.Config_Full_Count >= Enqueue_Limit then
-                  --  fail
-                  Done_Count := Done_Count + 1;
-                  Skip := True;
-               end if;
-            end if;
-
-            if not Skip then
-               case P_Status.Recover_State is
-               when Active =>
-                  if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then
-                     --  Still working
-                     return True;
-                  else
-                     if P_Status.Active_Workers = 0 then
-                        --  fail; no configs left to check.
-                        Done_Count := Done_Count + 1;
-                     end if;
-                  end if;
-
-               when Ready =>
-                  if P_Status.Parser_State.Recover.Config_Heap.Count > 0 and 
then
-                    P_Status.Parser_State.Recover.Config_Heap.Min_Key <= 
P_Status.Parser_State.Recover.Results.Min_Key
-                  then
-                     --  Still more to check.
-                     return True;
-
-                  elsif P_Status.Active_Workers = 0 then
-                     Done_Count := Done_Count + 1;
-                  end if;
-
-               when others =>
-                  null;
-               end case;
-            end if;
-
-         when Success | Fail =>
-            Done_Count := Done_Count + 1;
-         end case;
-      end loop;
-
-      return Done_Count = Parsers.Count;
-   end Get_Barrier;
-
-   protected body Supervisor is
-
-      procedure Initialize
-        (Parsers   : not null access Parser_Lists.List;
-         Terminals : not null access constant Base_Token_Arrays.Vector)
-      is
-         Index : SAL.Peek_Type := 1;
-      begin
-         Supervisor.Parsers      := Parsers;
-         Supervisor.Terminals    := Terminals;
-         All_Parsers_Done        := False;
-         Success_Counter         := 0;
-         Min_Success_Check_Count := Natural'Last;
-         Total_Enqueue_Count     := 0;
-         Fatal_Called            := False;
-         Result                  := Recover_Status'First;
-         Error_ID                := Ada.Exceptions.Null_Id;
-
-         for I in Parsers.Iterate loop
-            if Parsers.Reference (I).Recover_Insert_Delete_Current /= 
Recover_Op_Arrays.No_Index then
-               --  Previous error recovery resume not finished; this is 
supposed to
-               --  be checked in Parser.
-               raise SAL.Programmer_Error;
-            end if;
-
-            Parser_Status (Index) :=
-              (Recover_State  => Active,
-               Parser_State   => Parser_Lists.Persistent_State_Ref (I),
-               Fail_Mode      => Success,
-               Active_Workers => 0);
-
-            declare
-               Data : McKenzie_Data renames Parsers.Reference (I).Recover;
-            begin
-               Data.Config_Heap.Clear;
-               Data.Results.Clear;
-               Data.Enqueue_Count := 0;
-               Data.Check_Count   := 0;
-               Data.Success       := False;
-            end;
-
-            Index := Index + 1;
-         end loop;
-      end Initialize;
-
-      entry Get
-        (Parser_Index : out SAL.Base_Peek_Type;
-         Config       : out Configuration;
-         Status       : out Config_Status)
-        when (Fatal_Called or All_Parsers_Done) or else Get_Barrier
-          (Parsers, Parser_Status, Min_Success_Check_Count, 
Total_Enqueue_Count, Check_Delta_Limit, Enqueue_Limit)
-      is
-         Done_Count     : SAL.Base_Peek_Type := 0;
-         Skip           : Boolean;
-         Min_Cost       : Integer            := Integer'Last;
-         Min_Cost_Index : SAL.Base_Peek_Type;
-
-         procedure Set_Outputs (I : in SAL.Peek_Type)
-         is begin
-            Parser_Index := I;
-            Config       := Parser_Status 
(I).Parser_State.Recover.Config_Heap.Remove;
-            Status       := Valid;
-
-            Parser_Status (I).Parser_State.Recover.Check_Count :=
-              Parser_Status (I).Parser_State.Recover.Check_Count + 1;
-
-            Parser_Status (I).Active_Workers := Parser_Status 
(I).Active_Workers + 1;
-         end Set_Outputs;
-
-         procedure Set_All_Done
-         is begin
-            Parser_Index := SAL.Base_Peek_Type'First;
-            Config       := (others => <>);
-            Status       := All_Done;
-         end Set_All_Done;
-
-      begin
-         if Fatal_Called or All_Parsers_Done then
-            Set_All_Done;
-            return;
-         end if;
-
-         --  Same logic as in Get_Barrier, but different actions.
-         --
-         --  No task_id in outline trace messages, because they may appear in
-         --  .parse_good
-         for I in Parser_Status'Range loop
-            Skip := False;
-
-            declare
-               P_Status : Base.Parser_Status renames Parser_Status (I);
-            begin
-               case P_Status.Recover_State is
-               when Active | Ready =>
-                  if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then
-                     if P_Status.Parser_State.Recover.Check_Count - 
Check_Delta_Limit >= Min_Success_Check_Count then
-                        if Trace_McKenzie > Outline then
-                           Put_Line
-                             (Trace.all,
-                              P_Status.Parser_State.Label, "fail; check delta 
(limit" &
-                                Integer'Image (Min_Success_Check_Count + 
Check_Delta_Limit) & ")",
-                              Task_ID => False);
-                        end if;
-                        P_Status.Recover_State := Fail;
-                        P_Status.Fail_Mode     := Fail_Check_Delta;
-
-                        Done_Count := Done_Count + 1;
-                        Skip := True;
-
-                     elsif Total_Enqueue_Count + 
P_Status.Parser_State.Recover.Config_Full_Count >= Enqueue_Limit then
-                        if Trace_McKenzie > Outline then
-                           Put_Line
-                             (Trace.all,
-                              P_Status.Parser_State.Label, "fail; total 
enqueue limit (" &
-                                Enqueue_Limit'Image & " cost" &
-                                
P_Status.Parser_State.Recover.Config_Heap.Min_Key'Image & ")",
-                              Task_ID => False);
-                        end if;
-                        P_Status.Recover_State := Fail;
-                        P_Status.Fail_Mode     := Fail_Enqueue_Limit;
-
-                        Done_Count := Done_Count + 1;
-                        Skip := True;
-                     end if;
-                  end if;
-
-                  if not Skip then
-                     case P_Status.Recover_State is
-                     when Active =>
-                        if P_Status.Parser_State.Recover.Config_Heap.Count > 0 
then
-                           if 
P_Status.Parser_State.Recover.Config_Heap.Min_Key < Min_Cost then
-                              Min_Cost       := 
P_Status.Parser_State.Recover.Config_Heap.Min_Key;
-                              Min_Cost_Index := I;
-                              --  not done
-                           end if;
-                        else
-                           if P_Status.Active_Workers = 0 then
-                              --  No configs left to check (rarely happens 
with real languages).
-                              if Trace_McKenzie > Outline then
-                                 Put_Line
-                                   (Trace.all, P_Status.Parser_State.Label, 
"fail; no configs left", Task_ID => False);
-                              end if;
-                              P_Status.Recover_State := Fail;
-                              P_Status.Fail_Mode     := Fail_No_Configs_Left;
-
-                              Done_Count := Done_Count + 1;
-                           end if;
-                        end if;
-
-                     when Ready =>
-                        if P_Status.Parser_State.Recover.Config_Heap.Count > 0 
and then
-                          P_Status.Parser_State.Recover.Config_Heap.Min_Key <=
-                          P_Status.Parser_State.Recover.Results.Min_Key
-                        then
-                           --  Still more to check. We don't check Min_Cost 
here so this parser
-                           --  can finish quickly.
-                           Set_Outputs (I);
-                           return;
-
-                        elsif P_Status.Active_Workers = 0 then
-                           P_Status.Recover_State := Success;
-                           Done_Count             := Done_Count + 1;
-                        end if;
-                     when others =>
-                        null;
-                     end case;
-                  end if;
-
-               when Success | Fail =>
-                  Done_Count := Done_Count + 1;
-               end case;
-            end;
-         end loop;
-
-         if Min_Cost /= Integer'Last then
-            Set_Outputs (Min_Cost_Index);
-
-         elsif Done_Count = Parsers.Count then
-            if Trace_McKenzie > Extra then
-               Trace.Put_Line ("Supervisor: done, " & (if Success_Counter > 0 
then "succeed" else "fail"));
-            end if;
-
-            Set_All_Done;
-            All_Parsers_Done := True;
-         else
-            raise SAL.Programmer_Error with "Get_Barrier and Get logic do not 
match";
-         end if;
-      end Get;
-
-      procedure Success
-        (Parser_Index : in     SAL.Peek_Type;
-         Config       : in     Configuration;
-         Configs      : in out Config_Heaps.Heap_Type)
-      is
-         Data : McKenzie_Data renames Parser_Status 
(Parser_Index).Parser_State.Recover;
-      begin
-         Put (Parser_Index, Configs); --  Decrements Active_Worker_Count.
-
-         if Trace_McKenzie > Detail then
-            Put
-              ("succeed: enqueue" & Integer'Image (Data.Enqueue_Count) & ", 
check " & Integer'Image (Data.Check_Count),
-               Trace.all, Parser_Status (Parser_Index).Parser_State.Label, 
Terminals.all, Config);
-         end if;
-
-         if Force_Full_Explore then
-            return;
-         end if;
-
-         Success_Counter := Success_Counter + 1;
-         Result          := Success;
-
-         Data.Success := True;
-
-         if Data.Check_Count < Min_Success_Check_Count then
-            Min_Success_Check_Count := Data.Check_Count;
-         end if;
-
-         if Force_High_Cost_Solutions then
-            Data.Results.Add (Config);
-            if Data.Results.Count > 3 then
-               Parser_Status (Parser_Index).Recover_State := Ready;
-            end if;
-         else
-            if Data.Results.Count = 0 then
-               Data.Results.Add (Config);
-
-               Parser_Status (Parser_Index).Recover_State := Ready;
-
-            elsif Config.Cost < Data.Results.Min_Key then
-               --  delete higher cost configs from Results
-               loop
-                  Data.Results.Drop;
-                  exit when Data.Results.Count = 0 or else
-                    Config.Cost >= Data.Results.Min_Key;
-               end loop;
-
-               Data.Results.Add (Config);
-
-            elsif Config.Cost = Data.Results.Min_Key then
-               Data.Results.Add (Config);
-
-            else
-               --  Config.Cost > Results.Min_Key
-               null;
-            end if;
-         end if;
-      end Success;
-
-      procedure Put (Parser_Index : in SAL.Peek_Type; Configs : in out 
Config_Heaps.Heap_Type)
-      is
-         Configs_Count : constant SAL.Base_Peek_Type := Configs.Count; -- 
Before it is emptied, for Trace.
-
-         P_Status : Base.Parser_Status renames Parser_Status (Parser_Index);
-         Data : McKenzie_Data renames P_Status.Parser_State.Recover;
-      begin
-         P_Status.Active_Workers := P_Status.Active_Workers - 1;
-
-         Total_Enqueue_Count := Total_Enqueue_Count + Integer (Configs_Count);
-         Data.Enqueue_Count  := Data.Enqueue_Count + Integer (Configs_Count);
-         loop
-            exit when Configs.Count = 0;
-
-            --  [1] has a check for duplicate configs here; that only happens 
with
-            --  higher costs, which take too long for our application.
-            Data.Config_Heap.Add (Configs.Remove);
-         end loop;
-
-         if Trace_McKenzie > Detail then
-            Put_Line
-              (Trace.all, P_Status.Parser_State.Label,
-               "enqueue:" & SAL.Base_Peek_Type'Image (Configs_Count) &
-                 "/" & SAL.Base_Peek_Type'Image (Data.Config_Heap.Count) &
-                 "/" & Trimmed_Image (Total_Enqueue_Count) &
-                 "/" & Trimmed_Image (Data.Check_Count) &
-                 ", min cost:" &
-                 (if Data.Config_Heap.Count > 0
-                  then Integer'Image (Data.Config_Heap.Min_Key)
-                  else " ? ") &
-                 ", active workers:" & Integer'Image 
(P_Status.Active_Workers));
-         end if;
-      end Put;
-
-      procedure Config_Full (Prefix : in String; Parser_Index : in 
SAL.Peek_Type)
-      is
-         P_Status : Base.Parser_Status renames Parser_Status (Parser_Index);
-         Data : McKenzie_Data renames P_Status.Parser_State.Recover;
-      begin
-         Data.Config_Full_Count := Data.Config_Full_Count + 1;
-         if Trace_McKenzie > Outline then
-            Put_Line (Trace.all, Label (Parser_Index), Prefix & ": config.ops 
is full; " &
-                        Data.Config_Full_Count'Image);
-         end if;
-      end Config_Full;
-
-      function Recover_Result return Recover_Status
-      is
-         Temp : Recover_Status := Result;
-      begin
-         if Result = Success then
-            return Success;
-         else
-            for S of Parser_Status loop
-               Temp := Recover_Status'Max (Result, S.Fail_Mode);
-            end loop;
-            return Temp;
-         end if;
-      end Recover_Result;
-
-      procedure Fatal (E : in Ada.Exceptions.Exception_Occurrence)
-      is
-         use Ada.Exceptions;
-      begin
-         if Trace_McKenzie > Outline then
-            Trace.Put_Line ("task " & Task_Attributes.Value'Image & " 
Supervisor: Error");
-         end if;
-         Fatal_Called   := True;
-         Error_ID       := Exception_Identity (E);
-         Error_Message  := +Exception_Message (E);
-         if Debug_Mode then
-            Trace.Put_Line (Exception_Name (E) & ": " & Exception_Message (E));
-            Trace.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E)); 
-- includes Prefix
-         end if;
-      end Fatal;
-
-      entry Done (Error_ID : out Ada.Exceptions.Exception_Id; Message : out 
Ada.Strings.Unbounded.Unbounded_String)
-        when All_Parsers_Done or Fatal_Called
-      is begin
-         Error_ID := Supervisor.Error_ID;
-         Message  := Error_Message;
-         if Trace_McKenzie > Detail then
-            Trace.New_Line;
-            Trace.Put_Line ("Supervisor: Done");
-         end if;
-      end Done;
-
-      function Parser_State (Parser_Index : in SAL.Peek_Type) return 
Parser_Lists.Constant_Reference_Type
-      is begin
-         return (Element => Parser_Status (Parser_Index).Parser_State);
-      end Parser_State;
-
-      function Label (Parser_Index : in SAL.Peek_Type) return Natural
-      is begin
-         return Parser_Status (Parser_Index).Parser_State.Label;
-      end Label;
-
-   end Supervisor;
-
-   procedure Put
-     (Message      : in              String;
-      Super        : not null access Base.Supervisor;
-      Shared       : not null access Base.Shared;
-      Parser_Index : in              SAL.Peek_Type;
-      Config       : in              Configuration;
-      Task_ID      : in              Boolean := True)
-   is begin
-      Put (Message, Super.Trace.all, Super.Parser_State (Parser_Index).Label,
-           Shared.Terminals.all, Config, Task_ID);
-   end Put;
-
-end WisiToken.Parse.LR.McKenzie_Recover.Base;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.ads 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.ads
deleted file mode 100644
index f67df90..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-base.ads
+++ /dev/null
@@ -1,185 +0,0 @@
---  Abstract :
---
---  Base utilities for McKenzie_Recover
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Parse.LR.Parser_Lists;
-private package WisiToken.Parse.LR.McKenzie_Recover.Base is
-
-   ----------
-   --  Protected object specs.
-   --
-   --  Tasking design requirements:
-   --
-   --  1) For each parse_state, find all solutions of the same lowest
-   --  cost.
-   --
-   --  2) use as many CPUs as available as fully as possible.
-   --
-   --  3) avoid
-   --     a) busy waits
-   --     b) race conditions
-   --     c) deadlocks.
-   --
-   --  For 2), we use worker_tasks to perform the check computations on
-   --  each configuration. We allocate N - 1 worker_tasks, where N is the
-   --  number of available CPUs, saving one CPU for Supervisor and the
-   --  foreground IDE.
-   --
-   --  For 1), worker_tasks always get the lowest cost configuration
-   --  available. However, some active worker_task may have a lower cost
-   --  configuration that it has not yet delivered to Supervisor.
-   --  Therefore we always wait until all current active worker_tasks
-   --  deliver their results before deciding we are done.
-   --
-   --  For 3a) we have one Supervisor protected object that controls
-   --  access to all Parse_States and configurations, and a Shared object
-   --  that provides appropriate access to the Shared_Parser components.
-   --
-   --  It is tempting to try to reduce contention for Supervisor by
-   --  having one protected object per parser, but that requires the
-   --  worker tasks to busy loop checking all the parsers.
-   --
-   --  There is still a race condition on Success; the solutions can be
-   --  delivered in different orders on different runs. This matters
-   --  because each solution results in a successful parse, possibly with
-   --  different actions (different indentation computed, for example).
-   --  Which solution finally succeeds depends on which are terminated
-   --  due to identical parser stacks, which in turn depends on the order
-   --  they were delivered. See ada-mode/tests/ada_mode-interactive_2.adb
-   --  for an example.
-   --
-   --  There is also a race condition on how many failed or higher cost
-   --  configurations are checked, before the final solutions are found.
-
-   type Config_Status is (Valid, All_Done);
-   type Recover_State is (Active, Ready, Success, Fail);
-
-   type Parser_Status is record
-      Recover_State : Base.Recover_State;
-      Parser_State  : Parser_Lists.State_Access;
-      Fail_Mode     : Recover_Status;
-
-      Active_Workers : Natural;
-      --  Count of Worker_Tasks that have done Get but not Put or Success.
-   end record;
-
-   type Parser_Status_Array is array (SAL.Peek_Type range <>) of Parser_Status;
-
-   protected type Supervisor
-     (Trace             : not null access WisiToken.Trace'Class;
-      Check_Delta_Limit : Natural;
-      Enqueue_Limit     : Natural;
-      Parser_Count      : SAL.Peek_Type)
-   is
-      --  There is only one object of this type, declared in Recover.
-
-      procedure Initialize
-        (Parsers   : not null access Parser_Lists.List;
-         Terminals : not null access constant Base_Token_Arrays.Vector);
-
-      entry Get
-        (Parser_Index : out SAL.Base_Peek_Type;
-         Config       : out Configuration;
-         Status       : out Config_Status);
-      --  Get a new configuration to check. Available when there is a
-      --  configuration to get, or when all configs have been checked.
-      --
-      --  Increments active worker count.
-      --
-      --  Status values mean:
-      --
-      --  Valid - Parser_Index, Config are valid, should be checked.
-      --
-      --  All_Done - Parser_Index, Config are not valid.
-
-      procedure Success
-        (Parser_Index : in     SAL.Peek_Type;
-         Config       : in     Configuration;
-         Configs      : in out Config_Heaps.Heap_Type);
-      --  Report that Configuration succeeds for Parser_Label, and enqueue
-      --  Configs.
-      --
-      --  Decrements active worker count.
-
-      procedure Put (Parser_Index : in SAL.Peek_Type; Configs : in out 
Config_Heaps.Heap_Type);
-      --  Add Configs to the McKenzie_Data Config_Heap for Parser_Label
-      --
-      --  Decrements active worker count.
-
-      procedure Config_Full (Prefix : in String; Parser_Index : in 
SAL.Peek_Type);
-      --  Report that a config.ops was full when trying to add another op.
-      --  This is counted towards the enqueue limit.
-
-      function Recover_Result return Recover_Status;
-
-      procedure Fatal (E : in Ada.Exceptions.Exception_Occurrence);
-      --  Report a fatal error; abort all processing, make Done
-      --  available.
-
-      entry Done (Error_ID : out Ada.Exceptions.Exception_Id; Message : out 
Ada.Strings.Unbounded.Unbounded_String);
-      --  Available when all parsers have failed or succeeded, or an error
-      --  occured.
-      --
-      --  If Error_ID is not Null_Id, an error occured.
-
-      function Parser_State (Parser_Index : in SAL.Peek_Type) return 
Parser_Lists.Constant_Reference_Type;
-      function Label (Parser_Index : in SAL.Peek_Type) return Natural;
-
-   private
-      Parsers   : access Parser_Lists.List;
-      Terminals : access constant Base_Token_Arrays.Vector;
-
-      All_Parsers_Done        : Boolean;
-      Success_Counter         : Natural;
-      Min_Success_Check_Count : Natural;
-      Total_Enqueue_Count     : Natural;
-      Fatal_Called            : Boolean;
-      Result                  : Recover_Status;
-      Error_ID                : Ada.Exceptions.Exception_Id;
-      Error_Message           : Ada.Strings.Unbounded.Unbounded_String;
-      Parser_Status           : Parser_Status_Array (1 .. Parser_Count);
-   end Supervisor;
-
-   type Shared
-     (Trace                          : not null access WisiToken.Trace'Class;
-      Lexer                          : not null access constant 
WisiToken.Lexer.Instance'Class;
-      Table                          : not null access constant Parse_Table;
-      Language_Fixes                 : 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Terminals                      : not null access constant 
Base_Token_Arrays.Vector;
-      Line_Begin_Token               : not null access constant 
Line_Begin_Token_Vectors.Vector)
-     is null record;
-   --  There is only one object of this type, declared in Recover. It
-   --  provides appropriate access to Shared_Parser components.
-   --
-   --  Since all the accessible objects are read-only (except Trace),
-   --  there are no protected operations, and this is not a protected
-   --  type.
-
-   procedure Put
-     (Message      : in              String;
-      Super        : not null access Base.Supervisor;
-      Shared       : not null access Base.Shared;
-      Parser_Index : in              SAL.Peek_Type;
-      Config       : in              Configuration;
-      Task_ID      : in              Boolean := True);
-
-end WisiToken.Parse.LR.McKenzie_Recover.Base;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.adb 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.adb
deleted file mode 100644
index 2741dff..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.adb
+++ /dev/null
@@ -1,1875 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-with SAL.Gen_Bounded_Definite_Queues;
-with WisiToken.Parse.LR.McKenzie_Recover.Parse;
-with WisiToken.Parse.LR.Parser;
-package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
-
-   procedure Do_Shift
-     (Label             : in              String;
-      Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Peek_Type;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type;
-      Config            : in out          Configuration;
-      State             : in              State_Index;
-      ID                : in              Token_ID;
-      Cost_Delta        : in              Integer;
-      Strategy          : in              Strategies)
-   is
-      use Config_Op_Arrays;
-      McKenzie_Param : McKenzie_Param_Type renames Shared.Table.McKenzie_Param;
-
-      Op : constant Config_Op := (Insert, ID, Config.Current_Shared_Token);
-   begin
-      Config.Strategy_Counts (Strategy) := Config.Strategy_Counts (Strategy) + 
1;
-
-      if Is_Full (Config.Ops) then
-         Super.Config_Full ("do_shift ops", Parser_Index);
-         raise Bad_Config;
-      else
-         Append (Config.Ops, Op);
-      end if;
-
-      if Cost_Delta = 0 then
-         Config.Cost := Config.Cost + McKenzie_Param.Insert (ID);
-      else
-         --  Cost_Delta /= 0 comes from Insert_Minimal_Complete_Actions. That
-         --  doesn't mean it is better than any other solution, so don't let
-         --  cost be 0.
-         --
-         --  We don't just eliminate all cost for Minimal_Complete_Actions;
-         --  that leads to using it far too much at the expense of better
-         --  solutions.
-         Config.Cost := Integer'Max (1, Config.Cost + McKenzie_Param.Insert 
(ID) + Cost_Delta);
-      end if;
-
-      Config.Error_Token.ID := Invalid_Token_ID;
-      Config.Check_Status   := (Label => WisiToken.Semantic_Checks.Ok);
-
-      if Config.Stack.Is_Full then
-         Super.Config_Full ("do_shift stack", Parser_Index);
-         raise Bad_Config;
-      else
-         Config.Stack.Push ((State, Invalid_Node_Index, (ID, Virtual => True, 
others => <>)));
-      end if;
-      if Trace_McKenzie > Detail then
-         Base.Put
-           ((if Label'Length > 0 then Label & ": " else "") & "insert " & 
Image (ID, Super.Trace.Descriptor.all),
-            Super, Shared, Parser_Index, Config);
-      end if;
-
-      Local_Config_Heap.Add (Config);
-   end Do_Shift;
-
-   procedure Do_Reduce_1
-     (Label             : in              String;
-      Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Peek_Type;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type;
-      Config            : in out          Configuration;
-      Action            : in              Reduce_Action_Rec;
-      Do_Language_Fixes : in              Boolean := True)
-   is
-      use all type Semantic_Checks.Check_Status_Label;
-      use all type WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-
-      Prev_State : constant Unknown_State_Index := Config.Stack.Peek.State;
-
-      Descriptor : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-      Table      : Parse_Table renames Shared.Table.all;
-      Nonterm    : Recover_Token;
-      New_State  : Unknown_State_Index;
-   begin
-      Config.Check_Status := Parse.Reduce_Stack (Shared, Config.Stack, Action, 
Nonterm, Default_Virtual => True);
-      case Config.Check_Status.Label is
-      when Ok =>
-         null;
-
-      when Semantic_Checks.Error =>
-         Config.Error_Token       := Nonterm;
-         Config.Check_Token_Count := Action.Token_Count;
-
-         if Do_Language_Fixes then
-            if Shared.Language_Fixes /= null then
-               Shared.Language_Fixes
-                 (Super.Trace.all, Shared.Lexer, Super.Label (Parser_Index), 
Shared.Table.all, Shared.Terminals.all,
-                  Super.Parser_State (Parser_Index).Tree, Local_Config_Heap,
-                  Config);
-            end if;
-         end if;
-
-         --  Finish the reduce; ignore the check fail.
-         if Config.Stack.Depth < SAL.Base_Peek_Type (Config.Check_Token_Count) 
then
-            raise SAL.Programmer_Error;
-         else
-            Config.Stack.Pop (SAL.Base_Peek_Type (Config.Check_Token_Count));
-         end if;
-         Config.Error_Token.ID := Invalid_Token_ID;
-         Config.Check_Status   := (Label => Ok);
-      end case;
-
-      if Config.Stack.Depth = 0 or else Config.Stack.Peek.State = 
Unknown_State then
-         raise Bad_Config;
-      end if;
-
-      New_State := Goto_For (Table, Config.Stack.Peek.State, 
Action.Production.LHS);
-
-      if New_State = Unknown_State then
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Super.Trace.all, Super.Label (Parser_Index), Label &
-                 ": Do_Reduce_1: unknown_State " & 
Config.Stack.Peek.State'Image & " " &
-                 Image (Action.Production.LHS, Descriptor));
-         end if;
-         raise Bad_Config;
-      end if;
-
-      Config.Stack.Push ((New_State, Invalid_Node_Index, Nonterm));
-
-      if Trace_McKenzie > Extra and Label'Length > 0 then
-         Put_Line
-           (Super.Trace.all, Super.Label (Parser_Index), Label &
-              ": state" & State_Index'Image (Prev_State) & " reduce" &
-              Ada.Containers.Count_Type'Image (Action.Token_Count) & " to " &
-              Image (Action.Production.LHS, Descriptor) & ", goto" &
-              State_Index'Image (New_State) & " via" & State_Index'Image 
(Config.Stack.Peek (2).State));
-      end if;
-   end Do_Reduce_1;
-
-   procedure Do_Reduce_2
-     (Label             : in              String;
-      Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Peek_Type;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type;
-      Config            : in out          Configuration;
-      Inserted_ID       : in              Token_ID;
-      Cost_Delta        : in              Integer;
-      Strategy          : in              Strategies)
-   is
-      --  Perform reduce actions until shift Inserted_ID; if all succeed,
-      --  add the final configuration to the heap, return True. If a conflict 
is
-      --  encountered, process the other action the same way. If a semantic
-      --  check fails, enqueue possible solutions. For parse table error
-      --  actions, or exception Bad_Config, return False.
-
-      Orig_Config : Configuration;
-      Table       : Parse_Table renames Shared.Table.all;
-      Next_Action : Parse_Action_Node_Ptr := Action_For (Table, 
Config.Stack.Peek.State, Inserted_ID);
-   begin
-      if Next_Action.Next /= null then
-         Orig_Config := Config;
-      end if;
-
-      case Next_Action.Item.Verb is
-      when Shift =>
-         Do_Shift
-           (Label, Super, Shared, Parser_Index, Local_Config_Heap, Config, 
Next_Action.Item.State, Inserted_ID,
-            Cost_Delta, Strategy);
-
-      when Reduce =>
-         Do_Reduce_1 (Label, Super, Shared, Parser_Index, Local_Config_Heap, 
Config, Next_Action.Item);
-         Do_Reduce_2
-           (Label, Super, Shared, Parser_Index, Local_Config_Heap, Config, 
Inserted_ID, Cost_Delta, Strategy);
-
-      when Accept_It =>
-         raise SAL.Programmer_Error with "found test case for Do_Reduce 
Accept_It";
-
-      when Error =>
-         if Trace_McKenzie > Extra and Label'Length > 0 then
-            Put_Line
-              (Super.Trace.all, Super.Label (Parser_Index), Label & ": error 
on " &
-                 Image (Inserted_ID, Super.Trace.Descriptor.all) &
-                 " in state" & State_Index'Image (Config.Stack.Peek.State));
-         end if;
-      end case;
-
-      loop
-         exit when Next_Action.Next = null;
-         --  There is a conflict; create a new config to shift or reduce.
-         declare
-            New_Config : Configuration := Orig_Config;
-            Action     : Parse_Action_Rec renames Next_Action.Next.Item;
-         begin
-            case Action.Verb is
-            when Shift =>
-               Do_Shift
-                 (Label, Super, Shared, Parser_Index, Local_Config_Heap, 
New_Config, Action.State, Inserted_ID,
-                  Cost_Delta, Strategy);
-
-            when Reduce =>
-               Do_Reduce_1 (Label, Super, Shared, Parser_Index, 
Local_Config_Heap, New_Config, Action);
-               Do_Reduce_2
-                 (Label, Super, Shared, Parser_Index, Local_Config_Heap, 
New_Config, Inserted_ID,
-                  Cost_Delta, Strategy);
-
-            when Accept_It =>
-               raise SAL.Programmer_Error with "found test case for Do_Reduce 
Accept_It conflict";
-
-            when Error =>
-               null;
-            end case;
-         end;
-
-         Next_Action := Next_Action.Next;
-      end loop;
-   exception
-   when Bad_Config =>
-      if Debug_Mode then
-         raise;
-      end if;
-   end Do_Reduce_2;
-
-   function Edit_Point_Matches_Ops (Config : in Configuration) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-      pragma Assert (Length (Config.Ops) > 0);
-      Op : Config_Op renames Constant_Ref (Config.Ops, Last_Index 
(Config.Ops));
-   begin
-      return Config.Current_Shared_Token =
-        (case Op.Op is
-         when Fast_Forward => Op.FF_Token_Index,
-         when Undo_Reduce  => Invalid_Token_Index, -- ie, "we don't know", so 
return False.
-         when Push_Back    => Op.PB_Token_Index,
-         when Insert       => Op.Ins_Token_Index,
-         when Delete       => Op.Del_Token_Index + 1);
-   end Edit_Point_Matches_Ops;
-
-   procedure Fast_Forward
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type;
-      Config            : in              Configuration)
-   is
-      --  Apply the ops in Config; they were inserted by some fix.
-      --  Leaves Config.Error_Token, Config.Check_Status set.
-      --  If there are conflicts, all are parsed; if more than one succeed.
-      --  All configs are enqueued in Local_Config_Heap.
-
-      use Parse.Parse_Item_Arrays;
-      use Config_Op_Arrays;
-
-      Parse_Items : aliased Parse.Parse_Item_Arrays.Vector;
-
-      Dummy : Boolean := Parse.Parse
-        (Super, Shared, Parser_Index, Parse_Items, Config,
-         Shared_Token_Goal => Invalid_Token_Index,
-         All_Conflicts     => True,
-         Trace_Prefix      => "fast_forward");
-   begin
-      --  This solution is from Language_Fixes (see gate on call site
-      --  below); any cost increase is done there.
-      --
-      --  We used to handle the Parse_Items.Length = 1 case specially, and
-      --  return Continue. Maintaining that requires too much code
-      --  duplication.
-
-      for I in First_Index (Parse_Items) .. Last_Index (Parse_Items) loop
-         declare
-            Item : Parse.Parse_Item renames 
Parse.Parse_Item_Array_Refs.Variable_Ref (Parse_Items, I);
-         begin
-            if Item.Parsed and Item.Config.Current_Insert_Delete = 
No_Insert_Delete then
-               --  Item.Config.Error_Token.ID, Check_Status are correct.
-
-               if not Edit_Point_Matches_Ops (Item.Config) then
-
-                  if Is_Full (Item.Config.Ops) then
-                     Super.Config_Full ("fast_forward 1", Parser_Index);
-                     raise Bad_Config;
-                  else
-                     Append (Item.Config.Ops, (Fast_Forward, 
Item.Config.Current_Shared_Token));
-                  end if;
-               end if;
-
-               Item.Config.Minimal_Complete_State := None;
-               Item.Config.Matching_Begin_Done    := False;
-               Local_Config_Heap.Add (Item.Config);
-
-               if Trace_McKenzie > Detail then
-                  Base.Put ("fast forward enqueue", Super, Shared, 
Parser_Index, Item.Config);
-               end if;
-            end if;
-         exception
-         when Bad_Config =>
-            null;
-         end;
-      end loop;
-   end Fast_Forward;
-
-   function Check
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in out          Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-     return Check_Status
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-      use Parse.Parse_Item_Arrays;
-      use all type Semantic_Checks.Check_Status_Label;
-
-      Parse_Items : aliased Parse.Parse_Item_Arrays.Vector;
-      Result      : Check_Status := Continue;
-   begin
-      if Length (Config.Ops) > 0 then
-         declare
-            Op : Config_Op renames Constant_Ref (Config.Ops, Last_Index 
(Config.Ops));
-         begin
-            case Op.Op is
-            when Push_Back =>
-               --  Check would undo the Push_Back, leading to
-               --  duplicate results. See test_mckenzie_recover.adb 
Do_Delete_First and
-               --  three_action_conflict_lalr.parse_good for examples.
-               return Continue;
-
-            when Undo_Reduce =>
-               if Config.Check_Status.Label /= Ok then
-                  --  This is the "ignore error" solution for a check fail; 
check it.
-                  Config.Check_Status   := (Label => Ok);
-                  Config.Error_Token.ID := Invalid_Token_ID;
-
-               else
-                  --  Check would undo the Undo_Reduce, leading to
-                  --  duplicate results.
-                  return Continue;
-               end if;
-            when others =>
-               --  Check it
-               null;
-            end case;
-         end;
-      end if;
-
-      if Parse.Parse
-        (Super, Shared, Parser_Index, Parse_Items, Config, 
Config.Resume_Token_Goal,
-         All_Conflicts => False,
-         Trace_Prefix  => "check")
-      then
-         Config.Error_Token.ID := Invalid_Token_ID;
-         --  FIXME: if there were conflicts, enqueue them; they might yield a
-         --  cheaper or same cost solution?
-         if Trace_McKenzie > Extra then
-            Put_Line (Super.Trace.all, Super.Label (Parser_Index), "check 
result: SUCCESS");
-         end if;
-         return Success;
-      end if;
-
-      --  Set Config.error to reflect failure, if it is at current token, so
-      --  Use_Minimal_Complete_Actions can see it.
-      declare
-         Item : Parse.Parse_Item renames 
Parse.Parse_Item_Array_Refs.Constant_Ref
-           (Parse_Items, First_Index (Parse_Items));
-      begin
-         if Item.Config.Check_Status.Label /= Ok then
-            Config.Check_Status := Item.Config.Check_Status;
-            Config.Error_Token  := Item.Config.Error_Token;
-
-            --  Explore cannot fix a check fail; only Language_Fixes can. The
-            --  "ignore error" case is handled immediately on return from
-            --  Language_Fixes in Process_One, below.
-            Result := Abandon;
-
-         elsif Item.Config.Error_Token.ID /= Invalid_Token_ID then
-
-            if Item.Shift_Count = 0 then
-               Config.Error_Token  := Item.Config.Error_Token;
-               Config.Check_Status := (Label => Ok);
-            else
-               --  Error is not at current token, but Explore might find 
something
-               --  that will help (see test_mckenzie_recover.adb Extra_Begin). 
On the
-               --  other hand, this can lead to lots of bogus configs (see
-               --  If_In_Handler).
-               Config.Error_Token.ID := Invalid_Token_ID;
-               Config.Check_Status   := (Label => Ok);
-            end if;
-         end if;
-      end;
-
-      --  All Parse_Items either failed or were not parsed; if they failed
-      --  and made progress, enqueue them.
-      for I in First_Index (Parse_Items) .. Last_Index (Parse_Items) loop
-         declare
-            Item : Parse.Parse_Item renames 
Parse.Parse_Item_Array_Refs.Variable_Ref (Parse_Items, I);
-         begin
-            --  When Parse starts above, Config.Current_Shared_Token matches
-            --  Config.Ops. So if Item.Config.Current_Shared_Token >
-            --  Config.Current_Shared_Token, it made some progress. Append or
-            --  update a Fast_Forward to indicate the changed edit point.
-            if Item.Config.Error_Token.ID /= Invalid_Token_ID and
-              Item.Config.Current_Shared_Token > Config.Current_Shared_Token
-            then
-               Item.Config.Minimal_Complete_State := None;
-               Item.Config.Matching_Begin_Done    := False;
-
-               if Constant_Ref (Item.Config.Ops, Last_Index 
(Item.Config.Ops)).Op = Fast_Forward then
-                  --  Update the trailing Fast_Forward.
-                  Variable_Ref (Item.Config.Ops, Last_Index 
(Item.Config.Ops)).FF_Token_Index :=
-                    Item.Config.Current_Shared_Token;
-               else
-                  if Is_Full (Item.Config.Ops) then
-                     Super.Config_Full ("check 1", Parser_Index);
-                     raise Bad_Config;
-                  else
-                     Append (Item.Config.Ops, (Fast_Forward, 
Item.Config.Current_Shared_Token));
-                  end if;
-               end if;
-               Local_Config_Heap.Add (Item.Config);
-               if Trace_McKenzie > Detail then
-                  Base.Put ("new error point ", Super, Shared, Parser_Index, 
Item.Config);
-               end if;
-            end if;
-         end;
-      end loop;
-
-      if Trace_McKenzie > Extra then
-         Put_Line (Super.Trace.all, Super.Label (Parser_Index), "check result: 
" & Result'Image);
-      end if;
-      return Result;
-   exception
-   when Bad_Config =>
-      return Abandon;
-   end Check;
-
-   function Check_Reduce_To_Start
-     (Super        : not null access Base.Supervisor;
-      Shared       : not null access Base.Shared;
-      Parser_Index : in              SAL.Base_Peek_Type;
-      Orig_Config  : in              Configuration)
-     return Boolean
-      --  Returns True if Config reduces to the start nonterm.
-   is
-      Table : Parse_Table renames Shared.Table.all;
-
-      function To_Reduce_Action (Item : in Minimal_Action) return 
Reduce_Action_Rec
-      is begin
-         return (Reduce, Item.Production, null, null, Item.Token_Count);
-      end To_Reduce_Action;
-
-      Local_Config_Heap : Config_Heaps.Heap_Type; -- never used, because 
Do_Language_Fixes is False.
-
-      Config  : Configuration                := Orig_Config;
-      Actions : Minimal_Action_Arrays.Vector := Table.States 
(Config.Stack.Peek.State).Minimal_Complete_Actions;
-   begin
-      loop
-         case Actions.Length is
-         when 0 =>
-            if (for some Item of Table.States (Config.Stack.Peek.State).Kernel 
=>
-                  Item.Production.LHS = Super.Trace.Descriptor.Accept_ID)
-            then
-               return True;
-            else
-               return False;
-            end if;
-
-         when 1 =>
-            case Actions (Actions.First_Index).Verb is
-            when Shift =>
-               return False;
-
-            when Reduce =>
-               Do_Reduce_1
-                 ("", Super, Shared, Parser_Index, Local_Config_Heap, Config,
-                  To_Reduce_Action (Actions (Actions.First_Index)),
-                  Do_Language_Fixes => False);
-
-               Actions := Table.States 
(Config.Stack.Peek.State).Minimal_Complete_Actions;
-            end case;
-
-         when others =>
-            return False;
-         end case;
-
-         --  loop only exits via returns above
-      end loop;
-   exception
-   when Bad_Config =>
-      --  From Do_Reduce_1
-      return False;
-   end Check_Reduce_To_Start;
-
-   procedure Try_Push_Back
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in              Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      Trace          : WisiToken.Trace'Class renames Super.Trace.all;
-      McKenzie_Param : McKenzie_Param_Type renames Shared.Table.McKenzie_Param;
-      Prev_Recover   : constant WisiToken.Base_Token_Index := 
Super.Parser_State (Parser_Index).Resume_Token_Goal;
-
-      Token : constant Recover_Token := Config.Stack.Peek.Token;
-   begin
-      --  Try pushing back the stack top, to allow insert and other
-      --  operations at that point.
-      --
-      --  Since we are not actually changing the source text, it is tempting
-      --  to give this operation zero cost. But then we keep doing push_back
-      --  forever, making no progress. So we give it a cost.
-
-      if Token.Min_Terminal_Index /= Invalid_Token_Index and
-        --  No point in pushing back an empty nonterm; that leads to duplicate
-        --  solutions with Undo_Reduce; see test_mckenzie_recover.adb Error_2.
-
-        (Prev_Recover = Invalid_Token_Index or else Prev_Recover < 
Token.Min_Terminal_Index)
-        --  Don't push back past previous error recover (that would require
-        --  keeping track of previous inserts/deletes, and would not be useful
-        --  in most cases).
-      then
-         declare
-            use Config_Op_Arrays;
-            New_Config : Configuration := Config;
-         begin
-            New_Config.Error_Token.ID := Invalid_Token_ID;
-            New_Config.Check_Status   := (Label => 
WisiToken.Semantic_Checks.Ok);
-
-            New_Config.Stack.Pop;
-
-            if Is_Full (New_Config.Ops) then
-               Super.Config_Full ("push_back 1", Parser_Index);
-               raise Bad_Config;
-            else
-               if Token.Min_Terminal_Index = Invalid_Token_Index then
-                  --  Token is empty; Config.current_shared_token does not 
change, no
-                  --  cost increase.
-                  Append (New_Config.Ops, (Push_Back, Token.ID, 
New_Config.Current_Shared_Token));
-               else
-                  New_Config.Cost := New_Config.Cost + 
McKenzie_Param.Push_Back (Token.ID);
-                  Append (New_Config.Ops, (Push_Back, Token.ID, 
Token.Min_Terminal_Index));
-                  New_Config.Current_Shared_Token := Token.Min_Terminal_Index;
-               end if;
-            end if;
-            New_Config.Strategy_Counts (Push_Back) := 
New_Config.Strategy_Counts (Push_Back) + 1;
-
-            Local_Config_Heap.Add (New_Config);
-
-            if Trace_McKenzie > Detail then
-               Base.Put ("push_back " & Image (Token.ID, 
Trace.Descriptor.all), Super, Shared,
-                         Parser_Index, New_Config);
-            end if;
-         end;
-      end if;
-   end Try_Push_Back;
-
-   function Just_Pushed_Back_Or_Deleted (Config : in Configuration; ID : in 
Token_ID) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-      Last_Token_Index : WisiToken.Token_Index := Config.Current_Shared_Token;
-      --  Index of token in last op checked.
-   begin
-      --  This function is called when considering whether to insert ID before
-      --  Config.Current_Shared_Token.
-      --
-      --  We need to consider more than one recent op here; see 
test_mckenzie_recover.adb
-      --  Check_Multiple_Delete_For_Insert. Checking only one op allows this 
solution there:
-      --
-      --  ...  (DELETE, END, 7), (DELETE, SEMICOLON, 8), (INSERT, END, 9), 
(INSERT, SEMICOLON, 9)
-      --
-      for I in reverse First_Index (Config.Ops) .. Last_Index (Config.Ops) loop
-         declare
-            Op : Config_Op renames Constant_Ref (Config.Ops, I);
-         begin
-            case Op.Op is
-            when Push_Back =>
-               --  The case we are preventing for Push_Back is typically one 
of:
-               --  (PUSH_BACK, Identifier, 2), (INSERT, Identifier, 2)
-               --  (PUSH_BACK, Identifier, 2), (PUSH_BACK, END, 3), (INSERT, 
Identifier, 3), (INSERT, END, 3),
-               if Op.PB_Token_Index = Last_Token_Index then
-                  if Op.PB_ID = ID then
-                     return True;
-                  else
-                     if Op.PB_Token_Index = WisiToken.Token_Index'First then
-                        return False;
-                     else
-                        Last_Token_Index := Op.PB_Token_Index - 1;
-                     end if;
-                  end if;
-               else
-                  --  Op is at a different edit point.
-                  return False;
-               end if;
-
-            when Delete =>
-               if Op.Del_Token_Index = Last_Token_Index - 1 then
-                  if Op.Del_ID = ID then
-                     return True;
-                  else
-                     Last_Token_Index := Op.Del_Token_Index;
-                  end if;
-               else
-                  --  Op is at a different edit point.
-                  return False;
-               end if;
-
-            when Fast_Forward | Insert | Undo_Reduce =>
-               return False;
-            end case;
-         end;
-      end loop;
-      return False;
-   end Just_Pushed_Back_Or_Deleted;
-
-   procedure Try_Undo_Reduce
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in              Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      use Config_Op_Arrays;
-
-      Trace          : WisiToken.Trace'Class renames Super.Trace.all;
-      McKenzie_Param : McKenzie_Param_Type renames Shared.Table.McKenzie_Param;
-      Token          : constant Recover_Token := Config.Stack.Peek.Token;
-      New_Config     : Configuration          := Config;
-      Token_Count    : Ada.Containers.Count_Type;
-   begin
-      --  Try expanding the nonterm on the stack top, to allow pushing_back
-      --  its components, or insert and other operations at that point.
-
-      New_Config.Error_Token.ID := Invalid_Token_ID;
-      New_Config.Check_Status   := (Label => WisiToken.Semantic_Checks.Ok);
-
-      Token_Count := Undo_Reduce (New_Config.Stack, Super.Parser_State 
(Parser_Index).Tree);
-
-      if Token.Min_Terminal_Index /= Invalid_Token_Index  then
-         --  If Token is empty no cost increase.
-         New_Config.Cost := New_Config.Cost + McKenzie_Param.Undo_Reduce 
(Token.ID);
-      end if;
-
-      if Is_Full (New_Config.Ops) then
-         Super.Config_Full ("undo_reduce 1", Parser_Index);
-         raise Bad_Config;
-      else
-         Append (New_Config.Ops, (Undo_Reduce, Token.ID, Token_Count));
-      end if;
-      New_Config.Strategy_Counts (Undo_Reduce) := New_Config.Strategy_Counts 
(Undo_Reduce) + 1;
-
-      Local_Config_Heap.Add (New_Config);
-
-      if Trace_McKenzie > Detail then
-         Base.Put ("undo_reduce " & Image (Token.ID, Trace.Descriptor.all), 
Super, Shared,
-                   Parser_Index, New_Config);
-      end if;
-   end Try_Undo_Reduce;
-
-   procedure Insert_From_Action_List
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in              Configuration;
-      Minimal_Insert    : in              Token_ID_Arrays.Vector;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      Table      : Parse_Table renames Shared.Table.all;
-      EOF_ID     : Token_ID renames Super.Trace.Descriptor.EOI_ID;
-      Descriptor : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-
-      --  Find terminal insertions from the current state's action_list to try.
-      --
-      --  We perform any needed reductions and one shift, so the config is
-      --  in a consistent state, and enqueue the result. If there are any
-      --  conflicts or semantic check fails encountered, they create other
-      --  configs to enqueue.
-
-      Current_Token : constant Token_ID := Current_Token_ID_Peek
-        (Shared.Terminals.all, Config.Current_Shared_Token, 
Config.Insert_Delete, Config.Current_Insert_Delete);
-
-      Cached_Config : Configuration;
-      Cached_Action : Reduce_Action_Rec;
-      --  Most of the time, all the reductions in a state are the same. So
-      --  we cache the first result. This includes one reduction; if an
-      --  associated semantic check failed, this does not include the fixes.
-
-      I : Parse_Action_Node_Ptr;
-   begin
-      for Node of Table.States (Config.Stack.Peek.State).Action_List loop
-         I := Node.Actions;
-         loop
-            exit when I = null;
-            declare
-               ID     : constant Token_ID := Node.Symbol;
-               Action : Parse_Action_Rec renames I.Item;
-            begin
-               if ID /= EOF_ID and then -- can't insert eof
-                 ID /= Invalid_Token_ID -- invalid when Verb = Error
-               then
-                  if Just_Pushed_Back_Or_Deleted (Config, ID) then
-                     if Trace_McKenzie > Extra then
-                        Put_Line
-                          (Super.Trace.all, Super.Label (Parser_Index), 
"Insert: abandon " & Image (ID, Descriptor) &
-                             ": undo push_back");
-                     end if;
-                  elsif ID = Current_Token then
-                     --  This is needed because we allow explore when the 
error is not at
-                     --  the explore point; it prevents inserting useless 
tokens (ie
-                     --  'identifier ;' in ada_lite).
-                     if Trace_McKenzie > Extra then
-                        Put_Line
-                          (Super.Trace.all, Super.Label (Parser_Index), 
"Insert: abandon " & Image (ID, Descriptor) &
-                             ": current token");
-                     end if;
-
-                  elsif (for some Minimal of Minimal_Insert => ID = Minimal) 
then
-                     --  Was inserted by Insert_Minimal_Complete_Actions
-                     null;
-
-                  else
-                     case Action.Verb is
-                     when Shift =>
-                        declare
-                           New_Config : Configuration := Config;
-                        begin
-                           Do_Shift
-                             ("Insert", Super, Shared, Parser_Index, 
Local_Config_Heap, New_Config, Action.State, ID,
-                              Cost_Delta => 0,
-                              Strategy   => Insert);
-                        end;
-
-                     when Reduce =>
-                        if not Equal (Action, Cached_Action) then
-                           declare
-                              New_Config : Configuration := Config;
-                           begin
-                              New_Config.Error_Token.ID := Invalid_Token_ID;
-                              New_Config.Check_Status   := (Label => 
WisiToken.Semantic_Checks.Ok);
-
-                              Do_Reduce_1
-                                ("Insert", Super, Shared, Parser_Index, 
Local_Config_Heap, New_Config, Action);
-                              Cached_Config := New_Config;
-                              Cached_Action := Action;
-
-                              Do_Reduce_2
-                                ("Insert", Super, Shared, Parser_Index, 
Local_Config_Heap, New_Config, ID,
-                                 Cost_Delta => 0,
-                                 Strategy   => Insert);
-                           end;
-
-                        else
-                           declare
-                              New_Config : Configuration := Cached_Config;
-                           begin
-                              Do_Reduce_2
-                                ("Insert", Super, Shared, Parser_Index, 
Local_Config_Heap, New_Config, ID,
-                                 Cost_Delta => 0,
-                                 Strategy   => Insert);
-                           end;
-                        end if;
-
-                     when Accept_It =>
-                        raise SAL.Programmer_Error with "found test case for 
Process_One Accept_It";
-
-                     when Error =>
-                        null;
-                     end case;
-                  end if;
-               end if;
-            end;
-            I := I.Next;
-         end loop;
-      end loop;
-   end Insert_From_Action_List;
-
-   function Insert_Minimal_Complete_Actions
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Orig_Config       : in out          Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-     return Token_ID_Arrays.Vector
-      --  Return tokens inserted (empty if none).
-   is
-      use Ada.Containers;
-
-      Table         : Parse_Table renames Shared.Table.all;
-      Descriptor    : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-      Inserted      : Token_ID_Array (1 .. 10) := (others => Invalid_Token_ID);
-      Inserted_Last : Integer                  := Inserted'First - 1;
-
-      type Work_Item is record
-         Action     : Minimal_Action;
-         Cost_Delta : Integer;
-         Config     : Configuration;
-      end record;
-
-      package Item_Queues is new SAL.Gen_Bounded_Definite_Queues (Work_Item);
-      use Item_Queues;
-
-      Work : Queue_Type (10);
-      --  The required queue size depends on the number of multiple-item
-      --  Minimal_Complete_Actions encountered. That is limited by compound
-      --  statement nesting, and by the frequency of such actions.
-
-      procedure Safe_Add_Work (Label : in String; Item : in Work_Item)
-      is begin
-         if Is_Full (Work) then
-            Super.Config_Full ("Minimal_Complete_Actions " & Label, 
Parser_Index);
-            raise Bad_Config;
-         else
-            Add (Work, Item);
-         end if;
-      end Safe_Add_Work;
-
-      function To_Reduce_Action (Action : in Minimal_Action) return 
Reduce_Action_Rec
-        is (Reduce, Action.Production, null, null, Action.Token_Count);
-
-      procedure Minimal_Do_Shift
-        (Action     : in     Minimal_Action;
-         Cost_Delta : in     Integer;
-         Config     : in out Configuration)
-      is begin
-         if Just_Pushed_Back_Or_Deleted (Config, Action.ID) then
-            if Trace_McKenzie > Extra then
-               Put_Line
-                 (Super.Trace.all, Super.Label (Parser_Index),
-                  "Minimal_Complete_Actions: abandon " & Image (Action.ID, 
Descriptor) & ": undo push back");
-            end if;
-         else
-            Config.Check_Status           := (Label => 
WisiToken.Semantic_Checks.Ok);
-            Config.Minimal_Complete_State := Active;
-            Inserted_Last                 := Inserted_Last + 1;
-            if Inserted_Last <= Inserted'Last then
-               Inserted (Inserted_Last)      := Action.ID;
-            else
-               Super.Config_Full ("minimal_do_shift Inserted", Parser_Index);
-               raise Bad_Config;
-            end if;
-
-            Do_Shift
-              ("Minimal_Complete_Actions", Super, Shared, Parser_Index, 
Local_Config_Heap, Config,
-               Action.State, Action.ID, Cost_Delta,
-               Strategy => Minimal_Complete);
-         end if;
-      end Minimal_Do_Shift;
-
-      procedure Enqueue_Min_Actions
-        (Label   : in String;
-         Actions : in Minimal_Action_Arrays.Vector;
-         Config  : in Configuration)
-      is
-         use SAL;
-         Length : array (Actions.First_Index .. Actions.Last_Index) of 
Count_Type := (others => Count_Type'Last);
-
-         Min_Length : Count_Type := Count_Type'Last;
-      begin
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Super.Trace.all, Super.Label (Parser_Index), 
"Minimal_Complete_Actions: " & Label &
-                 Image (Actions, Descriptor));
-         end if;
-
-         if Actions.Length = 0 then
-            return;
-         elsif Actions.Length = 1 then
-            Safe_Add_Work
-              ("1", (Actions (Actions.First_Index), 
Table.McKenzie_Param.Minimal_Complete_Cost_Delta, Config));
-            return;
-         end if;
-
-         --  More than one minimal action in State; try to use next states and
-         --  recursion to pick one.
-         Actions_Loop :
-         for I in Actions.First_Index .. Actions.Last_Index loop
-            declare
-               function Matches (Item : in Kernel_Info; Action : in 
Minimal_Action) return Boolean
-               is begin
-                  case Action.Verb is
-                  when Shift =>
-                     return Item.Before_Dot = Action.ID;
-                  when Reduce =>
-                     return Item.Before_Dot = Action.Production.LHS;
-                  end case;
-               end Matches;
-
-               function Length_After_Dot
-                 (Item   : in Kernel_Info;
-                  Action : in Minimal_Action;
-                  Stack  : in Recover_Stacks.Stack)
-                 return Ada.Containers.Count_Type
-               is
-                  Match_ID   : Token_ID;
-                  New_Stack  : Recover_Stacks.Stack      := Stack;
-                  Next_State : Unknown_State_Index;
-                  Result     : Ada.Containers.Count_Type;
-                  Min_Result : Ada.Containers.Count_Type := 
Ada.Containers.Count_Type'Last;
-               begin
-                  case Action.Verb is
-                  when Shift =>
-                     New_Stack.Push
-                       ((Action.State, Invalid_Node_Index, (ID => Action.ID, 
others => <>)));
-                     Next_State := Action.State;
-                     Match_ID   := Action.ID;
-
-                  when Reduce =>
-                     New_Stack.Pop (SAL.Base_Peek_Type (Action.Token_Count));
-                     Next_State := Goto_For (Shared.Table.all, 
New_Stack.Peek.State, Action.Production.LHS);
-                     if Next_State = Unknown_State then
-                        --  We get here when Insert_From_Action_Table started 
us down a bad path
-                        raise Bad_Config;
-                     end if;
-
-                     New_Stack.Push
-                       ((Next_State, Invalid_Node_Index, (ID => 
Action.Production.LHS, others => <>)));
-                     Match_ID   := Action.Production.LHS;
-                  end case;
-
-                  if Trace_McKenzie > Extra then
-                     Super.Trace.Put (Next_State'Image & " " & Trimmed_Image 
(Item.Production));
-                  end if;
-
-                  for Item of Shared.Table.States (Next_State).Kernel loop
-                     if Item.Before_Dot = Match_ID then
-                        if Item.Length_After_Dot = 0 then
-                           Result := Length_After_Dot
-                             (Item, (Reduce, Item.Reduce_Production, 
Item.Reduce_Count), New_Stack);
-                        else
-                           Result := Item.Length_After_Dot;
-                        end if;
-                     end if;
-
-                     if Result < Min_Result then
-                        Min_Result := Result;
-                     end if;
-                  end loop;
-                  return Min_Result;
-               end Length_After_Dot;
-
-               Action     : constant Minimal_Action := Actions (I);
-               Next_State : constant State_Index    :=
-                 (case Action.Verb is
-                  when Shift  => Action.State,
-                  when Reduce => Goto_For
-                    (Shared.Table.all,
-                     Config.Stack.Peek (Base_Peek_Type (Action.Token_Count) + 
1).State,
-                     Action.Production.LHS));
-            begin
-               if Trace_McKenzie > Extra then
-                  Super.Trace.Put
-                    ("task" & Task_Attributes.Value'Image &
-                       Super.Label (Parser_Index)'Image & ": 
Minimal_Complete_Actions: " &
-                       Image (Action, Descriptor));
-               end if;
-
-               for Item of Shared.Table.States (Next_State).Kernel loop
-
-                  if Matches (Item, Action) then
-                     --  For Action.Verb = Reduce, more than one item may match
-                     if Item.Length_After_Dot = 0 then
-                        --  Set Length from a non-zero-length non-recursive 
item.
-                        Length (I) := Length_After_Dot (Item, Action, 
Config.Stack);
-
-                     elsif Item.Length_After_Dot < Length (I) then
-                        if Trace_McKenzie > Extra then
-                           --  Length_After_Dot outputs this in other branch
-                           Super.Trace.Put (Next_State'Image & " " & 
Trimmed_Image (Item.Production));
-                        end if;
-                        Length (I) := Item.Length_After_Dot;
-
-                     end if;
-
-                     if Trace_McKenzie > Extra then
-                        Super.Trace.Put (" length" & Length (I)'Image);
-                     end if;
-                     if Length (I) < Min_Length then
-                        Min_Length := Length (I);
-                     end if;
-                  end if;
-               end loop;
-               if Trace_McKenzie > Extra then
-                  Super.Trace.New_Line;
-               end if;
-            end;
-         end loop Actions_Loop;
-
-         for I in Length'Range loop
-            if Length (I) = Min_Length then
-               Safe_Add_Work ("2", (Actions (I), 
Table.McKenzie_Param.Minimal_Complete_Cost_Delta, Config));
-
-            elsif Trace_McKenzie > Extra then
-               Put_Line
-                 (Super.Trace.all, Super.Label (Parser_Index), 
"Minimal_Complete_Actions: drop " &
-                    Image (Actions (I), Descriptor) & " not minimal or 
recursive");
-            end if;
-         end loop;
-      end Enqueue_Min_Actions;
-
-   begin
-      if Orig_Config.Stack.Depth = 1 then
-         --  Get here with an empty source file, or a syntax error on the first
-         --  token.
-         return Token_ID_Arrays.Empty_Vector;
-
-      elsif Orig_Config.Minimal_Complete_State = Done then
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Super.Trace.all, Super.Label (Parser_Index), 
"Minimal_Complete_Actions: done");
-         end if;
-         return Token_ID_Arrays.Empty_Vector;
-      end if;
-
-      Enqueue_Min_Actions ("", Table.States 
(Orig_Config.Stack.Peek.State).Minimal_Complete_Actions, Orig_Config);
-
-      loop
-         exit when Is_Empty (Work);
-
-         declare
-            Item : Work_Item := Get (Work);
-         begin
-            if Trace_McKenzie > Extra then
-               Put_Line
-                 (Super.Trace.all, Super.Label (Parser_Index), 
"Minimal_Complete_Actions: dequeue work item " &
-                    Image (Item.Action, Descriptor));
-            end if;
-
-            case Item.Action.Verb is
-            when Reduce =>
-               --  Do a reduce, look at resulting state. Keep reducing until 
we can't
-               --  anymore.
-               declare
-                  Reduce_Action : Reduce_Action_Rec := To_Reduce_Action 
(Item.Action);
-                  Actions       : Minimal_Action_Arrays.Vector;
-               begin
-                  loop
-                     Do_Reduce_1
-                       ("Minimal_Complete_Actions", Super, Shared, 
Parser_Index, Local_Config_Heap, Item.Config,
-                        Reduce_Action,
-                        Do_Language_Fixes => False);
-
-                     Actions := Table.States 
(Item.Config.Stack.Peek.State).Minimal_Complete_Actions;
-
-                     case Actions.Length is
-                     when 0 =>
-                        if Trace_McKenzie > Extra then
-                           Put_Line
-                             (Super.Trace.all, Super.Label (Parser_Index),
-                              "Minimal_Complete_Actions abandoned: no 
actions");
-                        end if;
-                        exit;
-                     when 1 =>
-                        case Actions (Actions.First_Index).Verb is
-                        when Shift =>
-                           Minimal_Do_Shift (Actions (Actions.First_Index), 
Item.Cost_Delta, Item.Config);
-                           exit;
-                        when Reduce =>
-                           Reduce_Action := To_Reduce_Action (Actions 
(Actions.First_Index));
-                        end case;
-
-                     when others =>
-                        Enqueue_Min_Actions ("multiple actions ", Actions, 
Item.Config);
-                        exit;
-                     end case;
-                  end loop;
-               end;
-
-            when Shift =>
-               Minimal_Do_Shift (Item.Action, Item.Cost_Delta, Item.Config);
-            end case;
-         end;
-      end loop;
-
-      if Inserted_Last = Inserted'First - 1 then
-         --  Nothing inserted this round.
-         if Orig_Config.Minimal_Complete_State = Active then
-            Orig_Config.Minimal_Complete_State := Done;
-         end if;
-      end if;
-
-      return To_Vector (Inserted (1 .. Inserted_Last));
-   exception
-   when Bad_Config =>
-      return Token_ID_Arrays.Empty_Vector;
-   end Insert_Minimal_Complete_Actions;
-
-   procedure Insert_Matching_Begin
-     (Super                 : not null access Base.Supervisor;
-      Shared                : not null access Base.Shared;
-      Parser_Index          : in              SAL.Base_Peek_Type;
-      Config                : in              Configuration;
-      Local_Config_Heap     : in out          Config_Heaps.Heap_Type;
-      Matching_Begin_Tokens : in              Token_ID_Arrays.Vector)
-   is
-      Table      : Parse_Table renames Shared.Table.all;
-      Descriptor : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-   begin
-      --  We don't check for insert = current token; that's either ok or a
-      --  severe bug in Shared.Language_Matching_Begin_Tokens.
-
-      if Config.Matching_Begin_Done then
-         if Trace_McKenzie > Extra then
-            Put_Line (Super.Trace.all, Super.Label (Parser_Index), 
"Matching_Begin abandoned: done");
-         end if;
-         return;
-      end if;
-
-      if Just_Pushed_Back_Or_Deleted (Config, Matching_Begin_Tokens 
(Matching_Begin_Tokens.First_Index)) then
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Super.Trace.all, Super.Label (Parser_Index), "Matching_Begin 
abandoned " &
-                 Image (Matching_Begin_Tokens 
(Matching_Begin_Tokens.First_Index), Descriptor) & ": undo push_back");
-         end if;
-         return;
-      end if;
-
-      declare
-         New_Config  : Configuration := Config;
-      begin
-         for ID of Matching_Begin_Tokens loop
-            Insert (New_Config, ID);
-         end loop;
-
-         declare
-            use Parse.Parse_Item_Arrays;
-            Parse_Items : aliased Parse.Parse_Item_Arrays.Vector;
-            Dummy : constant Boolean :=  Parse.Parse
-              (Super, Shared, Parser_Index, Parse_Items, New_Config,
-               Shared_Token_Goal => Invalid_Token_Index,
-               All_Conflicts     => True,
-               Trace_Prefix      => "parse Matching_Begin");
-         begin
-            for I in First_Index (Parse_Items) .. Last_Index (Parse_Items) loop
-               declare
-                  Item : Parse.Parse_Item renames 
Parse.Parse_Item_Array_Refs.Variable_Ref (Parse_Items, I);
-               begin
-                  if Item.Parsed and Item.Config.Current_Insert_Delete = 
No_Insert_Delete then
-                     Item.Config.Matching_Begin_Done := True;
-                     Item.Config.Cost := Item.Config.Cost + 
Table.McKenzie_Param.Matching_Begin;
-                     Item.Config.Strategy_Counts (Matching_Begin) := 
Item.Config.Strategy_Counts (Matching_Begin) + 1;
-                     Item.Config.Error_Token.ID := Invalid_Token_ID;
-                     Item.Config.Check_Status := (Label => 
WisiToken.Semantic_Checks.Ok);
-
-                     if Trace_McKenzie > Detail then
-                        Base.Put
-                          ("Matching_Begin: insert " & Image 
(Matching_Begin_Tokens, Descriptor),
-                           Super, Shared, Parser_Index, Item.Config);
-                     end if;
-                     Local_Config_Heap.Add (Item.Config);
-                  else
-                     if Trace_McKenzie > Detail then
-                        Base.Put
-                          ("Matching_Begin: abandon " & Image 
(Matching_Begin_Tokens, Descriptor) & ": parse fail",
-                           Super, Shared, Parser_Index, Item.Config);
-                     end if;
-                  end if;
-               end;
-            end loop;
-         end;
-      end;
-   exception
-   when SAL.Container_Full =>
-      --  From config_ops_sorted
-      Super.Config_Full ("Minimal_Complete_Actions 3", Parser_Index);
-   end Insert_Matching_Begin;
-
-   procedure Try_Insert_Terminal
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in out          Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      use all type 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Tokens                : Token_ID_Array_1_3;
-      Matching_Begin_Tokens : Token_ID_Arrays.Vector;
-      Forbid_Minimal_Insert : Boolean := False;
-
-      Minimal_Inserted : Token_ID_Arrays.Vector;
-   begin
-      if Shared.Language_Matching_Begin_Tokens /= null then
-         Current_Token_ID_Peek_3
-           (Shared.Terminals.all, Config.Current_Shared_Token, 
Config.Insert_Delete, Config.Current_Insert_Delete,
-            Tokens);
-
-         Shared.Language_Matching_Begin_Tokens (Tokens, Config, 
Matching_Begin_Tokens, Forbid_Minimal_Insert);
-      end if;
-
-      if not Forbid_Minimal_Insert then
-         --  See test_mckenzie_recover.adb Forbid_Minimal_Insert for rationale.
-         Minimal_Inserted := Insert_Minimal_Complete_Actions
-           (Super, Shared, Parser_Index, Config, Local_Config_Heap);
-      end if;
-
-      if Matching_Begin_Tokens.Length > 0 then
-         Insert_Matching_Begin (Super, Shared, Parser_Index, Config, 
Local_Config_Heap, Matching_Begin_Tokens);
-      end if;
-
-      --  We always do all three; Insert_Minimal_Complete (unless
-      --  Forbid_Minimal_Insert), Insert_Matching_Begin,
-      --  Insert_From_Action_List; in general it's not possible to tell when
-      --  one will be better (see test_mckenzie_recover.adb
-      --  Always_Minimal_Complete, Always_Matching_Begin).
-      --  Insert_From_Action_List does not insert the Minimal_Inserted tokens,
-      --  and it will never insert the Matching_Begin_Tokens, so there is no
-      --  duplication. Insert_From_Action_List will normally be more
-      --  expensive.
-      Insert_From_Action_List (Super, Shared, Parser_Index, Config, 
Minimal_Inserted, Local_Config_Heap);
-
-      --  It is tempting to use the Goto_List to find nonterms to insert.
-      --  But that can easily lead to error states, and it turns out to be
-      --  not useful, especially if the grammar has been relaxed so most
-      --  expressions and lists can be empty.
-
-   exception
-   when Bad_Config =>
-      null;
-   end Try_Insert_Terminal;
-
-   procedure Try_Insert_Quote
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in out          Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      use Config_Op_Arrays;
-      use all type Parser.Language_String_ID_Set_Access;
-
-      Descriptor  : WisiToken.Descriptor renames Shared.Trace.Descriptor.all;
-      Check_Limit : WisiToken.Token_Index renames 
Shared.Table.McKenzie_Param.Check_Limit;
-
-      Current_Line            : constant Line_Number_Type := 
Shared.Terminals.all (Config.Current_Shared_Token).Line;
-      Lexer_Error_Token       : Base_Token;
-
-      function Recovered_Lexer_Error (Line : in Line_Number_Type) return 
Base_Token_Index
-      is begin
-         --  We are assuming the list of lexer errors is short, so binary
-         --  search would not be significantly faster.
-         for Err of reverse Shared.Lexer.Errors loop
-            if Err.Recover_Token /= Invalid_Token_Index and then
-              Shared.Terminals.all (Err.Recover_Token).Line = Line
-            then
-               return Err.Recover_Token;
-            end if;
-         end loop;
-         return Invalid_Token_Index;
-      end Recovered_Lexer_Error;
-
-      Lexer_Error_Token_Index : constant Base_Token_Index := 
Recovered_Lexer_Error (Current_Line);
-
-      function String_ID_Set (String_ID : in Token_ID) return Token_ID_Set
-      is begin
-         if Shared.Language_String_ID_Set = null then
-            return (String_ID .. String_ID => True);
-         else
-            return Shared.Language_String_ID_Set (Descriptor, String_ID);
-         end if;
-      end String_ID_Set;
-
-      procedure String_Literal_In_Stack
-        (Label             : in     String;
-         New_Config        : in out Configuration;
-         Matching          : in     SAL.Peek_Type;
-         String_Literal_ID : in     Token_ID)
-      is
-         Saved_Shared_Token : constant WisiToken.Token_Index := 
New_Config.Current_Shared_Token;
-
-         Tok         : Recover_Token;
-         J           : WisiToken.Token_Index;
-         Parse_Items : aliased Parse.Parse_Item_Arrays.Vector;
-      begin
-         --  Matching is the index of a token on New_Config.Stack containing a 
string
-         --  literal. Push back thru that token, then delete all tokens after
-         --  the string literal to Saved_Shared_Token.
-         if not Has_Space (New_Config.Ops, Ada.Containers.Count_Type 
(Matching)) then
-            Super.Config_Full ("insert quote 1 " & Label, Parser_Index);
-            raise Bad_Config;
-         end if;
-         for I in 1 .. Matching loop
-            if Push_Back_Valid (New_Config) then
-               Tok := New_Config.Stack.Pop.Token;
-               Append (New_Config.Ops, (Push_Back, Tok.ID, 
Tok.Min_Terminal_Index));
-            else
-               --  Probably pushing back thru a previously inserted token
-               raise Bad_Config;
-            end if;
-         end loop;
-
-         New_Config.Current_Shared_Token := Tok.Min_Terminal_Index;
-
-         --  Find last string literal in pushed back terminals.
-         J := Saved_Shared_Token - 1;
-         loop
-            exit when Shared.Terminals.all (J).ID = String_Literal_ID;
-            J := J - 1;
-         end loop;
-
-         begin
-            if Parse.Parse
-              (Super, Shared, Parser_Index, Parse_Items, New_Config,
-               Shared_Token_Goal => J,
-               All_Conflicts     => False,
-               Trace_Prefix      => "insert quote parse pushback " & Label)
-            then
-               --  The non-deleted tokens parsed without error. We don't care 
if any
-               --  conflicts were encountered; we are not using the parse 
result.
-               New_Config := Parse.Parse_Item_Array_Refs.Constant_Ref 
(Parse_Items, 1).Config;
-               Append (New_Config.Ops, (Fast_Forward, 
New_Config.Current_Shared_Token));
-            else
-               raise SAL.Programmer_Error;
-            end if;
-         exception
-         when Bad_Config =>
-            raise SAL.Programmer_Error;
-         end;
-
-         if New_Config.Current_Shared_Token < Saved_Shared_Token - 1 and then
-           (not Has_Space
-              (New_Config.Ops, Ada.Containers.Count_Type (Saved_Shared_Token - 
1 - New_Config.Current_Shared_Token)))
-         then
-            Super.Config_Full ("insert quote 2 " & Label, Parser_Index);
-            raise Bad_Config;
-         end if;
-
-         for J in New_Config.Current_Shared_Token .. Saved_Shared_Token - 1 
loop
-            Append (New_Config.Ops, (Delete, Shared.Terminals.all (J).ID, J));
-         end loop;
-
-         New_Config.Current_Shared_Token := Saved_Shared_Token;
-
-      end String_Literal_In_Stack;
-
-      procedure Push_Back_Tokens
-        (Full_Label            : in     String;
-         New_Config            : in out Configuration;
-         Min_Pushed_Back_Index :    out Base_Token_Index)
-      is
-         Item : Recover_Stack_Item;
-      begin
-         loop
-            Item := New_Config.Stack.Peek;
-            if Item.Token.Virtual then
-               --  Don't push back an inserted token
-               exit;
-
-            elsif Item.Token.Byte_Region = Null_Buffer_Region then
-               --  Don't need push_back for an empty token
-               New_Config.Stack.Pop;
-
-            elsif Item.Tree_Index = Invalid_Node_Index then
-               --  Item was pushed on stack during recovery, and we do not know
-               --  its Line. To avoid crossing a line boundary, we stop 
push_backs
-               --  here.
-               exit;
-
-            else
-               if Shared.Terminals.all
-                 (Super.Parser_State (Parser_Index).Tree.First_Shared_Terminal 
(Item.Tree_Index)).Line = Current_Line
-                 --  Don't let push_back cross a line boundary.
-               then
-                  if Is_Full (New_Config.Ops) then
-                     Super.Config_Full (Full_Label, Parser_Index);
-                     raise Bad_Config;
-                  else
-                     New_Config.Stack.Pop;
-                     Append (New_Config.Ops, (Push_Back, Item.Token.ID, 
Item.Token.Min_Terminal_Index));
-                  end if;
-               end if;
-
-               exit;
-            end if;
-         end loop;
-         Min_Pushed_Back_Index := Item.Token.Min_Terminal_Index;
-      end Push_Back_Tokens;
-
-      procedure Finish
-        (Label       : in     String;
-         New_Config  : in out Configuration;
-         First, Last : in     Base_Token_Index)
-      is
-         Adj_First : constant Base_Token_Index := (if First = 
Invalid_Token_Index then Last else First);
-         Adj_Last  : constant Base_Token_Index := (if Last = 
Invalid_Token_Index then First else Last);
-      begin
-         --  Delete tokens First .. Last; either First - 1 or Last + 1 should
-         --  be a String_Literal. Leave Current_Shared_Token at Last + 1.
-
-         if Adj_Last = Invalid_Token_Index or Adj_First = Invalid_Token_Index 
then
-            pragma Assert (False);
-            raise Bad_Config;
-         end if;
-
-         New_Config.Error_Token.ID := Invalid_Token_ID;
-         New_Config.Check_Status   := (Label => WisiToken.Semantic_Checks.Ok);
-
-         --  This is a guess, so we give it a nominal cost
-         New_Config.Cost := New_Config.Cost + 1;
-
-         if not Has_Space (New_Config.Ops, Ada.Containers.Count_Type (Last - 
First)) then
-            Super.Config_Full ("insert quote 3 " & Label, Parser_Index);
-            raise Bad_Config;
-         end if;
-
-         for I in Adj_First .. Adj_Last loop
-            Append (New_Config.Ops, (Delete, Shared.Terminals.all (I).ID, I));
-         end loop;
-         New_Config.Current_Shared_Token := Last + 1;
-
-         --  Let explore do insert after these deletes.
-         Append (New_Config.Ops, (Fast_Forward, 
New_Config.Current_Shared_Token));
-
-         if New_Config.Resume_Token_Goal - Check_Limit < 
New_Config.Current_Shared_Token then
-            New_Config.Resume_Token_Goal := New_Config.Current_Shared_Token + 
Check_Limit;
-            if Trace_McKenzie > Extra then
-               Put_Line
-                 (Super.Trace.all, Super.Label (Parser_Index), 
"resume_token_goal:" & WisiToken.Token_Index'Image
-                    (New_Config.Resume_Token_Goal));
-            end if;
-         end if;
-
-         New_Config.Strategy_Counts (String_Quote) := 
New_Config.Strategy_Counts (String_Quote) + 1;
-
-         if Trace_McKenzie > Detail then
-            Base.Put ("insert quote " & Label & " ", Super, Shared, 
Parser_Index, New_Config);
-         end if;
-      end Finish;
-
-   begin
-      --  When the lexer finds an unbalanced quote, it inserts a virtual
-      --  balancing quote at the same character position as the unbalanced
-      --  quote, returning an empty string literal token there. The parser
-      --  does not see that as an error; it encounters a syntax error
-      --  before, at, or after that string literal.
-      --
-      --  Here we assume the parse error in Config.Error_Token is due to
-      --  putting the balancing quote in the wrong place (although we do
-      --  check that; see test_mckenzie_recover.adb String_Quote_6), and
-      --  attempt to find a better place to put the balancing quote. Then
-      --  all tokens from the balancing quote to the unbalanced quote are
-      --  now part of a string literal, so delete them, leaving just the
-      --  string literal created by Lexer error recovery.
-
-      --  First we check to see if there is an unbalanced quote in the
-      --  current line; if not, just return. Some lexer errors are for other
-      --  unrecognized characters; see ada_mode-recover_bad_char.adb.
-      --
-      --  An alternate strategy is to treat the lexer error as a parse error
-      --  immediately, but that complicates the parse logic.
-
-      Config.String_Quote_Checked := Current_Line;
-
-      if Lexer_Error_Token_Index = Invalid_Token_Index then
-         return;
-      end if;
-
-      Lexer_Error_Token := Shared.Terminals.all (Lexer_Error_Token_Index);
-
-      --  It is not possible to tell where the best place to put the
-      --  balancing quote is, so we always try all reasonable places.
-
-      if Lexer_Error_Token.Byte_Region.First = 
Config.Error_Token.Byte_Region.First then
-         --  The parse error token is the string literal at the lexer error.
-         --
-         --  case a: Insert the balancing quote somewhere before the error
-         --  point. There is no way to tell how far back to put the balancing
-         --  quote, so we just do one non-empty token. See
-         --  test_mckenzie_recover.adb String_Quote_0. So far we have not found
-         --  a test case for more than one token.
-         declare
-            New_Config            : Configuration := Config;
-            Min_Pushed_Back_Index : Base_Token_Index;
-         begin
-            Push_Back_Tokens ("insert quote 4 a", New_Config, 
Min_Pushed_Back_Index);
-            Finish ("a", New_Config, Min_Pushed_Back_Index, 
Config.Current_Shared_Token - 1);
-            Local_Config_Heap.Add (New_Config);
-         end;
-
-         --  Note that it is not reasonable to insert a quote after the error
-         --  in this case. If that were the right solution, the parser error
-         --  token would not be the lexer repaired string literal, since a
-         --  string literal would be legal here.
-
-      elsif Lexer_Error_Token.Byte_Region.First < 
Config.Error_Token.Byte_Region.First then
-         --  The unbalanced quote is before the parse error token; see
-         --  test_mckenzie_recover.adb String_Quote_2.
-         --
-         --  The missing quote belongs after the parse error token, before or
-         --  at the end of the current line; try inserting it at the end of
-         --  the current line.
-         --
-         --  The lexer repaired string literal may be in a reduced token on the
-         --  stack.
-
-         declare
-            Matching : SAL.Peek_Type := 1;
-         begin
-            Find_Descendant_ID
-              (Super.Parser_State (Parser_Index).Tree, Config, 
Lexer_Error_Token.ID,
-               String_ID_Set (Lexer_Error_Token.ID), Matching);
-
-            if Matching = Config.Stack.Depth then
-               --  String literal is in a virtual nonterm; give up. So far 
this only
-               --  happens in a high cost non critical config.
-               if Trace_McKenzie > Detail then
-                  Put_Line
-                    (Super.Trace.all, Super.Label (Parser_Index), "insert 
quote b abandon; string literal in virtual");
-               end if;
-               return;
-            end if;
-
-            declare
-               New_Config : Configuration := Config;
-            begin
-               String_Literal_In_Stack ("b", New_Config, Matching, 
Lexer_Error_Token.ID);
-
-               Finish
-                 ("b", New_Config, Config.Current_Shared_Token, 
Shared.Line_Begin_Token.all (Current_Line + 1) - 1);
-               Local_Config_Heap.Add (New_Config);
-            end;
-         end;
-
-      else
-         --  The unbalanced quote is after the parse error token.
-
-         --  case c: Assume a missing quote belongs immediately before the 
current token.
-         --  See test_mckenzie_recover.adb String_Quote_3.
-         declare
-            New_Config : Configuration := Config;
-         begin
-            Finish ("c", New_Config, Config.Current_Shared_Token, 
Lexer_Error_Token_Index - 1);
-            Local_Config_Heap.Add (New_Config);
-         exception
-         when Bad_Config =>
-            null;
-         end;
-
-         --  case d: Assume a missing quote belongs somewhere farther before
-         --  the current token; try one non-empty (as in case a above). See
-         --  test_mckenzie_recover.adb String_Quote_4, String_Quote_6.
-         declare
-            New_Config            : Configuration := Config;
-            Min_Pushed_Back_Index : Base_Token_Index;
-         begin
-            Push_Back_Tokens ("insert quote 5 d", New_Config, 
Min_Pushed_Back_Index);
-            Finish ("d", New_Config, Min_Pushed_Back_Index, 
Lexer_Error_Token_Index - 1);
-            Local_Config_Heap.Add (New_Config);
-         exception
-         when SAL.Container_Empty =>
-            --  From Stack.Pop
-            null;
-         when Bad_Config =>
-            null;
-         end;
-
-         --  case e: Assume the actual error is an extra quote that terminates
-         --  an intended string literal early, in which case there is a token
-         --  on the stack containing the string literal that should be extended
-         --  to the found quote. See test_mckenzie_recover.adb String_Quote_1.
-         declare
-            Matching : SAL.Peek_Type := 1;
-         begin
-            --  Lexer_Error_Token is a string literal; find a matching one.
-            Find_Descendant_ID
-              (Super.Parser_State (Parser_Index).Tree, Config, 
Lexer_Error_Token.ID, String_ID_Set
-                 (Lexer_Error_Token.ID), Matching);
-
-            if Matching = Config.Stack.Depth then
-               --  No matching string literal, so this case does not apply.
-               null;
-            else
-               declare
-                  New_Config : Configuration := Config;
-               begin
-                  String_Literal_In_Stack ("e", New_Config, Matching, 
Lexer_Error_Token.ID);
-
-                  Finish ("e", New_Config, Config.Current_Shared_Token, 
Lexer_Error_Token_Index);
-                  Local_Config_Heap.Add (New_Config);
-               end;
-            end if;
-         end;
-      end if;
-   exception
-   when Bad_Config =>
-      null;
-   end Try_Insert_Quote;
-
-   procedure Try_Delete_Input
-     (Super             : not null access Base.Supervisor;
-      Shared            : not null access Base.Shared;
-      Parser_Index      : in              SAL.Base_Peek_Type;
-      Config            : in              Configuration;
-      Local_Config_Heap : in out          Config_Heaps.Heap_Type)
-   is
-      --  Try deleting (= skipping) the current shared input token.
-
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-      Trace       : WisiToken.Trace'Class renames Super.Trace.all;
-      EOF_ID      : Token_ID renames Trace.Descriptor.EOI_ID;
-      Check_Limit : WisiToken.Token_Index renames 
Shared.Table.McKenzie_Param.Check_Limit;
-
-      McKenzie_Param : McKenzie_Param_Type renames Shared.Table.McKenzie_Param;
-
-      ID : constant Token_ID := Shared.Terminals.all 
(Config.Current_Shared_Token).ID;
-   begin
-      if ID /= EOF_ID and then
-         --  can't delete EOF
-         (Length (Config.Ops) = 0 or else
-           --  Don't delete an ID we just inserted; waste of time
-           (not Equal (Constant_Ref (Config.Ops, Last_Index (Config.Ops)),
-                       (Insert, ID, Config.Current_Shared_Token))))
-      then
-         declare
-            New_Config : Configuration := Config;
-
-            function Matching_Push_Back return Boolean
-            is begin
-               for I in reverse First_Index (New_Config.Ops) .. Last_Index 
(New_Config.Ops) loop
-                  declare
-                     Op : Config_Op renames Config_Op_Array_Refs.Variable_Ref 
(New_Config.Ops, I).Element.all;
-                  begin
-                     exit when not (Op.Op in Undo_Reduce | Push_Back | Delete);
-                     if Op = (Push_Back, ID, New_Config.Current_Shared_Token) 
then
-                        return True;
-                     end if;
-                  end;
-               end loop;
-               return False;
-            end Matching_Push_Back;
-         begin
-            New_Config.Error_Token.ID := Invalid_Token_ID;
-            New_Config.Check_Status   := (Label => 
WisiToken.Semantic_Checks.Ok);
-
-            New_Config.Cost := New_Config.Cost + McKenzie_Param.Delete (ID);
-            New_Config.Strategy_Counts (Delete) := Config.Strategy_Counts 
(Delete) + 1;
-
-            if Matching_Push_Back then
-               --  We are deleting a push_back; cancel the push_back cost, to 
make
-               --  this the same as plain deleting.
-               New_Config.Cost := Natural'Max (Natural'First, New_Config.Cost 
- McKenzie_Param.Push_Back (ID));
-            end if;
-
-            if Is_Full (New_Config.Ops) then
-               Super.Config_Full ("delete", Parser_Index);
-               raise Bad_Config;
-            else
-               Append (New_Config.Ops, (Delete, ID, 
Config.Current_Shared_Token));
-            end if;
-            New_Config.Current_Shared_Token := New_Config.Current_Shared_Token 
+ 1;
-
-            if New_Config.Resume_Token_Goal - Check_Limit < 
New_Config.Current_Shared_Token then
-               New_Config.Resume_Token_Goal := New_Config.Current_Shared_Token 
+ Check_Limit;
-            end if;
-
-            Local_Config_Heap.Add (New_Config);
-
-            if Trace_McKenzie > Detail then
-               Base.Put
-                 ("delete " & Image (ID, Trace.Descriptor.all), Super, Shared, 
Parser_Index, New_Config);
-            end if;
-         end;
-      end if;
-   end Try_Delete_Input;
-
-   procedure Process_One
-     (Super         : not null access Base.Supervisor;
-      Shared        : not null access Base.Shared;
-      Config_Status : out             Base.Config_Status)
-   is
-      --  Get one config from Super, check to see if it is a viable
-      --  solution. If not, enqueue variations to check.
-
-      use all type Base.Config_Status;
-      use all type Parser.Language_Fixes_Access;
-      use all type Semantic_Checks.Check_Status_Label;
-
-      Trace      : WisiToken.Trace'Class renames Super.Trace.all;
-      Descriptor : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-      Table      : Parse_Table renames Shared.Table.all;
-
-      Parser_Index : SAL.Base_Peek_Type;
-      Config       : Configuration;
-
-      Local_Config_Heap : Config_Heaps.Heap_Type;
-      --  We collect all the variants to enqueue, then deliver them all at
-      --  once to Super, to minimizes task interactions.
-   begin
-      Super.Get (Parser_Index, Config, Config_Status);
-
-      if Config_Status = All_Done then
-         return;
-      end if;
-
-      if Trace_McKenzie > Detail then
-         Base.Put ("dequeue", Super, Shared, Parser_Index, Config);
-         if Trace_McKenzie > Extra then
-            Put_Line (Trace, Super.Label (Parser_Index), "stack: " & Image 
(Config.Stack, Trace.Descriptor.all));
-         end if;
-      end if;
-
-      --  Fast_Forward; parse Insert, Delete in Config.Ops that have not
-      --  been parsed yet. 'parse' here means adjusting Config.Stack and
-      --  Current_Terminal_Index. Code in this file always parses when
-      --  adding ops to Config (except as noted); Language_Fixes should use
-      --  McKenzie_Recover.Insert, Delete instead.
-      if Config.Current_Insert_Delete = 1 then
-         --  Config is from Language_Fixes.
-
-         Fast_Forward (Super, Shared, Parser_Index, Local_Config_Heap, Config);
-         Super.Put (Parser_Index, Local_Config_Heap);
-         return;
-      end if;
-
-      pragma Assert (Config.Current_Insert_Delete = 0);
-      --  Config.Current_Insert_Delete > 1 is a programming error.
-
-      if Config.Error_Token.ID /= Invalid_Token_ID then
-         if Shared.Language_Fixes = null then
-            null;
-         else
-            Shared.Language_Fixes
-              (Trace, Shared.Lexer, Super.Label (Parser_Index), 
Shared.Table.all,
-               Shared.Terminals.all, Super.Parser_State (Parser_Index).Tree, 
Local_Config_Heap,
-               Config);
-
-            --  The solutions enqueued by Language_Fixes should be lower cost 
than
-            --  others (typically 0), so they will be checked first.
-         end if;
-
-         if Config.Check_Status.Label = Ok then
-            --  Parse table Error action.
-            --
-            --  We don't clear Config.Error_Token here, because
-            --  Language_Use_Minimal_Complete_Actions needs it. We only clear 
it
-            --  when a parse results in no error (or a different error), or a
-            --  push_back moves the Current_Token.
-            null;
-
-         else
-            --  Assume "ignore check error" is a viable solution. But give it a
-            --  cost, so a solution provided by Language_Fixes is preferred.
-
-            declare
-               New_State : Unknown_State_Index;
-            begin
-               Config.Cost := Config.Cost + 
Table.McKenzie_Param.Ignore_Check_Fail;
-               Config.Strategy_Counts (Ignore_Error) := Config.Strategy_Counts 
(Ignore_Error) + 1;
-
-               --  finish reduce.
-               Config.Stack.Pop (SAL.Base_Peek_Type 
(Config.Check_Token_Count));
-
-               New_State := Goto_For (Table, Config.Stack.Peek.State, 
Config.Error_Token.ID);
-
-               if New_State = Unknown_State then
-                  if Config.Stack.Depth = 1 then
-                     --  Stack is empty, and we did not get Accept; really bad 
syntax got
-                     --  us here; abandon this config. See 
ada_mode-recover_bad_char.adb.
-                     Super.Put (Parser_Index, Local_Config_Heap);
-                     return;
-                  else
-                     raise SAL.Programmer_Error with
-                       "process_one found test case for new_state = Unknown; 
old state " &
-                       Trimmed_Image (Config.Stack.Peek.State) & " nonterm " & 
Image
-                         (Config.Error_Token.ID, Trace.Descriptor.all);
-                  end if;
-               end if;
-
-               Config.Stack.Push ((New_State, Invalid_Node_Index, 
Config.Error_Token));
-
-               --  We _don't_ clear Check_Status and Error_Token here; Check 
needs
-               --  them, and sets them as appropriate.
-            end;
-         end if;
-      end if;
-
-      --  Call Check to see if this config succeeds.
-      case Check (Super, Shared, Parser_Index, Config, Local_Config_Heap) is
-      when Success =>
-         Super.Success (Parser_Index, Config, Local_Config_Heap);
-         return;
-
-      when Abandon =>
-         Super.Put (Parser_Index, Local_Config_Heap);
-         return;
-
-      when Continue =>
-         null;
-
-      end case;
-
-      if Trace_McKenzie > Detail then
-         Base.Put ("continuing", Super, Shared, Parser_Index, Config);
-         if Trace_McKenzie > Extra then
-            Put_Line (Trace, Super.Label (Parser_Index), "stack: " & Image 
(Config.Stack, Trace.Descriptor.all));
-         end if;
-      end if;
-
-      --  Grouping these operations (push_back, delete, insert) ensures that
-      --  there are no duplicate solutions found. We reset the grouping
-      --  after each fast_forward.
-      --
-      --  We do delete before insert so Insert_Matching_Begin can operate on
-      --  the new next token, before Fast_Forwarding past it.
-      --
-      --  All possible permutations will be explored.
-
-      pragma Assert (Config.Stack.Depth > 0);
-
-      Try_Insert_Terminal (Super, Shared, Parser_Index, Config, 
Local_Config_Heap);
-
-      if Push_Back_Valid (Config) and then
-        (not Check_Reduce_To_Start (Super, Shared, Parser_Index, Config))
-        --  If Config reduces to the start nonterm, there's no point in 
Push_Back or Undo_Reduce.
-      then
-         Try_Push_Back (Super, Shared, Parser_Index, Config, 
Local_Config_Heap);
-
-         if Undo_Reduce_Valid (Config.Stack, Super.Parser_State 
(Parser_Index).Tree) then
-            Try_Undo_Reduce (Super, Shared, Parser_Index, Config, 
Local_Config_Heap);
-         end if;
-      end if;
-
-      if None_Since_FF (Config.Ops, Insert) then
-         Try_Delete_Input (Super, Shared, Parser_Index, Config, 
Local_Config_Heap);
-      end if;
-
-      --  This is run once per input line, independent of what other ops
-      --  have been done.
-      if Config.Check_Status.Label = Ok and
-        (Descriptor.String_1_ID /= Invalid_Token_ID or Descriptor.String_2_ID 
/= Invalid_Token_ID) and
-        (Config.String_Quote_Checked = Invalid_Line_Number or else
-           Config.String_Quote_Checked < Shared.Terminals.all 
(Config.Current_Shared_Token).Line)
-      then
-         --  See if there is a mismatched quote. The solution is to delete
-         --  tokens, nominally replacing them with an expanded string literal.
-         --  So we try this when it is ok to try delete.
-         if None_Since_FF (Config.Ops, Insert) then
-            Try_Insert_Quote (Super, Shared, Parser_Index, Config, 
Local_Config_Heap);
-         end if;
-      end if;
-
-      Super.Put (Parser_Index, Local_Config_Heap);
-   exception
-   when Bad_Config =>
-      --  Just abandon this config; tell Super we are done.
-      Super.Put (Parser_Index, Local_Config_Heap);
-
-   when E : others =>
-      Super.Put (Parser_Index, Local_Config_Heap);
-      if Debug_Mode then
-         raise;
-      elsif Trace_McKenzie > Outline then
-         Put_Line
-           (Super.Trace.all, Super.Label (Parser_Index),
-            "Process_One: unhandled exception " & 
Ada.Exceptions.Exception_Name (E) & ": " &
-              Ada.Exceptions.Exception_Message (E));
-      end if;
-   end Process_One;
-
-end WisiToken.Parse.LR.McKenzie_Recover.Explore;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.ads 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.ads
deleted file mode 100644
index b80124a..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-explore.ads
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  Code to explore parse table, enqueuing new configs to check.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Parse.LR.McKenzie_Recover.Base;
-private package WisiToken.Parse.LR.McKenzie_Recover.Explore is
-
-   procedure Process_One
-     (Super         : not null access Base.Supervisor;
-      Shared        : not null access Base.Shared;
-      Config_Status : out             Base.Config_Status);
-
-end WisiToken.Parse.LR.McKenzie_Recover.Explore;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.adb 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.adb
deleted file mode 100644
index b56bba6..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.adb
+++ /dev/null
@@ -1,327 +0,0 @@
---  Abstract :
---
---  See spec
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse.LR.McKenzie_Recover.Parse is
-
-   procedure Compute_Nonterm
-     (ID              : in     Token_ID;
-      Stack           : in     Recover_Stacks.Stack;
-      Tokens          : in out Recover_Token_Array;
-      Nonterm         :    out Recover_Token;
-      Default_Virtual : in     Boolean)
-   is
-      Min_Terminal_Index_Set : Boolean := False;
-   begin
-      Nonterm :=
-        (ID      => ID,
-         Virtual => (if Tokens'Length = 0 then Default_Virtual else False),
-         others  => <>);
-
-      for I in Tokens'Range loop
-         Tokens (I) := Stack.Peek (Tokens'Last - I + 1).Token;
-      end loop;
-
-      for T of Tokens loop
-         Nonterm.Virtual := Nonterm.Virtual or T.Virtual;
-
-         if Nonterm.Byte_Region.First > T.Byte_Region.First then
-            Nonterm.Byte_Region.First := T.Byte_Region.First;
-         end if;
-
-         if Nonterm.Byte_Region.Last < T.Byte_Region.Last then
-            Nonterm.Byte_Region.Last := T.Byte_Region.Last;
-         end if;
-
-         if not Min_Terminal_Index_Set then
-            if T.Min_Terminal_Index /= Invalid_Token_Index then
-               Min_Terminal_Index_Set     := True;
-               Nonterm.Min_Terminal_Index := T.Min_Terminal_Index;
-            end if;
-         end if;
-      end loop;
-   end Compute_Nonterm;
-
-   function Reduce_Stack
-     (Shared          : not null access Base.Shared;
-      Stack           : in out          Recover_Stacks.Stack;
-      Action          : in              Reduce_Action_Rec;
-      Nonterm         :    out          Recover_Token;
-      Default_Virtual : in              Boolean)
-     return Semantic_Checks.Check_Status
-   is
-      use all type Semantic_Checks.Semantic_Check;
-      use all type Semantic_Checks.Check_Status_Label;
-
-      Last   : constant SAL.Base_Peek_Type := SAL.Base_Peek_Type 
(Action.Token_Count);
-      Tokens : Recover_Token_Array (1 .. Last);
-   begin
-      pragma Assert (Stack.Depth > Last);
-      Compute_Nonterm (Action.Production.LHS, Stack, Tokens, Nonterm, 
Default_Virtual);
-
-      if Action.Check = null then
-         --  Now we can pop the stack.
-         Stack.Pop (SAL.Base_Peek_Type (Action.Token_Count));
-         return (Label => Ok);
-      else
-         return Status : constant Semantic_Checks.Check_Status :=
-           Action.Check (Shared.Lexer, Nonterm, Tokens, Recover_Active => True)
-         do
-            if Status.Label = Ok then
-               Stack.Pop (SAL.Base_Peek_Type (Action.Token_Count));
-            end if;
-         end return;
-      end if;
-   end Reduce_Stack;
-
-   function Parse_One_Item
-     (Super             :         not null access Base.Supervisor;
-      Shared            :         not null access Base.Shared;
-      Parser_Index      :         in              SAL.Peek_Type;
-      Parse_Items       : aliased in out          Parse_Item_Arrays.Vector;
-      Parse_Item_Index  :         in              Positive;
-      Shared_Token_Goal :         in              Base_Token_Index;
-      Trace_Prefix      :         in              String)
-     return Boolean
-   is
-      --  Perform parse actions on Parse_Items (Parse_Item_Index), until one
-      --  fails (return False) or Shared_Token_Goal is shifted (return
-      --  True).
-      --
-      --  We return Boolean, not Check_Status, because Abandon and Continue
-      --  are up to the caller.
-      --
-      --  If any actions have conflicts, append the conflict configs and 
actions to
-      --  Parse_Items.
-
-      use Parse_Item_Arrays;
-      use Config_Op_Arrays;
-      use all type Semantic_Checks.Check_Status_Label;
-
-      Trace      : WisiToken.Trace'Class renames Super.Trace.all;
-      Descriptor : WisiToken.Descriptor renames Super.Trace.Descriptor.all;
-      Table      : Parse_Table renames Shared.Table.all;
-
-      Item   : Parse_Item renames Parse_Item_Array_Refs.Variable_Ref 
(Parse_Items, Parse_Item_Index).Element.all;
-      Config : Configuration renames Item.Config;
-      Action : Parse_Action_Node_Ptr renames Item.Action;
-
-      Conflict : Parse_Action_Node_Ptr;
-
-      Restore_Terminals_Current : Base_Token_Index;
-      Current_Token             : Base_Token := McKenzie_Recover.Current_Token
-        (Terminals                 => Shared.Terminals.all,
-         Terminals_Current         => Config.Current_Shared_Token,
-         Restore_Terminals_Current => Restore_Terminals_Current,
-         Insert_Delete             => Config.Insert_Delete,
-         Current_Insert_Delete     => Config.Current_Insert_Delete);
-
-      New_State : Unknown_State_Index;
-      Success   : Boolean := True;
-
-   begin
-      if Trace_McKenzie > Detail then
-         if Trace_McKenzie > Extra then
-            if Config.Current_Insert_Delete /= No_Insert_Delete then
-               Put_Line (Trace, Super.Label (Parser_Index), Trace_Prefix & ": 
Insert_Delete: " &
-                           Image (Config.Insert_Delete, Trace.Descriptor.all));
-            end if;
-         end if;
-
-         Base.Put (Trace_Prefix & ": " & Image (Current_Token, Descriptor), 
Super, Shared, Parser_Index, Config);
-         if Shared_Token_Goal /= Invalid_Token_Index then
-            Put_Line (Trace, Super.Label (Parser_Index), Trace_Prefix & ": 
Shared_Token_Goal :" &
-                        WisiToken.Token_Index'Image (Shared_Token_Goal));
-         end if;
-      end if;
-
-      Item.Parsed := True;
-
-      if Action = null then
-         Action := Action_For (Table, Config.Stack.Peek.State, 
Current_Token.ID);
-      end if;
-
-      loop
-         Conflict := Action.Next;
-         loop
-            exit when Conflict = null;
-            if Is_Full (Parse_Items) then
-               if Trace_McKenzie > Outline then
-                  Put_Line (Trace, Super.Label (Parser_Index), Trace_Prefix & 
": too many conflicts; abandoning");
-               end if;
-            else
-               declare
-                  New_Config : Configuration := Config;
-               begin
-                  New_Config.Current_Shared_Token := Restore_Terminals_Current;
-
-                  if Trace_McKenzie > Detail then
-                     Put_Line
-                       (Trace, Super.Label (Parser_Index), Trace_Prefix & ":" 
& State_Index'Image
-                          (New_Config.Stack.Peek.State) & ": add conflict " &
-                          Image (Conflict.Item, Descriptor));
-                  end if;
-
-                  Append (Parse_Items, (New_Config, Conflict, Parsed => False, 
Shift_Count => Item.Shift_Count));
-               end;
-            end if;
-            Conflict := Conflict.Next;
-         end loop;
-
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Trace, Super.Label (Parser_Index), Trace_Prefix & ":" & 
State_Index'Image (Config.Stack.Peek.State) &
-                 " :" & WisiToken.Token_Index'Image 
(Config.Current_Shared_Token) &
-                 ":" & Image (Current_Token, Descriptor) &
-                 " : " & Image (Action.Item, Descriptor) &
-                 (if Action.Item.Verb = Reduce
-                  then " via" & Config.Stack.Peek (SAL.Peek_Type 
(Action.Item.Token_Count + 1)).State'Image
-                  else ""));
-         end if;
-
-         case Action.Item.Verb is
-         when Shift =>
-            Item.Shift_Count := Item.Shift_Count + 1;
-
-            Config.Stack.Push
-              ((Action.Item.State,
-                Invalid_Node_Index,
-                (Current_Token.ID,
-                 Byte_Region        => Current_Token.Byte_Region,
-                 Min_Terminal_Index =>
-                   (if Config.Current_Insert_Delete = No_Insert_Delete
-                    then Config.Current_Shared_Token
-                    else Invalid_Token_Index),
-                 Name              => Null_Buffer_Region,
-                 Virtual           => Config.Current_Insert_Delete /= 
No_Insert_Delete)));
-
-            Current_Token := Next_Token
-              (Terminals                 => Shared.Terminals.all,
-               Terminals_Current         => Config.Current_Shared_Token,
-               Restore_Terminals_Current => Restore_Terminals_Current,
-               Insert_Delete             => Config.Insert_Delete,
-               Current_Insert_Delete     => Config.Current_Insert_Delete);
-
-         when Reduce =>
-            declare
-               Nonterm : Recover_Token;
-            begin
-               Config.Check_Status := Reduce_Stack
-                 (Shared, Config.Stack, Action.Item, Nonterm,
-                  Default_Virtual => Config.Current_Insert_Delete /= 
No_Insert_Delete);
-
-               case Config.Check_Status.Label is
-               when Ok =>
-                  New_State := Config.Stack.Peek.State;
-                  New_State := Goto_For (Table, New_State, 
Action.Item.Production.LHS);
-
-                  if New_State = Unknown_State then
-                     --  Most likely from an inappropriate language fix.
-                     if Trace_McKenzie > Outline then
-                        Base.Put (Trace_Prefix & ": Unknown_State: ", Super, 
Shared, Parser_Index, Config);
-                        Put_Line (Trace, Trace_Prefix & ": stack: " & Image 
(Config.Stack, Descriptor));
-                     end if;
-
-                     --  We can't just return False here; user must abandon 
this config.
-                     raise Bad_Config;
-                  end if;
-
-                  Config.Stack.Push ((New_State, Invalid_Node_Index, Nonterm));
-
-               when Semantic_Checks.Error =>
-                  Config.Error_Token       := Nonterm;
-                  Config.Check_Token_Count := Action.Item.Token_Count;
-                  Success                  := False;
-               end case;
-            end;
-
-         when Error =>
-
-            Config.Error_Token :=
-              (ID          => Current_Token.ID,
-               Byte_Region => Current_Token.Byte_Region,
-               others      => <>);
-            Success            := False;
-
-         when Accept_It =>
-            null;
-         end case;
-
-         exit when not Success or
-           Action.Item.Verb = Accept_It or
-           (if Shared_Token_Goal = Invalid_Token_Index
-            then Length (Config.Insert_Delete) = 0
-            else Config.Current_Shared_Token > Shared_Token_Goal);
-
-         Action := Action_For (Table, Config.Stack.Peek.State, 
Current_Token.ID);
-      end loop;
-
-      Config.Current_Shared_Token := Restore_Terminals_Current;
-
-      return Success;
-   end Parse_One_Item;
-
-   function Parse
-     (Super             :         not null access Base.Supervisor;
-      Shared            :         not null access Base.Shared;
-      Parser_Index      :         in              SAL.Peek_Type;
-      Parse_Items       : aliased    out          Parse_Item_Arrays.Vector;
-      Config            :         in              Configuration;
-      Shared_Token_Goal :         in              Base_Token_Index;
-      All_Conflicts     :         in              Boolean;
-      Trace_Prefix      :         in              String)
-     return Boolean
-   is
-      use Parse_Item_Arrays;
-      Trace : WisiToken.Trace'Class renames Super.Trace.all;
-
-      Last_Parsed : Natural;
-      Success     : Boolean;
-   begin
-      Clear (Parse_Items);
-      Append (Parse_Items, (Config, Action => null, Parsed => False, 
Shift_Count => 0));
-
-      --  Clear any errors; so they reflect the parse result.
-      declare
-         Config : Configuration renames Parse_Item_Array_Refs.Variable_Ref
-           (Parse_Items, First_Index (Parse_Items)).Config;
-      begin
-         Config.Error_Token.ID := Invalid_Token_ID;
-         Config.Check_Status   := (Label => Semantic_Checks.Ok);
-      end;
-
-      Last_Parsed := First_Index (Parse_Items);
-      loop
-         --  Loop over initial config and any conflicts.
-         Success := Parse_One_Item
-           (Super, Shared, Parser_Index, Parse_Items, Last_Parsed, 
Shared_Token_Goal, Trace_Prefix);
-
-         exit when Last_Index (Parse_Items) = Last_Parsed;
-
-         exit when Success and not All_Conflicts;
-
-         Last_Parsed := Last_Parsed + 1;
-         if Trace_McKenzie > Detail then
-            Put_Line (Trace, Super.Label (Parser_Index), Trace_Prefix & ": 
parse conflict");
-         end if;
-      end loop;
-
-      return Success;
-   end Parse;
-
-end WisiToken.Parse.LR.McKenzie_Recover.Parse;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.ads 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.ads
deleted file mode 100644
index abd8946..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover-parse.ads
+++ /dev/null
@@ -1,83 +0,0 @@
---  Abstract :
---
---  Config parsing subprograms.
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
-with WisiToken.Parse.LR.McKenzie_Recover.Base;
-private package WisiToken.Parse.LR.McKenzie_Recover.Parse is
-
-   function Reduce_Stack
-     (Shared          : not null access Base.Shared;
-      Stack           : in out          Recover_Stacks.Stack;
-      Action          : in              Reduce_Action_Rec;
-      Nonterm         :    out          Recover_Token;
-      Default_Virtual : in              Boolean)
-     return Semantic_Checks.Check_Status;
-   --  Reduce Stack according to Action, setting Nonterm. If
-   --  Action.Token_Count = 0, set Nonterm.Virtual := Default_Virtual.
-
-   type Parse_Item is record
-      Config      : Configuration;
-      Action      : Parse_Action_Node_Ptr;
-      Parsed      : Boolean;
-      Shift_Count : Natural := 0;
-
-      --  On return from Parse, if Parsed = False, this item was queued by a
-      --  conflict, but not parsed; it should be ignored.
-      --
-      --  Otherwise, if Config.Error_Token.ID = Invalid_Token_ID and
-      --  Config.Check_Status.Label = Ok, Config was parsed successfully to
-      --  the goal.
-      --
-      --  Otherwise, the parser failed a semantic check, or encountered an
-      --  Error action. Action gives the last action processed. Shift_Count
-      --  gives the number of shifts performed. If Check_Status.Label is
-      --  Error, Action.Item.Verb must be Reduce, and Config is in the
-      --  pre-reduce state.
-   end record;
-
-   package Parse_Item_Arrays is new SAL.Gen_Bounded_Definite_Vectors 
(Positive, Parse_Item, Capacity => 10);
-   --  Parse_Item_Arrays.Capacity sets maximum conflicts in one call to Parse
-
-   package Parse_Item_Array_Refs is new Parse_Item_Arrays.Gen_Refs;
-
-   function Parse
-     (Super             :         not null access Base.Supervisor;
-      Shared            :         not null access Base.Shared;
-      Parser_Index      :         in              SAL.Peek_Type;
-      Parse_Items       : aliased    out          Parse_Item_Arrays.Vector;
-      Config            :         in              Configuration;
-      Shared_Token_Goal :         in              Base_Token_Index;
-      All_Conflicts     :         in              Boolean;
-      Trace_Prefix      :         in              String)
-     return Boolean;
-   --  Attempt to parse Config and any conflict configs. If not
-   --  All_Conflicts, return when Config.Insert_Delete is all processed,
-   --  and either Shared_Token_Goal = Invalid_Token_Index or
-   --  Shared_Token_Goal is shifted. If All_Conflicts, return when all
-   --  conflict configs have been parsed.
-   --
-   --  Parsed configs are in Parse_Items; there is more than one if a
-   --  conflict is encountered. Parse returns True if at least one
-   --  Parse_Item parsed successfully to the goal. In that case, the
-   --  other items are either not parsed or failed. See comment in
-   --  Parse_Item for more detail.
-   --
-   --  Raises Bad_Config if parse encounters Unknown_State.
-
-end WisiToken.Parse.LR.McKenzie_Recover.Parse;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover.adb 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover.adb
deleted file mode 100644
index 3287fb4..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover.adb
+++ /dev/null
@@ -1,1306 +0,0 @@
---  Abstract :
---
---  See spec
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Characters.Handling;
-with Ada.Exceptions;
-with Ada.Unchecked_Deallocation;
-with System.Multiprocessors;
-with WisiToken.Parse.LR.McKenzie_Recover.Base;
-with WisiToken.Parse.LR.McKenzie_Recover.Explore;
-with WisiToken.Parse.LR.Parser_Lists;
-package body WisiToken.Parse.LR.McKenzie_Recover is
-   use all type System.Multiprocessors.CPU_Range;
-
-   type Supervisor_Access is access all Base.Supervisor;
-   type Shared_Access is access all Base.Shared;
-
-   task type Worker_Task is
-      entry Start
-        (ID     : in Integer;
-         Super  : in Supervisor_Access;
-         Shared : in Shared_Access);
-      --  Start getting parser/configs to check from Config_Store. Stop when
-      --  Super reports All_Done;
-
-      entry Done;
-      --  Available after Super has reported All_Done.
-   end Worker_Task;
-
-   type Worker_Access is access Worker_Task;
-   procedure Free is new Ada.Unchecked_Deallocation (Worker_Task, 
Worker_Access);
-
-   task body Worker_Task
-   is
-      use all type Base.Config_Status;
-      Super  : Supervisor_Access;
-      Shared : Shared_Access;
-
-      Status : Base.Config_Status := Valid;
-   begin
-      loop
-         select
-            accept Start
-              (ID     : in Integer;
-               Super  : in Supervisor_Access;
-               Shared : in Shared_Access)
-
-            do
-               Task_Attributes.Set_Value (ID);
-               Worker_Task.Super  := Super;
-               Worker_Task.Shared := Shared;
-            end Start;
-         or
-            terminate;
-         end select;
-
-         loop
-            Explore.Process_One (Super, Shared, Status);
-            exit when Status = All_Done;
-         end loop;
-
-         accept Done;
-
-         Super  := null;
-         Shared := null;
-      end loop;
-
-   exception
-   when E : others =>
-      Super.Fatal (E);
-   end Worker_Task;
-
-   Worker_Tasks : array (1 .. System.Multiprocessors.CPU_Range'Max (1, 
System.Multiprocessors.Number_Of_CPUs - 1)) of
-     Worker_Access;
-   --  Declaring an array of tasks directly causes a circular elaboration
-   --  problem, and would mean a task that terminates due to an exception
-   --  is never restarted.
-
-   procedure To_Recover
-     (Parser_Stack : in     Parser_Lists.Parser_Stacks.Stack;
-      Tree         : in     Syntax_Trees.Tree;
-      Stack        : in out Recover_Stacks.Stack)
-   is
-      Depth : constant SAL.Peek_Type := Parser_Stack.Depth;
-   begin
-      pragma Assert (Stack.Depth = 0);
-      if Stack.Size < Depth then
-         raise SAL.Programmer_Error with "recover stack needs more space;" & 
Depth'Image;
-      end if;
-      for I in reverse 1 .. Depth loop
-         declare
-            Item  : Parser_Lists.Parser_Stack_Item renames Parser_Stack (I);
-            Token : constant Recover_Token := (if I = Depth then (others => 
<>) else Tree.Recover_Token (Item.Token));
-         begin
-            Stack.Push ((Item.State, Item.Token, Token));
-         end;
-      end loop;
-   end To_Recover;
-
-   procedure Recover_Init
-     (Shared_Parser : in out LR.Parser.Parser;
-      Parser_State  : in out Parser_Lists.Parser_State)
-   is
-      use all type WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-
-      Trace  : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-      Config : Configuration;
-      Error  : Parse_Error renames Parser_State.Errors 
(Parser_State.Errors.Last);
-   begin
-      Parser_State.Recover.Enqueue_Count := Parser_State.Recover.Enqueue_Count 
+ 1;
-
-      Config.Resume_Token_Goal := Parser_State.Shared_Token + 
Shared_Parser.Table.McKenzie_Param.Check_Limit;
-
-      if Trace_McKenzie > Outline then
-         Trace.New_Line;
-         Trace.Put_Line
-           ("parser" & Integer'Image (Parser_State.Label) &
-              ": State" & State_Index'Image (Parser_State.Stack (1).State) &
-              " Current_Token " & Parser_State.Tree.Image 
(Parser_State.Current_Token, Trace.Descriptor.all) &
-              " Resume_Token_Goal" & WisiToken.Token_Index'Image 
(Config.Resume_Token_Goal));
-         Trace.Put_Line
-           ((case Error.Label is
-             when Action => "Action",
-             when Check => "Check, " & Semantic_Checks.Image 
(Error.Check_Status, Trace.Descriptor.all),
-             when Message => raise SAL.Programmer_Error));
-         if Trace_McKenzie > Extra then
-            Put_Line
-              (Trace, Parser_State.Label, "stack: " & Parser_Lists.Image
-                 (Parser_State.Stack, Trace.Descriptor.all, 
Parser_State.Tree));
-         end if;
-      end if;
-
-      --  Additional initialization of Parser_State.Recover is done in
-      --  Supervisor.Initialize.
-
-      To_Recover (Parser_State.Stack, Parser_State.Tree, Config.Stack);
-
-      --  Parser_State.Recover_Insert_Delete must be empty (else we would not 
get
-      --  here). Therefore Parser_State current token is in
-      --  Shared_Parser.Shared_Token.
-
-      Config.Current_Shared_Token := Parser_State.Shared_Token;
-
-      case Error.Label is
-      when Action =>
-         Config.Error_Token := Parser_State.Tree.Recover_Token 
(Error.Error_Token);
-         if Trace_McKenzie > Detail then
-            Put ("enqueue", Trace, Parser_State.Label, 
Shared_Parser.Terminals, Config,
-                 Task_ID => False);
-         end if;
-
-      when Check =>
-         if Shared_Parser.Language_Fixes = null then
-            --  The only fix is to ignore the error.
-            if Trace_McKenzie > Detail then
-               Config.Strategy_Counts (Ignore_Error) := 1;
-               Put ("enqueue", Trace, Parser_State.Label, 
Shared_Parser.Terminals, Config,
-                    Task_ID => False);
-            end if;
-
-         else
-            --  Undo the reduction that encountered the error, let Process_One
-            --  enqueue possible solutions. We leave the cost at 0, since this 
is
-            --  the root config. Later logic will enqueue the 'ignore error'
-            --  solution; see McKenzie_Recover.Explore Process_One.
-
-            Config.Check_Status      := Error.Check_Status;
-            Config.Error_Token       := Config.Stack.Peek.Token;
-            Config.Check_Token_Count := Undo_Reduce (Config.Stack, 
Parser_State.Tree);
-
-            Config_Op_Arrays.Append (Config.Ops, (Undo_Reduce, 
Config.Error_Token.ID, Config.Check_Token_Count));
-
-            if Trace_McKenzie > Detail then
-               Put ("undo_reduce " & Image
-                      (Config.Error_Token.ID, Trace.Descriptor.all), Trace, 
Parser_State.Label,
-                    Shared_Parser.Terminals, Config, Task_ID => False);
-            end if;
-         end if;
-
-      when Message =>
-         --  Last error entry should be the failure that caused us to enter
-         --  recovery.
-         raise SAL.Programmer_Error;
-      end case;
-
-      Parser_State.Recover.Config_Heap.Add (Config);
-   end Recover_Init;
-
-   function Recover (Shared_Parser : in out LR.Parser.Parser) return 
Recover_Status
-   is
-      use all type Parser.Post_Recover_Access;
-      Trace : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-
-      Parsers : Parser_Lists.List renames Shared_Parser.Parsers;
-
-      Skip_Next : Boolean := False;
-
-      Super : aliased Base.Supervisor
-        (Trace'Access,
-         Check_Delta_Limit => 
Shared_Parser.Table.McKenzie_Param.Check_Delta_Limit,
-         Enqueue_Limit     => Shared_Parser.Table.McKenzie_Param.Enqueue_Limit,
-         Parser_Count      => Parsers.Count);
-
-      Shared : aliased Base.Shared
-        (Shared_Parser.Trace,
-         Shared_Parser.Lexer.all'Access,
-         Shared_Parser.Table,
-         Shared_Parser.Language_Fixes,
-         Shared_Parser.Language_Matching_Begin_Tokens,
-         Shared_Parser.Language_String_ID_Set,
-         Shared_Parser.Terminals'Access,
-         Shared_Parser.Line_Begin_Token'Access);
-
-      Task_Count : constant System.Multiprocessors.CPU_Range :=
-        (if Shared_Parser.Table.McKenzie_Param.Task_Count = 0
-         then Worker_Tasks'Last
-         --  Keep one CPU free for this main task, and the user.
-         else Shared_Parser.Table.McKenzie_Param.Task_Count);
-
-   begin
-      if Trace_McKenzie > Outline then
-         Trace.New_Line;
-         Trace.Put_Line (" McKenzie error recovery");
-      end if;
-
-      Super.Initialize (Parsers'Unrestricted_Access, 
Shared_Parser.Terminals'Unrestricted_Access);
-
-      for Parser_State of Parsers loop
-         Recover_Init (Shared_Parser, Parser_State);
-      end loop;
-
-      if Trace_McKenzie > Outline then
-         Trace.New_Line;
-         Trace.Put_Line (Task_Count'Image & " parallel tasks");
-      end if;
-
-      for I in Worker_Tasks'First .. Task_Count loop
-         if Worker_Tasks (I) = null then
-            Worker_Tasks (I) := new Worker_Task;
-            if Debug_Mode then
-               Trace.Put_Line ("new Worker_Task" & 
System.Multiprocessors.CPU_Range'Image (I));
-            end if;
-
-         elsif Worker_Tasks (I)'Terminated then
-            Free (Worker_Tasks (I));
-            Worker_Tasks (I) := new Worker_Task;
-            if Debug_Mode then
-               Trace.Put_Line ("recreated Worker_Task" & 
System.Multiprocessors.CPU_Range'Image (I));
-            end if;
-         end if;
-
-         Worker_Tasks (I).Start (Integer (I), Super'Unchecked_Access, 
Shared'Unchecked_Access);
-      end loop;
-
-      declare
-         use Ada.Exceptions;
-         ID      : Exception_Id;
-         Message : Ada.Strings.Unbounded.Unbounded_String;
-      begin
-         Super.Done (ID, Message); -- Wait for all parsers to fail or succeed
-
-         --  Ensure all worker tasks stop getting configs before proceeding;
-         --  otherwise local variables disappear while the task is still trying
-         --  to access them.
-         for I in Worker_Tasks'First .. Task_Count loop
-            if not Worker_Tasks (I)'Terminated then
-               Worker_Tasks (I).Done;
-            end if;
-         end loop;
-
-         if ID /= Null_Id then
-            Raise_Exception (ID, -Message);
-         end if;
-      end;
-
-      --  Spawn new parsers for multiple solutions.
-      --
-      --  One option here would be to keep only the parser with the least
-      --  cost fix. However, the normal reason for having multiple parsers
-      --  is to resolve a grammar ambiguity; the least cost fix might
-      --  resolve the ambiguity the wrong way. As could any other fix, of
-      --  course.
-      --
-      --  We could try to check here for redundant solutions; configs for a
-      --  parser that have the same or "equivalent" ops. But those will be
-      --  caught in the main parse by the check for duplicate state; doing
-      --  the same check here is premature optimization.
-      declare
-         use Parser_Lists;
-
-         Cur         : Cursor             := Parsers.First;
-         Solutions   : SAL.Base_Peek_Type := 0;
-         Spawn_Limit : SAL.Base_Peek_Type := Shared_Parser.Max_Parallel; -- 
per parser
-      begin
-         for Parser of Parsers loop
-            if Parser.Recover.Success then
-               Solutions := Solutions + Parser.Recover.Results.Count;
-            end if;
-         end loop;
-
-         if Solutions > Shared_Parser.Max_Parallel and Trace_McKenzie > 
Outline then
-            Trace.Put_Line ("too many parallel parsers required in recover; 
dropping some solutions");
-            Spawn_Limit := Shared_Parser.Max_Parallel / Parsers.Count;
-         end if;
-
-         loop
-            declare
-               Data : McKenzie_Data renames State_Ref (Cur).Recover;
-            begin
-               if Data.Success then
-                  if Trace_McKenzie > Outline then
-                     Trace.Put_Line
-                       (Integer'Image (Label (Cur)) &
-                          ": succeed" & SAL.Base_Peek_Type'Image 
(Data.Results.Count) &
-                          ", enqueue" & Integer'Image (Data.Enqueue_Count) &
-                          ", check " & Integer'Image (Data.Check_Count) &
-                          ", cost: " & Integer'Image (Data.Results.Min_Key));
-                  end if;
-
-                  if Data.Results.Count > 1 then
-                     for I in 1 .. SAL.Base_Peek_Type'Min (Spawn_Limit, 
Data.Results.Count - 1) loop
-                        Parsers.Prepend_Copy (Cur); --  does not copy recover
-                        if Trace_McKenzie > Outline or Trace_Parse > Outline 
then
-                           Trace.Put_Line
-                             ("spawn parser" & Integer'Image 
(Parsers.First.Label) & " from " &
-                                Trimmed_Image (Cur.Label) & " (" & 
Trimmed_Image (Integer (Parsers.Count)) &
-                                " active)");
-                           Put ("", Trace, Parsers.First.Label, 
Shared_Parser.Terminals,
-                                Data.Results.Peek, Task_ID => False, Strategy 
=> True);
-                        end if;
-
-                        State_Ref (Parsers.First).Recover.Results.Add 
(Data.Results.Remove);
-                        State_Ref (Parsers.First).Recover.Success := True;
-                     end loop;
-                  end if;
-
-                  if Trace_McKenzie > Outline or Trace_Parse > Outline then
-                     Put ("", Trace, Cur.State_Ref.Label, 
Shared_Parser.Terminals, Data.Results.Peek,
-                          Task_ID => False, Strategy => True);
-                  end if;
-               else
-                  if Trace_McKenzie > Outline then
-                     Trace.Put_Line
-                       (Integer'Image (Cur.Label) &
-                          ": fail, enqueue" & Integer'Image 
(Data.Enqueue_Count) &
-                          (if Data.Config_Full_Count > 0 then ", config_full" 
& Data.Config_Full_Count'Image else "") &
-                          ", check " & Integer'Image (Data.Check_Count) &
-                          ", max shared_token " & WisiToken.Token_Index'Image 
(Shared_Parser.Terminals.Last_Index));
-                  end if;
-               end if;
-
-            end;
-            Next (Cur);
-            exit when Is_Done (Cur);
-         end loop;
-      end;
-
-      --  Edit Parser_State to apply solutions.
-
-      --  We don't use 'for Parser_State of Parsers loop' here,
-      --  because we might need to terminate a parser.
-      declare
-         Current_Parser : Parser_Lists.Cursor := Parsers.First;
-      begin
-         loop
-            exit when Current_Parser.Is_Done;
-
-            if Current_Parser.State_Ref.Recover.Success then
-               begin
-                  --  Can't have active 'renames State_Ref' when terminate a 
parser
-                  declare
-                     use Parser_Lists;
-                     use Config_Op_Arrays, Config_Op_Array_Refs;
-
-                     Parser_State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref;
-
-                     Descriptor : WisiToken.Descriptor renames 
Shared_Parser.Trace.Descriptor.all;
-                     Stack      : Parser_Stacks.Stack renames 
Parser_State.Stack;
-                     Tree       : Syntax_Trees.Tree renames Parser_State.Tree;
-                     Data       : McKenzie_Data renames Parser_State.Recover;
-                     Result     : Configuration renames Data.Results.Peek;
-
-                     Stack_Matches_Ops     : Boolean := True;
-                     Shared_Token_Changed  : Boolean := False;
-                     Current_Token_Virtual : Boolean := False;
-                     First_Insert          : Boolean := True;
-                  begin
-                     --  The verb will be reset by the main parser; just 
indicate the
-                     --  parser recovered from the error.
-                     Parser_State.Set_Verb (Shift);
-
-                     Parser_State.Errors (Parser_State.Errors.Last).Recover := 
Result;
-
-                     Parser_State.Resume_Token_Goal := 
Result.Resume_Token_Goal;
-
-                     if Trace_McKenzie > Extra then
-                        Put_Line (Trace, Parser_State.Label, "before Ops 
applied:", Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "stack " & Image (Stack, 
Descriptor, Tree),
-                           Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "Shared_Token  " & Image
-                             (Parser_State.Shared_Token, 
Shared_Parser.Terminals, Descriptor),
-                           Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "Current_Token " & 
Parser_State.Tree.Image
-                             (Parser_State.Current_Token, Descriptor),
-                           Task_ID => False);
-                     end if;
-
-                     --  We don't apply all Ops to the parser stack here, 
because there can
-                     --  be other input tokens between the inserts and 
deletes, and there
-                     --  can be conflicts; we let the main parser handle that. 
We can apply
-                     --  all ops up to the first insert.
-                     --
-                     --  Other than Add_Terminal, there's no need to modify
-                     --  Parser_State.Tree. Any tree nodes created by the 
failed parse that
-                     --  are pushed back are useful for error repair, and will 
just be
-                     --  ignored in future parsing. This also avoids enlarging 
a
-                     --  non-flushed branched tree, which saves time and space.
-                     --
-                     --  Language_Fixes may abuse the rules about adding Ops, 
so we check
-                     --  that as much as is reasonable here. We use Assert to 
get an
-                     --  immediate error in a debug build, and raise 
Bad_Config to avoid
-                     --  further corruption in a release build.
-
-                     for I in First_Index (Result.Ops) .. Last_Index 
(Result.Ops) loop
-                        declare
-                           Op : Config_Op renames Constant_Ref (Result.Ops, I);
-                        begin
-                           case Op.Op is
-                           when Fast_Forward =>
-                              --  The parser would do shifts and reduces for 
the tokens we are
-                              --  skipping here
-                              Stack_Matches_Ops := False;
-
-                           when Undo_Reduce =>
-                              --  If Stack_Matches_Ops, we must do the 
Stack.Pop and Pushes, and we
-                              --  can use Stack.Peek to check if the 
Undo_Reduce is valid.
-                              --
-                              --  If not Stack_Matches_Ops, we have to assume 
Undo_Reduce is valid.
-                              --
-                              --  See test_mckenzie_recover.adb Extra_Begin 
for an example of Undo_Reduce
-                              --  after other ops.
-                              if Stack_Matches_Ops then
-                                 if not (Tree.Is_Nonterm (Stack.Peek.Token) and
-                                           (I = First_Index (Result.Ops) or 
else
-                                              Push_Back_Valid
-                                                (Tree.First_Shared_Terminal 
(Stack.Peek.Token), Result.Ops, I - 1)))
-                                 then
-                                    pragma Assert (False);
-                                    if Trace_McKenzie > Outline then
-                                       Put_Line
-                                         (Trace, Parser_State.Label, "invalid 
Undo_Reduce in apply config",
-                                          Task_ID => False);
-                                    end if;
-                                    raise Bad_Config;
-                                 end if;
-
-                                 for C of Tree.Children (Stack.Pop.Token) loop
-                                    Stack.Push ((Tree.State (C), C));
-                                 end loop;
-                              end if;
-
-                           when Push_Back =>
-                              --  If Stack_Matches_Ops, we must do the 
Stack.Pop, and can use that
-                              --  to check if the Push_Back is valid.
-                              --
-                              --  If not Stack_Matches_Ops, we have to assume 
Op.PB_Token_Index is
-                              --  correct, and we do not do Stack.Pop. We can 
still check the target
-                              --  token index against the previous ops.
-                              --
-                              --  See test_mckenzie_recover.adb Erorr_2 for an 
example of Push_Back
-                              --  after other ops.
-                              if not
-                                (I = First_Index (Result.Ops) or else
-                                   Push_Back_Valid
-                                     (Target_Token_Index =>
-                                        (if Stack_Matches_Ops
-                                         then Tree.First_Shared_Terminal 
(Stack.Peek.Token)
-                                         else Op.PB_Token_Index),
-                                      Ops     => Result.Ops,
-                                      Prev_Op => I - 1))
-                              then
-                                 if Trace_McKenzie > Outline then
-                                    Put_Line
-                                      (Trace, Parser_State.Label, "invalid 
Push_Back in apply config op" & I'Image,
-                                       Task_ID => False);
-                                 end if;
-                                 pragma Assert (False);
-                                 raise Bad_Config;
-                              end if;
-
-                              if Stack_Matches_Ops then
-                                 Stack.Pop;
-
-                                 if Op.PB_Token_Index /= Invalid_Token_Index 
then
-                                    --  Pushing back an empty nonterm has no 
effect on the input stream.
-                                    Parser_State.Shared_Token := 
Op.PB_Token_Index;
-                                    Shared_Token_Changed      := True;
-                                 end if;
-                              end if;
-
-                           when Insert =>
-                              Recover_Op_Arrays.Append
-                                (Parser_State.Recover_Insert_Delete,
-                                 (Op              => Insert,
-                                  Ins_ID          => Op.Ins_ID,
-                                  Ins_Token_Index => Op.Ins_Token_Index,
-                                  Ins_Tree_Node   => Invalid_Node_Index));
-
-                              if Parser_State.Recover_Insert_Delete_Current = 
No_Index then
-                                 Parser_State.Recover_Insert_Delete_Current :=
-                                   Recover_Op_Arrays.Last_Index 
(Parser_State.Recover_Insert_Delete);
-                              end if;
-
-                              if First_Insert and Op.Ins_Token_Index = 
Parser_State.Shared_Token then
-                                 --  We need First_Insert here, not just 
Stack_Matches_Ops, when the
-                                 --  first insert is preceeded only by 
Push_Back and Undo_Reduce, with
-                                 --  at least one Undo_Reduce (so 
Stack_Matches_Ops is False when we
-                                 --  get here). See test_mckenzie_recover.adb 
Missing_Name_3
-
-                                 First_Insert := False;
-
-                                 --  Normally Insert is completed by 
Stack.Push; we let the main parser
-                                 --  do that.
-                                 Stack_Matches_Ops := False;
-
-                                 --  Add_Terminal is normally done in the 
lexer phase, so we do this here.
-                                 Parser_State.Current_Token := 
Parser_State.Tree.Add_Terminal
-                                   (Op.Ins_ID, Op.Ins_Token_Index);
-                                 Recover_Op_Array_Refs.Variable_Ref
-                                   (Parser_State.Recover_Insert_Delete,
-                                    Recover_Op_Arrays.Last_Index 
(Parser_State.Recover_Insert_Delete)).Ins_Tree_Node :=
-                                      Parser_State.Current_Token;
-
-                                 Current_Token_Virtual                      := 
True;
-                                 Parser_State.Recover_Insert_Delete_Current := 
No_Index;
-                              else
-                                 --  Let main parser handle it
-                                 null;
-                              end if;
-
-                           when Delete =>
-                              Recover_Op_Arrays.Append
-                                (Parser_State.Recover_Insert_Delete,
-                                 (Op              => Delete,
-                                  Del_ID          => Op.Del_ID,
-                                  Del_Token_Index => Op.Del_Token_Index));
-
-                              if Stack_Matches_Ops and Op.Del_Token_Index = 
Parser_State.Shared_Token then
-                                 --  Delete has no effect on Stack, so we can 
apply multiple deletes.
-                                 Parser_State.Shared_Token := 
Op.Del_Token_Index + 1;
-                                 Shared_Token_Changed      := True;
-
-                                 Parser_State.Recover_Insert_Delete_Current := 
No_Index;
-                              else
-                                 if Parser_State.Recover_Insert_Delete_Current 
= No_Index then
-                                    Parser_State.Recover_Insert_Delete_Current 
:=
-                                      Recover_Op_Arrays.Last_Index 
(Parser_State.Recover_Insert_Delete);
-                                 end if;
-
-                              end if;
-
-                           end case;
-                        end;
-                     end loop;
-
-                     --  If not Shared_Token_Changed, Shared_Token is the 
error token,
-                     --  which is the next token to read. If 
Shared_Token_Changed, we have
-                     --  set Shared_Token consistent with that; it is the next 
token to
-                     --  read. If Current_Token_Virtual, then after all the 
virtual tokens
-                     --  are inserted, the main parser would normally increment
-                     --  Parser_State.Shared_Token to get the next token, but 
we don't want
-                     --  that now. We could set Shared_Token to 1 less, but 
this way the
-                     --  debug messages all show the expected Shared_Terminal.
-
-                     Parser_State.Inc_Shared_Token := not 
Current_Token_Virtual;
-
-                     --  The main parser always sets Current_Token to be the 
syntax tree
-                     --  node containing Shared_Token; ensure that is true 
here (virtual
-                     --  tokens where handled above).
-
-                     if (not Current_Token_Virtual) and Shared_Token_Changed 
then
-                        Parser_State.Current_Token := Shared_Parser.Terminals
-                          (Parser_State.Shared_Token).Tree_Index;
-                     end if;
-
-                     if Trace_McKenzie > Extra then
-                        Put_Line (Trace, Parser_State.Label, "after Ops 
applied:", Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "stack " & 
Parser_Lists.Image
-                             (Stack, Descriptor, Tree),
-                           Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "Shared_Token  " & Image
-                             (Parser_State.Shared_Token, 
Shared_Parser.Terminals, Descriptor), Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "Current_Token " & 
Parser_State.Tree.Image
-                             (Parser_State.Current_Token, Descriptor), Task_ID 
=> False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "recover_insert_delete" &
-                             Parser_State.Recover_Insert_Delete_Current'Image 
& ":" &
-                             Image (Parser_State.Recover_Insert_Delete, 
Descriptor), Task_ID => False);
-                        Put_Line
-                          (Trace, Parser_State.Label, "inc_shared_token " &
-                             Boolean'Image (Parser_State.Inc_Shared_Token),
-                           Task_ID => False);
-                     end if;
-                  end;
-               exception
-               when Bad_Config =>
-                  if Parsers.Count = 1 then
-                     --  Oops. just give up
-                     return Fail_Programmer_Error;
-                  end if;
-                  Parsers.Terminate_Parser (Current_Parser, "bad config in 
recover", Trace, Shared_Parser.Terminals);
-                  --  Terminate advances Current_Parser
-                  Skip_Next := True;
-               end;
-            end if;
-            if Skip_Next then
-               Skip_Next := False;
-            else
-               Current_Parser.Next;
-            end if;
-         end loop;
-      end;
-      if Shared_Parser.Post_Recover /= null then
-         Shared_Parser.Post_Recover.all;
-      end if;
-
-      return Super.Recover_Result;
-
-   exception
-   when E : others =>
-      if Debug_Mode then
-         Trace.Put (Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E), Prefix => True);
-         Trace.New_Line;
-         raise;
-      else
-         return Fail_Programmer_Error;
-      end if;
-   end Recover;
-
-   ----------
-   --  Spec private subprograms; for language-specific
-   --  child packages.
-
-   procedure Check (ID : Token_ID; Expected_ID : in Token_ID)
-   is begin
-      pragma Assert (ID = Expected_ID, Token_ID'Image (ID) & " /=" & 
Token_ID'Image (Expected_ID));
-   end Check;
-
-   function Current_Token
-     (Terminals                 :         in     Base_Token_Arrays.Vector;
-      Terminals_Current         :         in out WisiToken.Base_Token_Index;
-      Restore_Terminals_Current :            out WisiToken.Base_Token_Index;
-      Insert_Delete             : aliased in out Config_Op_Arrays.Vector;
-      Current_Insert_Delete     :         in out SAL.Base_Peek_Type)
-     return Base_Token
-   is
-      use Config_Op_Arrays;
-      use Config_Op_Array_Refs;
-
-      procedure Inc_I_D
-      is begin
-         Current_Insert_Delete := Current_Insert_Delete + 1;
-         if Current_Insert_Delete > Last_Index (Insert_Delete) then
-            Current_Insert_Delete := No_Insert_Delete;
-            Clear (Insert_Delete);
-         end if;
-      end Inc_I_D;
-
-   begin
-      if Terminals_Current = Invalid_Token_Index then
-         --  Happens with really bad syntax; see test_mckenzie_recover.adb 
Error_4.
-         raise Bad_Config;
-      end if;
-
-      loop
-         if Current_Insert_Delete = No_Insert_Delete then
-            Restore_Terminals_Current := Terminals_Current;
-            return Terminals (Terminals_Current);
-
-         elsif Token_Index (Constant_Ref (Insert_Delete, 
Current_Insert_Delete)) = Terminals_Current then
-            declare
-               Op : Insert_Delete_Op renames Constant_Ref (Insert_Delete, 
Current_Insert_Delete);
-            begin
-               case Insert_Delete_Op_Label (Op.Op) is
-               when Insert =>
-                  --  Decrement Terminals_Current so Next_Token knows it 
should always
-                  --  increment it. Save the initial value, to restore in case 
of error.
-                  Restore_Terminals_Current := Terminals_Current;
-                  Terminals_Current         := Terminals_Current - 1;
-                  return (ID => ID (Op), others => <>);
-
-               when Delete =>
-                  Terminals_Current         := Terminals_Current + 1;
-                  Restore_Terminals_Current := Terminals_Current;
-                  Inc_I_D;
-               end case;
-            end;
-         else
-            return Terminals (Terminals_Current);
-         end if;
-      end loop;
-   end Current_Token;
-
-   function Current_Token_ID_Peek
-     (Terminals             :         in Base_Token_Arrays.Vector;
-      Terminals_Current     :         in Base_Token_Index;
-      Insert_Delete         : aliased in Config_Op_Arrays.Vector;
-      Current_Insert_Delete :         in SAL.Base_Peek_Type)
-     return Token_ID
-   is
-      use Config_Op_Array_Refs;
-
-      Result : Token_ID;
-   begin
-      if Terminals_Current = Base_Token_Index'First then
-         --  Happens with really bad syntax.
-         raise Bad_Config;
-      end if;
-
-      --  First set Result from Terminals; may be overridden by
-      --  Insert_Delete below.
-      Result := Terminals (Terminals_Current).ID;
-
-      if Current_Insert_Delete = No_Insert_Delete then
-         null;
-
-      elsif Token_Index (Constant_Ref (Insert_Delete, Current_Insert_Delete)) 
= Terminals_Current then
-         declare
-            Op : Insert_Delete_Op renames Constant_Ref (Insert_Delete, 
Current_Insert_Delete);
-         begin
-            case Insert_Delete_Op_Label (Op.Op) is
-            when Insert =>
-               Result := Op.Ins_ID;
-
-            when Delete =>
-               --  This should have been handled in Check
-               raise SAL.Programmer_Error;
-            end case;
-         end;
-      end if;
-      return Result;
-   end Current_Token_ID_Peek;
-
-   procedure Current_Token_ID_Peek_3
-     (Terminals             :         in     Base_Token_Arrays.Vector;
-      Terminals_Current     :         in     Base_Token_Index;
-      Insert_Delete         : aliased in     Config_Op_Arrays.Vector;
-      Current_Insert_Delete :         in     SAL.Base_Peek_Type;
-      Tokens                :            out Token_ID_Array_1_3)
-   is
-      Terminals_Next : WisiToken.Token_Index := Terminals_Current + 1;
-   begin
-      if Terminals_Current = Base_Token_Index'First then
-         --  Happens with really bad syntax; see test_mckenzie_recover.adb 
Error_4.
-         raise Bad_Config;
-      end if;
-
-      --  First set Tokens from Terminals; may be overridden by
-      --  Insert_Delete below.
-      Tokens (1) := Terminals (Terminals_Current).ID;
-      if Terminals_Next <= Terminals.Last_Index then
-         Tokens (2) := Terminals (Terminals_Next).ID;
-         Terminals_Next := Terminals_Next + 1;
-         if Terminals_Next <= Terminals.Last_Index then
-            Tokens (3) := Terminals (Terminals_Next).ID;
-         else
-            Tokens (3) := Invalid_Token_ID;
-         end if;
-      else
-         Tokens (2) := Invalid_Token_ID;
-         Tokens (3) := Invalid_Token_ID;
-      end if;
-
-      if Current_Insert_Delete = No_Insert_Delete then
-         null;
-      else
-         for I in Tokens'Range loop
-            declare
-               use Config_Op_Arrays, Config_Op_Array_Refs;
-               J : constant SAL.Base_Peek_Type := Current_Insert_Delete + 
SAL.Peek_Type (I) - 1;
-            begin
-               if (J in First_Index (Insert_Delete) .. Last_Index 
(Insert_Delete)) and then
-                 Token_Index (Constant_Ref (Insert_Delete, J)) = 
Terminals_Current
-               then
-                  declare
-                     Op : Insert_Delete_Op renames Constant_Ref 
(Insert_Delete, J);
-                  begin
-                     case Insert_Delete_Op_Label (Op.Op) is
-                     when Insert =>
-                        Tokens (I) := Op.Ins_ID;
-
-                     when Delete =>
-                        --  This should have been handled in Check
-                        raise SAL.Programmer_Error;
-                     end case;
-                  end;
-               end if;
-            end;
-         end loop;
-      end if;
-   end Current_Token_ID_Peek_3;
-
-   procedure Delete_Check
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      ID        : in     Token_ID)
-   is
-      use Config_Op_Arrays;
-      Op : constant Config_Op := (Delete, ID, Config.Current_Shared_Token);
-   begin
-      Check (Terminals (Config.Current_Shared_Token).ID, ID);
-      if Is_Full (Config.Ops) or Is_Full (Config.Insert_Delete) then
-         raise Bad_Config;
-      end if;
-      Append (Config.Ops, Op);
-      Append (Config.Insert_Delete, Op);
-      Config.Current_Insert_Delete := 1;
-   end Delete_Check;
-
-   procedure Delete_Check
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      Index     : in out WisiToken.Token_Index;
-      ID        : in     Token_ID)
-   is begin
-      Check (Terminals (Index).ID, ID);
-      Delete (Terminals, Config, Index);
-   end Delete_Check;
-
-   procedure Delete
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      Index     : in out WisiToken.Token_Index)
-   is
-      use Config_Op_Arrays;
-      Op : constant Config_Op := (Delete, Terminals (Index).ID, Index);
-   begin
-      if Is_Full (Config.Ops) or Is_Full (Config.Insert_Delete) then
-         raise Bad_Config;
-      end if;
-      Append (Config.Ops, Op);
-      Append (Config.Insert_Delete, Op);
-      Config.Current_Insert_Delete := 1;
-      Index := Index + 1;
-   end Delete;
-
-   function Find_ID
-     (Config         : in     Configuration;
-      ID             : in     Token_ID)
-     return Boolean
-   is begin
-      for I in 1 .. Config.Stack.Depth - 1 loop
-         --  Depth has Invalid_Token_ID
-         if ID = Config.Stack.Peek (I).Token.ID then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Find_ID;
-
-   procedure Find_ID
-     (Config         : in     Configuration;
-      ID             : in     Token_ID;
-      Matching_Index : in out SAL.Peek_Type)
-   is begin
-      loop
-         exit when Matching_Index = Config.Stack.Depth; -- Depth has 
Invalid_Token_ID
-         declare
-            Stack_ID : Token_ID renames Config.Stack.Peek 
(Matching_Index).Token.ID;
-         begin
-            exit when Stack_ID = ID;
-         end;
-         Matching_Index := Matching_Index + 1;
-      end loop;
-   end Find_ID;
-
-   procedure Find_ID
-     (Config         : in     Configuration;
-      IDs            : in     Token_ID_Set;
-      Matching_Index : in out SAL.Peek_Type)
-   is begin
-      loop
-         exit when Matching_Index >= Config.Stack.Depth; -- Depth has 
Invalid_Token_ID
-         declare
-            ID : Token_ID renames Config.Stack.Peek (Matching_Index).Token.ID;
-         begin
-            exit when ID in IDs'First .. IDs'Last and then IDs (ID);
-         end;
-         Matching_Index := Matching_Index + 1;
-      end loop;
-   end Find_ID;
-
-   procedure Find_Descendant_ID
-     (Tree           : in     Syntax_Trees.Tree;
-      Config         : in     Configuration;
-      ID             : in     Token_ID;
-      ID_Set         : in     Token_ID_Set;
-      Matching_Index : in out SAL.Peek_Type)
-   is
-      use Syntax_Trees;
-   begin
-      loop
-         exit when Matching_Index >= Config.Stack.Depth; -- Depth has 
Invalid_Token_ID
-         exit when Config.Stack.Peek (Matching_Index).Token.ID in ID_Set'Range 
and then
-           (ID_Set (Config.Stack.Peek (Matching_Index).Token.ID) and
-              (Config.Stack.Peek (Matching_Index).Tree_Index /= 
Invalid_Node_Index and then
-                 Tree.Find_Descendant (Config.Stack.Peek 
(Matching_Index).Tree_Index, ID) /= Invalid_Node_Index));
-
-         Matching_Index := Matching_Index + 1;
-      end loop;
-   end Find_Descendant_ID;
-
-   procedure Find_Matching_Name
-     (Config              : in     Configuration;
-      Lexer               : access constant WisiToken.Lexer.Instance'Class;
-      Name                : in     String;
-      Matching_Name_Index : in out SAL.Peek_Type;
-      Case_Insensitive    : in     Boolean)
-   is
-      use Ada.Characters.Handling;
-      Match_Name : constant String := (if Case_Insensitive then To_Lower 
(Name) else Name);
-   begin
-      loop
-         exit when Matching_Name_Index >= Config.Stack.Depth; -- Depth has 
Invalid_Token_ID
-         declare
-            Token       : Recover_Token renames Config.Stack.Peek 
(Matching_Name_Index).Token;
-            Name_Region : constant Buffer_Region :=
-              (if Token.Name = Null_Buffer_Region
-               then Token.Byte_Region
-               else Token.Name);
-         begin
-            exit when Name_Region /= Null_Buffer_Region and then
-              Match_Name =
-              (if Case_Insensitive
-               then To_Lower (Lexer.Buffer_Text (Name_Region))
-               else Lexer.Buffer_Text (Name_Region));
-
-            Matching_Name_Index := Matching_Name_Index + 1;
-         end;
-      end loop;
-   end Find_Matching_Name;
-
-   procedure Find_Matching_Name
-     (Config              : in     Configuration;
-      Lexer               : access constant WisiToken.Lexer.Instance'Class;
-      Name                : in     String;
-      Matching_Name_Index : in out SAL.Peek_Type;
-      Other_ID            : in     Token_ID;
-      Other_Count         :    out Integer;
-      Case_Insensitive    : in     Boolean)
-   is
-      use Ada.Characters.Handling;
-      Match_Name : constant String := (if Case_Insensitive then To_Lower 
(Name) else Name);
-   begin
-      Other_Count := 0;
-
-      loop
-         exit when Matching_Name_Index >= Config.Stack.Depth; -- Depth has 
Invalid_Token_ID
-         declare
-            Token       : Recover_Token renames Config.Stack.Peek 
(Matching_Name_Index).Token;
-            Name_Region : constant Buffer_Region :=
-              (if Token.Name = Null_Buffer_Region
-               then Token.Byte_Region
-               else Token.Name);
-         begin
-            exit when Name_Region /= Null_Buffer_Region and then
-              Match_Name =
-              (if Case_Insensitive
-               then To_Lower (Lexer.Buffer_Text (Name_Region))
-               else Lexer.Buffer_Text (Name_Region));
-
-            if Other_ID = Token.ID then
-               Other_Count := Other_Count + 1;
-            end if;
-
-            Matching_Name_Index := Matching_Name_Index + 1;
-         end;
-      end loop;
-   end Find_Matching_Name;
-
-   procedure Insert (Config : in out Configuration; ID : in Token_ID)
-   is begin
-      Insert (Config, Config.Current_Shared_Token, ID);
-   end Insert;
-
-   procedure Insert (Config : in out Configuration; IDs : in Token_ID_Array)
-   is begin
-      for ID of IDs loop
-         Insert (Config, ID);
-      end loop;
-   end Insert;
-
-   procedure Insert (Config : in out Configuration; Index : in 
WisiToken.Token_Index; ID : in Token_ID)
-   is
-      use Config_Op_Arrays;
-      Op : constant Config_Op := (Insert, ID, Index);
-   begin
-      if Is_Full (Config.Ops) or Is_Full (Config.Insert_Delete) then
-         raise Bad_Config;
-      end if;
-      Append (Config.Ops, Op);
-      Append (Config.Insert_Delete, Op);
-      Config.Current_Insert_Delete := 1;
-   end Insert;
-
-   function Next_Token
-     (Terminals                 :         in     Base_Token_Arrays.Vector;
-      Terminals_Current         :         in out Base_Token_Index;
-      Restore_Terminals_Current :         in out WisiToken.Base_Token_Index;
-      Insert_Delete             : aliased in out Config_Op_Arrays.Vector;
-      Current_Insert_Delete     :         in out SAL.Base_Peek_Type)
-     return Base_Token
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-
-      function Next_Terminal return Base_Token
-      is begin
-         Terminals_Current         := Terminals_Current + 1;
-         Restore_Terminals_Current := Terminals_Current;
-         return Terminals (Terminals_Current);
-      end Next_Terminal;
-
-   begin
-      loop
-         if Last_Index (Insert_Delete) > 0 and then Current_Insert_Delete = 
Last_Index (Insert_Delete) then
-            Current_Insert_Delete := No_Insert_Delete;
-            Clear (Insert_Delete);
-            return Next_Terminal;
-
-         elsif Current_Insert_Delete = No_Insert_Delete then
-            return Next_Terminal;
-
-         elsif Token_Index (Constant_Ref (Insert_Delete, Current_Insert_Delete 
+ 1)) = Terminals_Current + 1 then
-            Current_Insert_Delete := Current_Insert_Delete + 1;
-            declare
-               Op : Insert_Delete_Op renames Constant_Ref (Insert_Delete, 
Current_Insert_Delete);
-            begin
-               case Insert_Delete_Op_Label'(Op.Op) is
-               when Insert =>
-                  return (ID => Op.Ins_ID, others => <>);
-
-               when Delete =>
-                  Terminals_Current         := Terminals_Current + 1;
-                  Restore_Terminals_Current := Terminals_Current;
-               end case;
-            end;
-
-         else
-            return Next_Terminal;
-         end if;
-      end loop;
-   end Next_Token;
-
-   function Push_Back_Valid
-     (Target_Token_Index : in WisiToken.Base_Token_Index;
-      Ops             : in Config_Op_Arrays.Vector;
-      Prev_Op         : in Positive_Index_Type)
-     return Boolean
-   is
-      use Config_Op_Arrays;
-      Fast_Forward_Seen : Boolean := False;
-   begin
-      --  We require a Fast_Forward after Insert or Delete, to eliminate
-      --  duplicate results from push_back before and after a
-      --  delete (see test_mckenzie_recover.adb Extra_Begin).
-      --
-      --  If Target_Token_Index is greater than the new current terminal
-      --  implied by Prev_Op, the Push_Back is valid. Otherwise, it is
-      --  invalid (it should have been done first); we only need to look at
-      --  one op other than Fast_Forward.
-      for I in reverse First_Index (Ops) .. Prev_Op loop
-         declare
-            Op : Config_Op renames Element (Ops, I);
-         begin
-            case Op.Op is
-            when Fast_Forward =>
-               --  We need to see the op before the Fast_Forward to tell if 
Push_Back
-               --  to Target_Token_Index is ok.
-               Fast_Forward_Seen := True;
-
-            when Undo_Reduce =>
-               --  We don't know what the new terminal is from this op. We'll 
just
-               --  have to trust the programmers.
-               return True;
-
-            when Push_Back =>
-               --  If neither the proposed Push_Back nor Op is for an empty 
token,
-               --  successive Push_Backs have decreasing targets; see
-               --  test_mckenzie_recover.adb Missing_Name_0.
-               --
-               --  However, if there is a Fast_Forward between two Push_Backs,
-               --  Target_Token_Index must be >= Op.PB_Token_Index. See
-               --  ada-mode-recover_27.adb.
-               --
-               --  If called from Undo_Reduce_Valid where the Undo_Reduce 
token is
-               --  empty, we get Target_Token_Index = Op.PB_Token_Index.
-               return Target_Token_Index = Invalid_Token_Index or else
-                 Op.PB_Token_Index = Invalid_Token_Index or else
-                 (if Fast_Forward_Seen
-                  then Target_Token_Index > Op.PB_Token_Index
-                  else Target_Token_Index <= Op.PB_Token_Index);
-
-            when Insert =>
-               --  If Target_Token_Index = Op.Ins_Token_Index, we want the edit
-               --  point to be at the same token as before; that's ok.
-               --
-               --  If Target_Token_Index > Ins_Token_Index, the Push_Back is 
partway
-               --  into a Fast_Forward.
-               return Fast_Forward_Seen and
-                 (Target_Token_Index = Invalid_Token_Index or else
-                    Target_Token_Index >= Op.Ins_Token_Index);
-
-            when Delete =>
-               --  As for Insert
-               return Fast_Forward_Seen and
-                 (Target_Token_Index = Invalid_Token_Index or else
-                    Target_Token_Index >= Op.Del_Token_Index);
-            end case;
-         end;
-      end loop;
-      --  We can only get here if the only ops in Ops are Fast_Forward,
-      --  which is a programming error.
-      pragma Assert (False);
-      raise Bad_Config;
-   end Push_Back_Valid;
-
-   procedure Push_Back (Config : in out Configuration)
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-
-      Item        : constant Recover_Stack_Item := Config.Stack.Pop;
-      Token_Index : constant Base_Token_Index   := 
Item.Token.Min_Terminal_Index;
-
-      function Compare (Left : in Base_Token_Index; Right : in Config_Op) 
return Boolean
-        is (case Right.Op is
-            when Fast_Forward    => False,
-            when Undo_Reduce     => False,
-            when Push_Back       => False,
-            when Insert => Left < Right.Ins_Token_Index,
-            when Delete => Left < Right.Del_Token_Index);
-      --  If Left = Right.Token_Index, we assume the Right ops go _after_
-      --  the Left, so the Left do not need to be repeated.
-   begin
-      if Token_Index /= Invalid_Token_Index then
-         Config.Current_Shared_Token := Token_Index;
-         for I in First_Index (Config.Ops) .. Last_Index (Config.Ops) loop
-            if Compare (Token_Index, Constant_Ref (Config.Ops, I)) then
-               if Is_Full (Config.Insert_Delete) then
-                  raise Bad_Config;
-               end if;
-               Append (Config.Insert_Delete, Constant_Ref (Config.Ops, I));
-            end if;
-         end loop;
-      end if;
-
-      if Is_Full (Config.Ops) then
-         raise Bad_Config;
-      end if;
-      Append (Config.Ops, (Push_Back, Item.Token.ID, 
Config.Current_Shared_Token));
-   end Push_Back;
-
-   procedure Push_Back_Check (Config : in out Configuration; Expected_ID : in 
Token_ID)
-   is begin
-      Check (Config.Stack.Peek (1).Token.ID, Expected_ID);
-      Push_Back (Config);
-   end Push_Back_Check;
-
-   procedure Push_Back_Check (Config : in out Configuration; Expected : in 
Token_ID_Array)
-   is begin
-      for ID of Expected loop
-         if Push_Back_Valid (Config) then
-            Push_Back_Check (Config, ID);
-         else
-            raise Bad_Config;
-         end if;
-      end loop;
-   end Push_Back_Check;
-
-   procedure Put
-     (Message      : in     String;
-      Trace        : in out WisiToken.Trace'Class;
-      Parser_Label : in     Natural;
-      Terminals    : in     Base_Token_Arrays.Vector;
-      Config       : in     Configuration;
-      Task_ID      : in     Boolean := True;
-      Strategy     : in     Boolean := False)
-   is
-      --  For debugging output
-
-      --  Build a string, call trace.put_line once, so output from multiple
-      --  tasks is not interleaved (mostly).
-      use Config_Op_Array_Refs;
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-      use all type WisiToken.Semantic_Checks.Check_Status_Label;
-
-      Descriptor : WisiToken.Descriptor renames Trace.Descriptor.all;
-
-      Result : Ada.Strings.Unbounded.Unbounded_String :=
-        (if Task_ID then +"task" & Task_Attributes.Value'Image else +"") &
-        Integer'Image (Parser_Label) & ": " &
-        (if Message'Length > 0 then Message & ":" else "");
-   begin
-      Result := Result & Natural'Image (Config.Cost);
-      if Strategy or Trace_McKenzie > Extra then
-         Result := Result & ", (";
-         for C of Config.Strategy_Counts loop
-            Result := Result & Integer'Image (C);
-         end loop;
-         Result := Result & "), ";
-      else
-         Result := Result & ", ";
-      end if;
-      if Config.Check_Status.Label /= Ok then
-         Result := Result & Semantic_Checks.Check_Status_Label'Image 
(Config.Check_Status.Label) & " ";
-      elsif Config.Error_Token.ID /= Invalid_Token_ID then
-         Result := Result & "Error " & Image (Config.Error_Token, Descriptor) 
& " ";
-      end if;
-      Result := Result & Image (Config.Stack, Descriptor, Depth => 1);
-
-      if Config.Current_Insert_Delete = No_Insert_Delete then
-         Result := Result & "|" & Image (Config.Current_Shared_Token, 
Terminals, Descriptor) & "|";
-      else
-         Result := Result & "/" & Trimmed_Image (Config.Current_Insert_Delete) 
& ":" &
-           Image (Constant_Ref (Config.Insert_Delete, 
Config.Current_Insert_Delete), Descriptor) & "/";
-      end if;
-
-      Result := Result & Image (Config.Ops, Descriptor);
-      if Config.Minimal_Complete_State /= None then
-         Result := Result & " minimal_complete " & 
Config.Minimal_Complete_State'Image;
-      end if;
-      Trace.Put_Line (-Result);
-   end Put;
-
-   procedure Put_Line
-     (Trace        : in out WisiToken.Trace'Class;
-      Parser_Label : in     Natural;
-      Message      : in     String;
-      Task_ID      : in     Boolean := True)
-   is begin
-      Trace.Put_Line
-        ((if Task_ID then "task" & Task_Attributes.Value'Image else "") &
-           Integer'Image (Parser_Label) & ": " & Message);
-   end Put_Line;
-
-   function Undo_Reduce
-     (Stack : in out Recover_Stacks.Stack;
-      Tree  : in     Syntax_Trees.Tree)
-     return Ada.Containers.Count_Type
-   is
-      Nonterm_Item : constant Recover_Stack_Item := Recover_Stacks.Pop (Stack);
-   begin
-      declare
-         Children : constant Valid_Node_Index_Array := Tree.Children 
(Nonterm_Item.Tree_Index);
-      begin
-         for C of Children loop
-            Stack.Push ((Tree.State (C), C, Tree.Recover_Token (C)));
-         end loop;
-         return Children'Length;
-      end;
-   end Undo_Reduce;
-
-   procedure Undo_Reduce_Check
-     (Config   : in out Configuration;
-      Tree     : in     Syntax_Trees.Tree;
-      Expected : in     Token_ID)
-   is begin
-      pragma Assert (Config.Stack.Depth > 1);
-      Check (Config.Stack.Peek (1).Token.ID, Expected);
-      Config_Op_Arrays.Append (Config.Ops, (Undo_Reduce, Expected, Undo_Reduce 
(Config.Stack, Tree)));
-   exception
-   when SAL.Container_Full =>
-      raise Bad_Config;
-   end Undo_Reduce_Check;
-
-   procedure Undo_Reduce_Check
-     (Config   : in out Configuration;
-      Tree     : in     Syntax_Trees.Tree;
-      Expected : in     Token_ID_Array)
-   is begin
-      for ID of Expected loop
-         Undo_Reduce_Check (Config, Tree, ID);
-      end loop;
-   end Undo_Reduce_Check;
-
-end WisiToken.Parse.LR.McKenzie_Recover;
diff --git a/packages/wisi/wisitoken-parse-lr-mckenzie_recover.ads 
b/packages/wisi/wisitoken-parse-lr-mckenzie_recover.ads
deleted file mode 100644
index 2f33cd2..0000000
--- a/packages/wisi/wisitoken-parse-lr-mckenzie_recover.ads
+++ /dev/null
@@ -1,310 +0,0 @@
---  Abstract :
---
---  Implement [McKenzie] error recovery, extended to parallel parsers.
---
---  References:
---
---  [McKenzie] McKenzie, Bruce J., Yeatman, Corey, and De Vere,
---  Lorraine. Error repair in shift reduce parsers. ACM Trans. Prog.
---  Lang. Syst., 17(4):672-689, July 1995.  Described in [Grune 2008] ref 321.
---
---  [Grune 2008] Parsing Techniques, A Practical Guide, Second
---  Edition. Dick Grune, Ceriel J.H. Jacobs.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Task_Attributes;
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Lexer;
-package WisiToken.Parse.LR.McKenzie_Recover is
-   use all type Ada.Containers.Count_Type;
-
-   Bad_Config : exception;
-   --  Raised when a config is determined to violate some programming
-   --  convention; abandon it.
-
-   type Recover_Status is (Fail_Check_Delta, Fail_Enqueue_Limit, 
Fail_No_Configs_Left, Fail_Programmer_Error, Success);
-
-   function Recover (Shared_Parser : in out WisiToken.Parse.LR.Parser.Parser) 
return Recover_Status;
-   --  Attempt to modify Parser.Parsers state and Parser.Lookahead to
-   --  allow recovering from an error state.
-
-   Force_Full_Explore        : Boolean := False;
-   --  Sometimes recover throws an exception in a race condition case
-   --  that is hard to reproduce. Setting this True ignores all Success,
-   --  so all configs are checked.
-
-   Force_High_Cost_Solutions : Boolean := False;
-   --  Similarly, setting this true keeps all solutions that are found,
-   --  and forces at least three.
-
-private
-
-   ----------
-   --  Visible for language-specific child packages. Alphabetical.
-
-   procedure Check (ID : Token_ID; Expected_ID : in Token_ID)
-   with Inline => True;
-   --  Check that ID = Expected_ID; raise Assertion_Error if not.
-   --  Implemented using 'pragma Assert'.
-
-   function Current_Token
-     (Terminals                 :         in     Base_Token_Arrays.Vector;
-      Terminals_Current         :         in out Base_Token_Index;
-      Restore_Terminals_Current :            out WisiToken.Base_Token_Index;
-      Insert_Delete             : aliased in out Config_Op_Arrays.Vector;
-      Current_Insert_Delete     :         in out SAL.Base_Peek_Type)
-     return Base_Token;
-   --  Return the current token, from either Terminals or Insert_Delete;
-   --  set up for Next_Token.
-   --
-   --  See Next_Token for more info.
-
-   function Current_Token_ID_Peek
-     (Terminals             :         in Base_Token_Arrays.Vector;
-      Terminals_Current     :         in Base_Token_Index;
-      Insert_Delete         : aliased in Config_Op_Arrays.Vector;
-      Current_Insert_Delete :         in SAL.Base_Peek_Type)
-     return Token_ID;
-   --  Return the current token from either Terminals or
-   --  Insert_Delete, without setting up for Next_Token.
-
-   procedure Current_Token_ID_Peek_3
-     (Terminals             :         in     Base_Token_Arrays.Vector;
-      Terminals_Current     :         in     Base_Token_Index;
-      Insert_Delete         : aliased in     Config_Op_Arrays.Vector;
-      Current_Insert_Delete :         in     SAL.Base_Peek_Type;
-      Tokens                :            out Token_ID_Array_1_3);
-   --  Return the current token (in Tokens (1)) from either Terminals or
-   --  Insert_Delete, without setting up for Next_Token. Return the two
-   --  following tokens in Tokens (2 .. 3).
-
-   procedure Delete_Check
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      ID        : in     Token_ID);
-   --  Check that Terminals (Config.Current_Shared_Token) = ID. Append a
-   --  Delete op to Config.Ops, and insert it in Config.Insert_Delete in
-   --  token_index order.
-   --
-   --  This or the next routine must be used instead of Config.Ops.Append
-   --  (Delete...) unless the code also takes care of changing
-   --  Config.Current_Shared_Token. Note that this routine does _not_
-   --  increment Config.Current_Shared_Token, so it can only be used to
-   --  delete one token.
-
-   procedure Delete_Check
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      Index     : in out     WisiToken.Token_Index;
-      ID        : in     Token_ID);
-   --  Check that Terminals (Index) = ID. Append a Delete op to
-   --  Config.Ops, and insert it in Config.Insert_Delete in token_index
-   --  order. Increments Index, for convenience when deleting several
-   --  tokens.
-
-   procedure Delete
-     (Terminals : in     Base_Token_Arrays.Vector;
-      Config    : in out Configuration;
-      Index     : in out WisiToken.Token_Index);
-   --  Same as Delete_Check, without the check.
-
-   function Find_ID
-     (Config         : in     Configuration;
-      ID             : in     Token_ID)
-     return Boolean;
-   --  Search Config.Stack for a token with ID, starting at
-   --  stack top. Return True if found, False if not.
-
-   procedure Find_ID
-     (Config         : in     Configuration;
-      ID             : in     Token_ID;
-      Matching_Index : in out SAL.Peek_Type);
-   --  Search Config.Stack for a token with ID, starting at
-   --  Matching_Index. If found, Matching_Index points to it.
-   --  If not found, Matching_Index = Config.Stack.Depth.
-
-   procedure Find_ID
-     (Config         : in     Configuration;
-      IDs            : in     Token_ID_Set;
-      Matching_Index : in out SAL.Peek_Type);
-   --  Search Config.Stack for a token with ID in IDs, starting at
-   --  Matching_Index. If found, Matching_Index points to it.
-   --  If not found, Matching_Index = Config.Stack.Depth.
-
-   procedure Find_Descendant_ID
-     (Tree           : in     Syntax_Trees.Tree;
-      Config         : in     Configuration;
-      ID             : in     Token_ID;
-      ID_Set         : in     Token_ID_Set;
-      Matching_Index : in out SAL.Peek_Type);
-   --  Search Config.Stack for a token with id in ID_Set, with a
-   --  descendant with id = ID, starting at Matching_Index. If found,
-   --  Matching_Index points to it. If not found, Matching_Index =
-   --  Config.Stack.Depth.
-
-   procedure Find_Matching_Name
-     (Config              : in     Configuration;
-      Lexer               : access constant WisiToken.Lexer.Instance'Class;
-      Name                : in     String;
-      Matching_Name_Index : in out SAL.Peek_Type;
-      Case_Insensitive    : in     Boolean);
-   --  Search Config.Stack for a token matching Name, starting at
-   --  Matching_Name_Index. If found, Matching_Name_Index points to it.
-   --  If not found, Matching_Name_Index = Config.Stack.Depth.
-
-   procedure Find_Matching_Name
-     (Config              : in     Configuration;
-      Lexer               : access constant WisiToken.Lexer.Instance'Class;
-      Name                : in     String;
-      Matching_Name_Index : in out SAL.Peek_Type;
-      Other_ID            : in     Token_ID;
-      Other_Count         :    out Integer;
-      Case_Insensitive    : in     Boolean);
-   --  Search Config.Stack for a token matching Name, starting at
-   --  Matching_Name_Index. If found, Matching_Name_Index points to it.
-   --  If not found, Matching_Name_Index = Config.Stack.Depth.
-   --
-   --  Also count tokens with ID = Other_ID.
-
-   procedure Insert (Config : in out Configuration; ID : in Token_ID);
-   --  Append an Insert op at Config.Current_Shared_Token, to Config.Ops,
-   --  and insert it in Config.Insert_Deleted in token_index order.
-
-   procedure Insert (Config : in out Configuration; IDs : in Token_ID_Array);
-   --  Call Insert for each item in IDs.
-
-   procedure Insert (Config : in out Configuration; Index : in 
WisiToken.Token_Index; ID : in Token_ID);
-   --  Same as Insert, but at Index, not Config.Current_Shared_Token.
-
-   function Next_Token
-     (Terminals                 :         in     Base_Token_Arrays.Vector;
-      Terminals_Current         :         in out Base_Token_Index;
-      Restore_Terminals_Current :         in out Base_Token_Index;
-      Insert_Delete             : aliased in out Config_Op_Arrays.Vector;
-      Current_Insert_Delete     :         in out SAL.Base_Peek_Type)
-     return Base_Token;
-   --  Return the next token, from either Terminals or Insert_Delete;
-   --  update Terminals_Current or Current_Insert_Delete.
-   --
-   --  If result is Insert_Delete.Last_Index, Current_Insert_Delete =
-   --  Last_Index; Insert_Delete is cleared and Current_Insert_Delete
-   --  reset on next call.
-   --
-   --  When done parsing, caller must reset actual Terminals_Current to
-   --  Restore_Terminals_Current.
-   --
-   --  Insert_Delete contains only Insert and Delete ops, in token_index
-   --  order. Those ops are applied when Terminals_Current =
-   --  op.token_index.
-
-   function Push_Back_Valid
-     (Target_Token_Index : in WisiToken.Base_Token_Index;
-      Ops             : in Config_Op_Arrays.Vector;
-      Prev_Op         : in Positive_Index_Type)
-     return Boolean;
-
-   function Push_Back_Valid (Config : in Configuration) return Boolean
-     is (Config.Stack.Depth > 1 and then
-           (not Config.Stack.Peek.Token.Virtual and
-              --  If Virtual, this is from earlier in this recover session; no 
point
-              --  in trying to redo it.
-              (Config_Op_Arrays.Length (Config.Ops) = 0 or else
-                 Push_Back_Valid
-                   (Config.Stack.Peek.Token.Min_Terminal_Index,
-                    Config.Ops,
-                    Config_Op_Arrays.Last_Index (Config.Ops)))));
-
-   procedure Push_Back (Config : in out Configuration)
-   with Pre => Push_Back_Valid (Config);
-   --  Pop the top Config.Stack item, set Config.Current_Shared_Token to
-   --  the first terminal in that item. If the item is empty,
-   --  Config.Current_Shared_Token is unchanged.
-
-   procedure Push_Back_Check (Config : in out Configuration; Expected_ID : in 
Token_ID)
-   with Pre => Push_Back_Valid (Config);
-   --  In effect, call Check and Push_Back.
-
-   procedure Push_Back_Check (Config : in out Configuration; Expected : in 
Token_ID_Array);
-   --  Call Push_Back_Check for each item in Expected.
-   --
-   --  Raises Bad_Config if any of the push_backs is invalid.
-
-   procedure Put
-     (Message      : in     String;
-      Trace        : in out WisiToken.Trace'Class;
-      Parser_Label : in     Natural;
-      Terminals    : in     Base_Token_Arrays.Vector;
-      Config       : in     Configuration;
-      Task_ID      : in     Boolean := True;
-      Strategy     : in     Boolean := False);
-   --  Put Message and an image of Config to Trace.
-
-   procedure Put_Line
-     (Trace        : in out WisiToken.Trace'Class;
-      Parser_Label : in     Natural;
-      Message      : in     String;
-      Task_ID      : in     Boolean := True);
-   --  Put message to Trace, with parser and task info.
-
-   function Undo_Reduce_Valid
-     (Stack   : in Recover_Stacks.Stack;
-      Tree    : in Syntax_Trees.Tree)
-     return Boolean
-     --  Check if Undo_Reduce is valid when there is no previous Config_Op.
-     --
-     --  Undo_Reduce needs to know what tokens the nonterm contains, to
-     --  push them on the stack. Thus we need a valid Tree index. It is
-     --  tempting to also allow an empty nonterm when Tree_Index is
-     --  invalid, but that fails when the real Undo_Reduce results in
-     --  another empty nonterm on the stack; see test_mckenzie_recover.adb
-     --  Error_During_Resume_3.
-     is (Stack.Depth > 1 and then
-           Stack.Peek.Tree_Index /= Invalid_Node_Index and then
-               Tree.Is_Nonterm (Stack.Peek.Tree_Index));
-
-   function Undo_Reduce_Valid
-     (Stack   : in Recover_Stacks.Stack;
-      Tree    : in Syntax_Trees.Tree;
-      Ops     : in Config_Op_Arrays.Vector;
-      Prev_Op : in Positive_Index_Type)
-     return Boolean
-   is (Undo_Reduce_Valid (Stack, Tree) and then Push_Back_Valid 
(Stack.Peek.Token.Min_Terminal_Index, Ops, Prev_Op));
-
-   function Undo_Reduce
-     (Stack : in out Recover_Stacks.Stack;
-      Tree  : in     Syntax_Trees.Tree)
-     return Ada.Containers.Count_Type
-   with Pre => Undo_Reduce_Valid (Stack, Tree);
-   --  Undo the reduction that produced the top stack item, return the
-   --  token count for that reduction.
-
-   procedure Undo_Reduce_Check
-     (Config   : in out Configuration;
-      Tree     : in     Syntax_Trees.Tree;
-      Expected : in     Token_ID)
-   with Inline => True;
-   --  Call Check, Undo_Reduce.
-
-   procedure Undo_Reduce_Check
-     (Config   : in out Configuration;
-      Tree     : in     Syntax_Trees.Tree;
-      Expected : in     Token_ID_Array);
-   --  Call Undo_Reduce_Check for each item in Expected.
-
-   package Task_Attributes is new Ada.Task_Attributes (Integer, 0);
-
-end WisiToken.Parse.LR.McKenzie_Recover;
diff --git a/packages/wisi/wisitoken-parse-lr-parser.adb 
b/packages/wisi/wisitoken-parse-lr-parser.adb
deleted file mode 100644
index 04b6f6b..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser.adb
+++ /dev/null
@@ -1,1256 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Calendar.Formatting;
-with Ada.Exceptions;
-with GNAT.Traceback.Symbolic;
-with WisiToken.Parse.LR.McKenzie_Recover;
-package body WisiToken.Parse.LR.Parser is
-
-   function Reduce_Stack_1
-     (Current_Parser : in     Parser_Lists.Cursor;
-      Action         : in     Reduce_Action_Rec;
-      Nonterm        :    out WisiToken.Valid_Node_Index;
-      Lexer          : in     WisiToken.Lexer.Handle;
-      Trace          : in out WisiToken.Trace'Class)
-     return WisiToken.Semantic_Checks.Check_Status_Label
-   is
-      --  We treat semantic check errors as parse errors here, to allow
-      --  error recovery to take better advantage of them. One recovery
-      --  strategy is to fix things so the semantic check passes.
-
-      use all type Semantic_Checks.Check_Status_Label;
-      use all type Semantic_Checks.Semantic_Check;
-
-      Parser_State  : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref.Element.all;
-      Children_Tree : Valid_Node_Index_Array (1 .. SAL.Base_Peek_Type 
(Action.Token_Count));
-   begin
-      for I in reverse Children_Tree'Range loop
-         Children_Tree (I) := Parser_State.Stack.Pop.Token;
-      end loop;
-
-      Nonterm := Parser_State.Tree.Add_Nonterm
-        (Action.Production, Children_Tree, Action.Action,
-         Default_Virtual => Parser_State.Tree.Is_Virtual 
(Parser_State.Current_Token));
-      --  Computes Nonterm.Byte_Region, Virtual
-
-      if Trace_Parse > Detail then
-         Trace.Put_Line (Parser_State.Tree.Image (Nonterm, 
Trace.Descriptor.all, Include_Children => True));
-      end if;
-
-      if Action.Check = null then
-         return Ok;
-
-      else
-         declare
-            Nonterm_Token  : Recover_Token                := 
Parser_State.Tree.Recover_Token (Nonterm);
-            Children_Token : constant Recover_Token_Array := 
Parser_State.Tree.Recover_Token_Array (Children_Tree);
-            Status         : Semantic_Checks.Check_Status;
-         begin
-            Status := Action.Check (Lexer, Nonterm_Token, Children_Token, 
Recover_Active => False);
-
-            if Nonterm_Token.Name /= Null_Buffer_Region then
-               Parser_State.Tree.Set_Name_Region (Nonterm, Nonterm_Token.Name);
-            end if;
-
-            if Trace_Parse > Detail then
-               Trace.Put_Line ("semantic check " & Semantic_Checks.Image 
(Status, Trace.Descriptor.all));
-            end if;
-
-            case Status.Label is
-            when Ok =>
-               return Ok;
-
-            when Semantic_Checks.Error =>
-               if Parser_State.Resume_Active then
-                  --  Ignore this error; that's how McKenzie_Recover decided 
to fix it
-                  return Ok;
-
-               else
-                  Parser_State.Errors.Append
-                    ((Label          => Check,
-                      First_Terminal => Trace.Descriptor.First_Terminal,
-                      Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                      Check_Status   => Status,
-                      Recover        => (others => <>)));
-                  return Status.Label;
-               end if;
-            end case;
-         exception
-         when Partial_Parse =>
-            --  From Action.Check
-            Parser_State.Tree.Set_Root (Nonterm);
-            raise;
-         end;
-      end if;
-   end Reduce_Stack_1;
-
-   procedure Do_Action
-     (Action         : in Parse_Action_Rec;
-      Current_Parser : in Parser_Lists.Cursor;
-      Shared_Parser  : in LR.Parser.Parser)
-   is
-      use all type Semantic_Checks.Check_Status_Label;
-
-      Parser_State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref;
-      Trace        : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-      Nonterm      : WisiToken.Valid_Node_Index;
-      Status       : Semantic_Checks.Check_Status_Label;
-   begin
-      if Trace_Parse > Detail then
-         Trace.Put
-           (Integer'Image (Current_Parser.Label) & ": " &
-              Trimmed_Image (Parser_State.Stack.Peek.State) & ": " &
-              Parser_State.Tree.Image (Parser_State.Current_Token, 
Trace.Descriptor.all) & " : ");
-         Put (Trace, Action);
-         Trace.New_Line;
-      end if;
-
-      case Action.Verb is
-      when Shift =>
-         Current_Parser.Set_Verb (Shift);
-         Parser_State.Stack.Push ((Action.State, Parser_State.Current_Token));
-         Parser_State.Tree.Set_State (Parser_State.Current_Token, 
Action.State);
-
-      when Reduce =>
-         declare
-            New_State : constant Unknown_State_Index := Goto_For
-              (Table => Shared_Parser.Table.all,
-               State => Parser_State.Stack (SAL.Base_Peek_Type 
(Action.Token_Count) + 1).State,
-               ID    => Action.Production.LHS);
-         begin
-            if New_State = Unknown_State then
-               --  This is due to a bug in the LALR parser generator (see
-               --  lalr_generator_bug_01.wy); we treat it as a syntax error.
-               Current_Parser.Set_Verb (Error);
-               if Trace_Parse > Detail then
-                  Trace.Put_Line (" ... error");
-               end if;
-
-            else
-               Status := Reduce_Stack_1 (Current_Parser, Action, Nonterm, 
Shared_Parser.Lexer, Trace);
-
-               --  Even when Reduce_Stack_1 returns Error, it did reduce the 
stack, so
-               --  push Nonterm.
-               Parser_State.Stack.Push ((New_State, Nonterm));
-
-               Parser_State.Tree.Set_State (Nonterm, New_State);
-
-               case Status is
-               when Ok =>
-                  Current_Parser.Set_Verb (Reduce);
-
-                  if Trace_Parse > Detail then
-                     Trace.Put_Line (" ... goto state " & Trimmed_Image 
(New_State));
-                  end if;
-
-               when Semantic_Checks.Error =>
-                  Current_Parser.Set_Verb (Error);
-                  Parser_State.Zombie_Token_Count := 1;
-               end case;
-            end if;
-         end;
-
-      when Accept_It =>
-         case Reduce_Stack_1
-           (Current_Parser,
-            (Reduce, Action.Production, Action.Action, Action.Check, 
Action.Token_Count),
-            Nonterm, Shared_Parser.Lexer, Trace)
-         is
-         when Ok =>
-            Current_Parser.Set_Verb (Action.Verb);
-
-            Parser_State.Tree.Set_Root (Nonterm);
-
-         when Semantic_Checks.Error =>
-            Current_Parser.Set_Verb (Error);
-            Parser_State.Zombie_Token_Count := 1;
-         end case;
-
-      when Error =>
-         Current_Parser.Set_Verb (Action.Verb);
-
-         Parser_State.Zombie_Token_Count := 1;
-
-         declare
-            Expecting : constant Token_ID_Set := LR.Expecting
-              (Shared_Parser.Table.all, Parser_State.Stack.Peek.State);
-         begin
-            Parser_State.Errors.Append
-              ((Label          => LR.Action,
-                First_Terminal => Trace.Descriptor.First_Terminal,
-                Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                Error_Token    => Parser_State.Current_Token,
-                Expecting      => Expecting,
-                Recover        => (others => <>)));
-
-            if Trace_Parse > Outline then
-               Put
-                 (Trace,
-                  Integer'Image (Current_Parser.Label) & ":" &
-                    Unknown_State_Index'Image (Parser_State.Stack.Peek.State) 
& ": expecting: " &
-                    Image (Expecting, Trace.Descriptor.all));
-               Trace.New_Line;
-            end if;
-         end;
-      end case;
-   end Do_Action;
-
-   procedure Do_Deletes
-     (Shared_Parser : in out LR.Parser.Parser;
-      Parser_State  : in out Parser_Lists.Parser_State)
-   is
-      use Recover_Op_Arrays, Recover_Op_Array_Refs;
-      Ins_Del     : Vector renames Parser_State.Recover_Insert_Delete;
-      Ins_Del_Cur : Extended_Index renames 
Parser_State.Recover_Insert_Delete_Current;
-   begin
-      if Trace_Parse > Extra then
-         Shared_Parser.Trace.Put_Line
-           (Integer'Image (Parser_State.Label) & ": shared_token:" &
-              WisiToken.Token_Index'Image (Parser_State.Shared_Token) &
-              " inc_shared_token: " & Boolean'Image 
(Parser_State.Inc_Shared_Token) &
-              " recover_insert_delete:" &
-              (if Parser_State.Recover_Insert_Delete_Current = No_Index
-               then ""
-               else Parser_State.Recover_Insert_Delete_Current'Image & " " &
-                  Image
-                    (Constant_Ref (Parser_State.Recover_Insert_Delete, 
Parser_State.Recover_Insert_Delete_Current),
-                     Shared_Parser.Trace.Descriptor.all)));
-      end if;
-
-      loop
-         exit when Ins_Del_Cur = Recover_Op_Arrays.No_Index;
-         declare
-            Op : Recover_Op renames Constant_Ref (Ins_Del, Ins_Del_Cur);
-         begin
-            if Op.Op = Delete and then
-              Op.Del_Token_Index =
-              (if Parser_State.Inc_Shared_Token
-               then Parser_State.Shared_Token + 1
-               else Parser_State.Shared_Token)
-            then
-               Parser_State.Shared_Token := Parser_State.Shared_Token + 1;
-               --  We don't reset Inc_Shared_Token here; only after the next 
token is
-               --  actually used.
-               Ins_Del_Cur := Ins_Del_Cur + 1;
-               if Ins_Del_Cur > Last_Index (Ins_Del)  then
-                  Ins_Del_Cur := No_Index;
-               end if;
-            else
-               exit;
-            end if;
-         end;
-      end loop;
-   end Do_Deletes;
-
-   --  Verb: the type of parser cycle to execute;
-   --
-   --  Accept : all Parsers.Verb return Accept - done parsing.
-   --
-   --  Shift : some Parsers.Verb return Shift, all with the same current
-   --  token in Shared_Parser.Terminals.
-   --
-   --  Pause : Resume is active, and this parser has reached Resume_Goal,
-   --  so it is waiting for the others to catch up.
-   --
-   --  Reduce : some Parsers.Verb return Reduce.
-   --
-   --  Error : all Parsers.Verb return Error.
-   --
-   --  Zombie_Count: count of parsers in Error state
-   procedure Parse_Verb
-     (Shared_Parser : in out LR.Parser.Parser;
-      Verb          :    out All_Parse_Action_Verbs;
-      Zombie_Count  :    out SAL.Base_Peek_Type)
-   is
-      Shift_Count   : SAL.Base_Peek_Type := 0;
-      Accept_Count  : SAL.Base_Peek_Type := 0;
-      Error_Count   : SAL.Base_Peek_Type := 0;
-      Resume_Active : Boolean            := False;
-   begin
-      Zombie_Count := 0;
-
-      for Parser_State of Shared_Parser.Parsers loop
-         case Parser_State.Verb is
-         when Pause | Shift =>
-            Do_Deletes (Shared_Parser, Parser_State);
-
-            Shift_Count := Shift_Count + 1;
-            Parser_State.Set_Verb (Shift);
-
-            if Parser_State.Resume_Active then
-               --  There may still be ops left in Recover_Insert_Delete after 
we get
-               --  to Resume_Token_Goal, probably from a Language_Fix or 
string quote
-               --  fix that deletes a lot of tokens.
-               if Parser_State.Resume_Token_Goal <= Parser_State.Shared_Token 
and
-                 Parser_State.Recover_Insert_Delete_Current = 
Recover_Op_Arrays.No_Index
-               then
-                  Parser_State.Resume_Active := False;
-                  if Trace_Parse > Detail then
-                     Shared_Parser.Trace.Put_Line (Integer'Image 
(Parser_State.Label) & ": resume_active: False");
-                  end if;
-               else
-                  Resume_Active := True;
-               end if;
-            end if;
-
-         when Reduce =>
-            Verb := Reduce;
-            return;
-
-         when Accept_It =>
-            Accept_Count := Accept_Count + 1;
-
-         when Error =>
-            if Shared_Parser.Enable_McKenzie_Recover then
-               --  This parser is waiting for others to error; they can 
continue
-               --  parsing.
-               Zombie_Count := Zombie_Count + 1;
-            else
-               Error_Count := Error_Count + 1;
-            end if;
-         end case;
-      end loop;
-
-      if Accept_Count > 0 and Shared_Parser.Parsers.Count = Accept_Count + 
Zombie_Count then
-         Verb := Accept_It;
-
-      elsif Shared_Parser.Parsers.Count = Error_Count + Zombie_Count then
-         Verb := Error;
-
-      elsif Shift_Count > 0 then
-         Verb := Shift;
-
-      else
-         raise SAL.Programmer_Error;
-      end if;
-
-      if Resume_Active then
-         for Parser_State of Shared_Parser.Parsers loop
-            if Parser_State.Verb = Shift and not Parser_State.Resume_Active 
then
-               Parser_State.Set_Verb (Pause);
-            end if;
-         end loop;
-      end if;
-   end Parse_Verb;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   overriding procedure Finalize (Object : in out LR.Parser.Parser)
-   is begin
-      Free_Table (Object.Table);
-   end Finalize;
-
-   procedure New_Parser
-     (Parser                         :    out          LR.Parser.Parser;
-      Trace                          : not null access WisiToken.Trace'Class;
-      Lexer                          : in              WisiToken.Lexer.Handle;
-      Table                          : in              Parse_Table_Ptr;
-      Language_Fixes                 : in              Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
Language_String_ID_Set_Access;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Max_Parallel                   : in              SAL.Base_Peek_Type := 
Default_Max_Parallel;
-      Terminate_Same_State           : in              Boolean            := 
True)
-   is
-      use all type Syntax_Trees.User_Data_Access;
-   begin
-      Parser.Lexer     := Lexer;
-      Parser.Trace     := Trace;
-      Parser.User_Data := User_Data;
-
-      --  Terminals,  Line_Begin_Token are initialized to empty arrays.
-
-      Parser.Table                          := Table;
-      Parser.Language_Fixes                 := Language_Fixes;
-      Parser.Language_Matching_Begin_Tokens := Language_Matching_Begin_Tokens;
-      Parser.Language_String_ID_Set         := Language_String_ID_Set;
-
-      Parser.Enable_McKenzie_Recover := not McKenzie_Defaulted (Table.all);
-
-      Parser.Max_Parallel         := Max_Parallel;
-      Parser.Terminate_Same_State := Terminate_Same_State;
-
-      if User_Data /= null then
-         User_Data.Set_Lexer_Terminals (Lexer, 
Parser.Terminals'Unchecked_Access);
-      end if;
-   end New_Parser;
-
-   overriding procedure Parse (Shared_Parser : aliased in out LR.Parser.Parser)
-   is
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-      use all type Syntax_Trees.User_Data_Access;
-      use all type Ada.Containers.Count_Type;
-
-      Trace : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-
-      Current_Verb   : All_Parse_Action_Verbs;
-      Action         : Parse_Action_Node_Ptr;
-      Zombie_Count   : SAL.Base_Peek_Type;
-
-      procedure Check_Error (Check_Parser : in out Parser_Lists.Cursor)
-      is
-         procedure Report_Error
-         is begin
-            Shared_Parser.Parsers.First_State_Ref.Errors.Append
-              ((Label          => LR.Message,
-                First_Terminal => Trace.Descriptor.First_Terminal,
-                Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                Recover        => <>,
-                Msg            => +"error during resume"));
-            if Debug_Mode then
-               raise SAL.Programmer_Error with Check_Parser.Label'Image & ": 
error during resume";
-            else
-               raise Syntax_Error;
-            end if;
-         end Report_Error;
-
-      begin
-         if Check_Parser.Verb = Error then
-            --  This parser errored on last input. This is how grammar 
conflicts
-            --  are resolved when the input text is valid, in which case we 
should
-            --  just terminate this parser. However, this may be due to invalid
-            --  input text, so we keep the parser alive but suspended for a few
-            --  tokens, to see if the other parsers also error, in which case 
they
-            --  all participate in error recovery.
-
-            --  We do not create zombie parsers during resume.
-            if not Check_Parser.State_Ref.Resume_Active then
-               --  Parser is now a zombie
-               if Trace_Parse > Detail then
-                  Trace.Put_Line (Integer'Image (Check_Parser.Label) & ": 
zombie");
-               end if;
-               Check_Parser.Next;
-
-            else
-               if Shared_Parser.Parsers.Count = 1 then
-                  Report_Error;
-
-               else
-                  --  This is ok if a conflict occured during resume - we 
assume this is
-                  --  a branch that failed during recover as well. Otherwise 
it's a
-                  --  programmer error.
-                  if Check_Parser.State_Ref.Conflict_During_Resume then
-                     Shared_Parser.Parsers.Terminate_Parser
-                       (Check_Parser, "error in conflict during resume", 
Shared_Parser.Trace.all,
-                        Shared_Parser.Terminals);
-                  else
-                     Report_Error;
-                  end if;
-               end if;
-            end if;
-         else
-            Check_Parser.Next;
-         end if;
-      end Check_Error;
-
-   begin
-      if Debug_Mode then
-         Trace.Put_Clock ("start");
-      end if;
-
-      if Shared_Parser.User_Data /= null then
-         Shared_Parser.User_Data.Reset;
-      end if;
-
-      Shared_Parser.String_Quote_Checked := Invalid_Line_Number;
-      Shared_Parser.Shared_Tree.Clear;
-      Shared_Parser.Parsers              := Parser_Lists.New_List
-        (Shared_Tree => Shared_Parser.Shared_Tree'Unchecked_Access);
-
-      Shared_Parser.Lex_All;
-
-      Shared_Parser.Parsers.First.State_Ref.Stack.Push 
((Shared_Parser.Table.State_First, others => <>));
-
-      Main_Loop :
-      loop
-         --  exit on Accept_It action or syntax error.
-
-         Parse_Verb (Shared_Parser, Current_Verb, Zombie_Count);
-
-         if Trace_Parse > Extra then
-            Trace.Put_Line ("cycle start; current_verb: " & 
Parse_Action_Verbs'Image (Current_Verb));
-         end if;
-
-         case Current_Verb is
-         when Pause =>
-            null;
-
-         when Shift =>
-            --  We just shifted a token; get the next token from
-            --  Shared_Parser.Terminals.
-
-            for Parser_State of Shared_Parser.Parsers loop
-               if Parser_State.Verb = Error then
-                  if Shared_Parser.Enable_McKenzie_Recover then
-                     Parser_State.Zombie_Token_Count := 
Parser_State.Zombie_Token_Count + 1;
-                     if Trace_Parse > Extra then
-                        Trace.Put_Line
-                          (Integer'Image (Parser_State.Label) & ": zombie (" &
-                             WisiToken.Token_Index'Image
-                               (Shared_Parser.Table.McKenzie_Param.Check_Limit 
- Parser_State.Zombie_Token_Count) &
-                             " tokens remaining)");
-                     end if;
-                  end if;
-
-               elsif Parser_State.Verb = Shift then
-                  declare
-                     function Insert_Virtual return Boolean
-                     is
-                        use Recover_Op_Arrays, Recover_Op_Array_Refs;
-                        Ins_Del     : Vector renames 
Parser_State.Recover_Insert_Delete;
-                        Ins_Del_Cur : Extended_Index renames 
Parser_State.Recover_Insert_Delete_Current;
-                        Result : Boolean := False;
-                     begin
-                        if Ins_Del_Cur /= No_Index then
-                           declare
-                              Op : Recover_Op renames Variable_Ref (Ins_Del, 
Ins_Del_Cur);
-                           begin
-                              if Op.Op = Insert and then
-                                Op.Ins_Token_Index =
-                                (if Parser_State.Inc_Shared_Token
-                                 then Parser_State.Shared_Token + 1
-                                 else Parser_State.Shared_Token)
-                              then
-                                 Result := True;
-
-                                 Parser_State.Current_Token := 
Parser_State.Tree.Add_Terminal
-                                   (Op.Ins_ID, Before => Op.Ins_Token_Index);
-
-                                 Op.Ins_Tree_Node := 
Parser_State.Current_Token;
-
-                                 Ins_Del_Cur := Ins_Del_Cur + 1;
-                                 if Ins_Del_Cur > Last_Index (Ins_Del) then
-                                    Ins_Del_Cur := No_Index;
-                                 end if;
-                              end if;
-                           end;
-                        end if;
-                        return Result;
-                     end Insert_Virtual;
-                  begin
-                     if Insert_Virtual then
-                        null;
-
-                     elsif (if Parser_State.Inc_Shared_Token
-                            then Parser_State.Shared_Token + 1
-                            else Parser_State.Shared_Token) <= 
Shared_Parser.Terminals.Last_Index
-                     then
-                        if Parser_State.Inc_Shared_Token then
-                           --  Inc_Shared_Token is only set False by 
McKenzie_Recover; see there
-                           --  for when/why. Don't increment past wisi_eoi 
(happens when input
-                           --  buffer is empty; test_mckenzie_recover.adb 
Empty_Comments).
-                           Parser_State.Shared_Token := 
Parser_State.Shared_Token + 1;
-                        else
-                           Parser_State.Inc_Shared_Token := True;
-                        end if;
-
-                        Parser_State.Current_Token := Shared_Parser.Terminals
-                          (Parser_State.Shared_Token).Tree_Index;
-
-                     end if;
-                  end;
-
-                  if Trace_Parse > Extra then
-                     Trace.Put_Line
-                       (Integer'Image (Parser_State.Label) & ": current_token" 
& Parser_State.Tree.Image
-                          (Parser_State.Current_Token, Trace.Descriptor.all));
-                  end if;
-               end if;
-            end loop;
-
-         when Accept_It =>
-            --  All parsers accepted or are zombies.
-            declare
-               Count : constant SAL.Base_Peek_Type := 
Shared_Parser.Parsers.Count;
-               Current_Parser : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-            begin
-               if Count = 1 then
-                  --  Nothing more to do
-                  exit Main_Loop;
-
-               elsif Zombie_Count + 1 = Count then
-                  --  All but one are zombies
-                  loop
-                     if Current_Parser.Verb = Accept_It then
-                        Current_Parser.Next;
-                     else
-                        declare
-                           Temp  : Parser_Lists.Cursor := Current_Parser;
-                        begin
-                           Current_Parser.Next;
-                           Shared_Parser.Parsers.Terminate_Parser
-                             (Temp, "zombie", Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                        end;
-                     end if;
-                     exit when Current_Parser.Is_Done;
-                  end loop;
-
-                  exit Main_Loop;
-
-               else
-                  --  More than one parser is active.
-                  declare
-                     use all type Parser_Lists.Cursor;
-                     Error_Parser_Count : Integer := (if 
Shared_Parser.Lexer.Errors.Length > 0 then 1 else 0);
-
-                     Recover_Cost           : Integer;
-                     Min_Recover_Cost       : Integer                   := 
Integer'Last;
-                     Recover_Ops_Length     : Ada.Containers.Count_Type;
-                     Min_Recover_Ops_Length : Ada.Containers.Count_Type := 
Ada.Containers.Count_Type'Last;
-                     Recover_Cur            : Parser_Lists.Cursor       := 
Current_Parser;
-                  begin
-                     Current_Parser := Shared_Parser.Parsers.First;
-                     loop
-                        if Current_Parser.Verb = Accept_It then
-                           if Current_Parser.State_Ref.Errors.Length > 0 then
-                              Error_Parser_Count := Error_Parser_Count + 1;
-                           end if;
-                           Current_Parser.Next;
-                        else
-                           declare
-                              Temp  : Parser_Lists.Cursor := Current_Parser;
-                           begin
-                              Current_Parser.Next;
-                              Shared_Parser.Parsers.Terminate_Parser
-                                (Temp, "zombie", Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                           end;
-                        end if;
-                        exit when Current_Parser.Is_Done;
-                     end loop;
-
-                     if Error_Parser_Count > 0 then
-                        --  There was at least one error. We assume that 
caused the ambiguous
-                        --  parse, and we pick the parser with the minimum 
cost and minimum
-                        --  recover ops length (consistent with 
Duplicate_State) to allow the
-                        --  parse to succeed. We terminate the other parsers 
so the remaining
-                        --  parser can do Execute_Actions.
-                        --
-                        --  If there are multiple errors, this metric is not 
very meaningful.
-                        --
-                        --  Note all surviving parsers must have the same 
error count.
-                        Current_Parser := Shared_Parser.Parsers.First;
-                        loop
-                           Recover_Cost := Current_Parser.Min_Recover_Cost;
-                           if Recover_Cost < Min_Recover_Cost then
-                              Min_Recover_Cost       := Recover_Cost;
-                              Min_Recover_Ops_Length := 
Current_Parser.Max_Recover_Ops_Length;
-                              Recover_Cur            := Current_Parser;
-
-                           elsif Recover_Cost = Min_Recover_Cost then
-                              Recover_Ops_Length := 
Current_Parser.Max_Recover_Ops_Length;
-                              if Recover_Ops_Length < Min_Recover_Ops_Length 
then
-                                 Min_Recover_Ops_Length := Recover_Ops_Length;
-                                 Recover_Cur    := Current_Parser;
-                              end if;
-                           end if;
-                           Current_Parser.Next;
-                           exit when Current_Parser.Is_Done;
-                        end loop;
-
-                        Current_Parser := Shared_Parser.Parsers.First;
-                        loop
-                           if Current_Parser = Recover_Cur then
-                              Current_Parser.Next;
-                           else
-                              declare
-                                 Temp  : Parser_Lists.Cursor := Current_Parser;
-                              begin
-                                 Current_Parser.Next;
-                                 Shared_Parser.Parsers.Terminate_Parser
-                                   (Temp,
-                                    (if Recover_Cost = Min_Recover_Cost and 
then
-                                       Recover_Ops_Length = 
Min_Recover_Ops_Length
-                                     then "random"
-                                     else "recover cost/length"),
-                                    Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                              end;
-                           end if;
-                           exit when Current_Parser.Is_Done;
-                        end loop;
-
-                        exit Main_Loop;
-
-                     else
-                        --  There were no previous errors. We allow the parse 
to fail, on the
-                        --  assumption that an otherwise correct input should 
not yield an
-                        --  ambiguous parse.
-                        declare
-                           Token : Base_Token renames Shared_Parser.Terminals 
(Shared_Parser.Terminals.Last_Index);
-                        begin
-                           raise WisiToken.Parse_Error with Error_Message
-                             (Shared_Parser.Lexer.File_Name, Token.Line, 
Token.Column,
-                              "Ambiguous parse:" & SAL.Base_Peek_Type'Image 
(Count) & " parsers active.");
-                        end;
-                     end if;
-                  end;
-               end if;
-            end;
-
-         when Reduce =>
-            null;
-
-         when Error =>
-            --  All parsers errored; attempt recovery
-            declare
-               use all type McKenzie_Recover.Recover_Status;
-
-               Recover_Result : McKenzie_Recover.Recover_Status := 
McKenzie_Recover.Recover_Status'First;
-
-               Pre_Recover_Parser_Count : constant SAL.Base_Peek_Type := 
Shared_Parser.Parsers.Count;
-               Start : Ada.Calendar.Time;
-            begin
-               --  Recover algorithms expect current token at
-               --  Parsers(*).Current_Token, will set
-               --  Parsers(*).Recover_Insert_Delete with new input tokens and
-               --  deletions, adjust Parsers(*).Stack, and set
-               --  Parsers(*).Current_Token and Parsers(*).Verb.
-
-               if Shared_Parser.Enable_McKenzie_Recover then
-                  if Debug_Mode then
-                     Trace.Put_Clock ("pre-recover" & 
Shared_Parser.Parsers.Count'Img & " active");
-                     Start := Ada.Calendar.Clock;
-                  end if;
-                  Recover_Result := McKenzie_Recover.Recover (Shared_Parser);
-                  if Debug_Mode then
-                     declare
-                        use Ada.Calendar;
-                        Recover_Duration : constant Duration := Clock - Start;
-                     begin
-                        Trace.Put_Clock
-                          ("post-recover" & Shared_Parser.Parsers.Count'Img & 
" active," & Recover_Duration'Image);
-                     end;
-                  end if;
-
-                  if Trace_Parse > Outline then
-                     if Recover_Result = Success  then
-                        Trace.Put_Line
-                          ("recover: succeed, parser count" & 
SAL.Base_Peek_Type'Image (Shared_Parser.Parsers.Count));
-                     else
-                        Trace.Put_Line
-                          ("recover: fail " & 
McKenzie_Recover.Recover_Status'Image (Recover_Result) &
-                             ", parser count" & SAL.Base_Peek_Type'Image 
(Shared_Parser.Parsers.Count));
-                     end if;
-                  end if;
-
-                  if Ada.Text_IO.Is_Open (Shared_Parser.Recover_Log_File) then
-                     declare
-                        use Ada.Text_IO;
-                     begin
-                        Put
-                          (Shared_Parser.Recover_Log_File,
-                           Ada.Calendar.Formatting.Image (Ada.Calendar.Clock) 
& " " &
-                             Shared_Parser.Partial_Parse_Active'Image & " " &
-                             Recover_Result'Image & " " &
-                             Pre_Recover_Parser_Count'Image & " '" &
-                             Shared_Parser.Lexer.File_Name & "'");
-
-                        Put (Shared_Parser.Recover_Log_File, '(');
-                        for Parser of Shared_Parser.Parsers loop
-                           Put (Shared_Parser.Recover_Log_File, Image 
(Parser.Recover.Results.Peek.Strategy_Counts));
-                           Put
-                             (Shared_Parser.Recover_Log_File,
-                              Integer'Image (Parser.Recover.Enqueue_Count) &
-                                Integer'Image (Parser.Recover.Check_Count) & " 
" &
-                                Boolean'Image (Parser.Recover.Success));
-                        end loop;
-                        Put (Shared_Parser.Recover_Log_File, ')');
-
-                        New_Line (Shared_Parser.Recover_Log_File);
-                        Flush (Shared_Parser.Recover_Log_File);
-                     end;
-                  end if;
-               else
-                  if Trace_Parse > Outline or Trace_McKenzie > Outline then
-                     Trace.Put_Line ("recover disabled");
-                  end if;
-               end if;
-
-               if Recover_Result = Success then
-                  for Parser_State of Shared_Parser.Parsers loop
-                     Parser_State.Resume_Active          := True;
-                     Parser_State.Conflict_During_Resume := False;
-
-                     if Trace_Parse > Outline then
-                        Trace.Put_Line
-                          (Integer'Image (Parser_State.Label) & ": 
Current_Token " &
-                             Parser_State.Tree.Image 
(Parser_State.Current_Token, Trace.Descriptor.all) &
-                             " Shared_Token " & Image
-                               (Parser_State.Shared_Token, 
Shared_Parser.Terminals, Trace.Descriptor.all));
-
-                        if Trace_Parse > Detail then
-                           Shared_Parser.Trace.Put_Line
-                             (Integer'Image (Parser_State.Label) & ": 
resume_active: True, token goal" &
-                                WisiToken.Token_Index'Image 
(Parser_State.Resume_Token_Goal));
-                        end if;
-                     end if;
-
-                     Parser_State.Zombie_Token_Count := 0;
-
-                     case Parser_State.Verb is
-                     when Reduce =>
-                        null;
-
-                     when Error =>
-                        --  Force this parser to be terminated.
-                        if Shared_Parser.Enable_McKenzie_Recover then
-                           Parser_State.Zombie_Token_Count := 
Shared_Parser.Table.McKenzie_Param.Check_Limit + 1;
-                        end if;
-
-                     when Shift =>
-                        null;
-
-                     when Pause | Accept_It =>
-                        raise SAL.Programmer_Error;
-                     end case;
-                  end loop;
-
-               else
-                  --  Terminate with error. Parser_State has all the required 
info on
-                  --  the original error (recorded by Error in Do_Action); 
report reason
-                  --  recover failed.
-                  for Parser_State of Shared_Parser.Parsers loop
-                     Parser_State.Errors.Append
-                       ((Label          => LR.Message,
-                         First_Terminal => Trace.Descriptor.First_Terminal,
-                         Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                         Recover        => <>,
-                         Msg            =>
-                           (if Shared_Parser.Enable_McKenzie_Recover
-                            then +"recover: fail " & 
McKenzie_Recover.Recover_Status'Image (Recover_Result)
-                            else +"recover disabled")));
-                  end loop;
-                  raise WisiToken.Syntax_Error;
-               end if;
-
-               --  Recover sets Parser.Verb to Shift for all active parsers, to
-               --  indicate it no longer has an error. Set Current_Verb to 
reflect
-               --  that.
-               Current_Verb := Shift;
-            end;
-         end case;
-
-         --  We don't use 'for Parser_State of Parsers loop' here,
-         --  because terminate on error and spawn on conflict require
-         --  changing the parser list.
-         declare
-            Current_Parser : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-         begin
-            Action_Loop :
-            loop
-               exit Action_Loop when Current_Parser.Is_Done;
-
-               --  We don't check duplicate state during resume, because the 
tokens
-               --  inserted/deleted by error recover may cause initially 
duplicate
-               --  states to diverge.
-               if not Current_Parser.State_Ref.Resume_Active and
-                 Shared_Parser.Terminate_Same_State and
-                 Current_Verb = Shift
-               then
-                  Shared_Parser.Parsers.Duplicate_State
-                    (Current_Parser, Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                  --  If Duplicate_State terminated Current_Parser, 
Current_Parser now
-                  --  points to the next parser. Otherwise it is unchanged.
-               end if;
-
-               exit Action_Loop when Current_Parser.Is_Done;
-
-               if Trace_Parse > Extra then
-                  Trace.Put_Line
-                    ("current_verb: " & Parse_Action_Verbs'Image 
(Current_Verb) &
-                       "," & Integer'Image (Current_Parser.Label) &
-                       ".verb: " & Parse_Action_Verbs'Image 
(Current_Parser.Verb));
-               end if;
-
-               --  Each branch of the following 'if' calls either 
Current_Parser.Free
-               --  (which advances to the next parser) or Current_Parser.Next.
-
-               if Current_Parser.Verb = Error then
-                  --  This parser is a zombie; see Check_Error above.
-                  --
-                  --  Check to see if it is time to terminate it
-                  if Shared_Parser.Enable_McKenzie_Recover and then
-                    Current_Parser.State_Ref.Zombie_Token_Count <= 
Shared_Parser.Table.McKenzie_Param.Check_Limit
-                  then
-                     if Trace_Parse > Detail then
-                        Trace.Put_Line (Integer'Image (Current_Parser.Label) & 
": zombie");
-                     end if;
-
-                     Current_Parser.Next;
-                  else
-                     Shared_Parser.Parsers.Terminate_Parser
-                       (Current_Parser, "zombie", Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                  end if;
-
-               elsif Current_Parser.Verb = Current_Verb then
-
-                  if Trace_Parse > Extra then
-                     Parser_Lists.Put_Top_10 (Trace, Current_Parser);
-                  end if;
-
-                  declare
-                     State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref.Element.all;
-                  begin
-                     Action := Action_For
-                       (Table => Shared_Parser.Table.all,
-                        State => State.Stack.Peek.State,
-                        ID    => State.Tree.ID (State.Current_Token));
-                  end;
-
-                  declare
-                     Conflict : Parse_Action_Node_Ptr := Action.Next;
-                  begin
-                     loop
-                        exit when Conflict = null;
-                        --  Spawn a new parser (before modifying 
Current_Parser stack).
-
-                        Current_Parser.State_Ref.Conflict_During_Resume := 
Current_Parser.State_Ref.Resume_Active;
-
-                        if Shared_Parser.Parsers.Count = 
Shared_Parser.Max_Parallel then
-                           --  If errors were recovered, terminate a parser 
that used the
-                           --  highest cost solution.
-                           declare
-                              use all type 
WisiToken.Parse.LR.Parser_Lists.Cursor;
-                              Max_Recover_Cost : Integer             := 0;
-                              Cur              : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-                              Max_Parser       : Parser_Lists.Cursor := Cur;
-                           begin
-                              loop
-                                 exit when Cur.Is_Done;
-                                 if Cur.Total_Recover_Cost > Max_Recover_Cost 
then
-                                    Max_Parser       := Cur;
-                                    Max_Recover_Cost := Cur.Total_Recover_Cost;
-                                 end if;
-                                 Cur.Next;
-                              end loop;
-
-                              if Max_Recover_Cost > 0 then
-                                 if Max_Parser = Current_Parser then
-                                    Current_Parser.Next;
-
-                                    Shared_Parser.Parsers.Terminate_Parser
-                                      (Max_Parser, "too many parsers; max 
error repair cost", Trace,
-                                       Shared_Parser.Terminals);
-
-                                    --  We changed Current_Parser, so start 
over
-                                    goto Continue_Action_Loop;
-                                 else
-                                    Shared_Parser.Parsers.Terminate_Parser
-                                      (Max_Parser, "too many parsers; max 
error repair cost", Trace,
-                                       Shared_Parser.Terminals);
-                                 end if;
-                              end if;
-                           end;
-                        end if;
-
-                        if Shared_Parser.Parsers.Count = 
Shared_Parser.Max_Parallel then
-                           declare
-                              Parser_State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref;
-                              Token : Base_Token renames 
Shared_Parser.Terminals (Parser_State.Shared_Token);
-                           begin
-                              raise WisiToken.Parse_Error with Error_Message
-                                (Shared_Parser.Lexer.File_Name, Token.Line, 
Token.Column,
-                                 "too many parallel parsers required in 
grammar state" &
-                                   State_Index'Image 
(Parser_State.Stack.Peek.State) &
-                                   "; simplify grammar, or increase 
max-parallel (" &
-                                   SAL.Base_Peek_Type'Image 
(Shared_Parser.Max_Parallel) & ")");
-                           end;
-
-                        else
-                           if Trace_Parse > Outline then
-                              declare
-                                 Parser_State : Parser_Lists.Parser_State 
renames Current_Parser.State_Ref;
-                              begin
-                                 Trace.Put_Line
-                                   (Integer'Image (Current_Parser.Label) & ": 
" &
-                                      Trimmed_Image 
(Parser_State.Stack.Peek.State) & ": " &
-                                      Parser_State.Tree.Image
-                                        (Parser_State.Current_Token, 
Trace.Descriptor.all) & " : " &
-                                      "spawn" & Integer'Image 
(Shared_Parser.Parsers.Last_Label + 1) & ", (" &
-                                      Trimmed_Image (1 + Integer 
(Shared_Parser.Parsers.Count)) & " active)");
-                              end;
-                           end if;
-
-                           Shared_Parser.Parsers.Prepend_Copy (Current_Parser);
-                           Do_Action (Conflict.Item, 
Shared_Parser.Parsers.First, Shared_Parser);
-
-                           --  We must terminate error parsers immediately in 
order to avoid
-                           --  zombie parsers during recovery.
-                           declare
-                              Temp : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-                           begin
-                              Check_Error (Temp);
-                           end;
-                        end if;
-
-                        Conflict := Conflict.Next;
-                     end loop;
-                  end;
-                  Do_Action (Action.Item, Current_Parser, Shared_Parser);
-                  Check_Error (Current_Parser);
-
-               else
-                  --  Current parser is waiting for others to catch up
-                  Current_Parser.Next;
-               end if;
-               <<Continue_Action_Loop>>
-            end loop Action_Loop;
-         end;
-      end loop Main_Loop;
-
-      if Trace_Parse > Outline then
-         Trace.Put_Line (Shared_Parser.Parsers.First.Label'Image & ": 
succeed");
-      end if;
-
-      if Debug_Mode then
-         Trace.Put_Clock ("finish parse");
-      end if;
-
-      --  We don't raise Syntax_Error for lexer errors, since they are all
-      --  recovered, either by inserting a quote, or by ignoring the
-      --  character.
-   exception
-   when Syntax_Error | WisiToken.Parse_Error | Partial_Parse =>
-      if Debug_Mode then
-         Trace.Put_Clock ("finish - error");
-      end if;
-      raise;
-
-   when E : others =>
-      declare
-         Msg : constant String := Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E);
-      begin
-         if Shared_Parser.Parsers.Count > 0 then
-            --  Emacs displays errors in the *syntax-errors* buffer
-            Shared_Parser.Parsers.First_State_Ref.Errors.Append
-              ((Label          => LR.Message,
-                First_Terminal => Trace.Descriptor.First_Terminal,
-                Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                Recover        => <>,
-                Msg            => +Msg));
-         end if;
-
-         if Debug_Mode then
-            Trace.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E)); 
-- includes Prefix
-            Trace.New_Line;
-         end if;
-
-         --  Emacs displays the exception message in the echo area; easy to 
miss
-         raise WisiToken.Parse_Error with Msg;
-      end;
-   end Parse;
-
-   overriding function Tree (Shared_Parser : in Parser) return 
Syntax_Trees.Tree
-   is begin
-      if Shared_Parser.Parsers.Count > 1 then
-         raise WisiToken.Parse_Error with "ambigous parse";
-      else
-         return Shared_Parser.Parsers.First_State_Ref.Tree;
-      end if;
-   end Tree;
-
-   overriding function Tree_Var_Ref (Shared_Parser : aliased in out Parser) 
return Syntax_Trees.Tree_Variable_Reference
-   is begin
-      if Shared_Parser.Parsers.Count > 1 then
-         raise WisiToken.Parse_Error with "ambigous parse";
-      else
-         return (Element => Shared_Parser.Parsers.First_State_Ref.Tree'Access);
-      end if;
-   end Tree_Var_Ref;
-
-   overriding
-   procedure Execute_Actions
-     (Parser          : in out LR.Parser.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null)
-   is
-      use all type Syntax_Trees.User_Data_Access;
-      use all type WisiToken.Syntax_Trees.Semantic_Action;
-
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      procedure Process_Node
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index)
-      is
-         use all type Syntax_Trees.Node_Label;
-      begin
-         if Tree.Label (Node) /= Nonterm then
-            return;
-         end if;
-
-         declare
-            Tree_Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-         begin
-            Parser.User_Data.Reduce (Tree, Node, Tree_Children);
-            if Tree.Action (Node) /= null then
-               begin
-                  Tree.Action (Node) (Parser.User_Data.all, Tree, Node, 
Tree_Children);
-               exception
-               when E : others =>
-                  declare
-                     Line   : Line_Number_Type  := Line_Number_Type'First;
-                     Column : Ada.Text_IO.Count := Ada.Text_IO.Count'First;
-                  begin
-                     if Tree.First_Shared_Terminal (Node) = 
Invalid_Token_Index then
-                        declare
-                           Byte_Region : Buffer_Region renames 
Tree.Byte_Region (Node);
-                        begin
-                           if Byte_Region /= Null_Buffer_Region then
-                              Column := Ada.Text_IO.Count (Byte_Region.First);
-                           end if;
-                        end;
-                     else
-                        declare
-                           Token : Base_Token renames Parser.Terminals 
(Tree.First_Shared_Terminal (Node));
-                        begin
-                           Line := Token.Line;
-                           Column := Token.Column;
-                        end;
-                     end if;
-                     raise WisiToken.Parse_Error with Error_Message
-                       (Parser.Lexer.File_Name, Line, Column,
-                        "action raised exception " & 
Ada.Exceptions.Exception_Name (E) & ": " &
-                          Ada.Exceptions.Exception_Message (E));
-                  end;
-               end;
-            end if;
-         end;
-      end Process_Node;
-
-   begin
-      if Parser.User_Data /= null then
-         if Parser.Parsers.Count > 1 then
-            raise Syntax_Error with "ambiguous parse; can't execute actions";
-         end if;
-
-         declare
-            use Recover_Op_Arrays, Recover_Op_Array_Refs;
-            Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_State_Ref;
-         begin
-            pragma Assert (Parser_State.Tree.Flushed);
-
-            Parser_State.Tree.Set_Parents;
-
-            if Trace_Action > Outline then
-               if Trace_Action > Extra then
-                  Parser_State.Tree.Print_Tree (Descriptor, 
Parser_State.Tree.Root, Image_Augmented);
-                  Parser.Trace.New_Line;
-               end if;
-               Parser.Trace.Put_Line
-                 (Integer'Image (Parser_State.Label) & ": root node: " & 
Parser_State.Tree.Image
-                    (Parser_State.Tree.Root, Descriptor));
-            end if;
-
-            for I in First_Index (Parser_State.Recover_Insert_Delete) ..
-              Last_Index (Parser_State.Recover_Insert_Delete)
-            loop
-               declare
-                  Op : Recover_Op renames Constant_Ref 
(Parser_State.Recover_Insert_Delete, I);
-               begin
-                  case Op.Op is
-                  when Insert =>
-                     Parser.User_Data.Insert_Token (Parser_State.Tree, 
Op.Ins_Tree_Node);
-                  when Delete =>
-                     Parser.User_Data.Delete_Token (Parser_State.Tree, 
Op.Del_Token_Index);
-                  end case;
-               end;
-            end loop;
-
-            Parser.User_Data.Initialize_Actions (Parser_State.Tree);
-            Parser_State.Tree.Process_Tree (Process_Node'Access);
-         end;
-      end if;
-   end Execute_Actions;
-
-   overriding function Any_Errors (Parser : in LR.Parser.Parser) return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-      Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_Constant_State_Ref;
-   begin
-      pragma Assert (Parser_State.Tree.Flushed);
-      return Parser.Parsers.Count > 1 or Parser_State.Errors.Length > 0 or 
Parser.Lexer.Errors.Length > 0;
-   end Any_Errors;
-
-   overriding procedure Put_Errors (Parser : in LR.Parser.Parser)
-   is
-      use Ada.Text_IO;
-
-      Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_Constant_State_Ref;
-      Descriptor   : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-   begin
-      for Item of Parser.Lexer.Errors loop
-         Put_Line
-           (Current_Error,
-            Parser.Lexer.File_Name & ":0:0: lexer unrecognized character at" & 
Buffer_Pos'Image (Item.Char_Pos));
-      end loop;
-
-      for Item of Parser_State.Errors loop
-         case Item.Label is
-         when Action =>
-            declare
-               Index : constant Base_Token_Index := 
Parser_State.Tree.First_Shared_Terminal (Item.Error_Token);
-            begin
-               if Index = Invalid_Token_Index then
-                  --  Error_Token is virtual
-                  Put_Line
-                    (Current_Error,
-                     Error_Message
-                       (Parser.Lexer.File_Name, 1, 0,
-                        "syntax error: expecting " & Image (Item.Expecting, 
Descriptor) &
-                          ", found " & Image (Parser_State.Tree.ID 
(Item.Error_Token), Descriptor)));
-               else
-                  declare
-                     Token : Base_Token renames Parser.Terminals (Index);
-                  begin
-                     Put_Line
-                       (Current_Error,
-                        Error_Message
-                          (Parser.Lexer.File_Name, Token.Line, Token.Column,
-                           "syntax error: expecting " & Image (Item.Expecting, 
Descriptor) &
-                             ", found '" & Parser.Lexer.Buffer_Text 
(Token.Byte_Region) & "'"));
-                  end;
-               end if;
-            end;
-         when Check =>
-            Put_Line
-              (Current_Error,
-               Parser.Lexer.File_Name & ":0:0: semantic check error: " &
-                 Semantic_Checks.Image (Item.Check_Status, Descriptor));
-         when Message =>
-            Put_Line (Current_Error, -Item.Msg);
-         end case;
-
-         if Item.Recover.Stack.Depth /= 0 then
-            Put_Line (Current_Error, "   recovered: " & Image 
(Item.Recover.Ops, Descriptor));
-         end if;
-      end loop;
-   end Put_Errors;
-
-end WisiToken.Parse.LR.Parser;
diff --git a/packages/wisi/wisitoken-parse-lr-parser.ads 
b/packages/wisi/wisitoken-parse-lr-parser.ads
deleted file mode 100644
index 46626fd..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser.ads
+++ /dev/null
@@ -1,162 +0,0 @@
---  Abstract :
---
---  A generalized LR parser.
---
---  In a child package of Parser.LR partly for historical reasons,
---  partly to allow McKenzie_Recover to be in a sibling package.
---
---  Copyright (C) 2002, 2003, 2009, 2010, 2013-2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Parse.LR.Parser_Lists;
-with WisiToken.Lexer;
-with WisiToken.Parse;
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.LR.Parser is
-
-   Default_Max_Parallel : constant := 15;
-
-   type Language_Fixes_Access is access procedure
-     (Trace             : in out WisiToken.Trace'Class;
-      Lexer             : access constant WisiToken.Lexer.Instance'Class;
-      Parser_Label      : in     Natural;
-      Parse_Table       : in     WisiToken.Parse.LR.Parse_Table;
-      Terminals         : in     Base_Token_Arrays.Vector;
-      Tree              : in     Syntax_Trees.Tree;
-      Local_Config_Heap : in out Config_Heaps.Heap_Type;
-      Config            : in     Configuration);
-   --  Config encountered a parse table Error action, or failed a
-   --  semantic check; attempt to provide a language-specific fix,
-   --  enqueuing new configs on Local_Config_Heap.
-   --
-   --  For a failed semantic check, Config.Stack is in the pre-reduce
-   --  state, Config.Error_Token gives the nonterm token,
-   --  Config.Check_Token_Count the token count for the reduce. May be
-   --  called with Nonterm.Virtual = True or Tree.Valid_Indices (stack
-   --  top token_count items) false.
-   --
-   --  For an Error action, Config.Error_Token gives the terminal that
-   --  caused the error.
-
-   type Language_Matching_Begin_Tokens_Access is access procedure
-     (Tokens                  : in     Token_ID_Array_1_3;
-      Config                  : in     Configuration;
-      Matching_Tokens         :    out Token_ID_Arrays.Vector;
-      Forbid_Minimal_Complete :    out Boolean);
-   --  Tokens (1) caused a parse error; Tokens (2 .. 3) are the following
-   --  tokens (Invalid_Token_ID if none). Set Matching_Tokens to a token
-   --  sequence that starts a production matching Tokens. If
-   --  Minimal_Complete would produce a bad solution at this error point,
-   --  set Forbid_Minimal_Complete True.
-   --
-   --  For example, if Tokens is a block end, return tokens that are the
-   --  corresponding block begin. If the error point is inside a
-   --  multi-token 'end' (ie 'end if;', or 'end <name>;'), set
-   --  Forbid_Minimal_Complete True.
-
-   type Language_String_ID_Set_Access is access function
-     (Descriptor        : in WisiToken.Descriptor;
-      String_Literal_ID : in Token_ID)
-     return Token_ID_Set;
-   --  Return a Token_ID_Set containing String_Literal_ID and
-   --  nonterminals that can contain String_Literal_ID as part of an
-   --  expression. Used in placing a missing string quote.
-
-   type Post_Recover_Access is access procedure;
-
-   type Parser is new WisiToken.Parse.Base_Parser with record
-      Table                          : Parse_Table_Ptr;
-      Language_Fixes                 : Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : Language_String_ID_Set_Access;
-
-      String_Quote_Checked : Line_Number_Type := Invalid_Line_Number;
-      --  Max line checked for missing string quote.
-
-      Post_Recover : Post_Recover_Access;
-      --  Gather data for tests.
-
-      Shared_Tree : aliased Syntax_Trees.Base_Tree;
-      --  Each parser (normal and recover) has its own branched syntax tree,
-      --  all branched from this tree. Terminals are added to the tree when
-      --  they become the current token.
-      --
-      --  It is never the case that terminals are added to this shared tree
-      --  when there is more than one task active, so we don't need a
-      --  protected tree.
-      --
-      --  See WisiToken.LR.Parser_Lists Parser_State for more discussion of
-      --  Shared_Tree.
-
-      Parsers : aliased Parser_Lists.List;
-
-      Max_Parallel            : SAL.Base_Peek_Type;
-      Terminate_Same_State    : Boolean;
-      Enable_McKenzie_Recover : Boolean;
-      Recover_Log_File        : Ada.Text_IO.File_Type;
-      Partial_Parse_Active    : Boolean := False;
-      --  Partial_Parse_Active is only used in recover log messages.
-   end record;
-
-   overriding procedure Finalize (Object : in out LR.Parser.Parser);
-   --  Deep free Object.Table.
-
-   procedure New_Parser
-     (Parser                         :    out          LR.Parser.Parser;
-      Trace                          : not null access WisiToken.Trace'Class;
-      Lexer                          : in              WisiToken.Lexer.Handle;
-      Table                          : in              Parse_Table_Ptr;
-      Language_Fixes                 : in              Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
Language_String_ID_Set_Access;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Max_Parallel                   : in              SAL.Base_Peek_Type := 
Default_Max_Parallel;
-      Terminate_Same_State           : in              Boolean            := 
True);
-
-   overriding procedure Parse (Shared_Parser : aliased in out 
LR.Parser.Parser);
-   --  Attempt a parse. Calls Parser.Lexer.Reset, runs lexer to end of
-   --  input setting Shared_Parser.Terminals, then parses tokens.
-   --
-   --  If an error is encountered, Parser.Lexer_Errors and
-   --  Parsers(*).Errors contain information about the errors. If a
-   --  recover strategy succeeds, no exception is raised. If recover does
-   --  not succeed, raises Syntax_Error.
-   --
-   --  For errors where no recovery is possible, raises Parse_Error with
-   --  an appropriate error message.
-
-   overriding function Tree (Shared_Parser : in Parser) return 
Syntax_Trees.Tree;
-   overriding function Tree_Var_Ref (Shared_Parser : aliased in out Parser) 
return Syntax_Trees.Tree_Variable_Reference;
-   --  If there is one parser in Parsers, return its tree. Otherwise,
-   --  raise Parse_Error for an ambiguous parse.
-
-   overriding procedure Execute_Actions
-     (Parser          : in out LR.Parser.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null);
-   --  Call User_Data.Delete_Token on any tokens deleted by error
-   --  recovery, then User_Data.Reduce and the grammar semantic actions
-   --  on all nonterms in the syntax tree.
-
-   overriding function Any_Errors (Parser : in LR.Parser.Parser) return 
Boolean;
-   --  Return True if any errors where encountered, recovered or not.
-
-   overriding procedure Put_Errors (Parser : in LR.Parser.Parser);
-   --  Put user-friendly error messages from the parse to
-   --  Ada.Text_IO.Current_Error.
-
-end WisiToken.Parse.LR.Parser;
diff --git a/packages/wisi/wisitoken-parse-lr-parser_lists.adb 
b/packages/wisi/wisitoken-parse-lr-parser_lists.adb
deleted file mode 100644
index 553f772..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser_lists.adb
+++ /dev/null
@@ -1,416 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2014 - 2020  All Rights Reserved.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse.LR.Parser_Lists is
-
-   function Parser_Stack_Image
-     (Stack      : in Parser_Stacks.Stack;
-      Descriptor : in WisiToken.Descriptor;
-      Tree       : in Syntax_Trees.Tree;
-      Depth      : in SAL.Base_Peek_Type := 0)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-
-      Last : constant SAL.Base_Peek_Type :=
-        (if Depth = 0
-         then Stack.Depth
-         else SAL.Base_Peek_Type'Min (Depth, Stack.Depth));
-
-      Result : Unbounded_String := +"(";
-   begin
-      for I in 1 .. Last loop
-         declare
-            Item : Parser_Stack_Item renames Stack.Peek (I);
-         begin
-            Result := Result &
-              ((if Item.State = Unknown_State then " " else Trimmed_Image 
(Item.State)) & " :" &
-                 (if I = Stack.Depth
-                  then ""
-                  else
-                    (if Item.Token = Invalid_Node_Index -- From recover 
fast-forward
-                     then ""
-                     else Tree.Image (Item.Token, Descriptor) & ", ")));
-         end;
-      end loop;
-      return To_String (Result & ")");
-   end Parser_Stack_Image;
-
-   function New_List (Shared_Tree : in Syntax_Trees.Base_Tree_Access) return 
List
-   is
-      First_Parser_Label : constant := 0;
-      Parser : Parser_State := (Label => First_Parser_Label, others => <>);
-   begin
-      Parser.Tree.Initialize (Shared_Tree, Flush => True);
-
-      return Result : List
-      do
-         Result.Parser_Label := First_Parser_Label;
-
-         Result.Elements.Append (Parser);
-      end return;
-   end New_List;
-
-   function Last_Label (List : in Parser_Lists.List) return Natural
-   is begin
-      return List.Parser_Label;
-   end Last_Label;
-
-   function Count (List : in Parser_Lists.List) return SAL.Base_Peek_Type
-   is begin
-      return List.Elements.Length;
-   end Count;
-
-   function First (List : aliased in out Parser_Lists.List'Class) return Cursor
-   is begin
-      return (Elements => List.Elements'Access, Ptr => List.Elements.First);
-   end First;
-
-   procedure Next (Cursor : in out Parser_Lists.Cursor)
-   is begin
-      Parser_State_Lists.Next (Cursor.Ptr);
-   end Next;
-
-   function Is_Done (Cursor : in Parser_Lists.Cursor) return Boolean
-   is
-      use Parser_State_Lists;
-   begin
-      return Cursor.Ptr = No_Element;
-   end Is_Done;
-
-   function Label (Cursor : in Parser_Lists.Cursor) return Natural
-   is begin
-      return Parser_State_Lists.Constant_Ref (Cursor.Ptr).Label;
-   end Label;
-
-   function Total_Recover_Cost (Cursor : in Parser_Lists.Cursor) return Integer
-   is
-      Result : Integer := 0;
-   begin
-      for Error of Parser_State_Lists.Constant_Ref (Cursor.Ptr).Errors loop
-         Result := Error.Recover.Cost;
-      end loop;
-      return Result;
-   end Total_Recover_Cost;
-
-   function Max_Recover_Ops_Length (Cursor : in Parser_Lists.Cursor) return 
Ada.Containers.Count_Type
-   is
-      use Ada.Containers;
-      use Config_Op_Arrays;
-      Result : Count_Type := 0;
-      Errors : Parse_Error_Lists.List renames Parser_State_Lists.Constant_Ref 
(Cursor.Ptr).Errors;
-   begin
-      for Error of Errors loop
-         if Length (Error.Recover.Ops) > Result then
-            Result := Length (Error.Recover.Ops);
-         end if;
-      end loop;
-      return Result;
-   end Max_Recover_Ops_Length;
-
-   function Min_Recover_Cost (Cursor : in Parser_Lists.Cursor) return Integer
-   is
-      Result : Integer := Integer'Last;
-      Errors : Parse_Error_Lists.List renames Parser_State_Lists.Constant_Ref 
(Cursor.Ptr).Errors;
-   begin
-      for Error of Errors loop
-         if Error.Recover.Cost < Result then
-            Result := Error.Recover.Cost;
-         end if;
-      end loop;
-      return Result;
-   end Min_Recover_Cost;
-
-   procedure Set_Verb (Cursor : in Parser_Lists.Cursor; Verb : in 
All_Parse_Action_Verbs)
-   is begin
-      Parser_State_Lists.Variable_Ref (Cursor.Ptr).Verb := Verb;
-   end Set_Verb;
-
-   function Verb (Cursor : in Parser_Lists.Cursor) return 
All_Parse_Action_Verbs
-   is begin
-      return Parser_State_Lists.Constant_Ref (Cursor.Ptr).Verb;
-   end Verb;
-
-   procedure Terminate_Parser
-     (Parsers   : in out List;
-      Current   : in out Cursor'Class;
-      Message   : in     String;
-      Trace     : in out WisiToken.Trace'Class;
-      Terminals : in     Base_Token_Arrays.Vector)
-   is
-      State : Parser_State renames Parser_State_Lists.Constant_Ref 
(Current.Ptr).Element.all;
-
-      procedure Free (Cursor : in out Parser_Lists.Cursor'Class)
-      is
-         Temp : Parser_State_Lists.Cursor := Cursor.Ptr;
-      begin
-         Parser_State_Lists.Next (Cursor.Ptr);
-         Parser_State_Lists.Delete (Cursor.Elements.all, Temp);
-      end Free;
-   begin
-      if Trace_Parse > Outline then
-         Trace.Put_Line
-           (Integer'Image (Current.Label) & ": terminate (" &
-              Trimmed_Image (Integer (Parsers.Count) - 1) & " active)" &
-              ": " & Message & Image
-                (State.Tree.First_Shared_Terminal (State.Current_Token),
-                 Terminals, Trace.Descriptor.all));
-      end if;
-
-      Free (Current);
-
-      if Parsers.Count = 1 then
-         Parsers.First.State_Ref.Tree.Flush;
-      end if;
-   end Terminate_Parser;
-
-   procedure Duplicate_State
-     (Parsers   : in out List;
-      Current   : in out Cursor'Class;
-      Trace     : in out WisiToken.Trace'Class;
-      Terminals : in     Base_Token_Arrays.Vector)
-   is
-      use all type Ada.Containers.Count_Type;
-
-      function Compare
-        (Stack_1 : in Parser_Stacks.Stack;
-         Tree_1  : in Syntax_Trees.Tree;
-         Stack_2 : in Parser_Stacks.Stack;
-         Tree_2  : in Syntax_Trees.Tree)
-        return Boolean
-      is
-      begin
-         if Stack_1.Depth /= Stack_2.Depth then
-            return False;
-         else
-            for I in reverse 1 .. Stack_1.Depth - 1 loop
-               --  Assume they differ near the top; no point in comparing 
bottom
-               --  item. The syntax trees will differ even if the tokens on 
the stack
-               --  are the same, so compare the tokens.
-               declare
-                  Item_1 : Parser_Stack_Item renames Stack_1 (I);
-                  Item_2 : Parser_Stack_Item renames Stack_2 (I);
-               begin
-                  if Item_1.State /= Item_2.State then
-                     return False;
-                  else
-                     if not Syntax_Trees.Same_Token (Tree_1, Item_1.Token, 
Tree_2, Item_2.Token) then
-                        return False;
-                     end if;
-                  end if;
-               end;
-            end loop;
-            return True;
-         end if;
-      end Compare;
-
-      Other : Cursor := Parsers.First;
-   begin
-      loop
-         exit when Other.Is_Done;
-         declare
-            Other_Parser : Parser_State renames Other.State_Ref;
-         begin
-            if Other.Label /= Current.Label and then
-              Other.Verb /= Error and then
-              Compare
-                (Other_Parser.Stack, Other_Parser.Tree, 
Current.State_Ref.Stack, Current.State_Ref.Tree)
-            then
-               exit;
-            end if;
-         end;
-         Other.Next;
-      end loop;
-
-      if not Other.Is_Done then
-         --  Both have the same number of errors, otherwise one would have been
-         --  terminated earlier.
-         if Other.Total_Recover_Cost = Current.Total_Recover_Cost then
-            if Other.Max_Recover_Ops_Length = Current.Max_Recover_Ops_Length 
then
-               Parsers.Terminate_Parser (Other, "duplicate state: random", 
Trace, Terminals);
-            else
-               --  Keep the minimum ops length
-               if Other.Max_Recover_Ops_Length > 
Current.Max_Recover_Ops_Length then
-                  null;
-               else
-                  Other := Cursor (Current);
-                  Current.Next;
-               end if;
-               Parsers.Terminate_Parser (Other, "duplicate state: ops length", 
Trace, Terminals);
-            end if;
-         else
-            if Other.Total_Recover_Cost > Current.Total_Recover_Cost then
-               null;
-            else
-               Other := Cursor (Current);
-               Current.Next;
-            end if;
-            Parsers.Terminate_Parser (Other, "duplicate state: cost", Trace, 
Terminals);
-         end if;
-      end if;
-   end Duplicate_State;
-
-   function State_Ref (Position : in Cursor) return State_Reference
-   is begin
-      return (Element => Parser_State_Lists.Constant_Ref 
(Position.Ptr).Element);
-   end State_Ref;
-
-   function First_State_Ref (List : in Parser_Lists.List'Class) return 
State_Reference
-   is begin
-      return (Element => Parser_State_Lists.Constant_Ref 
(List.Elements.First).Element);
-   end First_State_Ref;
-
-   function First_Constant_State_Ref (List : in Parser_Lists.List'Class) 
return Constant_State_Reference
-   is begin
-      return (Element => Parser_State_Lists.Constant_Ref 
(List.Elements.First).Element);
-   end First_Constant_State_Ref;
-
-   procedure Put_Top_10 (Trace : in out WisiToken.Trace'Class; Cursor : in 
Parser_Lists.Cursor)
-   is
-      Parser_State : Parser_Lists.Parser_State renames 
Parser_State_Lists.Constant_Ref (Cursor.Ptr);
-   begin
-      Trace.Put (Natural'Image (Parser_State.Label) & " stack: ");
-      Trace.Put_Line (Image (Parser_State.Stack, Trace.Descriptor.all, 
Parser_State.Tree, Depth => 10));
-   end Put_Top_10;
-
-   procedure Prepend_Copy
-     (List   : in out Parser_Lists.List;
-      Cursor : in     Parser_Lists.Cursor'Class)
-   is
-      New_Item : Parser_State;
-   begin
-      List.Parser_Label := List.Parser_Label + 1;
-      declare
-         Item : Parser_State renames Parser_State_Lists.Variable_Ref 
(Cursor.Ptr);
-         --  We can't do 'Prepend' in the scope of this 'renames';
-         --  that would be tampering with cursors.
-      begin
-         Item.Tree.Set_Flush_False;
-
-         --  We specify all items individually, rather copy Item and then
-         --  override a few, to avoid copying large items like Recover.
-         --  We copy Recover.Enqueue_Count .. Check_Count for unit tests.
-         New_Item :=
-           (Shared_Token                  => Item.Shared_Token,
-            Recover_Insert_Delete         => Item.Recover_Insert_Delete,
-            Recover_Insert_Delete_Current => 
Item.Recover_Insert_Delete_Current,
-            Current_Token                 => Item.Current_Token,
-            Inc_Shared_Token              => Item.Inc_Shared_Token,
-            Stack                         => Item.Stack,
-            Tree                          => Item.Tree,
-            Recover                       =>
-              (Enqueue_Count              => Item.Recover.Enqueue_Count,
-               Config_Full_Count          => Item.Recover.Config_Full_Count,
-               Check_Count                => Item.Recover.Check_Count,
-               others                     => <>),
-            Resume_Active                 => Item.Resume_Active,
-            Resume_Token_Goal             => Item.Resume_Token_Goal,
-            Conflict_During_Resume        => Item.Conflict_During_Resume,
-            Zombie_Token_Count            => 0,
-            Errors                        => Item.Errors,
-            Label                         => List.Parser_Label,
-            Verb                          => Item.Verb);
-      end;
-      List.Elements.Prepend (New_Item);
-   end Prepend_Copy;
-
-   ----------
-   --  stuff for iterators
-
-   function To_Cursor (Ptr : in Parser_Node_Access) return Cursor
-   is begin
-      return (Ptr.Elements, Ptr.Ptr);
-   end To_Cursor;
-
-   function Constant_Reference
-     (Container : aliased in List'Class;
-      Position  :         in Parser_Node_Access)
-     return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Parser_State_Lists.Constant_Ref 
(Position.Ptr).Element);
-   end Constant_Reference;
-
-   function Reference
-     (Container : aliased in out List'Class;
-      Position  :         in     Parser_Node_Access)
-     return State_Reference
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Parser_State_Lists.Variable_Ref 
(Position.Ptr).Element);
-   end Reference;
-
-   function Persistent_State_Ref (Position : in Parser_Node_Access) return 
State_Access
-   is begin
-      return State_Access (Parser_State_Lists.Persistent_Ref (Position.Ptr));
-   end Persistent_State_Ref;
-
-   type Iterator (Elements : access Parser_State_Lists.List) is new 
Iterator_Interfaces.Forward_Iterator
-     with null record;
-
-   overriding function First (Object : Iterator) return Parser_Node_Access;
-   overriding function Next
-     (Object   : in Iterator;
-      Position : in Parser_Node_Access)
-     return Parser_Node_Access;
-
-   overriding function First (Object : Iterator) return Parser_Node_Access
-   is begin
-      return (Elements => Object.Elements, Ptr => Object.Elements.First);
-   end First;
-
-   overriding function Next
-     (Object   : in Iterator;
-      Position : in Parser_Node_Access)
-     return Parser_Node_Access
-   is
-      pragma Unreferenced (Object);
-   begin
-      return (Position.Elements, Parser_State_Lists.Next (Position.Ptr));
-   end Next;
-
-   function Iterate (Container : aliased in out List) return 
Iterator_Interfaces.Forward_Iterator'Class
-   is begin
-      return Iterator'(Elements => Container.Elements'Access);
-   end Iterate;
-
-   function Has_Element (Iterator : in Parser_Node_Access) return Boolean
-   is begin
-      return Parser_State_Lists.Has_Element (Iterator.Ptr);
-   end Has_Element;
-
-   function Label (Iterator : in Parser_State) return Natural
-   is begin
-      return Iterator.Label;
-   end Label;
-
-   function Verb (Iterator : in Parser_State) return All_Parse_Action_Verbs
-   is begin
-      return Iterator.Verb;
-   end Verb;
-
-   procedure Set_Verb (Iterator : in out Parser_State; Verb : in 
All_Parse_Action_Verbs)
-   is begin
-      Iterator.Verb := Verb;
-   end Set_Verb;
-
-end WisiToken.Parse.LR.Parser_Lists;
diff --git a/packages/wisi/wisitoken-parse-lr-parser_lists.ads 
b/packages/wisi/wisitoken-parse-lr-parser_lists.ads
deleted file mode 100644
index 6a77e6c..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser_lists.ads
+++ /dev/null
@@ -1,274 +0,0 @@
---  Abstract :
---
---  Generalized LR parser state.
---
---  Copyright (C) 2014-2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Iterator_Interfaces;
-with SAL.Gen_Indefinite_Doubly_Linked_Lists;
-with SAL.Gen_Unbounded_Definite_Stacks;
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.LR.Parser_Lists is
-
-   type Parser_Stack_Item is record
-      State : Unknown_State_Index     := Unknown_State;
-      Token : Node_Index := Invalid_Node_Index;
-   end record;
-
-   package Parser_Stacks is new SAL.Gen_Unbounded_Definite_Stacks 
(Parser_Stack_Item);
-
-   function Parser_Stack_Image
-     (Stack      : in Parser_Stacks.Stack;
-      Descriptor : in WisiToken.Descriptor;
-      Tree       : in Syntax_Trees.Tree;
-      Depth      : in SAL.Base_Peek_Type := 0)
-     return String;
-   --  If Depth = 0, put all of Stack. Otherwise put Min (Depth,
-   --  Stack.Depth) items.
-   --
-   --  Unique name for calling from debugger
-
-   function Image
-     (Stack      : in Parser_Stacks.Stack;
-      Descriptor : in WisiToken.Descriptor;
-      Tree       : in Syntax_Trees.Tree;
-      Depth      : in SAL.Base_Peek_Type := 0)
-     return String renames Parser_Stack_Image;
-
-   type Base_Parser_State is tagged
-   record
-      --  Visible components for direct access
-
-      Shared_Token : Base_Token_Index := Invalid_Token_Index;
-      --  Last token read from Shared_Parser.Terminals.
-
-      Recover_Insert_Delete : aliased Recover_Op_Arrays.Vector;
-      --  Tokens that were inserted or deleted during error recovery.
-      --  Contains only Insert and Delete ops. Filled by error recover, used
-      --  by main parse and Execute_Actions.
-      --
-      --  Not emptied between error recovery sessions, so Execute_Actions
-      --  knows about all insert/delete.
-
-      Recover_Insert_Delete_Current : Recover_Op_Arrays.Extended_Index := 
Recover_Op_Arrays.No_Index;
-      --  Next item in Recover_Insert_Delete to be processed by main parse;
-      --  No_Index if all done.
-
-      Current_Token : Node_Index := Invalid_Node_Index;
-      --  Current terminal, in Tree
-
-      Inc_Shared_Token : Boolean := True;
-
-      Stack : Parser_Stacks.Stack;
-      --  There is no need to use a branched stack; max stack length is
-      --  proportional to source text nesting depth, not source text length.
-
-      Tree : aliased Syntax_Trees.Tree;
-      --  We use a branched tree to avoid copying large trees for each
-      --  spawned parser; tree size is proportional to source text size. In
-      --  normal parsing, parallel parsers are short-lived; they each process
-      --  a few tokens, to resolve a grammar conflict.
-      --
-      --  When there is only one parser, tree nodes are written directly to
-      --  the shared tree (via the branched tree, with Flush => True).
-      --
-      --  When there is more than one, tree nodes are written to the
-      --  branched tree. Then when all but one parsers are terminated, the
-      --  remaining branched tree is flushed into the shared tree.
-
-      Recover : aliased LR.McKenzie_Data := (others => <>);
-
-      Zombie_Token_Count : Base_Token_Index := 0;
-      --  If Zombie_Token_Count > 0, this parser has errored, but is waiting
-      --  to see if other parsers do also.
-
-      Resume_Active          : Boolean          := False;
-      Resume_Token_Goal      : Base_Token_Index := Invalid_Token_Index;
-      Conflict_During_Resume : Boolean          := False;
-      --  Resume is complete for this parser Shared_Token reaches this
-      --  Resume_Token_Goal.
-
-      Errors : Parse_Error_Lists.List;
-   end record;
-
-   type Parser_State is new Base_Parser_State with private;
-   type State_Access is access all Parser_State;
-
-   type List is tagged private
-   with
-     Constant_Indexing => Constant_Reference,
-     Variable_Indexing => Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Parser_State;
-
-   function New_List (Shared_Tree : in Syntax_Trees.Base_Tree_Access) return 
List;
-
-   function Last_Label (List : in Parser_Lists.List) return Natural;
-
-   function Count (List : in Parser_Lists.List) return SAL.Base_Peek_Type;
-
-   type Cursor (<>) is tagged private;
-
-   function First (List : aliased in out Parser_Lists.List'Class) return 
Cursor;
-   procedure Next (Cursor : in out Parser_Lists.Cursor);
-   function Is_Done (Cursor : in Parser_Lists.Cursor) return Boolean;
-   function Has_Element (Cursor : in Parser_Lists.Cursor) return Boolean is 
(not Is_Done (Cursor));
-   function Label (Cursor : in Parser_Lists.Cursor) return Natural;
-   function Total_Recover_Cost (Cursor : in Parser_Lists.Cursor) return 
Integer;
-   function Max_Recover_Ops_Length (Cursor : in Parser_Lists.Cursor) return 
Ada.Containers.Count_Type;
-   function Min_Recover_Cost (Cursor : in Parser_Lists.Cursor) return Integer;
-
-   procedure Set_Verb (Cursor : in Parser_Lists.Cursor; Verb : in 
All_Parse_Action_Verbs);
-   function Verb (Cursor : in Parser_Lists.Cursor) return 
All_Parse_Action_Verbs;
-
-   procedure Terminate_Parser
-     (Parsers   : in out List;
-      Current   : in out Cursor'Class;
-      Message   : in     String;
-      Trace     : in out WisiToken.Trace'Class;
-      Terminals : in     Base_Token_Arrays.Vector);
-   --  Terminate Current. Current is set to no element.
-   --
-   --  Terminals is used to report the current token in the message.
-
-   procedure Duplicate_State
-     (Parsers   : in out List;
-      Current   : in out Cursor'Class;
-      Trace     : in out WisiToken.Trace'Class;
-      Terminals : in     Base_Token_Arrays.Vector);
-   --  If any other parser in Parsers has a stack equivalent to Current,
-   --  Terminate one of them. Current is either unchanged, or advanced to
-   --  the next parser.
-   --
-   --  Terminals is used to report the current token in the message.
-
-   type State_Reference (Element : not null access Parser_State) is null record
-   with Implicit_Dereference => Element;
-
-   function State_Ref (Position : in Cursor) return State_Reference
-   with Pre => Has_Element (Position);
-   --  Direct access to visible components of Parser_State
-
-   function First_State_Ref (List : in Parser_Lists.List'Class) return 
State_Reference
-   with Pre => List.Count > 0;
-   --  Direct access to visible components of first parser's Parser_State
-
-   type Constant_State_Reference (Element : not null access constant 
Parser_State) is null record
-   with Implicit_Dereference => Element;
-
-   function First_Constant_State_Ref (List : in Parser_Lists.List'Class) 
return Constant_State_Reference
-   with Pre => List.Count > 0;
-   --  Direct access to visible components of first parser's Parser_State
-
-   procedure Put_Top_10 (Trace : in out WisiToken.Trace'Class; Cursor : in 
Parser_Lists.Cursor);
-   --  Put image of top 10 stack items to Trace.
-
-   procedure Prepend_Copy (List : in out Parser_Lists.List; Cursor : in 
Parser_Lists.Cursor'Class);
-   --  Copy parser at Cursor, prepend to current list. New copy will not
-   --  appear in Cursor.Next ...; it is accessible as First (List).
-   --
-   --  Copy.Recover is set to default.
-
-   ----------
-   --  Stuff for iterators, to allow
-   --  'for Parser of Parsers loop'
-   --  'for I in Parsers.Iterate loop'
-   --
-   --  requires Parser_State to be not an incomplete type.
-
-   --  We'd like to use Cursor here, but we want that to be tagged, to
-   --  allow 'Cursor.operation' syntax, and the requirements of
-   --  iterators prevent a tagged iterator type (two tagged types on
-   --  First in this package body). So we use Parser_Node_Access as
-   --  the iterator type for Iterators, and typical usage is:
-   --
-   --  for I in Parsers.Iterate loop
-   --     declare
-   --        Cursor : Parser_Lists.Cursor renames To_Cursor (Parsers, I);
-   --     begin
-   --        Cursor.<cursor operation>
-   --
-   --        ... Parsers (I).<visible parser_state component> ...
-   --     end;
-   --  end loop;
-   --
-   --  or:
-   --  for Current_Parser of Parsers loop
-   --     ... Current_Parser.<visible parser_state component> ...
-   --  end loop;
-
-   type Parser_Node_Access (<>) is private;
-
-   function To_Cursor (Ptr : in Parser_Node_Access) return Cursor;
-
-   type Constant_Reference_Type (Element : not null access constant 
Parser_State) is null record
-   with Implicit_Dereference => Element;
-
-   function Constant_Reference
-     (Container : aliased in List'Class;
-      Position  :         in Parser_Node_Access)
-     return Constant_Reference_Type;
-   pragma Inline (Constant_Reference);
-
-   function Reference
-     (Container : aliased in out List'Class;
-      Position  :         in     Parser_Node_Access)
-     return State_Reference;
-   pragma Inline (Reference);
-
-   function Persistent_State_Ref (Position : in Parser_Node_Access) return 
State_Access;
-
-   function Has_Element (Iterator : in Parser_Node_Access) return Boolean;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces 
(Parser_Node_Access, Has_Element);
-
-   function Iterate (Container : aliased in out List) return 
Iterator_Interfaces.Forward_Iterator'Class;
-
-   --  Access to some private Parser_State components
-
-   function Label (Iterator : in Parser_State) return Natural;
-   procedure Set_Verb (Iterator : in out Parser_State; Verb : in 
All_Parse_Action_Verbs);
-   function Verb (Iterator : in Parser_State) return All_Parse_Action_Verbs;
-
-private
-
-   type Parser_State is new Base_Parser_State with record
-      Label : Natural; -- for debugging/verbosity
-
-      Verb : All_Parse_Action_Verbs := Shift; -- current action to perform
-   end record;
-
-   package Parser_State_Lists is new SAL.Gen_Indefinite_Doubly_Linked_Lists 
(Parser_State);
-
-   type List is tagged record
-      Elements     : aliased Parser_State_Lists.List;
-      Parser_Label : Natural; -- label of last added parser.
-   end record;
-
-   type Cursor (Elements : access Parser_State_Lists.List) is tagged
-   record
-      Ptr : Parser_State_Lists.Cursor;
-   end record;
-
-   type Parser_Node_Access (Elements : access Parser_State_Lists.List) is
-   record
-      Ptr : Parser_State_Lists.Cursor;
-   end record;
-
-end WisiToken.Parse.LR.Parser_Lists;
diff --git a/packages/wisi/wisitoken-parse-lr-parser_no_recover.adb 
b/packages/wisi/wisitoken-parse-lr-parser_no_recover.adb
deleted file mode 100644
index 6fd2b80..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser_no_recover.adb
+++ /dev/null
@@ -1,574 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-package body WisiToken.Parse.LR.Parser_No_Recover is
-
-   procedure Reduce_Stack_1
-     (Current_Parser : in     Parser_Lists.Cursor;
-      Action         : in     Reduce_Action_Rec;
-      Nonterm        :    out Valid_Node_Index;
-      Trace          : in out WisiToken.Trace'Class)
-   is
-      Parser_State  : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref.Element.all;
-      Children_Tree : Valid_Node_Index_Array (1 .. SAL.Base_Peek_Type 
(Action.Token_Count));
-      --  for Set_Children.
-   begin
-      for I in reverse Children_Tree'Range loop
-         Children_Tree (I) := Parser_State.Stack.Pop.Token;
-      end loop;
-
-      Nonterm := Parser_State.Tree.Add_Nonterm
-        (Action.Production, Children_Tree, Action.Action, Default_Virtual => 
False);
-      --  Computes Nonterm.Byte_Region
-
-      if Trace_Parse > Detail then
-         Trace.Put_Line (Parser_State.Tree.Image (Nonterm, 
Trace.Descriptor.all, Include_Children => True));
-      end if;
-   end Reduce_Stack_1;
-
-   procedure Do_Action
-     (Action         : in Parse_Action_Rec;
-      Current_Parser : in Parser_Lists.Cursor;
-      Shared_Parser  : in Parser)
-   is
-      Parser_State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref;
-      Trace        : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-      Nonterm      : Valid_Node_Index;
-   begin
-      if Trace_Parse > Detail then
-         Trace.Put
-           (Integer'Image (Current_Parser.Label) & ": " &
-              Trimmed_Image (Parser_State.Stack.Peek.State) & ": " &
-              Parser_State.Tree.Image (Parser_State.Current_Token, 
Trace.Descriptor.all) & " : ");
-         Put (Trace, Action);
-         Trace.New_Line;
-      end if;
-
-      case Action.Verb is
-      when Shift =>
-         Current_Parser.Set_Verb (Shift);
-         Parser_State.Stack.Push ((Action.State, Parser_State.Current_Token));
-         Parser_State.Tree.Set_State (Parser_State.Current_Token, 
Action.State);
-
-      when Reduce =>
-         Current_Parser.Set_Verb (Reduce);
-
-         declare
-            New_State : constant Unknown_State_Index := Goto_For
-              (Table => Shared_Parser.Table.all,
-               State => Parser_State.Stack (SAL.Base_Peek_Type 
(Action.Token_Count) + 1).State,
-               ID    => Action.Production.LHS);
-         begin
-            if New_State = Unknown_State then
-               --  This is due to a bug in the LALR parser generator (see
-               --  lalr_generator_bug_01.wy); we treat it as a syntax error.
-               Current_Parser.Set_Verb (Error);
-               if Trace_Parse > Detail then
-                  Trace.Put_Line (" ... error");
-               end if;
-            else
-               Reduce_Stack_1 (Current_Parser, Action, Nonterm, Trace);
-               Parser_State.Stack.Push ((New_State, Nonterm));
-               Parser_State.Tree.Set_State (Nonterm, New_State);
-
-               if Trace_Parse > Detail then
-                  Trace.Put_Line (" ... goto state " & Trimmed_Image 
(New_State));
-               end if;
-            end if;
-         end;
-
-      when Accept_It =>
-         Current_Parser.Set_Verb (Accept_It);
-         Reduce_Stack_1
-           (Current_Parser,
-            (Reduce, Action.Production, Action.Action, Action.Check, 
Action.Token_Count),
-            Nonterm, Trace);
-
-         Parser_State.Tree.Set_Root (Nonterm);
-
-      when Error =>
-         Current_Parser.Set_Verb (Action.Verb);
-
-         --  We don't raise Syntax_Error here; another parser may be able to
-         --  continue.
-
-         declare
-            Expecting : constant Token_ID_Set := LR.Expecting
-              (Shared_Parser.Table.all, 
Current_Parser.State_Ref.Stack.Peek.State);
-         begin
-            Parser_State.Errors.Append
-              ((Label          => LR.Action,
-                First_Terminal => Trace.Descriptor.First_Terminal,
-                Last_Terminal  => Trace.Descriptor.Last_Terminal,
-                Error_Token    => Parser_State.Current_Token,
-                Expecting      => Expecting,
-                Recover        => (others => <>)));
-
-            if Trace_Parse > Outline then
-               Put
-                 (Trace,
-                  Integer'Image (Current_Parser.Label) & ": expecting: " &
-                    Image (Expecting, Trace.Descriptor.all));
-               Trace.New_Line;
-            end if;
-         end;
-      end case;
-   end Do_Action;
-
-   --  Return the type of parser cycle to execute.
-   --
-   --  Accept : all Parsers.Verb return Accept - done parsing.
-   --
-   --  Shift : some Parsers.Verb return Shift.
-   --
-   --  Reduce : some Parsers.Verb return Reduce.
-   --
-   --  Error : all Parsers.Verb return Error.
-   procedure Parse_Verb
-     (Shared_Parser : in out Parser;
-      Verb          :    out All_Parse_Action_Verbs)
-   is
-      Shift_Count  : SAL.Base_Peek_Type := 0;
-      Accept_Count : SAL.Base_Peek_Type := 0;
-      Error_Count  : SAL.Base_Peek_Type := 0;
-   begin
-      for Parser_State of Shared_Parser.Parsers loop
-         case Parser_State.Verb is
-         when Shift =>
-            Shift_Count := Shift_Count + 1;
-
-         when Reduce =>
-            Verb := Reduce;
-            return;
-
-         when Accept_It =>
-            Accept_Count := Accept_Count + 1;
-
-         when Error =>
-            Error_Count := Error_Count + 1;
-
-         when Pause =>
-            --  This is parser_no_recover
-            raise SAL.Programmer_Error;
-         end case;
-      end loop;
-
-      if Shared_Parser.Parsers.Count = Accept_Count then
-         Verb := Accept_It;
-
-      elsif Shared_Parser.Parsers.Count = Error_Count then
-         Verb := Error;
-
-      elsif Shift_Count > 0 then
-         Verb := Shift;
-
-      else
-         raise SAL.Programmer_Error;
-      end if;
-   end Parse_Verb;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   overriding procedure Finalize (Object : in out Parser)
-   is begin
-      Free_Table (Object.Table);
-   end Finalize;
-
-   procedure New_Parser
-     (Parser               :    out          LR.Parser_No_Recover.Parser;
-      Trace                : not null access WisiToken.Trace'Class;
-      Lexer                : in              WisiToken.Lexer.Handle;
-      Table                : in              Parse_Table_Ptr;
-      User_Data            : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Max_Parallel         : in              SAL.Base_Peek_Type := 
Default_Max_Parallel;
-      First_Parser_Label   : in              Integer            := 1;
-      Terminate_Same_State : in              Boolean            := True)
-   is
-      use all type Syntax_Trees.User_Data_Access;
-   begin
-      Parser.Lexer                := Lexer;
-      Parser.Trace                := Trace;
-      Parser.Table                := Table;
-      Parser.User_Data            := User_Data;
-      Parser.Max_Parallel         := Max_Parallel;
-      Parser.First_Parser_Label   := First_Parser_Label;
-      Parser.Terminate_Same_State := Terminate_Same_State;
-
-      if User_Data /= null then
-         User_Data.Set_Lexer_Terminals (Lexer, 
Parser.Terminals'Unchecked_Access);
-      end if;
-   end New_Parser;
-
-   overriding procedure Parse (Shared_Parser : aliased in out Parser)
-   is
-      use all type Syntax_Trees.User_Data_Access;
-
-      Trace : WisiToken.Trace'Class renames Shared_Parser.Trace.all;
-
-      Current_Verb : All_Parse_Action_Verbs;
-      Action       : Parse_Action_Node_Ptr;
-
-      procedure Check_Error (Check_Parser : in out Parser_Lists.Cursor)
-      is begin
-         if Check_Parser.Verb = Error then
-            --  This parser errored on last input. This is how grammar 
conflicts
-            --  are resolved when the input text is valid, so we terminate this
-            --  parser.
-
-            if Shared_Parser.Parsers.Count = 1 then
-               raise Syntax_Error;
-            else
-               Shared_Parser.Parsers.Terminate_Parser
-                 (Check_Parser, "", Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-            end if;
-         else
-            Check_Parser.Next;
-         end if;
-      end Check_Error;
-
-   begin
-      if Shared_Parser.User_Data /= null then
-         Shared_Parser.User_Data.Reset;
-      end if;
-
-      Shared_Parser.Shared_Tree.Clear;
-
-      Shared_Parser.Parsers := Parser_Lists.New_List
-        (Shared_Tree => Shared_Parser.Shared_Tree'Unchecked_Access);
-
-      Shared_Parser.Lex_All;
-
-      Shared_Parser.Parsers.First.State_Ref.Stack.Push 
((Shared_Parser.Table.State_First, others => <>));
-
-      Main_Loop :
-      loop
-         --  exit on Accept_It action or syntax error.
-
-         Parse_Verb (Shared_Parser, Current_Verb);
-
-         case Current_Verb is
-         when Shift =>
-            --  All parsers just shifted a token; get the next token
-
-            for Parser_State of Shared_Parser.Parsers loop
-               Parser_State.Shared_Token  := Parser_State.Shared_Token + 1;
-               Parser_State.Current_Token := Shared_Parser.Terminals
-                          (Parser_State.Shared_Token).Tree_Index;
-            end loop;
-
-         when Accept_It =>
-            --  All parsers accepted.
-            declare
-               Count : constant SAL.Base_Peek_Type := 
Shared_Parser.Parsers.Count;
-            begin
-               if Count = 1 then
-                  --  Nothing more to do
-                  if Trace_Parse > Outline then
-                     Trace.Put_Line (Integer'Image 
(Shared_Parser.Parsers.First.Label) & ": succeed");
-                  end if;
-                  exit Main_Loop;
-
-               else
-                  --  More than one parser is active; ambiguous parse.
-                  declare
-                     Token : Base_Token renames Shared_Parser.Terminals 
(Shared_Parser.Terminals.Last_Index);
-                  begin
-                     raise WisiToken.Parse_Error with Error_Message
-                       (Shared_Parser.Lexer.File_Name, Token.Line, 
Token.Column,
-                        "Ambiguous parse:" & SAL.Base_Peek_Type'Image (Count) 
& " parsers active.");
-                  end;
-               end if;
-            end;
-
-         when Reduce =>
-            null;
-
-         when Error =>
-            --  All parsers errored; terminate with error. Semantic_State has 
all
-            --  the required info (recorded by Error in Do_Action), so we just
-            --  raise the exception.
-            raise Syntax_Error;
-
-         when Pause =>
-            --  This is parser_no_recover
-            raise SAL.Programmer_Error;
-         end case;
-
-         --  We don't use 'for Parser_State of Parsers loop' here,
-         --  because terminate on error and spawn on conflict require
-         --  changing the parser list.
-         declare
-            Current_Parser : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-         begin
-            loop
-               exit when Current_Parser.Is_Done;
-
-               if Shared_Parser.Terminate_Same_State and
-                 Current_Verb = Shift
-               then
-                  Shared_Parser.Parsers.Duplicate_State
-                    (Current_Parser, Shared_Parser.Trace.all, 
Shared_Parser.Terminals);
-                  --  If Duplicate_State terminated Current_Parser, 
Current_Parser now
-                  --  points to the next parser. Otherwise it is unchanged.
-               end if;
-
-               exit when Current_Parser.Is_Done;
-
-               if Trace_Parse > Extra then
-                  Trace.Put_Line
-                    ("current_verb: " & Parse_Action_Verbs'Image 
(Current_Verb) &
-                       "," & Integer'Image (Current_Parser.Label) &
-                       ".verb: " & Parse_Action_Verbs'Image 
(Current_Parser.Verb));
-               end if;
-
-               --  Each branch of the following 'if' calls either 
Current_Parser.Free
-               --  (which advances to the next parser) or Current_Parser.Next.
-
-               if Current_Parser.Verb = Current_Verb then
-                  if Trace_Parse > Extra then
-                     Parser_Lists.Put_Top_10 (Trace, Current_Parser);
-                  end if;
-
-                  declare
-                     State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref.Element.all;
-                  begin
-                     Action := Action_For
-                       (Table => Shared_Parser.Table.all,
-                        State => State.Stack.Peek.State,
-                        ID    => State.Tree.ID (State.Current_Token));
-                  end;
-
-                  declare
-                     Conflict : Parse_Action_Node_Ptr := Action.Next;
-                  begin
-                     loop
-                        exit when Conflict = null;
-                        --  Spawn a new parser (before modifying 
Current_Parser stack).
-
-                        if Shared_Parser.Parsers.Count = 
Shared_Parser.Max_Parallel then
-                           declare
-                              Parser_State : Parser_Lists.Parser_State renames 
Current_Parser.State_Ref;
-                              Token : Base_Token renames 
Shared_Parser.Terminals (Parser_State.Shared_Token);
-                           begin
-                              raise WisiToken.Parse_Error with Error_Message
-                                (Shared_Parser.Lexer.File_Name, Token.Line, 
Token.Column,
-                                 ": too many parallel parsers required in 
grammar state" &
-                                   State_Index'Image 
(Parser_State.Stack.Peek.State) &
-                                   "; simplify grammar, or increase 
max-parallel (" &
-                                   SAL.Base_Peek_Type'Image 
(Shared_Parser.Max_Parallel) & ")");
-                           end;
-                        else
-                           if Trace_Parse > Outline then
-                              declare
-                                 Parser_State : Parser_Lists.Parser_State 
renames Current_Parser.State_Ref;
-                              begin
-                                 Trace.Put_Line
-                                   (Integer'Image (Current_Parser.Label) & ": 
" &
-                                      Trimmed_Image 
(Parser_State.Stack.Peek.State) & ": " &
-                                      Parser_State.Tree.Image
-                                        (Parser_State.Current_Token, 
Trace.Descriptor.all) & " : " &
-                                      "spawn" & Integer'Image 
(Shared_Parser.Parsers.Last_Label + 1) & ", (" &
-                                      Trimmed_Image (1 + Integer 
(Shared_Parser.Parsers.Count)) & " active)");
-                              end;
-                           end if;
-
-                           Shared_Parser.Parsers.Prepend_Copy (Current_Parser);
-                           Do_Action (Conflict.Item, 
Shared_Parser.Parsers.First, Shared_Parser);
-
-                           declare
-                              Temp : Parser_Lists.Cursor := 
Shared_Parser.Parsers.First;
-                           begin
-                              Check_Error (Temp);
-                           end;
-                        end if;
-
-                        Conflict := Conflict.Next;
-                     end loop;
-                  end;
-
-                  Do_Action (Action.Item, Current_Parser, Shared_Parser);
-                  Check_Error (Current_Parser);
-
-               else
-                  --  Current parser is waiting for others to catch up
-                  Current_Parser.Next;
-               end if;
-            end loop;
-         end;
-      end loop Main_Loop;
-
-      --  We don't raise Syntax_Error for lexer errors, since they are all
-      --  recovered, either by inserting a quote, or by ignoring the
-      --  character.
-   end Parse;
-
-   overriding procedure Execute_Actions
-     (Parser          : in out LR.Parser_No_Recover.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null)
-   is
-      pragma Unreferenced (Image_Augmented);
-      use all type Syntax_Trees.User_Data_Access;
-
-      procedure Process_Node
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index)
-      is
-         use all type Syntax_Trees.Node_Label;
-      begin
-         if Tree.Label (Node) /= Nonterm then
-            return;
-         end if;
-
-         declare
-            use all type Syntax_Trees.Semantic_Action;
-            Tree_Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-         begin
-            Parser.User_Data.Reduce (Tree, Node, Tree_Children);
-
-            if Tree.Action (Node) /= null then
-               begin
-                  Tree.Action (Node) (Parser.User_Data.all, Tree, Node, 
Tree_Children);
-               exception
-               when E : others =>
-                  declare
-                     Line   : Line_Number_Type  := Line_Number_Type'First;
-                     Column : Ada.Text_IO.Count := Ada.Text_IO.Count'First;
-                  begin
-                     if Tree.First_Shared_Terminal (Node) = 
Invalid_Token_Index then
-                        declare
-                           Byte_Region : Buffer_Region renames 
Tree.Byte_Region (Node);
-                        begin
-                           if Byte_Region /= Null_Buffer_Region then
-                              Column := Ada.Text_IO.Count (Byte_Region.First);
-                           end if;
-                        end;
-                     else
-                        declare
-                           Token : Base_Token renames Parser.Terminals 
(Tree.First_Shared_Terminal (Node));
-                        begin
-                           Line := Token.Line;
-                           Column := Token.Column;
-                        end;
-                     end if;
-                     raise WisiToken.Parse_Error with Error_Message
-                       (Parser.Lexer.File_Name, Line, Column,
-                        "action raised exception " & 
Ada.Exceptions.Exception_Name (E) & ": " &
-                          Ada.Exceptions.Exception_Message (E));
-                  end;
-               end;
-            end if;
-         end;
-      end Process_Node;
-
-   begin
-      if Parser.User_Data /= null then
-         if Parser.Parsers.Count > 1 then
-            raise Syntax_Error with "ambiguous parse; can't execute actions";
-         end if;
-
-         declare
-            Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_State_Ref.Element.all;
-         begin
-            Parser_State.Tree.Set_Parents;
-            Parser.User_Data.Initialize_Actions (Parser_State.Tree);
-            Parser_State.Tree.Process_Tree (Process_Node'Access);
-         end;
-      end if;
-   end Execute_Actions;
-
-   overriding function Tree (Parser : in LR.Parser_No_Recover.Parser) return 
Syntax_Trees.Tree
-   is begin
-      if Parser.Parsers.Count > 1 then
-         raise WisiToken.Parse_Error with "ambigous parse";
-      else
-         return Parser.Parsers.First_State_Ref.Tree;
-      end if;
-   end Tree;
-
-   overriding
-   function Tree_Var_Ref
-     (Parser : aliased in out LR.Parser_No_Recover.Parser)
-     return Syntax_Trees.Tree_Variable_Reference
-   is begin
-      if Parser.Parsers.Count > 1 then
-         raise WisiToken.Parse_Error with "ambigous parse";
-      else
-         return (Element => Parser.Parsers.First_State_Ref.Tree'Access);
-      end if;
-   end Tree_Var_Ref;
-
-   overriding function Any_Errors (Parser : in LR.Parser_No_Recover.Parser) 
return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-      Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_Constant_State_Ref;
-   begin
-      pragma Assert (Parser_State.Tree.Flushed);
-      return Parser.Parsers.Count > 1 or Parser_State.Errors.Length > 0 or 
Parser.Lexer.Errors.Length > 0;
-   end Any_Errors;
-
-   overriding procedure Put_Errors (Parser : in LR.Parser_No_Recover.Parser)
-   is
-      use Ada.Text_IO;
-
-      Parser_State : Parser_Lists.Parser_State renames 
Parser.Parsers.First_Constant_State_Ref;
-      Descriptor   : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-   begin
-      for Item of Parser.Lexer.Errors loop
-         Put_Line
-           (Current_Error,
-            Parser.Lexer.File_Name & ":0:0: lexer unrecognized character at" & 
Buffer_Pos'Image (Item.Char_Pos));
-      end loop;
-
-      for Item of Parser_State.Errors loop
-         case Item.Label is
-         when Action =>
-            declare
-               Token : Base_Token renames Parser.Terminals 
(Parser_State.Tree.First_Shared_Terminal (Item.Error_Token));
-            begin
-               Put_Line
-                 (Current_Error,
-                  Error_Message
-                    (Parser.Lexer.File_Name, Token.Line, Token.Column,
-                     "syntax error: expecting " & Image (Item.Expecting, 
Descriptor) &
-                       ", found '" & Parser.Lexer.Buffer_Text 
(Token.Byte_Region) & "'"));
-            end;
-
-         when Check =>
-            null;
-
-         when Message =>
-            Put_Line (Current_Error, -Item.Msg);
-         end case;
-
-      end loop;
-   end Put_Errors;
-
-end WisiToken.Parse.LR.Parser_No_Recover;
diff --git a/packages/wisi/wisitoken-parse-lr-parser_no_recover.ads 
b/packages/wisi/wisitoken-parse-lr-parser_no_recover.ads
deleted file mode 100644
index 5e630d2..0000000
--- a/packages/wisi/wisitoken-parse-lr-parser_no_recover.ads
+++ /dev/null
@@ -1,92 +0,0 @@
---  Abstract :
---
---  A generalized LR parser, with no error recovery, no semantic checks.
---
---  This allows wisi-generate (which uses the generated wisi_grammar)
---  to not depend on wisitoken-lr-mckenzie_recover, so editing that
---  does not cause everything to be regenerated/compiled.
---
---  Copyright (C) 2002, 2003, 2009, 2010, 2013 - 2015, 2017 - 2020 Free 
Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Lexer;
-with WisiToken.Parse.LR.Parser_Lists;
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.LR.Parser_No_Recover is
-
-   Default_Max_Parallel : constant := 15;
-
-   type Parser is new WisiToken.Parse.Base_Parser with record
-      Table       : Parse_Table_Ptr;
-      Shared_Tree : aliased Syntax_Trees.Base_Tree;
-      --  Each parser has its own branched syntax tree, all branched from
-      --  this tree.
-      --
-      --  See WisiToken.LR.Parser_Lists Parser_State for more discussion of
-      --  Shared_Tree.
-
-      Parsers : aliased Parser_Lists.List;
-
-      Max_Parallel         : SAL.Base_Peek_Type;
-      First_Parser_Label   : Integer;
-      Terminate_Same_State : Boolean;
-   end record;
-
-   overriding procedure Finalize (Object : in out LR.Parser_No_Recover.Parser);
-   --  Deep free Object.Table.
-
-   procedure New_Parser
-     (Parser               :    out          LR.Parser_No_Recover.Parser;
-      Trace                : not null access WisiToken.Trace'Class;
-      Lexer                : in              WisiToken.Lexer.Handle;
-      Table                : in              Parse_Table_Ptr;
-      User_Data            : in              Syntax_Trees.User_Data_Access;
-      Max_Parallel         : in              SAL.Base_Peek_Type := 
Default_Max_Parallel;
-      First_Parser_Label   : in              Integer            := 1;
-      Terminate_Same_State : in              Boolean            := True);
-
-   overriding procedure Parse (Shared_Parser : aliased in out 
LR.Parser_No_Recover.Parser);
-   --  Attempt a parse. Calls Parser.Lexer.Reset, runs lexer to end of
-   --  input setting Shared_Parser.Terminals, then parses tokens.
-   --
-   --  If a parse error is encountered, raises Syntax_Error.
-   --  Parser.Lexer_Errors and Parsers(*).Errors contain information
-   --  about the errors.
-   --
-   --  For other errors, raises Parse_Error with an appropriate error
-   --  message.
-
-   overriding function Tree (Parser : in LR.Parser_No_Recover.Parser) return 
Syntax_Trees.Tree;
-
-   overriding
-   function Tree_Var_Ref
-     (Parser : aliased in out LR.Parser_No_Recover.Parser)
-     return Syntax_Trees.Tree_Variable_Reference;
-
-   overriding function Any_Errors (Parser : in LR.Parser_No_Recover.Parser) 
return Boolean;
-
-   overriding procedure Put_Errors (Parser : in LR.Parser_No_Recover.Parser);
-   --  Put user-friendly error messages from the parse to
-   --  Ada.Text_IO.Current_Error.
-
-   overriding procedure Execute_Actions
-     (Parser          : in out LR.Parser_No_Recover.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null);
-   --  Execute the grammar actions in Parser.
-
-end WisiToken.Parse.LR.Parser_No_Recover;
diff --git a/packages/wisi/wisitoken-parse-lr.adb 
b/packages/wisi/wisitoken-parse-lr.adb
deleted file mode 100644
index 27fe85d..0000000
--- a/packages/wisi/wisitoken-parse-lr.adb
+++ /dev/null
@@ -1,767 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2013-2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (GPL);
-
-with Ada.Exceptions;
-with Ada.Strings.Maps;
-with Ada.Strings.Fixed;
-with Ada.Text_IO;
-with GNATCOLL.Mmap;
-package body WisiToken.Parse.LR is
-
-   ----------
-   --  Public subprograms, declaration order
-
-   function Image (Item : in Parse_Action_Rec; Descriptor : in 
WisiToken.Descriptor) return String
-   is
-      use Ada.Containers;
-   begin
-      case Item.Verb is
-      when Shift =>
-         return "(Shift," & State_Index'Image (Item.State) & ")";
-
-      when Reduce =>
-         return "(Reduce," & Count_Type'Image (Item.Token_Count) & ", " &
-           Image (Item.Production.LHS, Descriptor) & "," & Trimmed_Image 
(Item.Production.RHS) & ")";
-      when Accept_It =>
-         return "(Accept It)";
-      when Error =>
-         return "(Error)";
-      end case;
-   end Image;
-
-   procedure Put (Trace : in out WisiToken.Trace'Class; Item : in 
Parse_Action_Rec)
-   is
-      use Ada.Containers;
-   begin
-      case Item.Verb is
-      when Shift =>
-         Trace.Put ("shift and goto state" & State_Index'Image (Item.State), 
Prefix => False);
-
-      when Reduce =>
-         Trace.Put
-           ("reduce" & Count_Type'Image (Item.Token_Count) & " tokens to " &
-              Image (Item.Production.LHS, Trace.Descriptor.all),
-            Prefix => False);
-      when Accept_It =>
-         Trace.Put ("accept it", Prefix => False);
-      when Error =>
-         Trace.Put ("ERROR", Prefix => False);
-      end case;
-   end Put;
-
-   function Equal (Left, Right : in Parse_Action_Rec) return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Left.Verb = Right.Verb then
-         case Left.Verb is
-         when Shift =>
-            return Left.State = Right.State;
-
-         when Reduce | Accept_It =>
-            return Left.Production.LHS = Right.Production.LHS and 
Left.Token_Count = Right.Token_Count;
-
-         when Error =>
-            return True;
-         end case;
-      else
-         return False;
-      end if;
-   end Equal;
-
-   function Is_In (Item : in Parse_Action_Rec; List : in 
Parse_Action_Node_Ptr) return Boolean
-   is
-      Node : Parse_Action_Node_Ptr := List;
-   begin
-      loop
-         exit when Node = null;
-         if Equal (Item, Node.Item) then
-            return True;
-         end if;
-         Node := Node.Next;
-      end loop;
-      return False;
-   end Is_In;
-
-   function Compare (Left, Right : in Token_ID) return SAL.Compare_Result
-   is begin
-      if Left < Right then
-         return SAL.Less;
-      elsif Left = Right then
-         return SAL.Equal;
-      else
-         return SAL.Greater;
-      end if;
-   end Compare;
-
-   procedure Add
-     (List   : in out Action_Arrays.Vector;
-      Symbol : in     Token_ID;
-      Action : in     Parse_Action_Rec)
-   is begin
-      declare
-         Node : constant Action_Arrays.Find_Reference_Type := List.Find 
(Symbol);
-      begin
-         if Node.Element /= null then
-            declare
-               I : Parse_Action_Node_Ptr := Node.Element.Actions;
-            begin
-               loop
-                  exit when I.Next = null;
-                  I := I.Next;
-               end loop;
-               I.Next := new Parse_Action_Node'(Action, null);
-               return;
-            end;
-         end if;
-      end;
-      List.Insert ((Symbol, new Parse_Action_Node'(Action, null)));
-   end Add;
-
-   function To_Vector (Item : in Kernel_Info_Array) return 
Kernel_Info_Arrays.Vector
-   is begin
-      return Result : Kernel_Info_Arrays.Vector do
-         Result.Set_First_Last (Item'First, Item'Last);
-         for I in Item'Range loop
-            Result (I) := Item (I);
-         end loop;
-      end return;
-   end To_Vector;
-
-   function Strict_Image (Item : in Kernel_Info) return String
-   is begin
-      return "(" & Image (Item.Production) & ", " &
-        Item.Before_Dot'Image & ", " &
-        Item.Length_After_Dot'Image & ", " &
-        Image (Item.Reduce_Production) & ", " &
-        Item.Reduce_Count'Image & ")";
-   end Strict_Image;
-
-   function Strict_Image (Item : in Minimal_Action) return String
-   is begin
-      case Item.Verb is
-      when Shift =>
-         return "(Shift, " & Image (Item.Production) & ", " &
-           Token_ID'Image (Item.ID) & "," & State_Index'Image (Item.State) & 
")";
-
-      when Reduce =>
-         return "(Reduce, " & Image (Item.Production) & ", " &
-           Ada.Containers.Count_Type'Image (Item.Token_Count) & ")";
-      end case;
-   end Strict_Image;
-
-   function Image (Item : in Minimal_Action; Descriptor : in 
WisiToken.Descriptor) return String
-   is begin
-      case Item.Verb is
-      when Shift =>
-         return "Shift " & Image (Item.ID, Descriptor);
-      when Reduce =>
-         return "Reduce to " & Image (Item.Production.LHS, Descriptor);
-      end case;
-   end Image;
-
-   function To_Vector (Item : in Minimal_Action_Array) return 
Minimal_Action_Arrays.Vector
-   is begin
-      return Result : Minimal_Action_Arrays.Vector do
-         Result.Set_First_Last (Item'First, Item'Last);
-         for I in Item'Range loop
-            Result.Replace_Element (I, Item (I));
-         end loop;
-      end return;
-   end To_Vector;
-
-   procedure Add_Action
-     (State       : in out LR.Parse_State;
-      Symbol      : in     Token_ID;
-      Production  : in     Production_ID;
-      State_Index : in     WisiToken.State_Index)
-   is begin
-      Add (State.Action_List, Symbol, (Shift, Production, State_Index));
-   end Add_Action;
-
-   procedure Add_Action
-     (State           : in out LR.Parse_State;
-      Symbol          : in     Token_ID;
-      Verb            : in     LR.Parse_Action_Verbs;
-      Production      : in     Production_ID;
-      RHS_Token_Count : in     Ada.Containers.Count_Type;
-      Semantic_Action : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check  : in     Semantic_Checks.Semantic_Check)
-   is
-      Action : constant Parse_Action_Rec :=
-        (case Verb is
-         when Reduce    => (Reduce, Production, Semantic_Action, 
Semantic_Check, RHS_Token_Count),
-         when Accept_It => (Accept_It, Production, Semantic_Action, 
Semantic_Check, RHS_Token_Count),
-         when others    => raise SAL.Programmer_Error);
-   begin
-      Add (State.Action_List, Symbol, Action);
-   end Add_Action;
-
-   procedure Add_Action
-     (State           : in out Parse_State;
-      Symbols         : in     Token_ID_Array;
-      Production      : in     Production_ID;
-      RHS_Token_Count : in     Ada.Containers.Count_Type;
-      Semantic_Action : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check  : in     WisiToken.Semantic_Checks.Semantic_Check)
-   is begin
-      --  We assume WisiToken.BNF.Output_Ada_Common.Duplicate_Reduce is True
-      --  for this state; no conflicts, all the same action, Recursive.
-      for Symbol of Symbols loop
-         Add_Action
-           (State, Symbol, Reduce, Production, RHS_Token_Count,
-            Semantic_Action, Semantic_Check);
-      end loop;
-   end Add_Action;
-
-   procedure Add_Conflict
-     (State             : in out LR.Parse_State;
-      Symbol            : in     Token_ID;
-      Reduce_Production : in     Production_ID;
-      RHS_Token_Count   : in     Ada.Containers.Count_Type;
-      Semantic_Action   : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check    : in     Semantic_Checks.Semantic_Check)
-   is
-      Conflict : constant Parse_Action_Rec :=
-        (Reduce, Reduce_Production, Semantic_Action, Semantic_Check, 
RHS_Token_Count);
-
-      Ref : constant Action_Arrays.Find_Reference_Constant_Type := 
State.Action_List.Find_Constant (Symbol);
-
-      Node : Parse_Action_Node_Ptr := Ref.Actions;
-   begin
-      loop
-         exit when Node.Next = null;
-         Node := Node.Next;
-      end loop;
-      Node.Next := new Parse_Action_Node'(Conflict, null);
-   end Add_Conflict;
-
-   procedure Add_Goto
-     (State      : in out LR.Parse_State;
-      Symbol     : in     Token_ID;
-      To_State   : in     State_Index)
-   is begin
-      State.Goto_List.Insert ((Symbol, To_State));
-   end Add_Goto;
-
-   function Goto_For
-     (Table : in Parse_Table;
-      State : in State_Index;
-      ID    : in Token_ID)
-     return Unknown_State_Index
-   is
-      Ref : constant Goto_Arrays.Find_Reference_Constant_Type := Table.States 
(State).Goto_List.Find_Constant (ID);
-   begin
-      if Ref.Element = null then
-         --  We can only get here during error recovery.
-         return Unknown_State;
-      else
-         return Ref.State;
-      end if;
-   end Goto_For;
-
-   function Action_For
-     (Table : in Parse_Table;
-      State : in State_Index;
-      ID    : in Token_ID)
-     return Parse_Action_Node_Ptr
-   is
-      Ref : constant Action_Arrays.Find_Reference_Constant_Type := 
Table.States (State).Action_List.Find_Constant (ID);
-   begin
-      if Ref.Element = null then
-         return Table.Error_Action;
-      end if;
-
-      return Ref.Actions;
-   end Action_For;
-
-   function Expecting (Table : in Parse_Table; State : in State_Index) return 
Token_ID_Set
-   is
-      Result : Token_ID_Set := (Table.First_Terminal .. Table.Last_Terminal => 
False);
-   begin
-      for Action of Table.States (State).Action_List loop
-         Result (Action.Symbol) := True;
-      end loop;
-      return Result;
-   end Expecting;
-
-   procedure Free_Table (Table : in out Parse_Table_Ptr)
-   is
-      procedure Free is new Ada.Unchecked_Deallocation (Parse_Table, 
Parse_Table_Ptr);
-      Parse_Action      : Parse_Action_Node_Ptr;
-      Temp_Parse_Action : Parse_Action_Node_Ptr;
-   begin
-      if Table = null then
-         return;
-      end if;
-
-      for State of Table.States loop
-         for Action of State.Action_List loop
-            Parse_Action := Action.Actions;
-            loop
-               exit when Parse_Action = null;
-               Temp_Parse_Action := Parse_Action;
-               Parse_Action := Parse_Action.Next;
-               Free (Temp_Parse_Action);
-            end loop;
-         end loop;
-      end loop;
-
-      Free (Table);
-   end Free_Table;
-
-   function Get_Text_Rep
-     (File_Name      : in String;
-      McKenzie_Param : in McKenzie_Param_Type;
-      Actions        : in Semantic_Action_Array_Arrays.Vector)
-     return Parse_Table_Ptr
-   is
-      use Ada.Text_IO;
-
-      File            : GNATCOLL.Mmap.Mapped_File;
-      Region          : GNATCOLL.Mmap.Mapped_Region;
-      Buffer          : GNATCOLL.Mmap.Str_Access;
-      Buffer_Abs_Last : Integer; --  Buffer'Last, except Buffer has no bounds
-      Buffer_Last     : Integer := 0; -- Last char read from Buffer
-
-      Delimiters : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set (" ;" & ASCII.LF);
-
-      function Check_Semicolon return Boolean
-      is begin
-         if Buffer (Buffer_Last) = ';' then
-            --  There is a space, newline, or newline and space after ';'. 
Leave
-            --  Buffer_Last on newline for Check_New_Line.
-            Buffer_Last := Buffer_Last + 1;
-            return True;
-         else
-            return False;
-         end if;
-      end Check_Semicolon;
-
-      procedure Check_Semicolon
-      is begin
-         if Buffer (Buffer_Last) = ';' then
-            --  There is a space, newline, or newline and space after ';'. 
Leave
-            --  Buffer_Last on newline for Check_New_Line.
-            Buffer_Last := Buffer_Last + 1;
-         else
-            raise SAL.Programmer_Error with Error_Message
-              (File_Name, 1, Ada.Text_IO.Count (Buffer_Last),
-               "expecting semicolon, found '" & Buffer (Buffer_Last) & "'");
-         end if;
-      end Check_Semicolon;
-
-      function Check_EOI return Boolean
-      is begin
-         return Buffer_Last >= Buffer_Abs_Last;
-      end Check_EOI;
-
-      procedure Check_New_Line
-      is
-         use Ada.Strings.Maps;
-      begin
-         if Buffer (Buffer_Last) = ASCII.LF then
-            --  There is a space or semicolon after some newlines.
-            if Is_In (Buffer (Buffer_Last + 1), Delimiters) then
-               Buffer_Last := Buffer_Last + 1;
-            end if;
-         else
-            raise SAL.Programmer_Error with Error_Message
-              (File_Name, 1, Ada.Text_IO.Count (Buffer_Last),
-               "expecting new_line, found '" & Buffer (Buffer_Last) & "'");
-         end if;
-      end Check_New_Line;
-
-      type Buffer_Region is record
-         First : Integer;
-         Last  : Integer;
-      end record;
-
-      function Next_Value return Buffer_Region;
-      pragma Inline (Next_Value);
-
-      function Next_Value return Buffer_Region
-      is
-         use Ada.Strings.Fixed;
-         First : constant Integer := Buffer_Last + 1;
-      begin
-         Buffer_Last := Index (Buffer.all, Delimiters, First);
-         return (First, Buffer_Last - 1);
-      end Next_Value;
-
-      procedure Raise_Gen_Next_Value_Constraint_Error (Name : String; Region : 
Buffer_Region);
-      pragma No_Return (Raise_Gen_Next_Value_Constraint_Error);
-
-      procedure Raise_Gen_Next_Value_Constraint_Error (Name : String; Region : 
Buffer_Region)
-      is begin
-         --  Factored out from Gen_Next_Value to make Inline efficient.
-         raise SAL.Programmer_Error with Error_Message
-           (File_Name, 1, Ada.Text_IO.Count (Region.First),
-            "expecting " & Name & ", found '" & Buffer (Region.First .. 
Region.Last) & "'");
-      end Raise_Gen_Next_Value_Constraint_Error;
-
-      generic
-         type Value_Type is (<>);
-         Name : in String;
-      function Gen_Next_Value return Value_Type;
-      pragma Inline (Gen_Next_Value);
-
-      function Gen_Next_Value return Value_Type
-      is
-         Region : constant Buffer_Region := Next_Value;
-      begin
-         return Value_Type'Value (Buffer (Region.First .. Region.Last));
-      exception
-      when Constraint_Error =>
-         Raise_Gen_Next_Value_Constraint_Error (Name, Region);
-      end Gen_Next_Value;
-
-      function Next_State_Index is new Gen_Next_Value (State_Index, 
"State_Index");
-      function Next_Token_ID is new Gen_Next_Value (Token_ID, "Token_ID");
-      function Next_Integer is new Gen_Next_Value (Integer, "Integer");
-      function Next_Parse_Action_Verbs is new Gen_Next_Value 
(Parse_Action_Verbs, "Parse_Action_Verbs");
-      function Next_Boolean is new Gen_Next_Value (Boolean, "Boolean");
-      function Next_Count_Type is new Gen_Next_Value 
(Ada.Containers.Count_Type, "Count_Type");
-   begin
-      File            := GNATCOLL.Mmap.Open_Read (File_Name);
-      Region          := GNATCOLL.Mmap.Read (File);
-      Buffer          := GNATCOLL.Mmap.Data (Region);
-      Buffer_Abs_Last := GNATCOLL.Mmap.Last (Region);
-
-      declare
-         use Ada.Containers;
-
-         --  We don't read the discriminants in the aggregate, because
-         --  aggregate evaluation order is not guaranteed.
-         State_First       : constant State_Index := Next_State_Index;
-         State_Last        : constant State_Index := Next_State_Index;
-         First_Terminal    : constant Token_ID    := Next_Token_ID;
-         Last_Terminal     : constant Token_ID    := Next_Token_ID;
-         First_Nonterminal : constant Token_ID    := Next_Token_ID;
-         Last_Nonterminal  : constant Token_ID    := Next_Token_ID;
-
-         Table : constant Parse_Table_Ptr := new Parse_Table
-           (State_First, State_Last, First_Terminal, Last_Terminal, 
First_Nonterminal, Last_Nonterminal);
-      begin
-         Check_New_Line;
-
-         Table.McKenzie_Param := McKenzie_Param;
-
-         for State of Table.States loop
-            declare
-               Actions_Done : Boolean := False;
-            begin
-               State.Action_List.Set_Capacity (Next_Count_Type);
-
-               loop
-                  declare
-                     Node_I      : Action_Node;
-                     Node_J      : Parse_Action_Node_Ptr := new 
Parse_Action_Node;
-                     Action_Done : Boolean               := False;
-                     Verb        : Parse_Action_Verbs;
-                  begin
-                     Node_I.Actions := Node_J;
-                     loop
-                        Verb := Next_Parse_Action_Verbs;
-                        Node_J.Item :=
-                          (case Verb is
-                           when Shift     => (Verb => Shift, others => <>),
-                           when Reduce    => (Verb => Reduce, others => <>),
-                           when Accept_It => (Verb => Accept_It, others => <>),
-                           when Error     => (Verb => Error, others => <>));
-
-                        Node_J.Item.Production.LHS := Next_Token_ID;
-                        Node_J.Item.Production.RHS := Next_Integer;
-
-                        case Verb is
-                        when Shift =>
-                           Node_J.Item.State := Next_State_Index;
-
-                        when Reduce | Accept_It =>
-                           if Next_Boolean then
-                              Node_J.Item.Action := Actions
-                                
(Node_J.Item.Production.LHS)(Node_J.Item.Production.RHS).Action;
-                           else
-                              Node_J.Item.Action := null;
-                           end if;
-                           if Next_Boolean then
-                              Node_J.Item.Check := Actions
-                                
(Node_J.Item.Production.LHS)(Node_J.Item.Production.RHS).Check;
-                           else
-                              Node_J.Item.Check := null;
-                           end if;
-                           Node_J.Item.Token_Count := Next_Count_Type;
-
-                        when Error =>
-                           raise SAL.Programmer_Error;
-                        end case;
-
-                        if Check_Semicolon then
-                           Action_Done := True;
-
-                           Node_I.Symbol := Next_Token_ID;
-
-                           if Check_Semicolon then
-                              Actions_Done := True;
-                           end if;
-                        end if;
-
-                        exit when Action_Done;
-
-                        Node_J.Next := new Parse_Action_Node;
-                        Node_J      := Node_J.Next;
-                     end loop;
-
-                     Check_New_Line;
-                     State.Action_List.Insert (Node_I);
-                  end;
-
-                  exit when Actions_Done;
-               end loop;
-            end;
-
-            if Check_Semicolon then
-               --  No Gotos
-               null;
-            else
-               State.Goto_List.Set_Capacity (Next_Count_Type);
-               declare
-                  Node : Goto_Node;
-               begin
-                  loop
-                     Node.Symbol := Next_Token_ID;
-                     Node.State  := Next_State_Index;
-                     State.Goto_List.Insert (Node);
-                     exit when Check_Semicolon;
-                  end loop;
-               end;
-            end if;
-            Check_New_Line;
-
-            declare
-               First : constant Count_Type := Next_Count_Type;
-               Last  : constant Integer    := Next_Integer;
-            begin
-               if Last = -1 then
-                  --  State.Kernel not set for state 0
-                  null;
-               else
-                  State.Kernel.Set_First_Last (First, Count_Type (Last));
-
-                  for I in State.Kernel.First_Index .. State.Kernel.Last_Index 
loop
-                     State.Kernel (I).Production.LHS        := Next_Token_ID;
-                     State.Kernel (I).Production.RHS        := Next_Integer;
-                     State.Kernel (I).Before_Dot            := Next_Token_ID;
-                     State.Kernel (I).Length_After_Dot      := Next_Count_Type;
-                     State.Kernel (I).Reduce_Production.LHS := Next_Token_ID;
-                     State.Kernel (I).Reduce_Production.RHS := Next_Integer;
-                     State.Kernel (I).Reduce_Count          := Next_Count_Type;
-                  end loop;
-               end if;
-            end;
-            Check_New_Line;
-
-            if Check_Semicolon then
-               --  No minimal action
-               null;
-            else
-               declare
-                  First : constant Count_Type := Next_Count_Type;
-                  Last  : constant Count_Type := Next_Count_Type;
-               begin
-                  State.Minimal_Complete_Actions.Set_First_Last (First, Last);
-               end;
-               for I in State.Minimal_Complete_Actions.First_Index .. 
State.Minimal_Complete_Actions.Last_Index loop
-                  declare
-                     Verb         : constant Minimal_Verbs := 
Next_Parse_Action_Verbs;
-                     LHS          : Token_ID;
-                     RHS          : Integer;
-                     ID           : Token_ID;
-                     Action_State : State_Index;
-                     Count        : Ada.Containers.Count_Type;
-                  begin
-                     LHS := Next_Token_ID;
-                     RHS := Next_Integer;
-                     case Verb is
-                     when Shift =>
-                        ID           := Next_Token_ID;
-                        Action_State := Next_State_Index;
-                        State.Minimal_Complete_Actions.Replace_Element (I, 
(Shift, (LHS, RHS), ID, Action_State));
-                     when Reduce =>
-                        Count := Next_Count_Type;
-                        State.Minimal_Complete_Actions.Replace_Element (I, 
(Reduce, (LHS, RHS), Count));
-                     end case;
-                  end;
-               end loop;
-               Check_Semicolon;
-            end if;
-            Check_New_Line;
-
-            exit when Check_EOI;
-         end loop;
-
-         Table.Error_Action := new Parse_Action_Node'((Verb => Error, others 
=> <>), null);
-
-         return Table;
-      end;
-   exception
-   when Name_Error =>
-      raise User_Error with "parser table text file '" & File_Name & "' not 
found.";
-
-   when SAL.Programmer_Error =>
-      raise;
-
-   when E : others =>
-      raise SAL.Programmer_Error with Error_Message
-        (File_Name, 1, Ada.Text_IO.Count (Buffer_Last),
-         Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E));
-   end Get_Text_Rep;
-
-   function Compare (Left, Right : in Insert_Delete_Op) return 
SAL.Compare_Result
-   is
-      Left_Token_Index : constant WisiToken.Token_Index :=
-        (case Insert_Delete_Op_Label'(Left.Op) is
-         when Insert => Left.Ins_Token_Index,
-         when Delete => Left.Del_Token_Index);
-      Right_Token_Index : constant WisiToken.Token_Index :=
-        (case Insert_Delete_Op_Label'(Right.Op) is
-         when Insert => Right.Ins_Token_Index,
-         when Delete => Right.Del_Token_Index);
-   begin
-      if Left_Token_Index < Right_Token_Index then
-         return SAL.Less;
-      elsif Left_Token_Index = Right_Token_Index then
-         return SAL.Equal;
-      else
-         return SAL.Greater;
-      end if;
-   end Compare;
-
-   function Equal (Left : in Config_Op; Right : in Insert_Op) return Boolean
-   is begin
-      return Left.Op = Insert and then
-        Left.Ins_ID = Right.Ins_ID and then
-        Left.Ins_Token_Index = Right.Ins_Token_Index;
-   end Equal;
-
-   function None (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-   begin
-      for I in First_Index (Ops) .. Last_Index (Ops) loop
-         if Constant_Ref (Ops, I).Op = Op then
-            return False;
-         end if;
-      end loop;
-      return True;
-   end None;
-
-   function None_Since_FF (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-   begin
-      for I in reverse First_Index (Ops) .. Last_Index (Ops) loop
-         declare
-            O : Config_Op renames Constant_Ref (Ops, I);
-         begin
-            exit when O.Op = Fast_Forward;
-            if O.Op = Op then
-               return False;
-            end if;
-         end;
-      end loop;
-      return True;
-   end None_Since_FF;
-
-   function Only_Since_FF (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Length (Ops) = 0 or else Constant_Ref (Ops, Last_Index (Ops)).Op /= 
Op then
-         return False;
-      else
-         for I in reverse First_Index (Ops) .. Last_Index (Ops) loop
-            declare
-               O : Config_Op renames Constant_Ref (Ops, I);
-            begin
-               exit when O.Op = Fast_Forward;
-               if O.Op /= Op then
-                  return False;
-               end if;
-            end;
-         end loop;
-         return True;
-      end if;
-   end Only_Since_FF;
-
-   function Any (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean
-   is
-      use Config_Op_Arrays, Config_Op_Array_Refs;
-   begin
-      for I in First_Index (Ops) .. Last_Index (Ops) loop
-         declare
-            O : Config_Op renames Constant_Ref (Ops, I);
-         begin
-            if O.Op = Op then
-               return True;
-            end if;
-         end;
-      end loop;
-      return False;
-   end Any;
-
-   function Valid_Tree_Indices (Stack : in Recover_Stacks.Stack; Depth : in 
SAL.Base_Peek_Type) return Boolean
-   is begin
-      for I in 1 .. Depth loop
-         if Stack.Peek (I).Tree_Index = Invalid_Node_Index then
-            return False;
-         end if;
-      end loop;
-      return True;
-   end Valid_Tree_Indices;
-
-   procedure Set_Key (Item : in out Configuration; Key : in Integer)
-   is begin
-      Item.Cost := Key;
-   end Set_Key;
-
-   procedure Accumulate (Data : in McKenzie_Data; Counts : in out 
Strategy_Counts)
-   is
-      procedure Proc (Config : in Configuration)
-      is begin
-         for I in Config.Strategy_Counts'Range loop
-            Counts (I) := Counts (I) + Config.Strategy_Counts (I);
-         end loop;
-      end Proc;
-   begin
-      Data.Results.Process (Proc'Unrestricted_Access);
-   end Accumulate;
-
-end WisiToken.Parse.LR;
diff --git a/packages/wisi/wisitoken-parse-lr.ads 
b/packages/wisi/wisitoken-parse-lr.ads
deleted file mode 100644
index da30920..0000000
--- a/packages/wisi/wisitoken-parse-lr.ads
+++ /dev/null
@@ -1,698 +0,0 @@
---  Abstract :
---
---  Root package of an implementation of an LR (Left-to-right scanning
---  Rightmost-deriving) parser. Includes operations for building the
---  parse table at runtime. See the child packages .Parse and
---  .Parse_No_Recover for running the parser.
---
---  References :
---
---  See wisitoken.ads
---
---  Copyright (C) 2002, 2003, 2009, 2010, 2013 - 2015, 2017 - 2020 Free 
Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Indefinite_Doubly_Linked_Lists;
-with Ada.Unchecked_Deallocation;
-with SAL.Gen_Array_Image;
-with SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux;
-with SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux;
-with SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
-with SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci;
-with SAL.Gen_Unbounded_Definite_Vectors_Sorted;
-with System.Multiprocessors;
-with WisiToken.Semantic_Checks;
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.LR is
-   use all type SAL.Base_Peek_Type;
-
-   type All_Parse_Action_Verbs is (Pause, Shift, Reduce, Accept_It, Error);
-   subtype Parse_Action_Verbs is All_Parse_Action_Verbs range Shift .. Error;
-   subtype Minimal_Verbs is All_Parse_Action_Verbs range Shift .. Reduce;
-   --  Pause is only used for error recovery, to allow parallel parsers
-   --  to re-sync on the same input terminal.
-
-   subtype Token_ID_Array_1_3 is Token_ID_Array (1 .. 3);
-   --  For Language_Matching_Begin_Tokens.
-
-   type Parse_Action_Rec (Verb : Parse_Action_Verbs := Shift) is
-   record
-      Production : Production_ID;
-      --  The production that produced this action. Used to find kernel
-      --  items during error recovery.
-
-      case Verb is
-      when Shift =>
-         State : State_Index := State_Index'Last;
-
-      when Reduce | Accept_It =>
-         --  Production.LHS is the result nonterm
-         Action      : WisiToken.Syntax_Trees.Semantic_Action   := null;
-         Check       : WisiToken.Semantic_Checks.Semantic_Check := null;
-         Token_Count : Ada.Containers.Count_Type                := 0;
-
-      when Error =>
-         null;
-      end case;
-   end record;
-   subtype Shift_Action_Rec is Parse_Action_Rec (Shift);
-   subtype Reduce_Action_Rec is Parse_Action_Rec (Reduce);
-
-   function Image (Item : in Parse_Action_Rec; Descriptor : in 
WisiToken.Descriptor) return String;
-   --  Ada aggregate syntax, leaving out Action, Check in reduce; for debug 
output
-
-   procedure Put (Trace : in out WisiToken.Trace'Class; Item : in 
Parse_Action_Rec);
-   --  Put a line for Item in parse trace format, with no prefix.
-
-   function Equal (Left, Right : in Parse_Action_Rec) return Boolean;
-   --  Ignore items not used by the canonical shift-reduce algorithm.
-
-   type Parse_Action_Node;
-   type Parse_Action_Node_Ptr is access Parse_Action_Node;
-
-   type Parse_Action_Node is record
-      Item : Parse_Action_Rec;
-      Next : Parse_Action_Node_Ptr; -- non-null only for conflicts
-   end record;
-   procedure Free is new Ada.Unchecked_Deallocation (Parse_Action_Node, 
Parse_Action_Node_Ptr);
-
-   function Is_In (Item : in Parse_Action_Rec; List : in 
Parse_Action_Node_Ptr) return Boolean;
-   --  True if Item is Equal to any element of List.
-
-   type Action_Node is record
-      Symbol  : Token_ID := Invalid_Token_ID; -- ignored if Action is Error
-      Actions : Parse_Action_Node_Ptr;
-   end record;
-
-   function To_Key (Item : in Action_Node) return Token_ID is (Item.Symbol);
-
-   function Compare (Left, Right : in Token_ID) return SAL.Compare_Result;
-
-   package Action_Arrays is new SAL.Gen_Unbounded_Definite_Vectors_Sorted
-     (Action_Node, Token_ID, To_Key, Compare);
-
-   procedure Add
-     (List   : in out Action_Arrays.Vector;
-      Symbol : in     Token_ID;
-      Action : in     Parse_Action_Rec);
-   --  Add action to List, sorted on ascending Symbol.
-
-   type Goto_Node is record
-      Symbol : Token_ID;
-      State  : State_Index;
-   end record;
-
-   function To_Key (Item : in Goto_Node) return Token_ID is (Item.Symbol);
-
-   package Goto_Arrays is  new SAL.Gen_Unbounded_Definite_Vectors_Sorted
-     (Goto_Node, Token_ID, To_Key, Compare);
-
-   type Kernel_Info is record
-      Production       : Production_ID;
-      Before_Dot       : Token_ID                  := Token_ID'First;
-      Length_After_Dot : Ada.Containers.Count_Type := 0;
-
-      Reduce_Production : Production_ID;
-      Reduce_Count      : Ada.Containers.Count_Type := 0;
-      --  The reduction that error recovery should do for this item if
-      --  Length_After_Dot = 0. Reduce_Production /= Production when item
-      --  after dot is nullable.
-      --
-      --  It is tempting to make Length_After_Dot a discriminant to
-      --  eliminate Reduce_* when they are not needed, but we don't have a
-      --  static value of Length_After_Dot when it is non-zero.
-   end record;
-
-   function Strict_Image (Item : in Kernel_Info) return String;
-
-   type Kernel_Info_Array is array (Ada.Containers.Count_Type range <>) of 
Kernel_Info;
-   package Kernel_Info_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Ada.Containers.Count_Type, Kernel_Info, (others => <>));
-
-   function To_Vector (Item : in Kernel_Info_Array) return 
Kernel_Info_Arrays.Vector;
-
-   function Image is new Kernel_Info_Arrays.Gen_Image (Strict_Image);
-
-   type Minimal_Action (Verb : Minimal_Verbs := Shift) is
-   record
-      Production  : Production_ID := Invalid_Production_ID;
-
-      case Verb is
-      when Shift =>
-         ID    : Token_ID    := Invalid_Token_ID;
-         State : State_Index := State_Index'Last;
-
-      when Reduce =>
-         Token_Count : Ada.Containers.Count_Type;
-      end case;
-   end record;
-
-   function Strict_Image (Item : in Minimal_Action) return String;
-   --  Strict Ada aggregate syntax, for generated code.
-
-   function Image (Item : in Minimal_Action; Descriptor : in 
WisiToken.Descriptor) return String;
-   --  For debugging
-
-   type Minimal_Action_Array is array (Ada.Containers.Count_Type range <>) of 
Minimal_Action;
-   package Minimal_Action_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Ada.Containers.Count_Type, Minimal_Action, (others => <>));
-
-   function To_Vector (Item : in Minimal_Action_Array) return 
Minimal_Action_Arrays.Vector;
-
-   function Image is new Minimal_Action_Arrays.Gen_Image_Aux (Descriptor, 
Trimmed_Image, Image);
-   function Strict_Image is new Minimal_Action_Arrays.Gen_Image (Strict_Image);
-
-   type Parse_State is record
-      Action_List : Action_Arrays.Vector;
-      Goto_List   : Goto_Arrays.Vector;
-
-      --  The following are used in error recovery.
-      Kernel                   : Kernel_Info_Arrays.Vector;
-      Minimal_Complete_Actions : Minimal_Action_Arrays.Vector;
-      --  Parse actions that will most quickly complete a production in this
-      --  state. Kernel is used to reduce the number of actions.
-   end record;
-
-   type Parse_State_Array is array (State_Index range <>) of Parse_State;
-
-   procedure Add_Action
-     (State       : in out Parse_State;
-      Symbol      : in     Token_ID;
-      Production  : in     Production_ID;
-      State_Index : in     WisiToken.State_Index);
-   --  Add a Shift action to tail of State action list.
-
-   procedure Add_Action
-     (State           : in out Parse_State;
-      Symbol          : in     Token_ID;
-      Verb            : in     Parse_Action_Verbs;
-      Production      : in     Production_ID;
-      RHS_Token_Count : in     Ada.Containers.Count_Type;
-      Semantic_Action : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check  : in     WisiToken.Semantic_Checks.Semantic_Check);
-   --  Add a Reduce or Accept_It action to tail of State action list.
-
-   procedure Add_Action
-     (State           : in out Parse_State;
-      Symbols         : in     Token_ID_Array;
-      Production      : in     Production_ID;
-      RHS_Token_Count : in     Ada.Containers.Count_Type;
-      Semantic_Action : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check  : in     WisiToken.Semantic_Checks.Semantic_Check);
-   --  Add duplicate Reduce actions, and final Error action, to tail of
-   --  State action list.
-
-   procedure Add_Conflict
-     (State             : in out Parse_State;
-      Symbol            : in     Token_ID;
-      Reduce_Production : in     Production_ID;
-      RHS_Token_Count   : in     Ada.Containers.Count_Type;
-      Semantic_Action   : in     WisiToken.Syntax_Trees.Semantic_Action;
-      Semantic_Check    : in     WisiToken.Semantic_Checks.Semantic_Check);
-   --  Add a Reduce conflict to State.
-
-   procedure Add_Goto
-     (State    : in out Parse_State;
-      Symbol   : in     Token_ID;
-      To_State : in     State_Index);
-   --  Add a goto item to State goto list; keep goto list sorted in ascending 
order on Symbol.
-
-   type McKenzie_Param_Type
-     (First_Terminal    : Token_ID;
-      Last_Terminal     : Token_ID;
-      First_Nonterminal : Token_ID;
-      Last_Nonterminal  : Token_ID)
-   is record
-      Insert      : Token_ID_Array_Natural (First_Terminal .. Last_Terminal);
-      Delete      : Token_ID_Array_Natural (First_Terminal .. Last_Terminal);
-      Push_Back   : Token_ID_Array_Natural (First_Terminal .. 
Last_Nonterminal);
-      Undo_Reduce : Token_ID_Array_Natural (First_Nonterminal .. 
Last_Nonterminal);
-      --  Cost of operations on config stack, input.
-
-      Minimal_Complete_Cost_Delta : Integer;
-      --  Reduction in cost due to using Minimal_Complete_Action.
-
-      Matching_Begin : Integer;
-      --  Cost of Matching_Begin strategy (applied once, independent of
-      --  token count).
-
-      Fast_Forward : Integer;
-      --  Cost of moving the edit point forward over input tokens.
-
-      Ignore_Check_Fail : Natural;
-      --  Cost of ignoring a semantic check failure. Should be at least the
-      --  cost of a typical fix for such a failure.
-
-      Task_Count : System.Multiprocessors.CPU_Range;
-      --  Number of parallel tasks during recovery. If 0, use
-      --  System.Multiprocessors.Number_Of_CPUs - 1.
-
-      Check_Limit       : Token_Index; -- max tokens to parse ahead when 
checking a configuration.
-      Check_Delta_Limit : Natural;     -- max configs checked, delta over 
successful parser.
-      Enqueue_Limit     : Natural;     -- max configs enqueued.
-   end record;
-
-   Default_McKenzie_Param : constant McKenzie_Param_Type :=
-     (First_Terminal              => Token_ID'Last,
-      Last_Terminal               => Token_ID'First,
-      First_Nonterminal           => Token_ID'Last,
-      Last_Nonterminal            => Token_ID'First,
-      Insert                      => (others => 0),
-      Delete                      => (others => 0),
-      Push_Back                   => (others => 0),
-      Undo_Reduce                 => (others => 0),
-      Minimal_Complete_Cost_Delta => -1,
-      Fast_Forward                => 0,
-      Matching_Begin              => 0,
-      Ignore_Check_Fail           => 0,
-      Task_Count                  => System.Multiprocessors.CPU_Range'Last,
-      Check_Limit                 => 4,
-      Check_Delta_Limit           => Natural'Last,
-      Enqueue_Limit               => Natural'Last);
-
-   type Parse_Table
-     (State_First       : State_Index;
-      State_Last        : State_Index;
-      First_Terminal    : Token_ID;
-      Last_Terminal     : Token_ID;
-      First_Nonterminal : Token_ID;
-      Last_Nonterminal  : Token_ID)
-     is tagged
-   record
-      States         : Parse_State_Array (State_First .. State_Last);
-      Error_Action   : Parse_Action_Node_Ptr;
-      McKenzie_Param : McKenzie_Param_Type (First_Terminal, Last_Terminal, 
First_Nonterminal, Last_Nonterminal);
-   end record;
-
-   function Goto_For
-     (Table : in Parse_Table;
-      State : in State_Index;
-      ID    : in Token_ID)
-     return Unknown_State_Index;
-   --  Return next state after reducing stack by nonterminal ID;
-   --  Unknown_State if none (only possible during error recovery).
-   --  Second form allows retrieving Production.
-
-   function Action_For
-     (Table : in Parse_Table;
-      State : in State_Index;
-      ID    : in Token_ID)
-     return Parse_Action_Node_Ptr
-   with Post => Action_For'Result /= null;
-   --  Return the action for State, terminal ID.
-
-   function Expecting (Table : in Parse_Table; State : in State_Index) return 
Token_ID_Set;
-
-   function McKenzie_Defaulted (Table : in Parse_Table) return Boolean is
-     --  We can't use Table.McKenzie_Param = Default_McKenzie_Param here,
-     --  because the discriminants are different.
-     (Table.McKenzie_Param.Check_Limit = Default_McKenzie_Param.Check_Limit and
-        Table.McKenzie_Param.Check_Delta_Limit = 
Default_McKenzie_Param.Check_Delta_Limit and
-        Table.McKenzie_Param.Enqueue_Limit = 
Default_McKenzie_Param.Enqueue_Limit);
-
-   type Parse_Table_Ptr is access Parse_Table;
-   procedure Free_Table (Table : in out Parse_Table_Ptr);
-
-   type Semantic_Action is record
-      Action : WisiToken.Syntax_Trees.Semantic_Action := null;
-      Check  : WisiToken.Semantic_Checks.Semantic_Check := null;
-   end record;
-
-   package Semantic_Action_Arrays is new SAL.Gen_Unbounded_Definite_vectors 
(Natural, Semantic_Action, (others => <>));
-   package Semantic_Action_Array_Arrays is new 
SAL.Gen_Unbounded_Definite_Vectors
-     (Token_ID, Semantic_Action_Arrays.Vector, 
Semantic_Action_Arrays.Empty_Vector);
-
-   function Get_Text_Rep
-     (File_Name      : in String;
-      McKenzie_Param : in McKenzie_Param_Type;
-      Actions        : in Semantic_Action_Array_Arrays.Vector)
-     return Parse_Table_Ptr;
-   --  Read machine-readable text format of states (as output by
-   --  WisiToken.Generate.LR.Put_Text_Rep) from file File_Name. Result
-   --  has actions, checks from Productions.
-
-   ----------
-   --  For McKenzie_Recover. Declared here because Parser_Lists needs
-   --  these, Mckenzie_Recover needs Parser_Lists.
-   --
-   --  We don't maintain a syntax tree during recover; it's too slow, and
-   --  not needed for any operations. The parser syntax tree is used for
-   --  Undo_Reduce, which is only done on nonterms reduced by the main
-   --  parser, not virtual nonterms produced by recover.
-
-   package Fast_Token_ID_Arrays is new SAL.Gen_Bounded_Definite_Vectors
-     (SAL.Peek_Type, Token_ID, Capacity => 20);
-
-   No_Insert_Delete : constant SAL.Base_Peek_Type := 0;
-
-   function Image
-     (Index      : in SAL.Peek_Type;
-      Tokens     : in Fast_Token_ID_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-     is (SAL.Peek_Type'Image (Index) & ":" & SAL.Peek_Type'Image 
(Fast_Token_ID_Arrays.Last_Index (Tokens)) & ":" &
-           Image (Fast_Token_ID_Arrays.Element (Tokens, Index), Descriptor));
-
-   type Config_Op_Label is (Fast_Forward, Undo_Reduce, Push_Back, Insert, 
Delete);
-   subtype Insert_Delete_Op_Label is Config_Op_Label range Insert .. Delete;
-   --  Fast_Forward is a placeholder to mark a fast_forward parse; that
-   --  resets what operations are allowed to be done on a config.
-   --
-   --  Undo_Reduce is the inverse of Reduce.
-   --
-   --  Push_Back pops the top stack item, and moves the input stream
-   --  pointer back to the first shared_terminal contained by that item.
-   --
-   --  Insert inserts a new token in the token input stream, before the
-   --  given point in Terminals.
-   --
-   --  Delete deletes one item from the token input stream, at the given
-   --  point.
-
-   type Config_Op (Op : Config_Op_Label := Fast_Forward) is record
-      --  We store enough information to perform the operation on the main
-      --  parser stack and input stream when the config is the result
-      --  of a successful recover.
-
-      case Op is
-      when Fast_Forward =>
-         FF_Token_Index : WisiToken.Token_Index;
-         --  Config.Current_Shared_Token after the operation is done; the last
-         --  token shifted.
-
-      when Undo_Reduce =>
-         Nonterm : Token_ID;
-         --  The nonterminal popped off the stack.
-
-         Token_Count : Ada.Containers.Count_Type;
-         --  The number of tokens pushed on the stack.
-
-      when Push_Back =>
-         PB_ID : Token_ID;
-         --  The nonterm ID popped off the stack.
-
-         PB_Token_Index : WisiToken.Base_Token_Index;
-         --  Config.Current_Shared_Token after
-         --  the operation is done. If the token is empty, Token_Index is
-         --  Invalid_Token_Index.
-
-      when Insert =>
-         Ins_ID : Token_ID;
-         --  The token ID inserted.
-
-         Ins_Token_Index : WisiToken.Base_Token_Index;
-         --  Ins_ID is inserted before Token_Index.
-
-      when Delete =>
-         Del_ID : Token_ID;
-         --  The token ID deleted.
-
-         Del_Token_Index : WisiToken.Base_Token_Index;
-         --  Token at Token_Index is deleted.
-
-      end case;
-   end record;
-   subtype Insert_Delete_Op is Config_Op with Dynamic_Predicate => 
(Insert_Delete_Op.Op in Insert_Delete_Op_Label);
-   subtype Insert_Op is Config_Op with Dynamic_Predicate => (Insert_Op.Op = 
Insert);
-
-   function Token_Index (Op : in Insert_Delete_Op) return WisiToken.Token_Index
-     is (case Insert_Delete_Op_Label'(Op.Op) is
-         when Insert => Op.Ins_Token_Index,
-         when Delete => Op.Del_Token_Index);
-
-   function ID (Op : in Insert_Delete_Op) return WisiToken.Token_ID
-     is (case Insert_Delete_Op_Label'(Op.Op) is
-         when Insert => Op.Ins_ID,
-         when Delete => Op.Del_ID);
-
-   function Compare (Left, Right : in Insert_Delete_Op) return 
SAL.Compare_Result;
-   --  Compare token_index.
-
-   function Equal (Left : in Config_Op; Right : in Insert_Op) return Boolean;
-   --  Ignore state, stack_depth
-
-   package Config_Op_Arrays is new SAL.Gen_Bounded_Definite_Vectors
-     (Positive_Index_Type, Config_Op, Capacity => 80);
-   --  Using a fixed size vector significantly speeds up
-   --  McKenzie_Recover. The capacity is determined by the maximum number
-   --  of repair operations, which is limited by the cost_limit McKenzie
-   --  parameter plus an arbitrary number from the language-specific
-   --  repairs; in practice, a capacity of 80 is enough so far. If a
-   --  config does hit that limit, it is abandoned; some other config is
-   --  likely to be cheaper.
-
-   package Config_Op_Array_Refs is new Config_Op_Arrays.Gen_Refs;
-
-   function Config_Op_Image (Item : in Config_Op; Descriptor : in 
WisiToken.Descriptor) return String
-     is ("(" & Config_Op_Label'Image (Item.Op) & ", " &
-           (case Item.Op is
-            when Fast_Forward => WisiToken.Token_Index'Image 
(Item.FF_Token_Index),
-            when Undo_Reduce => Image (Item.Nonterm, Descriptor) & "," &
-                 Ada.Containers.Count_Type'Image (Item.Token_Count),
-            when Push_Back => Image (Item.PB_ID, Descriptor) & "," &
-                 WisiToken.Token_Index'Image (Item.PB_Token_Index),
-            when Insert => Image (Item.Ins_ID, Descriptor) & "," &
-                 WisiToken.Token_Index'Image (Item.Ins_Token_Index),
-            when Delete => Image (Item.Del_ID, Descriptor) & "," &
-                 WisiToken.Token_Index'Image (Item.Del_Token_Index))
-           & ")");
-
-   function Image (Item : in Config_Op; Descriptor : in WisiToken.Descriptor) 
return String
-     renames Config_Op_Image;
-
-   function Config_Op_Array_Image is new Config_Op_Arrays.Gen_Image_Aux 
(WisiToken.Descriptor, Image);
-   function Image (Item : in Config_Op_Arrays.Vector; Descriptor : in 
WisiToken.Descriptor) return String
-     renames Config_Op_Array_Image;
-
-   function None (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean;
-   --  True if Ops contains no Op.
-
-   function None_Since_FF (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean;
-   --  True if Ops contains no Op after the last Fast_Forward (or ops.first, if
-   --  no Fast_Forward).
-
-   function Only_Since_FF (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean;
-   --  True if Ops contains only Op (at least one) after the last Fast_Forward 
(or ops.first, if
-   --  no Fast_Forward).
-
-   function Any (Ops : aliased in Config_Op_Arrays.Vector; Op : in 
Config_Op_Label) return Boolean;
-   --  True if Ops contains at least one Op.
-
-   type Recover_Op (Op : Insert_Delete_Op_Label := Insert) is record
-      --  Add Ins_Tree_Node to Config_Op info, set when item is
-      --  parsed; used to create user augmented token.
-
-      case Op is
-      when Insert =>
-         Ins_ID : Token_ID := Invalid_Token_ID;
-         --  The token ID inserted.
-
-         Ins_Token_Index : Base_Token_Index := Invalid_Token_Index;
-         --  Ins_ID is inserted before Token_Index.
-
-         Ins_Tree_Node : Node_Index := Invalid_Node_Index;
-
-      when Delete =>
-         Del_ID : Token_ID;
-         --  The token ID deleted.
-
-         Del_Token_Index : Base_Token_Index;
-         --  Token at Token_Index is deleted.
-
-      end case;
-   end record;
-
-   package Recover_Op_Arrays is new SAL.Gen_Bounded_Definite_Vectors
-     (Positive_Index_Type, Recover_Op, Capacity => 80);
-
-   package Recover_Op_Array_Refs is new Recover_Op_Arrays.Gen_Refs;
-
-   function Image (Item : in Recover_Op; Descriptor : in WisiToken.Descriptor) 
return String
-     is ("(" & Item.Op'Image & ", " &
-           (case Item.Op is
-            when Insert => Image (Item.Ins_ID, Descriptor) & "," &
-                 Item.Ins_Token_Index'Image & "," &
-                 Item.Ins_Tree_Node'Image,
-            when Delete => Image (Item.Del_ID, Descriptor) & "," &
-                 Item.Del_Token_Index'Image)
-           & ")");
-
-   function Image is new Recover_Op_Arrays.Gen_Image_Aux 
(WisiToken.Descriptor, Image);
-
-   type Recover_Stack_Item is record
-      State : Unknown_State_Index := Unknown_State;
-
-      Tree_Index : Node_Index := Invalid_Node_Index;
-      --  Valid if copied at recover initialize, Invalid if pushed during
-      --  recover.
-
-      Token : Recover_Token;
-      --  Virtual is False if token is from input text; True if inserted
-      --  during recover.
-   end record;
-
-   package Recover_Stacks is new SAL.Gen_Bounded_Definite_Stacks 
(Recover_Stack_Item);
-
-   function Image (Item : in Recover_Stack_Item; Descriptor : in 
WisiToken.Descriptor) return String
-     is ((if Item.State = Unknown_State then " " else Trimmed_Image 
(Item.State)) & " : " &
-           Image (Item.Token, Descriptor));
-
-   function Recover_Stack_Image is new Recover_Stacks.Gen_Image_Aux 
(WisiToken.Descriptor, Image);
-   --  Unique name for calling from debugger
-
-   function Image
-     (Stack      : in Recover_Stacks.Stack;
-      Descriptor : in WisiToken.Descriptor;
-      Depth      : in SAL.Base_Peek_Type := 0)
-     return String
-     renames Recover_Stack_Image;
-
-   function Valid_Tree_Indices (Stack : in Recover_Stacks.Stack; Depth : in 
SAL.Base_Peek_Type) return Boolean with
-     Pre => Stack.Depth >= Depth;
-   --  Return True if Stack top Depth items have valid Tree_Indices,
-   --  which is true if they were copied from the parser stack, and not
-   --  pushed by recover.
-
-   type Strategies is
-     (Ignore_Error, Language_Fix, Minimal_Complete, Matching_Begin,
-      Push_Back, Undo_Reduce, Insert, Delete, String_Quote);
-
-   type Strategy_Counts is array (Strategies) of Natural;
-   function Image is new SAL.Gen_Array_Image (Strategies, Natural, 
Strategy_Counts, Trimmed_Image);
-
-   type Minimal_Complete_State is (None, Active, Done);
-
-   type Configuration is record
-      Stack : Recover_Stacks.Stack (70);
-      --  Initially built from the parser stack, then the stack after the
-      --  Ops below have been performed.
-      --
-      --  Required size is determined by source code structure nesting;
-      --  larger size slows down recover due to memory cache thrashing and
-      --  allocation.
-      --
-      --  Emacs Ada mode wisi.adb needs > 50
-
-      Resume_Token_Goal : WisiToken.Token_Index := WisiToken.Token_Index'Last;
-      --  A successful solution shifts this token. Per-config because it
-      --  increases with Delete; we increase Shared_Parser.Resume_Token_Goal
-      --  only from successful configs.
-
-      Current_Shared_Token : Base_Token_Index := WisiToken.Token_Index'Last;
-      --  Index into Shared_Parser.Terminals for current input token, after
-      --  all of Inserted is input. Initially the error token.
-
-      String_Quote_Checked : Line_Number_Type := Invalid_Line_Number;
-      --  Max line checked for missing string quote.
-
-      Insert_Delete : aliased Config_Op_Arrays.Vector;
-      --  Edits to the input stream that are not yet parsed; contains only
-      --  Insert and Delete ops, in token_index order.
-
-      Current_Insert_Delete : SAL.Base_Peek_Type := No_Insert_Delete;
-      --  Index of the next op in Insert_Delete. If No_Insert_Delete, use
-      --  Current_Shared_Token.
-
-      Error_Token       : Recover_Token;
-      Check_Token_Count : Ada.Containers.Count_Type;
-      Check_Status      : Semantic_Checks.Check_Status;
-      --  If parsing this config ended with a parse error, Error_Token is
-      --  the token that failed to shift, Check_Status.Label is Ok.
-      --
-      --  If parsing this config ended with a semantic check fail,
-      --  Error_Token is the nonterm created by the reduction,
-      --  Check_Token_Count the number of tokens in the right hand side, and
-      --  Check_Status is the error.
-      --
-      --  Error_Token is set to Invalid_Token_ID when Config is parsed
-      --  successfully, or modified so the error is no longer meaningful (ie
-      --  in explore when adding an op, or in language_fixes when adding a
-      --  fix).
-
-      Ops : aliased Config_Op_Arrays.Vector;
-      --  Record of operations applied to this Config, in application order.
-      --  Insert and Delete ops that are not yet parsed are reflected in
-      --  Insert_Delete, in token_index order.
-
-      Cost : Natural := 0;
-
-      Strategy_Counts : LR.Strategy_Counts := (others => 0);
-      --  Count of strategies that produced Ops.
-
-      Minimal_Complete_State : LR.Minimal_Complete_State := None;
-      Matching_Begin_Done    : Boolean                   := False;
-   end record;
-
-   function Key (A : in Configuration) return Integer is (A.Cost);
-
-   procedure Set_Key (Item : in out Configuration; Key : in Integer);
-
-   package Config_Heaps is new SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci
-     (Element_Type   => Configuration,
-      Key_Type       => Integer,
-      Key            => Key,
-      Set_Key        => Set_Key);
-
-   type Check_Status is (Success, Abandon, Continue);
-   subtype Non_Success_Status is Check_Status range Abandon .. Continue;
-
-   type McKenzie_Data is tagged record
-      Config_Heap       : Config_Heaps.Heap_Type;
-      Enqueue_Count     : Integer := 0;
-      Config_Full_Count : Integer := 0;
-      Check_Count       : Integer := 0;
-      Results           : Config_Heaps.Heap_Type;
-      Success           : Boolean := False;
-   end record;
-   type McKenzie_Access is access all McKenzie_Data;
-
-   procedure Accumulate (Data : in McKenzie_Data; Counts : in out 
Strategy_Counts);
-   --  Sum Results.Strategy_Counts.
-
-   type Parse_Error_Label is (Action, Check, Message);
-
-   type Parse_Error
-     (Label          : Parse_Error_Label;
-      First_Terminal : Token_ID;
-      Last_Terminal  : Token_ID)
-   is record
-      Recover : Configuration;
-
-      case Label is
-      when Action =>
-         Error_Token : Valid_Node_Index; -- index into Parser.Tree
-         Expecting   : Token_ID_Set (First_Terminal .. Last_Terminal);
-
-      when Check =>
-         Check_Status : Semantic_Checks.Check_Status;
-
-      when Message =>
-         Msg : Ada.Strings.Unbounded.Unbounded_String;
-      end case;
-   end record;
-
-   package Parse_Error_Lists is new 
Ada.Containers.Indefinite_Doubly_Linked_Lists (Parse_Error);
-
-end WisiToken.Parse.LR;
diff --git a/packages/wisi/wisitoken-parse-packrat-generated.adb 
b/packages/wisi/wisitoken-parse-packrat-generated.adb
deleted file mode 100644
index 7d73f34..0000000
--- a/packages/wisi/wisitoken-parse-packrat-generated.adb
+++ /dev/null
@@ -1,96 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse.Packrat.Generated is
-
-   overriding procedure Parse (Parser : aliased in out Generated.Parser)
-   is
-      --  'aliased' required for Base_Tree'Access. WORKAROUND: that was
-      --  enough when Parser type was declared in generated Main; now that
-      --  it's a derived type, it doesn't work. So we use Unchecked_Access.
-
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      Junk : WisiToken.Valid_Node_Index;
-      pragma Unreferenced (Junk);
-
-      Result : Memo_Entry;
-   begin
-      Parser.Base_Tree.Clear;
-      Parser.Tree.Initialize (Parser.Base_Tree'Unchecked_Access, Flush => 
True);
-      Parser.Lex_All;
-      Parser.Derivs.Set_First_Last (Descriptor.First_Nonterminal, 
Descriptor.Last_Nonterminal);
-
-      for Nonterm in Descriptor.First_Nonterminal .. 
Parser.Trace.Descriptor.Last_Nonterminal loop
-         Parser.Derivs (Nonterm).Clear;
-         Parser.Derivs (Nonterm).Set_First_Last (Parser.Terminals.First_Index, 
Parser.Terminals.Last_Index);
-      end loop;
-
-      for Token_Index in Parser.Terminals.First_Index .. 
Parser.Terminals.Last_Index loop
-         Junk := Parser.Tree.Add_Terminal (Token_Index, Parser.Terminals);
-         --  FIXME: move this into Lex_All, delete Terminals, just use 
Syntax_Tree
-      end loop;
-
-      Result := Parser.Parse_WisiToken_Accept (Parser, 
Parser.Terminals.First_Index - 1);
-
-      if Result.State /= Success then
-         if Trace_Parse > Outline then
-            Parser.Trace.Put_Line ("parse failed");
-         end if;
-
-         raise Syntax_Error with "parse failed"; --  FIXME: need better error 
message!
-      else
-         Parser.Tree.Set_Root (Result.Result);
-      end if;
-
-   end Parse;
-
-   overriding function Tree (Parser : in Generated.Parser) return 
Syntax_Trees.Tree
-   is begin
-      return Parser.Tree;
-   end Tree;
-
-   overriding function Tree_Var_Ref
-     (Parser : aliased in out Generated.Parser)
-     return Syntax_Trees.Tree_Variable_Reference
-   is begin
-      return (Element => Parser.Tree'Access);
-   end Tree_Var_Ref;
-
-   overriding function Any_Errors (Parser : in Generated.Parser) return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      return Parser.Lexer.Errors.Length > 0;
-   end Any_Errors;
-
-   overriding procedure Put_Errors (Parser : in Generated.Parser)
-   is
-      use Ada.Text_IO;
-   begin
-      for Item of Parser.Lexer.Errors loop
-         Put_Line
-           (Current_Error,
-            Parser.Lexer.File_Name & ":0:0: lexer unrecognized character at" & 
Buffer_Pos'Image (Item.Char_Pos));
-      end loop;
-
-      --  FIXME: Packrat parser does not report errors yet.
-   end Put_Errors;
-
-end WisiToken.Parse.Packrat.Generated;
diff --git a/packages/wisi/wisitoken-parse-packrat-generated.ads 
b/packages/wisi/wisitoken-parse-packrat-generated.ads
deleted file mode 100644
index 4932465..0000000
--- a/packages/wisi/wisitoken-parse-packrat-generated.ads
+++ /dev/null
@@ -1,76 +0,0 @@
---  Abstract :
---
---  Types and operations for a packrat parser runtime, with nonterm
---  parsing subprograms generated by wisi-generate.
---
---  References:
---
---  see parent.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.Packrat.Generated is
-
-   Recursive : exception; -- FIXME: delete
-
-   type Memo_State is (No_Result, Failure, Success);
-   subtype Result_States is Memo_State range Failure .. Success;
-
-   type Memo_Entry (State : Memo_State := No_Result) is record
-
-      case State is
-      when No_Result =>
-         Recursive : Boolean := False; --  FIXME: delete
-
-      when Failure =>
-         null;
-
-      when Success =>
-         Result : aliased Valid_Node_Index;
-
-         Last_Token : Base_Token_Index; --  FIXME: change to Last_Pos
-
-      end case;
-   end record;
-
-   package Memos is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_Index, Memo_Entry, Default_Element => (others => <>));
-
-   subtype Result_Type is Memo_Entry
-   with Dynamic_Predicate => Result_Type.State in Result_States;
-
-   package Derivs is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_ID, Memos.Vector, Default_Element => Memos.Empty_Vector);
-
-   type Parse_WisiToken_Accept is access
-     --  WORKAROUND: using Packrat.Parser'Class here hits a GNAT Bug box in 
GPL 2018.
-     function (Parser : in out Base_Parser'Class; Last_Pos : in 
Base_Token_Index) return Result_Type;
-
-   type Parser is new Packrat.Parser with record
-      Derivs : Generated.Derivs.Vector; --  FIXME: use discriminated array, as 
in procedural
-
-      Parse_WisiToken_Accept : Generated.Parse_WisiToken_Accept;
-   end record;
-
-   overriding procedure Parse (Parser : aliased in out Generated.Parser);
-   overriding function Tree (Parser : in Generated.Parser) return 
Syntax_Trees.Tree;
-   overriding function Tree_Var_Ref
-     (Parser : aliased in out Generated.Parser)
-     return Syntax_Trees.Tree_Variable_Reference;
-   overriding function Any_Errors (Parser : in Generated.Parser) return 
Boolean;
-   overriding procedure Put_Errors (Parser : in Generated.Parser);
-
-end WisiToken.Parse.Packrat.Generated;
diff --git a/packages/wisi/wisitoken-parse-packrat-procedural.adb 
b/packages/wisi/wisitoken-parse-packrat-procedural.adb
deleted file mode 100644
index 887794e..0000000
--- a/packages/wisi/wisitoken-parse-packrat-procedural.adb
+++ /dev/null
@@ -1,267 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse.Packrat.Procedural is
-
-   function Apply_Rule
-     (Parser   : in out Procedural.Parser;
-      R        : in     Token_ID;
-      Last_Pos : in     Base_Token_Index)
-     return Memo_Entry
-   with Post => Apply_Rule'Result.State in Failure .. Success;
-
-   function Eval
-     (Parser   : in out Procedural.Parser;
-      R        : in     Token_ID;
-      Last_Pos : in     Base_Token_Index)
-     return Memo_Entry
-   with Post => Eval'Result.State in Failure .. Success;
-
-   ----------
-   --  bodies
-
-   function Eval
-     (Parser   : in out Procedural.Parser;
-      R        : in     Token_ID;
-      Last_Pos : in     Base_Token_Index)
-     return Memo_Entry
-   is
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      subtype Terminal is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-
-      Pos : Base_Token_Index := Last_Pos; --  last token parsed.
-   begin
-      for RHS_Index in Parser.Grammar (R).RHSs.First_Index .. Parser.Grammar 
(R).RHSs.Last_Index loop
-         declare
-            use all type Ada.Containers.Count_Type;
-            RHS  : WisiToken.Productions.Right_Hand_Side renames 
Parser.Grammar (R).RHSs (RHS_Index);
-            Memo : Memo_Entry; --  for temporary or intermediate results
-         begin
-            if RHS.Tokens.Length = 0 then
-               return
-                 (State              => Success,
-                  Result             => Parser.Tree.Add_Nonterm
-                    (Production      => (R, RHS_Index),
-                     Action          => RHS.Action,
-                     Children        => (1 .. 0 => Invalid_Node_Index),
-                     Default_Virtual => False),
-                  Last_Pos           => Pos);
-            else
-               declare
-                  Children : Valid_Node_Index_Array
-                    (SAL.Base_Peek_Type (RHS.Tokens.First_Index) .. 
SAL.Base_Peek_Type (RHS.Tokens.Last_Index));
-               begin
-                  for I in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index loop
-                     if RHS.Tokens (I) in Terminal then
-                        if Pos = Parser.Terminals.Last_Index then
-                           goto Fail_RHS;
-
-                        elsif Parser.Terminals (Pos + 1).ID = RHS.Tokens (I) 
then
-                           Pos := Pos + 1;
-                           Children (SAL.Base_Peek_Type (I)) := Tree_Index 
(Pos);
-                        else
-                           goto Fail_RHS;
-                        end if;
-                     else
-                        Memo := Apply_Rule (Parser, RHS.Tokens (I), Pos);
-                        case Memo.State is
-                        when Success =>
-                           Children (SAL.Base_Peek_Type (I)) := Memo.Result;
-                           Pos := Memo.Last_Pos;
-
-                        when Failure =>
-                           goto Fail_RHS;
-                        when No_Result =>
-                           raise SAL.Programmer_Error;
-                        end case;
-                     end if;
-                  end loop;
-
-                  return
-                    (State              => Success,
-                     Result             => Parser.Tree.Add_Nonterm
-                       (Production      => (R, RHS_Index),
-                        Action          => RHS.Action,
-                        Children        => Children,
-                        Default_Virtual => False),
-                     Last_Pos           => Pos);
-
-                  <<Fail_RHS>>
-                  Pos := Last_Pos;
-               end;
-            end if;
-         end;
-      end loop;
-      --  get here when all RHSs fail
-
-      return (State => Failure);
-   end Eval;
-
-   function Apply_Rule
-     (Parser   : in out Procedural.Parser;
-      R        : in     Token_ID;
-      Last_Pos : in     Base_Token_Index)
-     return Memo_Entry
-   is
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      Pos       : Base_Token_Index     := Last_Pos;     --  last token parsed.
-      Start_Pos : constant Token_Index := Last_Pos + 1; --  first token in 
current nonterm
-      Memo      : Memo_Entry           := Parser.Derivs (R)(Start_Pos);
-
-      Pos_Recurse_Last : Base_Token_Index := Last_Pos;
-      Result_Recurse   : Memo_Entry;
-   begin
-      case Memo.State is
-      when Success =>
-         return Memo;
-
-      when Failure =>
-         return (State => Failure);
-
-      when No_Result =>
-         if Parser.Direct_Left_Recursive (R) then
-            Parser.Derivs (R).Replace_Element (Start_Pos, (State => Failure));
-         else
-            Memo := Eval (Parser, R, Last_Pos);
-            if (Trace_Parse > Detail and Memo.State = Success) or Trace_Parse 
> Extra then
-               case Memo.State is
-               when Success =>
-                  Parser.Trace.Put_Line (Parser.Tree.Image (Memo.Result, 
Descriptor, Include_Children => True));
-               when Failure =>
-                  Parser.Trace.Put_Line (Image (R, Descriptor) & " failed at 
pos" & Last_Pos'Image);
-               when No_Result =>
-                  raise SAL.Programmer_Error;
-               end case;
-            end if;
-            Parser.Derivs (R).Replace_Element (Start_Pos, Memo);
-            return Memo;
-         end if;
-      end case;
-
-      loop
-         Pos := Last_Pos;
-
-         if Pos > Parser.Terminals.Last_Index then --  FIXME: this can't pass 
here; Last_Pos never > last_index
-            --  There might be an empty nonterm after the last token
-            return (State => Failure);
-         end if;
-
-         Result_Recurse := Eval (Parser, R, Pos);
-
-         if Result_Recurse.State = Success then
-            if Result_Recurse.Last_Pos > Pos_Recurse_Last then
-               Parser.Derivs (R).Replace_Element (Start_Pos, Result_Recurse);
-               Pos              := Result_Recurse.Last_Pos;
-               Pos_Recurse_Last := Pos;
-
-               if WisiToken.Trace_Parse > Detail then
-                  Parser.Trace.Put_Line
-                    (Parser.Tree.Image (Result_Recurse.Result, Descriptor, 
Include_Children => True));
-               end if;
-               --  continue looping
-
-            elsif Result_Recurse.Last_Pos = Pos_Recurse_Last then
-               if Parser.Tree.Buffer_Region_Is_Empty (Result_Recurse.Result) 
then
-                  Parser.Derivs (R).Replace_Element (Start_Pos, 
Result_Recurse);
-               end if;
-               exit;
-            else
-               --  Result_Recurse.Last_Pos < Pos_Recurse_Last
-               exit;
-            end if;
-         else
-            exit;
-         end if;
-      end loop;
-      return Parser.Derivs (R)(Start_Pos);
-   end Apply_Rule;
-
-   ----------
-   --  Public subprograms
-
-   function Create
-     (Grammar               : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Direct_Left_Recursive : in     Token_ID_Set;
-      Start_ID              : in     Token_ID;
-      Trace                 : access WisiToken.Trace'Class;
-      Lexer                 :        WisiToken.Lexer.Handle;
-      User_Data             :        WisiToken.Syntax_Trees.User_Data_Access)
-     return Procedural.Parser
-   is begin
-      return Parser : Procedural.Parser (Grammar.First_Index, 
Grammar.Last_Index) do
-         Parser.Trace                 := Trace;
-         Parser.Lexer                 := Lexer;
-         Parser.User_Data             := User_Data;
-         Parser.Grammar               := Grammar;
-         Parser.Start_ID              := Start_ID;
-         Parser.Direct_Left_Recursive := Direct_Left_Recursive;
-      end return;
-   end Create;
-
-   overriding procedure Parse (Parser : aliased in out Procedural.Parser)
-   is
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      Junk : Valid_Node_Index;
-      pragma Unreferenced (Junk);
-
-      Result : Memo_Entry;
-   begin
-      Parser.Base_Tree.Clear;
-      Parser.Tree.Initialize (Parser.Base_Tree'Unchecked_Access, Flush => 
True);
-      Parser.Lex_All;
-
-      for Nonterm in Descriptor.First_Nonterminal .. 
Parser.Trace.Descriptor.Last_Nonterminal loop
-         Parser.Derivs (Nonterm).Clear;
-         Parser.Derivs (Nonterm).Set_First_Last (Parser.Terminals.First_Index, 
Parser.Terminals.Last_Index + 1);
-         --  There might be an empty nonterm after the last token
-      end loop;
-
-      for Token_Index in Parser.Terminals.First_Index .. 
Parser.Terminals.Last_Index loop
-         Junk := Parser.Tree.Add_Terminal (Token_Index, Parser.Terminals);
-      end loop;
-
-      Result := Apply_Rule (Parser, Parser.Start_ID, 
Parser.Terminals.First_Index - 1);
-
-      if Result.State /= Success then
-         if Trace_Parse > Outline then
-            Parser.Trace.Put_Line ("parse failed");
-         end if;
-
-         raise Syntax_Error with "parse failed"; --  FIXME: need better error 
message!
-      else
-         Parser.Tree.Set_Root (Result.Result);
-      end if;
-   end Parse;
-
-   overriding function Tree (Parser : in Procedural.Parser) return 
Syntax_Trees.Tree
-   is begin
-      return Parser.Tree;
-   end Tree;
-
-   overriding function Tree_Var_Ref
-     (Parser : aliased in out Procedural.Parser)
-     return Syntax_Trees.Tree_Variable_Reference
-   is begin
-      return (Element => Parser.Tree'Access);
-   end Tree_Var_Ref;
-
-end WisiToken.Parse.Packrat.Procedural;
diff --git a/packages/wisi/wisitoken-parse-packrat-procedural.ads 
b/packages/wisi/wisitoken-parse-packrat-procedural.ads
deleted file mode 100644
index ff04837..0000000
--- a/packages/wisi/wisitoken-parse-packrat-procedural.ads
+++ /dev/null
@@ -1,86 +0,0 @@
---  Abstract :
---
---  Procedural packrat parser, supporting only direct left recursion.
---
---  Coding style, algorithm is the same as generated by
---  wisi-generate_packrat, but in procedural form.
---
---  References:
---
---  See parent.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Productions;
-package WisiToken.Parse.Packrat.Procedural is
-
-   --  These types duplicate Packrat.Generated. We keep them separate so
-   --  we can experiment with ways of implementing indirect left
-   --  recursion.
-
-   type Memo_State is (No_Result, Failure, Success);
-   subtype Result_States is Memo_State range Failure .. Success;
-
-   type Memo_Entry (State : Memo_State := No_Result) is record
-      case State is
-      when No_Result =>
-         null;
-
-      when Failure =>
-         null;
-
-      when Success =>
-         Result   : WisiToken.Valid_Node_Index;
-         Last_Pos : Base_Token_Index;
-
-      end case;
-   end record;
-
-   package Memos is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_Index, Memo_Entry, Default_Element => (others => <>));
-   type Derivs is array (Token_ID range <>) of Memos.Vector;
-
-   type Parser (First_Nonterminal, Last_Nonterminal : Token_ID) is new 
Packrat.Parser with
-   record
-      Grammar               : WisiToken.Productions.Prod_Arrays.Vector;
-      Start_ID              : Token_ID;
-      Direct_Left_Recursive : Token_ID_Set (First_Nonterminal .. 
Last_Nonterminal);
-      Derivs                : Procedural.Derivs (First_Nonterminal .. 
Last_Nonterminal);
-   end record;
-
-   function Create
-     (Grammar               : in     WisiToken.Productions.Prod_Arrays.Vector;
-      Direct_Left_Recursive : in     Token_ID_Set;
-      Start_ID              : in     Token_ID;
-      Trace                 : access WisiToken.Trace'Class;
-      Lexer                 :        WisiToken.Lexer.Handle;
-      User_Data             :        WisiToken.Syntax_Trees.User_Data_Access)
-     return Procedural.Parser;
-
-   overriding procedure Parse (Parser : aliased in out Procedural.Parser);
-   overriding function Tree (Parser : in Procedural.Parser) return 
Syntax_Trees.Tree;
-   overriding function Tree_Var_Ref
-     (Parser : aliased in out Procedural.Parser)
-     return Syntax_Trees.Tree_Variable_Reference;
-
-   overriding function Any_Errors (Parser : in Procedural.Parser) return 
Boolean
-     is (False);
-   --  All errors are reported by Parse raising Syntax_Error.
-
-   overriding procedure Put_Errors (Parser : in Procedural.Parser)
-   is null;
-
-end WisiToken.Parse.Packrat.Procedural;
diff --git a/packages/wisi/wisitoken-parse-packrat.adb 
b/packages/wisi/wisitoken-parse-packrat.adb
deleted file mode 100644
index 46ea1e9..0000000
--- a/packages/wisi/wisitoken-parse-packrat.adb
+++ /dev/null
@@ -1,63 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse.Packrat is
-
-   overriding
-   procedure Execute_Actions
-     (Parser          : in out Packrat.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null)
-   is
-      Descriptor : WisiToken.Descriptor renames Parser.Trace.Descriptor.all;
-
-      procedure Process_Node
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index)
-      is
-         use all type Syntax_Trees.Node_Label;
-      begin
-         if Tree.Label (Node) /= Nonterm then
-            return;
-         end if;
-
-         declare
-            use all type Syntax_Trees.Semantic_Action;
-            Tree_Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-         begin
-            Parser.User_Data.Reduce (Tree, Node, Tree_Children);
-
-            if Tree.Action (Node) /= null then
-               Tree.Action (Node) (Parser.User_Data.all, Tree, Node, 
Tree_Children);
-            end if;
-         end;
-      end Process_Node;
-
-   begin
-      if Trace_Action > Outline then
-         if Trace_Action > Extra then
-            Parser.Tree.Print_Tree (Descriptor, Parser.Tree.Root, 
Image_Augmented);
-            Parser.Trace.New_Line;
-         end if;
-         Parser.Trace.Put_Line ("root node: " & Parser.Tree.Image 
(Parser.Tree.Root, Descriptor));
-      end if;
-
-      Parser.Tree.Process_Tree (Process_Node'Access);
-   end Execute_Actions;
-
-end WisiToken.Parse.Packrat;
diff --git a/packages/wisi/wisitoken-parse-packrat.ads 
b/packages/wisi/wisitoken-parse-packrat.ads
deleted file mode 100644
index 9c0421f..0000000
--- a/packages/wisi/wisitoken-parse-packrat.ads
+++ /dev/null
@@ -1,75 +0,0 @@
---  Abstract :
---
---  Types and operations for a packrat parser runtime.
---
---  References:
---
---  [ford thesis] Bryan Ford thesis http://bford.info/pub/lang/thesis
---
---  [langkit]     AdaCore langkit   https://github.com/adacore/langkit
---
---  [tratt 2010]  http://tratt.net/laurie/research/pubs/papers/
---                tratt__direct_left_recursive_parsing_expression_grammars.pdf
---
---  [warth 2008]  Warth, A., Douglass, J.R. and Millstein, T.D., 2008. Packrat
---                parsers can support left recursion. PEPM, 8, pp.103-110.
---
---  Copyright (C) 2018, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
---  Design:
---
---  [ford thesis] uses Haskell lazy evaluation, and does not use a
---  lexer. We use a lexer to reduce the memory requirement. Although
---  eliminating the lexer would make it easier to support additional
---  syntax for a preprocessor or template generator.
---
---  [langkit] uses a lexer, and implements lazy evaluation via
---  Memo_State, Memo_Entry as we do here, except that their result
---  type is a specific AST type provided by a generic parameter; we
---  use the general purpose Syntax_Tree.Tree type.
---
---  [langkit] also applies a memory optimization; it only saves the
---  last 16 results for each nonterminal. We don't do that yet, so we
---  can get some data on how well that works.
-
-pragma License (Modified_GPL);
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse.Packrat is
-
-   function Tree_Index (Terminal_Index : in Token_Index) return 
Valid_Node_Index
-     is (Valid_Node_Index (Terminal_Index));
-   --  All tokens are read and entered into the syntax tree before any
-   --  nonterms are reduced, so the mapping from Terminals token_index to
-   --  Tree node_index is identity.
-   --  FIXME: use Terminals (Terminal_Index).Tree_Index
-
-   type Parser is abstract new Base_Parser with record
-      --  Dynamic parsing data
-
-      Base_Tree : aliased WisiToken.Syntax_Trees.Base_Tree;
-      Tree      : aliased WisiToken.Syntax_Trees.Tree;
-      --  FIXME: Current we only need Base_Tree for Execute_Actions, except
-      --  that Syntax_Trees only declares the needed operations on Tree. But
-      --  we may need more trees for error recovery; if not, fix
-      --  Syntax_Trees, move Base_Tree and Execute_Actions up to
-      --  base_parser.
-
-   end record;
-
-   overriding
-   procedure Execute_Actions
-     (Parser          : in out Packrat.Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null);
-
-end WisiToken.Parse.Packrat;
diff --git a/packages/wisi/wisitoken-parse.adb 
b/packages/wisi/wisitoken-parse.adb
deleted file mode 100644
index 535c423..0000000
--- a/packages/wisi/wisitoken-parse.adb
+++ /dev/null
@@ -1,108 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Parse is
-
-   function Next_Grammar_Token (Parser : in out Base_Parser'Class) return 
Token_ID
-   is
-      use all type Ada.Containers.Count_Type;
-      use all type Syntax_Trees.User_Data_Access;
-
-      Token : Base_Token;
-      Error : Boolean;
-   begin
-      loop
-         Error := Parser.Lexer.Find_Next (Token);
-
-         --  We don't handle Error until later; we assume it was recovered.
-
-         if Token.Line /= Invalid_Line_Number then
-            --  Some lexers don't support line numbers.
-            if Parser.Lexer.First then
-               if Parser.Line_Begin_Token.Length = 0 then
-                  Parser.Line_Begin_Token.Set_First_Last (Token.Line, 
Token.Line);
-               else
-                  Parser.Line_Begin_Token.Set_First_Last 
(Parser.Line_Begin_Token.First_Index, Token.Line);
-               end if;
-               Parser.Line_Begin_Token (Token.Line) := 
Parser.Terminals.Last_Index +
-                 (if Token.ID >= Parser.Trace.Descriptor.First_Terminal then 1 
else 0);
-
-            elsif Token.ID = Parser.Trace.Descriptor.EOI_ID then
-               Parser.Line_Begin_Token.Set_First_Last 
(Parser.Line_Begin_Token.First_Index, Token.Line + 1);
-               Parser.Line_Begin_Token (Token.Line + 1) := 
Parser.Terminals.Last_Index + 1;
-            end if;
-         end if;
-
-         if Trace_Parse > Lexer_Debug then
-            Parser.Trace.Put_Line (Image (Token, Parser.Trace.Descriptor.all));
-         end if;
-
-         if Token.ID >= Parser.Trace.Descriptor.First_Terminal then
-
-            Parser.Terminals.Append (Token);
-
-            --  We create the syntax tree node here, so Lexer_To_Augmented can
-            --  store augmented data in it.
-            Parser.Terminals (Parser.Terminals.Last_Index).Tree_Index := 
Parser.Tree_Var_Ref.Add_Terminal
-              (Parser.Terminals.Last_Index, Parser.Terminals);
-
-            if Parser.User_Data /= null then
-               Parser.User_Data.Lexer_To_Augmented
-                 (Parser.Tree_Var_Ref, Parser.Terminals 
(Parser.Terminals.Last_Index), Parser.Lexer);
-            end if;
-
-            exit;
-         else
-            --  non-grammar; not in syntax tree
-            if Parser.User_Data /= null then
-               Parser.User_Data.Lexer_To_Augmented (Parser.Tree_Var_Ref, 
Token, Parser.Lexer);
-            end if;
-         end if;
-      end loop;
-
-      if Error then
-         declare
-            Error : WisiToken.Lexer.Error renames 
Parser.Lexer.Errors.Reference (Parser.Lexer.Errors.Last);
-         begin
-            if Error.Recover_Char (1) /= ASCII.NUL then
-               Error.Recover_Token := Parser.Terminals.Last_Index;
-            end if;
-         end;
-      end if;
-
-      return Token.ID;
-   end Next_Grammar_Token;
-
-   procedure Lex_All (Parser : in out Base_Parser'Class)
-   is
-      EOF_ID : constant Token_ID := Parser.Trace.Descriptor.EOI_ID;
-   begin
-      Parser.Lexer.Errors.Clear;
-      Parser.Terminals.Clear;
-      Parser.Line_Begin_Token.Clear;
-      loop
-         exit when EOF_ID = Next_Grammar_Token (Parser);
-      end loop;
-      if Trace_Parse > Outline then
-         Parser.Trace.Put_Line (Token_Index'Image 
(Parser.Terminals.Last_Index) & " tokens lexed");
-      end if;
-
-   end Lex_All;
-
-end WisiToken.Parse;
diff --git a/packages/wisi/wisitoken-parse.ads 
b/packages/wisi/wisitoken-parse.ads
deleted file mode 100644
index 1493658..0000000
--- a/packages/wisi/wisitoken-parse.ads
+++ /dev/null
@@ -1,84 +0,0 @@
---  Abstract :
---
---  Subprograms common to more than one parser, higher-level than in 
wisitoken.ads
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with WisiToken.Lexer;
-with WisiToken.Syntax_Trees;
-package WisiToken.Parse is
-
-   type Base_Parser is abstract new Ada.Finalization.Limited_Controlled with 
record
-      Trace     : access WisiToken.Trace'Class;
-      Lexer     : WisiToken.Lexer.Handle;
-      User_Data : WisiToken.Syntax_Trees.User_Data_Access;
-      Terminals : aliased WisiToken.Base_Token_Arrays.Vector;
-
-      Line_Begin_Token : aliased WisiToken.Line_Begin_Token_Vectors.Vector;
-      --  Line_Begin_Token (I) is the index into Terminals of the first
-      --  grammar token on line I. Line_Begin_Token.First_Index is the first
-      --  line containing a grammar token (after leading comments). However,
-      --  if the only token on line I is a non_grammar token (ie a comment,
-      --  or a newline for a blank line), Line_Begin_Token (I) is the last
-      --  grammar token on the previous non-blank line. If Line (I) is a
-      --  non-first line in a multi-line terminal token, Line_Begin_Token
-      --  (I) is Invalid_Token_Index.
-   end record;
-   --  Common to all parsers. Finalize should free any allocated objects.
-
-   function Next_Grammar_Token (Parser : in out Base_Parser'Class) return 
Token_ID;
-   --  Get next token from Lexer, call User_Data.Lexer_To_Augmented. If
-   --  it is a grammar token, store in Terminals and return its id.
-   --  Otherwise, repeat.
-   --
-   --  Propagates Fatal_Error from Lexer.
-
-   procedure Lex_All (Parser : in out Base_Parser'Class);
-   --  Clear Terminals, Line_Begin_Token; reset User_Data. Then call
-   --  Next_Grammar_Token repeatedly until EOF_ID is returned.
-   --
-   --  The user must first call Lexer.Reset_* to set the input text.
-
-   procedure Parse (Parser : aliased in out Base_Parser) is abstract;
-   --  Call Lex_All, then execute parse algorithm to parse the tokens,
-   --  storing the result in Parser for Execute_Actions.
-   --
-   --  If a parse error is encountered, raises Syntax_Error.
-   --  Parser.Lexer_Errors and Parser contain information about the
-   --  errors.
-   --
-   --  For other errors, raises Parse_Error with an appropriate error
-   --  message.
-
-   function Tree (Parser : in Base_Parser) return Syntax_Trees.Tree is 
abstract;
-   --  Return the syntax tree resulting from the parse.
-
-   function Tree_Var_Ref (Parser : aliased in out Base_Parser) return 
Syntax_Trees.Tree_Variable_Reference is abstract;
-   --  Return a writable reference to the syntax tree resulting from the parse.
-
-   function Any_Errors (Parser : in Base_Parser) return Boolean is abstract;
-
-   procedure Put_Errors (Parser : in Base_Parser) is abstract;
-   --  Output error messages to Ada.Text_IO.Current_Error.
-
-   procedure Execute_Actions
-     (Parser          : in out Base_Parser;
-      Image_Augmented : in     Syntax_Trees.Image_Augmented := null)
-     is abstract;
-   --  Execute all actions in Parser.Tree.
-
-end WisiToken.Parse;
diff --git a/packages/wisi/wisitoken-parse_table-mode.el 
b/packages/wisi/wisitoken-parse_table-mode.el
deleted file mode 100644
index e864ab0..0000000
--- a/packages/wisi/wisitoken-parse_table-mode.el
+++ /dev/null
@@ -1,95 +0,0 @@
-;; wisitoken-parse_table-mode.el --- For navigating in a parse table as output 
by wisitoken-bnf-generate. -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2017 - 2020  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Keywords: parser
-;; Version: 1.0
-;; package-requires: ((emacs "25.1"))
-;; URL: http://www.nongnu.org/ada-mode/wisi/wisi.html
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-(require 'xref)
-
-(defun wisitoken-parse_table--xref-backend () 'wisitoken-parse_table)
-
-(cl-defgeneric xref-backend-identifier-completion-table ((_backend (eql 
wisitoken-parse_table)))
-  ;; could complete on nonterms, find productions
-  nil)
-
-(cl-defmethod xref-backend-identifier-at-point ((_backend (eql 
wisitoken-parse_table)))
-  ;; if we are on one of:
-  ;; - ’goto state nnn’ in a state action
-  ;; => return nnn state
-  ;;
-  ;; or
-  ;; - foo <= bar baz
-  ;; => return nonterminal name at point
-  ;;
-  ;; - 'reduce n tokens to <nonterminal> <prod_id>'
-  ;; => return 'prod_id: name'
-  (cond
-   ((save-excursion
-      (beginning-of-line)
-      ;; "go to" for bison output
-      (search-forward-regexp "go ?to state \\([0-9]+\\)" (line-end-position) 
t))
-    (match-string 1))
-
-   ((save-excursion
-      (beginning-of-line)
-      (search-forward-regexp "reduce [0-9]+ tokens to \\([[:alnum:]_]+\\) 
\\([0-9.]+\\)" (line-end-position) t))
-    (concat (match-string 2) ": " (match-string 1)))
-
-   (t
-    (thing-at-point 'symbol))))
-
-(cl-defgeneric xref-backend-definitions ((_backend (eql 
wisitoken-parse_table)) identifier)
-  ;; IDENTIFIER is from xref-back-identifier-at-point; a state number or a 
nonterminal
-  (let ((state-p (string-match "\\`[0-9]+\\'" identifier))
-       (prod_id-p (string-match "\\`[0-9.]+: " identifier)))
-    (save-excursion
-      (goto-char (point-min))
-      (cond
-       (state-p
-       (search-forward-regexp (concat "^State " identifier ":$")))
-
-       (prod_id-p
-       (search-forward-regexp (concat identifier " <=")))
-
-       (t
-       (search-forward-regexp (concat "^[0-9.]+: " identifier " <=")))
-       )
-      (list (xref-make identifier (xref-make-buffer-location (current-buffer) 
(match-beginning 0))))
-      )))
-
-;;;###autoload
-(define-minor-mode wisitoken-parse_table-mode
-  "Provides navigation in wisi-generate parse table output."
-  nil ":parse_table" nil
-  (add-hook 'xref-backend-functions #'wisitoken-parse_table--xref-backend nil 
t)
-
-  (if wisitoken-parse_table-mode
-      (read-only-mode 0)
-    (read-only-mode 1)
-  ))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.parse_table.*\\'" . 
wisitoken-parse_table-mode))
-
-(provide 'wisitoken-parse_table-mode)
-;; end of file
diff --git a/packages/wisi/wisitoken-productions.adb 
b/packages/wisi/wisitoken-productions.adb
deleted file mode 100644
index 2f1892f..0000000
--- a/packages/wisi/wisitoken-productions.adb
+++ /dev/null
@@ -1,83 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018, 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO;
-package body WisiToken.Productions is
-
-   function Image (Item : in Recursion_Arrays.Vector) return String
-   is
-      use Ada.Strings.Unbounded;
-      Result     : Ada.Strings.Unbounded.Unbounded_String := +"(";
-      Need_Comma : Boolean                                := False;
-   begin
-      --  We assume most are None, so we use named association
-      for I in Item.First_Index .. Item.Last_Index loop
-         if Item (I) /= None then
-            Result := Result & (if Need_Comma then ", " else "") & 
Trimmed_Image (I) & " => " & Image (Item (I));
-            Need_Comma := True;
-         end if;
-      end loop;
-      Result := Result & ")";
-      return -Result;
-   end Image;
-
-   function Constant_Ref_RHS
-     (Grammar : in Prod_Arrays.Vector;
-      ID      : in Production_ID)
-     return RHS_Arrays.Constant_Reference_Type
-   is begin
-      return RHS_Arrays.Constant_Ref (Grammar (ID.LHS).RHSs, ID.RHS);
-   end Constant_Ref_RHS;
-
-   function Image
-     (LHS        : in Token_ID;
-      RHS_Index  : in Natural;
-      RHS        : in Token_ID_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String := +Trimmed_Image ((LHS, RHS_Index)) & ": " & 
Image (LHS, Descriptor) & " <=";
-   begin
-      for ID of RHS loop
-         Result := Result & ' ' & Image (ID, Descriptor);
-      end loop;
-      return To_String (Result);
-   end Image;
-
-   procedure Put (Grammar : Prod_Arrays.Vector; Descriptor : in 
WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-   begin
-      for P of Grammar loop
-         for R in P.RHSs.First_Index .. P.RHSs.Last_Index loop
-            Put (Image (P.LHS, R, P.RHSs (R).Tokens, Descriptor));
-            if (for all Item of Grammar (P.LHS).RHSs (R).Recursion => Item = 
None) then
-               New_Line;
-            else
-               Put_Line (" ; " & Image (Grammar (P.LHS).RHSs (R).Recursion));
-            end if;
-         end loop;
-      end loop;
-   end Put;
-
-end WisiToken.Productions;
diff --git a/packages/wisi/wisitoken-productions.ads 
b/packages/wisi/wisitoken-productions.ads
deleted file mode 100644
index 8b8c8f8..0000000
--- a/packages/wisi/wisitoken-productions.ads
+++ /dev/null
@@ -1,88 +0,0 @@
---  Abstract :
---
---  Type and operations for building grammar productions.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library is distributed in
---  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
---  even the implied warranty of MERCHAN- TABILITY or FITNESS FOR A
---  PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with SAL.Gen_Unbounded_Definite_Vectors;
-with WisiToken.Semantic_Checks;
-with WisiToken.Syntax_Trees;
-package WisiToken.Productions is
-   use all type Ada.Containers.Count_Type;
-
-   package Recursion_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive, Recursion_Class, Default_Element => None);
-
-   function Image (Item : in Recursion_Arrays.Vector) return String;
-   --  For parse_table
-
-   type Right_Hand_Side is record
-      Tokens    : Token_ID_Arrays.Vector;
-      Recursion : Recursion_Arrays.Vector;
-      --  Recursion for each token. There may be more than one recursion cycle 
for any token,
-      --  but we don't track that.
-
-      Action : WisiToken.Syntax_Trees.Semantic_Action;
-      Check  : WisiToken.Semantic_Checks.Semantic_Check;
-   end record
-   with Dynamic_Predicate =>
-     (Tokens.Length = 0 or Tokens.First_Index = 1) and
-     (Recursion.Length = 0 or
-      (Recursion.First_Index = Tokens.First_Index and Recursion.Last_Index = 
Tokens.Last_Index));
-
-   package RHS_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Natural, Right_Hand_Side, Default_Element => (others => <>));
-
-   type Instance is record
-      LHS  : Token_ID := Invalid_Token_ID;
-      RHSs : RHS_Arrays.Vector;
-   end record;
-
-   package Prod_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_ID, Instance, Default_Element => (others => <>));
-
-   function Constant_Ref_RHS
-     (Grammar : in Prod_Arrays.Vector;
-      ID      : in Production_ID)
-     return RHS_Arrays.Constant_Reference_Type;
-
-   function Image
-     (LHS        : in Token_ID;
-      RHS_Index  : in Natural;
-      RHS        : in Token_ID_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-   --  For comments in generated code, diagnostic messages.
-
-   procedure Put (Grammar : Prod_Arrays.Vector; Descriptor : in 
WisiToken.Descriptor);
-   --  Put Image of each production to Ada.Text_IO.Current_Output, for 
parse_table.
-
-   package Line_Number_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Natural, Line_Number_Type, Default_Element => Invalid_Line_Number);
-
-   type Prod_Source_Line_Map is record
-      Line    : Line_Number_Type := Invalid_Line_Number;
-      RHS_Map : Line_Number_Arrays.Vector;
-   end record;
-
-   package Source_Line_Maps is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_ID, Prod_Source_Line_Map, Default_Element => (others => <>));
-   --  For line numbers of productions in source files.
-
-end WisiToken.Productions;
diff --git a/packages/wisi/wisitoken-semantic_checks.adb 
b/packages/wisi/wisitoken-semantic_checks.adb
deleted file mode 100644
index d69ac77..0000000
--- a/packages/wisi/wisitoken-semantic_checks.adb
+++ /dev/null
@@ -1,152 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Characters.Handling;
-package body WisiToken.Semantic_Checks is
-
-   function Image (Item : in Check_Status; Descriptor : in 
WisiToken.Descriptor) return String
-   is begin
-      case Item.Label is
-      when Ok =>
-         return Check_Status_Label'Image (Item.Label);
-      when Error =>
-         return '(' & Check_Status_Label'Image (Item.Label) & ", " &
-           Image (Item.Begin_Name, Descriptor) & ',' &
-           Image (Item.End_Name, Descriptor) & ')';
-      end case;
-   end Image;
-
-   function Match_Names
-     (Lexer        : access constant WisiToken.Lexer.Instance'Class;
-      Descriptor   : in     WisiToken.Descriptor;
-      Tokens       : in     Recover_Token_Array;
-      Start_Index  : in     Positive_Index_Type;
-      End_Index    : in     Positive_Index_Type;
-      End_Optional : in     Boolean)
-     return Check_Status
-   is
-      Start_Name_Region : constant Buffer_Region :=
-        (if Tokens (Start_Index).Name = Null_Buffer_Region
-         then Tokens (Start_Index).Byte_Region
-         else Tokens (Start_Index).Name);
-      End_Name_Region : constant Buffer_Region :=
-        (if Tokens (End_Index).Name = Null_Buffer_Region
-         then Tokens (End_Index).Byte_Region
-         else Tokens (End_Index).Name);
-
-      function Equal return Boolean
-      is
-         use Ada.Characters.Handling;
-      begin
-         if Descriptor.Case_Insensitive then
-            return To_Lower (Lexer.Buffer_Text (Start_Name_Region)) =
-              To_Lower (Lexer.Buffer_Text (End_Name_Region));
-         else
-            return Lexer.Buffer_Text (Start_Name_Region) = Lexer.Buffer_Text 
(End_Name_Region);
-         end if;
-      end Equal;
-
-   begin
-      if Tokens (Start_Index).Virtual or Tokens (End_Index).Virtual then
-         return (Label => Ok);
-
-      elsif End_Optional then
-         if End_Name_Region = Null_Buffer_Region then
-            return (Label => Ok);
-         elsif Start_Name_Region = Null_Buffer_Region then
-            return (Extra_Name_Error, Tokens (Start_Index), Tokens 
(End_Index));
-         else
-            if Equal then
-               return (Label => Ok);
-            else
-               return (Match_Names_Error, Tokens (Start_Index), Tokens 
(End_Index));
-            end if;
-         end if;
-
-      else
-         if Start_Name_Region = Null_Buffer_Region then
-            if End_Name_Region = Null_Buffer_Region then
-               return (Label => Ok);
-            else
-               return (Extra_Name_Error, Tokens (Start_Index), Tokens 
(End_Index));
-            end if;
-
-         elsif End_Name_Region = Null_Buffer_Region then
-            return (Missing_Name_Error, Tokens (Start_Index), Tokens 
(End_Index));
-
-         else
-            if Equal then
-               return (Label => Ok);
-            else
-               return (Match_Names_Error, Tokens (Start_Index), Tokens 
(End_Index));
-            end if;
-         end if;
-      end if;
-   end Match_Names;
-
-   function Propagate_Name
-     (Nonterm    : in out Recover_Token;
-      Tokens     : in     Recover_Token_Array;
-      Name_Index : in     Positive_Index_Type)
-     return Check_Status
-   is begin
-      if Tokens (Name_Index).Name = Null_Buffer_Region then
-         Nonterm.Name := Tokens (Name_Index).Byte_Region;
-      else
-         Nonterm.Name := Tokens (Name_Index).Name;
-      end if;
-      return (Label => Ok);
-   end Propagate_Name;
-
-   function Merge_Names
-     (Nonterm     : in out Recover_Token;
-      Tokens      : in     Recover_Token_Array;
-      First_Index : in     Positive_Index_Type;
-      Last_Index  : in     Positive_Index_Type)
-     return Check_Status
-   is
-      First_Name : Buffer_Region renames Tokens (First_Index).Name;
-      Last_Name  : Buffer_Region renames Tokens (Last_Index).Name;
-   begin
-      Nonterm.Name :=
-        First_Name and
-          (if Last_Name = Null_Buffer_Region
-           then Tokens (Last_Index).Byte_Region
-           else Last_Name);
-      return (Label => Ok);
-   end Merge_Names;
-
-   function Terminate_Partial_Parse
-     (Partial_Parse_Active    : in Boolean;
-      Partial_Parse_Byte_Goal : in Buffer_Pos;
-      Recover_Active          : in Boolean;
-      Nonterm                 : in Recover_Token)
-     return Check_Status
-   is begin
-      if Partial_Parse_Active and then
-        (not Recover_Active) and then
-        Nonterm.Byte_Region.Last >= Partial_Parse_Byte_Goal
-      then
-         raise WisiToken.Partial_Parse;
-      else
-         return (Label => Ok);
-      end if;
-   end Terminate_Partial_Parse;
-
-end WisiToken.Semantic_Checks;
diff --git a/packages/wisi/wisitoken-semantic_checks.ads 
b/packages/wisi/wisitoken-semantic_checks.ads
deleted file mode 100644
index c55371e..0000000
--- a/packages/wisi/wisitoken-semantic_checks.ads
+++ /dev/null
@@ -1,106 +0,0 @@
---  Abstract :
---
---  Grammar semantic check routines.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Lexer;
-package WisiToken.Semantic_Checks is
-
-   type Check_Status_Label is
-     (Ok,
-      Missing_Name_Error, -- block start has name, required block end name 
missing
-      Extra_Name_Error,   -- block start has no name, end has one
-      Match_Names_Error); -- both names present, but don't match
-
-   subtype Error is Check_Status_Label range Check_Status_Label'Succ (Ok) .. 
Check_Status_Label'Last;
-
-   type Check_Status (Label : Check_Status_Label := Ok) is record
-      case Label is
-      when Ok =>
-         null;
-
-      when Error =>
-         Begin_Name : Recover_Token;
-         End_Name   : Recover_Token;
-      end case;
-   end record;
-
-   subtype Error_Check_Status is Check_Status
-   with Dynamic_Predicate => Error_Check_Status.Label /= Ok;
-
-   function Image (Item : in Check_Status; Descriptor : WisiToken.Descriptor) 
return String;
-
-   type Semantic_Check is access function
-     (Lexer          : access constant WisiToken.Lexer.Instance'Class;
-      Nonterm        : in out Recover_Token;
-      Tokens         : in     Recover_Token_Array;
-      Recover_Active : in     Boolean)
-     return Check_Status;
-   --  Called during parsing and error recovery to implement higher level
-   --  checks, such as block name matching in Ada.
-
-   Null_Check : constant Semantic_Check := null;
-
-   function Match_Names
-     (Lexer        : access constant WisiToken.Lexer.Instance'Class;
-      Descriptor   : in     WisiToken.Descriptor;
-      Tokens       : in     Recover_Token_Array;
-      Start_Index  : in     Positive_Index_Type;
-      End_Index    : in     Positive_Index_Type;
-      End_Optional : in     Boolean)
-     return Check_Status;
-   --  Check that buffer text at Tokens (Start_Index).Name matches buffer
-   --  text at Tokens (End_Index).Name. Comparison is controlled by
-   --  Descriptor.Case_Insensitive.
-
-   function Propagate_Name
-     (Nonterm    : in out Recover_Token;
-      Tokens     : in     Recover_Token_Array;
-      Name_Index : in     Positive_Index_Type)
-     return Check_Status;
-   function Merge_Names
-     (Nonterm     : in out Recover_Token;
-      Tokens      : in     Recover_Token_Array;
-      Name_Index  : in     Positive_Index_Type)
-     return Check_Status
-   renames Propagate_Name;
-   --  Set Nonterm.Name to Tokens (Name_Index).Name, or .Byte_Region, if
-   --  .Name is Null_Buffer_Region. Return Ok.
-
-   function Merge_Names
-     (Nonterm     : in out Recover_Token;
-      Tokens      : in     Recover_Token_Array;
-      First_Index : in     Positive_Index_Type;
-      Last_Index  : in     Positive_Index_Type)
-     return Check_Status;
-   --  Then set Nonterm.Name to the merger of Tokens (First_Index ..
-   --  Last_Index).Name, return Ok.
-   --
-   --  If Tokens (Last_Index).Name is Null_Buffer_Region, use Tokens
-   --  (Last_Index).Byte_Region instead.
-
-   function Terminate_Partial_Parse
-     (Partial_Parse_Active    : in Boolean;
-      Partial_Parse_Byte_Goal : in Buffer_Pos;
-      Recover_Active          : in Boolean;
-      Nonterm                 : in Recover_Token)
-     return Check_Status;
-   pragma Inline (Terminate_Partial_Parse);
-   --  If partial parse is complete, raise Wisitoken.Partial_Parse;
-   --  otherwise return Ok.
-
-end WisiToken.Semantic_Checks;
diff --git a/packages/wisi/wisitoken-syntax_trees-lr_utils.adb 
b/packages/wisi/wisitoken-syntax_trees-lr_utils.adb
deleted file mode 100644
index cf04a80..0000000
--- a/packages/wisi/wisitoken-syntax_trees-lr_utils.adb
+++ /dev/null
@@ -1,939 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019, 2020 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-package body WisiToken.Syntax_Trees.LR_Utils is
-
-   procedure Raise_Programmer_Error
-     (Label      : in String;
-      Descriptor : in WisiToken.Descriptor;
-      Lexer      : in WisiToken.Lexer.Handle;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Terminals  : in WisiToken.Base_Token_Arrays.Vector;
-      Node       : in Node_Index)
-   is
-      Terminal_Index : constant Base_Token_Index := Tree.First_Shared_Terminal 
(Node);
-   begin
-      raise SAL.Programmer_Error with Error_Message
-        (Lexer.File_Name,
-         --  Not clear why we need Line + 1 here, to match Emacs.
-         (if Terminal_Index = Invalid_Token_Index then 1 else Terminals 
(Terminal_Index).Line + 1), 0,
-         Label & ": " &
-           Tree.Image (Node, Descriptor, Include_Children => True, 
Include_RHS_Index => True, Node_Numbers => True));
-   end Raise_Programmer_Error;
-
-   function Count (Container : Constant_List) return Ada.Containers.Count_Type
-   is
-      use Ada.Containers;
-      Result : Count_Type := 0;
-   begin
-      for Item of Container loop
-         Result := Result + 1;
-      end loop;
-      return Result;
-   end Count;
-
-   function Contains (Container : in Constant_List; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      return (for some N of Container => N = Node);
-   end Contains;
-
-   function To_Cursor (Container : in Constant_List; Node : in 
Valid_Node_Index) return Cursor
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Node => Node);
-   end To_Cursor;
-
-   function Contains (Container : in Constant_List; Item : in Cursor) return 
Boolean
-   is begin
-      return (for some N of Container => N = Item.Node);
-   end Contains;
-
-   function First
-     (Tree       : in WisiToken.Syntax_Trees.Tree;
-      Root       : in WisiToken.Node_Index;
-      List_ID    : in WisiToken.Token_ID;
-      Element_ID : in WisiToken.Token_ID)
-     return Node_Index
-   is begin
-      if Root = Invalid_Node_Index then
-         return Invalid_Node_Index;
-      else
-         return Result : Node_Index do
-            Result := Root;
-            loop
-               declare
-                  Children : constant Valid_Node_Index_Array := Tree.Children 
(Result);
-               begin
-                  if Tree.ID (Children (1)) = List_ID then
-                     Result := Children (1);
-                  elsif Tree.ID (Children (1)) = Element_ID then
-                     Result := Children (1);
-                     exit;
-                  else
-                     raise SAL.Programmer_Error;
-                  end if;
-               end;
-            end loop;
-         end return;
-      end if;
-   end First;
-
-   function First (Container : in Constant_List) return Cursor
-   is begin
-      return (Node => First (Container.Tree.all, Container.Root, 
Container.List_ID, Container.Element_ID));
-   end First;
-
-   function Last
-     (Tree : in WisiToken.Syntax_Trees.Tree;
-      Root : in WisiToken.Node_Index)
-     return Node_Index
-   is begin
-      if Root = Invalid_Node_Index then
-         return Invalid_Node_Index;
-      else
-         --  Tree is one of:
-         --
-         --  case a: single element list
-         --  element_list : root
-         --  | element: Last
-         --
-         --  case c: no next
-         --  element_list: root
-         --  | element_list
-         --  | | element:
-         --  | element: Last
-         return Tree.Child (Root, SAL.Base_Peek_Type (Tree.Child_Count 
(Root)));
-      end if;
-   end Last;
-
-   function Last  (Container : in Constant_List) return Cursor
-   is begin
-      return (Node => Last (Container.Tree.all, Container.Root));
-   end Last;
-
-   function Next
-     (Tree       : in Syntax_Trees.Tree;
-      List_ID    : in Token_ID;
-      Element_ID : in Token_ID;
-      Position   : in Node_Index)
-     return Node_Index
-   is begin
-      if Position = Invalid_Node_Index then
-         return Position;
-      else
-         return Result : Node_Index do
-            declare
-               --  Tree is one of:
-               --
-               --  case a: first element, no next
-               --  rhs
-               --  | rhs_item_list
-               --  | | rhs_item: Element
-               --  | action
-               --
-               --  case b: first element, next
-               --  rhs_item_list
-               --  | rhs_item_list
-               --  | | rhs_item: Element
-               --  | rhs_item: next element
-               --
-               --  case c: non-first element, no next
-               --  rhs
-               --  | rhs_item_list : Grand_Parent
-               --  | | rhs_item_list
-               --  | | | rhs_item:
-               --  | | rhs_item: Element
-               --  | action : Aunt
-               --
-               --  case d: non-first element, next
-               --  rhs_item_list
-               --  | rhs_item_list : Grand_Parent
-               --  | | rhs_item_list
-               --  | | | rhs_item:
-               --  | | rhs_item: Element
-               --  | rhs_item: next element : Aunt
-
-               Grand_Parent : constant Node_Index := Tree.Parent (Position, 2);
-
-               Aunts           : constant Valid_Node_Index_Array :=
-                 (if Grand_Parent = Invalid_Node_Index or else Tree.ID 
(Grand_Parent) /= List_ID
-                  then (1 .. 0 => Invalid_Node_Index)
-                  else Tree.Children (Grand_Parent));
-
-               Last_List_Child : SAL.Base_Peek_Type := Aunts'First - 1;
-            begin
-               if Grand_Parent = Invalid_Node_Index or else Tree.ID 
(Grand_Parent) /= List_ID then
-                  --  No next
-                  Result := Invalid_Node_Index;
-               else
-                  for I in Aunts'Range loop
-                     if Tree.ID (Aunts (I)) in List_ID | Element_ID then
-                        Last_List_Child := I;
-                     end if;
-                  end loop;
-
-                  if Last_List_Child = 1 then
-                     --  No next
-                     Result := Invalid_Node_Index;
-                  else
-                     Result := Aunts (Last_List_Child);
-                  end if;
-               end if;
-            end;
-         end return;
-      end if;
-   end Next;
-
-   overriding function Next (Iter : Iterator; Position : Cursor) return Cursor
-   is begin
-      return
-        (Node => Next
-           (Iter.Container.Tree.all, Iter.Container.List_ID, 
Iter.Container.Element_ID, Position.Node));
-   end Next;
-
-   function Previous
-     (Tree     : in Syntax_Trees.Tree;
-      Position : in Node_Index)
-     return Node_Index
-   is begin
-      if Position = Invalid_Node_Index then
-         return Position;
-      else
-         return Result : Node_Index do
-            --  Tree is one of:
-            --
-            --  case a: first element, no prev
-            --  ?
-            --  | rhs_item_list
-            --  | | rhs_item: Element
-            --
-            --  case b: second element
-            --  ?
-            --  | rhs_item_list
-            --  | | rhs_item: prev item
-            --  | rhs_item: Element
-            --
-            --  case c: nth element
-            --  ?
-            --  | rhs_item_list
-            --  | | rhs_item_list
-            --  | | | rhs_item:
-            --  | | rhs_item: prev element
-            --  | rhs_item: Element
-            declare
-               Parent : constant Valid_Node_Index := Tree.Parent (Position);
-            begin
-               if Position = Tree.Child (Parent, 1) then
-                  --  No prev
-                  Result := Invalid_Node_Index;
-
-               else
-                  declare
-                     Prev_Children : constant Valid_Node_Index_Array := 
Tree.Children
-                       (Tree.Child (Parent, 1));
-                  begin
-                     Result := Prev_Children (Prev_Children'Last);
-                  end;
-               end if;
-            end;
-         end return;
-      end if;
-   end Previous;
-
-   overriding function Previous (Iter : Iterator; Position : Cursor) return 
Cursor
-   is begin
-      return (Node => Previous (Iter.Container.Tree.all, Position.Node));
-   end Previous;
-
-   function List_Constant_Ref (Container : aliased in Constant_List'Class; 
Position : in Cursor) return Valid_Node_Index
-   is
-      pragma Unreferenced (Container);
-   begin
-      return Position.Node;
-   end List_Constant_Ref;
-
-   overriding function Next (Iter : in Constant_Iterator; Position : Cursor) 
return Cursor
-   is begin
-      return (Node => Next (Iter.Container.Tree.all, Iter.Container.List_ID, 
Iter.Container.Element_ID, Position.Node));
-   end Next;
-
-   overriding function Previous (Iter : in Constant_Iterator; Position : 
Cursor) return Cursor
-   is begin
-      return (Node => Previous (Iter.Container.Tree.all, Position.Node));
-   end Previous;
-
-   function Find
-     (Container : in Constant_List;
-      Target    : in Valid_Node_Index)
-     return Cursor
-   is begin
-      for Cur in Container.Iterate_Constant loop
-         if Target = Cur.Node then
-            return Cur;
-         end if;
-      end loop;
-      return No_Element;
-   end Find;
-
-   function Find
-     (Container : in Constant_List;
-      Target    : in String;
-      Equal     : in Find_Equal)
-     return Cursor
-   is begin
-      for Cur in Container.Iterate_Constant loop
-         if Equal (Target, Container, Cur.Node) then
-            return Cur;
-         end if;
-      end loop;
-      return No_Element;
-   end Find;
-
-   package body Creators is
-
-      function Create_List
-        (Tree         : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root         :         in     Valid_Node_Index;
-         List_ID      :         in     WisiToken.Token_ID;
-         Element_ID   :         in     WisiToken.Token_ID;
-         Separator_ID :         in     WisiToken.Token_ID)
-        return List
-      is
-         pragma Unreferenced (List_ID); --  checked in precondition.
-
-         Multi_Element_RHS : constant Natural :=
-           (if Tree.Child_Count (Root) = 1
-            then (if Tree.RHS_Index (Root) = 0 then 1 else 0)
-            elsif Tree.Child_Count (Root) in 2 .. 3 --  3 if there is a 
separator
-            then Tree.RHS_Index (Root)
-            else raise SAL.Programmer_Error);
-      begin
-         return
-           (Tree'Access, Root,
-            List_ID           => Tree.ID (Root),
-            One_Element_RHS   => (if Multi_Element_RHS = 0 then 1 else 0),
-            Multi_Element_RHS => Multi_Element_RHS,
-            Element_ID        => Element_ID,
-            Separator_ID      => Separator_ID);
-      end Create_List;
-
-      function Create_List
-        (Tree       : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root       :         in     Valid_Node_Index;
-         List_ID    :         in     WisiToken.Token_ID;
-         Element_ID :         in     WisiToken.Token_ID)
-        return Constant_List
-      is
-         pragma Unreferenced (List_ID); --  in precondition
-      begin
-         return
-           (Tree'Access, Root,
-            List_ID    => Tree.ID (Root),
-            Element_ID => Element_ID);
-      end Create_List;
-
-      function Create_List
-        (Container :         in     Constant_List;
-         Tree      : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root      :         in     Valid_Node_Index)
-        return Constant_List
-      is begin
-         return Create_List (Tree, Root, Container.List_ID, 
Container.Element_ID);
-      end Create_List;
-
-      function Create_List (Container : in out List; Root : in 
Valid_Node_Index) return List
-      is begin
-         return Create_List (Container.Tree.all, Root, Container.List_ID, 
Container.Element_ID, Container.Separator_ID);
-      end Create_List;
-
-      function Create_From_Element
-        (Tree         : aliased in out WisiToken.Syntax_Trees.Tree;
-         Element      :         in     Valid_Node_Index;
-         List_ID      :         in     WisiToken.Token_ID;
-         Element_ID   :         in     WisiToken.Token_ID;
-         Separator_ID :         in     WisiToken.Token_ID)
-        return List
-      is
-         Root : Valid_Node_Index := Tree.Parent (Element);
-      begin
-         loop
-            exit when Tree.Parent (Root) = Invalid_Node_Index or else Tree.ID 
(Tree.Parent (Root)) /= List_ID;
-            Root := Tree.Parent (Root);
-         end loop;
-         return Create_List (Tree, Root, List_ID, Element_ID, Separator_ID);
-      end Create_From_Element;
-
-      function Create_From_Element (Container : in out List; Element : in 
Valid_Node_Index) return List
-      is begin
-         return Create_From_Element
-           (Container.Tree.all, Element, Container.List_ID, 
Container.Element_ID, Container.Separator_ID);
-      end Create_From_Element;
-
-      function Create_From_Element
-        (Tree       : aliased in out WisiToken.Syntax_Trees.Tree;
-         Element    :         in     Valid_Node_Index;
-         List_ID    :         in     WisiToken.Token_ID;
-         Element_ID :         in     WisiToken.Token_ID)
-        return Constant_List
-      is
-         Root : Valid_Node_Index := Tree.Parent (Element);
-      begin
-         loop
-            exit when Tree.Parent (Root) = Invalid_Node_Index or else Tree.ID 
(Tree.Parent (Root)) /= List_ID;
-            Root := Tree.Parent (Root);
-         end loop;
-         return Create_List (Tree, Root, List_ID, Element_ID);
-      end Create_From_Element;
-
-      function Invalid_List (Tree : aliased in out 
WisiToken.Syntax_Trees.Tree) return List
-      is begin
-         return
-           (Tree              => Tree'Access,
-            Root              => Invalid_Node_Index,
-            List_ID           => Invalid_Token_ID,
-            One_Element_RHS   => 0,
-            Multi_Element_RHS => 0,
-            Element_ID        => Invalid_Token_ID,
-            Separator_ID      => Invalid_Token_ID);
-      end Invalid_List;
-
-      function Invalid_List (Tree : aliased in out 
WisiToken.Syntax_Trees.Tree) return Constant_List
-      is begin
-         return
-           (Tree       => Tree'Access,
-            Root       => Invalid_Node_Index,
-            List_ID    => Invalid_Token_ID,
-            Element_ID => Invalid_Token_ID);
-      end Invalid_List;
-
-      function Empty_List
-        (Tree              : aliased in out WisiToken.Syntax_Trees.Tree;
-         List_ID           :         in     WisiToken.Token_ID;
-         Multi_Element_RHS :         in     Natural;
-         Element_ID        :         in     WisiToken.Token_ID;
-         Separator_ID      :         in     WisiToken.Token_ID)
-        return List
-      is begin
-         return
-           (Tree'Access,
-            Root              => Invalid_Node_Index,
-            List_ID           => List_ID,
-            One_Element_RHS   => (if Multi_Element_RHS = 0 then 1 else 0),
-            Multi_Element_RHS => Multi_Element_RHS,
-            Element_ID        => Element_ID,
-            Separator_ID      => Separator_ID);
-      end Empty_List;
-
-      function Empty_List (Container : in out List) return List
-      is begin
-         return Empty_List
-           (Container.Tree.all, Container.List_ID, 
Container.Multi_Element_RHS, Container.Element_ID,
-            Container.Separator_ID);
-      end Empty_List;
-   end Creators;
-
-   procedure Append
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index)
-   is
-      Tree : Syntax_Trees.Tree renames Container.Tree.all;
-   begin
-      if Container.Root = Invalid_Node_Index then
-         Container :=
-           (Container.Tree,
-            List_ID           => Container.List_ID,
-            One_Element_RHS   => Container.One_Element_RHS,
-            Multi_Element_RHS => Container.Multi_Element_RHS,
-            Element_ID        => Container.Element_ID,
-            Separator_ID      => Container.Separator_ID,
-            Root              => Tree.Add_Nonterm
-              (Production     => (Container.List_ID, 
Container.One_Element_RHS),
-               Children       => (1 => New_Element)));
-
-      else
-         --  Adding element Last in spec example
-         declare
-            List_Parent : constant Node_Index         := Tree.Parent 
(Container.Root);
-            Old_Root    : constant Valid_Node_Index   := Container.Root;
-            Child_Index : constant SAL.Base_Peek_Type :=
-              (if List_Parent = Invalid_Node_Index
-               then 0
-               else Tree.Child_Index (List_Parent, Old_Root));
-         begin
-            Container.Root :=
-              Tree.Add_Nonterm
-                (Production     => (Container.List_ID, 
Container.Multi_Element_RHS),
-                 Children       =>
-                   (if Container.Separator_ID = Invalid_Token_ID
-                    then (Old_Root, New_Element)
-                    else (Old_Root, Tree.Add_Terminal 
(Container.Separator_ID), New_Element)));
-
-            if List_Parent = Invalid_Node_Index then
-               if Tree.Root = Old_Root then
-                  Tree.Root := Container.Root;
-               end if;
-
-            else
-               Tree.Replace_Child
-                 (List_Parent,
-                  Child_Index,
-                  Old_Child => Deleted_Child,
-                  New_Child => Container.Root);
-            end if;
-         end;
-      end if;
-   end Append;
-
-   procedure Prepend
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index)
-   is
-      Tree : Syntax_Trees.Tree renames Container.Tree.all;
-   begin
-      if Container.Root = Invalid_Node_Index then
-         Container :=
-           (Container.Tree,
-            List_ID           => Container.List_ID,
-            One_Element_RHS   => Container.One_Element_RHS,
-            Multi_Element_RHS => Container.Multi_Element_RHS,
-            Element_ID        => Container.Element_ID,
-            Separator_ID      => Container.Separator_ID,
-            Root              => Tree.Add_Nonterm
-              (Production     => (Container.List_ID, 
Container.One_Element_RHS),
-               Children       => (1 => New_Element)));
-
-      else
-         --  Inserting element First (with list parent node and separator) in 
spec example
-         declare
-            Old_First  : constant Valid_Node_Index := Container.First.Node;
-            Parent : constant Valid_Node_Index := Tree.Parent (Old_First);
-
-            List_Node : constant Valid_Node_Index := Tree.Add_Nonterm
-              ((Container.List_ID, Container.One_Element_RHS),
-               (1 => New_Element));
-         begin
-            Tree.Set_Children
-              (Node     => Parent,
-               New_ID   => (Container.List_ID, Container.Multi_Element_RHS),
-               Children =>
-                 (if Container.Separator_ID = Invalid_Token_ID
-                  then (List_Node, Old_First)
-                  else (List_Node, Tree.Add_Terminal (Container.Separator_ID), 
Old_First)));
-         end;
-      end if;
-   end Prepend;
-
-   procedure Insert
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index;
-      After       : in     Cursor)
-   is
-      --  Current Tree (see wisitoken_syntax_trees-test.adb Test_Insert_1):
-      --
-      --  list: Tree.Root
-      --  | list = Parent
-      --  | | list
-      --  | | | list
-      --  | | | | element: 1 = First
-      --  | | | separator
-      --  | | | element: 2 = After
-      --  | | separator
-      --  | | element: 3 = Before
-      --  | separator
-      --  | element: 4 = Last
-
-      --  Insert New_Element after 2:
-      --
-      --  list: Tree.Root
-      --  | list
-      --  | | list = Parent
-      --  | | | list: new_list_nonterm
-      --  | | | | list
-      --  | | | | | element: First
-      --  | | | | separator
-      --  | | | | element: After
-      --  | | | separator
-      --  | | | element: new
-      --  | | separator
-      --  | | element: Before
-      --  | separator
-      --  | element: Last
-      Iter   : constant Iterator   := Container.Iterate;
-      Before : constant Node_Index := Iter.Next (After).Node;
-   begin
-      if After.Node = Invalid_Node_Index then
-         Prepend (Container, New_Element);
-      elsif Before = Invalid_Node_Index then
-         Append (Container, New_Element);
-      else
-         declare
-            Parent      : constant Valid_Node_Index := Container.Tree.Parent 
(Before);
-            Old_Child   : constant Valid_Node_Index := Container.Tree.Parent 
(After.Node);
-            Child_Index : constant SAL.Peek_Type    := 
Container.Tree.Child_Index (Parent, Old_Child);
-
-            New_List_Nonterm : constant Valid_Node_Index := 
Container.Tree.Add_Nonterm
-              (Production => (Container.List_ID, Container.Multi_Element_RHS),
-               Children   =>
-                 (if Container.Separator_ID = Invalid_Token_ID
-                  then (Old_Child, New_Element)
-                  else (Old_Child, Container.Tree.Add_Terminal 
(Container.Separator_ID), New_Element)));
-
-         begin
-            --  After = Container.First is not a special case:
-            --
-            --  list: Tree.Root
-            --  | list
-            --  | | list = Parent
-            --  | | | list: new_list_nonterm
-            --  | | | | list
-            --  | | | | | element: First = After
-            --  | | | | separator
-            --  | | | | element: New_Element
-            --  | | | separator
-            --  | | | element: Before
-            --
-            --  Typical case:
-            --
-            --  | | list = Parent
-            --  | | | list: New_list_nonterm
-            --  | | | | | ...
-            --  | | | | separator
-            --  | | | | element: After
-            --  | | | separator
-            --  | | | element: New_Element
-            --  | | separator
-            --  | | element: Before
-
-            Container.Tree.Replace_Child
-              (Parent               => Parent,
-               Child_Index          => Child_Index,
-               Old_Child            => Deleted_Child,
-               New_Child            => New_List_Nonterm,
-               Old_Child_New_Parent => New_List_Nonterm);
-         end;
-      end if;
-   end Insert;
-
-   procedure Copy
-     (Source_List  : in     Constant_List'Class;
-      Source_First : in     Cursor := No_Element;
-      Source_Last  : in     Cursor := No_Element;
-      Dest_List    : in out List'Class)
-   is
-      Source_Iter : constant Constant_Iterator := Source_List.Iterate_Constant;
-
-      Item : Cursor          := (if Source_First = No_Element then 
Source_List.First else Source_First);
-      Last : constant Cursor := (if Source_Last = No_Element then 
Source_List.Last else Source_Last);
-   begin
-      for N of Source_List loop
-         exit when not Has_Element (Item);
-
-         Dest_List.Append (Dest_List.Tree.Copy_Subtree (Item.Node));
-
-         exit when Item = Last;
-
-         Item := Source_Iter.Next (Item);
-      end loop;
-   end Copy;
-
-   procedure Delete
-     (Container : in out List;
-      Item      : in out Cursor)
-   is
-      Tree : Syntax_Trees.Tree renames Container.Tree.all;
-   begin
-      if Container.First = Container.Last then
-         --  result is empty
-         declare
-            List_Parent : constant Node_Index := Tree.Parent (Container.Root);
-         begin
-            if List_Parent = Invalid_Node_Index then
-               if Tree.Root = Container.Root then
-                  Tree.Root := Invalid_Node_Index;
-               end if;
-
-            else
-               Tree.Replace_Child
-                 (List_Parent,
-                  Child_Index => Tree.Child_Index (List_Parent, 
Container.Root),
-                  Old_Child => Container.Root,
-                  New_Child => Deleted_Child);
-            end if;
-            Container.Root := Invalid_Node_Index;
-         end;
-
-      elsif Item = Container.First then
-         --  Before:
-         --
-         --  0011: | List_1: Parent_2
-         --  0009: | | List_0: delete
-         --  0008: | | | Element_0: old First: Item.Node: delete
-         --  0001: | | | | ...
-         --  0002: | | separator?: delete
-         --  0010: | | Element_0: new First
-         --  0003: | | | ...
-
-         --
-         --  After:
-         --
-         --  0011: | List_0: Parent_2
-         --  0010: | | Element_0: new First
-         --  0003: | | | ...
-
-         declare
-            Parent_2 : constant Valid_Node_Index := Tree.Parent (Item.Node, 2);
-         begin
-            Tree.Set_Children
-              (Parent_2,
-               (Container.List_ID, Container.One_Element_RHS),
-               (1 => Tree.Child (Parent_2, (if Container.Separator_ID = 
Invalid_Token_ID then 2 else 3))));
-         end;
-
-      elsif Item = Container.Last then
-         --  Before:
-         --
-         --   ?  ?: List_Parent
-         --  15: | List_1 : Root, delete
-         --  11: | | List_*: New_Root
-         --  10: | | | Element_0
-         --  03: | | ...
-         --  06: | | separator?, delete
-         --  14: | | Element_0 : Last. delete
-         --  07: | | | ...
-
-         --   ?  ?: List_Parent
-         --  11: | List_*: Root
-         --  10: | | Element_0
-         --  03: | ...
-
-         declare
-            List_Parent : constant Node_Index       := Tree.Parent 
(Container.Root);
-            New_Root    : constant Valid_Node_Index := Tree.Child 
(Container.Root, 1);
-         begin
-            if List_Parent = Invalid_Node_Index then
-               Tree.Delete_Parent (New_Root);
-               Container.Root := New_Root;
-
-            else
-               declare
-                  Parent_Index : constant SAL.Peek_Type := Tree.Child_Index 
(List_Parent, Container.Root);
-               begin
-                  Tree.Replace_Child
-                    (List_Parent, Parent_Index,
-                     Old_Child            => Container.Root,
-                     New_Child            => New_Root,
-                     Old_Child_New_Parent => Invalid_Node_Index);
-               end;
-            end if;
-
-            Container.Root := New_Root;
-         end;
-
-      else
-         --  Node numbers from test_lr_utils test case 1.
-         --
-         --  before:
-         --  15: list: Parent_2
-         --  13: | list: Parent_1, Old_Child
-         --  11: | | list: Parent_1_Child_1, New_Child
-         --  09: | | | list:
-         --  08: | | | | element: 1, First
-         --  02: | | | separator?
-         --  10: | | | element: 2
-         --  04: | | separator?
-         --  12: | | element: 3, Item.Node, delete
-         --  06: | separator?
-         --  14: | element: 4, Last
-         --
-         --  after
-         --  15: list: Parent_2
-         --  11: | list: Parent_1_Child_1
-         --  09: | | list:
-         --  08: | | | element: 1, First
-         --  02: | | separator?
-         --  10: | | element: 2
-         --  06: | separator?
-         --  14: | element: 4, Last
-
-         declare
-            Parent_1         : constant Valid_Node_Index := Tree.Parent 
(Item.Node);
-            Parent_2         : constant Valid_Node_Index := Tree.Parent 
(Parent_1);
-            Parent_1_Child_1 : constant Valid_Node_Index := Tree.Child 
(Parent_1, 1);
-         begin
-            Tree.Replace_Child
-              (Parent_2, 1,
-               Old_Child            => Parent_1,
-               New_Child            => Parent_1_Child_1,
-               Old_Child_New_Parent => Invalid_Node_Index);
-         end;
-      end if;
-
-      Item.Node := Invalid_Node_Index;
-   end Delete;
-
-   function Valid_Skip_List (Tree : aliased in out Syntax_Trees.Tree; 
Skip_List : in Skip_Array) return Boolean
-   is begin
-      if Skip_List'Length = 0 then return False; end if;
-
-      if Skip_List (Skip_List'Last).Label /= Skip then return False; end if;
-
-      if (for some I in Skip_List'First .. Skip_List'Last - 1 => Skip_List 
(I).Label /= Nested) then
-         return False;
-      end if;
-
-      for I in Skip_List'First + 1 .. Skip_List'Last loop
-         if Tree.ID (Skip_List (I).Element) /= Skip_List (I - 1).Element_ID 
then
-            return False;
-         end if;
-      end loop;
-
-      if Skip_List'Length > 2 then
-         declare
-            I : constant Positive_Index_Type := Skip_List'Last - 1;
-         begin
-            if Creators.Create_From_Element
-              (Tree, Skip_List (I - 1).Element, Skip_List (I).List_ID, 
Skip_List (I).Element_ID).Count = 1
-            then
-               return False;
-            end if;
-         end;
-      end if;
-
-      return True;
-   end Valid_Skip_List;
-
-   function Copy_Skip_Nested
-     (Source_List       :         in     Constant_List'Class;
-      Skip_List         :         in     Skip_Array;
-      Skip_Found        :         in out Boolean;
-      Tree              : aliased in out Syntax_Trees.Tree;
-      Separator_ID      :         in     Token_ID;
-      Multi_Element_RHS :         in     Natural)
-      return Node_Index
-   is
-      Dest_List : List := Creators.Empty_List
-        (Tree, Source_List.List_ID, Multi_Element_RHS, Source_List.Element_ID, 
Separator_ID);
-
-      function Get_Dest_Child
-        (Node      : in Valid_Node_Index;
-         Skip_List : in Skip_Array)
-        return Valid_Node_Index
-      with Pre => Tree.Is_Nonterm (Node) and
-                  (Skip_List'Length > 1 and then
-                   (Skip_List (Skip_List'First).Label = Nested and Skip_List 
(Skip_List'Last).Label = Skip))
-      is
-         Skip_This : Nested_Skip_Item renames Skip_List (Skip_List'First);
-      begin
-         if Node = Skip_This.List_Root then
-            return Copy_Skip_Nested
-              (Creators.Create_List
-                 (Tree,
-                  Root       => Skip_This.List_Root,
-                  List_ID    => Skip_This.List_ID,
-                  Element_ID => Skip_This.Element_ID),
-               Skip_List (Skip_List'First + 1 .. Skip_List'Last),
-               Skip_Found, Tree, Skip_This.Separator_ID, 
Skip_This.Multi_Element_RHS);
-         else
-            declare
-               Source_Children : constant Valid_Node_Index_Array := 
Tree.Children (Node);
-               Dest_Children   : Valid_Node_Index_Array 
(Source_Children'Range);
-            begin
-               for I in Source_Children'Range loop
-                  if Source_Children (I) = Skip_This.List_Root then
-                     Dest_Children (I) := Copy_Skip_Nested
-                       (Creators.Create_List
-                          (Tree,
-                           Root       => Skip_This.List_Root,
-                           List_ID    => Skip_This.List_ID,
-                           Element_ID => Skip_This.Element_ID),
-                        Skip_List (Skip_List'First + 1 .. Skip_List'Last),
-                        Skip_Found, Tree, Skip_This.Separator_ID, 
Skip_This.Multi_Element_RHS);
-                  else
-                     if Tree.Label (Source_Children (I)) = Nonterm then
-                        Dest_Children (I) := Get_Dest_Child (Source_Children 
(I), Skip_List);
-                     else
-                        Dest_Children (I) := Tree.Copy_Subtree 
(Source_Children (I));
-                     end if;
-                  end if;
-               end loop;
-
-               return Tree.Add_Nonterm (Tree.Production_ID (Node), 
Dest_Children, Tree.Action (Node));
-            end;
-         end if;
-      end Get_Dest_Child;
-
-      Skip_This : Nested_Skip_Item renames Skip_List (Skip_List'First);
-   begin
-      --  See test_lr_utils.adb Test_Copy_Skip for an example.
-      for N of Source_List loop
-         if Skip_This.Element = N then
-            case Skip_This.Label is
-            when Skip =>
-               --  Done nesting; skip this one
-               Skip_Found := True;
-
-            when Nested =>
-               Dest_List.Append (Get_Dest_Child (N, Skip_List));
-            end case;
-         else
-            Dest_List.Append (Tree.Copy_Subtree (N));
-         end if;
-      end loop;
-      return Dest_List.Root;
-   end Copy_Skip_Nested;
-
-   function Copy_Skip_Nested
-     (Skip_List :         in     Skip_Info;
-      Tree      : aliased in out Syntax_Trees.Tree)
-     return Node_Index
-   is
-      Source_List : constant Constant_List := Creators.Create_List
-        (Tree,
-         Root       => Skip_List.Start_List_Root,
-         List_ID    => Skip_List.Start_List_ID,
-         Element_ID => Skip_List.Start_Element_ID);
-
-      Skip_Found : Boolean := False;
-   begin
-      return Result : constant Node_Index := Copy_Skip_Nested
-        (Source_List, Skip_List.Skips, Skip_Found, Tree, 
Skip_List.Start_Separator_ID,
-         Skip_List.Start_Multi_Element_RHS)
-      do
-         if not Skip_Found then
-            raise SAL.Programmer_Error with "Skip not found";
-         end if;
-      end return;
-   end Copy_Skip_Nested;
-
-   function List_Root
-     (Tree    : in Syntax_Trees.Tree;
-      Node    : in Valid_Node_Index;
-      List_ID : in Token_ID)
-     return Valid_Node_Index
-   is
-      Root : Node_Index := Node;
-   begin
-      loop
-         exit when Tree.Parent (Root) = Invalid_Node_Index or else Tree.ID 
(Tree.Parent (Root)) /= List_ID;
-         Root := Tree.Parent (Root);
-      end loop;
-      return Root;
-   end List_Root;
-
-end WisiToken.Syntax_Trees.LR_Utils;
diff --git a/packages/wisi/wisitoken-syntax_trees-lr_utils.ads 
b/packages/wisi/wisitoken-syntax_trees-lr_utils.ads
deleted file mode 100644
index 6f0403c..0000000
--- a/packages/wisi/wisitoken-syntax_trees-lr_utils.ads
+++ /dev/null
@@ -1,475 +0,0 @@
---  Abstract :
---
---  Utilities for navigating syntax trees produced by an LR parser.
---
---  Design :
---
---  It would be safer if Cursor contained a pointer to Iterator; then
---  Copy and Splice could just take Cursor arguments. But that
---  requires mode 'aliased in' for First, Last, which is not
---  conformant with Ada.Iterator_Interfaces.
---
---  Copyright (C) 2019, 2020 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Iterator_Interfaces;
-with SAL.Gen_Unconstrained_Array_Image_Aux;
-package WisiToken.Syntax_Trees.LR_Utils is
-   use all type SAL.Base_Peek_Type;
-
-   procedure Raise_Programmer_Error
-     (Label      : in String;
-      Descriptor : in WisiToken.Descriptor;
-      Lexer      : in WisiToken.Lexer.Handle;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Terminals  : in WisiToken.Base_Token_Arrays.Vector;
-      Node       : in WisiToken.Node_Index);
-   pragma No_Return (Raise_Programmer_Error);
-
-   ----------
-   --  List functions
-   --
-   --  A list has one of the following grammar forms:
-   --
-   --  list : list element | element ;
-   --  list : element | list element ;
-   --
-   --  list : list separator element | element ;
-   --  list : element | list separator element ;
-   --
-   --  In the syntax tree, this looks like:
-   --
-   --  list: Root
-   --  | list
-   --  | | list
-   --  | | | element: First
-   --  | | separator?
-   --  | | element: 2
-   --  | separator?
-   --  | element: 3
-   --  separator?
-   --  element: Last
-
-   type Constant_List (<>) is tagged private with
-     Constant_Indexing => List_Constant_Ref,
-     Default_Iterator  => Iterate_Constant,
-     Iterator_Element  => Valid_Node_Index;
-
-   function Tree (Container : in Constant_List) return Tree_Constant_Reference
-   with Pre => not Container.Is_Invalid;
-
-   function Is_Invalid (Container : in Constant_List) return Boolean;
-
-   function Is_Empty (Container : in Constant_List) return Boolean;
-   --  Returns True if Container is invalid, or if Container is empty
-
-   function Root (Container : in Constant_List) return Node_Index
-   with Pre => not Container.Is_Invalid;
-
-   function List_ID (Container : in Constant_List) return Token_ID
-   with Pre => not Container.Is_Invalid;
-
-   function Element_ID (Container : in Constant_List) return Token_ID
-   with Pre => not Container.Is_Invalid;
-
-   function Count (Container : in Constant_List) return 
Ada.Containers.Count_Type
-   with Pre => not Container.Is_Invalid;
-
-   function Contains (Container : in Constant_List; Node : in 
Valid_Node_Index) return Boolean
-   with Pre => not Container.Is_Invalid;
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function To_Cursor (Container : in Constant_List; Node : in 
Valid_Node_Index) return Cursor
-   with Pre => (not Container.Is_Invalid) and then
-               (Container.Contains (Node) and Container.Tree.ID (Node) = 
Container.Element_ID);
-
-   function Contains (Container : in Constant_List; Item : in Cursor) return 
Boolean
-   with Pre => not Container.Is_Invalid;
-
-   function Has_Element (Cursor : in LR_Utils.Cursor) return Boolean;
-
-   function Node (Cursor : in LR_Utils.Cursor) return Node_Index;
-   --  Invalid_Node_Index if not Has_Element (Cursor).
-
-   function Get_Node (Cursor : in LR_Utils.Cursor) return Node_Index
-     renames Node;
-   --  Useful when Node is hidden by another declaration.
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   type Iterator (Container : not null access constant Constant_List'Class) is
-     new Iterator_Interfaces.Reversible_Iterator
-     with null record;
-
-   function First (Container : in Constant_List) return Cursor;
-   function Last  (Container : in Constant_List) return Cursor;
-
-   overriding function First (Iter : in Iterator) return Cursor is 
(Iter.Container.First);
-   overriding function Last  (Iter : in Iterator) return Cursor is 
(Iter.Container.Last);
-   overriding function Next     (Iter : in Iterator; Position : Cursor) return 
Cursor;
-   overriding function Previous (Iter : in Iterator; Position : Cursor) return 
Cursor;
-
-   function List_Constant_Ref
-     (Container : aliased in Constant_List'Class;
-      Position  :         in Cursor)
-     return Valid_Node_Index;
-
-   type Constant_Iterator (Container : not null access constant Constant_List) 
is new
-     Iterator_Interfaces.Reversible_Iterator
-     with null record;
-
-   overriding function First (Iter : in Constant_Iterator) return Cursor is 
(Iter.Container.First);
-   overriding function Last  (Iter : in Constant_Iterator) return Cursor is 
(Iter.Container.Last);
-   overriding function Next     (Iter : in Constant_Iterator; Position : 
Cursor) return Cursor;
-   overriding function Previous (Iter : in Constant_Iterator; Position : 
Cursor) return Cursor;
-
-   function Iterate_Constant (Container : aliased in Constant_List'Class) 
return Constant_Iterator
-   is (Iterator_Interfaces.Reversible_Iterator with Container'Access);
-
-   type Find_Equal is access function
-     (Target : in String;
-      List   : in Constant_List'Class;
-      Node   : in Valid_Node_Index)
-   return Boolean;
-   --  Function called by Find to compare Target to Node. Target, List
-   --  are the Find arguments; Node is an element of List. Return True if
-   --  Node matches Target.
-
-   function Find
-     (Container : in Constant_List;
-      Target    : in Valid_Node_Index)
-     return Cursor
-   with Pre => not Container.Is_Invalid and Container.Tree.ID (Target) = 
Container.Element_ID;
-
-   function Find
-     (Container : in Constant_List;
-      Target    : in String;
-      Equal     : in Find_Equal)
-     return Cursor
-   with Pre => not Container.Is_Invalid;
-
-   type List (<>) is new Constant_List with private with
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Valid_Node_Index;
-
-   function Separator_ID (Container : in List) return Token_ID
-   with Pre => not Container.Is_Invalid;
-
-   function Iterate (Container : aliased in List'Class) return Iterator
-   is (Iterator_Interfaces.Reversible_Iterator with Container'Access);
-
-   package Creators is
-      --  Nested package so these are not primitive, and don't have to be
-      --  overridden for List.
-
-      function Create_List
-        (Tree         : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root         :         in     Valid_Node_Index;
-         List_ID      :         in     WisiToken.Token_ID;
-         Element_ID   :         in     WisiToken.Token_ID;
-         Separator_ID :         in     WisiToken.Token_ID)
-        return List
-      with Pre => (Tree.Is_Nonterm (Root) and then Tree.Has_Children (Root)) 
and Tree.ID (Root) = List_ID;
-      --  If there is no separator, set Separator_ID = 
WisiToken.Invalid_Token_ID
-      --  The list cannot be empty; use Empty_List for an empty list.
-
-      function Create_List
-        (Tree       : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root       :         in     Valid_Node_Index;
-         List_ID    :         in     WisiToken.Token_ID;
-         Element_ID :         in     WisiToken.Token_ID)
-        return Constant_List
-      with Pre => (Tree.Is_Nonterm (Root) and then Tree.Has_Children (Root)) 
and Tree.ID (Root) = List_ID;
-      --  The separator is only need when adding new elements.
-
-      function Create_List
-        (Container :         in     Constant_List;
-         Tree      : aliased in out WisiToken.Syntax_Trees.Tree;
-         Root      :         in     Valid_Node_Index)
-        return Constant_List
-      with Pre => (Container.Tree.Is_Nonterm (Root) and then
-                   Container.Tree.Has_Children (Root)) and
-                  Container.Tree.ID (Root) = Container.List_ID;
-      --  Same as Create_List, get all other params from Container.
-      --  Need Tree for non-constant view.
-
-      function Create_List (Container : in out List; Root : in 
Valid_Node_Index) return List
-      with Pre => (Container.Tree.Is_Nonterm (Root) and then 
Container.Tree.Has_Children (Root)) and
-                  Container.Tree.ID (Root) = Container.List_ID;
-      --  Same as Create_List, get all other params from Container.
-
-      function Create_From_Element
-        (Tree         : aliased in out WisiToken.Syntax_Trees.Tree;
-         Element      :         in     Valid_Node_Index;
-         List_ID      :         in     WisiToken.Token_ID;
-         Element_ID   :         in     WisiToken.Token_ID;
-         Separator_ID :         in     WisiToken.Token_ID)
-        return List
-      with Pre => Tree.ID (Tree.Parent (Element)) = List_ID and
-                  Tree.ID (Element) = Element_ID and
-                  Tree.ID (Tree.Parent (Element)) = List_ID;
-      --  Same as Create_List, but it first finds the root as an ancestor of
-      --  Element.
-
-      function Create_From_Element (Container : in out List; Element : in 
Valid_Node_Index) return List
-      with Pre => Container.Tree.ID (Container.Tree.Parent (Element)) = 
Container.List_ID and
-                  Container.Tree.ID (Element) = Container.Element_ID and
-                  Container.Tree.ID (Container.Tree.Parent (Element)) = 
Container.List_ID;
-      --  Same as Create_From_Element, get all other params from Container.
-
-      function Create_From_Element
-        (Tree       : aliased in out WisiToken.Syntax_Trees.Tree;
-         Element    :         in     Valid_Node_Index;
-         List_ID    :         in     WisiToken.Token_ID;
-         Element_ID :         in     WisiToken.Token_ID)
-        return Constant_List
-      with Pre => Tree.ID (Tree.Parent (Element)) = List_ID and
-                  Tree.ID (Element) = Element_ID and
-                  Tree.ID (Tree.Parent (Element)) = List_ID;
-      --  Same as Create_List, but it first finds the root as an ancestor of
-      --  Element.
-
-      function Invalid_List (Tree : aliased in out 
WisiToken.Syntax_Trees.Tree) return List;
-      function Invalid_List (Tree : aliased in out 
WisiToken.Syntax_Trees.Tree) return Constant_List;
-      --  First, Last return empty cursor, count returns 0, all other
-      --  operations fail a precondition check.
-      --
-      --  Useful when the result should never be used, but must be present,
-      --  as in a conditional expression.
-
-      function Empty_List
-        (Tree              : aliased in out WisiToken.Syntax_Trees.Tree;
-         List_ID           :         in     WisiToken.Token_ID;
-         Multi_Element_RHS :         in     Natural;
-         Element_ID        :         in     WisiToken.Token_ID;
-         Separator_ID      :         in     WisiToken.Token_ID)
-        return List;
-      --  Result Root returns Invalid_Node_Index; First, Last return empty
-      --  cursor, count returns 0; Append works correctly.
-
-      function Empty_List (Container : in out List) return List;
-      --  Same as Empty_List, get all other params from Container.
-
-   end Creators;
-
-   function Compatible (A, B : in Constant_List'Class) return Boolean;
-   --  True if A and B are not invalid, and all components are the same
-   --  except Root.
-
-   procedure Append
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index)
-   with Pre => not Container.Is_Invalid and then Container.Tree.ID 
(New_Element) = Container.Element_ID;
-   --  Append New_Item to Container, including Container.Separator_ID if
-   --  it is not Invalid_Token_Index.
-   --
-   --  If Container was Empty, or if Container.Root has no parent in
-   --  Tree, the modified list has no parent. Otherwise, the parent of
-   --  Container.Root is updated to hold the new Container.Root.
-
-   procedure Prepend
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index)
-   with Pre => not Container.Is_Invalid and then Container.Tree.ID 
(New_Element) = Container.Element_ID;
-   --  Prepend New_Item to Container, including Container.Separator_ID if
-   --  it is not Invalid_Token_Index.
-   --
-   --  Container.Root parent is unchanged.
-
-   procedure Insert
-     (Container   : in out List;
-      New_Element : in     Valid_Node_Index;
-      After       : in     Cursor)
-   with Pre => not Container.Is_Invalid and then
-               (Container.Tree.ID (New_Element) = Container.Element_ID and
-                (After = No_Element or else Container.Contains (After)));
-   --  Insert New_Item into Container after Ater, including
-   --  Container.Separator_ID if it is not Invalid_Token_Index.
-   --
-   --  If After is No_Element, calls Prepend.
-   --
-   --  If Container was Empty, or if Container.Root has no parent, the
-   --  modified list has no parent. Otherwise, if After is
-   --  Container.Last, the parent of Container.Root is updated to hold
-   --  the new Container.Root.
-
-   procedure Copy
-     (Source_List  : in     Constant_List'Class;
-      Source_First : in     Cursor := No_Element;
-      Source_Last  : in     Cursor := No_Element;
-      Dest_List    : in out List'Class)
-   with Pre => Compatible (Source_List, Dest_List);
-   --  Deep copy slice of Source_List, appending to Dest_List.
-   --
-   --  If First = No_Element, copy from List.First.
-   --  If Last = No_Element, copy thru List.Last.
-
-   procedure Delete
-     (Container : in out List;
-      Item      : in out Cursor)
-   with Pre => Container.Contains (Item);
-   --  Delete Item from Container. Parent of Container.Root is updated
-   --  appropriately. Cursor is set to No_Element.
-
-   type Skip_Label is (Nested, Skip);
-
-   type Skip_Item (Label : Skip_Label := Skip_Label'First) is
-   record
-      Element : Valid_Node_Index;
-      case Label is
-      when Nested =>
-         --  Element is an element in the list currently being copied
-         --  containing a nested list with an element to skip (given by Element
-         --  in the next Skip_Item). The nested list is defined by:
-         List_Root         : Valid_Node_Index;
-         List_ID           : Token_ID;
-         Element_ID        : Token_ID;
-         Separator_ID      : Token_ID;
-         Multi_Element_RHS : Natural;
-
-      when Skip =>
-         --  Element is the element in the current list to skip.
-         null;
-      end case;
-   end record;
-   subtype Nested_Skip_Item is Skip_Item (Nested);
-
-   function Image (Item : in Skip_Item; Descriptor : in WisiToken.Descriptor) 
return String
-   is ("(" & Item.Label'Image & ", " & Item.Element'Image &
-         (case Item.Label is
-          when Nested => "," & Item.List_Root'Image & ", " & Image 
(Item.List_ID, Descriptor),
-          when Skip => "") &
-         ")");
-
-   type Skip_Array is array (Positive_Index_Type range <>) of Skip_Item;
-
-   type Skip_Info (Skip_Last : SAL.Base_Peek_Type) is
-   record
-      --  Skip_Last may be Positive_Index_Type'First - 1 to indicate an
-      --  empty or invalid skip list.
-      Start_List_Root         : Valid_Node_Index := Valid_Node_Index'Last;
-      Start_List_ID           : Token_ID         := Invalid_Token_ID;
-      Start_Element_ID        : Token_ID         := Invalid_Token_ID;
-      Start_Separator_ID      : Token_ID         := Invalid_Token_ID;
-      Start_Multi_Element_RHS : Natural          := 0;
-      Skips                   : Skip_Array (Positive_Index_Type'First .. 
Skip_Last);
-   end record;
-
-   function Image is new SAL.Gen_Unconstrained_Array_Image_Aux
-     (Positive_Index_Type, Skip_Item, Skip_Array, WisiToken.Descriptor, Image);
-
-   function Image (Item : in Skip_Info; Descriptor : in WisiToken.Descriptor) 
return String
-   is ("(" &
-         (if Item.Start_List_ID = Invalid_Token_ID
-          then ""
-          else Item.Start_List_Root'Image & ", " & Image (Item.Start_List_ID, 
Descriptor) & ", " &
-             Image (Item.Skips, Descriptor))
-         & ")");
-
-   function Valid_Skip_List (Tree : aliased in out Syntax_Trees.Tree; 
Skip_List : in Skip_Array) return Boolean;
-   --  The last element must be Skip, preceding elements must all be
-   --  Nested. The Element in each array element must have ID = preceding
-   --  Element_ID. The net result of all skips must not be empty, unless
-   --  there is only one item (Skip); Start_List_Root may contain only
-   --  that.
-
-   function Copy_Skip_Nested
-     (Skip_List :         in     Skip_Info;
-      Tree      : aliased in out Syntax_Trees.Tree)
-     return Node_Index
-   with Pre => Skip_List.Start_List_ID /= Invalid_Token_ID and then
-               (Valid_Skip_List (Tree, Skip_List.Skips) and
-                Skip_List.Start_List_ID /= Skip_List.Start_Element_ID);
-   --  Copy list rooted at Skip_List.Start_List, skipping one element as
-   --  indicated by Skip_List.Skip. Return root of copied list.
-   --
-   --  Result is Invalid_Node_Index (indicating an empty list) if
-   --  Skip_List has only one item (Skip), and Skip_List.Start_List_Root
-   --  has only that item.
-   --
-   --  Raises SAL.Programmer_Error if skip item described by Skip_List is
-   --  not found.
-
-   function List_Root
-     (Tree    : in Syntax_Trees.Tree;
-      Node    : in Valid_Node_Index;
-      List_ID : in Token_ID)
-     return Valid_Node_Index
-   with Pre => Tree.ID (Node) = List_ID;
-
-private
-   type Cursor is record
-      Node : Node_Index;
-   end record;
-
-   No_Element : constant Cursor := (Node => Invalid_Node_Index);
-
-   type Constant_List (Tree : not null access WisiToken.Syntax_Trees.Tree) is 
tagged
-     --  We'd prefer to have Tree be 'constant' here, but then it would
-     --  also be constant in List, where we _don't_ want that. An
-     --  alternative design would be to not derive List from Constant_List;
-     --  then we would would have to duplicate all operations.
-   record
-      Root       : WisiToken.Node_Index;
-      List_ID    : WisiToken.Token_ID;
-      Element_ID : WisiToken.Token_ID;
-   end record;
-
-   type List is new Constant_List with
-   record
-      One_Element_RHS   : Natural;
-      Multi_Element_RHS : Natural;
-      Separator_ID      : WisiToken.Token_ID;
-   end record;
-
-   function Tree (Container : in Constant_List) return Tree_Constant_Reference
-   is (Element => Container.Tree);
-
-   function Is_Invalid (Container : in Constant_List) return Boolean
-   is (Container.List_ID = Invalid_Token_ID);
-
-   function Is_Empty (Container : in Constant_List) return Boolean
-   is (Container.Root = Invalid_Node_Index);
-
-   function Root (Container : in Constant_List) return Node_Index
-   is (Container.Root);
-
-   function List_ID (Container : in Constant_List) return Token_ID
-   is (Container.List_ID);
-
-   function Element_ID (Container : in Constant_List) return Token_ID
-   is (Container.Element_ID);
-
-   function Has_Element (Cursor : in LR_Utils.Cursor) return Boolean
-   is (Cursor.Node /= Invalid_Node_Index);
-
-   function Node (Cursor : in LR_Utils.Cursor) return Node_Index
-   is (Cursor.Node);
-
-   function Separator_ID (Container : in List) return Token_ID
-   is (Container.Separator_ID);
-
-   function Compatible (A, B : in Constant_List'Class) return Boolean
-   is
-     (A.Tree = B.Tree and
-        A.List_ID /= Invalid_Token_ID and
-        B.List_ID /= Invalid_Token_ID and
-        A.List_ID = B.List_ID and
-        A.Element_ID = B.Element_ID);
-
-end WisiToken.Syntax_Trees.LR_Utils;
diff --git a/packages/wisi/wisitoken-syntax_trees.adb 
b/packages/wisi/wisitoken-syntax_trees.adb
deleted file mode 100644
index 0a38ae7..0000000
--- a/packages/wisi/wisitoken-syntax_trees.adb
+++ /dev/null
@@ -1,2111 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Text_IO;
-with SAL.Generic_Decimal_Image;
-package body WisiToken.Syntax_Trees is
-
-   --  Body specs, alphabetical, as needed
-
-   function Image
-     (Tree              : in Syntax_Trees.Tree;
-      N                 : in Syntax_Trees.Node;
-      Node_Index        : in Valid_Node_Index;
-      Descriptor        : in WisiToken.Descriptor;
-      Include_Children  : in Boolean;
-      Include_RHS_Index : in Boolean := False;
-      Node_Numbers      : in Boolean := False)
-     return String;
-
-   procedure Move_Branch_Point (Tree : in out Syntax_Trees.Tree; Required_Node 
: in Valid_Node_Index);
-
-   type Visit_Parent_Mode is (Before, After);
-
-   function Process_Tree
-     (Tree         : in Syntax_Trees.Tree;
-      Node         : in Valid_Node_Index;
-      Visit_Parent : in Visit_Parent_Mode;
-      Process_Node : access function
-        (Tree : in Syntax_Trees.Tree;
-         Node : in Valid_Node_Index)
-        return Boolean)
-     return Boolean;
-   --  Call Process_Node on nodes in tree rooted at Node. Return when
-   --  Process_Node returns False (Process_Tree returns False), or when
-   --  all nodes have been processed (Process_Tree returns True).
-
-   procedure Set_Children
-     (Tree     : in out Syntax_Trees.Tree;
-      Parent   : in     Valid_Node_Index;
-      Children : in     Valid_Node_Index_Array);
-
-   ----------
-   --  Public and body operations, alphabetical
-
-   function Action
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Semantic_Action
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).Action
-         else Tree.Branched_Nodes (Node).Action);
-   end Action;
-
-   procedure Add_Child
-     (Tree   : in out Syntax_Trees.Tree;
-      Parent : in     Valid_Node_Index;
-      Child  : in     Valid_Node_Index)
-   is
-      Node : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Parent);
-   begin
-      Node.Children.Append (Child);
-      Tree.Shared_Tree.Nodes (Child).Parent := Parent;
-   end Add_Child;
-
-   function Add_Identifier
-     (Tree        : in out Syntax_Trees.Tree;
-      ID          : in     Token_ID;
-      Identifier  : in     Identifier_Index;
-      Byte_Region : in     WisiToken.Buffer_Region)
-     return Valid_Node_Index
-   is begin
-      Tree.Shared_Tree.Nodes.Append
-        ((Label       => Virtual_Identifier,
-          Byte_Region => Byte_Region,
-          ID          => ID,
-          Identifier  => Identifier,
-          others      => <>));
-      Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-      return Tree.Last_Shared_Node;
-   end Add_Identifier;
-
-   function Add_Nonterm
-     (Tree            : in out Syntax_Trees.Tree;
-      Production      : in     WisiToken.Production_ID;
-      Children        : in     Valid_Node_Index_Array;
-      Action          : in     Semantic_Action := null;
-      Default_Virtual : in     Boolean         := False)
-     return Valid_Node_Index
-   is
-      Nonterm_Node : Valid_Node_Index;
-   begin
-      if Tree.Flush then
-         Tree.Shared_Tree.Nodes.Append
-           ((Label      => Syntax_Trees.Nonterm,
-             ID         => Production.LHS,
-             Action     => Action,
-             RHS_Index  => Production.RHS,
-             Virtual    => (if Children'Length = 0 then Default_Virtual else 
False),
-             others     => <>));
-         Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-         Nonterm_Node          := Tree.Last_Shared_Node;
-      else
-         Tree.Branched_Nodes.Append
-           ((Label     => Syntax_Trees.Nonterm,
-             ID        => Production.LHS,
-             Action    => Action,
-             RHS_Index => Production.RHS,
-             Virtual   => (if Children'Length = 0 then Default_Virtual else 
False),
-             others    => <>));
-         Nonterm_Node := Tree.Branched_Nodes.Last_Index;
-      end if;
-
-      if Children'Length = 0 then
-         return Nonterm_Node;
-      end if;
-
-      Set_Children (Tree, Nonterm_Node, Children);
-
-      return Nonterm_Node;
-   end Add_Nonterm;
-
-   function Add_Terminal
-     (Tree      : in out Syntax_Trees.Tree;
-      Terminal  : in     Token_Index;
-      Terminals : in     Base_Token_Arrays.Vector)
-     return Valid_Node_Index
-   is begin
-      if Tree.Flush then
-         Tree.Shared_Tree.Nodes.Append
-           ((Label       => Shared_Terminal,
-             ID          => Terminals (Terminal).ID,
-             Byte_Region => Terminals (Terminal).Byte_Region,
-             Terminal    => Terminal,
-             others      => <>));
-         Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-         return Tree.Last_Shared_Node;
-      else
-         Tree.Branched_Nodes.Append
-           ((Label       => Shared_Terminal,
-             ID          => Terminals (Terminal).ID,
-             Byte_Region => Terminals (Terminal).Byte_Region,
-             Terminal    => Terminal,
-             others      => <>));
-         return Tree.Branched_Nodes.Last_Index;
-      end if;
-   end Add_Terminal;
-
-   function Add_Terminal
-     (Tree     : in out Syntax_Trees.Tree;
-      Terminal : in     Token_ID;
-      Before   : in     Base_Token_Index := Invalid_Token_Index)
-     return Valid_Node_Index
-   is begin
-      if Tree.Flush then
-         Tree.Shared_Tree.Nodes.Append
-           ((Label  => Virtual_Terminal,
-             ID     => Terminal,
-             Before => Before,
-             others => <>));
-         Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-         return Tree.Last_Shared_Node;
-      else
-         Tree.Branched_Nodes.Append
-           ((Label  => Virtual_Terminal,
-             ID     => Terminal,
-             Before => Before,
-             others => <>));
-         return Tree.Branched_Nodes.Last_Index;
-      end if;
-   end Add_Terminal;
-
-   function Before
-     (Tree             : in Syntax_Trees.Tree;
-      Virtual_Terminal : in Valid_Node_Index)
-     return Base_Token_Index
-   is begin
-      if Tree.Flush then
-         return Tree.Shared_Tree.Nodes (Virtual_Terminal).Before;
-      else
-         return Tree.Branched_Nodes (Virtual_Terminal).Before;
-      end if;
-   end Before;
-
-   function Augmented
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Base_Token_Class_Access
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Augmented;
-      else
-         return Tree.Branched_Nodes (Node).Augmented;
-      end if;
-   end Augmented;
-
-   function Augmented_Const
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Base_Token_Class_Access_Constant
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Base_Token_Class_Access_Constant (Tree.Shared_Tree.Nodes 
(Node).Augmented);
-      else
-         return Base_Token_Class_Access_Constant (Tree.Branched_Nodes 
(Node).Augmented);
-      end if;
-   end Augmented_Const;
-
-   function Buffer_Region_Is_Empty (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Byte_Region = Null_Buffer_Region;
-      else
-         return Tree.Branched_Nodes (Node).Byte_Region = Null_Buffer_Region;
-      end if;
-   end Buffer_Region_Is_Empty;
-
-   function Byte_Region
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Buffer_Region
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).Byte_Region
-         else Tree.Branched_Nodes (Node).Byte_Region);
-   end Byte_Region;
-
-   function Child
-     (Tree        : in Syntax_Trees.Tree;
-      Node        : in Valid_Node_Index;
-      Child_Index : in Positive_Index_Type)
-     return Node_Index
-   is
-      function Compute (N : in Syntax_Trees.Node) return Node_Index
-      is begin
-         if N.Label /= Nonterm then
-            return Invalid_Node_Index;
-
-         elsif Child_Index in N.Children.First_Index .. N.Children.Last_Index 
then
-            return N.Children (Child_Index);
-         else
-            return Invalid_Node_Index;
-         end if;
-      end Compute;
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         return Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end Child;
-
-   function Child_Count (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Ada.Containers.Count_Type
-   is begin
-      return Tree.Get_Node_Const_Ref (Node).Children.Length;
-   end Child_Count;
-
-   function Child_Index
-     (N     : in Node;
-      Child : in Valid_Node_Index)
-     return SAL.Peek_Type
-   is begin
-      for I in N.Children.First_Index .. N.Children.Last_Index loop
-         if N.Children (I) = Child then
-            return I;
-         end if;
-      end loop;
-      raise SAL.Programmer_Error; -- Should be prevented by precondition
-   end Child_Index;
-
-   function Child_Index
-     (Tree   : in out Syntax_Trees.Tree;
-      Parent : in     Valid_Node_Index;
-      Child  : in     Valid_Node_Index)
-     return SAL.Peek_Type
-   is
-      N : Node_Var_Ref renames Get_Node_Var_Ref (Tree, Parent);
-   begin
-      return Child_Index (N, Child);
-   end Child_Index;
-
-   function Children (N : in Syntax_Trees.Node) return Valid_Node_Index_Array
-   is begin
-      if N.Children.Length = 0 then
-         return (1 .. 0 => <>);
-      else
-         return Result : Valid_Node_Index_Array (N.Children.First_Index .. 
N.Children.Last_Index) do
-            for I in Result'Range loop
-               Result (I) := N.Children (I);
-            end loop;
-         end return;
-      end if;
-   end Children;
-
-   function Children (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Valid_Node_Index_Array
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Children (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Children (Tree.Branched_Nodes (Node));
-      end if;
-   end Children;
-
-   procedure Clear (Tree : in out Syntax_Trees.Base_Tree)
-   is begin
-      Tree.Finalize;
-   end Clear;
-
-   procedure Clear (Tree : in out Syntax_Trees.Tree)
-   is begin
-      if Tree.Shared_Tree.Augmented_Present then
-         for Node of Tree.Branched_Nodes loop
-            if Node.Label = Nonterm then
-               Free (Node.Augmented);
-            end if;
-         end loop;
-      end if;
-      Tree.Shared_Tree.Finalize;
-      Tree.Last_Shared_Node := Invalid_Node_Index;
-      Tree.Branched_Nodes.Clear;
-   end Clear;
-
-   function Copy_Subtree
-     (Tree : in out Syntax_Trees.Tree;
-      Root : in     Valid_Node_Index)
-     return Valid_Node_Index
-   is
-      function Copy_Node
-        (Tree   : in out Syntax_Trees.Tree;
-         Index  : in     Valid_Node_Index;
-         Parent : in     Node_Index)
-        return Valid_Node_Index
-      is begin
-         case Tree.Shared_Tree.Nodes (Index).Label is
-         when Shared_Terminal =>
-            declare
-               Node : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Index);
-            begin
-               Tree.Shared_Tree.Nodes.Append
-                 ((Label       => Shared_Terminal,
-                   ID          => Node.ID,
-                   Byte_Region => Node.Byte_Region,
-                   Parent      => Parent,
-                   State       => Unknown_State,
-                   Augmented   => Node.Augmented,
-                   Terminal    => Node.Terminal));
-            end;
-
-         when Virtual_Terminal =>
-            declare
-               Node : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Index);
-            begin
-               Tree.Shared_Tree.Nodes.Append
-                 ((Label       => Virtual_Terminal,
-                   ID          => Node.ID,
-                   Byte_Region => Node.Byte_Region,
-                   Parent      => Parent,
-                   State       => Unknown_State,
-                   Augmented   => Node.Augmented,
-                   Before      => Node.Before));
-            end;
-
-         when Virtual_Identifier =>
-            declare
-               Node : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Index);
-            begin
-               Tree.Shared_Tree.Nodes.Append
-                 ((Label       => Virtual_Identifier,
-                   ID          => Node.ID,
-                   Byte_Region => Node.Byte_Region,
-                   Parent      => Parent,
-                   State       => Unknown_State,
-                   Augmented   => Node.Augmented,
-                   Identifier  => Node.Identifier));
-            end;
-
-         when Nonterm =>
-            declare
-               Children     : constant Valid_Node_Index_Array := Tree.Children 
(Index);
-               Parent       : Node_Index                      := 
Invalid_Node_Index;
-               New_Children : Valid_Node_Index_Arrays.Vector;
-            begin
-               if Children'Length > 0 then
-                  New_Children.Set_First_Last (Children'First, Children'Last);
-                  for I in Children'Range loop
-                     New_Children (I) := Copy_Node (Tree, Children (I), 
Parent);
-                  end loop;
-               end if;
-
-               declare
-                  Node : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes 
(Index);
-               begin
-                  Tree.Shared_Tree.Nodes.Append
-                    ((Label              => Nonterm,
-                      ID                 => Node.ID,
-                      Byte_Region        => Node.Byte_Region,
-                      Parent             => Parent,
-                      State              => Unknown_State,
-                      Augmented          => Node.Augmented,
-                      Virtual            => Node.Virtual,
-                      RHS_Index          => Node.RHS_Index,
-                      Action             => Node.Action,
-                      Name               => Node.Name,
-                      Children           => New_Children,
-                      Min_Terminal_Index => Node.Min_Terminal_Index));
-               end;
-
-               Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-               Parent := Tree.Last_Shared_Node;
-               for I in New_Children.First_Index .. New_Children.Last_Index 
loop
-                  Tree.Shared_Tree.Nodes (New_Children (I)).Parent := Parent;
-               end loop;
-
-               return Parent;
-            end;
-         end case;
-         Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-         return Tree.Last_Shared_Node;
-      end Copy_Node;
-
-   begin
-      return Copy_Node (Tree, Root, Invalid_Node_Index);
-   end Copy_Subtree;
-
-   function Count_IDs
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return SAL.Base_Peek_Type
-   is
-      function Compute (N : in Syntax_Trees.Node) return SAL.Base_Peek_Type
-      is
-         use all type SAL.Base_Peek_Type;
-      begin
-         return Result : SAL.Base_Peek_Type := 0 do
-            if N.ID = ID then
-               Result := 1;
-            end if;
-            case N.Label is
-            when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-               null;
-            when Nonterm =>
-               for I of N.Children loop
-                  --  We don't check for Deleted_Child here; encountering one 
indicates
-                  --  an error in the user algorithm.
-                  Result := Result + Count_IDs (Tree, I, ID);
-               end loop;
-            end case;
-         end return;
-      end Compute;
-   begin
-      return Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Count_IDs;
-
-   function Count_Terminals
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Integer
-     --  Count_Terminals must return Integer for Get_Terminals,
-     --  Positive_Index_Type for Get_Terminal_IDs.
-   is
-      function Compute (N : in Syntax_Trees.Node) return Integer
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return 1;
-
-         when Nonterm =>
-            return Result : Integer := 0 do
-               for C of N.Children loop
-                  --  This can be called to build a debugging image while 
editing the tree
-                  if C /= Deleted_Child then
-                     Result := Result + Count_Terminals (Tree, C);
-                  end if;
-               end loop;
-            end return;
-         end case;
-      end Compute;
-   begin
-      return Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Count_Terminals;
-
-   procedure Delete_Parent
-     (Tree : in out Syntax_Trees.Tree;
-      Node : in     Valid_Node_Index)
-   is
-      N      : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Node);
-      Parent : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (N.Parent);
-   begin
-      Parent.Children (Child_Index (Parent, Node)) := Deleted_Child;
-
-      if N.Parent = Tree.Root then
-         Tree.Root := Node;
-      end if;
-
-      N.Parent := Invalid_Node_Index;
-   end Delete_Parent;
-
-   function Error_Message
-     (Tree      : in Syntax_Trees.Tree;
-      Terminals : in Base_Token_Array_Access_Constant;
-      Node      : in Valid_Node_Index;
-      File_Name : in String;
-      Message   : in String)
-     return String
-   is
-      First_Terminal : constant Valid_Node_Index  := Tree.First_Terminal 
(Node);
-      Line           : Line_Number_Type  := Line_Number_Type'First;
-      Column         : Ada.Text_IO.Count := Ada.Text_IO.Count'First;
-   begin
-      case Tree.Label (First_Terminal) is
-      when Shared_Terminal =>
-         declare
-            Token : Base_Token renames Terminals.all 
(Tree.First_Shared_Terminal (First_Terminal));
-         begin
-            Line   := Token.Line;
-            Column := Token.Column;
-         end;
-
-      when Virtual_Terminal | Virtual_Identifier =>
-         Line   := Line_Number_Type'First;
-         Column := Ada.Text_IO.Count (Tree.Byte_Region (First_Terminal).First);
-
-      when others =>
-         null;
-      end case;
-      return WisiToken.Error_Message (File_Name, Line, Column, Message);
-   end Error_Message;
-
-   overriding procedure Finalize (Tree : in out Base_Tree)
-   is begin
-      Tree.Traversing  := False;
-      Tree.Parents_Set := False;
-      if Tree.Augmented_Present then
-         for Node of Tree.Nodes loop
-            if Node.Label = Nonterm then
-               Free (Node.Augmented);
-            end if;
-         end loop;
-         Tree.Augmented_Present := False;
-      end if;
-      Tree.Nodes.Finalize;
-   end Finalize;
-
-   overriding procedure Finalize (Tree : in out Syntax_Trees.Tree)
-   is begin
-      if Tree.Last_Shared_Node /= Invalid_Node_Index then
-         --  Tree.Branched_Nodes Augmented are shallow copies of
-         --  Tree.Shared_Tree.Nodes Augmented, so we don't free them there;
-         --  they are freed in Base_Tree.Finalize above.
-         Tree.Branched_Nodes.Finalize;
-         Tree.Last_Shared_Node := Invalid_Node_Index;
-         Tree.Shared_Tree := null;
-      end if;
-   end Finalize;
-
-   function Insert_After
-     (User_Data            : in out User_Data_Type;
-      Tree                 : in     Syntax_Trees.Tree'Class;
-      Token                : in     Valid_Node_Index;
-      Insert_On_Blank_Line : in     Boolean)
-     return Boolean
-   is
-      pragma Unreferenced (User_Data, Tree, Token, Insert_On_Blank_Line);
-   begin
-      return False;
-   end Insert_After;
-
-   function Find_Ancestor
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      ID         : in Token_ID;
-      Max_Parent : in Boolean := False)
-     return Node_Index
-   is
-      N           : Node_Index := Node;
-      Last_Parent : Node_Index := Invalid_Node_Index;
-   begin
-      loop
-         N :=
-           (if N <= Tree.Last_Shared_Node
-            then Tree.Shared_Tree.Nodes (N).Parent
-            else Tree.Branched_Nodes (N).Parent);
-
-         exit when N = Invalid_Node_Index;
-         Last_Parent := N;
-
-         exit when ID =
-           (if N <= Tree.Last_Shared_Node
-            then Tree.Shared_Tree.Nodes (N).ID
-            else Tree.Branched_Nodes (N).ID);
-      end loop;
-
-      return (if Max_Parent then Last_Parent else N);
-   end Find_Ancestor;
-
-   function Find_Ancestor
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      IDs        : in Token_ID_Array;
-      Max_Parent : in Boolean := False)
-     return Node_Index
-   is
-      N           : Node_Index := Node;
-      Last_Parent : Node_Index := Invalid_Node_Index;
-   begin
-      loop
-         N :=
-           (if N <= Tree.Last_Shared_Node
-            then Tree.Shared_Tree.Nodes (N).Parent
-            else Tree.Branched_Nodes (N).Parent);
-
-         exit when N = Invalid_Node_Index;
-         Last_Parent := N;
-
-         exit when
-           (for some ID of IDs => ID =
-              (if N <= Tree.Last_Shared_Node
-               then Tree.Shared_Tree.Nodes (N).ID
-               else Tree.Branched_Nodes (N).ID));
-      end loop;
-      return (if Max_Parent then Last_Parent else N);
-   end Find_Ancestor;
-
-   function Find_Child
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index
-   is
-      function Compute (N : in Syntax_Trees.Node) return Node_Index
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return Invalid_Node_Index;
-         when Nonterm =>
-            for C of N.Children loop
-               if C /= Deleted_Child then
-                  if ID =
-                    (if C <= Tree.Last_Shared_Node
-                     then Tree.Shared_Tree.Nodes (C).ID
-                     else Tree.Branched_Nodes (C).ID)
-                  then
-                     return C;
-                  end if;
-               end if;
-            end loop;
-            return Invalid_Node_Index;
-         end case;
-      end Compute;
-   begin
-      return Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Find_Child;
-
-   function Find_Descendant
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index
-   is
-      Found : Node_Index := Invalid_Node_Index;
-
-      function Process (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-      is
-         Node_ID : constant Token_ID :=
-           (if Node <= Tree.Last_Shared_Node
-            then Tree.Shared_Tree.Nodes (Node).ID
-            else Tree.Branched_Nodes (Node).ID);
-      begin
-         if Node_ID = ID then
-            Found := Node;
-            return False;
-         else
-            return True;
-         end if;
-      end Process;
-
-      Junk : constant Boolean := Process_Tree (Tree, Node, Before, 
Process'Access);
-      pragma Unreferenced (Junk);
-   begin
-      return Found;
-   end Find_Descendant;
-
-   function Find_Descendant
-     (Tree      : in     Syntax_Trees.Tree;
-      Node      : in     Valid_Node_Index;
-      Predicate : access function (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean)
-     return Node_Index
-   is
-      Found : Node_Index := Invalid_Node_Index;
-
-      function Process (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-      is begin
-         if Predicate (Tree, Node) then
-            Found := Node;
-            return False;
-         else
-            return True;
-         end if;
-      end Process;
-
-      Junk : constant Boolean := Process_Tree (Tree, Node, Before, 
Process'Access);
-      pragma Unreferenced (Junk);
-   begin
-      return Found;
-   end Find_Descendant;
-
-   function Find_Sibling
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index
-   is
-      function Compute_2 (N : in Syntax_Trees.Node) return Node_Index
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return Invalid_Node_Index;
-
-         when Nonterm =>
-            for C of N.Children loop
-               if C /= Deleted_Child then
-                  if ID =
-                    (if C <= Tree.Last_Shared_Node
-                     then Tree.Shared_Tree.Nodes (C).ID
-                     else Tree.Branched_Nodes (C).ID)
-                  then
-                     return C;
-                  end if;
-               end if;
-            end loop;
-            return Invalid_Node_Index;
-         end case;
-      end Compute_2;
-
-      function Compute_1 (Parent : in Node_Index) return Node_Index
-      is begin
-         if Parent = Invalid_Node_Index then
-            return Invalid_Node_Index;
-
-         else
-            return Compute_2
-              ((if Parent <= Tree.Last_Shared_Node
-                then Tree.Shared_Tree.Nodes (Parent)
-                else Tree.Branched_Nodes (Parent)));
-         end if;
-      end Compute_1;
-   begin
-      return Compute_1
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node).Parent
-          else Tree.Branched_Nodes (Node).Parent));
-   end Find_Sibling;
-
-   function First_Index (Tree : in Syntax_Trees.Tree) return Node_Index
-   is begin
-      return Tree.Shared_Tree.Nodes.First_Index;
-   end First_Index;
-
-   procedure Flush (Tree : in out Syntax_Trees.Tree)
-   is begin
-      --  This is the opposite of Move_Branch_Point
-      Tree.Shared_Tree.Nodes.Merge (Tree.Branched_Nodes);
-      Tree.Last_Shared_Node := Tree.Shared_Tree.Nodes.Last_Index;
-      Tree.Flush            := True;
-   end Flush;
-
-   function Flushed (Tree : in Syntax_Trees.Tree) return Boolean
-   is begin
-      return Tree.Flush;
-   end Flushed;
-
-   procedure Get_IDs
-     (Tree   : in     Syntax_Trees.Tree;
-      Node   : in     Valid_Node_Index;
-      ID     : in     Token_ID;
-      Result : in out Valid_Node_Index_Array;
-      Last   : in out SAL.Base_Peek_Type)
-   is
-      use all type SAL.Base_Peek_Type;
-
-      procedure Compute (N : in Syntax_Trees.Node)
-      is begin
-         if N.ID = ID then
-            Last := Last + 1;
-            Result (Last) := Node;
-         end if;
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            null;
-         when Nonterm =>
-            for I of N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               Get_IDs (Tree, I, ID, Result, Last);
-            end loop;
-         end case;
-      end Compute;
-   begin
-      Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Get_IDs;
-
-   function Get_IDs
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Valid_Node_Index_Array
-   is
-      Last : SAL.Base_Peek_Type := 0;
-   begin
-      Tree.Shared_Tree.Traversing := True;
-      return Result : Valid_Node_Index_Array (1 .. Count_IDs (Tree, Node, ID)) 
do
-         Get_IDs (Tree, Node, ID, Result, Last);
-         Tree.Shared_Tree.Traversing := False;
-      end return;
-   end Get_IDs;
-
-   procedure Get_Terminals
-     (Tree   : in     Syntax_Trees.Tree;
-      Node   : in     Valid_Node_Index;
-      Result : in out Valid_Node_Index_Array;
-      Last   : in out SAL.Base_Peek_Type)
-   is
-      use all type SAL.Base_Peek_Type;
-
-      procedure Compute (N : in Syntax_Trees.Node)
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            Last := Last + 1;
-            Result (Last) := Node;
-
-         when Nonterm =>
-            for C of N.Children loop
-               --  This is called to build an edited source image while 
editing the tree
-               if C /= Deleted_Child then
-                  Get_Terminals (Tree, C, Result, Last);
-               end if;
-            end loop;
-         end case;
-      end Compute;
-   begin
-      Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Get_Terminals;
-
-   function Get_Terminals (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Valid_Node_Index_Array
-   is
-      Last : SAL.Base_Peek_Type := 0;
-   begin
-      Tree.Shared_Tree.Traversing := True;
-      return Result : Valid_Node_Index_Array (1 .. SAL.Base_Peek_Type 
(Count_Terminals (Tree, Node))) do
-         Get_Terminals (Tree, Node, Result, Last);
-         Tree.Shared_Tree.Traversing := False;
-      end return;
-   end Get_Terminals;
-
-   function First_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   is
-      function Compute (Index : in Valid_Node_Index; N : in Syntax_Trees.Node) 
return Node_Index
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return Index;
-         when Nonterm =>
-            for C of N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               declare
-                  Term : constant Node_Index := First_Terminal (Tree, C);
-               begin
-                  if Term /= Invalid_Node_Index then
-                     return Term;
-                  end if;
-               end;
-            end loop;
-            return Invalid_Node_Index;
-         end case;
-      end Compute;
-   begin
-      return Compute
-        (Node,
-         (if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end First_Terminal;
-
-   procedure Get_Terminal_IDs
-     (Tree   : in     Syntax_Trees.Tree;
-      Node   : in     Valid_Node_Index;
-      Result : in out Token_ID_Array;
-      Last   : in out SAL.Base_Peek_Type)
-   is
-      procedure Compute (N : in Syntax_Trees.Node)
-      is
-         use all type SAL.Base_Peek_Type;
-      begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            Last := Last + 1;
-            Result (Integer (Last)) := N.ID;
-
-         when Nonterm =>
-            for I of N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               Get_Terminal_IDs (Tree, I, Result, Last);
-            end loop;
-         end case;
-      end Compute;
-   begin
-      Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Get_Terminal_IDs;
-
-   function Get_Terminal_IDs (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Token_ID_Array
-   is
-      Last : SAL.Base_Peek_Type := 0;
-   begin
-      Tree.Shared_Tree.Traversing := True;
-      return Result : Token_ID_Array (1 .. Count_Terminals (Tree, Node))  do
-         Get_Terminal_IDs (Tree, Node, Result, Last);
-         Tree.Shared_Tree.Traversing := False;
-      end return;
-   end Get_Terminal_IDs;
-
-   function First_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Token_Index
-   is
-      function Compute (N : in Syntax_Trees.Node) return Base_Token_Index
-      is begin
-         return
-           (case N.Label is
-            when Shared_Terminal => N.Terminal,
-            when Virtual_Terminal |
-              Virtual_Identifier => Invalid_Token_Index,
-            when Nonterm         => N.Min_Terminal_Index);
-      end Compute;
-
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         return Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end First_Shared_Terminal;
-
-   function First_Terminal_ID (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Token_ID
-   is
-      function Compute (N : in Syntax_Trees.Node) return Token_ID
-      is begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return N.ID;
-
-         when Nonterm =>
-            for C of N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               declare
-                  ID : constant Token_ID := First_Terminal_ID (Tree, C);
-               begin
-                  if ID /= Invalid_Token_ID then
-                     return ID;
-                  end if;
-               end;
-            end loop;
-            return Invalid_Token_ID;
-         end case;
-      end Compute;
-   begin
-      return Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end First_Terminal_ID;
-
-   function Has_Branched_Nodes (Tree : in Syntax_Trees.Tree) return Boolean
-   is begin
-      return Tree.Branched_Nodes.Length > 0;
-   end Has_Branched_Nodes;
-
-   function Has_Child
-     (Tree  : in Syntax_Trees.Tree;
-      Node  : in Valid_Node_Index;
-      Child : in Valid_Node_Index)
-     return Boolean
-   is begin
-      for C of Tree.Get_Node_Const_Ref (Node).Children loop
-         if C = Child then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Has_Child;
-
-   function Has_Children (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Children.Length > 0;
-      else
-         return Tree.Branched_Nodes (Node).Children.Length > 0;
-      end if;
-   end Has_Children;
-
-   function Has_Parent (Tree : in Syntax_Trees.Tree; Child : in 
Valid_Node_Index) return Boolean
-   is begin
-      return
-        (if Child <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Child).Parent /= Invalid_Node_Index
-         else Tree.Branched_Nodes (Child).Parent /= Invalid_Node_Index);
-   end Has_Parent;
-
-   function Has_Parent (Tree : in Syntax_Trees.Tree; Children : in 
Valid_Node_Index_Array) return Boolean
-   is begin
-      return
-        (for some Child of Children =>
-           (if Child <= Tree.Last_Shared_Node
-            then Tree.Shared_Tree.Nodes (Child).Parent /= Invalid_Node_Index
-            else Tree.Branched_Nodes (Child).Parent /= Invalid_Node_Index));
-   end Has_Parent;
-
-   function ID
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Token_ID
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).ID
-         else Tree.Branched_Nodes (Node).ID);
-   end ID;
-
-   function Identifier (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Identifier_Index
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).Identifier
-         else Tree.Branched_Nodes (Node).Identifier);
-   end Identifier;
-
-   function Image
-     (Tree         : in Syntax_Trees.Tree;
-      Children     : in Valid_Node_Index_Arrays.Vector;
-      Descriptor   : in WisiToken.Descriptor;
-      Node_Numbers : in Boolean)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result     : Unbounded_String := +"(";
-      Need_Comma : Boolean := False;
-   begin
-      for I of Children loop
-         Result := Result & (if Need_Comma then ", " else "") &
-           (if I = Deleted_Child
-            then "-"
-            else Tree.Image (I, Descriptor, Include_Children => False, 
Node_Numbers => Node_Numbers));
-         Need_Comma := True;
-      end loop;
-      Result := Result & ")";
-      return -Result;
-   end Image;
-
-   function Image
-     (Tree              : in Syntax_Trees.Tree;
-      N                 : in Syntax_Trees.Node;
-      Node_Index        : in Valid_Node_Index;
-      Descriptor        : in WisiToken.Descriptor;
-      Include_Children  : in Boolean;
-      Include_RHS_Index : in Boolean := False;
-      Node_Numbers      : in Boolean := False)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String := +(if Node_Numbers then Image (Node_Index) & 
":" else "");
-   begin
-      case N.Label is
-      when Shared_Terminal =>
-         Result := Result & Trimmed_Image (N.Terminal) & ":";
-
-      when Virtual_Identifier =>
-         Result := Result & Trimmed_Image (N.Identifier) & ";";
-
-      when others =>
-         null;
-      end case;
-
-      Result := Result & "(" & Image (N.ID, Descriptor) &
-        (if Include_RHS_Index and N.Label = Nonterm then "_" & Trimmed_Image 
(N.RHS_Index) else "") &
-        (if N.Byte_Region = Null_Buffer_Region then "" else ", " & Image 
(N.Byte_Region)) & ")";
-
-      if Include_Children and N.Label = Nonterm then
-         Result := Result & " <= " & Image (Tree, N.Children, Descriptor, 
Node_Numbers);
-      end if;
-
-      return -Result;
-   end Image;
-
-   function Image
-     (Tree              : in Syntax_Trees.Tree;
-      Node              : in Valid_Node_Index;
-      Descriptor        : in WisiToken.Descriptor;
-      Include_Children  : in Boolean := False;
-      Include_RHS_Index : in Boolean := False;
-      Node_Numbers      : in Boolean := False)
-     return String
-   is begin
-      return Tree.Image
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)),
-         Node, Descriptor, Include_Children, Include_RHS_Index, Node_Numbers);
-   end Image;
-
-   function Image
-     (Tree       : in Syntax_Trees.Tree;
-      Nodes      : in Valid_Node_Index_Array;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result     : Unbounded_String := +"(";
-      Need_Comma : Boolean := False;
-   begin
-      for I in Nodes'Range loop
-         Result := Result & (if Need_Comma then ", " else "") &
-           Tree.Image (Nodes (I), Descriptor);
-         Need_Comma := True;
-      end loop;
-      Result := Result & ")";
-      return -Result;
-   end Image;
-
-   function Image
-     (Item     : in Node_Sets.Vector;
-      Inverted : in Boolean := False)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String;
-   begin
-      for I in Item.First_Index .. Item.Last_Index loop
-         if (if Inverted then not Item (I) else Item (I)) then
-            Result := Result & Node_Index'Image (I);
-         end if;
-      end loop;
-      return -Result;
-   end Image;
-
-   procedure Initialize
-     (Branched_Tree : in out Syntax_Trees.Tree;
-      Shared_Tree   : in     Base_Tree_Access;
-      Flush         : in     Boolean;
-      Set_Parents   : in     Boolean := False)
-   is begin
-      Branched_Tree :=
-        (Ada.Finalization.Controlled with
-         Shared_Tree      => Shared_Tree,
-         Last_Shared_Node => Shared_Tree.Nodes.Last_Index,
-         Branched_Nodes   => <>,
-         Flush            => Flush,
-         Root             => <>);
-
-      Branched_Tree.Shared_Tree.Parents_Set := Set_Parents;
-   end Initialize;
-
-   function Is_Descendant_Of
-     (Tree       : in Syntax_Trees.Tree;
-      Root       : in Valid_Node_Index;
-      Descendant : in Valid_Node_Index)
-     return Boolean
-   is
-      Node : Node_Index := Descendant;
-   begin
-      loop
-         exit when Node = Invalid_Node_Index;
-         if Node = Root then
-            return True;
-         end if;
-
-         Node := Tree.Parent (Node);
-      end loop;
-      return False;
-   end Is_Descendant_Of;
-
-   function Is_Nonterm (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Label = Nonterm;
-      else
-         return Tree.Branched_Nodes (Node).Label = Nonterm;
-      end if;
-   end Is_Nonterm;
-
-   function Is_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Label = Shared_Terminal;
-      else
-         return Tree.Branched_Nodes (Node).Label = Shared_Terminal;
-      end if;
-   end Is_Shared_Terminal;
-
-   function Is_Virtual_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Label = Virtual_Terminal;
-      else
-         return Tree.Branched_Nodes (Node).Label = Virtual_Terminal;
-      end if;
-   end Is_Virtual_Terminal;
-
-   function Is_Virtual (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is
-      function Compute (N : in Syntax_Trees.Node) return Boolean
-      is begin
-         return N.Label = Virtual_Terminal or (N.Label = Nonterm and then 
N.Virtual);
-      end Compute;
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         return Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end Is_Virtual;
-
-   function Is_Virtual_Identifier (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).Label = Virtual_Identifier
-         else Tree.Branched_Nodes (Node).Label = Virtual_Identifier);
-   end Is_Virtual_Identifier;
-
-   function Label (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Node_Label
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Label;
-      else
-         return Tree.Branched_Nodes (Node).Label;
-      end if;
-   end Label;
-
-   function Last_Index (Tree : in Syntax_Trees.Tree) return Node_Index
-   is begin
-      return
-        (if Tree.Flush
-         then Tree.Shared_Tree.Nodes.Last_Index
-         else Tree.Branched_Nodes.Last_Index);
-   end Last_Index;
-
-   function Last_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Token_Index
-   is
-      --  Max_Terminal_Index is not cached, because it is not needed in 
recover.
-
-      function Compute (N : in Syntax_Trees.Node) return Base_Token_Index
-      is begin
-         case N.Label is
-         when Shared_Terminal =>
-            return N.Terminal;
-
-         when Virtual_Terminal | Virtual_Identifier =>
-            return Invalid_Token_Index;
-
-         when Nonterm =>
-            for C of reverse N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               declare
-                  Last_Term : constant Base_Token_Index := 
Tree.Last_Shared_Terminal (C);
-               begin
-                  if Last_Term /= Invalid_Token_Index then
-                     return Last_Term;
-                  end if;
-               end;
-            end loop;
-            return Invalid_Token_Index;
-         end case;
-      end Compute;
-
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         return Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end Last_Shared_Terminal;
-
-   function Last_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   is
-      N : constant Node_Const_Ref := Tree.Get_Node_Const_Ref (Node);
-   begin
-      case N.Label is
-      when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-         return Node;
-      when Nonterm =>
-         for C of reverse N.Children loop
-            --  Encountering Deleted_Child here is an error in the user 
algorithm.
-            declare
-               Term : constant Node_Index := Last_Terminal (Tree, C);
-            begin
-               if Term /= Invalid_Node_Index then
-                  return Term;
-               end if;
-            end;
-         end loop;
-         return Invalid_Node_Index;
-      end case;
-   end Last_Terminal;
-
-   function Min_Descendant (Nodes : in Node_Arrays.Vector; Node : in 
Valid_Node_Index) return Valid_Node_Index
-   is
-      N : Syntax_Trees.Node renames Nodes (Node);
-   begin
-      case N.Label is
-      when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-         return Node;
-
-      when Nonterm =>
-         declare
-            Min : Node_Index := Node;
-         begin
-            for C of N.Children loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               Min := Node_Index'Min (Min, Min_Descendant (Nodes, C));
-            end loop;
-            return Min;
-         end;
-      end case;
-   end Min_Descendant;
-
-   procedure Move_Branch_Point (Tree : in out Syntax_Trees.Tree; Required_Node 
: in Valid_Node_Index)
-   is begin
-      --  Note that this preserves all stored indices in Branched_Nodes.
-      Tree.Branched_Nodes.Prepend (Tree.Shared_Tree.Nodes, Required_Node, 
Tree.Last_Shared_Node);
-      Tree.Last_Shared_Node := Required_Node - 1;
-   end Move_Branch_Point;
-
-   function Next_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   is
-      use Valid_Node_Index_Arrays;
-      use all type SAL.Base_Peek_Type;
-
-      function First_Child (Node : in Valid_Node_Index) return Node_Index
-      is
-         N : Node_Const_Ref renames Tree.Get_Node_Const_Ref (Node);
-      begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return Node;
-         when Nonterm =>
-            --  Use first non-empty
-            for J in N.Children.First_Index .. N.Children.Last_Index loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               declare
-                  Result : constant Node_Index := First_Child (N.Children (J));
-               begin
-                  if Result /= Invalid_Node_Index then
-                     return Result;
-                  end if;
-               end;
-            end loop;
-            --  All Children are empty
-            return Invalid_Node_Index;
-         end case;
-      end First_Child;
-
-      function Next_Child (Child : in Valid_Node_Index; Node : in Node_Index) 
return Node_Index
-      is begin
-         --  Node is Parent of Child; return node immediately after Child.
-         if Node = Invalid_Node_Index then
-            return Invalid_Node_Index;
-         else
-            declare
-               N : Node_Const_Ref renames Tree.Get_Node_Const_Ref (Node);
-            begin
-               pragma Assert (N.Label = Nonterm);
-               for I in N.Children.First_Index .. N.Children.Last_Index loop
-                  --  Encountering Deleted_Child here is an error in the user 
algorithm.
-                  if N.Children (I) = Child then
-                     --  Use first non-empty next from I + 1.
-                     for J in I + 1 .. N.Children.Last_Index loop
-                        declare
-                           Result : constant Node_Index := First_Child 
(N.Children (J));
-                        begin
-                           if Result /= Invalid_Node_Index then
-                              return Result;
-                           end if;
-                        end;
-                     end loop;
-                     --  All next Children are empty
-                     return Next_Child (Node, N.Parent);
-                  end if;
-               end loop;
-               raise SAL.Programmer_Error;
-            end;
-         end if;
-      end Next_Child;
-
-      N : Node_Const_Ref renames Get_Node_Const_Ref (Tree, Node);
-   begin
-      return Next_Child (Node, N.Parent);
-   end Next_Terminal;
-
-   function Parent
-     (Tree  : in Syntax_Trees.Tree;
-      Node  : in Valid_Node_Index;
-      Count : in Positive := 1)
-     return Node_Index
-   is
-      Result : Node_Index := Node;
-      N      : Natural    := 0;
-   begin
-      loop
-         if Result <= Tree.Last_Shared_Node then
-            Result := Tree.Shared_Tree.Nodes (Result).Parent;
-         else
-            Result := Tree.Branched_Nodes (Result).Parent;
-         end if;
-         N := N + 1;
-         exit when N = Count or Result = Invalid_Node_Index;
-      end loop;
-      return Result;
-   end Parent;
-
-   function Prev_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   is
-      use Valid_Node_Index_Arrays;
-      use all type SAL.Base_Peek_Type;
-
-      function Last_Child (Node : in Valid_Node_Index) return Node_Index
-      is
-         N : Node_Const_Ref renames Tree.Get_Node_Const_Ref (Node);
-      begin
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            return Node;
-         when Nonterm =>
-            --  Use first non-empty from end.
-            for J in reverse N.Children.First_Index .. N.Children.Last_Index 
loop
-               --  Encountering Deleted_Child here is an error in the user 
algorithm.
-               declare
-                  Result : constant Node_Index := Last_Child (N.Children (J));
-               begin
-                  if Result /= Invalid_Node_Index then
-                     return Result;
-                  end if;
-               end;
-            end loop;
-            --  All Children are empty
-            return Invalid_Node_Index;
-         end case;
-      end Last_Child;
-
-      function Prev_Child (Child : in Valid_Node_Index; Node : in Node_Index) 
return Node_Index
-      is begin
-         --  Node is Parent of Child; return node immediately previous to 
Child.
-         if Node = Invalid_Node_Index then
-            return Invalid_Node_Index;
-         else
-            declare
-               N : Node_Const_Ref renames Tree.Get_Node_Const_Ref (Node);
-            begin
-               pragma Assert (N.Label = Nonterm);
-               for I in reverse N.Children.First_Index .. 
N.Children.Last_Index loop
-                  --  Encountering Deleted_Child here is an error in the user 
algorithm.
-                  if N.Children (I) = Child then
-                     --  Use first non-empty from I - 1.
-                     for J in reverse N.Children.First_Index .. I - 1 loop
-                        declare
-                           Result : constant Node_Index := Last_Child 
(N.Children (J));
-                        begin
-                           if Result /= Invalid_Node_Index then
-                              return Result;
-                           end if;
-                        end;
-                     end loop;
-                     --  All previous Children are empty
-                     return Prev_Child (Node, N.Parent);
-                  end if;
-               end loop;
-               raise SAL.Programmer_Error;
-            end;
-         end if;
-      end Prev_Child;
-
-      N : Node_Const_Ref renames Get_Node_Const_Ref (Tree, Node);
-   begin
-      return Prev_Child (Node, N.Parent);
-   end Prev_Terminal;
-
-   procedure Print_Tree
-     (Tree            : in Syntax_Trees.Tree;
-      Descriptor      : in WisiToken.Descriptor;
-      Root            : in Node_Index                   := Invalid_Node_Index;
-      Image_Augmented : in Syntax_Trees.Image_Augmented := null;
-      Image_Action    : in Syntax_Trees.Image_Action    := null)
-   is
-      use Ada.Text_IO;
-
-      Node_Printed : Node_Sets.Vector;
-
-      procedure Print_Node (Node : in Valid_Node_Index; Level : in Integer)
-      is
-         function Image is new SAL.Generic_Decimal_Image (Node_Index);
-
-         N : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Node);
-      begin
-         if Node_Printed (Node) then
-            --  This does not catch all possible tree edit errors, but it does
-            --  catch circles.
-            raise SAL.Programmer_Error with "Print_Tree: invalid tree; loop:" 
& Node_Index'Image (Node);
-         else
-            Node_Printed (Node) := True;
-         end if;
-
-         Put (Image (Node, Width => 4) & ": ");
-         for I in 1 .. Level loop
-            Put ("| ");
-         end loop;
-         Put (Image (Tree, N, Node, Descriptor, Include_Children => False, 
Include_RHS_Index => True));
-         if Image_Augmented /= null and N.Augmented /= null then
-            Put (" - " & Image_Augmented (N.Augmented));
-         end if;
-         if N.Label = Nonterm and then (Image_Action /= null and N.Action /= 
null) then
-            Put (" - " & Image_Action (N.Action));
-         end if;
-
-         New_Line;
-         if N.Label = Nonterm then
-            for Child of N.Children loop
-               if Child = Deleted_Child then
-                  Put ("    : ");
-                  for I in 1 .. Level + 1 loop
-                     Put ("| ");
-                  end loop;
-                  Put_Line (" <deleted>");
-               else
-                  Print_Node (Child, Level + 1);
-               end if;
-            end loop;
-         end if;
-      end Print_Node;
-
-      Print_Root : constant Node_Index := (if Root = Invalid_Node_Index then 
Tree.Root else Root);
-   begin
-      Node_Printed.Set_First_Last (Tree.First_Index, Tree.Last_Index);
-      if Print_Root = Invalid_Node_Index then
-         Put_Line ("<empty tree>");
-      else
-         Print_Node (Print_Root, 0);
-      end if;
-   end Print_Tree;
-
-   function Process_Tree
-     (Tree         : in Syntax_Trees.Tree;
-      Node         : in Valid_Node_Index;
-      Visit_Parent : in Visit_Parent_Mode;
-      Process_Node : access function
-        (Tree : in Syntax_Trees.Tree;
-         Node : in Valid_Node_Index)
-        return Boolean)
-     return Boolean
-   is
-      function Compute (N : in Syntax_Trees.Node) return Boolean
-      is begin
-         if Visit_Parent = Before then
-            if not Process_Node (Tree, Node) then
-               return False;
-            end if;
-         end if;
-
-         if N.Label = Nonterm then
-            for Child of N.Children loop
-               if Child /= Deleted_Child then
-                  if not Process_Tree (Tree, Child, Visit_Parent, 
Process_Node) then
-                     return False;
-                  end if;
-               end if;
-            end loop;
-         end if;
-
-         if Visit_Parent = After then
-            return Process_Node (Tree, Node);
-         else
-            return True;
-         end if;
-      end Compute;
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         return Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         return Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end Process_Tree;
-
-   procedure Process_Tree
-     (Tree         : in out Syntax_Trees.Tree;
-      Node         : in     Valid_Node_Index;
-      Process_Node : access procedure
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index))
-   is
-      procedure Compute (N : in Syntax_Trees.Node)
-      is begin
-         if N.Label = Nonterm then
-            for Child of N.Children loop
-               if Child /= Deleted_Child then
-                  Process_Tree (Tree, Child, Process_Node);
-               end if;
-            end loop;
-         end if;
-
-         Process_Node (Tree, Node);
-      end Compute;
-   begin
-      if Node <= Tree.Last_Shared_Node then
-         Compute (Tree.Shared_Tree.Nodes (Node));
-      else
-         Compute (Tree.Branched_Nodes (Node));
-      end if;
-   end Process_Tree;
-
-   procedure Process_Tree
-     (Tree         : in out Syntax_Trees.Tree;
-      Process_Node : access procedure
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index);
-      Root         : in     Node_Index := Invalid_Node_Index)
-   is begin
-      Tree.Shared_Tree.Traversing := True;
-      Process_Tree (Tree, (if Root = Invalid_Node_Index then Tree.Root else 
Root), Process_Node);
-      Tree.Shared_Tree.Traversing := False;
-   exception
-   when others =>
-      Tree.Shared_Tree.Traversing := False;
-      raise;
-   end Process_Tree;
-
-   function Production_ID
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Production_ID
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then (Tree.Shared_Tree.Nodes (Node).ID, Tree.Shared_Tree.Nodes 
(Node).RHS_Index)
-         else (Tree.Branched_Nodes (Node).ID, Tree.Branched_Nodes 
(Node).RHS_Index));
-   end Production_ID;
-
-   procedure Replace_Child
-     (Tree                 : in out Syntax_Trees.Tree;
-      Parent               : in     Valid_Node_Index;
-      Child_Index          : in     SAL.Peek_Type;
-      Old_Child            : in     Valid_Node_Index;
-      New_Child            : in     Valid_Node_Index;
-      Old_Child_New_Parent : in     Node_Index := Invalid_Node_Index)
-   is
-      N : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Parent);
-   begin
-      N.Children (Child_Index) := New_Child;
-
-      if Old_Child /= Deleted_Child then
-         Tree.Shared_Tree.Nodes (Old_Child).Parent := Old_Child_New_Parent;
-      end if;
-
-      Tree.Shared_Tree.Nodes (New_Child).Parent := Parent;
-   end Replace_Child;
-
-   function RHS_Index
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Natural
-   is begin
-      return
-        (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes (Node).RHS_Index
-         else Tree.Branched_Nodes (Node).RHS_Index);
-   end RHS_Index;
-
-   function Root (Tree : in Syntax_Trees.Tree) return Node_Index
-   is begin
-      return Tree.Root;
-   end Root;
-
-   procedure Set_Node_Identifier
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      ID         : in Token_ID;
-      Identifier : in Identifier_Index)
-   is
-      Current : constant Syntax_Trees.Node := Tree.Shared_Tree.Nodes (Node);
-   begin
-      for C of Current.Children loop
-         if C /= Deleted_Child then
-            Tree.Shared_Tree.Nodes (C).Parent := Invalid_Node_Index;
-         end if;
-      end loop;
-
-      Tree.Shared_Tree.Nodes.Replace_Element
-        (Node,
-         (Label       => Virtual_Identifier,
-          ID          => ID,
-          Identifier  => Identifier,
-          Byte_Region => Current.Byte_Region,
-          Parent      => Current.Parent,
-          State       => Unknown_State,
-          Augmented   => null));
-   end Set_Node_Identifier;
-
-   procedure Set_Parents (Tree : in out Syntax_Trees.Tree)
-   is
-      procedure Set_Parents
-        (Tree   : in out Syntax_Trees.Tree;
-         Node   : in     Valid_Node_Index;
-         Parent : in     Node_Index)
-      is
-         N : Node_Var_Ref renames Tree.Get_Node_Var_Ref (Node);
-      begin
-         N.Parent := Parent;
-         case N.Label is
-         when Shared_Terminal | Virtual_Terminal | Virtual_Identifier =>
-            null;
-
-         when Nonterm =>
-            for C of N.Children loop
-               if C = Deleted_Child then
-                  --  This can only happen if someone calls Set_Parents after 
parents
-                  --  are already set.
-                  raise SAL.Programmer_Error with "encountered Deleted_Child";
-               end if;
-               Set_Parents (Tree, C, Node);
-            end loop;
-         end case;
-      end Set_Parents;
-   begin
-      Set_Parents (Tree, Root (Tree), Invalid_Node_Index);
-      Tree.Shared_Tree.Parents_Set := True;
-   end Set_Parents;
-
-   procedure Set_Root (Tree : in out Syntax_Trees.Tree; Root : in 
Valid_Node_Index)
-   is begin
-      Tree.Root := Root;
-   end Set_Root;
-
-   function Same_Token
-     (Tree_1  : in Syntax_Trees.Tree'Class;
-      Index_1 : in Valid_Node_Index;
-      Tree_2  : in Syntax_Trees.Tree'Class;
-      Index_2 : in Valid_Node_Index)
-     return Boolean
-   is
-      function Compute (N_1, N_2 : in Syntax_Trees.Node) return Boolean
-      is begin
-         return N_1.Label = N_2.Label and
-           N_1.ID = N_2.ID and
-           N_1.Byte_Region = N_2.Byte_Region;
-      end Compute;
-   begin
-      return Compute
-        ((if Index_1 <= Tree_1.Last_Shared_Node
-          then Tree_1.Shared_Tree.Nodes (Index_1)
-          else Tree_1.Branched_Nodes (Index_1)),
-         (if Index_2 <= Tree_2.Last_Shared_Node
-          then Tree_2.Shared_Tree.Nodes (Index_2)
-          else Tree_2.Branched_Nodes (Index_2)));
-   end Same_Token;
-
-   procedure Set_Augmented
-     (Tree  : in out Syntax_Trees.Tree;
-      Node  : in     Valid_Node_Index;
-      Value : in     Base_Token_Class_Access)
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         Tree.Shared_Tree.Nodes (Node).Augmented := Value;
-      else
-         Tree.Branched_Nodes (Node).Augmented := Value;
-      end if;
-      Tree.Shared_Tree.Augmented_Present := True;
-   end Set_Augmented;
-
-   procedure Set_Children
-     (Tree     : in out Syntax_Trees.Tree;
-      Parent   : in     Valid_Node_Index;
-      Children : in     Valid_Node_Index_Array)
-   is
-      N : Node_Var_Ref renames Tree.Get_Node_Var_Ref (Parent);
-
-      Min_Terminal_Index_Set : Boolean := False;
-   begin
-      --  See Design note in spec about Parents, Parent_Set.
-
-      if Tree.Parents_Set then
-         --  Clear current Children.Parent first, in case some are also in new
-         --  children.
-         for C of N.Children loop
-            if C /= WisiToken.Deleted_Child then
-               Tree.Shared_Tree.Nodes (C).Parent := Invalid_Node_Index;
-            end if;
-         end loop;
-      end if;
-
-      N.Children.Set_First_Last (Children'First, Children'Last);
-
-      for I in Children'Range loop
-
-         N.Children (I) := Children (I);
-
-         if Tree.Parents_Set then
-            declare
-               Child_Node : Node renames Tree.Shared_Tree.Nodes (Children (I));
-            begin
-               if Child_Node.Parent /= Invalid_Node_Index then
-                  declare
-                     Other_Parent : Node renames Tree.Shared_Tree.Nodes 
(Child_Node.Parent);
-                     Child_Index  : constant SAL.Base_Peek_Type := 
Syntax_Trees.Child_Index
-                       (Other_Parent, Children (I));
-                  begin
-                     Other_Parent.Children (Child_Index) := 
WisiToken.Deleted_Child;
-                  end;
-               end if;
-
-               Child_Node.Parent := Parent;
-            end;
-         end if;
-
-         declare
-            K : Node_Const_Ref renames Tree.Get_Node_Const_Ref (Children (I));
-         begin
-            N.Virtual := N.Virtual or
-              (case K.Label is
-               when Shared_Terminal                       => False,
-               when Virtual_Terminal | Virtual_Identifier => True,
-               when Nonterm                               => K.Virtual);
-
-            if N.Byte_Region.First > K.Byte_Region.First then
-               N.Byte_Region.First := K.Byte_Region.First;
-            end if;
-
-            if N.Byte_Region.Last < K.Byte_Region.Last then
-               N.Byte_Region.Last := K.Byte_Region.Last;
-            end if;
-
-            if not Min_Terminal_Index_Set then
-               case K.Label is
-               when Shared_Terminal =>
-                  Min_Terminal_Index_Set := True;
-                  N.Min_Terminal_Index   := K.Terminal;
-
-               when Virtual_Terminal | Virtual_Identifier =>
-                  null;
-
-               when Nonterm =>
-                  if K.Min_Terminal_Index /= Invalid_Token_Index then
-                     --  not an empty nonterm
-                     Min_Terminal_Index_Set := True;
-                     N.Min_Terminal_Index   := K.Min_Terminal_Index;
-                  end if;
-               end case;
-            end if;
-         end;
-      end loop;
-   end Set_Children;
-
-   procedure Set_Children
-     (Tree     : in out Syntax_Trees.Tree;
-      Node     : in     Valid_Node_Index;
-      New_ID   : in     WisiToken.Production_ID;
-      Children : in     Valid_Node_Index_Array)
-   is
-      Parent_Node  : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Node);
-   begin
-      if New_ID /= (Parent_Node.ID, Parent_Node.RHS_Index) then
-         Parent_Node.Action := null;
-      end if;
-
-      Parent_Node.ID        := New_ID.LHS;
-      Parent_Node.RHS_Index := New_ID.RHS;
-
-      Set_Children (Tree, Node, Children);
-   end Set_Children;
-
-   procedure Set_State
-     (Tree  : in out Syntax_Trees.Tree;
-      Node  : in     Valid_Node_Index;
-      State : in     State_Index)
-   is begin
-      if Tree.Flush then
-         Tree.Shared_Tree.Nodes (Node).State := State;
-      else
-         if Node <= Tree.Last_Shared_Node then
-            Tree.Shared_Tree.Nodes (Node).State := State;
-         else
-            Tree.Branched_Nodes (Node).State := State;
-         end if;
-      end if;
-   end Set_State;
-
-   procedure Set_Flush_False (Tree : in out Syntax_Trees.Tree)
-   is begin
-      if Tree.Flush then
-         Tree.Flush := False;
-         Tree.Branched_Nodes.Set_First_Last (Tree.Last_Shared_Node + 1, 
Tree.Last_Shared_Node);
-      end if;
-   end Set_Flush_False;
-
-   procedure Set_Name_Region
-     (Tree   : in out Syntax_Trees.Tree;
-      Node   : in     Valid_Node_Index;
-      Region : in     Buffer_Region)
-   is begin
-      if Tree.Flush then
-         Tree.Shared_Tree.Nodes (Node).Name := Region;
-
-      else
-         if Node <= Tree.Last_Shared_Node then
-            Move_Branch_Point (Tree, Node);
-         end if;
-
-         Tree.Branched_Nodes (Node).Name := Region;
-      end if;
-   end Set_Name_Region;
-
-   function Sub_Tree_Root (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Valid_Node_Index
-   is
-      N : Valid_Node_Index := Node;
-   begin
-      loop
-         exit when Tree.Shared_Tree.Nodes (N).Parent = Invalid_Node_Index;
-         N := Tree.Shared_Tree.Nodes (N).Parent;
-      end loop;
-      return N;
-   end Sub_Tree_Root;
-
-   function Terminal (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Base_Token_Index
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).Terminal;
-      else
-         return Tree.Branched_Nodes (Node).Terminal;
-      end if;
-   end Terminal;
-
-   function Traversing (Tree : in Syntax_Trees.Tree) return Boolean
-   is begin
-      return Tree.Shared_Tree.Traversing;
-   end Traversing;
-
-   function Recover_Token
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Recover_Token
-   is
-      function Compute (N : Syntax_Trees.Node) return WisiToken.Recover_Token
-      is begin
-         case N.Label is
-         when Shared_Terminal =>
-            return
-              (ID                 => N.ID,
-               Byte_Region        => N.Byte_Region,
-               Min_Terminal_Index => N.Terminal,
-               Name               => Null_Buffer_Region,
-               Virtual            => False);
-
-         when Virtual_Terminal | Virtual_Identifier =>
-            return
-              (ID                 => N.ID,
-               Byte_Region        => Null_Buffer_Region,
-               Min_Terminal_Index => Invalid_Token_Index,
-               Name               => Null_Buffer_Region,
-               Virtual            => True);
-
-         when Nonterm =>
-            return
-              (ID                 => N.ID,
-               Byte_Region        => N.Byte_Region,
-               Min_Terminal_Index => N.Min_Terminal_Index,
-               Name               => N.Name,
-               Virtual            => N.Virtual);
-         end case;
-      end Compute;
-   begin
-      return Compute
-        ((if Node <= Tree.Last_Shared_Node
-          then Tree.Shared_Tree.Nodes (Node)
-          else Tree.Branched_Nodes (Node)));
-   end Recover_Token;
-
-   function Recover_Token_Array
-     (Tree  : in Syntax_Trees.Tree;
-      Nodes : in Valid_Node_Index_Array)
-     return WisiToken.Recover_Token_Array
-   is begin
-      return Result : WisiToken.Recover_Token_Array (Nodes'First .. 
Nodes'Last) do
-         for I in Result'Range loop
-            Result (I) := Tree.Recover_Token (Nodes (I));
-         end loop;
-      end return;
-   end Recover_Token_Array;
-
-   function State (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Unknown_State_Index
-   is begin
-      if Node <= Tree.Last_Shared_Node then
-         return Tree.Shared_Tree.Nodes (Node).State;
-      else
-         return Tree.Branched_Nodes (Node).State;
-      end if;
-   end State;
-
-   procedure Validate_Tree
-     (Tree          : in out Syntax_Trees.Tree;
-      Terminals     : in     Base_Token_Array_Access_Constant;
-      Descriptor    : in     WisiToken.Descriptor;
-      File_Name     : in     String;
-      Root          : in     Node_Index                 := Invalid_Node_Index;
-      Validate_Node : in     Syntax_Trees.Validate_Node := null)
-   is
-      procedure Process_Node
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index)
-      is
-         use Ada.Text_IO;
-         N : Syntax_Trees.Node renames Tree.Shared_Tree.Nodes (Node);
-         Node_Image_Output : Boolean := False;
-      begin
-         if N.Label = Nonterm then
-            for I in N.Children.First_Index .. N.Children.Last_Index loop
-               if N.Children (I) = Deleted_Child then
-                  if not Node_Image_Output then
-                     Put_Line
-                       (Current_Error,
-                        Tree.Error_Message
-                          (Terminals, Node, File_Name,
-                           Image (Tree, N, Node, Descriptor,
-                                  Include_Children => False,
-                                  Node_Numbers     => True)));
-                     Node_Image_Output := True;
-                  end if;
-                  Put_Line
-                    (Current_Error, Tree.Error_Message
-                       (Terminals, Node, File_Name, "... child" & I'Image & " 
deleted"));
-
-               else
-                  declare
-                     Child_Parent : constant Node_Index := 
Tree.Shared_Tree.Nodes (N.Children (I)).Parent;
-                  begin
-                     if Child_Parent /= Node then
-                        if not Node_Image_Output then
-                           Put_Line
-                             (Current_Error,
-                              Tree.Error_Message
-                                (Terminals, Node, File_Name,
-                                 Image (Tree, N, Node, Descriptor,
-                                        Include_Children => False,
-                                        Node_Numbers     => True)));
-                           Node_Image_Output := True;
-                        end if;
-                        if Child_Parent = Invalid_Node_Index then
-                           Put_Line
-                             (Current_Error, Tree.Error_Message
-                                (Terminals, Node, File_Name, "... child.parent 
invalid"));
-                        else
-                           Put_Line
-                             (Current_Error, Tree.Error_Message
-                                (Terminals, Node, File_Name, "... 
child.parent" & Child_Parent'Image & " incorrect"));
-                        end if;
-                     end if;
-                  end;
-               end if;
-            end loop;
-         end if;
-
-         if Validate_Node /= null then
-            Validate_Node (Tree, Node, Node_Image_Output);
-         end if;
-      end Process_Node;
-
-   begin
-      Process_Tree (Tree, (if Root = Invalid_Node_Index then Tree.Root else 
Root), Process_Node'Access);
-   end Validate_Tree;
-
-end WisiToken.Syntax_Trees;
diff --git a/packages/wisi/wisitoken-syntax_trees.ads 
b/packages/wisi/wisitoken-syntax_trees.ads
deleted file mode 100644
index db29bac..0000000
--- a/packages/wisi/wisitoken-syntax_trees.ads
+++ /dev/null
@@ -1,805 +0,0 @@
---  Abstract :
---
---  Syntax tree type and operations.
---
---  Design :
---
---  There is one syntax tree for each parallel parser. There is one
---  shared Terminals array (provided by the master parser), matching
---  the actual input text.
---
---  Node contains a Parent component, to make it easy to traverse the
---  tree in any direction. However, we do not set the Parent nodes
---  while parsing, to simplify branching the syntax tree for parallel
---  parsing. When a new nonterm is added to a branched tree, if it set
---  the parent component of its children, it would first have to move
---  those children, and all intervening nodes, into the branched tree.
---  Since Shared_Terminals nodes are created before all other nodes
---  (when the lexer is run, to allow Lexer_To_Augmented to store info
---  in the node), that would mean every branched tree is a practically
---  complete copy of the entire tree, significantly slowing down
---  parsing (by a factor of 250 on ada-mode wisi.adb when we did this
---  by mistake!).
---
---  The parent components are set by Set_Parents, which is called by
---  Parser.Execute_Actions before the actions are executed.
---  Fortunately, we don't need the parent components during error
---  recover. After calling Set_Parents (ie, while editing the syntax
---  tree after parse), any functions that modify children or parents
---  update the corresponding links, setting them to Invalid_Node_Index
---  or Deleted_Child as appropriate.
---
---  We provide Base_Tree and Tree in one package, because only Tree
---  needs an API; the only way Base_Tree is accessed is via Tree.
---
---  Base_Tree and Tree are not limited to allow
---  wisitoken-parse-lr-parser_lists.ads Prepend_Copy to copy them. No
---  Adjust is needed; Shared_Tree is shared between parsers, and
---  Augmented pointers are also shared, since during parse they are
---  set only for Shared_Terminals.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with SAL.Gen_Unbounded_Definite_Vectors;
-with WisiToken.Lexer;
-package WisiToken.Syntax_Trees is
-
-   type Base_Tree is new Ada.Finalization.Controlled with private;
-
-   type Base_Tree_Access is access all Base_Tree;
-
-   overriding procedure Finalize (Tree : in out Base_Tree);
-   --  Free any allocated storage.
-
-   function Is_Empty (Tree : in Base_Tree) return Boolean;
-
-   type Tree is new Ada.Finalization.Controlled with private;
-
-   type Tree_Variable_Reference (Element : not null access Tree) is null 
record with
-     Implicit_Dereference => Element;
-
-   type Tree_Constant_Reference (Element : not null access constant Tree) is 
null record with
-     Implicit_Dereference => Element;
-
-   function Is_Empty (Tree : in Syntax_Trees.Tree) return Boolean;
-
-   procedure Initialize
-     (Branched_Tree : in out Tree;
-      Shared_Tree   : in     Base_Tree_Access;
-      Flush         : in     Boolean;
-      Set_Parents   : in     Boolean := False)
-   with Pre => Branched_Tree.Is_Empty and Shared_Tree.Is_Empty;
-   --  Set Branched_Tree to refer to Shared_Tree.
-
-   overriding procedure Finalize (Tree : in out Syntax_Trees.Tree);
-   --  Free any allocated storage.
-
-   type Node_Label is
-     (Shared_Terminal,    -- text is user input, accessed via Parser.Terminals
-      Virtual_Terminal,   -- no text; inserted during error recovery
-      Virtual_Identifier, -- text in user data, created during tree rewrite
-      Nonterm             -- contains terminals/nonterminals/identifiers
-     );
-
-   type User_Data_Type is tagged limited null record;
-   --  Many test languages don't need this, so we default the procedures
-   --  to null.
-
-   type User_Data_Access is access all User_Data_Type'Class;
-
-   procedure Set_Lexer_Terminals
-     (User_Data : in out User_Data_Type;
-      Lexer     : in     WisiToken.Lexer.Handle;
-      Terminals : in     Base_Token_Array_Access_Constant)
-   is null;
-
-   procedure Reset (User_Data : in out User_Data_Type) is null;
-   --  Reset to start a new parse.
-
-   procedure Initialize_Actions
-     (User_Data : in out User_Data_Type;
-      Tree      : in     Syntax_Trees.Tree'Class)
-     is null;
-   --  Called by Execute_Actions, before processing the tree.
-
-   procedure Lexer_To_Augmented
-     (User_Data : in out          User_Data_Type;
-      Tree      : in out          Syntax_Trees.Tree'Class;
-      Token     : in              Base_Token;
-      Lexer     : not null access WisiToken.Lexer.Instance'Class)
-     is null;
-   --  Read auxiliary data from Lexer, do something useful with it.
-   --  Called before parsing, once for each token in the input stream. If
-   --  Token is a grammar token, client can use Tree.Set_Augmented
-   --  (Token.Tree_Node).
-
-   function Insert_After
-     (User_Data            : in out User_Data_Type;
-      Tree                 : in     Syntax_Trees.Tree'Class;
-      Token                : in     Valid_Node_Index;
-      Insert_On_Blank_Line : in     Boolean)
-     return Boolean;
-   --  Return True if ID should be treated as if inserted after the
-   --  previous shared terminal, rather than before the next (which is
-   --  the default). This can affect which line it appears on, which
-   --  affects indentation. Called from Insert_Token.
-   --
-   --  The default implementation always returns False.
-
-   procedure Insert_Token
-     (User_Data : in out User_Data_Type;
-      Tree      : in out Syntax_Trees.Tree'Class;
-      Token     : in     Valid_Node_Index)
-   is null;
-   --  Token was inserted in error recovery; update other tokens and Tree
-   --  as needed. Called from Execute_Actions for each inserted token,
-   --  before processing the syntax tree.
-
-   procedure Delete_Token
-     (User_Data   : in out User_Data_Type;
-      Tree        : in out Syntax_Trees.Tree'Class;
-      Token_Index : in     WisiToken.Token_Index)
-   is null;
-   --  Token at Token_Index was deleted in error recovery; update
-   --  remaining tokens as needed. Called from Execute_Actions for each
-   --  deleted token, before processing the syntax tree.
-
-   procedure Reduce
-     (User_Data : in out User_Data_Type;
-      Tree      : in out Syntax_Trees.Tree'Class;
-      Nonterm   : in     Valid_Node_Index;
-      Tokens    : in     Valid_Node_Index_Array)
-   is null;
-   --  Reduce Tokens to Nonterm. Nonterm.Byte_Region is computed by
-   --  caller.
-
-   type Semantic_Action is access procedure
-     (User_Data : in out User_Data_Type'Class;
-      Tree      : in out Syntax_Trees.Tree;
-      Nonterm   : in     Valid_Node_Index;
-      Tokens    : in     Valid_Node_Index_Array);
-   --  Routines of this type are called by
-   --  WisiToken.LR.Parser.Execute_Actions when it processes a Nonterm
-   --  node in the syntax tree. Tokens are the children of Nonterm.
-
-   Null_Action : constant Semantic_Action := null;
-
-   procedure Clear (Tree : in out Syntax_Trees.Base_Tree);
-   procedure Clear (Tree : in out Syntax_Trees.Tree);
-   --  Delete all Elements and free associated memory; keep results of
-   --  Initialize.
-
-   procedure Flush (Tree : in out Syntax_Trees.Tree);
-   --  Move all nodes in branched part to shared tree, set Flush mode
-   --  True.
-
-   procedure Set_Flush_False (Tree : in out Syntax_Trees.Tree);
-   --  Set Flush mode False; use Flush to set True.
-
-   function Flushed (Tree : in Syntax_Trees.Tree) return Boolean;
-
-   function Copy_Subtree
-     (Tree : in out Syntax_Trees.Tree;
-      Root : in     Valid_Node_Index)
-     return Valid_Node_Index
-   with Pre => Tree.Flushed and Tree.Parents_Set;
-   --  Deep copy (into Tree) subtree of Tree rooted at Root. Return root
-   --  of new subtree; it has no parent.
-   --
-   --  Parents of new child nodes are set. Node index order is preserved.
-   --  References to objects external to tree are shallow copied
-   --  (Terminals, Augmented, Action).
-
-   function Add_Nonterm
-     (Tree            : in out Syntax_Trees.Tree;
-      Production      : in     Production_ID;
-      Children        : in     Valid_Node_Index_Array;
-      Action          : in     Semantic_Action := null;
-      Default_Virtual : in     Boolean         := False)
-     return Valid_Node_Index
-   with Pre => not Tree.Traversing and
-               (for all C of Children => C /= Deleted_Child);
-   --  Add a new Nonterm node, which can be empty. Result points to the
-   --  added node. If Children'Length = 0, set Nonterm.Virtual :=
-   --  Default_Virtual.
-   --
-   --  If Tree.Parents_Set, then Children.Parent are set to the new node,
-   --  and in previous parents of those children (if any), the
-   --  corresponding entry in Children is set to Deleted_Child.
-
-   function Add_Terminal
-     (Tree      : in out Syntax_Trees.Tree;
-      Terminal  : in     Token_Index;
-      Terminals : in     Base_Token_Arrays.Vector)
-     return Valid_Node_Index
-   with Pre => not Tree.Traversing;
-   --  Add a new Terminal node. Terminal must be an index into Terminals.
-   --  Result points to the added node.
-
-   function Add_Terminal
-     (Tree     : in out Syntax_Trees.Tree;
-      Terminal : in     Token_ID;
-      Before   : in     Base_Token_Index := Invalid_Token_Index)
-     return Valid_Node_Index
-   with Pre => not Tree.Traversing;
-   --  Add a new Virtual_Terminal node with no parent. Before is the
-   --  index of the terminal in Terminals that this virtual is inserted
-   --  before during error correction; if Invalid_Token_Index, it is
-   --  inserted during EBNF translation, and there is no such terminal.
-   --  Result points to the added node.
-
-   function Before
-     (Tree             : in Syntax_Trees.Tree;
-      Virtual_Terminal : in Valid_Node_Index)
-     return Base_Token_Index
-   with Pre => Tree.Is_Virtual_Terminal (Virtual_Terminal);
-
-   function Add_Identifier
-     (Tree        : in out Syntax_Trees.Tree;
-      ID          : in     Token_ID;
-      Identifier  : in     Identifier_Index;
-      Byte_Region : in     WisiToken.Buffer_Region)
-     return Valid_Node_Index
-   with Pre => Tree.Flushed and (not Tree.Traversing);
-   --  Add a new Virtual_Identifier node with no parent. Byte_Region
-   --  should point to an area in the source buffer related to the new
-   --  identifier, to aid debugging. Result points to the added node.
-
-   procedure Add_Child
-     (Tree   : in out Syntax_Trees.Tree;
-      Parent : in     Valid_Node_Index;
-      Child  : in     Valid_Node_Index)
-   with
-     Pre => Tree.Flushed and Tree.Parents_Set and (not Tree.Traversing) and
-            Tree.Is_Nonterm (Parent);
-   --  Sets Child.Parent.
-
-   function Child_Index
-     (Tree   : in out Syntax_Trees.Tree;
-      Parent : in     Valid_Node_Index;
-      Child  : in     Valid_Node_Index)
-     return SAL.Peek_Type
-   with Pre => Tree.Has_Child (Parent, Child);
-
-   procedure Replace_Child
-     (Tree                 : in out Syntax_Trees.Tree;
-      Parent               : in     Valid_Node_Index;
-      Child_Index          : in     SAL.Peek_Type;
-      Old_Child            : in     Valid_Node_Index;
-      New_Child            : in     Valid_Node_Index;
-      Old_Child_New_Parent : in     Node_Index := Invalid_Node_Index)
-   with
-     Pre => Tree.Flushed and Tree.Parents_Set and (not Tree.Traversing) and
-            (Tree.Is_Nonterm (Parent) and then
-             (Tree.Child (Parent, Child_Index) = Old_Child and
-              (Old_Child = Deleted_Child or else
-               Tree.Parent (Old_Child) = Parent)));
-   --  In Parent.Children, replace child at Child_Index with New_Child.
-   --  Unless Old_Child is Deleted_Child, set Old_Child.Parent to
-   --  Old_Child_New_Parent (may be Invalid_Node_Index). Unless New_Child
-   --  is Deleted_Child, set New_Child.Parent to Parent.
-   --
-   --  If Old_Child is Deleted_Child, Old_Child_New_Parent should be left
-   --  to default.
-
-   procedure Set_Children
-     (Tree     : in out Syntax_Trees.Tree;
-      Node     : in     Valid_Node_Index;
-      New_ID   : in     WisiToken.Production_ID;
-      Children : in     Valid_Node_Index_Array)
-   with
-     Pre => Tree.Flushed and Tree.Parents_Set and (not Tree.Traversing) and
-            Tree.Is_Nonterm (Node) and
-            (for all C of Children => C /= Deleted_Child);
-   --  If parents of current Node.Children are not Invalid_Node_Index,
-   --  set corresponding entry in those parents to Deleted_Child, then
-   --  set Parent to Invalid_Node_Index.
-   --
-   --  Then set ID of Node to New_ID, and Node.Children to Children; set
-   --  parents of Children to Node.
-   --
-   --  If New_ID /= Tree.Production_ID (Node), Node.Action is set
-   --  to null, because the old Action probably no longer applies.
-
-   procedure Delete_Parent
-     (Tree : in out Syntax_Trees.Tree;
-      Node : in     Valid_Node_Index)
-   with
-     Pre => Tree.Flushed and Tree.Parents_Set and (not Tree.Traversing) and
-            Tree.Parent (Node) /= Invalid_Node_Index;
-   --  Set child in Node.Parent to Deleted_Child. If Node.Parent =
-   --  Tree.Root, set Tree.Root to Node. Set Node.Parent to
-   --  Invalid_Node_Index.
-
-   procedure Set_Node_Identifier
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      ID         : in Token_ID;
-      Identifier : in Identifier_Index)
-   with Pre => Tree.Flushed and Tree.Parents_Set and (not Tree.Traversing) and
-               Tree.Is_Nonterm (Node);
-   --  Set parents of current Node.Children to Invalid_Node_Index.
-   --  Then change Node to a Virtual_Identifier.
-
-   procedure Set_State
-     (Tree  : in out Syntax_Trees.Tree;
-      Node  : in     Valid_Node_Index;
-      State : in     State_Index);
-
-   function State (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Unknown_State_Index;
-
-   function Label (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Node_Label;
-
-   function Child_Count (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Ada.Containers.Count_Type
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function Children (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Valid_Node_Index_Array
-   with Pre => Tree.Is_Nonterm (Node);
-   --  Any children that were cleared by Add_Nonterm are returned as
-   --  Deleted_Child.
-
-   function Child
-     (Tree        : in Syntax_Trees.Tree;
-      Node        : in Valid_Node_Index;
-      Child_Index : in Positive_Index_Type)
-     return Node_Index
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function Has_Branched_Nodes (Tree : in Syntax_Trees.Tree) return Boolean;
-   function Has_Children (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean
-   with Pre => Tree.Is_Nonterm (Node);
-   function Has_Child
-     (Tree  : in Syntax_Trees.Tree;
-      Node  : in Valid_Node_Index;
-      Child : in Valid_Node_Index)
-     return Boolean
-   with Pre => Tree.Is_Nonterm (Node);
-   function Has_Parent (Tree : in Syntax_Trees.Tree; Child : in 
Valid_Node_Index) return Boolean;
-   function Has_Parent (Tree : in Syntax_Trees.Tree; Children : in 
Valid_Node_Index_Array) return Boolean;
-
-   function Buffer_Region_Is_Empty (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-   --  True if contained buffer region is empty; always the case for
-   --  virtual tokens, and for most copied tokens. Use Has_Children or
-   --  Child_Count to see if Node has children.
-
-   function Is_Nonterm (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-   function Is_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-   function Is_Virtual_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-
-   function Is_Virtual (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-   --  Virtual_Terminal, Virtual_Identifier, or Nonterm that contains some 
Virtual tokens.
-
-   function Is_Virtual_Identifier (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean;
-   function Traversing (Tree : in Syntax_Trees.Tree) return Boolean;
-
-   function Parents_Set (Tree : in Syntax_Trees.Tree) return Boolean;
-   procedure Set_Parents (Tree : in out Syntax_Trees.Tree)
-   with Pre => Tree.Flushed and Tree.Root /= Invalid_Node_Index;
-
-   function Parent
-     (Tree  : in Syntax_Trees.Tree;
-      Node  : in Valid_Node_Index;
-      Count : in Positive := 1)
-     return Node_Index
-   with Pre => Tree.Parents_Set;
-   --  Return Count parent of Node.
-
-   procedure Set_Name_Region
-     (Tree   : in out Syntax_Trees.Tree;
-      Node   : in     Valid_Node_Index;
-      Region : in     Buffer_Region)
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function ID
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Token_ID;
-
-   function Production_ID
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Production_ID
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function Byte_Region
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Buffer_Region;
-
-   function RHS_Index
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Natural
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function Same_Token
-     (Tree_1  : in Syntax_Trees.Tree'Class;
-      Index_1 : in Valid_Node_Index;
-      Tree_2  : in Syntax_Trees.Tree'Class;
-      Index_2 : in Valid_Node_Index)
-     return Boolean;
-   --  True if the two tokens have the same ID and Byte_Region.
-
-   function Recover_Token
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return WisiToken.Recover_Token;
-
-   function Recover_Token_Array
-     (Tree  : in Syntax_Trees.Tree;
-      Nodes : in Valid_Node_Index_Array)
-     return WisiToken.Recover_Token_Array;
-
-   procedure Set_Augmented
-     (Tree  : in out Syntax_Trees.Tree;
-      Node  : in     Valid_Node_Index;
-      Value : in     Base_Token_Class_Access);
-   --  Value will be deallocated when Tree is finalized.
-
-   function Augmented
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Base_Token_Class_Access;
-   --  Returns result of Set_Augmented.
-
-   function Augmented_Const
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Base_Token_Class_Access_Constant;
-
-   function Action
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Semantic_Action
-   with Pre => Tree.Is_Nonterm (Node);
-
-   function Find_Ancestor
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      ID         : in Token_ID;
-      Max_Parent : in Boolean := False)
-     return Node_Index
-   with Pre => Tree.Parents_Set;
-   function Find_Ancestor
-     (Tree       : in Syntax_Trees.Tree;
-      Node       : in Valid_Node_Index;
-      IDs        : in Token_ID_Array;
-      Max_Parent : in Boolean := False)
-     return Node_Index
-   with Pre => Tree.Parents_Set;
-   --  Return the ancestor of Node that contains ID (starting search with
-   --  Node.Parent), or Invalid_Node_Index if none match.
-   --
-   --  If Max_Parent, return max parent found if none match; this will be
-   --  Invalid_Node_Index if Node has no parent.
-
-   function Find_Sibling
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index
-   with Pre => Tree.Parents_Set and then Tree.Has_Parent (Node);
-   --  Return the sibling of Node that contains ID, or Invalid_Node_Index if
-   --  none match.
-
-   function Find_Child
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index
-   with Pre => Tree.Is_Nonterm (Node);
-   --  Return the child of Node whose ID is ID, or Invalid_Node_Index if
-   --  none match.
-
-   function Find_Descendant
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Node_Index;
-   --  Return the descendant of Node (may be Node) whose ID is ID, or
-   --  Invalid_Node_Index if none match.
-
-   function Find_Descendant
-     (Tree      : in     Syntax_Trees.Tree;
-      Node      : in     Valid_Node_Index;
-      Predicate : access function (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Boolean)
-     return Node_Index;
-   --  Return the descendant of Node (may be Node) for which Predicate
-   --  returns True, or Invalid_Node_Index if none do.
-
-   function Is_Descendant_Of
-     (Tree       : in Syntax_Trees.Tree;
-      Root       : in Valid_Node_Index;
-      Descendant : in Valid_Node_Index)
-     return Boolean
-   with Pre => Tree.Parents_Set and Tree.Is_Nonterm (Root);
-
-   procedure Set_Root (Tree : in out Syntax_Trees.Tree; Root : in 
Valid_Node_Index);
-
-   function Root (Tree : in Syntax_Trees.Tree) return Node_Index;
-   --  Return value set by Set_Root.
-   --  returns Invalid_Node_Index if Tree is empty.
-
-   function Sub_Tree_Root (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Valid_Node_Index
-   with Pre => Tree.Parents_Set;
-   --  Return top ancestor of Node.
-
-   procedure Process_Tree
-     (Tree         : in out Syntax_Trees.Tree;
-      Process_Node : access procedure
-        (Tree : in out Syntax_Trees.Tree;
-         Node : in     Valid_Node_Index);
-      Root         : in     Node_Index := Invalid_Node_Index)
-   with Pre => Root /= Invalid_Node_Index or Tree.Root /= Invalid_Node_Index;
-   --  Traverse subtree of Tree rooted at Root (default Tree.Root) in
-   --  depth-first order, calling Process_Node on each node.
-
-   function Identifier (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Identifier_Index
-   with Pre => Tree.Is_Virtual_Identifier (Node);
-
-   function Terminal (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Index) 
return Base_Token_Index
-   with Pre => Tree.Is_Shared_Terminal (Node);
-
-   function First_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Token_Index;
-   --  Returns first shared terminal in subtree under Node
-   --  (ignoring virtual terminals). If result is Invalid_Token_Index,
-   --  all terminals are virtual, or a nonterm is empty.
-
-   function Last_Shared_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Base_Token_Index;
-   --  Returns last shared terminal in subtree under Node (ignoring
-   --  virtual terminals). If result is Invalid_Token_Index, all
-   --  terminals are virtual, or a nonterm is empty.
-
-   function Get_Terminals (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Valid_Node_Index_Array;
-   --  Return sequence of terminals in Node.
-   --
-   --  "Terminals" can be Shared_Terminal, Virtual_Terminal,
-   --  Virtual_Identifier.
-
-   function First_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index;
-   --  First of Get_Terminals. Invalid_Node_Index if Node is an empty 
nonterminal.
-
-   function Last_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index;
-   --  Last of Get_Terminals. Invalid_Node_Index if Node is an empty 
nonterminal.
-
-   function Prev_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   with Pre => Tree.Parents_Set and Tree.Label (Node) in Shared_Terminal | 
Virtual_Terminal | Virtual_Identifier;
-   --  Return the terminal that is immediately before Node in Tree;
-   --  Invalid_Node_Index if Node is the first terminal in Tree.
-
-   function Next_Terminal (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Node_Index
-   with Pre => Tree.Parents_Set and Tree.Label (Node) in Shared_Terminal | 
Virtual_Terminal | Virtual_Identifier;
-   --  Return the terminal that is immediately after Node in Tree;
-   --  Invalid_Node_Index if Node is the last terminal in Tree.
-
-   function Get_Terminal_IDs (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Token_ID_Array;
-   --  Same as Get_Terminals, but return the IDs.
-
-   function First_Terminal_ID (Tree : in Syntax_Trees.Tree; Node : in 
Valid_Node_Index) return Token_ID;
-   --  First of Get_Terminal_IDs; Invalid_Token_ID if Node is empty.
-
-   function Get_IDs
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index;
-      ID   : in Token_ID)
-     return Valid_Node_Index_Array;
-   --  Return all descendants of Node matching ID.
-
-   function Image
-     (Tree              : in Syntax_Trees.Tree;
-      Node              : in Valid_Node_Index;
-      Descriptor        : in WisiToken.Descriptor;
-      Include_Children  : in Boolean := False;
-      Include_RHS_Index : in Boolean := False;
-      Node_Numbers      : in Boolean := False)
-     return String;
-   function Image
-     (Tree       : in Syntax_Trees.Tree;
-      Nodes      : in Valid_Node_Index_Array;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-   --  For debug and error messages.
-
-   function First_Index (Tree : in Syntax_Trees.Tree) return Node_Index;
-   function Last_Index (Tree : in Syntax_Trees.Tree) return Node_Index;
-
-   package Node_Sets is new SAL.Gen_Unbounded_Definite_Vectors 
(Valid_Node_Index, Boolean, Default_Element => False);
-
-   function Image
-     (Item     : in Node_Sets.Vector;
-      Inverted : in Boolean := False)
-     return String;
-   --  Simple list of numbers, for debugging
-
-   function Error_Message
-     (Tree      : in Syntax_Trees.Tree;
-      Terminals : in Base_Token_Array_Access_Constant;
-      Node      : in Valid_Node_Index;
-      File_Name : in String;
-      Message   : in String)
-     return String;
-   --  Get Line, column from Node.
-
-   type Validate_Node is access procedure
-     (Tree              : in     Syntax_Trees.Tree;
-      Node              : in     Valid_Node_Index;
-      Node_Image_Output : in out Boolean);
-   --  Called by Validate_Tree for each node visited; perform other
-   --  checks, output to Text_IO.Current_Error. If Node_Image_Output is
-   --  False, output Image (Tree, Node, Descriptor, Node_Numbers => True) once
-   --  before any error messages.
-
-   procedure Validate_Tree
-     (Tree          : in out Syntax_Trees.Tree;
-      Terminals     : in     Base_Token_Array_Access_Constant;
-      Descriptor    : in     WisiToken.Descriptor;
-      File_Name     : in     String;
-      Root          : in     Node_Index                 := Invalid_Node_Index;
-      Validate_Node : in     Syntax_Trees.Validate_Node := null)
-   with Pre => Tree.Flushed and Tree.Parents_Set;
-   --  Verify child/parent links, and that no children are Deleted_Child.
-   --  Violations output a message to Text_IO.Current_Error.
-
-   type Image_Augmented is access function (Aug : in Base_Token_Class_Access) 
return String;
-   type Image_Action is access function (Action : in Semantic_Action) return 
String;
-
-   procedure Print_Tree
-     (Tree            : in Syntax_Trees.Tree;
-      Descriptor      : in WisiToken.Descriptor;
-      Root            : in Node_Index                   := Invalid_Node_Index;
-      Image_Augmented : in Syntax_Trees.Image_Augmented := null;
-      Image_Action    : in Syntax_Trees.Image_Action    := null)
-   with Pre => Tree.Flushed;
-   --  Print tree rooted at Root (default Tree.Root) to
-   --  Text_IO.Current_Output, for debugging. For each node,
-   --  Image_Augmented is called if it is not null and node.augmented is
-   --  not null.
-
-private
-   use all type Ada.Containers.Count_Type;
-
-   type Node (Label : Node_Label := Virtual_Terminal) is
-   --  Label has a default to allow changing the label during tree editing.
-   record
-      ID : WisiToken.Token_ID := Invalid_Token_ID;
-
-      Byte_Region : Buffer_Region := Null_Buffer_Region;
-      --  Computed by Set_Children, used in Semantic_Check actions and debug
-      --  messages.
-
-      Parent : Node_Index := Invalid_Node_Index;
-
-      State : Unknown_State_Index := Unknown_State;
-      --  Parse state that was on stack with this token, to allow undoing a
-      --  reduce.
-
-      Augmented : Base_Token_Class_Access := null;
-
-      case Label is
-      when Shared_Terminal =>
-         Terminal : Token_Index; -- into Parser.Terminals
-
-      when Virtual_Terminal =>
-         Before : Base_Token_Index := Invalid_Token_Index; -- into 
Parser.Terminals
-
-      when Virtual_Identifier =>
-         Identifier : Identifier_Index; -- into user data
-
-      when Nonterm =>
-         Virtual : Boolean := False;
-         --  True if any child node is Virtual_Terminal or Nonterm with Virtual
-         --  set. Used by Semantic_Check actions.
-
-         RHS_Index : Natural;
-         --  With ID, index into Productions.
-         --  Used for debug output, keep for future use.
-
-         Action : Semantic_Action := null;
-
-         Name : Buffer_Region := Null_Buffer_Region;
-         --  Name is set and checked by Semantic_Check actions.
-
-         Children : Valid_Node_Index_Arrays.Vector;
-
-         Min_Terminal_Index : Base_Token_Index := Invalid_Token_Index;
-         --  Cached for push_back of nonterminals during recovery
-      end case;
-   end record;
-
-   subtype Nonterm_Node is Node (Nonterm);
-
-   package Node_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Valid_Node_Index, Node, Default_Element => (others => <>));
-
-   type Base_Tree is new Ada.Finalization.Controlled with record
-      Nodes : Node_Arrays.Vector;
-      --  During normal parsing, tokens are added to Nodes by "parallel"
-      --  LALR parsers, but they are all run from one Ada task, so there's
-      --  no need for Nodes to be Protected. Packrat parsing also has a
-      --  single Ada task.
-      --
-      --  During McKenzie_Recover, which has multiple Ada tasks, the syntax
-      --  tree is read but not modified.
-
-      Augmented_Present : Boolean := False;
-      --  True if Set_Augmented has been called on any node. Declared in
-      --  Base_Tree so it can be checked by Finalize (Base_Tree) and
-      --  Finalize (Tree).
-
-      Traversing : Boolean := False;
-      --  True while traversing tree in Process_Tree.
-      --  Declared in Base_Tree so it is cleared by Finalize.
-
-      Parents_Set : Boolean := False;
-      --  We don't set Node.Parent until after parse is done; see Design
-      --  note above.
-   end record;
-
-   function Is_Empty (Tree : in Base_Tree) return Boolean
-   is (Tree.Nodes.Length = 0);
-
-   type Tree is new Ada.Finalization.Controlled with record
-      Shared_Tree : Base_Tree_Access;
-      --  If we need to set anything (ie parent) in Shared_Tree, we move the
-      --  branch point instead, unless Flush = True.
-
-      Last_Shared_Node : Node_Index := Invalid_Node_Index;
-      Branched_Nodes   : Node_Arrays.Vector;
-      Flush            : Boolean    := False;
-      --  If Flush is True, all nodes are in Shared_Tree. Otherwise, all
-      --  greater than Last_Shared_Node are in Branched_Nodes.
-      --
-      --  We maintain Last_Shared_Node when Flush is True or False, so
-      --  subprograms that have no reason to check Flush can rely on
-      --  Last_Shared_Node.
-
-      Root : Node_Index := Invalid_Node_Index;
-   end record with
-     Type_Invariant =>
-       (Shared_Tree = null or else
-        (if Tree.Flush
-         then Last_Shared_Node = Shared_Tree.Nodes.Last_Index and
-            Branched_Nodes.Length = 0
-         else Last_Shared_Node <= Shared_Tree.Nodes.Last_Index and
-            Last_Shared_Node < Branched_Nodes.First_Index));
-
-   subtype Node_Const_Ref is Node_Arrays.Constant_Reference_Type;
-   subtype Node_Var_Ref is Node_Arrays.Variable_Reference_Type;
-
-   function Get_Node_Const_Ref
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Node_Const_Ref
-   is (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes.Constant_Ref (Node)
-         else Tree.Branched_Nodes.Constant_Ref (Node));
-
-   function Get_Node_Var_Ref
-     (Tree : in Syntax_Trees.Tree;
-      Node : in Valid_Node_Index)
-     return Node_Var_Ref
-   is (if Node <= Tree.Last_Shared_Node
-         then Tree.Shared_Tree.Nodes.Variable_Ref (Node)
-         else Tree.Branched_Nodes.Variable_Ref (Node));
-
-   function Is_Empty (Tree : in Syntax_Trees.Tree) return Boolean
-   is (Tree.Branched_Nodes.Length = 0 and (Tree.Shared_Tree = null or else 
Tree.Shared_Tree.Is_Empty));
-
-   function Parents_Set (Tree : in Syntax_Trees.Tree) return Boolean
-   is (Tree.Shared_Tree.Parents_Set);
-
-end WisiToken.Syntax_Trees;
diff --git a/packages/wisi/wisitoken-text_io_trace.adb 
b/packages/wisi/wisitoken-text_io_trace.adb
deleted file mode 100644
index 77fb331..0000000
--- a/packages/wisi/wisitoken-text_io_trace.adb
+++ /dev/null
@@ -1,113 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017, 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Calendar.Formatting;
-with Ada.Strings.Fixed;
-package body WisiToken.Text_IO_Trace is
-
-   function Insert_Prefix_At_Newlines (Trace : in Text_IO_Trace.Trace; Item : 
in String) return String
-   is
-      use Ada.Strings.Fixed;
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String;
-      First : Integer := Item'First;
-      Last : Integer;
-   begin
-      loop
-         Last := Index (Pattern => "" & ASCII.LF, Source => Item (First .. 
Item'Last));
-         exit when Last = 0;
-         Result := Result & Item (First .. Last) & Trace.Prefix;
-         First := Last + 1;
-      end loop;
-      Result := Result & Item (First .. Item'Last);
-      return -Result;
-   end Insert_Prefix_At_Newlines;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   overriding
-   procedure Set_Prefix (Trace : in out Text_IO_Trace.Trace; Prefix : in 
String)
-   is begin
-      Trace.Prefix := +Prefix;
-   end Set_Prefix;
-
-   overriding
-   procedure Put (Trace : in out Text_IO_Trace.Trace; Item : in String; Prefix 
: in Boolean := True)
-   is
-      use Ada.Text_IO;
-   begin
-      if Trace.File /= null and then Is_Open (Trace.File.all) then
-         Ada.Text_IO.Put (Trace.File.all, (if Prefix then -Trace.Prefix else 
"") & Item);
-      else
-         Ada.Text_IO.Put ((if Prefix then -Trace.Prefix else "") & Item);
-      end if;
-   end Put;
-
-   overriding
-   procedure Put_Line (Trace : in out Text_IO_Trace.Trace; Item : in String)
-   is
-      use Ada.Strings.Fixed;
-      use Ada.Text_IO;
-      Temp : constant String :=
-        (if 0 /= Index (Item, "" & ASCII.LF)
-         then Insert_Prefix_At_Newlines (Trace, Item)
-         else Item);
-   begin
-
-      if Trace.File /= null and then Is_Open (Trace.File.all) then
-         Ada.Text_IO.Put_Line (Trace.File.all, -Trace.Prefix & Temp);
-         Ada.Text_IO.Flush (Trace.File.all);
-      else
-         Ada.Text_IO.Put_Line (-Trace.Prefix & Temp);
-         Ada.Text_IO.Flush;
-      end if;
-   end Put_Line;
-
-   overriding
-   procedure New_Line (Trace : in out Text_IO_Trace.Trace)
-   is
-      use Ada.Text_IO;
-   begin
-      if Trace.File /= null and then Is_Open (Trace.File.all) then
-         Ada.Text_IO.New_Line (Trace.File.all);
-      else
-         Ada.Text_IO.New_Line;
-      end if;
-   end New_Line;
-
-   overriding
-   procedure Put_Clock (Trace : in out Text_IO_Trace.Trace; Label : in String)
-   is begin
-      Trace.Put_Line
-        (Ada.Calendar.Formatting.Image
-           (Ada.Calendar.Clock, Include_Time_Fraction => True) & " " & Label);
-   end Put_Clock;
-
-   procedure Set_File (Trace : in out Text_IO_Trace.Trace; File : in 
Ada.Text_IO.File_Access)
-   is begin
-      Trace.File := File;
-   end Set_File;
-
-   procedure Clear_File (Trace : in out Text_IO_Trace.Trace)
-   is begin
-      Trace.File := null;
-   end Clear_File;
-
-end WisiToken.Text_IO_Trace;
diff --git a/packages/wisi/wisitoken-text_io_trace.ads 
b/packages/wisi/wisitoken-text_io_trace.ads
deleted file mode 100644
index b400c23..0000000
--- a/packages/wisi/wisitoken-text_io_trace.ads
+++ /dev/null
@@ -1,53 +0,0 @@
---  Abstract :
---
---  Trace output to Ada.Text_IO
---
---  Copyright (C) 2017, 2019, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO;
-package WisiToken.Text_IO_Trace is
-
-   type Trace is limited new WisiToken.Trace with private;
-   --  Defaults to Ada.Text_IO.Standard_Output
-
-   overriding
-   procedure Set_Prefix (Trace : in out Text_IO_Trace.Trace; Prefix : in 
String);
-
-   overriding
-   procedure Put (Trace : in out Text_IO_Trace.Trace; Item : in String; Prefix 
: in Boolean := True);
-
-   overriding
-   procedure Put_Line (Trace : in out Text_IO_Trace.Trace; Item : in String);
-   --  If Item contains ASCII.LF, Prefix is output after each one.
-
-   overriding
-   procedure New_Line (Trace : in out Text_IO_Trace.Trace);
-
-   overriding
-   procedure Put_Clock (Trace : in out Text_IO_Trace.Trace; Label : in String);
-
-   procedure Set_File (Trace : in out Text_IO_Trace.Trace; File : in 
Ada.Text_IO.File_Access);
-   --  Set file for trace output. Default is Text_IO.Current_Output.
-
-   procedure Clear_File (Trace : in out Text_IO_Trace.Trace);
-   --  Clear internal file; output to Text_IO.Current_Output.
-
-private
-   type Trace is limited new WisiToken.Trace with record
-      File   : Ada.Text_IO.File_Access;
-      Prefix : Ada.Strings.Unbounded.Unbounded_String;
-   end record;
-end WisiToken.Text_IO_Trace;
diff --git a/packages/wisi/wisitoken-to_tree_sitter.adb 
b/packages/wisi/wisitoken-to_tree_sitter.adb
deleted file mode 100644
index 2213414..0000000
--- a/packages/wisi/wisitoken-to_tree_sitter.adb
+++ /dev/null
@@ -1,528 +0,0 @@
---  Abstract :
---
---  Translate a wisitoken grammar file to a tree-sitter grammar file.
---
---  References:
---
---  [1] tree-sitter grammar: 
https://tree-sitter.github.io/tree-sitter/creating-parsers#the-grammar-dsl
---
---  Copyright (C) 2020 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with WisiToken.Syntax_Trees.LR_Utils;
-with WisiToken.Parse.LR.Parser_No_Recover;
-with WisiToken.Syntax_Trees;
-with WisiToken.Text_IO_Trace;
-with WisiToken_Grammar_Runtime;
-with Wisitoken_Grammar_Actions; use Wisitoken_Grammar_Actions;
-with Wisitoken_Grammar_Main;
-procedure WisiToken.To_Tree_Sitter
-is
-   procedure Put_Usage
-   is begin
-      Put_Line ("wisitoken-to_tree_sitter [--verbosity <level] <wisitoken 
grammar file> <language_name>");
-   end Put_Usage;
-
-   procedure Print_Tree_Sitter
-     (Data             : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Tree             : in Syntax_Trees.Tree;
-      Output_File_Name : in String;
-      Language_Name    : in String)
-   is
-      use WisiToken.Syntax_Trees;
-
-      File : File_Type;
-
-      --  Local specs
-
-      procedure Put_RHS_Item_List (Node : in Valid_Node_Index; First : in 
Boolean)
-      with Pre => Tree.ID (Node) = +rhs_item_list_ID;
-
-      --  Local bodies
-
-      function Get_Text (Tree_Index : in Valid_Node_Index) return String
-      is
-         function Strip_Delimiters (Tree_Index : in Valid_Node_Index) return 
String
-         is
-            Region : Buffer_Region renames Data.Terminals.all (Tree.Terminal 
(Tree_Index)).Byte_Region;
-         begin
-            if -Tree.ID (Tree_Index) in RAW_CODE_ID | REGEXP_ID | ACTION_ID 
then
-               --  Strip delimiters. We don't strip leading/trailing spaces to 
preserve indent.
-               return Data.Grammar_Lexer.Buffer_Text ((Region.First + 2, 
Region.Last - 2));
-
-               --  We don't strip string delimiters; tree-setter can use the 
same ones.
-            else
-               return Data.Grammar_Lexer.Buffer_Text (Region);
-            end if;
-         end Strip_Delimiters;
-
-      begin
-         case Tree.Label (Tree_Index) is
-         when Shared_Terminal =>
-            return Strip_Delimiters (Tree_Index);
-
-         when Virtual_Terminal =>
-            --  Terminal keyword inserted during tree edit. We could check for
-            --  Identifier, but that will be caught later.
-            return Image (Tree.ID (Tree_Index), 
Wisitoken_Grammar_Actions.Descriptor);
-
-         when Virtual_Identifier =>
-            raise SAL.Programmer_Error;
-
-         when Nonterm =>
-            declare
-               use all type Ada.Strings.Unbounded.Unbounded_String;
-               Result       : Ada.Strings.Unbounded.Unbounded_String;
-               Tree_Indices : constant Valid_Node_Index_Array := 
Tree.Get_Terminals (Tree_Index);
-               Need_Space   : Boolean                                      := 
False;
-            begin
-               for Tree_Index of Tree_Indices loop
-                  Result := Result & (if Need_Space then " " else "") &
-                    Get_Text (Tree_Index);
-                  Need_Space := True;
-               end loop;
-               return -Result;
-            end;
-         end case;
-      end Get_Text;
-
-      procedure Not_Translated (Label : in String; Node : in Valid_Node_Index)
-      is begin
-         New_Line (File);
-         Put (File, "// " & Label & ": not translated: " & Node_Index'Image 
(Node) & ":" &
-                Tree.Image (Node, Wisitoken_Grammar_Actions.Descriptor, 
Include_Children => True));
-      end Not_Translated;
-
-      procedure Put_RHS_Alternative_List (Node : in Valid_Node_Index; First : 
in Boolean)
-      with Pre => Tree.ID (Node) = +rhs_alternative_list_ID
-      is begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            --  If only alternative, don't need "choice()".
-            Put_RHS_Item_List (Tree.Child (Node, 1), First => True);
-
-         when 1 =>
-            if First then
-               Put (File, "choice(");
-            end if;
-
-            Put_RHS_Alternative_List (Tree.Child (Node, 1), First => False);
-            Put (File, ", ");
-            Put_RHS_Item_List (Tree.Child (Node, 3), First => True);
-
-            if First then
-               Put (File, ")");
-            end if;
-
-         when others =>
-            Not_Translated ("Put_RHS_Alternative_List", Node);
-         end case;
-      end Put_RHS_Alternative_List;
-
-      procedure Put_RHS_Optional_Item (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_optional_item_ID
-      is begin
-         Put (File, "optional(");
-
-         case Tree.RHS_Index (Node) is
-         when 0 | 1 =>
-            Put_RHS_Alternative_List (Tree.Child (Node, 2), First => True);
-         when 2 =>
-            Put (File, "$." & Get_Text (Tree.Child (Node, 1)));
-         when 3 =>
-            --  STRING_LITERAL_2
-            Put (File, Get_Text (Tree.Child (Node, 1)));
-         when others =>
-            Not_Translated ("Put_RHS_Optional_Item", Node);
-         end case;
-
-         Put (File, ")");
-      end Put_RHS_Optional_Item;
-
-      procedure Put_RHS_Multiple_Item (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_multiple_item_ID
-      is begin
-         case Tree.RHS_Index (Node) is
-         when 0 | 3 =>
-            Put (File, "repeat(");
-            Put_RHS_Alternative_List (Tree.Child (Node, 2), First => True);
-            Put (File, ")");
-
-         when 1 | 2 =>
-            Put (File, "repeat1(");
-            Put_RHS_Alternative_List (Tree.Child (Node, 2), First => True);
-            Put (File, ")");
-
-         when 4 =>
-            Put (File, "repeat1(");
-            Put (File, "$." & Get_Text (Tree.Child (Node, 1)));
-            Put (File, ")");
-
-         when 5 =>
-            Put (File, "repeat(");
-            Put (File, "$." & Get_Text (Tree.Child (Node, 1)));
-            Put (File, ")");
-
-         when others =>
-            Not_Translated ("Put_RHS_Multiple_Item", Node);
-         end case;
-      end Put_RHS_Multiple_Item;
-
-      procedure Put_RHS_Group_Item (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_group_item_ID
-      is begin
-         Not_Translated ("Put_RHS_Group_Item", Node); -- maybe just plain ()?
-      end Put_RHS_Group_Item;
-
-      procedure Put_RHS_Item (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_item_ID
-      is begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            declare
-               use WisiToken_Grammar_Runtime;
-
-               Ident : constant String     := Get_Text (Node);
-               Decl  : constant Node_Index := Find_Declaration (Data, Tree, 
Ident);
-            begin
-               if Decl = Invalid_Node_Index then
-                  Raise_Programmer_Error ("decl for '" & Ident & "' not 
found", Data, Tree, Node);
-
-               elsif Tree.ID (Decl) = +nonterminal_ID then
-                  Put (File, "$." & Get_Text (Tree.Child (Decl, 1)));
-
-               else
-                  case Tree.RHS_Index (Decl) is
-                  when 0 =>
-                     case To_Token_Enum (Tree.ID (Tree.Child (Tree.Child 
(Decl, 2), 1))) is
-                     when KEYWORD_ID =>
-                        Put (File, Get_Text (Tree.Child (Decl, 4)));
-
-                     when NON_GRAMMAR_ID =>
-                        Not_Translated ("put_rhs_item", Node);
-
-                     when Wisitoken_Grammar_Actions.TOKEN_ID =>
-                        declare
-                           use WisiToken.Syntax_Trees.LR_Utils;
-                           Iter : constant Syntax_Trees.LR_Utils.Iterator :=
-                             Iterate (Data, Tree, Tree.Child (Decl, 4), 
+declaration_item_ID);
-                           Item : constant Valid_Node_Index :=
-                             Tree.Child (Syntax_Trees.LR_Utils.Node (First 
(Iter)), 1);
-                        begin
-                           case To_Token_Enum (Tree.ID (Item)) is
-                           when REGEXP_ID =>
-                              Put (File, "$." & Ident);
-
-                           when STRING_LITERAL_1_ID | STRING_LITERAL_2_ID =>
-                              --  FIXME: case insensitive?
-                              Put (File, Get_Text (Item));
-
-                           when others =>
-                              Not_Translated ("put_rhs_item ident token", 
Node);
-                           end case;
-                        end;
-
-                     when others =>
-                        Not_Translated ("put_rhs_item ident", Node);
-                     end case;
-
-                  when others =>
-                     Not_Translated ("put_rhs_item 0", Node);
-                  end case;
-               end if;
-            end;
-
-         when 1 =>
-            --  STRING_LITERAL_2
-            Put (File, Get_Text (Node));
-
-         when 2 =>
-            --  ignore attribute
-            null;
-
-         when 3 =>
-            Put_RHS_Optional_Item (Tree.Child (Node, 1));
-
-         when 4 =>
-            Put_RHS_Multiple_Item (Tree.Child (Node, 1));
-
-         when 5 =>
-            Put_RHS_Group_Item (Tree.Child (Node, 1));
-
-         when others =>
-            Not_Translated ("Put_RHS_Item", Node);
-         end case;
-      end Put_RHS_Item;
-
-      procedure Put_RHS_Element (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_element_ID
-      is begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put_RHS_Item (Tree.Child (Node, 1));
-
-         when 1 =>
-            --  Ignore the label
-            Put_RHS_Item (Tree.Child (Node, 3));
-
-         when others =>
-            Not_Translated ("Put_RHS_Element", Node);
-         end case;
-      end Put_RHS_Element;
-
-      procedure Put_RHS_Item_List (Node : in Valid_Node_Index; First : in 
Boolean)
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         if Children'Length = 1 then
-            Put_RHS_Element (Children (1));
-         else
-            if First then
-               Put (File, "seq(");
-            end if;
-            Put_RHS_Item_List (Children (1), First => False);
-            Put (File, ", ");
-            Put_RHS_Element (Children (2));
-
-            if First then
-               Put (File, ")");
-            end if;
-         end if;
-      end Put_RHS_Item_List;
-
-      procedure Put_RHS (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_ID
-      is begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put (File, "/* empty */,");
-
-         when 1 .. 3 =>
-            Put_RHS_Item_List (Tree.Child (Node, 1), First => True);
-            --  ignore actions
-
-         when others =>
-            Not_Translated ("put_rhs", Node);
-         end case;
-      end Put_RHS;
-
-      procedure Put_RHS_List (Node : in Valid_Node_Index; First : in Boolean)
-      with Pre => Tree.ID (Node) = +rhs_list_ID
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put_RHS (Children (1));
-
-         when 1 =>
-            if First then
-               Put (File, "choice(");
-            end if;
-
-            Put_RHS_List (Children (1), First => False);
-            Put (File, ",");
-            Put_RHS (Children (3));
-
-            if First then
-               Put (File, ")");
-            end if;
-
-         when others =>
-            Not_Translated ("Put_RHS_List", Node);
-         end case;
-      end Put_RHS_List;
-
-      procedure Process_Node (Node : in Valid_Node_Index)
-      is begin
-         case To_Token_Enum (Tree.ID (Node)) is
-         --  Enum_Token_ID alphabetical order
-         when compilation_unit_ID =>
-            Process_Node (Tree.Child (Node, 1));
-
-         when compilation_unit_list_ID =>
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            begin
-               case To_Token_Enum (Tree.ID (Children (1))) is
-               when compilation_unit_list_ID =>
-                  Process_Node (Children (1));
-                  Process_Node (Children (2));
-               when compilation_unit_ID =>
-                  Process_Node (Children (1));
-               when others =>
-                  raise SAL.Programmer_Error;
-               end case;
-            end;
-
-         when declaration_ID =>
-            case Tree.RHS_Index (Node) is
-            when 0 =>
-               if Tree.ID (Tree.Child (Tree.Child (Node, 2), 1)) = 
+Wisitoken_Grammar_Actions.TOKEN_ID then
-                  declare
-                     use Ada.Strings;
-                     use Ada.Strings.Fixed;
-                     use WisiToken.Syntax_Trees.LR_Utils;
-                     Name : constant String := Get_Text (Tree.Child (Node, 3));
-                     Iter : constant Syntax_Trees.LR_Utils.Iterator :=
-                       WisiToken_Grammar_Runtime.Iterate (Data, Tree, 
Tree.Child (Node, 4), +declaration_item_ID);
-                     Item : constant Valid_Node_Index :=
-                       Tree.Child (Syntax_Trees.LR_Utils.Node (First (Iter)), 
1);
-                  begin
-                     case To_Token_Enum (Tree.ID (Item)) is
-                     when REGEXP_ID =>
-                        Put_Line (File, Name & ": $ => /" & Trim (Get_Text 
(Item), Both) & "/,");
-
-                     when others =>
-                        null;
-                     end case;
-                  end;
-               end if;
-
-            when others =>
-               null;
-            end case;
-
-         when nonterminal_ID =>
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            begin
-               Put (File, Get_Text (Children (1)) & ": $ => ");
-
-               Put_RHS_List (Children (3), First => True);
-
-               Put_Line (File, ",");
-            end;
-
-         when wisitoken_accept_ID =>
-            Process_Node (Tree.Child (Node, 1));
-
-         when others =>
-            raise SAL.Not_Implemented with Image (Tree.ID (Node), 
Wisitoken_Grammar_Actions.Descriptor);
-         end case;
-      end Process_Node;
-   begin
-      Create (File, Out_File, Output_File_Name);
-      Put_Line (File, "// generated from " & Data.Grammar_Lexer.File_Name & " 
-*- buffer-read-only:t -*-");
-
-      --  FIXME: copy copyright, license?
-
-      Put_Line (File, "module.exports = grammar({");
-      Put_Line (File, "  name: '" & Language_Name & "',");
-
-      Put_Line (File, "  rules: {");
-
-      Process_Node (Tree.Root);
-
-      Put_Line (File, "  }");
-      Put_Line (File, "});");
-      Close (File);
-   end Print_Tree_Sitter;
-
-   Trace          : aliased WisiToken.Text_IO_Trace.Trace 
(Wisitoken_Grammar_Actions.Descriptor'Access);
-   Input_Data     : aliased WisiToken_Grammar_Runtime.User_Data_Type;
-   Grammar_Parser : WisiToken.Parse.LR.Parser_No_Recover.Parser;
-
-   Input_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-   Language_Name   : Ada.Strings.Unbounded.Unbounded_String;
-begin
-   Wisitoken_Grammar_Main.Create_Parser
-     (Parser    => Grammar_Parser,
-      Trace     => Trace'Unchecked_Access,
-      User_Data => Input_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-      Arg : Integer := 1;
-   begin
-      if not (Argument_Count in 1 .. 4) then
-         Put_Usage;
-         Set_Exit_Status (Failure);
-         return;
-      end if;
-
-      loop
-         exit when Arg > Argument_Count;
-
-         if Argument (Arg) = "--verbosity" then
-            Arg := Arg + 1;
-            Trace_Generate_EBNF := Integer'Value (Argument (Arg));
-            Arg := Arg + 1;
-
-         else
-            exit;
-         end if;
-      end loop;
-
-      --  no more options
-      Input_File_Name := +Argument (Arg);
-      Arg := Arg + 1;
-      Language_Name := +Argument (Arg);
-   end;
-
-   begin
-      Grammar_Parser.Lexer.Reset_With_File (-Input_File_Name);
-   exception
-   when Ada.Text_IO.Name_Error | Ada.Text_IO.Use_Error =>
-      raise Ada.Text_IO.Name_Error with "input file '" & (-Input_File_Name) & 
"' could not be opened.";
-   end;
-
-   begin
-      Grammar_Parser.Parse;
-   exception
-   when WisiToken.Syntax_Error =>
-      Grammar_Parser.Put_Errors;
-      raise;
-   end;
-
-   Grammar_Parser.Execute_Actions;
-
-   declare
-      use Ada.Directories;
-
-      Output_File_Name : constant String := Base_Name (-Input_File_Name) & 
".js";
-
-      Tree  : WisiToken.Syntax_Trees.Tree renames 
Grammar_Parser.Parsers.First_State_Ref.Tree;
-   begin
-      if Trace_Generate_EBNF > Outline then
-         Put_Line ("'" & (-Input_File_Name) & "' => '" & Output_File_Name & 
"'");
-      end if;
-
-      if Trace_Generate_EBNF > Detail then
-         Put_Line ("wisitoken tree:");
-         Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor);
-         Ada.Text_IO.New_Line;
-      end if;
-
-      Print_Tree_Sitter (Input_Data, Tree, Output_File_Name, -Language_Name);
-   end;
-
-exception
-when WisiToken.Syntax_Error | WisiToken.Parse_Error =>
-   --  error message already output
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-
-when E :  others =>
-   declare
-      use Ada.Exceptions;
-      use Ada.Command_Line;
-   begin
-      Put_Line (Standard_Error, Exception_Name (E) & ": " & Exception_Message 
(E));
-      Put_Line (Standard_Error, GNAT.Traceback.Symbolic.Symbolic_Traceback 
(E));
-      Set_Exit_Status (Failure);
-   end;
-end WisiToken.To_Tree_Sitter;
diff --git a/packages/wisi/wisitoken-user_guide.info 
b/packages/wisi/wisitoken-user_guide.info
deleted file mode 100644
index 7bbdb1b..0000000
--- a/packages/wisi/wisitoken-user_guide.info
+++ /dev/null
@@ -1,611 +0,0 @@
-This is wisitoken-user_guide.info, produced by makeinfo version 6.7 from
-wisitoken-user_guide.texinfo.
-
-Copyright (C) 2014-2015, 2017, 2018, 2020 Stephen Leake.
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU Free Documentation License,
-     Version 1.3 or any later version published by the Free Software
-     Foundation; with no Invariant Sections, no Front-Cover Texts and no
-     Back-Cover Texts.  A copy of the license is included in the section
-     entitled "GNU Free Documentation License".
-INFO-DIR-SECTION Parser generators
-START-INFO-DIR-ENTRY
-* wisitoken-bnf-generate: (wisitoken-bnf-generate).         Ada and Elisp 
parser generator
-END-INFO-DIR-ENTRY
-
-
-File: wisitoken-user_guide.info,  Node: Top,  Next: Overview,  Up: (dir)
-
-WisiToken User Guide
-********************
-
-Copyright (C) 2014-2015, 2017, 2018, 2020 Stephen Leake.
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU Free Documentation License,
-     Version 1.3 or any later version published by the Free Software
-     Foundation; with no Invariant Sections, no Front-Cover Texts and no
-     Back-Cover Texts.  A copy of the license is included in the section
-     entitled "GNU Free Documentation License".
-
-* Menu:
-
-* Overview::
-* Common grammar problems::
-* Grammar File Syntax::
-
-
-File: wisitoken-user_guide.info,  Node: Overview,  Next: Common grammar 
problems,  Prev: Top,  Up: Top
-
-1 Overview
-**********
-
-WisiToken is a parser and parser generator toolkit, supporting
-generalized LR (both LALR and LR1) and packrat parsers; the LR parser
-provides robust error recovery.  The grammar can be expressed as either
-Ada source code statements, or in an EBNF file.  The parser generator
-generates Ada, either plain or assuming the Emacs wisi package.
-
-   At one point, "wisi" was short for "Wisent Indentation engine"; the
-Emacs 'wisi' package implements an indentation engine that used to be
-based on the Emacs wisent parser.  However, that parser has now been
-replaced by the WisiToken parser, so "wisi" is just a name.
-
-* Menu:
-
-* Install::
-
-
-File: wisitoken-user_guide.info,  Node: Install,  Up: Overview
-
-1.1 Install
-===========
-
-WisiToken is available as source code only, although a subset is
-available in the GNU ELPA package 'wisi'.
-
-   You will also need to install a lexer generator.  WisiToken supports
-re2c, and other lexers can be added.
-
-   re2c is available from <http://re2c.org/>; it is also packaged in
-Mingw64 and Debian.  WisiToken requires at least version 1.3.  WisiToken
-assumes the executable 're2c' is in '$PATH'.
-
-
-File: wisitoken-user_guide.info,  Node: Common grammar problems,  Next: 
Grammar File Syntax,  Prev: Overview,  Up: Top
-
-2 Common grammar problems
-*************************
-
-LALR grammars are tricky.  Here we describe some common problems people
-run into.
-
-* Menu:
-
-* Empty choice in list::
-
-
-File: wisitoken-user_guide.info,  Node: Empty choice in list,  Up: Common 
grammar problems
-
-2.1 Empty choice in list
-========================
-
-Many programming languages have lists in the grammar.  For example, Ada
-has lists of declarations:
-
-     package_body
-       : PACKAGE name IS declaration_list BEGIN statement_list END SEMICOLON
-       ;
-
-     declaration_list
-       : declaration
-       | declaration_list declaration
-       ;
-
-     declaration
-       : object_declaration
-       | subprogram_declaration
-       ;; ...
-       ;
-
-   Note that the above grammar fragment does not allow an empty
-declaration_list.  But Ada does, so the question is how can we add that
-to the grammar.
-
-   There are four choices:
-
-  1. Add an empty declaration choice to declaration_list:
-
-          declaration_list
-            : ;; empty list
-            | declaration
-            | declaration_list declaration
-            ;
-     This is now redundant; since declaration_list can be empty, the
-     second choice is not needed:
-          declaration_list
-            : ;; empty list
-            | declaration_list declaration
-            ;
-
-  2. Add an empty declaration choice to declaration:
-
-          declaration
-            : ;; empty declaration
-            | object_declaration
-            | subprogram_declaration
-            ;; ...
-            ;
-
-  3. Add another rule with the empty production:
-
-          package_body
-            : PACKAGE name IS declarative_part BEGIN statement_list END 
SEMICOLON
-            ;
-
-          declarative_part
-            : ;; empty
-            | declaration_list
-            ;
-
-          declaration_list
-            : declaration
-            | declaration_list declaration
-            ;
-
-          declaration
-            : object_declaration
-            | subprogram_declaration
-            ;; ...
-            ;
-
-  4. Add another choice in package_body that leaves out
-     declaration_list:
-          package_body
-            : PACKAGE name IS declaration_list BEGIN statement_list END 
SEMICOLON
-            | PACKAGE name IS BEGIN statement_list END SEMICOLON
-            ;
-
-   Choice 1 is redundant, giving parse errors at parse time.  Consider
-the following statements, where "<empty>" is used to indicate an empty
-declaration:
-
-   1) package One is <empty> begin end ; 2) package One is package One
-is <empty> begin end ; begin end ; 3) package One is <empty> package One
-is <empty declaration> begin end ; begin end ;
-
-   In parsing 3), the second 'package' causes a shift/reduce conflict;
-shift to start the nested declaration (as in 2), reduce to the empty
-declaration.  Both are correct according to the grammar.
-
-   Choice 2 leads to a shift/reduce conflict in the production for
-package_body; implementing the wisi parser as a generalized LALR parser
-allows it to handle this option.
-
-   Choice 2 is the preferred choice for Ada, since it involves the least
-modifications to the original Ada grammar in the Ada reference manual.
-
-
-File: wisitoken-user_guide.info,  Node: Grammar File Syntax,  Prev: Common 
grammar problems,  Up: Top
-
-3 Grammar File Syntax
-*********************
-
-The grammar file syntax is based on Gnu bison syntax with some additions
-and deletions (*note Bison: (bison)Top.).
-
-   (The grammar is specified in the WisiToken grammar file
-'wisitoken_grammar.wy').
-
-   The top level file structure is a list of declarations and
-nonterminals.
-
-   Comments are started by ';;' and terminated by end of line.
-
-* Menu:
-
-* Declarations::
-* Nonterminals::
-* Conditional code::
-
-
-File: wisitoken-user_guide.info,  Node: Declarations,  Next: Nonterminals,  
Up: Grammar File Syntax
-
-3.1 Declarations
-================
-
-Declarations declare terminal tokens, conflicts, and other parser
-parameters.
-
-* Menu:
-
-* Raw Code::
-* Keywords::
-* Tokens::
-* Error recovery::
-* Other declarations::
-
-
-File: wisitoken-user_guide.info,  Node: Raw Code,  Next: Keywords,  Up: 
Declarations
-
-3.1.1 Raw code
---------------
-
-%code { actions | copyright_license } [spec | body | context | pre | post]... 
%{ <output language code> }%
-
-   Raw code declarations contain arbitrary code, copied verbatim into
-the output.  The keywords following '%code' determine where the section
-is output.
-
-
-File: wisitoken-user_guide.info,  Node: Keywords,  Next: Tokens,  Prev: Raw 
Code,  Up: Declarations
-
-3.1.2 Keywords
---------------
-
-%keyword <name> <string>
-
-   example:
-%keyword SEMICOLON ";"
-
-   "Keywords" are reserved words or symbols in the target language; the
-lexers recognize them by the given string.
-
-
-File: wisitoken-user_guide.info,  Node: Tokens,  Next: Error recovery,  Prev: 
Keywords,  Up: Declarations
-
-3.1.3 Tokens
-------------
-
-%token < kind > name regexp
-
-   example:
-%token <symbol> IDENTIFIER %[ ... ]%
-%token <punctuation> TICK "'"
-
-   The syntax of the regular expression is determined by the lexer
-generator.  The meaning of 'kind' is determined by the lexer ('re2c'
-ignores this), with the following defined by the WisiToken generator.
-Other token kinds have no effect; they may be used for documentation.
-
-'<string-double>'
-     %token <string-double> STRING_LITERAL %[ ... ]%
-     A string of characters that have string syntax, with double quote
-     delimiters.
-
-'<string-single>'
-     %token <string-single> CHARACTER_LITERAL %[ ... ]%
-     A string of characters that have string syntax, with single quote
-     delimiters.
-
-'<new-line>'
-     %token <new-line> [\n] %[ ... ]%
-     Not used by the wisi lexer; required by the Ada lexer.  The third
-     argument is the regular expression to recognize the entire comment.
-
-'<non-reporting>'
-     %token <non-reporting> WHITESPACE %[ [ \t] ]%
-     A token that is recognized by the lexer, but not returned to the
-     parser.
-
-'<delimited-text>'
-     %token <delimited-text> RAW_CODE "%{" "}%"
-     A token that contains arbitrary text, delimited by the two strings.
-
-
-File: wisitoken-user_guide.info,  Node: Error recovery,  Next: Other 
declarations,  Prev: Tokens,  Up: Declarations
-
-3.1.4 Error recovery
---------------------
-
-The parser uses an error recovery algorithm when it encounters a syntax
-error; if a solution is found, the parse continues.
-
-   Error recovery uses multiple tasks to take advantage of multiple CPU
-cores.  Unfortunately, this means there is a race condition; the
-solutions found can be delivered in different orders on different runs.
-This matters because each solution results in a successful parse,
-possibly with different actions (different indentation computed, for
-example).  Which solution finally succeeds depends on which are
-terminated due to identical parser stacks, which in turn depends on the
-order they were delivered.
-
-   Once the syntax errors are fixed, only ambiguities in the grammar
-itself can cause a similar problem.
-
-   Several grammar file declarations set parameters for the error
-recovery.  If none of these parameters are present in the grammar file,
-the generated parser does not do error recovery.
-
-   The error recovery algorithm generates possible solutions based on
-the parse state preceding the error point, by inserting, deleting, or
-pushing back tokens.  Each possible solution is given a cost, and
-enqueued to be checked later.  Solutions are checked in cost order
-(lowest first).
-
-'%mckenzie_check_limit <limit>'
-     The number of tokens past the error point that must be parsed
-     successfully for a solution to be deemed successful.  Smaller
-     values give faster recovery; larger values give better solutions.
-     Too large a value risks encountering another user error, making a
-     solution impossible.  3 or 4 works well in practice.
-
-'mckenzie_check_delta_limit <limit>'
-     When error recovery is entered with multiple parsers active, once a
-     solution has been found for one parser, the other parsers are
-     allowed to check only 'mckenzie_check_delta_limit' possible
-     solutions before they fail.  This prevents long recovery times.
-
-'%mckenzie_cost_default <insert> <delete> <push back> <ignore check fail>'
-     McKenzie error recovery default costs for insert, delete, push back
-     single tokens, and for ignoring a semantic check failure; four
-     floating point numbers.
-
-     "Push back" means undo parsing; remove tokens from the parse stack
-     and put them back into the input stream.  This moves the
-     insert/delete point, allowing better solutions.  The push back
-     default cost is also the undo reduce default cost.
-
-     If not specified, costs are zero.  Costs can be negative; they all
-     add linearly.
-
-'%mckenzie_cost_delete <token> <cost>'
-     McKenzie error recovery delete cost for a specific token.
-
-'%mckenzie_cost_fast_forward <cost>'
-     McKenzie error recovery cost for parsing ahead after fixing one
-     error, moving to the next error location.
-
-'%mckenzie_cost_insert <token> <cost>'
-     McKenzie error recovery insert cost for a specific token.
-
-'%mckenzie_cost_fast_forward <cost>'
-     McKenzie error recovery cost for using the 'matching_begin'
-     strategy.
-
-'%mckenzie_cost_push_back <token> <cost>'
-     McKenzie error recovery push back cost for a specific token.
-
-'%mckenzie_cost_undo_reduce <token> <cost>'
-     McKenzie error recovery undo reduce cost for a specific token.
-
-'%mckenzie_enqueue_limit <integer>'
-     McKenzie error recovery limit on possible solutions enqueued (to be
-     checked); default max integer.
-
-'%mckenzie_minimal_complete_cost_delta <cost>'
-     McKenzie error recovery cost added to the cost of an inserted token
-     when the insert is done by the minimal complete strategy; this cost
-     is normally negative.
-
-
-File: wisitoken-user_guide.info,  Node: Other declarations,  Prev: Error 
recovery,  Up: Declarations
-
-3.1.5 Other declarations
-------------------------
-
-'%case_insensitive'
-     If present, keywords are case insensitive in the lexer.
-
-'%conflict <conflict description>'
-     Declare a known conflict.
-
-     Example conflict declaration:
-     %conflict REDUCE/REDUCE in state abstract_limited_opt, 
abstract_limited_synchronized_opt on token NEW
-
-     The conflict description is output by 'wisitoken-bnf-generate' when
-     an undeclared conflict is detected.  If the user decides to not fix
-     the conflict, the description can be copied into the grammar source
-     file, so it will be ignored next time around.
-
-     Resolving conflicts in the grammar can be difficult, but leaving
-     them in can increase parse time and cause ambiguous parses.
-
-'%elisp_face <name>'
-     Declare a name for an elisp face constant.
-
-     When generating Ada code for Emacs, the elisp faces applied by
-     'wisi-face-apply' actions must be declared, so the elisp and Ada
-     code aggree on what they mean.
-
-'%elisp_indent <elisp name> <Ada name>'
-     Declare elisp and Ada names for an indent variable.
-
-     When generating Ada code for Emacs, the elisp indent variables used
-     in 'wisi-indent' actions must be declared, so the elisp and Ada
-     code aggree on what they mean.
-
-'%elisp_action <elisp name> <Ada name>'
-     Declare elisp and Ada names for a custom action subprogram written
-     in Ada.
-
-     The term "elisp" here is historical; the name is not actually used
-     by elisp in the current implementation.
-
-'end_names_optional_option <name>'
-     When generating Ada code for Emacs, the name of the Ada variable
-     determining whether end block names are optional.
-
-     In the Ada language, block names can be repeated at the end; for
-     example:
-
-     Get_Inputs :
-     loop
-     ...
-     end loop Get_Inputs;
-
-     These names are optional in the Ada standard.  Making them required
-     improves error recovery; the recovery algorithm can use matching
-     names to isolate the error.
-
-'generate <generate_algorithm> <output_language> [text_rep]'
-
-     '<generate_algorithm>' is one of 'LALR | LR1 | Packrat_Gen |
-     Packrat_Proc | External'
-
-     '<output_language>' is one of 'Ada | Ada_Emacs'
-
-     The algorithm/output_language pair declares one output source set.
-     Multiple sets can be declared; they are all generated together.
-
-     'text_rep' determines how the parse table is represented; if
-     present, it is in a text file that is loaded at parser run time.
-     If absent, it is in the code.  For very large parse tables, such as
-     for an LR1 parser for a large language like Ada, the text
-     representation may be needed, because the Ada compiler can't handle
-     the very large number of statements that represent the parser table
-     in the code.  The text file can take a long time to read at parser
-     startup (a few seconds for the Ada language).
-
-'%language_runtime'
-     Specify an alternate name for the language runtime package; the
-     default is 'Wisi.<language_name>'.
-
-'%meta_syntax [BNF | EBNF]'
-     Declares the syntax used by the grammar file.  BNF is a minor
-     extension of standard Backus Naur Form; EBNF is a large extension.
-     The default is BNF.
-
-'%no_enum'
-     By default, the generated Ada code includes an enumeration type
-     declaring each token.  This makes the language-specific runtime
-     easier to write (without this type, tokens are identified by
-     integers).
-
-     '%no_enum' causes the generated code to not include the token
-     enumeration type.
-
-'%no_language_runtime'
-     When generating Ada code for Emacs, '%no_language_runtime' causes
-     the generated code to not include the runtime.  Some grammars may
-     need no runtime, particularly if they are small grammars intendend
-     to test some generator feature.
-
-'%partial_recursion'
-     The error recovery algorithm requires computing the recursion
-     present in the language grammar.  For some grammars (such as Java),
-     this is too hard; '%partial_recursion' tells WisiToken to use a
-     simpler approximate calculation.  This will affect the quality of
-     the error recovery, but it will still be robust.
-
-'%start'
-     The start token for the grammar.
-
-'re2c_regexp <name> <value>'
-     Declare a named regular expression with re2c name and syntax.  The
-     name may then occur in another re2c regular expression.
-
-
-File: wisitoken-user_guide.info,  Node: Nonterminals,  Next: Conditional code, 
 Prev: Declarations,  Up: Grammar File Syntax
-
-3.2 Nonterminals
-================
-
-A nonterminal statement declares a nonterminal token, and the associated
-production rules and actions.
-
-   The syntax of a nonterminal statement is:
-
-nonterminal : rhs {| rhs} ;
-   A nonterminal is defined by a list of alternate right hand sides.
-
-rhs : {rhs_item} [action [action]] ;
-   Each right hand side is a list of items, followed by zero to two
-actions; the first is the post-parse action, the second the in-parse
-action.
-
-   In-parse actions are exeuted during the parse, when the production is
-reduced; they can add semantic checks that help during error recovery.
-
-   Post-parse actions are executed after the parse is complete, when a
-node produced by this production is visited during the tree traversal;
-they typically build an abstract syntax tree.
-
-   The actions are written in output-language code; for 'Ada_Emacs'
-output, this is elisp (a hold-over from when WisiToken only output elisp
-code).
-
-   If using BNF:
-rhs_item : token ;
-   Where 'token' is defined by a token declaration.
-
-   if using EBNF:
-rhs_item
-  : token
-  | < identifier = identifier >
-  | rhs_optional_item
-  | rhs_multiple_item
-  | '(' rhs {| rhs} ')'
-  ;
-   Here 'token' is either defined by a token declaration, or the token
-value contained in single quotes.
-
-   The second option is an attribute, as defined by ANTLR; these are
-ignored in wisitoken.
-
-   Parentheses are used to group items.
-
-rhs_optional_item
-  : '[' rhs {| rhs} ']'
-  | '(' rhs {| rhs} ')' '?'
-  | token '?'
-  ;
-   These options all mean the same thing; the content is present zero or
-one times.
-
-rhs_multiple_item
-  : '{' rhs {| rhs} '}'
-  | '{' rhs {| rhs} '}-'
-  | '(' rhs {| rhs} ')+'
-  | '(' rhs {| rhs} ')*'
-  | token '+'
-  | token '*'
-  ;
-   "{}", "()*", and "token*" mean the content is present zero or more
-times.  "{}-", "()+", and "token+" mean the content is present one or
-more times.
-
-
-File: wisitoken-user_guide.info,  Node: Conditional code,  Prev: Nonterminals, 
 Up: Grammar File Syntax
-
-3.3 Conditional code
-====================
-
-It is sometimes necessary to include or exclude some declarations and
-portions of rules based on the choice of lexer or parser.
-
-   Therefore WisiToken supports '%if ... %end if' in the grammar file:
-%if {lexer | parser} = {<lexer> | <generate_algorithm>}
-...
-%end if
-
-   The lines between '%if' and '%end if' are ignored if the current
-lexer or parser is not the one specified in the '%if' condition.
-
-   '%if ... %end if' cannot be nested.
-
-
-
-Tag Table:
-Node: Top727
-Node: Overview1378
-Node: Install2140
-Node: Common grammar problems2637
-Node: Empty choice in list2930
-Node: Grammar File Syntax5912
-Node: Declarations6469
-Node: Raw Code6775
-Node: Keywords7156
-Node: Tokens7468
-Node: Error recovery8803
-Node: Other declarations12525
-Node: Nonterminals17017
-Node: Conditional code19038
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/packages/wisi/wisitoken-wisi_ada.adb 
b/packages/wisi/wisitoken-wisi_ada.adb
deleted file mode 100644
index dd5e072..0000000
--- a/packages/wisi/wisitoken-wisi_ada.adb
+++ /dev/null
@@ -1,160 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2013, 2014, 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-package body WisiToken.Wisi_Ada is
-   use WisiToken.Productions;
-
-   function Only (Item : in Token_ID) return WisiToken.Token_ID_Arrays.Vector
-   is begin
-      return Result : WisiToken.Token_ID_Arrays.Vector do
-         Result.Append (Item);
-      end return;
-   end Only;
-
-   function "&" (Left : in Token_ID; Right : in Token_ID) return 
WisiToken.Token_ID_Arrays.Vector
-   is begin
-      return Result : WisiToken.Token_ID_Arrays.Vector do
-         Result.Append (Left);
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   function "+" (Tokens : in Token_ID_Arrays.Vector; Action : in 
Syntax_Trees.Semantic_Action) return Right_Hand_Side
-   is begin
-      return (Tokens, Recursion => <>, Action => Action, Check => null);
-   end "+";
-
-   function "+" (Tokens : in Token_ID; Action : in 
Syntax_Trees.Semantic_Action) return Right_Hand_Side
-   is begin
-      return (Only (Tokens), Recursion => <>, Action => Action, Check => null);
-   end "+";
-
-   function "+" (Action : in Syntax_Trees.Semantic_Action) return 
Right_Hand_Side
-   is begin
-      return (Tokens => <>, Recursion => <>, Action => Action, Check => null);
-   end "+";
-
-   function Only (Item : in WisiToken.Productions.Right_Hand_Side) return 
WisiToken.Productions.RHS_Arrays.Vector
-   is begin
-      return Result : WisiToken.Productions.RHS_Arrays.Vector do
-         Result.Append (Item);
-      end return;
-   end Only;
-
-   function "or"
-     (Left  : in WisiToken.Productions.Instance;
-      Right : in WisiToken.Productions.Right_Hand_Side)
-     return WisiToken.Productions.Instance
-   is begin
-      return Result : WisiToken.Productions.Instance := Left do
-         Result.RHSs.Append (Right);
-      end return;
-   end "or";
-
-   function "<=" (LHS : in Token_ID; RHSs : in 
WisiToken.Productions.RHS_Arrays.Vector) return Instance
-   is begin
-      return (LHS, RHSs);
-   end "<=";
-
-   function Only (Subject : in Instance) return Prod_Arrays.Vector
-   is begin
-      return Result : Prod_Arrays.Vector do
-         Result.Set_First_Last (Subject.LHS, Subject.LHS);
-         Result (Subject.LHS) := Subject;
-      end return;
-   end Only;
-
-   function Merge (Left, Right : in Instance) return Instance
-   is
-      Index : Integer := Left.RHSs.Last_Index + 1;
-   begin
-      return Result : Instance := Left do
-         Result.RHSs.Set_First_Last (Result.RHSs.First_Index, 
Left.RHSs.Last_Index + Integer (Right.RHSs.Length));
-         for RHS of Right.RHSs loop
-            Result.RHSs (Index) := RHS;
-            Index := Index + 1;
-         end loop;
-      end return;
-   end Merge;
-
-   function "and" (Left : in Instance; Right : in Instance) return 
Prod_Arrays.Vector
-   is begin
-      return Result : Prod_Arrays.Vector do
-         Result.Set_First_Last (Token_ID'Min (Left.LHS, Right.LHS), 
Token_ID'Max (Left.LHS, Right.LHS));
-         if Left.LHS = Right.LHS then
-            Result (Left.LHS) := Merge (Left, Right);
-         else
-            Result (Left.LHS) := Left;
-            Result (Right.LHS) := Right;
-         end if;
-      end return;
-   end "and";
-
-   function "and" (Left : in Prod_Arrays.Vector; Right : in Instance) return 
Prod_Arrays.Vector
-   is begin
-      return Result : Prod_Arrays.Vector := Left do
-         if Right.LHS < Result.First_Index then
-            Result.Set_First_Last (Right.LHS, Result.Last_Index);
-         elsif Right.LHS > Result.Last_Index then
-            Result.Set_First_Last (Result.First_Index, Right.LHS);
-         end if;
-
-         if Result (Right.LHS).LHS = Invalid_Token_ID then
-            Result (Right.LHS) := Right;
-         else
-            Result (Right.LHS) := Merge (Result (Right.LHS), Right);
-         end if;
-      end return;
-   end "and";
-
-   function "and" (Left : in Prod_Arrays.Vector; Right : in 
Prod_Arrays.Vector) return Prod_Arrays.Vector
-   is begin
-      return Result : Prod_Arrays.Vector := Left do
-         if Right.First_Index < Result.First_Index then
-            Result.Set_First_Last (Right.First_Index, Result.Last_Index);
-         elsif Right.First_Index > Result.Last_Index then
-            Result.Set_First_Last (Result.First_Index, Right.First_Index);
-         end if;
-         if Right.Last_Index < Result.First_Index then
-            Result.Set_First_Last (Right.Last_Index, Result.Last_Index);
-         elsif Right.Last_Index > Result.Last_Index then
-            Result.Set_First_Last (Result.First_Index, Right.Last_Index);
-         end if;
-
-         for P of Right loop
-            if Result (P.LHS).LHS = Invalid_Token_ID then
-               Result (P.LHS) := P;
-            else
-               Result (P.LHS) := Merge (Result (P.LHS), P);
-            end if;
-         end loop;
-      end return;
-   end "and";
-
-end WisiToken.Wisi_Ada;
diff --git a/packages/wisi/wisitoken-wisi_ada.ads 
b/packages/wisi/wisitoken-wisi_ada.ads
deleted file mode 100644
index a78643f..0000000
--- a/packages/wisi/wisitoken-wisi_ada.ads
+++ /dev/null
@@ -1,81 +0,0 @@
---  Abstract :
---
---  Type and operations for building a grammar directly in Ada source.
---
---  Copyright (C) 2003, 2013 - 2015, 2017, 2018 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-package WisiToken.Wisi_Ada is
-
-   function Only (Item : in Token_ID) return WisiToken.Token_ID_Arrays.Vector;
-   function "&" (Left : in Token_ID; Right : in Token_ID) return 
WisiToken.Token_ID_Arrays.Vector;
-
-   function "+"
-     (Tokens : in WisiToken.Token_ID_Arrays.Vector;
-      Action : in WisiToken.Syntax_Trees.Semantic_Action)
-     return WisiToken.Productions.Right_Hand_Side;
-   function "+"
-     (Tokens : in Token_ID;
-      Action : in WisiToken.Syntax_Trees.Semantic_Action)
-     return WisiToken.Productions.Right_Hand_Side;
-   function "+" (Action : in WisiToken.Syntax_Trees.Semantic_Action) return 
WisiToken.Productions.Right_Hand_Side;
-   --  Create the right hand side of a production.
-
-   function Only (Item : in WisiToken.Productions.Right_Hand_Side) return 
WisiToken.Productions.RHS_Arrays.Vector;
-   function "+" (Item : in WisiToken.Productions.Right_Hand_Side) return 
WisiToken.Productions.RHS_Arrays.Vector
-     renames Only;
-
-   function "or"
-     (Left  : in WisiToken.Productions.Instance;
-      Right : in WisiToken.Productions.Right_Hand_Side)
-     return WisiToken.Productions.Instance;
-
-   function "<="
-     (LHS  : in Token_ID;
-      RHSs : in WisiToken.Productions.RHS_Arrays.Vector)
-     return WisiToken.Productions.Instance;
-
-   function Only (Subject : in WisiToken.Productions.Instance) return 
WisiToken.Productions.Prod_Arrays.Vector;
-   function "+" (Subject : in WisiToken.Productions.Instance) return 
WisiToken.Productions.Prod_Arrays.Vector
-     renames Only;
-   --  First production in a grammar.
-
-   function "and"
-     (Left  : in WisiToken.Productions.Instance;
-      Right : in WisiToken.Productions.Instance)
-     return WisiToken.Productions.Prod_Arrays.Vector;
-   function "and"
-     (Left  : in WisiToken.Productions.Prod_Arrays.Vector;
-      Right : in WisiToken.Productions.Instance)
-     return WisiToken.Productions.Prod_Arrays.Vector;
-   function "and"
-     (Left : in WisiToken.Productions.Prod_Arrays.Vector;
-      Right : in WisiToken.Productions.Prod_Arrays.Vector)
-     return WisiToken.Productions.Prod_Arrays.Vector;
-   --  Create a grammar
-
-end WisiToken.Wisi_Ada;
diff --git a/packages/wisi/wisitoken.adb b/packages/wisi/wisitoken.adb
deleted file mode 100644
index 9efeb18..0000000
--- a/packages/wisi/wisitoken.adb
+++ /dev/null
@@ -1,367 +0,0 @@
---  Abstract:
---
---  See spec
---
---  Copyright (C) 2009, 2014-2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under the terms of the GNU General Public License
---  as published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. The WisiToken package is
---  distributed in the hope that it will be useful, but WITHOUT ANY
---  WARRANTY; without even the implied warranty of MERCHANTABILITY or
---  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
---  License for more details. You should have received a copy of the
---  GNU General Public License distributed with the WisiToken package;
---  see file GPL.txt. If not, write to the Free Software Foundation,
---  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this unit does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
--------------------------------------------------------------------------------
-
-with Ada.Strings.Fixed;
-package body WisiToken is
-
-   function Padded_Image (Item : in Token_ID; Desc : in Descriptor) return 
String
-   is begin
-      return Ada.Strings.Fixed.Head
-        (Desc.Image (Item).all,
-         (if Item in Desc.First_Terminal .. Desc.Last_Terminal
-          then Desc.Terminal_Image_Width
-          else Desc.Image_Width));
-   end Padded_Image;
-
-   function Image (Item : in Token_ID; Desc : in Descriptor) return String
-   is begin
-      return (if Item = Invalid_Token_ID then "-" else Desc.Image (Item).all);
-   end Image;
-
-   procedure Put_Tokens (Descriptor : in WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-   begin
-      for I in Token_ID'First .. Descriptor.Last_Nonterminal loop
-         Put_Line (Token_ID'Image (I) & " => " & Descriptor.Image (I).all);
-      end loop;
-   end Put_Tokens;
-
-   function Find_ID (Descriptor : in WisiToken.Descriptor; Name : in String) 
return Token_ID
-   is begin
-      for I in Descriptor.Image'Range loop
-         if Descriptor.Image (I).all = Name then
-            return I;
-         end if;
-      end loop;
-      raise SAL.Programmer_Error with "token name '" & Name & "' not found in 
descriptor.image";
-   end Find_ID;
-
-   procedure To_Vector (Item : in Token_ID_Array; Vector : in out 
Token_ID_Arrays.Vector)
-   is
-      J : Integer := Vector.First_Index;
-   begin
-      for ID of Item loop
-         Vector.Replace_Element (J, ID);
-         J := J + 1;
-      end loop;
-   end To_Vector;
-
-   function To_Vector (Item : in Token_ID_Array) return Token_ID_Arrays.Vector
-   is begin
-      return Result : Token_ID_Arrays.Vector do
-         Result.Set_First_Last (Item'First, Item'Last);
-         for I in Item'Range loop
-            Result (I) := Item (I);
-         end loop;
-      end return;
-   end To_Vector;
-
-   function Shared_Prefix (A, B : in Token_ID_Arrays.Vector) return Natural
-   is
-      use all type Ada.Containers.Count_Type;
-      I : Natural := A.First_Index;
-      J : Natural := B.First_Index;
-   begin
-      if A.Length = 0 or B.Length = 0 then
-         return 0;
-      end if;
-
-      loop
-         exit when A (I) /= B (I) or I = A.Last_Index or J = B.Last_Index;
-         I := I + 1;
-         J := J + 1;
-      end loop;
-      return I - 1;
-   end Shared_Prefix;
-
-   function "&" (Left : in Token_ID_Set; Right : in Token_ID) return 
Token_ID_Set
-   is begin
-      return Result : Token_ID_Set := Left do
-         Result (Right) := True;
-      end return;
-   end "&";
-
-   function To_Token_ID_Set (First, Last : in Token_ID; Item : in 
Token_ID_Array) return Token_ID_Set
-   is begin
-      return Result : Token_ID_Set := (First .. Last => False)
-      do
-         for ID of Item loop
-            Result (ID) := True;
-         end loop;
-      end return;
-   end To_Token_ID_Set;
-
-   procedure To_Set (Item : in Token_ID_Arrays.Vector; Set : out Token_ID_Set)
-   is begin
-      for ID of Item loop
-         Set (ID) := True;
-      end loop;
-   end To_Set;
-
-   function To_Array (Item : in Token_ID_Set) return Token_ID_Arrays.Vector
-   is begin
-      return Result : Token_ID_Arrays.Vector do
-         for ID in Item'Range loop
-            if Item (ID) then
-               Result.Append (ID);
-            end if;
-         end loop;
-      end return;
-   end To_Array;
-
-   function Any (Item : in Token_ID_Set) return Boolean
-   is begin
-      for I in Item'Range loop
-         if Item (I) then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Any;
-
-   function Count (Item : in Token_ID_Set) return Integer
-   is
-      Result : Integer := 0;
-   begin
-      for I in Item'Range loop
-         if Item (I) then
-            Result := Result + 1;
-         end if;
-      end loop;
-      return Result;
-   end Count;
-
-   function Image
-     (Item      : in Token_ID_Set;
-      Desc      : in Descriptor;
-      Max_Count : in Integer := Integer'Last;
-      Inverted  : in Boolean := False)
-     return String
-   is
-      use Ada.Strings.Unbounded;
-      Result     : Unbounded_String;
-      Need_Comma : Boolean := False;
-      Count      : Integer := 0;
-
-      function Include (Item : in Boolean) return Boolean
-      is begin
-         if not Inverted then
-            return Item;
-
-         else
-            return not Item;
-         end if;
-      end Include;
-
-   begin
-      for I in Item'Range loop
-         if Include (Item (I)) then
-            if Need_Comma then
-               Result := Result & ", ";
-            end if;
-            Result     := Result & Image (I, Desc);
-            Need_Comma := True;
-            Count := Count + 1;
-            if Count = Max_Count then
-               return To_String (Result);
-            end if;
-         end if;
-      end loop;
-      return To_String (Result);
-   end Image;
-
-   function Image (Item : in Production_ID) return String
-   is begin
-      return '(' & Trimmed_Image (Item.LHS) & ',' & Natural'Image (Item.RHS) & 
')';
-   end Image;
-
-   function Trimmed_Image (Item : in Production_ID) return String
-   is begin
-      return Trimmed_Image (Item.LHS) & '.' & Trimmed_Image (Item.RHS);
-   end Trimmed_Image;
-
-   function Padded_Image (Item : in Production_ID; Width : in Integer) return 
String
-   is
-      use Ada.Strings.Fixed;
-   begin
-      return Result : String (1 .. Width) do
-         Move (Trimmed_Image (Item), Result, Justify => Ada.Strings.Right);
-      end return;
-   end Padded_Image;
-
-   function To_Vector (Item : in Production_ID_Array) return 
Production_ID_Arrays.Vector
-   is begin
-      return Result : Production_ID_Arrays.Vector do
-         for I of Item loop
-            Result.Append (I);
-         end loop;
-      end return;
-   end To_Vector;
-
-   function Slice (Item : in Token_Array_Token_Set; I : in Token_ID) return 
Token_ID_Set
-   is
-      Result : Token_ID_Set := (Item'First (2) .. Item'Last (2) => False);
-   begin
-      for J in Result'Range loop
-         Result (J) := Item (I, J);
-      end loop;
-      return Result;
-   end Slice;
-
-   function Any (Item : in Token_Array_Token_Set; I : in Token_ID) return 
Boolean
-   is begin
-      for J in Item'Range (2) loop
-         if Item (I, J) then
-            return True;
-         end if;
-      end loop;
-      return False;
-   end Any;
-
-   function Any (Item : in Token_Array_Token_Set) return Boolean
-   is begin
-      for I in Item'Range (1) loop
-         for J in Item'Range (2) loop
-            if Item (I, J) then
-               return True;
-            end if;
-         end loop;
-      end loop;
-      return False;
-   end Any;
-
-   procedure Or_Slice (Item : in out Token_Array_Token_Set; I : in Token_ID; 
Value : in Token_ID_Set)
-   is begin
-      for J in Item'Range (2) loop
-         Item (I, J) := Item (I, J) or Value (J);
-      end loop;
-   end Or_Slice;
-
-   procedure Put (Descriptor : in WisiToken.Descriptor; Item : in 
Token_Array_Token_Set)
-   is
-      use Ada.Text_IO;
-      Paren_Done : Boolean := False;
-   begin
-      if not Any (Item) then
-         Put_Line ("(others => (others => False))");
-      else
-         Put ("(");
-         for I in Item'Range (1) loop
-            if Any (Item, I) then
-               Put_Line (" " & Image (I, Descriptor) & " =>");
-               Put ("  (");
-               Paren_Done := False;
-               for J in Item'Range (2) loop
-                  if Item (I, J) then
-                     if Paren_Done then
-                        Put_Line (" |");
-                        Put ("   " & Image (J, Descriptor));
-                     else
-                        Paren_Done := True;
-                        Put (Image (J, Descriptor));
-                     end if;
-                  end if;
-               end loop;
-               if Paren_Done then
-                  Put_Line (" => True,");
-                  Put_Line ("   others => False)");
-               else
-                  Put_Line (" others => False),");
-               end if;
-            end if;
-         end loop;
-         Put_Line ((if Paren_Done then " " else "") & "others => (others => 
False))");
-      end if;
-   end Put;
-
-   function Error_Message
-     (File_Name : in String;
-      Line      : in Line_Number_Type;
-      Column    : in Ada.Text_IO.Count;
-      Message   : in String)
-     return String
-   is begin
-      return File_Name & ":" &
-        Trimmed_Image (if Line = Invalid_Line_Number then Integer'(0) else 
Integer (Line)) & ":" &
-        Trimmed_Image (Integer (Column)) & ": " &
-        Message;
-   end Error_Message;
-
-   function Image (Item : in Buffer_Region) return String
-   is begin
-      return "(" & Trimmed_Image (Integer (Item.First)) & " ." & 
Buffer_Pos'Image (Item.Last) & ")";
-   end Image;
-
-   function "and" (Left, Right : in Buffer_Region) return Buffer_Region
-   is begin
-      return (Buffer_Pos'Min (Left.First, Right.First), Buffer_Pos'Max 
(Left.Last, Right.Last));
-   end "and";
-
-   function Image
-     (Item       : in Base_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is
-      ID_Image : constant String := WisiToken.Image (Item.ID, Descriptor);
-   begin
-      if Item.Char_Region = Null_Buffer_Region then
-         return "(" & ID_Image & ")";
-
-      else
-         return "(" & ID_Image & ", " & Image (Item.Char_Region) & ")";
-      end if;
-   end Image;
-
-   function Image
-     (Token      : in Base_Token_Index;
-      Terminals  : in Base_Token_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is begin
-      if Token = Invalid_Token_Index then
-         return "<invalid_token_index>";
-      else
-         return Token_Index'Image (Token) & ":" & Image (Terminals (Token), 
Descriptor);
-      end if;
-   end Image;
-
-   function Image
-     (Item       : in Recover_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is begin
-      return
-        (if Item.Min_Terminal_Index = Invalid_Token_Index
-         then ""
-         else Trimmed_Image (Item.Min_Terminal_Index) & ":") &
-        "(" & Image (Item.ID, Descriptor) &
-        (if Item.Byte_Region = Null_Buffer_Region then "" else ", " & Image 
(Item.Byte_Region)) & ")";
-   end Image;
-
-end WisiToken;
diff --git a/packages/wisi/wisitoken.ads b/packages/wisi/wisitoken.ads
deleted file mode 100644
index 2c7a11b..0000000
--- a/packages/wisi/wisitoken.ads
+++ /dev/null
@@ -1,508 +0,0 @@
---  Abstract:
---
---  Root of WisiToken lexer/parser generator and exector.
---
---  The token type is an integer subtype, not an enumeration type, to
---  avoid making this package generic, which would make all other
---  packages generic.
---
---  Additional information about a token can be stored in the
---  'augmented' field of the syntax tree; see
---  wisitoken-syntax_trees.ads.
---
---  References:
---
---  [dragon] "Compilers Principles, Techniques, and Tools" by Aho,
---  Sethi, and Ullman (aka: "The [Red] Dragon Book" due to the dragon
---  on the cover).
---
---  Copyright (C) 2009, 2010, 2013 - 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  This file is part of the WisiToken package.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
---
---  This software was originally developed with the name OpenToken by
---  the following company, and was released as open-source software as
---  a service to the community:
---
---           FlightSafety International Simulation Systems Division
---                    Broken Arrow, OK  USA  918-259-4000
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with Ada.Unchecked_Deallocation;
-with SAL.Generic_Decimal_Image;
-with SAL.Gen_Trimmed_Image;
-with SAL.Gen_Unbounded_Definite_Queues;
-with SAL.Gen_Unbounded_Definite_Vectors.Gen_Image;
-with SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux;
-with SAL.Gen_Unconstrained_Array_Image;
-package WisiToken is
-
-   Partial_Parse : exception; -- a partial parse terminated.
-
-   Syntax_Error : exception; -- no recovery for a syntax error was found
-
-   Parse_Error : exception; -- a non-recoverable non-fatal error was 
encountered; editing the input can fix the error.
-
-   Fatal_Error : exception; -- Error in code or grammar; editing input cannot 
fix error.
-
-   Grammar_Error : exception;
-   --  Grammar file has bad syntax, or grammar is not consistent (ie
-   --  unused tokens, missing productions, invalid actions)
-
-   User_Error : exception; -- other user error (ie command line parameter)
-
-   --  SAL.Programmer_Error : exception; -- a programming convention has been 
violated
-
-   subtype Positive_Index_Type is SAL.Peek_Type;
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (SAL.Base_Peek_Type);
-
-   type Unknown_State_Index is new Integer range -1 .. Integer'Last;
-   subtype State_Index is Unknown_State_Index range 0 .. 
Unknown_State_Index'Last;
-   Unknown_State : constant Unknown_State_Index := -1;
-
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Unknown_State_Index);
-
-   package State_Index_Queues is new SAL.Gen_Unbounded_Definite_Queues 
(State_Index);
-   package State_Index_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive, State_Index, Default_Element => State_Index'Last);
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Integer);
-   function Image is new State_Index_Arrays.Gen_Image (Trimmed_Image);
-
-   ----------
-   --  Token IDs
-
-   type Token_ID is range 0 .. Integer'Last; -- 0 origin to match elisp array
-
-   Invalid_Token_ID : constant Token_ID := Token_ID'Last;
-
-   type String_Access_Constant is access constant String;
-   type Token_ID_Array_String is array (Token_ID range <>) of 
String_Access_Constant;
-   type Token_ID_Array_Natural is array (Token_ID range <>) of Natural;
-
-   type Descriptor
-     (First_Terminal    : Token_ID;
-      Last_Terminal     : Token_ID;
-      First_Nonterminal : Token_ID;
-      Last_Nonterminal  : Token_ID;
-      EOI_ID            : Token_ID;
-      Accept_ID         : Token_ID)
-   is record
-      --  Tokens in the range Token_ID'First .. First_Terminal - 1 are
-      --  non-reporting (comments, whitespace), and thus are not used in
-      --  generating parse tables.
-      --
-      --  Tokens in the range Last_Terminal + 1 .. Last_Nonterminal are
-      --  the nonterminals of a grammar.
-      --
-      --  Components are discriminants if they can be specified statically.
-
-      Case_Insensitive : Boolean;  -- keywords and names
-      New_Line_ID      : Token_ID;
-
-      String_1_ID : Token_ID;
-      String_2_ID : Token_ID;
-      --  String_1 delimited by '; String_2 by ".
-      --
-      --  Used by missing quote error recovery. If the language does not
-      --  have two kinds of string literals, set one or both of these to
-      --  Invalid_Token_ID.
-
-      Image : Token_ID_Array_String (Token_ID'First .. Last_Nonterminal);
-      --  User names for tokens.
-
-      Terminal_Image_Width : Integer;
-      Image_Width          : Integer; --  max width of Image
-
-      Last_Lookahead : Token_ID;
-      --  LALR generate needs a 'Propagate_ID' lookahead that is distinct
-      --  from all terminals. Since lookaheads are Token_ID_Set, we need to
-      --  allocate First_Terminal .. Last_Terminal for LR1 generate, and
-      --  First_Terminal .. Propagate_ID for LALR generate, so we define
-      --  Last_Lookahead. After the LR table is generated, Last_Lookahead is
-      --  no longer used.
-   end record;
-   type Descriptor_Access is access Descriptor;
-   type Descriptor_Access_Constant is access constant Descriptor;
-
-   function Padded_Image (Item : in Token_ID; Desc : in Descriptor) return 
String;
-   --  Return Desc.Image (Item), padded to Terminal_Image_Width (if Item
-   --  is a terminal) or to Image_Width.
-
-   function Image (Item : in Token_ID; Desc : in Descriptor) return String;
-   --  Return Desc.Image (Item), or "-" for Invalid_Token_ID.
-
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Token_ID);
-
-   procedure Put_Tokens (Descriptor : in WisiToken.Descriptor);
-   --  Put user readable token list (token_id'first ..
-   --  descriptor.last_nonterminal) to Ada.Text_IO.Current_Output
-
-   function Find_ID (Descriptor : in WisiToken.Descriptor; Name : in String) 
return Token_ID;
-   --  Return index of Name in Descriptor.Image. If not found, raise 
Programmer_Error.
-
-   type Token_ID_Array is array (Positive range <>) of Token_ID;
-   --  Index is not Positive_Index_Type, mostly for historical reasons.
-
-   package Token_ID_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive, Token_ID, Default_Element => Invalid_Token_ID);
-
-   function Image is new Token_ID_Arrays.Gen_Image_Aux (Descriptor, 
Trimmed_Image, Image);
-   function Image_No_Assoc (Item : in Token_ID_Arrays.Vector; Aux : in 
Descriptor) return String
-     is (Image (Item, Aux, Association => False));
-
-   function Trimmed_Image is new Token_ID_Arrays.Gen_Image (Trimmed_Image);
-
-   procedure To_Vector (Item : in Token_ID_Array; Vector : in out 
Token_ID_Arrays.Vector);
-   function To_Vector (Item : in Token_ID_Array) return Token_ID_Arrays.Vector;
-
-   function Shared_Prefix (A, B : in Token_ID_Arrays.Vector) return Natural;
-   --  Return last index in A of a prefix shared between A, B; 0 if none.
-
-   type Token_ID_Set is array (Token_ID range <>) of Boolean;
-   type Token_ID_Set_Access is access Token_ID_Set;
-
-   function "&" (Left : in Token_ID_Set; Right : in Token_ID) return 
Token_ID_Set;
-   --  Include Left and Right in result.
-
-   function To_Token_ID_Set (First, Last : in Token_ID; Item : in 
Token_ID_Array) return Token_ID_Set;
-   --  First, Last determine size of result.
-   --  For each element in Item, set result (element) True.
-
-   procedure To_Set (Item : in Token_ID_Arrays.Vector; Set : out Token_ID_Set);
-   --  For each element of Item, set Set (element) True.
-
-   function To_Array (Item : in Token_ID_Set) return Token_ID_Arrays.Vector;
-
-   function Any (Item : in Token_ID_Set) return Boolean;
-
-   function Count (Item : in Token_ID_Set) return Integer;
-   --  Count of True elements.
-
-   function Image
-     (Item      : in Token_ID_Set;
-      Desc      : in Descriptor;
-      Max_Count : in Integer := Integer'Last;
-      Inverted  : in Boolean := False)
-     return String;
-   --  For diagnostics; not Ada syntax.
-
-   type Token_Array_Token_Set is array (Token_ID range <>, Token_ID range <>) 
of Boolean;
-
-   function Slice (Item : in Token_Array_Token_Set; I : in Token_ID) return 
Token_ID_Set;
-   function Any (Item : in Token_Array_Token_Set; I : in Token_ID) return 
Boolean;
-   function Any (Item : in Token_Array_Token_Set) return Boolean;
-   procedure Or_Slice (Item : in out Token_Array_Token_Set; I : in Token_ID; 
Value : in Token_ID_Set);
-
-   procedure Put (Descriptor : in WisiToken.Descriptor; Item : in 
Token_Array_Token_Set);
-   --  Put Item to Ada.Text_IO.Current_Output, using valid Ada aggregate
-   --  syntax.
-
-   type Token_Array_Token_ID is array (Token_ID range <>) of Token_ID;
-
-   package Token_Sequence_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_ID, Token_ID_Arrays.Vector, Default_Element => 
Token_ID_Arrays.Empty_Vector);
-
-   ----------
-   --  Production IDs; see wisitoken-productions.ads for more
-
-   type Production_ID is record
-      LHS : Token_ID := Invalid_Token_ID;
-      RHS : Natural  := 0;
-      --  Index into the production table.
-   end record;
-
-   Invalid_Production_ID : constant Production_ID := (others => <>);
-
-   function Image (Item : in Production_ID) return String;
-   --  Ada positional aggregate syntax, for code generation.
-
-   function Trimmed_Image (Item : in Production_ID) return String;
-   --  Nonterm.rhs_index, both integers, no leading or trailing space;
-   --  for parse table output and diagnostics.
-
-   Prod_ID_Image_Width : constant Integer := 7;
-   --  Max width of Trimmed_Image
-
-   function Padded_Image (Item : in Production_ID; Width : in Integer) return 
String;
-   --  Trimmed_Image padded with leading spaces to Width
-
-   package Production_ID_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive, Production_ID, Default_Element => Invalid_Production_ID);
-   function Image is new Production_ID_Arrays.Gen_Image (Image);
-   function Trimmed_Image is new Production_ID_Arrays.Gen_Image 
(Trimmed_Image);
-
-   type Production_ID_Array is array (Natural range <>) of Production_ID;
-
-   function To_Vector (Item : in Production_ID_Array) return 
Production_ID_Arrays.Vector;
-   function "+" (Item : in Production_ID_Array) return 
Production_ID_Arrays.Vector renames To_Vector;
-   function "+" (Item : in Production_ID) return Production_ID_Arrays.Vector 
is (To_Vector ((1 => Item)));
-
-   type Token_Array_Production_ID is array (Token_ID range <>) of 
Production_ID;
-
-   type Recursion_Class is (None, Direct_Left, Other_Left, Other, Other_Right, 
Direct_Right);
-   function Image (Item : in Recursion_Class) return String
-     is (case Item is
-         when None         => "None",
-         when Direct_Left  => "Direct_Left",
-         when Other_Left   => "Other_Left",
-         when Other        => "Other",
-         when Other_Right  => "Other_Right",
-         when Direct_Right => "Direct_Right");
-
-   ----------
-   --  Tokens
-
-   type Base_Buffer_Pos is range 0 .. Integer'Last;
-   subtype Buffer_Pos is Base_Buffer_Pos range 1 .. Base_Buffer_Pos'Last; -- 
match Emacs buffer origin.
-   type Buffer_Region is record
-      First : Buffer_Pos;
-      Last  : Base_Buffer_Pos; --  allow representing null range.
-   end record;
-
-   Invalid_Buffer_Pos : constant Buffer_Pos    := Buffer_Pos'Last;
-   Null_Buffer_Region : constant Buffer_Region := (Buffer_Pos'Last, 
Buffer_Pos'First);
-
-   function Length (Region : in Buffer_Region) return Natural is (Natural 
(Region.Last - Region.First + 1));
-
-   function Inside (Pos : in Buffer_Pos; Region : in Buffer_Region) return 
Boolean
-     is (Region.First <= Pos and Pos <= Region.Last);
-
-   function Image (Item : in Buffer_Region) return String;
-
-   function "and" (Left, Right : in Buffer_Region) return Buffer_Region;
-   --  Return region enclosing both Left and Right.
-
-   type Line_Number_Type is range 1 .. Natural'Last; -- Match Emacs buffer 
line numbers.
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Line_Number_Type);
-
-   Invalid_Line_Number : constant Line_Number_Type := Line_Number_Type'Last;
-
-   --  Syntax tree nodes.
-   type Node_Index is range 0 .. Integer'Last;
-   subtype Valid_Node_Index is Node_Index range 1 .. Node_Index'Last;
-   --  Note that Valid_Node_Index includes Deleted_Child.
-
-   Invalid_Node_Index : constant Node_Index := Node_Index'First;
-   Deleted_Child      : constant Node_Index := Node_Index'Last;
-
-   type Valid_Node_Index_Array is array (Positive_Index_Type range <>) of 
Valid_Node_Index;
-   --  Index matches Base_Token_Array, Augmented_Token_Array
-
-   function Image is new SAL.Generic_Decimal_Image (Valid_Node_Index);
-   --  Has Width parameter
-
-   function Image (Item : in Valid_Node_Index) return String
-     is (Image (Item, 4));
-
-   function Image is new SAL.Gen_Unconstrained_Array_Image
-     (Positive_Index_Type, Valid_Node_Index, Valid_Node_Index_Array, Image);
-
-   package Valid_Node_Index_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Positive_Index_Type, Valid_Node_Index, Default_Element => 
Valid_Node_Index'Last);
-   --  Index matches Valid_Node_Index_Array.
-
-   type Base_Token is tagged record
-      --  Base_Token is used in the core parser. The parser only needs ID and 
Tree_Index;
-      --  semantic checks need Byte_Region to compare names. Line, Col, and
-      --  Char_Region are included for error messages.
-
-      ID         : Token_ID   := Invalid_Token_ID;
-      Tree_Index : Node_Index := Invalid_Node_Index;
-
-      Byte_Region : Buffer_Region := Null_Buffer_Region;
-      --  Index into the Lexer buffer for the token text.
-
-      Line   : Line_Number_Type  := Invalid_Line_Number;
-      Column : Ada.Text_IO.Count := 0;
-      --  At start of token.
-
-      Char_Region : Buffer_Region := Null_Buffer_Region;
-      --  Character position, useful for finding the token location in Emacs
-      --  buffers.
-   end record;
-
-   type Base_Token_Class_Access is access all Base_Token'Class;
-   type Base_Token_Class_Access_Constant is access constant Base_Token'Class;
-
-   function Image
-     (Item       : in Base_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-   --  For debug/test messages.
-
-   procedure Free is new Ada.Unchecked_Deallocation (Base_Token'Class, 
Base_Token_Class_Access);
-
-   Invalid_Token : constant Base_Token := (others => <>);
-
-   type Base_Token_Index is range 0 .. Integer'Last;
-   subtype Token_Index is Base_Token_Index range 1 .. Base_Token_Index'Last;
-
-   Invalid_Token_Index : constant Base_Token_Index := Base_Token_Index'First;
-
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Base_Token_Index);
-
-   type Token_Index_Array is array (Natural range <>) of Token_Index;
-
-   package Recover_Token_Index_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Natural, Base_Token_Index, Default_Element => Invalid_Token_Index);
-
-   type Base_Token_Array is array (Positive_Index_Type range <>) of Base_Token;
-
-   package Base_Token_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_Index, Base_Token, Default_Element => (others => <>));
-   type Base_Token_Array_Access is access all Base_Token_Arrays.Vector;
-   type Base_Token_Array_Access_Constant is access constant 
Base_Token_Arrays.Vector;
-
-   function Image is new Base_Token_Arrays.Gen_Image_Aux 
(WisiToken.Descriptor, Trimmed_Image, Image);
-
-   function Image
-     (Token      : in Base_Token_Index;
-      Terminals  : in Base_Token_Arrays.Vector;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-
-   package Line_Begin_Token_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (Line_Number_Type, Base_Token_Index, Default_Element => 
Invalid_Token_Index);
-
-   type Recover_Token is record
-      --  Maintaining a syntax tree during error recovery is too slow, so we
-      --  store enough information in the recover stack to perform
-      --  Semantic_Checks, Language_Fixes, and Push_Back operations. and to
-      --  apply the solution to the main parser state. We make thousands of
-      --  copies of the parse stack during recover, so minimizing size and
-      --  compute time for this is critical.
-      ID : Token_ID := Invalid_Token_ID;
-
-      Byte_Region : Buffer_Region := Null_Buffer_Region;
-      --  Byte_Region is used to detect empty tokens, for cost and other 
issues.
-
-      Min_Terminal_Index : Base_Token_Index := Invalid_Token_Index;
-      --  For terminals, index of this token in Shared_Parser.Terminals. For
-      --  nonterminals, minimum of contained tokens (Invalid_Token_Index if
-      --  empty). For virtuals, Invalid_Token_Index. Used for push_back of
-      --  nonterminals.
-
-      Name : Buffer_Region := Null_Buffer_Region;
-      --  Set and used by semantic_checks.
-
-      Virtual : Boolean := True;
-      --  For terminals, True if inserted by recover. For nonterminals, True
-      --  if any contained token has Virtual = True.
-   end record;
-
-   function Image
-     (Item       : in Recover_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-
-   type Recover_Token_Array is array (Positive_Index_Type range <>) of 
Recover_Token;
-
-   package Recover_Token_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Token_Index, Recover_Token, Default_Element => (others => <>));
-
-   function Image is new Recover_Token_Arrays.Gen_Image_Aux 
(WisiToken.Descriptor, Trimmed_Image, Image);
-
-   type Base_Identifier_Index is range 0 .. Integer'Last;
-   subtype Identifier_Index is Base_Identifier_Index range 1 .. 
Base_Identifier_Index'Last;
-   --  For virtual identifiers created during syntax tree rewrite.
-
-   Invalid_Identifier_Index : constant Base_Identifier_Index := 
Base_Identifier_Index'First;
-
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Base_Identifier_Index);
-
-   ----------
-   --  Trace, debug
-
-   Trace_Parse : Integer  := 0;
-   --  If Trace_Parse > 0, Parse prints messages helpful for debugging
-   --  the grammar and/or the parser; higher value prints more.
-   --
-   --  Trace_Parse levels; output info if Trace_Parse > than:
-   --
-   Outline     : constant := 0; -- spawn/terminate parallel parsers, error 
recovery enter/exit
-   Detail      : constant := 1; -- add each parser cycle
-   Extra       : constant := 2; -- add pending semantic state operations
-   Lexer_Debug : constant := 3; -- add lexer debug
-
-   Trace_McKenzie : Integer  := 0;
-   --  If Trace_McKenzie > 0, Parse prints messages helpful for debugging 
error recovery.
-   --
-   --  Outline - error recovery enter/exit
-   --  Detail  - add each error recovery configuration
-   --  Extra   - add error recovery parse actions
-
-   Trace_Action : Integer := 0;
-   --  Output during Execute_Action, and unit tests.
-
-   Trace_Generate_EBNF             : Integer := 0;
-   Trace_Generate_Table            : Integer := 0;
-   Trace_Generate_Minimal_Complete : Integer := 0;
-   --  Output during grammar generation.
-
-   Trace_Time : Boolean := False;
-   --  Output execution time for various things.
-
-   Debug_Mode : Boolean := False;
-   --  If True, Output stack traces, propagate exceptions to top level.
-   --  Otherwise, be robust to errors, so user does not notice them.
-
-   type Trace (Descriptor : not null access constant WisiToken.Descriptor) is 
abstract tagged limited null record;
-   --  Output for tests/debugging. Descriptor included here because many
-   --  uses of Trace will use Image (Item, Descriptor);
-
-   procedure Set_Prefix (Trace : in out WisiToken.Trace; Prefix : in String) 
is abstract;
-   --  Prepend Prefix to all subsequent messages. Usefull for adding
-   --  comment syntax.
-
-   procedure Put (Trace : in out WisiToken.Trace; Item : in String; Prefix : 
in Boolean := True) is abstract;
-   --  Put Item to the Trace display. If Prefix is True, prepend the stored 
prefix.
-
-   procedure Put_Line (Trace : in out WisiToken.Trace; Item : in String) is 
abstract;
-   --  Put Item to the Trace display, followed by a newline.
-
-   procedure New_Line (Trace : in out WisiToken.Trace) is abstract;
-   --  Put a newline to the Trace display.
-
-   procedure Put_Clock (Trace : in out WisiToken.Trace; Label : in String) is 
abstract;
-   --  Put Ada.Calendar.Clock to Trace.
-
-   ----------
-   --  Misc
-
-   function "+" (Item : in String) return 
Ada.Strings.Unbounded.Unbounded_String
-     renames Ada.Strings.Unbounded.To_Unbounded_String;
-
-   function "-" (Item : in Ada.Strings.Unbounded.Unbounded_String) return 
String
-     renames Ada.Strings.Unbounded.To_String;
-
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image 
(Ada.Containers.Count_Type);
-
-   function Error_Message
-     (File_Name : in String;
-      Line      : in Line_Number_Type;
-      Column    : in Ada.Text_IO.Count;
-      Message   : in String)
-     return String;
-   --  Return Gnu-formatted error message.
-
-   type Names_Array is array (Integer range <>) of String_Access_Constant;
-   type Names_Array_Access is access Names_Array;
-   type Names_Array_Array is array (WisiToken.Token_ID range <>) of 
Names_Array_Access;
-   type Names_Array_Array_Access is access Names_Array_Array;
-
-end WisiToken;
diff --git a/packages/wisi/wisitoken_grammar_actions.adb 
b/packages/wisi/wisitoken_grammar_actions.adb
deleted file mode 100644
index 8819828..0000000
--- a/packages/wisi/wisitoken_grammar_actions.adb
+++ /dev/null
@@ -1,182 +0,0 @@
---  generated parser support file.
---  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c 
wisitoken_grammar.wy
---
-
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  Author: Stephen Leake <stephe-leake@stephe-leake.org>
---
---  This file is part of GNU Emacs.
---
---  GNU Emacs is free software: you can redistribute it and/or modify
---  it under the terms of the GNU General Public License as published by
---  the Free Software Foundation, either version 3 of the License, or
---  (at your option) any later version.
---
---  GNU Emacs is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY; without even the implied warranty of
---  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---  GNU General Public License for more details.
---
---  You should have received a copy of the GNU General Public License
---  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-with WisiToken_Grammar_Runtime; use WisiToken_Grammar_Runtime;
-
-package body Wisitoken_Grammar_Actions is
-
-   procedure declaration_0
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Declaration (User_Data, Tree, Tokens);
-   end declaration_0;
-
-   procedure declaration_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Declaration (User_Data, Tree, Tokens);
-   end declaration_1;
-
-   procedure declaration_2
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Declaration (User_Data, Tree, Tokens);
-   end declaration_2;
-
-   procedure declaration_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Declaration (User_Data, Tree, Tokens);
-   end declaration_3;
-
-   procedure declaration_4
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Start_If (User_Data, Tree, Tokens);
-   end declaration_4;
-
-   procedure declaration_5
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Tree, Nonterm, Tokens);
-   begin
-      End_If (User_Data);
-   end declaration_5;
-
-   procedure nonterminal_0
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Nonterminal (User_Data, Tree, Tokens);
-   end nonterminal_0;
-
-   procedure nonterminal_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Add_Nonterminal (User_Data, Tree, Tokens);
-   end nonterminal_1;
-
-   procedure rhs_item_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_item_1;
-
-   procedure rhs_item_2
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_item_2;
-
-   procedure rhs_item_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_item_3;
-
-   procedure rhs_item_4
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_item_4;
-
-   procedure rhs_item_5
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_item_5;
-
-   procedure rhs_optional_item_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      pragma Unreferenced (Nonterm);
-   begin
-      Check_EBNF (User_Data, Tree, Tokens, 1);
-   end rhs_optional_item_3;
-
-end Wisitoken_Grammar_Actions;
diff --git a/packages/wisi/wisitoken_grammar_actions.ads 
b/packages/wisi/wisitoken_grammar_actions.ads
deleted file mode 100644
index 1308267..0000000
--- a/packages/wisi/wisitoken_grammar_actions.ads
+++ /dev/null
@@ -1,237 +0,0 @@
---  generated parser support file.
---  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c PROCESS 
wisitoken_grammar.wy
---
-
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  Author: Stephen Leake <stephe-leake@stephe-leake.org>
---
---  This file is part of GNU Emacs.
---
---  GNU Emacs is free software: you can redistribute it and/or modify
---  it under the terms of the GNU General Public License as published by
---  the Free Software Foundation, either version 3 of the License, or
---  (at your option) any later version.
---
---  GNU Emacs is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY; without even the implied warranty of
---  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---  GNU General Public License for more details.
---
---  You should have received a copy of the GNU General Public License
---  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-with WisiToken.Syntax_Trees;
-package Wisitoken_Grammar_Actions is
-
-   Descriptor : aliased WisiToken.Descriptor :=
-     (First_Terminal    => 3,
-      Last_Terminal     => 36,
-      First_Nonterminal => 37,
-      Last_Nonterminal  => 56,
-      EOI_ID            => 36,
-      Accept_ID         => 37,
-      Case_Insensitive  => False,
-      New_Line_ID       => 1,
-      String_1_ID       => 35,
-      String_2_ID       => 34,
-      Image             =>
-        (new String'("WHITESPACE"),
-         new String'("NEW_LINE"),
-         new String'("COMMENT"),
-         new String'("CODE"),
-         new String'("END"),
-         new String'("IF"),
-         new String'("KEYWORD"),
-         new String'("NON_GRAMMAR"),
-         new String'("TOKEN"),
-         new String'("RAW_CODE"),
-         new String'("REGEXP"),
-         new String'("ACTION"),
-         new String'("BAR"),
-         new String'("COLON"),
-         new String'("COLON_COLON_EQUAL"),
-         new String'("COMMA"),
-         new String'("EQUAL"),
-         new String'("GREATER"),
-         new String'("LEFT_BRACE"),
-         new String'("LEFT_BRACKET"),
-         new String'("LEFT_PAREN"),
-         new String'("LESS"),
-         new String'("MINUS"),
-         new String'("PERCENT"),
-         new String'("PLUS"),
-         new String'("QUESTION"),
-         new String'("RIGHT_BRACE"),
-         new String'("RIGHT_BRACKET"),
-         new String'("RIGHT_PAREN"),
-         new String'("SEMICOLON"),
-         new String'("SLASH"),
-         new String'("STAR"),
-         new String'("NUMERIC_LITERAL"),
-         new String'("IDENTIFIER"),
-         new String'("STRING_LITERAL_1"),
-         new String'("STRING_LITERAL_2"),
-         new String'("Wisi_EOI"),
-         new String'("wisitoken_accept"),
-         new String'("declaration"),
-         new String'("token_keyword_non_grammar"),
-         new String'("identifier_list"),
-         new String'("declaration_item_list"),
-         new String'("declaration_item"),
-         new String'("nonterminal"),
-         new String'("semicolon_opt"),
-         new String'("rhs_list"),
-         new String'("rhs"),
-         new String'("rhs_attribute"),
-         new String'("rhs_element"),
-         new String'("rhs_item_list"),
-         new String'("rhs_item"),
-         new String'("rhs_group_item"),
-         new String'("rhs_optional_item"),
-         new String'("rhs_multiple_item"),
-         new String'("rhs_alternative_list"),
-         new String'("compilation_unit"),
-         new String'("compilation_unit_list")),
-      Terminal_Image_Width => 17,
-      Image_Width          => 25,
-      Last_Lookahead       => 37);
-
-   type Token_Enum_ID is
-     (WHITESPACE_ID,
-      NEW_LINE_ID,
-      COMMENT_ID,
-      CODE_ID,
-      END_ID,
-      IF_ID,
-      KEYWORD_ID,
-      NON_GRAMMAR_ID,
-      TOKEN_ID,
-      RAW_CODE_ID,
-      REGEXP_ID,
-      ACTION_ID,
-      BAR_ID,
-      COLON_ID,
-      COLON_COLON_EQUAL_ID,
-      COMMA_ID,
-      EQUAL_ID,
-      GREATER_ID,
-      LEFT_BRACE_ID,
-      LEFT_BRACKET_ID,
-      LEFT_PAREN_ID,
-      LESS_ID,
-      MINUS_ID,
-      PERCENT_ID,
-      PLUS_ID,
-      QUESTION_ID,
-      RIGHT_BRACE_ID,
-      RIGHT_BRACKET_ID,
-      RIGHT_PAREN_ID,
-      SEMICOLON_ID,
-      SLASH_ID,
-      STAR_ID,
-      NUMERIC_LITERAL_ID,
-      IDENTIFIER_ID,
-      STRING_LITERAL_1_ID,
-      STRING_LITERAL_2_ID,
-      Wisi_EOI_ID,
-      wisitoken_accept_ID,
-      declaration_ID,
-      token_keyword_non_grammar_ID,
-      identifier_list_ID,
-      declaration_item_list_ID,
-      declaration_item_ID,
-      nonterminal_ID,
-      semicolon_opt_ID,
-      rhs_list_ID,
-      rhs_ID,
-      rhs_attribute_ID,
-      rhs_element_ID,
-      rhs_item_list_ID,
-      rhs_item_ID,
-      rhs_group_item_ID,
-      rhs_optional_item_ID,
-      rhs_multiple_item_ID,
-      rhs_alternative_list_ID,
-      compilation_unit_ID,
-      compilation_unit_list_ID);
-
-   type Token_Enum_ID_Array is array (Positive range <>) of Token_Enum_ID;
-   use all type WisiToken.Token_ID;
-   function "+" (Item : in Token_Enum_ID) return WisiToken.Token_ID
-     is (WisiToken.Token_ID'First + Token_Enum_ID'Pos (Item));
-   function To_Token_Enum (Item : in WisiToken.Token_ID) return Token_Enum_ID
-     is (Token_Enum_ID'Val (Item - WisiToken.Token_ID'First));
-   function "-" (Item : in WisiToken.Token_ID) return Token_Enum_ID renames 
To_Token_Enum;
-
-   procedure declaration_0
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure declaration_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure declaration_2
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure declaration_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure declaration_4
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure declaration_5
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure nonterminal_0
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure nonterminal_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_item_1
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_item_2
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_item_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_item_4
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_item_5
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-   procedure rhs_optional_item_3
-    (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-     Tree      : in out WisiToken.Syntax_Trees.Tree;
-     Nonterm   : in     WisiToken.Valid_Node_Index;
-     Tokens    : in     WisiToken.Valid_Node_Index_Array);
-end Wisitoken_Grammar_Actions;
diff --git a/packages/wisi/wisitoken_grammar_main.adb 
b/packages/wisi/wisitoken_grammar_main.adb
deleted file mode 100644
index cb91adf..0000000
--- a/packages/wisi/wisitoken_grammar_main.adb
+++ /dev/null
@@ -1,662 +0,0 @@
---  generated parser support file.
---  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c 
wisitoken_grammar.wy
---
-
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  Author: Stephen Leake <stephe-leake@stephe-leake.org>
---
---  This file is part of GNU Emacs.
---
---  GNU Emacs is free software: you can redistribute it and/or modify
---  it under the terms of the GNU General Public License as published by
---  the Free Software Foundation, either version 3 of the License, or
---  (at your option) any later version.
---
---  GNU Emacs is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY; without even the implied warranty of
---  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---  GNU General Public License for more details.
---
---  You should have received a copy of the GNU General Public License
---  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-with Wisitoken_Grammar_Actions; use Wisitoken_Grammar_Actions;
-with WisiToken.Lexer.re2c;
-with wisitoken_grammar_re2c_c;
-package body Wisitoken_Grammar_Main is
-
-   package Lexer is new WisiToken.Lexer.re2c
-     (wisitoken_grammar_re2c_c.New_Lexer,
-      wisitoken_grammar_re2c_c.Free_Lexer,
-      wisitoken_grammar_re2c_c.Reset_Lexer,
-      wisitoken_grammar_re2c_c.Next_Token);
-
-   procedure Create_Parser
-     (Parser                         :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;
-      Trace                        : not null access WisiToken.Trace'Class;
-      User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access)
-   is
-      use WisiToken.Parse.LR;
-      Table : constant Parse_Table_Ptr := new Parse_Table
-        (State_First       => 0,
-         State_Last        => 102,
-         First_Terminal    => 3,
-         Last_Terminal     => 36,
-         First_Nonterminal => 37,
-         Last_Nonterminal  => 56);
-   begin
-      declare
-         procedure Subr_1
-         is begin
-            Table.States (0).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (0), 23, (38, 0), 1);
-            Add_Action (Table.States (0), 33, (43, 0), 2);
-            Table.States (0).Goto_List.Set_Capacity (4);
-            Add_Goto (Table.States (0), 38, 3);
-            Add_Goto (Table.States (0), 43, 4);
-            Add_Goto (Table.States (0), 55, 5);
-            Add_Goto (Table.States (0), 56, 6);
-            Table.States (1).Action_List.Set_Capacity (7);
-            Add_Action (Table.States (1), 3, (38, 1), 7);
-            Add_Action (Table.States (1), 4, (38, 5), 8);
-            Add_Action (Table.States (1), 5, (38, 4), 9);
-            Add_Action (Table.States (1), 6, (39, 0), 10);
-            Add_Action (Table.States (1), 7, (39, 1), 11);
-            Add_Action (Table.States (1), 8, (39, 2), 12);
-            Add_Action (Table.States (1), 33, (38, 2), 13);
-            Table.States (1).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (1), 39, 14);
-            Table.States (2).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (2), 13, (43, 0), 15);
-            Add_Action (Table.States (2), 14, (43, 1), 16);
-            Table.States (3).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (3), (23, 33, 36), (55, 0),  1, null, 
null);
-            Table.States (4).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (4), (23, 33, 36), (55, 1),  1, null, 
null);
-            Table.States (5).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (5), (23, 33, 36), (56, 0),  1, null, 
null);
-            Table.States (6).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (6), 23, (38, 0), 1);
-            Add_Action (Table.States (6), 33, (43, 0), 2);
-            Add_Action (Table.States (6), 36, Accept_It, (37, 0),  1, null, 
null);
-            Table.States (6).Goto_List.Set_Capacity (3);
-            Add_Goto (Table.States (6), 38, 3);
-            Add_Goto (Table.States (6), 43, 4);
-            Add_Goto (Table.States (6), 55, 17);
-            Table.States (7).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (7), 33, (40, 0), 18);
-            Table.States (7).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (7), 40, 19);
-            Table.States (8).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (8), 5, (38, 5), 20);
-            Table.States (9).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (9), 33, (38, 4), 21);
-            Table.States (10).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (10), (1 =>  33), (39, 0),  1, null, 
null);
-            Table.States (11).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (11), 21, (39, 1), 22);
-            Table.States (12).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (12), 21, (39, 2), 23);
-            Table.States (13).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (13), 8, (42, 10), 24);
-            Add_Action (Table.States (13), 10, (42, 5), 25);
-            Add_Action (Table.States (13), 15, (42, 0), 26);
-            Add_Action (Table.States (13), 16, (42, 2), 27);
-            Add_Action (Table.States (13), 20, (42, 3), 28);
-            Add_Action (Table.States (13), 23, Reduce, (38, 3),  2, 
declaration_3'Access, null);
-            Add_Action (Table.States (13), 28, (42, 6), 29);
-            Add_Action (Table.States (13), 30, (42, 7), 30);
-            Add_Action (Table.States (13), 32, (42, 4), 31);
-            Add_Action (Table.States (13), 33, (42, 1), 32);
-            Add_Conflict (Table.States (13), 33, (38, 3),  2, 
declaration_3'Access, null);
-            Add_Action (Table.States (13), 34, (42, 8), 33);
-            Add_Action (Table.States (13), 35, (42, 9), 34);
-            Add_Action (Table.States (13), 36, Reduce, (38, 3),  2, 
declaration_3'Access, null);
-            Table.States (13).Goto_List.Set_Capacity (2);
-            Add_Goto (Table.States (13), 41, 35);
-            Add_Goto (Table.States (13), 42, 36);
-            Table.States (14).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (14), 33, (38, 0), 37);
-            Table.States (15).Action_List.Set_Capacity (10);
-            Add_Action (Table.States (15), 12, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (15), 18, (53, 0), 38);
-            Add_Action (Table.States (15), 19, (52, 0), 39);
-            Add_Action (Table.States (15), 20, (51, 0), 40);
-            Add_Action (Table.States (15), 21, (47, 0), 41);
-            Add_Action (Table.States (15), 23, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (15), 29, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (15), 33, (48, 1), 42);
-            Add_Conflict (Table.States (15), 33, (46, 0),  0, null, null);
-            Add_Action (Table.States (15), 35, (50, 1), 43);
-            Add_Action (Table.States (15), 36, Reduce, (46, 0),  0, null, 
null);
-            Table.States (15).Goto_List.Set_Capacity (9);
-            Add_Goto (Table.States (15), 45, 44);
-            Add_Goto (Table.States (15), 46, 45);
-            Add_Goto (Table.States (15), 47, 46);
-            Add_Goto (Table.States (15), 48, 47);
-            Add_Goto (Table.States (15), 49, 48);
-            Add_Goto (Table.States (15), 50, 49);
-            Add_Goto (Table.States (15), 51, 50);
-            Add_Goto (Table.States (15), 52, 51);
-            Add_Goto (Table.States (15), 53, 52);
-            Table.States (16).Action_List.Set_Capacity (10);
-            Add_Action (Table.States (16), 12, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (16), 18, (53, 0), 38);
-            Add_Action (Table.States (16), 19, (52, 0), 39);
-            Add_Action (Table.States (16), 20, (51, 0), 40);
-            Add_Action (Table.States (16), 21, (47, 0), 41);
-            Add_Action (Table.States (16), 23, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (16), 29, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (16), 33, (48, 1), 42);
-            Add_Conflict (Table.States (16), 33, (46, 0),  0, null, null);
-            Add_Action (Table.States (16), 35, (50, 1), 43);
-            Add_Action (Table.States (16), 36, Reduce, (46, 0),  0, null, 
null);
-            Table.States (16).Goto_List.Set_Capacity (9);
-            Add_Goto (Table.States (16), 45, 53);
-            Add_Goto (Table.States (16), 46, 45);
-            Add_Goto (Table.States (16), 47, 46);
-            Add_Goto (Table.States (16), 48, 47);
-            Add_Goto (Table.States (16), 49, 48);
-            Add_Goto (Table.States (16), 50, 49);
-            Add_Goto (Table.States (16), 51, 50);
-            Add_Goto (Table.States (16), 52, 51);
-            Add_Goto (Table.States (16), 53, 52);
-            Table.States (17).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (17), (23, 33, 36), (56, 1),  2, null, 
null);
-            Table.States (18).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (18), (9, 33), (40, 0),  1, null, null);
-            Table.States (19).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (19), 9, (38, 1), 54);
-            Add_Action (Table.States (19), 33, (40, 1), 55);
-            Table.States (20).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (20), (23, 33, 36), (38, 5),  3, 
declaration_5'Access, null);
-            Table.States (21).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (21), 16, (38, 4), 56);
-            Table.States (22).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (22), 33, (39, 1), 57);
-            Table.States (23).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (23), 33, (39, 2), 58);
-            Table.States (24).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (24), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 10),  1, null,
-            null);
-            Table.States (25).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (25), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 5),  1, null,
-            null);
-            Table.States (26).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (26), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 0),  1, null,
-            null);
-            Table.States (27).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (27), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 2),  1, null,
-            null);
-            Table.States (28).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (28), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 3),  1, null,
-            null);
-            Table.States (29).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (29), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 6),  1, null,
-            null);
-            Table.States (30).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (30), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 7),  1, null,
-            null);
-            Table.States (31).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (31), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 4),  1, null,
-            null);
-            Table.States (32).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (32), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 1),  1, null,
-            null);
-            Table.States (33).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (33), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 8),  1, null,
-            null);
-            Table.States (34).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (34), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (42, 9),  1, null,
-            null);
-            Table.States (35).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (35), 8, (42, 10), 24);
-            Add_Action (Table.States (35), 10, (42, 5), 25);
-            Add_Action (Table.States (35), 15, (42, 0), 26);
-            Add_Action (Table.States (35), 16, (42, 2), 27);
-            Add_Action (Table.States (35), 20, (42, 3), 28);
-            Add_Action (Table.States (35), 23, Reduce, (38, 2),  3, 
declaration_2'Access, null);
-            Add_Action (Table.States (35), 28, (42, 6), 29);
-            Add_Action (Table.States (35), 30, (42, 7), 30);
-            Add_Action (Table.States (35), 32, (42, 4), 31);
-            Add_Action (Table.States (35), 33, (42, 1), 32);
-            Add_Conflict (Table.States (35), 33, (38, 2),  3, 
declaration_2'Access, null);
-            Add_Action (Table.States (35), 34, (42, 8), 33);
-            Add_Action (Table.States (35), 35, (42, 9), 34);
-            Add_Action (Table.States (35), 36, Reduce, (38, 2),  3, 
declaration_2'Access, null);
-            Table.States (35).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (35), 42, 59);
-            Table.States (36).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (36), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (41, 0),  1, null,
-            null);
-            Table.States (37).Action_List.Set_Capacity (11);
-            Add_Action (Table.States (37), 8, (42, 10), 24);
-            Add_Action (Table.States (37), 10, (42, 5), 25);
-            Add_Action (Table.States (37), 15, (42, 0), 26);
-            Add_Action (Table.States (37), 16, (42, 2), 27);
-            Add_Action (Table.States (37), 20, (42, 3), 28);
-            Add_Action (Table.States (37), 28, (42, 6), 29);
-            Add_Action (Table.States (37), 30, (42, 7), 30);
-            Add_Action (Table.States (37), 32, (42, 4), 31);
-            Add_Action (Table.States (37), 33, (42, 1), 32);
-            Add_Action (Table.States (37), 34, (42, 8), 33);
-            Add_Action (Table.States (37), 35, (42, 9), 34);
-            Table.States (37).Goto_List.Set_Capacity (2);
-            Add_Goto (Table.States (37), 41, 60);
-            Add_Goto (Table.States (37), 42, 36);
-            Table.States (38).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (38), 18, (53, 0), 38);
-            Add_Action (Table.States (38), 19, (52, 0), 39);
-            Add_Action (Table.States (38), 20, (51, 0), 40);
-            Add_Action (Table.States (38), 21, (47, 0), 41);
-            Add_Action (Table.States (38), 33, (48, 1), 42);
-            Add_Action (Table.States (38), 35, (50, 1), 43);
-            Table.States (38).Goto_List.Set_Capacity (8);
-            Add_Goto (Table.States (38), 47, 46);
-            Add_Goto (Table.States (38), 48, 47);
-            Add_Goto (Table.States (38), 49, 61);
-            Add_Goto (Table.States (38), 50, 49);
-            Add_Goto (Table.States (38), 51, 50);
-            Add_Goto (Table.States (38), 52, 51);
-            Add_Goto (Table.States (38), 53, 52);
-            Add_Goto (Table.States (38), 54, 62);
-            Table.States (39).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (39), 18, (53, 0), 38);
-            Add_Action (Table.States (39), 19, (52, 0), 39);
-            Add_Action (Table.States (39), 20, (51, 0), 40);
-            Add_Action (Table.States (39), 21, (47, 0), 41);
-            Add_Action (Table.States (39), 33, (48, 1), 42);
-            Add_Action (Table.States (39), 35, (50, 1), 43);
-            Table.States (39).Goto_List.Set_Capacity (8);
-            Add_Goto (Table.States (39), 47, 46);
-            Add_Goto (Table.States (39), 48, 47);
-            Add_Goto (Table.States (39), 49, 61);
-            Add_Goto (Table.States (39), 50, 49);
-            Add_Goto (Table.States (39), 51, 50);
-            Add_Goto (Table.States (39), 52, 51);
-            Add_Goto (Table.States (39), 53, 52);
-            Add_Goto (Table.States (39), 54, 63);
-            Table.States (40).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (40), 18, (53, 0), 38);
-            Add_Action (Table.States (40), 19, (52, 0), 39);
-            Add_Action (Table.States (40), 20, (51, 0), 40);
-            Add_Action (Table.States (40), 21, (47, 0), 41);
-            Add_Action (Table.States (40), 33, (48, 1), 42);
-            Add_Action (Table.States (40), 35, (50, 1), 43);
-            Table.States (40).Goto_List.Set_Capacity (8);
-            Add_Goto (Table.States (40), 47, 46);
-            Add_Goto (Table.States (40), 48, 47);
-            Add_Goto (Table.States (40), 49, 61);
-            Add_Goto (Table.States (40), 50, 49);
-            Add_Goto (Table.States (40), 51, 50);
-            Add_Goto (Table.States (40), 52, 51);
-            Add_Goto (Table.States (40), 53, 52);
-            Add_Goto (Table.States (40), 54, 64);
-            Table.States (41).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (41), 33, (47, 0), 65);
-            Table.States (42).Action_List.Set_Capacity (18);
-            Add_Action (Table.States (42), 11, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 12, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 16, (48, 1), 66);
-            Add_Action (Table.States (42), 18, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 19, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 20, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 21, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 23, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 24, (53, 4), 67);
-            Add_Action (Table.States (42), 25, (52, 2), 68);
-            Add_Action (Table.States (42), 26, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 27, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 28, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 29, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 31, (53, 5), 69);
-            Add_Action (Table.States (42), 33, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 35, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (42), 36, Reduce, (50, 0),  1, null, 
null);
-            Table.States (43).Action_List.Set_Capacity (15);
-            Add_Action (Table.States (43), 11, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 12, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 18, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 19, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 20, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 21, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 23, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 25, (52, 3), 70);
-            Add_Action (Table.States (43), 26, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 27, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 28, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 29, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 33, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 35, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Add_Action (Table.States (43), 36, Reduce, (50, 1),  1, 
rhs_item_1'Access, null);
-            Table.States (44).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (44), 12, (45, 1), 71);
-            Add_Action (Table.States (44), 23, (45, 2), 72);
-            Add_Conflict (Table.States (44), 23, (44, 1),  0, null, null);
-            Add_Action (Table.States (44), 29, (44, 0), 73);
-            Add_Action (Table.States (44), 33, Reduce, (44, 1),  0, null, 
null);
-            Add_Action (Table.States (44), 36, Reduce, (44, 1),  0, null, 
null);
-            Table.States (44).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (44), 44, 74);
-            Table.States (45).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (45), (12, 23, 29, 33, 36), (45, 0),  1, 
null, null);
-            Table.States (46).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (46), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (50, 2),  1,
-            rhs_item_2'Access, null);
-            Table.States (47).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (47), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (49, 0),  1, null,
-            null);
-            Table.States (48).Action_List.Set_Capacity (11);
-            Add_Action (Table.States (48), 11, (46, 2), 75);
-            Add_Action (Table.States (48), 12, Reduce, (46, 1),  1, null, 
null);
-            Add_Action (Table.States (48), 18, (53, 0), 38);
-            Add_Action (Table.States (48), 19, (52, 0), 39);
-            Add_Action (Table.States (48), 20, (51, 0), 40);
-            Add_Action (Table.States (48), 21, (47, 0), 41);
-            Add_Action (Table.States (48), 23, Reduce, (46, 1),  1, null, 
null);
-            Add_Action (Table.States (48), 29, Reduce, (46, 1),  1, null, 
null);
-            Add_Action (Table.States (48), 33, (48, 1), 42);
-            Add_Conflict (Table.States (48), 33, (46, 1),  1, null, null);
-            Add_Action (Table.States (48), 35, (50, 1), 43);
-            Add_Action (Table.States (48), 36, Reduce, (46, 1),  1, null, 
null);
-            Table.States (48).Goto_List.Set_Capacity (6);
-            Add_Goto (Table.States (48), 47, 46);
-            Add_Goto (Table.States (48), 48, 76);
-            Add_Goto (Table.States (48), 50, 49);
-            Add_Goto (Table.States (48), 51, 50);
-            Add_Goto (Table.States (48), 52, 51);
-            Add_Goto (Table.States (48), 53, 52);
-            Table.States (49).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (49), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (48, 0),  1, null,
-            null);
-            Table.States (50).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (50), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (50, 5),  1,
-            rhs_item_5'Access, null);
-            Table.States (51).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (51), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (50, 3),  1,
-            rhs_item_3'Access, null);
-            Table.States (52).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (52), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (50, 4),  1,
-            rhs_item_4'Access, null);
-            Table.States (53).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (53), 12, (45, 1), 71);
-            Add_Action (Table.States (53), 23, (45, 2), 72);
-            Add_Conflict (Table.States (53), 23, (44, 1),  0, null, null);
-            Add_Action (Table.States (53), 29, (44, 0), 73);
-            Add_Action (Table.States (53), 33, Reduce, (44, 1),  0, null, 
null);
-            Add_Action (Table.States (53), 36, Reduce, (44, 1),  0, null, 
null);
-            Table.States (53).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (53), 44, 77);
-            Table.States (54).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (54), (23, 33, 36), (38, 1),  4, 
declaration_1'Access, null);
-            Table.States (55).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (55), (9, 33), (40, 1),  2, null, null);
-            Table.States (56).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (56), 33, (38, 4), 78);
-            Table.States (57).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (57), 17, (39, 1), 79);
-            Table.States (58).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (58), 17, (39, 2), 80);
-            Table.States (59).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (59), (8, 10, 15, 16, 20, 23, 28, 30, 32, 
33, 34, 35, 36), (41, 1),  2, null,
-            null);
-            Table.States (60).Action_List.Set_Capacity (13);
-            Add_Action (Table.States (60), 8, (42, 10), 24);
-            Add_Action (Table.States (60), 10, (42, 5), 25);
-            Add_Action (Table.States (60), 15, (42, 0), 26);
-            Add_Action (Table.States (60), 16, (42, 2), 27);
-            Add_Action (Table.States (60), 20, (42, 3), 28);
-            Add_Action (Table.States (60), 23, Reduce, (38, 0),  4, 
declaration_0'Access, null);
-            Add_Action (Table.States (60), 28, (42, 6), 29);
-            Add_Action (Table.States (60), 30, (42, 7), 30);
-            Add_Action (Table.States (60), 32, (42, 4), 31);
-            Add_Action (Table.States (60), 33, (42, 1), 32);
-            Add_Conflict (Table.States (60), 33, (38, 0),  4, 
declaration_0'Access, null);
-            Add_Action (Table.States (60), 34, (42, 8), 33);
-            Add_Action (Table.States (60), 35, (42, 9), 34);
-            Add_Action (Table.States (60), 36, Reduce, (38, 0),  4, 
declaration_0'Access, null);
-            Table.States (60).Goto_List.Set_Capacity (1);
-            Add_Goto (Table.States (60), 42, 59);
-            Table.States (61).Action_List.Set_Capacity (10);
-            Add_Action (Table.States (61), 12, Reduce, (54, 0),  1, null, 
null);
-            Add_Action (Table.States (61), 18, (53, 0), 38);
-            Add_Action (Table.States (61), 19, (52, 0), 39);
-            Add_Action (Table.States (61), 20, (51, 0), 40);
-            Add_Action (Table.States (61), 21, (47, 0), 41);
-            Add_Action (Table.States (61), 26, Reduce, (54, 0),  1, null, 
null);
-            Add_Action (Table.States (61), 27, Reduce, (54, 0),  1, null, 
null);
-            Add_Action (Table.States (61), 28, Reduce, (54, 0),  1, null, 
null);
-            Add_Action (Table.States (61), 33, (48, 1), 42);
-            Add_Action (Table.States (61), 35, (50, 1), 43);
-            Table.States (61).Goto_List.Set_Capacity (6);
-            Add_Goto (Table.States (61), 47, 46);
-            Add_Goto (Table.States (61), 48, 76);
-            Add_Goto (Table.States (61), 50, 49);
-            Add_Goto (Table.States (61), 51, 50);
-            Add_Goto (Table.States (61), 52, 51);
-            Add_Goto (Table.States (61), 53, 52);
-            Table.States (62).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (62), 12, (54, 1), 81);
-            Add_Action (Table.States (62), 26, (53, 0), 82);
-            Table.States (63).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (63), 12, (54, 1), 81);
-            Add_Action (Table.States (63), 27, (52, 0), 83);
-            Table.States (64).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (64), 12, (54, 1), 81);
-            Add_Action (Table.States (64), 28, (51, 0), 84);
-            Table.States (65).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (65), 16, (47, 0), 85);
-            Table.States (66).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (66), 18, (53, 0), 38);
-            Add_Action (Table.States (66), 19, (52, 0), 39);
-            Add_Action (Table.States (66), 20, (51, 0), 40);
-            Add_Action (Table.States (66), 21, (47, 0), 41);
-            Add_Action (Table.States (66), 33, (50, 0), 86);
-            Add_Action (Table.States (66), 35, (50, 1), 43);
-            Table.States (66).Goto_List.Set_Capacity (5);
-            Add_Goto (Table.States (66), 47, 46);
-            Add_Goto (Table.States (66), 50, 87);
-            Add_Goto (Table.States (66), 51, 50);
-            Add_Goto (Table.States (66), 52, 51);
-            Add_Goto (Table.States (66), 53, 52);
-            Table.States (67).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (67), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (53, 4),  2, null,
-            null);
-            Table.States (68).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (68), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (52, 2),  2, null,
-            null);
-            Table.States (69).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (69), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (53, 5),  2, null,
-            null);
-            Table.States (70).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (70), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (52, 3),  2,
-            rhs_optional_item_3'Access, null);
-            Table.States (71).Action_List.Set_Capacity (10);
-            Add_Action (Table.States (71), 12, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (71), 18, (53, 0), 38);
-            Add_Action (Table.States (71), 19, (52, 0), 39);
-            Add_Action (Table.States (71), 20, (51, 0), 40);
-            Add_Action (Table.States (71), 21, (47, 0), 41);
-            Add_Action (Table.States (71), 23, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (71), 29, Reduce, (46, 0),  0, null, 
null);
-            Add_Action (Table.States (71), 33, (48, 1), 42);
-            Add_Conflict (Table.States (71), 33, (46, 0),  0, null, null);
-            Add_Action (Table.States (71), 35, (50, 1), 43);
-            Add_Action (Table.States (71), 36, Reduce, (46, 0),  0, null, 
null);
-            Table.States (71).Goto_List.Set_Capacity (8);
-            Add_Goto (Table.States (71), 46, 88);
-            Add_Goto (Table.States (71), 47, 46);
-            Add_Goto (Table.States (71), 48, 47);
-            Add_Goto (Table.States (71), 49, 48);
-            Add_Goto (Table.States (71), 50, 49);
-            Add_Goto (Table.States (71), 51, 50);
-            Add_Goto (Table.States (71), 52, 51);
-            Add_Goto (Table.States (71), 53, 52);
-            Table.States (72).Action_List.Set_Capacity (2);
-            Add_Action (Table.States (72), 4, (45, 3), 89);
-            Add_Action (Table.States (72), 5, (45, 2), 90);
-            Table.States (73).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (73), (23, 33, 36), (44, 0),  1, null, 
null);
-            Table.States (74).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (74), (23, 33, 36), (43, 0),  4, 
nonterminal_0'Access, null);
-            Table.States (75).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (75), 11, (46, 3), 91);
-            Add_Action (Table.States (75), 12, Reduce, (46, 2),  2, null, 
null);
-            Add_Action (Table.States (75), 23, Reduce, (46, 2),  2, null, 
null);
-            Add_Action (Table.States (75), 29, Reduce, (46, 2),  2, null, 
null);
-            Add_Action (Table.States (75), 33, Reduce, (46, 2),  2, null, 
null);
-            Add_Action (Table.States (75), 36, Reduce, (46, 2),  2, null, 
null);
-            Table.States (76).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (76), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (49, 1),  2, null,
-            null);
-            Table.States (77).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (77), (23, 33, 36), (43, 1),  4, 
nonterminal_1'Access, null);
-            Table.States (78).Action_List.Set_Capacity (3);
-            Add_Action (Table.States (78), (23, 33, 36), (38, 4),  5, 
declaration_4'Access, null);
-            Table.States (79).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (79), (1 =>  33), (39, 1),  4, null, 
null);
-            Table.States (80).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (80), (1 =>  33), (39, 2),  4, null, 
null);
-            Table.States (81).Action_List.Set_Capacity (6);
-            Add_Action (Table.States (81), 18, (53, 0), 38);
-            Add_Action (Table.States (81), 19, (52, 0), 39);
-            Add_Action (Table.States (81), 20, (51, 0), 40);
-            Add_Action (Table.States (81), 21, (47, 0), 41);
-            Add_Action (Table.States (81), 33, (48, 1), 42);
-            Add_Action (Table.States (81), 35, (50, 1), 43);
-            Table.States (81).Goto_List.Set_Capacity (7);
-            Add_Goto (Table.States (81), 47, 46);
-            Add_Goto (Table.States (81), 48, 47);
-            Add_Goto (Table.States (81), 49, 92);
-            Add_Goto (Table.States (81), 50, 49);
-            Add_Goto (Table.States (81), 51, 50);
-            Add_Goto (Table.States (81), 52, 51);
-            Add_Goto (Table.States (81), 53, 52);
-            Table.States (82).Action_List.Set_Capacity (15);
-            Add_Action (Table.States (82), 11, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 12, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 18, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 19, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 20, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 21, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 22, (53, 1), 93);
-            Add_Action (Table.States (82), 23, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 26, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 27, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 28, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 29, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 33, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 35, Reduce, (53, 0),  3, null, 
null);
-            Add_Action (Table.States (82), 36, Reduce, (53, 0),  3, null, 
null);
-            Table.States (83).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (83), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (52, 0),  3, null,
-            null);
-            Table.States (84).Action_List.Set_Capacity (17);
-            Add_Action (Table.States (84), 11, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 12, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 18, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 19, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 20, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 21, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 23, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 24, (53, 2), 94);
-            Add_Action (Table.States (84), 25, (52, 1), 95);
-            Add_Action (Table.States (84), 26, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 27, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 28, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 29, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 31, (53, 3), 96);
-            Add_Action (Table.States (84), 33, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 35, Reduce, (51, 0),  3, null, 
null);
-            Add_Action (Table.States (84), 36, Reduce, (51, 0),  3, null, 
null);
-            Table.States (85).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (85), 33, (47, 0), 97);
-            Table.States (86).Action_List.Set_Capacity (17);
-            Add_Action (Table.States (86), 11, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 12, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 18, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 19, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 20, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 21, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 23, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 24, (53, 4), 67);
-            Add_Action (Table.States (86), 25, (52, 2), 68);
-            Add_Action (Table.States (86), 26, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 27, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 28, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 29, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 31, (53, 5), 69);
-            Add_Action (Table.States (86), 33, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 35, Reduce, (50, 0),  1, null, 
null);
-            Add_Action (Table.States (86), 36, Reduce, (50, 0),  1, null, 
null);
-            Table.States (87).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (87), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (48, 1),  3, null,
-            null);
-            Table.States (88).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (88), (12, 23, 29, 33, 36), (45, 1),  3, 
null, null);
-            Table.States (89).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (89), 5, (45, 3), 98);
-            Table.States (90).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (90), 33, (45, 2), 99);
-            Table.States (91).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (91), (12, 23, 29, 33, 36), (46, 3),  3, 
null, null);
-            Table.States (92).Action_List.Set_Capacity (10);
-            Add_Action (Table.States (92), 12, Reduce, (54, 1),  3, null, 
null);
-            Add_Action (Table.States (92), 18, (53, 0), 38);
-            Add_Action (Table.States (92), 19, (52, 0), 39);
-            Add_Action (Table.States (92), 20, (51, 0), 40);
-            Add_Action (Table.States (92), 21, (47, 0), 41);
-            Add_Action (Table.States (92), 26, Reduce, (54, 1),  3, null, 
null);
-            Add_Action (Table.States (92), 27, Reduce, (54, 1),  3, null, 
null);
-            Add_Action (Table.States (92), 28, Reduce, (54, 1),  3, null, 
null);
-            Add_Action (Table.States (92), 33, (48, 1), 42);
-            Add_Action (Table.States (92), 35, (50, 1), 43);
-            Table.States (92).Goto_List.Set_Capacity (6);
-            Add_Goto (Table.States (92), 47, 46);
-            Add_Goto (Table.States (92), 48, 76);
-            Add_Goto (Table.States (92), 50, 49);
-            Add_Goto (Table.States (92), 51, 50);
-            Add_Goto (Table.States (92), 52, 51);
-            Add_Goto (Table.States (92), 53, 52);
-            Table.States (93).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (93), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (53, 1),  4, null,
-            null);
-            Table.States (94).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (94), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (53, 2),  4, null,
-            null);
-            Table.States (95).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (95), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (52, 1),  4, null,
-            null);
-            Table.States (96).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (96), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (53, 3),  4, null,
-            null);
-            Table.States (97).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (97), 17, (47, 0), 100);
-            Table.States (98).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (98), (12, 23, 29, 33, 36), (45, 3),  4, 
null, null);
-            Table.States (99).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (99), 16, (45, 2), 101);
-            Table.States (100).Action_List.Set_Capacity (14);
-            Add_Action (Table.States (100), (11, 12, 18, 19, 20, 21, 23, 26, 
27, 28, 29, 33, 35, 36), (47, 0),  5,
-            null, null);
-            Table.States (101).Action_List.Set_Capacity (1);
-            Add_Action (Table.States (101), 33, (45, 2), 102);
-            Table.States (102).Action_List.Set_Capacity (5);
-            Add_Action (Table.States (102), (12, 23, 29, 33, 36), (45, 2),  6, 
null, null);
-         end Subr_1;
-      begin
-         Subr_1;
-         Table.Error_Action := new Parse_Action_Node'((Verb => Error, others 
=> <>), null);
-      end;
-
-      WisiToken.Parse.LR.Parser_No_Recover.New_Parser
-        (Parser,
-         Trace,
-         Lexer.New_Lexer (Trace.Descriptor),
-         Table,
-         User_Data,
-         Max_Parallel         => 15,
-         Terminate_Same_State => True);
-   end Create_Parser;
-end Wisitoken_Grammar_Main;
diff --git a/packages/wisi/wisitoken_grammar_main.ads 
b/packages/wisi/wisitoken_grammar_main.ads
deleted file mode 100644
index 35a5e9e..0000000
--- a/packages/wisi/wisitoken_grammar_main.ads
+++ /dev/null
@@ -1,34 +0,0 @@
---  generated parser support file.
---  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c PROCESS 
wisitoken_grammar.wy
---
-
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  Author: Stephen Leake <stephe-leake@stephe-leake.org>
---
---  This file is part of GNU Emacs.
---
---  GNU Emacs is free software: you can redistribute it and/or modify
---  it under the terms of the GNU General Public License as published by
---  the Free Software Foundation, either version 3 of the License, or
---  (at your option) any later version.
---
---  GNU Emacs is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY; without even the implied warranty of
---  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---  GNU General Public License for more details.
---
---  You should have received a copy of the GNU General Public License
---  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-with WisiToken.Syntax_Trees;
-with WisiToken.Parse.LR.Parser_No_Recover;
-package Wisitoken_Grammar_Main is
-
-   procedure Create_Parser
-     (Parser                       :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;
-      --  no error recovery
-      Trace                        : not null access WisiToken.Trace'Class;
-      User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access);
-
-end Wisitoken_Grammar_Main;
diff --git a/packages/wisi/wisitoken_grammar_re2c.c 
b/packages/wisi/wisitoken_grammar_re2c.c
deleted file mode 100644
index b58f1d0..0000000
--- a/packages/wisi/wisitoken_grammar_re2c.c
+++ /dev/null
@@ -1,4303 +0,0 @@
-/* Generated by re2c 1.3 */
-#line 1 "../wisitoken_grammar.re2c"
-//  generated parser support file. -*- mode: C -*-
-//  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c 
wisitoken_grammar.wy
-//
-
-//  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
-//
-//  Author: Stephen Leake <stephe-leake@stephe-leake.org>
-//
-//  This file is part of GNU Emacs.
-//
-//  GNU Emacs is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  GNU Emacs is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-typedef struct wisi_lexer
-{
-   unsigned char* buffer;           // input text, in utf-8 encoding
-   unsigned char* buffer_last;      // last byte in buffer
-   unsigned char* cursor;           // current byte
-   unsigned char* byte_token_start; // byte position at start of current token
-   size_t         char_pos;         // character position of current character
-   size_t         char_token_start; // character position at start of current 
token
-   int            line;             // 1 indexed
-   int            line_token_start; // line at start of current token
-   unsigned char* marker;           // saved cursor
-   size_t         marker_pos;       // saved character position
-   size_t         marker_line;      // saved line
-   unsigned char* context;          // saved cursor
-   size_t         context_pos;      // saved character position
-   int            context_line;     // saved line
-   int            verbosity;
-
-} wisi_lexer;
-
-#define YYCTYPE unsigned char
-
-#define NO_ERROR 0
-#define ERROR_unrecognized_character 1
-wisi_lexer* wisitoken_grammar_new_lexer
-   (unsigned char* input, size_t length, int verbosity)
-{
-   wisi_lexer* result        = malloc (sizeof (wisi_lexer));
-   result->buffer            = input;
-   result->buffer_last       = input + length - 1;
-   result->cursor            = input;
-   result->byte_token_start  = input;
-   result->char_pos          = 1; /* match WisiToken.Buffer_Region */
-   result->char_token_start  = 1;
-   result->line              = (*result->cursor == 0x0A) ? 2 : 1;
-   result->line_token_start  = result->line;
-   result->verbosity         = verbosity;
-   return result;
-}
-
-void
-wisitoken_grammar_free_lexer(wisi_lexer** lexer)
-{
-   free(*lexer);
-   *lexer = 0;
-}
-
-void
-wisitoken_grammar_reset_lexer(wisi_lexer* lexer)
-{
-   lexer->cursor   = lexer->buffer;
-   lexer->char_pos = 1;
-   lexer->line     = (*lexer->cursor == 0x0A) ? 2 : 1;
-}
-
-static void debug(wisi_lexer* lexer, int state, unsigned char ch)
-{
-   if (lexer->verbosity > 0)
-      {
-      if (ch < ' ')
-         printf ("lexer: %d, 0x%x\n", state, ch);
-      else
-         printf ("lexer: %d, '%c' 0x%x\n", state, ch, ch);
-      }
-}
-#define YYDEBUG(state, ch) debug(lexer, state, ch)
-#define YYCURSOR lexer->cursor
-
-#define YYPEEK() (lexer->cursor <= lexer->buffer_last) ? *lexer->cursor : 4
-
-static void skip(wisi_lexer* lexer)
-{
-   if (lexer->cursor <= lexer->buffer_last)
-      ++lexer->cursor;
-   if (lexer->cursor <= lexer->buffer_last)
-   {
-      /* UFT-8 encoding: https://en.wikipedia.org/wiki/UTF-8#Description */
-      if (*lexer->cursor == 0x0A && lexer->cursor > lexer->buffer && 
*(lexer->cursor - 1) == 0x0D)
-        {/* second byte of DOS line ending */
-        }
-      else if ((*lexer->cursor & 0x80) == 0x80 && (*lexer->cursor & 0xC0) != 
0xC0)
-        {/* byte 2, 3 or 4 of multi-byte UTF-8 char */
-        }
-      else
-        ++lexer->char_pos;
-      if (*lexer->cursor == 0x0A) ++lexer->line;
-   }
-}
-#define YYSKIP() skip(lexer)
-#define YYBACKUP() lexer->marker = lexer->cursor; lexer->marker_pos = 
lexer->char_pos;lexer->marker_line = lexer->line
-#define YYRESTORE() lexer->cursor = lexer->marker; lexer->char_pos = 
lexer->marker_pos;lexer->line = lexer->marker_line
-#define YYBACKUPCTX() lexer->context = lexer->cursor; lexer->context_pos = 
lexer->char_pos;lexer->context_line = lexer->line
-#define YYRESTORECTX() lexer->cursor = lexer->context; lexer->char_pos = 
lexer->context_pos;lexer->line = lexer->context_line
-
-static void skip_to(wisi_lexer* lexer, char* target)
-{
-  int i;
-
-  while (lexer->cursor <= lexer->buffer_last)
-    {
-      if (*lexer->cursor == target[0])
-      {
-        i = 0;
-        do
-          i++;
-        while (0 != target[i] &&
-               lexer->cursor + i <= lexer->buffer_last &&
-               *(lexer->cursor + i) == target[i]);
-
-        if (0 == target[i])
-          {
-            for (i = 0; 0 != target[i]; i++)
-               skip(lexer);
-            break;
-          }
-      }
-      skip(lexer);
-    };
-}
-
-int wisitoken_grammar_next_token
-  (wisi_lexer* lexer,
-   int* id,
-   size_t* byte_position,
-   size_t* byte_length,
-   size_t* char_position,
-   size_t* char_length,
-   int*    line_start)
-{
-   int status = NO_ERROR;
-   *id = -1;
-   if (lexer->cursor > lexer->buffer_last)
-   {
-      *id            = 36;
-      *byte_position = lexer->buffer_last - lexer->buffer + 1;
-      *byte_length   = 0;
-      *char_position = lexer->char_token_start;
-      *char_length   = 0;
-      *line_start    = lexer->line;
-      return status;
-   }
-
-   lexer->byte_token_start = lexer->cursor;
-   lexer->char_token_start = lexer->char_pos;
-   if (*lexer->cursor == 0x0A)
-      lexer->line_token_start = lexer->line-1;
-   else
-      lexer->line_token_start = lexer->line;
-
-   while (*id == -1 && status == 0)
-   {
-
-#line 183 "../wisitoken_grammar_re2c.c"
-{
-       YYCTYPE yych;
-       unsigned int yyaccept = 0;
-       YYDEBUG(0, *YYCURSOR);
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x04:      goto yy4;
-       case '\t':
-       case ' ':       goto yy6;
-       case '\n':      goto yy8;
-       case '\r':      goto yy10;
-       case '"':       goto yy11;
-       case '%':       goto yy12;
-       case '\'':      goto yy14;
-       case '(':       goto yy15;
-       case ')':       goto yy17;
-       case '*':       goto yy19;
-       case '+':       goto yy21;
-       case ',':       goto yy23;
-       case '-':       goto yy25;
-       case '/':       goto yy27;
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':       goto yy29;
-       case ':':       goto yy32;
-       case ';':       goto yy34;
-       case '<':       goto yy36;
-       case '=':       goto yy38;
-       case '>':       goto yy40;
-       case '?':       goto yy42;
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case 'a':
-       case 'b':
-       case 'd':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'j':
-       case 'l':
-       case 'm':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':       goto yy44;
-       case '[':       goto yy47;
-       case ']':       goto yy49;
-       case 'c':       goto yy51;
-       case 'e':       goto yy52;
-       case 'i':       goto yy53;
-       case 'k':       goto yy54;
-       case 'n':       goto yy55;
-       case 't':       goto yy56;
-       case '{':       goto yy57;
-       case '|':       goto yy59;
-       case '}':       goto yy61;
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:      goto yy63;
-       case 0xE0:      goto yy64;
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:      goto yy65;
-       case 0xF0:      goto yy66;
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:      goto yy67;
-       case 0xF4:      goto yy68;
-       default:        goto yy2;
-       }
-yy2:
-       YYDEBUG(2, YYPEEK ());
-       YYSKIP ();
-yy3:
-       YYDEBUG(3, YYPEEK ());
-#line 262 "../wisitoken_grammar.re2c"
-       {status = ERROR_unrecognized_character; continue;}
-#line 338 "../wisitoken_grammar_re2c.c"
-yy4:
-       YYDEBUG(4, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(5, YYPEEK ());
-#line 260 "../wisitoken_grammar.re2c"
-       {*id =  36; continue;}
-#line 345 "../wisitoken_grammar_re2c.c"
-yy6:
-       YYDEBUG(6, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(7, YYPEEK ());
-#line 218 "../wisitoken_grammar.re2c"
-       { lexer->byte_token_start = lexer->cursor;
-          lexer->char_token_start = lexer->char_pos;
-          if (*lexer->cursor == 0x0A)
-             lexer->line_token_start = lexer->line-1;
-          else
-             lexer->line_token_start = lexer->line;
-          continue; }
-#line 358 "../wisitoken_grammar_re2c.c"
-yy8:
-       YYDEBUG(8, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(9, YYPEEK ());
-#line 225 "../wisitoken_grammar.re2c"
-       {*id =  1; continue;}
-#line 365 "../wisitoken_grammar_re2c.c"
-yy10:
-       YYDEBUG(10, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '\n':      goto yy8;
-       default:        goto yy3;
-       }
-yy11:
-       YYDEBUG(11, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case ' ':
-       case '!':
-       case '"':
-       case '#':
-       case '$':
-       case '%':
-       case '&':
-       case '\'':
-       case '(':
-       case ')':
-       case '*':
-       case '+':
-       case ',':
-       case '-':
-       case '.':
-       case '/':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case ':':
-       case ';':
-       case '<':
-       case '=':
-       case '>':
-       case '?':
-       case '@':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '[':
-       case '\\':
-       case ']':
-       case '^':
-       case '_':
-       case '`':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case '{':
-       case '|':
-       case '}':
-       case '~':
-       case 0x7F:
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy70;
-       default:        goto yy3;
-       }
-yy12:
-       YYDEBUG(12, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '(':       goto yy80;
-       case '[':       goto yy82;
-       case '{':       goto yy84;
-       default:        goto yy13;
-       }
-yy13:
-       YYDEBUG(13, YYPEEK ());
-#line 247 "../wisitoken_grammar.re2c"
-       {*id =  23; continue;}
-#line 544 "../wisitoken_grammar_re2c.c"
-yy14:
-       YYDEBUG(14, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case ' ':
-       case '!':
-       case '"':
-       case '#':
-       case '$':
-       case '%':
-       case '&':
-       case '\'':
-       case '(':
-       case ')':
-       case '*':
-       case '+':
-       case ',':
-       case '-':
-       case '.':
-       case '/':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case ':':
-       case ';':
-       case '<':
-       case '=':
-       case '>':
-       case '?':
-       case '@':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '[':
-       case '\\':
-       case ']':
-       case '^':
-       case '_':
-       case '`':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case '{':
-       case '|':
-       case '}':
-       case '~':
-       case 0x7F:
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy87;
-       default:        goto yy3;
-       }
-yy15:
-       YYDEBUG(15, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(16, YYPEEK ());
-#line 244 "../wisitoken_grammar.re2c"
-       {*id =  20; continue;}
-#line 707 "../wisitoken_grammar_re2c.c"
-yy17:
-       YYDEBUG(17, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(18, YYPEEK ());
-#line 252 "../wisitoken_grammar.re2c"
-       {*id =  28; continue;}
-#line 714 "../wisitoken_grammar_re2c.c"
-yy19:
-       YYDEBUG(19, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(20, YYPEEK ());
-#line 255 "../wisitoken_grammar.re2c"
-       {*id =  31; continue;}
-#line 721 "../wisitoken_grammar_re2c.c"
-yy21:
-       YYDEBUG(21, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(22, YYPEEK ());
-#line 248 "../wisitoken_grammar.re2c"
-       {*id =  24; continue;}
-#line 728 "../wisitoken_grammar_re2c.c"
-yy23:
-       YYDEBUG(23, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(24, YYPEEK ());
-#line 239 "../wisitoken_grammar.re2c"
-       {*id =  15; continue;}
-#line 735 "../wisitoken_grammar_re2c.c"
-yy25:
-       YYDEBUG(25, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case '_':       goto yy29;
-       default:        goto yy26;
-       }
-yy26:
-       YYDEBUG(26, YYPEEK ());
-#line 246 "../wisitoken_grammar.re2c"
-       {*id =  22; continue;}
-#line 758 "../wisitoken_grammar_re2c.c"
-yy27:
-       YYDEBUG(27, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(28, YYPEEK ());
-#line 254 "../wisitoken_grammar.re2c"
-       {*id =  30; continue;}
-#line 765 "../wisitoken_grammar_re2c.c"
-yy29:
-       YYDEBUG(29, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       YYDEBUG(30, YYPEEK ());
-       switch (yych) {
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case '_':       goto yy29;
-       default:        goto yy31;
-       }
-yy31:
-       YYDEBUG(31, YYPEEK ());
-#line 256 "../wisitoken_grammar.re2c"
-       {*id =  32; continue;}
-#line 789 "../wisitoken_grammar_re2c.c"
-yy32:
-       YYDEBUG(32, YYPEEK ());
-       yyaccept = 1;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case ':':       goto yy96;
-       default:        goto yy33;
-       }
-yy33:
-       YYDEBUG(33, YYPEEK ());
-#line 237 "../wisitoken_grammar.re2c"
-       {*id =  13; continue;}
-#line 804 "../wisitoken_grammar_re2c.c"
-yy34:
-       YYDEBUG(34, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case ';':       goto yy97;
-       default:        goto yy35;
-       }
-yy35:
-       YYDEBUG(35, YYPEEK ());
-#line 253 "../wisitoken_grammar.re2c"
-       {*id =  29; continue;}
-#line 817 "../wisitoken_grammar_re2c.c"
-yy36:
-       YYDEBUG(36, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(37, YYPEEK ());
-#line 245 "../wisitoken_grammar.re2c"
-       {*id =  21; continue;}
-#line 824 "../wisitoken_grammar_re2c.c"
-yy38:
-       YYDEBUG(38, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(39, YYPEEK ());
-#line 240 "../wisitoken_grammar.re2c"
-       {*id =  16; continue;}
-#line 831 "../wisitoken_grammar_re2c.c"
-yy40:
-       YYDEBUG(40, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(41, YYPEEK ());
-#line 241 "../wisitoken_grammar.re2c"
-       {*id =  17; continue;}
-#line 838 "../wisitoken_grammar_re2c.c"
-yy42:
-       YYDEBUG(42, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(43, YYPEEK ());
-#line 249 "../wisitoken_grammar.re2c"
-       {*id =  25; continue;}
-#line 845 "../wisitoken_grammar_re2c.c"
-yy44:
-       YYDEBUG(44, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-yy45:
-       YYDEBUG(45, YYPEEK ());
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':       goto yy44;
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:      goto yy100;
-       case 0xE0:      goto yy101;
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:      goto yy102;
-       case 0xF0:      goto yy103;
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:      goto yy104;
-       case 0xF4:      goto yy105;
-       default:        goto yy46;
-       }
-yy46:
-       YYDEBUG(46, YYPEEK ());
-#line 257 "../wisitoken_grammar.re2c"
-       {*id =  33; continue;}
-#line 976 "../wisitoken_grammar_re2c.c"
-yy47:
-       YYDEBUG(47, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(48, YYPEEK ());
-#line 243 "../wisitoken_grammar.re2c"
-       {*id =  19; continue;}
-#line 983 "../wisitoken_grammar_re2c.c"
-yy49:
-       YYDEBUG(49, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(50, YYPEEK ());
-#line 251 "../wisitoken_grammar.re2c"
-       {*id =  27; continue;}
-#line 990 "../wisitoken_grammar_re2c.c"
-yy51:
-       YYDEBUG(51, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'o':       goto yy106;
-       default:        goto yy45;
-       }
-yy52:
-       YYDEBUG(52, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'n':       goto yy107;
-       default:        goto yy45;
-       }
-yy53:
-       YYDEBUG(53, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'f':       goto yy108;
-       default:        goto yy45;
-       }
-yy54:
-       YYDEBUG(54, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'e':       goto yy110;
-       default:        goto yy45;
-       }
-yy55:
-       YYDEBUG(55, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'o':       goto yy111;
-       default:        goto yy45;
-       }
-yy56:
-       YYDEBUG(56, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'o':       goto yy112;
-       default:        goto yy45;
-       }
-yy57:
-       YYDEBUG(57, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(58, YYPEEK ());
-#line 242 "../wisitoken_grammar.re2c"
-       {*id =  18; continue;}
-#line 1057 "../wisitoken_grammar_re2c.c"
-yy59:
-       YYDEBUG(59, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(60, YYPEEK ());
-#line 236 "../wisitoken_grammar.re2c"
-       {*id =  12; continue;}
-#line 1064 "../wisitoken_grammar_re2c.c"
-yy61:
-       YYDEBUG(61, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(62, YYPEEK ());
-#line 250 "../wisitoken_grammar.re2c"
-       {*id =  26; continue;}
-#line 1071 "../wisitoken_grammar_re2c.c"
-yy63:
-       YYDEBUG(63, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy44;
-       default:        goto yy3;
-       }
-yy64:
-       YYDEBUG(64, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy100;
-       default:        goto yy3;
-       }
-yy65:
-       YYDEBUG(65, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy100;
-       default:        goto yy3;
-       }
-yy66:
-       YYDEBUG(66, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy102;
-       default:        goto yy3;
-       }
-yy67:
-       YYDEBUG(67, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy102;
-       default:        goto yy3;
-       }
-yy68:
-       YYDEBUG(68, YYPEEK ());
-       yyaccept = 0;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:      goto yy102;
-       default:        goto yy3;
-       }
-yy69:
-       YYDEBUG(69, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-yy70:
-       YYDEBUG(70, YYPEEK ());
-       switch (yych) {
-       case ' ':
-       case '!':
-       case '#':
-       case '$':
-       case '%':
-       case '&':
-       case '\'':
-       case '(':
-       case ')':
-       case '*':
-       case '+':
-       case ',':
-       case '-':
-       case '.':
-       case '/':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case ':':
-       case ';':
-       case '<':
-       case '=':
-       case '>':
-       case '?':
-       case '@':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '[':
-       case '\\':
-       case ']':
-       case '^':
-       case '_':
-       case '`':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case '{':
-       case '|':
-       case '}':
-       case '~':
-       case 0x7F:      goto yy69;
-       case '"':       goto yy72;
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:      goto yy74;
-       case 0xE0:      goto yy75;
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:      goto yy76;
-       case 0xF0:      goto yy77;
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:      goto yy78;
-       case 0xF4:      goto yy79;
-       default:        goto yy71;
-       }
-yy71:
-       YYDEBUG(71, YYPEEK ());
-       YYRESTORE ();
-       switch (yyaccept) {
-       case 0:         goto yy3;
-       case 1:         goto yy33;
-       case 2:         goto yy46;
-       case 3:         goto yy73;
-       case 4:         goto yy89;
-       case 5:         goto yy99;
-       case 6:         goto yy109;
-       case 7:         goto yy123;
-       case 8:         goto yy128;
-       case 9:         goto yy135;
-       case 10:        goto yy139;
-       default:        goto yy145;
-       }
-yy72:
-       YYDEBUG(72, YYPEEK ());
-       yyaccept = 3;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '"':       goto yy69;
-       default:        goto yy73;
-       }
-yy73:
-       YYDEBUG(73, YYPEEK ());
-#line 258 "../wisitoken_grammar.re2c"
-       {*id =  34; continue;}
-#line 1599 "../wisitoken_grammar_re2c.c"
-yy74:
-       YYDEBUG(74, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy69;
-       default:        goto yy71;
-       }
-yy75:
-       YYDEBUG(75, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy74;
-       default:        goto yy71;
-       }
-yy76:
-       YYDEBUG(76, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy74;
-       default:        goto yy71;
-       }
-yy77:
-       YYDEBUG(77, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy76;
-       default:        goto yy71;
-       }
-yy78:
-       YYDEBUG(78, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy76;
-       default:        goto yy71;
-       }
-yy79:
-       YYDEBUG(79, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:      goto yy76;
-       default:        goto yy71;
-       }
-yy80:
-       YYDEBUG(80, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(81, YYPEEK ());
-#line 235 "../wisitoken_grammar.re2c"
-       {*id =  11; skip_to(lexer, ")%"); continue;}
-#line 1936 "../wisitoken_grammar_re2c.c"
-yy82:
-       YYDEBUG(82, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(83, YYPEEK ());
-#line 234 "../wisitoken_grammar.re2c"
-       {*id =  10; skip_to(lexer, "]%"); continue;}
-#line 1943 "../wisitoken_grammar_re2c.c"
-yy84:
-       YYDEBUG(84, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(85, YYPEEK ());
-#line 233 "../wisitoken_grammar.re2c"
-       {*id =  9; skip_to(lexer, "}%"); continue;}
-#line 1950 "../wisitoken_grammar_re2c.c"
-yy86:
-       YYDEBUG(86, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-yy87:
-       YYDEBUG(87, YYPEEK ());
-       switch (yych) {
-       case ' ':
-       case '!':
-       case '"':
-       case '#':
-       case '$':
-       case '%':
-       case '&':
-       case '(':
-       case ')':
-       case '*':
-       case '+':
-       case ',':
-       case '-':
-       case '.':
-       case '/':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case ':':
-       case ';':
-       case '<':
-       case '=':
-       case '>':
-       case '?':
-       case '@':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '[':
-       case '\\':
-       case ']':
-       case '^':
-       case '_':
-       case '`':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case '{':
-       case '|':
-       case '}':
-       case '~':
-       case 0x7F:      goto yy86;
-       case '\'':      goto yy88;
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:      goto yy90;
-       case 0xE0:      goto yy91;
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:      goto yy92;
-       case 0xF0:      goto yy93;
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:      goto yy94;
-       case 0xF4:      goto yy95;
-       default:        goto yy71;
-       }
-yy88:
-       YYDEBUG(88, YYPEEK ());
-       yyaccept = 4;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '\'':      goto yy86;
-       default:        goto yy89;
-       }
-yy89:
-       YYDEBUG(89, YYPEEK ());
-#line 259 "../wisitoken_grammar.re2c"
-       {*id =  35; continue;}
-#line 2121 "../wisitoken_grammar_re2c.c"
-yy90:
-       YYDEBUG(90, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy86;
-       default:        goto yy71;
-       }
-yy91:
-       YYDEBUG(91, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy90;
-       default:        goto yy71;
-       }
-yy92:
-       YYDEBUG(92, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy90;
-       default:        goto yy71;
-       }
-yy93:
-       YYDEBUG(93, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy92;
-       default:        goto yy71;
-       }
-yy94:
-       YYDEBUG(94, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy92;
-       default:        goto yy71;
-       }
-yy95:
-       YYDEBUG(95, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:      goto yy92;
-       default:        goto yy71;
-       }
-yy96:
-       YYDEBUG(96, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '=':       goto yy113;
-       default:        goto yy71;
-       }
-yy97:
-       YYDEBUG(97, YYPEEK ());
-       yyaccept = 5;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       YYDEBUG(98, YYPEEK ());
-       switch (yych) {
-       case 0x00:
-       case 0x01:
-       case 0x02:
-       case 0x03:
-       case 0x05:
-       case 0x06:
-       case 0x07:
-       case 0x08:
-       case '\t':
-       case '\v':
-       case '\f':
-       case '\r':
-       case 0x0E:
-       case 0x0F:
-       case 0x10:
-       case 0x11:
-       case 0x12:
-       case 0x13:
-       case 0x14:
-       case 0x15:
-       case 0x16:
-       case 0x17:
-       case 0x18:
-       case 0x19:
-       case 0x1A:
-       case 0x1B:
-       case 0x1C:
-       case 0x1D:
-       case 0x1E:
-       case 0x1F:
-       case ' ':
-       case '!':
-       case '"':
-       case '#':
-       case '$':
-       case '%':
-       case '&':
-       case '\'':
-       case '(':
-       case ')':
-       case '*':
-       case '+':
-       case ',':
-       case '-':
-       case '.':
-       case '/':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case ':':
-       case ';':
-       case '<':
-       case '=':
-       case '>':
-       case '?':
-       case '@':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '[':
-       case '\\':
-       case ']':
-       case '^':
-       case '_':
-       case '`':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case '{':
-       case '|':
-       case '}':
-       case '~':
-       case 0x7F:      goto yy97;
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:      goto yy115;
-       case 0xE0:      goto yy116;
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:      goto yy117;
-       case 0xF0:      goto yy118;
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:      goto yy119;
-       case 0xF4:      goto yy120;
-       default:        goto yy99;
-       }
-yy99:
-       YYDEBUG(99, YYPEEK ());
-#line 226 "../wisitoken_grammar.re2c"
-       {*id =  2; continue;}
-#line 2651 "../wisitoken_grammar_re2c.c"
-yy100:
-       YYDEBUG(100, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy44;
-       default:        goto yy71;
-       }
-yy101:
-       YYDEBUG(101, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy100;
-       default:        goto yy71;
-       }
-yy102:
-       YYDEBUG(102, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy100;
-       default:        goto yy71;
-       }
-yy103:
-       YYDEBUG(103, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy102;
-       default:        goto yy71;
-       }
-yy104:
-       YYDEBUG(104, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy102;
-       default:        goto yy71;
-       }
-yy105:
-       YYDEBUG(105, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:      goto yy102;
-       default:        goto yy71;
-       }
-yy106:
-       YYDEBUG(106, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'd':       goto yy121;
-       default:        goto yy45;
-       }
-yy107:
-       YYDEBUG(107, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'd':       goto yy122;
-       default:        goto yy45;
-       }
-yy108:
-       YYDEBUG(108, YYPEEK ());
-       yyaccept = 6;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy109;
-       }
-yy109:
-       YYDEBUG(109, YYPEEK ());
-#line 229 "../wisitoken_grammar.re2c"
-       {*id =  5; continue;}
-#line 3130 "../wisitoken_grammar_re2c.c"
-yy110:
-       YYDEBUG(110, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'y':       goto yy124;
-       default:        goto yy45;
-       }
-yy111:
-       YYDEBUG(111, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'n':       goto yy125;
-       default:        goto yy45;
-       }
-yy112:
-       YYDEBUG(112, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'k':       goto yy126;
-       default:        goto yy45;
-       }
-yy113:
-       YYDEBUG(113, YYPEEK ());
-       YYSKIP ();
-       YYDEBUG(114, YYPEEK ());
-#line 238 "../wisitoken_grammar.re2c"
-       {*id =  14; continue;}
-#line 3167 "../wisitoken_grammar_re2c.c"
-yy115:
-       YYDEBUG(115, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy97;
-       default:        goto yy71;
-       }
-yy116:
-       YYDEBUG(116, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy115;
-       default:        goto yy71;
-       }
-yy117:
-       YYDEBUG(117, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy115;
-       default:        goto yy71;
-       }
-yy118:
-       YYDEBUG(118, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy117;
-       default:        goto yy71;
-       }
-yy119:
-       YYDEBUG(119, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:
-       case 0x90:
-       case 0x91:
-       case 0x92:
-       case 0x93:
-       case 0x94:
-       case 0x95:
-       case 0x96:
-       case 0x97:
-       case 0x98:
-       case 0x99:
-       case 0x9A:
-       case 0x9B:
-       case 0x9C:
-       case 0x9D:
-       case 0x9E:
-       case 0x9F:
-       case 0xA0:
-       case 0xA1:
-       case 0xA2:
-       case 0xA3:
-       case 0xA4:
-       case 0xA5:
-       case 0xA6:
-       case 0xA7:
-       case 0xA8:
-       case 0xA9:
-       case 0xAA:
-       case 0xAB:
-       case 0xAC:
-       case 0xAD:
-       case 0xAE:
-       case 0xAF:
-       case 0xB0:
-       case 0xB1:
-       case 0xB2:
-       case 0xB3:
-       case 0xB4:
-       case 0xB5:
-       case 0xB6:
-       case 0xB7:
-       case 0xB8:
-       case 0xB9:
-       case 0xBA:
-       case 0xBB:
-       case 0xBC:
-       case 0xBD:
-       case 0xBE:
-       case 0xBF:      goto yy117;
-       default:        goto yy71;
-       }
-yy120:
-       YYDEBUG(120, YYPEEK ());
-       YYSKIP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 0x80:
-       case 0x81:
-       case 0x82:
-       case 0x83:
-       case 0x84:
-       case 0x85:
-       case 0x86:
-       case 0x87:
-       case 0x88:
-       case 0x89:
-       case 0x8A:
-       case 0x8B:
-       case 0x8C:
-       case 0x8D:
-       case 0x8E:
-       case 0x8F:      goto yy117;
-       default:        goto yy71;
-       }
-yy121:
-       YYDEBUG(121, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'e':       goto yy127;
-       default:        goto yy45;
-       }
-yy122:
-       YYDEBUG(122, YYPEEK ());
-       yyaccept = 7;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy123;
-       }
-yy123:
-       YYDEBUG(123, YYPEEK ());
-#line 228 "../wisitoken_grammar.re2c"
-       {*id =  4; continue;}
-#line 3636 "../wisitoken_grammar_re2c.c"
-yy124:
-       YYDEBUG(124, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'w':       goto yy129;
-       default:        goto yy45;
-       }
-yy125:
-       YYDEBUG(125, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '_':       goto yy130;
-       default:        goto yy45;
-       }
-yy126:
-       YYDEBUG(126, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'e':       goto yy131;
-       default:        goto yy45;
-       }
-yy127:
-       YYDEBUG(127, YYPEEK ());
-       yyaccept = 8;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy128;
-       }
-yy128:
-       YYDEBUG(128, YYPEEK ());
-#line 227 "../wisitoken_grammar.re2c"
-       {*id =  3; continue;}
-#line 3795 "../wisitoken_grammar_re2c.c"
-yy129:
-       YYDEBUG(129, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'o':       goto yy132;
-       default:        goto yy45;
-       }
-yy130:
-       YYDEBUG(130, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'g':       goto yy133;
-       default:        goto yy45;
-       }
-yy131:
-       YYDEBUG(131, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'n':       goto yy134;
-       default:        goto yy45;
-       }
-yy132:
-       YYDEBUG(132, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'r':       goto yy136;
-       default:        goto yy45;
-       }
-yy133:
-       YYDEBUG(133, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'r':       goto yy137;
-       default:        goto yy45;
-       }
-yy134:
-       YYDEBUG(134, YYPEEK ());
-       yyaccept = 9;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy135;
-       }
-yy135:
-       YYDEBUG(135, YYPEEK ());
-#line 232 "../wisitoken_grammar.re2c"
-       {*id =  8; continue;}
-#line 3974 "../wisitoken_grammar_re2c.c"
-yy136:
-       YYDEBUG(136, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'd':       goto yy138;
-       default:        goto yy45;
-       }
-yy137:
-       YYDEBUG(137, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'a':       goto yy140;
-       default:        goto yy45;
-       }
-yy138:
-       YYDEBUG(138, YYPEEK ());
-       yyaccept = 10;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy139;
-       }
-yy139:
-       YYDEBUG(139, YYPEEK ());
-#line 230 "../wisitoken_grammar.re2c"
-       {*id =  6; continue;}
-#line 4123 "../wisitoken_grammar_re2c.c"
-yy140:
-       YYDEBUG(140, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'm':       goto yy141;
-       default:        goto yy45;
-       }
-yy141:
-       YYDEBUG(141, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'm':       goto yy142;
-       default:        goto yy45;
-       }
-yy142:
-       YYDEBUG(142, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'a':       goto yy143;
-       default:        goto yy45;
-       }
-yy143:
-       YYDEBUG(143, YYPEEK ());
-       yyaccept = 2;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case 'r':       goto yy144;
-       default:        goto yy45;
-       }
-yy144:
-       YYDEBUG(144, YYPEEK ());
-       yyaccept = 11;
-       YYSKIP ();
-       YYBACKUP ();
-       yych = YYPEEK ();
-       switch (yych) {
-       case '-':
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-       case 'A':
-       case 'B':
-       case 'C':
-       case 'D':
-       case 'E':
-       case 'F':
-       case 'G':
-       case 'H':
-       case 'I':
-       case 'J':
-       case 'K':
-       case 'L':
-       case 'M':
-       case 'N':
-       case 'O':
-       case 'P':
-       case 'Q':
-       case 'R':
-       case 'S':
-       case 'T':
-       case 'U':
-       case 'V':
-       case 'W':
-       case 'X':
-       case 'Y':
-       case 'Z':
-       case '_':
-       case 'a':
-       case 'b':
-       case 'c':
-       case 'd':
-       case 'e':
-       case 'f':
-       case 'g':
-       case 'h':
-       case 'i':
-       case 'j':
-       case 'k':
-       case 'l':
-       case 'm':
-       case 'n':
-       case 'o':
-       case 'p':
-       case 'q':
-       case 'r':
-       case 's':
-       case 't':
-       case 'u':
-       case 'v':
-       case 'w':
-       case 'x':
-       case 'y':
-       case 'z':
-       case 0xC2:
-       case 0xC3:
-       case 0xC4:
-       case 0xC5:
-       case 0xC6:
-       case 0xC7:
-       case 0xC8:
-       case 0xC9:
-       case 0xCA:
-       case 0xCB:
-       case 0xCC:
-       case 0xCD:
-       case 0xCE:
-       case 0xCF:
-       case 0xD0:
-       case 0xD1:
-       case 0xD2:
-       case 0xD3:
-       case 0xD4:
-       case 0xD5:
-       case 0xD6:
-       case 0xD7:
-       case 0xD8:
-       case 0xD9:
-       case 0xDA:
-       case 0xDB:
-       case 0xDC:
-       case 0xDD:
-       case 0xDE:
-       case 0xDF:
-       case 0xE0:
-       case 0xE1:
-       case 0xE2:
-       case 0xE3:
-       case 0xE4:
-       case 0xE5:
-       case 0xE6:
-       case 0xE7:
-       case 0xE8:
-       case 0xE9:
-       case 0xEA:
-       case 0xEB:
-       case 0xEC:
-       case 0xED:
-       case 0xEE:
-       case 0xEF:
-       case 0xF0:
-       case 0xF1:
-       case 0xF2:
-       case 0xF3:
-       case 0xF4:      goto yy45;
-       default:        goto yy145;
-       }
-yy145:
-       YYDEBUG(145, YYPEEK ());
-#line 231 "../wisitoken_grammar.re2c"
-       {*id =  7; continue;}
-#line 4292 "../wisitoken_grammar_re2c.c"
-}
-#line 263 "../wisitoken_grammar.re2c"
-
-   }
-   /* lexer->cursor and lexer ->char_pos are one char past end of token */
-   *byte_position = lexer->byte_token_start - lexer->buffer + 1;
-   *byte_length   = lexer->cursor - lexer->byte_token_start;
-   *char_position = lexer->char_token_start;
-   *char_length   = lexer->char_pos - lexer->char_token_start;
-   *line_start    = lexer->line_token_start;
-   return status;
-   }
diff --git a/packages/wisi/wisitoken_grammar_re2c_c.ads 
b/packages/wisi/wisitoken_grammar_re2c_c.ads
deleted file mode 100644
index d494b3f..0000000
--- a/packages/wisi/wisitoken_grammar_re2c_c.ads
+++ /dev/null
@@ -1,63 +0,0 @@
---  generated parser support file.
---  command line: wisitoken-bnf-generate.exe  --generate LALR Ada re2c 
wisitoken_grammar.wy
---
-
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  Author: Stephen Leake <stephe-leake@stephe-leake.org>
---
---  This file is part of GNU Emacs.
---
---  GNU Emacs is free software: you can redistribute it and/or modify
---  it under the terms of the GNU General Public License as published by
---  the Free Software Foundation, either version 3 of the License, or
---  (at your option) any later version.
---
---  GNU Emacs is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY; without even the implied warranty of
---  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---  GNU General Public License for more details.
---
---  You should have received a copy of the GNU General Public License
---  along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-with Interfaces.C;
-with WisiToken;
-with System;
-package wisitoken_grammar_re2c_c is
-
-   function New_Lexer
-     (Buffer    : in System.Address;
-      Length    : in Interfaces.C.size_t;
-      Verbosity : in Interfaces.C.int)
-     return System.Address
-   with Import        => True,
-        Convention    => C,
-        External_Name => "wisitoken_grammar_new_lexer";
-   --  Create the lexer object, passing it the full text to process.
-
-   procedure Free_Lexer (Lexer : in out System.Address)
-   with Import        => True,
-        Convention    => C,
-        External_Name => "wisitoken_grammar_free_lexer";
-   --  Free the lexer object
-
-   procedure Reset_Lexer (Lexer : in System.Address)
-   with Import        => True,
-        Convention    => C,
-        External_Name => "wisitoken_grammar_reset_lexer";
-
-   function Next_Token
-     (Lexer         : in     System.Address;
-      ID            :    out WisiToken.Token_ID;
-      Byte_Position :    out Interfaces.C.size_t;
-      Byte_Length   :    out Interfaces.C.size_t;
-      Char_Position :    out Interfaces.C.size_t;
-      Char_Length   :    out Interfaces.C.size_t;
-      Line_Start    :    out Interfaces.C.int)
-     return Interfaces.C.int
-   with Import        => True,
-        Convention    => C,
-        External_Name => "wisitoken_grammar_next_token";
-
-end wisitoken_grammar_re2c_c;
diff --git a/packages/wisi/wisitoken_grammar_runtime.adb 
b/packages/wisi/wisitoken_grammar_runtime.adb
deleted file mode 100644
index e40c147..0000000
--- a/packages/wisi/wisitoken_grammar_runtime.adb
+++ /dev/null
@@ -1,3442 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Characters.Handling;
-with Ada.Exceptions;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with GNAT.Regexp;
-with SAL.Generic_Decimal_Image;
-with WisiToken.Generate;   use WisiToken.Generate;
-package body WisiToken_Grammar_Runtime is
-
-   use WisiToken;
-   use Wisitoken_Grammar_Actions;
-
-   ----------
-   --  Body subprograms, misc order
-
-   function Get_Line
-     (Data : in User_Data_Type;
-      Tree : in Syntax_Trees.Tree;
-      Node : in WisiToken.Valid_Node_Index)
-     return WisiToken.Line_Number_Type
-   is
-      --  Find a source line for Node.
-
-      use WisiToken.Syntax_Trees;
-
-      Temp : Node_Index := Node;
-   begin
-      loop
-         if Tree.First_Shared_Terminal (Temp) = Invalid_Token_Index then
-            --  Node is empty or all virtual_identifiers; try parents.
-            Temp := Tree.Parent (Temp);
-            exit when Temp = Invalid_Node_Index;
-         else
-            return Data.Terminals.all (Tree.First_Shared_Terminal (Temp)).Line;
-         end if;
-      end loop;
-      return Invalid_Line_Number;
-   end Get_Line;
-
-   function Get_Text
-     (Data         : in User_Data_Type;
-      Tree         : in Syntax_Trees.Tree;
-      Tree_Index   : in Valid_Node_Index;
-      Strip_Quotes : in Boolean := False)
-     return String
-   is
-      use all type Syntax_Trees.Node_Label;
-
-      function Strip_Delimiters (Tree_Index : in Valid_Node_Index) return 
String
-      is
-         Region : Buffer_Region renames Data.Terminals.all (Tree.Terminal 
(Tree_Index)).Byte_Region;
-      begin
-         if -Tree.ID (Tree_Index) in RAW_CODE_ID | REGEXP_ID | ACTION_ID then
-            --  Strip delimiters. We don't strip leading/trailing spaces to 
preserve indent.
-            return Data.Grammar_Lexer.Buffer_Text ((Region.First + 2, 
Region.Last - 2));
-
-         elsif -Tree.ID (Tree_Index) in STRING_LITERAL_1_ID | 
STRING_LITERAL_2_ID and Strip_Quotes then
-            return Data.Grammar_Lexer.Buffer_Text ((Region.First + 1, 
Region.Last - 1));
-         else
-            return Data.Grammar_Lexer.Buffer_Text (Region);
-         end if;
-      end Strip_Delimiters;
-
-   begin
-      case Tree.Label (Tree_Index) is
-      when Shared_Terminal =>
-         return Strip_Delimiters (Tree_Index);
-
-      when Virtual_Terminal =>
-         --  Terminal keyword inserted during tree edit. We could check for
-         --  Identifier, but that will be caught later.
-         return Image (Tree.ID (Tree_Index), 
Wisitoken_Grammar_Actions.Descriptor);
-
-      when Virtual_Identifier =>
-         if Strip_Quotes then
-            declare
-               Quoted : constant String := -Data.Tokens.Virtual_Identifiers 
(Tree.Identifier (Tree_Index));
-            begin
-               return Quoted (Quoted'First + 1 .. Quoted'Last - 1);
-            end;
-         else
-            return -Data.Tokens.Virtual_Identifiers (Tree.Identifier 
(Tree_Index));
-         end if;
-
-      when Nonterm =>
-         declare
-            use all type Ada.Strings.Unbounded.Unbounded_String;
-            Result       : Ada.Strings.Unbounded.Unbounded_String;
-            Tree_Indices : constant Valid_Node_Index_Array := 
Tree.Get_Terminals (Tree_Index);
-            Need_Space   : Boolean                                      := 
False;
-         begin
-            for Tree_Index of Tree_Indices loop
-               Result := Result & (if Need_Space then " " else "") &
-                 Get_Text (Data, Tree, Tree_Index, Strip_Quotes);
-               Need_Space := True;
-            end loop;
-            return -Result;
-         end;
-      end case;
-   end Get_Text;
-
-   function Get_Child_Text
-     (Data         : in User_Data_Type;
-      Tree         : in Syntax_Trees.Tree;
-      Parent       : in Valid_Node_Index;
-      Child        : in SAL.Peek_Type;
-      Strip_Quotes : in Boolean := False)
-     return String
-   is
-      Tree_Indices : constant Valid_Node_Index_Array := Tree.Get_Terminals 
(Parent);
-   begin
-      return Get_Text (Data, Tree, Tree_Indices (Child), Strip_Quotes);
-   end Get_Child_Text;
-
-   procedure Start_If_1
-     (Data    : in out User_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      A_Index : in     Valid_Node_Index;
-      B_Index : in     Valid_Node_Index)
-   is
-      use all type WisiToken.BNF.Generate_Algorithm;
-      use all type WisiToken.BNF.Lexer_Type;
-   begin
-      if "lexer" = Get_Text (Data, Tree, A_Index) then
-         Data.If_Lexer_Present := True;
-         Data.Ignore_Lines     := Data.User_Lexer /= WisiToken.BNF.To_Lexer 
(Get_Text (Data, Tree, B_Index));
-
-      elsif "parser" = Get_Text (Data, Tree, A_Index) then
-         Data.If_Parser_Present := True;
-         Data.Ignore_Lines := Data.User_Parser /= 
WisiToken.BNF.Generate_Algorithm'Value
-           (Get_Text (Data, Tree, B_Index));
-
-      else
-         raise Grammar_Error with
-           Error_Message
-             (Data.Grammar_Lexer.File_Name, Data.Terminals.all 
(Tree.First_Shared_Terminal (A_Index)).Line,
-              "invalid '%if'; must be one of {lexer | parser}");
-      end if;
-   end Start_If_1;
-
-   function Get_RHS
-     (Data   : in out User_Data_Type;
-      Tree   : in     Syntax_Trees.Tree;
-      Labels : in out WisiToken.BNF.String_Arrays.Vector;
-      Token  : in     Valid_Node_Index)
-     return WisiToken.BNF.RHS_Type
-   with Pre => Tree.ID (Token) = +rhs_ID
-   is
-      use all type SAL.Base_Peek_Type;
-      Children : constant Valid_Node_Index_Array := Tree.Children (Token);
-   begin
-      return RHS : WisiToken.BNF.RHS_Type do
-         RHS.Source_Line := Get_Line (Data, Tree, Token);
-
-         if Children'Length > 0 then
-            for I of Tree.Get_IDs (Children (1), +rhs_element_ID) loop
-               case Tree.RHS_Index (I) is
-               when 0 =>
-                  --  rhs_item
-                  RHS.Tokens.Append
-                    ((Label      => +"",
-                      Identifier => +Get_Text (Data, Tree, Tree.Child (I, 
1))));
-
-               when 1 =>
-                  --  IDENTIFIER = rhs_item
-                  declare
-                     Label : constant String := Get_Text (Data, Tree, 
Tree.Child (I, 1));
-                  begin
-                     RHS.Tokens.Append
-                       ((Label      => +Label,
-                         Identifier => +Get_Text (Data, Tree, Tree.Child (I, 
3))));
-
-                     if (for all L of Labels => -L /= Label) then
-                        Labels.Append (+Label);
-                     end if;
-                  end;
-
-               when others =>
-                  Raise_Programmer_Error ("Get_RHS; unimplimented token", 
Data, Tree, I);
-               end case;
-            end loop;
-
-            if Children'Last >= 2 then
-               declare
-                  Text : constant String := Get_Text (Data, Tree, Children 
(2));
-               begin
-                  if Text'Length > 0 and (for some C of Text => C /= ' ') then
-                     RHS.Action := +Text;
-                     Data.Action_Count := Data.Action_Count + 1;
-                  end if;
-               end;
-            end if;
-
-            if Children'Last >= 3 then
-               RHS.Check := +Get_Text (Data, Tree, Children (3));
-               Data.Check_Count := Data.Check_Count + 1;
-            end if;
-         end if;
-      end return;
-   exception
-   when SAL.Programmer_Error =>
-      raise;
-   when E : others =>
-      declare
-         use Ada.Exceptions;
-      begin
-         Raise_Programmer_Error ("Get_RHS: " & Exception_Name (E) & ": " & 
Exception_Message (E), Data, Tree, Token);
-      end;
-   end Get_RHS;
-
-   procedure Get_Right_Hand_Sides
-     (Data             : in out User_Data_Type;
-      Tree             : in     WisiToken.Syntax_Trees.Tree;
-      Right_Hand_Sides : in out WisiToken.BNF.RHS_Lists.List;
-      Labels           : in out WisiToken.BNF.String_Arrays.Vector;
-      Token            : in     WisiToken.Valid_Node_Index)
-   with Pre => Tree.ID (Token) = +rhs_list_ID
-   is
-      Tokens : constant Valid_Node_Index_Array := Tree.Children (Token);
-   begin
-      case Tree.RHS_Index (Token) is
-      when 0 =>
-         --  | rhs
-         if not Data.Ignore_Lines then
-            Right_Hand_Sides.Append (Get_RHS (Data, Tree, Labels, Tokens (1)));
-         end if;
-
-      when 1 =>
-         --  | rhs_list BAR rhs
-         Get_Right_Hand_Sides (Data, Tree, Right_Hand_Sides, Labels, Tokens 
(1));
-
-         if not Data.Ignore_Lines then
-            Right_Hand_Sides.Append (Get_RHS (Data, Tree, Labels, Tokens (3)));
-         end if;
-
-      when 2 =>
-         --  | rhs_list PERCENT IF IDENTIFIER EQUAL IDENTIFIER
-         Get_Right_Hand_Sides (Data, Tree, Right_Hand_Sides, Labels, Tokens 
(1));
-         Start_If_1 (Data, Tree, Tokens (4), Tokens (6));
-
-      when 3 =>
-         --  | rhs_list PERCENT END IF
-         Get_Right_Hand_Sides (Data, Tree, Right_Hand_Sides, Labels, Tokens 
(1));
-         Data.Ignore_Lines := False;
-
-      when others =>
-         Raise_Programmer_Error ("Get_Right_Hand_Sides", Data, Tree, Token);
-      end case;
-   end Get_Right_Hand_Sides;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   overriding
-   procedure Set_Lexer_Terminals
-     (User_Data : in out User_Data_Type;
-      Lexer     : in     WisiToken.Lexer.Handle;
-      Terminals : in     Base_Token_Array_Access_Constant)
-   is begin
-      User_Data.Grammar_Lexer := Lexer;
-      User_Data.Terminals     := Terminals;
-   end Set_Lexer_Terminals;
-
-   overriding procedure Reset (Data : in out User_Data_Type)
-   is begin
-      --  Preserve data set in Phase Meta, or by Set_Lexer_Terminals, or by
-      --  wisitoken-bnf-generate.
-
-      --  Preserve Grammar_Lexer
-      --  Preserve User_Lexer
-      --  Preserve User_Parser
-      --  Perserve Generate_Set
-      --  Preserve Meta_Syntax
-      --  Preserve Phase
-      --  Preserve Terminals
-      --  Preserve Non_Grammar
-      --  EBNF_Nodes handled in Initialize_Actions
-      Data.Raw_Code          := (others => <>);
-      Data.Language_Params   :=
-        (Case_Insensitive => Data.Language_Params.Case_Insensitive,
-         others => <>);
-      Data.Tokens            :=
-        (Virtual_Identifiers => Data.Tokens.Virtual_Identifiers,
-         others => <>);
-      Data.Conflicts.Clear;
-      Data.McKenzie_Recover  := (others => <>);
-      Data.Rule_Count        := 0;
-      Data.Action_Count      := 0;
-      Data.Check_Count       := 0;
-      Data.Label_Count       := 0;
-      Data.If_Lexer_Present  := False;
-      Data.If_Parser_Present := False;
-      Data.Ignore_Lines      := False;
-   end Reset;
-
-   overriding procedure Initialize_Actions
-     (Data : in out User_Data_Type;
-      Tree : in     WisiToken.Syntax_Trees.Tree'Class)
-   is begin
-      Data.EBNF_Nodes.Clear;
-      Data.EBNF_Nodes.Set_First_Last (Tree.First_Index, Tree.Last_Index);
-   end Initialize_Actions;
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          User_Data_Type;
-      Tree  : in out          WisiToken.Syntax_Trees.Tree'Class;
-      Token : in              WisiToken.Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class)
-   is
-      pragma Unreferenced (Lexer);
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Token.ID < Wisitoken_Grammar_Actions.Descriptor.First_Terminal then
-         --  Non-grammar token
-         if Data.Terminals.Length = 0 then
-            Data.Leading_Non_Grammar.Append (Token);
-         else
-            declare
-               Containing_Aug : Augmented_Token_Access := 
Augmented_Token_Access
-                 (Tree.Augmented (Data.Last_Terminal_Node));
-            begin
-               if Containing_Aug = null then
-                  Containing_Aug := new Augmented_Token'
-                    (Data.Terminals.all (Tree.First_Shared_Terminal 
(Data.Last_Terminal_Node)) with Non_Grammar => <>);
-                  Tree.Set_Augmented (Data.Last_Terminal_Node, 
WisiToken.Base_Token_Class_Access (Containing_Aug));
-               end if;
-
-               Containing_Aug.Non_Grammar.Append (Token);
-            end;
-         end if;
-      else
-         Data.Last_Terminal_Node := Token.Tree_Index;
-      end if;
-   end Lexer_To_Augmented;
-
-   procedure Start_If
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is begin
-      --  all phases
-      Start_If_1 (User_Data_Type (User_Data), Tree, Tokens (3), Tokens (5));
-   end Start_If;
-
-   procedure End_If (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class)
-   is
-      Data : User_Data_Type renames User_Data_Type (User_Data);
-   begin
-      --  all phases
-      Data.Ignore_Lines := False;
-   end End_If;
-
-   procedure Add_Declaration
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      use all type WisiToken.Syntax_Trees.Node_Label;
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-
-      Data : User_Data_Type renames User_Data_Type (User_Data);
-
-      function Token (Index : in SAL.Peek_Type) return Base_Token
-      is
-         use all type SAL.Base_Peek_Type;
-      begin
-         if Tokens'Last < Index then
-            raise SAL.Programmer_Error;
-         elsif Tree.Label (Tokens (Index)) /= 
WisiToken.Syntax_Trees.Shared_Terminal then
-            raise SAL.Programmer_Error with "token at " & Image 
(Tree.Byte_Region (Tokens (Index))) &
-              " is a " & WisiToken.Syntax_Trees.Node_Label'Image (Tree.Label 
(Tokens (Index))) &
-              ", expecting Shared_Terminal";
-         else
-            return Data.Terminals.all (Tree.Terminal (Tokens (Index)));
-         end if;
-      end Token;
-
-      function Enum_ID (Index : in SAL.Peek_Type) return Token_Enum_ID
-      is (To_Token_Enum (Token (Index).ID));
-
-   begin
-      if Data.Phase = Meta then
-         if Tree.Label (Tokens (2)) = WisiToken.Syntax_Trees.Shared_Terminal 
then
-            case Enum_ID (2) is
-            when IDENTIFIER_ID =>
-               declare
-                  Kind : constant String := Data.Grammar_Lexer.Buffer_Text 
(Token (2).Byte_Region);
-               begin
-                  if Kind = "case_insensitive" then
-                     Data.Language_Params.Case_Insensitive := True;
-
-                  elsif Kind = "generate" then
-                     declare
-                        use all type SAL.Base_Peek_Type;
-                        Children : constant Valid_Node_Index_Array := 
Tree.Get_Terminals (Tokens (3));
-                        Tuple    : WisiToken.BNF.Generate_Tuple;
-                     begin
-                        Tuple.Gen_Alg  := WisiToken.BNF.To_Generate_Algorithm 
(Get_Text (Data, Tree, Children (1)));
-                        if Children'Last >= 2 then
-                           Tuple.Out_Lang := WisiToken.BNF.To_Output_Language 
(Get_Text (Data, Tree, Children (2)));
-                        end if;
-                        for I in 3 .. SAL.Base_Peek_Type (Children'Length) loop
-                           declare
-                              Text : constant String := Get_Text (Data, Tree, 
Children (I));
-                           begin
-                              if Text = "text_rep" then
-                                 Tuple.Text_Rep := True;
-
-                              elsif (for some I of WisiToken.BNF.Lexer_Image 
=> Text = I.all) then
-                                 Tuple.Lexer := WisiToken.BNF.To_Lexer (Text);
-
-                              elsif (for some I in 
WisiToken.BNF.Valid_Interface =>
-                                       WisiToken.BNF.To_Lower (Text) = 
WisiToken.BNF.To_Lower
-                                         (WisiToken.BNF.Valid_Interface'Image 
(I)))
-                              then
-                                 Tuple.Interface_Kind := 
WisiToken.BNF.Valid_Interface'Value (Text);
-                              else
-                                 declare
-                                    Token : Base_Token renames 
Data.Terminals.all (Tree.Terminal (Children (I)));
-                                 begin
-                                    raise Grammar_Error with Error_Message
-                                      (Data.Grammar_Lexer.File_Name, 
Token.Line, Token.Column,
-                                       "invalid generate param '" & Text & 
"'");
-                                 end;
-                              end if;
-                           end;
-                        end loop;
-                        WisiToken.BNF.Add (Data.Generate_Set, Tuple);
-                     end;
-
-                  elsif Kind = "meta_syntax" then
-                     if Data.Meta_Syntax = Unknown then
-                        --  Don't overwrite; somebody set it for a reason.
-                        declare
-                           Value_Str : constant String := 
WisiToken.BNF.To_Lower (Get_Text (Data, Tree, Tokens (3)));
-                        begin
-                           if Value_Str = "bnf" then
-                              Data.Meta_Syntax := BNF_Syntax;
-                           elsif Value_Str = "ebnf" then
-                              Data.Meta_Syntax := EBNF_Syntax;
-                              Data.EBNF_Nodes (Tree.Find_Ancestor (Tokens (2), 
+declaration_ID)) := True;
-
-                           else
-                              Put_Error ("invalid value for %meta_syntax; must 
be BNF | EBNF.");
-                           end if;
-                        end;
-                     end if;
-                  end if;
-               end;
-            when others =>
-               null;
-            end case;
-         end if;
-         return;
-      end if;
-
-      --  Add declaration to User_Data.Generate_Set, Language_Params,
-      --  Tokens, Conflicts, or McKenzie_Recover.
-
-      if Data.Ignore_Lines then
-         return;
-      end if;
-
-      case Tree.Label (Tokens (2)) is
-      when Syntax_Trees.Nonterm =>
-         --  must be token_keyword_non_grammar
-         declare
-            Children_2 : constant Valid_Node_Index_Array := Tree.Children 
(Tokens (2));
-            Child_1_ID : constant Token_Enum_ID := To_Token_Enum (Tree.ID 
(Children_2 (1)));
-         begin
-            case Child_1_ID is
-            when Wisitoken_Grammar_Actions.TOKEN_ID =>
-               declare
-                  Children_4 : constant Valid_Node_Index_Array := 
Tree.Children (Tokens (4));
-               begin
-                  WisiToken.BNF.Add_Token
-                    (Data.Tokens.Tokens,
-                     Kind         => Get_Text (Data, Tree, Children_2 (3)),
-                     Name         => Get_Text (Data, Tree, Tokens (3)),
-                     Value        => Get_Text (Data, Tree, Children_4 (1)),
-                     Repair_Image => (if Children_4'Length = 1 then "" else 
Get_Text (Data, Tree, Children_4 (2))));
-               end;
-
-            when KEYWORD_ID =>
-
-               Data.Tokens.Keywords.Append
-                 ((Name  => +Get_Text (Data, Tree, Tokens (3)),
-                   Value => +Get_Text (Data, Tree, Tokens (4))));
-
-            when NON_GRAMMAR_ID =>
-
-               WisiToken.BNF.Add_Token
-                 (Data.Tokens.Non_Grammar,
-                  Kind  => Get_Text (Data, Tree, Children_2 (3)),
-                  Name  => Get_Text (Data, Tree, Tokens (3)),
-                  Value => Get_Text (Data, Tree, Tokens (4)));
-
-            when others =>
-               raise SAL.Programmer_Error;
-            end case;
-         end;
-
-      when Syntax_Trees.Shared_Terminal =>
-         case Enum_ID (2) is
-         when CODE_ID =>
-            declare
-               Location : WisiToken.BNF.Raw_Code_Location;
-
-               --  % code identifier_list raw_code
-               --  1 2    3               4
-               --
-               --  identifier_list = "action spec context"
-               --  identifier_list children = identifier_list IDENTIFIER_ID
-               --  children = identifier_list IDENTIFIER_ID
-               --  children = IDENTIFIER_ID
-               function Get_Loc_List return Base_Token_Array
-               with Pre => Tree.ID (Tokens (3)) = +identifier_list_ID
-               is
-                  use all type SAL.Base_Peek_Type;
-                  use WisiToken.Syntax_Trees;
-                  Node   : Valid_Node_Index := Tokens (3);
-                  Result : Base_Token_Array (1 .. 3);
-                  First  : SAL.Peek_Type    := Result'Last + 1;
-               begin
-                  loop
-                     pragma Assert (Tree.ID (Node) = +identifier_list_ID);
-                     exit when not Tree.Has_Children (Node);
-                     declare
-                        Children : constant Valid_Node_Index_Array := 
Tree.Children (Node);
-                     begin
-                        if Children'Length = 1 then
-                           --  identifier_list : IDENTIFIER
-                           First := First - 1;
-                           Result (First) := Data.Terminals.all (Tree.Terminal 
(Children (1)));
-                           exit;
-
-                        elsif Children'Length = 2 then
-                           --  identifier_list : identifier_list IDENTIFIER
-                           First := First - 1;
-                           Result (First) := Data.Terminals.all (Tree.Terminal 
(Children (2)));
-
-                           Node := Children (1);
-                        else
-                           raise SAL.Programmer_Error;
-                        end if;
-                     end;
-                  end loop;
-                  return Result (First .. Result'Last);
-               end Get_Loc_List;
-
-               Loc_List : constant Base_Token_Array := Get_Loc_List;
-
-               function Get_Loc (Index : in SAL.Peek_Type) return String
-               is (Data.Grammar_Lexer.Buffer_Text (Loc_List 
(Index).Byte_Region));
-
-            begin
-               if Get_Loc (Loc_List'First) = "actions" then
-                  Location :=
-                    (if Get_Loc (2) = "spec" then
-                       (if Get_Loc (3) = "context" then 
WisiToken.BNF.Actions_Spec_Context
-                        elsif Get_Loc (3) = "pre" then 
WisiToken.BNF.Actions_Spec_Pre
-                        elsif Get_Loc (3) = "post" then 
WisiToken.BNF.Actions_Spec_Post
-                        else raise Grammar_Error with
-                          Error_Message
-                            (Data.Grammar_Lexer.File_Name, Loc_List (2).Line,
-                             "expecting {context | pre | post}"))
-
-                     elsif Get_Loc (2) = "body" then
-                       (if Get_Loc (3) = "context" then 
WisiToken.BNF.Actions_Body_Context
-                        elsif Get_Loc (3) = "pre" then 
WisiToken.BNF.Actions_Body_Pre
-                        elsif Get_Loc (3) = "post" then 
WisiToken.BNF.Actions_Body_Post
-                        else raise Grammar_Error with
-                          Error_Message
-                            (Data.Grammar_Lexer.File_Name, Loc_List (2).Line,
-                             "expecting {context | pre | post}"))
-
-                     else raise Grammar_Error);
-
-               elsif Get_Loc (Loc_List'First) = "copyright_license" then
-                  Location := WisiToken.BNF.Copyright_License;
-
-               else
-                  raise Grammar_Error with
-                    Error_Message
-                      (Data.Grammar_Lexer.File_Name, Loc_List 
(Loc_List'First).Line,
-                       "expecting {actions | copyright_license}");
-               end if;
-
-               Data.Raw_Code (Location) := WisiToken.BNF.Split_Lines (Get_Text 
(Data, Tree, Tokens (4)));
-            exception
-            when Grammar_Error =>
-               Put_Error
-                 (Error_Message
-                    (Data.Grammar_Lexer.File_Name, Token (2).Line, Token 
(2).Column,
-                     "invalid raw code location; actions {spec | body} 
{context | pre | post}"));
-            end;
-
-         when IDENTIFIER_ID =>
-            declare
-               Kind : constant String := Data.Grammar_Lexer.Buffer_Text (Token 
(2).Byte_Region);
-            begin
-               --  Alphabetical by Kind
-
-               if Kind = "case_insensitive" then
-                  --  Not in phase Other
-                  null;
-
-               elsif Kind = "conflict" then
-                  declare
-                     Tree_Indices : constant Valid_Node_Index_Array := 
Tree.Get_Terminals
-                       (Tokens (3));
-                     --   %conflict <action_a>/<action_b> in state <LHS_A>, 
<LHS_B> on token <on>
-                     --              1        2 3         4  5      6     7  8 
     9  10     11
-                  begin
-                     Data.Conflicts.Append
-                       ((Source_Line => Data.Terminals.all (Tree.Terminal 
(Tree_Indices (1))).Line,
-                         Action_A    => +Get_Text (Data, Tree, Tree_Indices 
(1)),
-                         LHS_A       => +Get_Text (Data, Tree, Tree_Indices 
(6)),
-                         Action_B    => +Get_Text (Data, Tree, Tree_Indices 
(3)),
-                         LHS_B       => +Get_Text (Data, Tree, Tree_Indices 
(8)),
-                         On          => +Get_Text (Data, Tree, Tree_Indices 
(11))));
-                  end;
-
-               elsif Kind = "end" then
-                  --  matching '%if' specified current lexer.
-                  null;
-
-               elsif Kind = "elisp_face" then
-                  Data.Tokens.Faces.Append (Get_Text (Data, Tree, Tokens (3), 
Strip_Quotes => True));
-
-               elsif Kind = "elisp_indent" then
-                  Data.Tokens.Indents.Append
-                    ((Name  => +Get_Child_Text (Data, Tree, Tokens (3), 1, 
Strip_Quotes => True),
-                      Value => +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               elsif Kind = "elisp_action" then
-                  Data.Tokens.Actions.Insert
-                    (Key             => +Get_Child_Text (Data, Tree, Tokens 
(3), 2),
-                     New_Item        =>
-                       (Action_Label => +Get_Child_Text (Data, Tree, Tokens 
(3), 1),
-                        Ada_Name     => +Get_Child_Text (Data, Tree, Tokens 
(3), 3)));
-
-               elsif Kind = "end_names_optional_option" then
-                  Data.Language_Params.End_Names_Optional_Option := +Get_Text 
(Data, Tree, Tokens (3));
-
-               elsif Kind = "generate" then
-                  --  Not in Other phase
-                  null;
-
-               elsif Kind = "language_runtime" then
-                  Data.Language_Params.Language_Runtime_Name :=
-                    +Get_Text (Data, Tree, Tokens (3), Strip_Quotes => True);
-
-               elsif Kind = "mckenzie_check_limit" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Check_Limit := Token_Index'Value 
(Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "mckenzie_check_delta_limit" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Check_Delta_Limit := Integer'Value 
(Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "mckenzie_cost_default" then
-                  if Tree.Get_Terminals (Tokens (3))'Length /= 4 then
-                     raise Grammar_Error with
-                       Error_Message
-                         (Data.Grammar_Lexer.File_Name,
-                          Data.Terminals.all (Tree.First_Shared_Terminal 
(Tokens (3))).Line,
-                          "too " & (if Tree.Get_Terminals (Tokens (3))'Length 
> 4 then "many" else "few") &
-                            " default costs; should be 'insert, delete, push 
back, ignore check fail'.");
-                  end if;
-
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Source_Line := Data.Terminals.all
-                    (Tree.First_Shared_Terminal (Tokens (1))).Line;
-
-                  Data.McKenzie_Recover.Default_Insert          := 
Natural'Value
-                    (Get_Child_Text (Data, Tree, Tokens (3), 1));
-                  Data.McKenzie_Recover.Default_Delete_Terminal := 
Natural'Value
-                    (Get_Child_Text (Data, Tree, Tokens (3), 2));
-                  Data.McKenzie_Recover.Default_Push_Back       := 
Natural'Value
-                    (Get_Child_Text (Data, Tree, Tokens (3), 3));
-                  Data.McKenzie_Recover.Ignore_Check_Fail       := 
Natural'Value
-                    (Get_Child_Text (Data, Tree, Tokens (3), 4));
-
-               elsif Kind = "mckenzie_cost_delete" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Delete.Append
-                    ((+Get_Child_Text (Data, Tree, Tokens (3), 1),
-                      +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               elsif Kind = "mckenzie_cost_fast_forward" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Fast_Forward :=
-                    Integer'Value (Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "mckenzie_cost_insert" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Insert.Append
-                    ((+Get_Child_Text (Data, Tree, Tokens (3), 1),
-                      +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               elsif Kind = "mckenzie_cost_matching_begin" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Matching_Begin :=
-                    Integer'Value (Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "mckenzie_cost_push_back" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Push_Back.Append
-                    ((+Get_Child_Text (Data, Tree, Tokens (3), 1),
-                      +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               elsif Kind = "mckenzie_cost_undo_reduce" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Undo_Reduce.Append
-                    ((+Get_Child_Text (Data, Tree, Tokens (3), 1),
-                      +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               elsif Kind = "mckenzie_enqueue_limit" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Enqueue_Limit := Natural'Value 
(Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "mckenzie_minimal_complete_cost_delta" then
-                  Data.Language_Params.Error_Recover := True;
-                  Data.McKenzie_Recover.Minimal_Complete_Cost_Delta :=
-                    Integer'Value (Get_Text (Data, Tree, Tokens (3)));
-
-               elsif Kind = "meta_syntax" then
-                  --  not in Other phase
-                  null;
-
-               elsif Kind = "no_enum" then
-                  Data.Language_Params.Declare_Enums := False;
-
-               elsif Kind = "no_language_runtime" then
-                  Data.Language_Params.Use_Language_Runtime := False;
-
-               elsif Kind = "partial_recursion" then
-                  Data.Language_Params.Partial_Recursion := True;
-
-               elsif Kind = "start" then
-                  Data.Language_Params.Start_Token := +Get_Text (Data, Tree, 
Tokens (3));
-
-               elsif Kind = "re2c_regexp" then
-                  Data.Tokens.re2c_Regexps.Append
-                    ((+Get_Child_Text (Data, Tree, Tokens (3), 1),
-                      +Get_Child_Text (Data, Tree, Tokens (3), 2)));
-
-               else
-                  raise Grammar_Error with Error_Message
-                    (Data.Grammar_Lexer.File_Name, Token (2).Line, Token 
(2).Column, "unexpected syntax");
-
-               end if;
-            end;
-
-         when others =>
-            raise Grammar_Error with Error_Message
-              (Data.Grammar_Lexer.File_Name, Token (2).Line, Token (2).Column, 
"unexpected syntax");
-         end case;
-
-      when Syntax_Trees.Virtual_Terminal | Syntax_Trees.Virtual_Identifier =>
-         raise SAL.Programmer_Error;
-      end case;
-   end Add_Declaration;
-
-   procedure Add_Nonterminal
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array)
-   is
-      use all type Ada.Containers.Count_Type;
-      use WisiToken.Syntax_Trees;
-
-      Data : User_Data_Type renames User_Data_Type (User_Data);
-
-      LHS_Node   : constant Valid_Node_Index := Tokens (1);
-      LHS_String : constant String           := Get_Text (Data, Tree, 
LHS_Node);
-
-      Right_Hand_Sides : WisiToken.BNF.RHS_Lists.List;
-      Labels           : WisiToken.BNF.String_Arrays.Vector;
-   begin
-      if Data.Phase = Meta or Data.Ignore_Lines then
-         return;
-      end if;
-
-      Data.Rule_Count := Data.Rule_Count + 1;
-
-      Get_Right_Hand_Sides (Data, Tree, Right_Hand_Sides, Labels, Tokens (3));
-
-      if WisiToken.BNF.Is_Present (Data.Tokens.Rules, LHS_String) then
-         case Tree.Label (LHS_Node) is
-         when Shared_Terminal =>
-            declare
-               LHS_Token : Base_Token renames Data.Terminals.all 
(Tree.Terminal (LHS_Node));
-            begin
-               raise Grammar_Error with Error_Message
-                 (Data.Grammar_Lexer.File_Name, LHS_Token.Line, 
LHS_Token.Column, "duplicate nonterm");
-            end;
-
-         when Virtual_Identifier =>
-            raise Grammar_Error with Error_Message
-              (Data.Grammar_Lexer.File_Name, 1, 1, "duplicate virtual nonterm 
'" & LHS_String & "'");
-
-         when others =>
-            Raise_Programmer_Error ("Add_Nonterminal", Data, Tree, LHS_Node);
-         end case;
-      else
-         Data.Label_Count := Data.Label_Count + Labels.Length;
-
-         Data.Tokens.Rules.Append
-           ((+LHS_String, Right_Hand_Sides, Labels,
-             Source_Line =>
-               (case Tree.Label (LHS_Node) is
-                when Shared_Terminal    => Data.Terminals.all 
(Tree.First_Shared_Terminal (LHS_Node)).Line,
-                when Virtual_Identifier => Invalid_Line_Number, -- IMPROVEME: 
get line from Right_Hand_Sides
-                when others             => raise SAL.Programmer_Error)));
-      end if;
-   end Add_Nonterminal;
-
-   function Image_Grammar_Action (Action : in 
WisiToken.Syntax_Trees.Semantic_Action) return String
-   is
-      pragma Unreferenced (Action);
-   begin
-      return "action";
-   end Image_Grammar_Action;
-
-   procedure Check_EBNF
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array;
-      Token     : in     WisiToken.Positive_Index_Type)
-   is
-      Data : User_Data_Type renames User_Data_Type (User_Data);
-   begin
-      case Data.Phase is
-      when Meta =>
-         Data.EBNF_Nodes (Tokens (Token)) := True;
-
-         if Data.Meta_Syntax /= EBNF_Syntax then
-            declare
-               Tok  : Base_Token renames Data.Terminals.all 
(Tree.First_Shared_Terminal (Tokens (Token)));
-            begin
-               raise Grammar_Error with Error_Message
-                 (Data.Grammar_Lexer.File_Name, Tok.Line, Tok.Column,
-                  "EBNF syntax used, but BNF specified; set '%meta_syntax 
EBNF'");
-            end;
-         end if;
-      when Other =>
-         Raise_Programmer_Error ("untranslated EBNF node", Data, Tree, 
Tree.Parent (Tokens (Token)));
-      end case;
-   end Check_EBNF;
-
-   procedure Raise_Programmer_Error
-     (Label : in String;
-      Data  : in User_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree;
-      Node  : in WisiToken.Node_Index)
-   is begin
-      WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error
-        (Label, Wisitoken_Grammar_Actions.Descriptor, Data.Grammar_Lexer, 
Tree, Data.Terminals.all, Node);
-   end Raise_Programmer_Error;
-
-   function Find_Declaration
-     (Data : in     User_Data_Type;
-      Tree : in out WisiToken.Syntax_Trees.Tree;
-      Name : in     String)
-     return WisiToken.Node_Index
-   is
-      use WisiToken.Syntax_Trees.LR_Utils;
-      use WisiToken.Syntax_Trees.LR_Utils.Creators;
-
-      function Decl_Name (Decl : in Valid_Node_Index) return String
-      is begin
-         case To_Token_Enum (Tree.ID (Decl)) is
-         when declaration_ID =>
-            case Tree.RHS_Index (Decl) is
-            when 0 =>
-               return Get_Text (Data, Tree, Tree.Child (Decl, 3));
-
-            when 2 | 3 =>
-               return Get_Text (Data, Tree, Tree.Child (Decl, 2));
-
-            when others =>
-               return "";
-            end case;
-
-         when nonterminal_ID =>
-            return Get_Text (Data, Tree, Tree.Child (Decl, 1));
-
-         when others =>
-            return "";
-         end case;
-      end Decl_Name;
-
-      --  Tree.Root is wisitoken_accept
-      List : constant Constant_List := Create_List
-        (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID);
-   begin
-      for N of List loop
-         declare
-            Decl : constant Valid_Node_Index := Tree.Child (N, 1);
-         begin
-            if Name = Decl_Name (Decl) then
-               return Decl;
-            end if;
-         end;
-      end loop;
-      return Invalid_Node_Index;
-   end Find_Declaration;
-
-   procedure Translate_EBNF_To_BNF
-     (Tree : in out WisiToken.Syntax_Trees.Tree;
-      Data : in out User_Data_Type)
-   is
-      use all type SAL.Base_Peek_Type;
-      use WisiToken.Syntax_Trees;
-
-      Copied_EBNF_Nodes : WisiToken.Valid_Node_Index_Arrays.Vector;
-
-      Symbol_Regexp : constant GNAT.Regexp.Regexp := GNAT.Regexp.Compile
-        ((if Data.Language_Params.Case_Insensitive
-          then "[A-Z0-9_]+"
-          else "[a-zA-Z0-9_]+"),
-         Case_Sensitive => not Data.Language_Params.Case_Insensitive);
-
-      procedure Erase_Copied_EBNF_Node (Node : in Valid_Node_Index)
-      is
-         use Ada.Text_IO;
-         Found : Boolean := False;
-      begin
-         if Trace_Generate_EBNF > Outline then
-            Put_Line ("erase copied deleted EBNF node" & Node'Image);
-         end if;
-         --  Vector Delete replaces content with
-         --  Valid_Node_Index_Arrays.Default_Element = Valid_Node_Index'Last =
-         --  Deleted_Child; this is clearer.
-
-         for I in Copied_EBNF_Nodes.First_Index .. 
Copied_EBNF_Nodes.Last_Index loop
-            if Copied_EBNF_Nodes (I) = Node then
-               Copied_EBNF_Nodes (I) := Deleted_Child;
-               Found := True;
-               exit;
-            end if;
-         end loop;
-         if not Found then
-            Put_Line (Current_Error, Tree.Image
-                        (Node, Wisitoken_Grammar_Actions.Descriptor, 
Node_Numbers => True) &
-                        " not found in Copied_EBNF_Nodes");
-            raise SAL.Programmer_Error;
-         end if;
-      end Erase_Copied_EBNF_Node;
-
-      procedure Clear_EBNF_Node (Node : in Valid_Node_Index)
-      is begin
-         if Node in Data.EBNF_Nodes.First_Index .. Data.EBNF_Nodes.Last_Index 
then
-            if Trace_Generate_EBNF > Outline then
-               Ada.Text_IO.Put_Line ("clear translated EBNF node" & 
Node'Image);
-            end if;
-
-            Data.EBNF_Nodes (Node) := False;
-         else
-            Erase_Copied_EBNF_Node (Node);
-         end if;
-      end Clear_EBNF_Node;
-
-      function New_Identifier (Text : in String) return Identifier_Index
-      is
-         ID : constant Identifier_Index := Base_Identifier_Index 
(Data.Tokens.Virtual_Identifiers.Length) + 1;
-      begin
-         Data.Tokens.Virtual_Identifiers.Append (+Text);
-         return ID;
-      end New_Identifier;
-
-      Keyword_Ident : constant Identifier_Index := New_Identifier ("keyword");
-      Percent_Ident : constant Identifier_Index := New_Identifier ("percent");
-
-      function Next_Nonterm_Name (Suffix : in String := "") return 
Identifier_Index
-      is
-         function Image is new SAL.Generic_Decimal_Image (Identifier_Index);
-         ID : constant Identifier_Index := Identifier_Index 
(Data.Tokens.Virtual_Identifiers.Length) + 1;
-      begin
-
-         if ID > 999 then
-            --  We assume 3 digits below
-            raise SAL.Programmer_Error with "more than 3 digits needed for 
virtual identifiers in EBNF translate";
-         end if;
-
-         Data.Tokens.Virtual_Identifiers.Append (+("nonterminal_" & Image (ID, 
Width => 3) & Suffix));
-
-         return ID;
-      end Next_Nonterm_Name;
-
-      function Find_Nonterminal
-        (Target : in String;
-         Equal  : in WisiToken.Syntax_Trees.LR_Utils.Find_Equal)
-        return Node_Index
-      is
-         use WisiToken.Syntax_Trees.LR_Utils;
-      begin
-         return Get_Node
-           (Creators.Create_List
-              (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID).Find
-              (Target, Equal));
-      end Find_Nonterminal;
-
-      function Tree_Add_Nonterminal
-        (Child_1 : in Valid_Node_Index;
-         Child_2 : in Valid_Node_Index;
-         Child_3 : in Valid_Node_Index;
-         Child_4 : in Valid_Node_Index)
-        return Valid_Node_Index
-      is begin
-         --  Work around GNAT error about arbitrary evaluation order in
-         --  aggregates (no error about the arbitrary order in subprogram
-         --  parameter_assocation_lists!).
-         return Tree.Add_Nonterm
-           (Production => (+nonterminal_ID, 0),
-            Children   => (Child_1, Child_2, Child_3, Child_4),
-            Action     => Wisitoken_Grammar_Actions.nonterminal_0'Access);
-      end Tree_Add_Nonterminal;
-
-      function Duplicate
-        (List        : in Syntax_Trees.LR_Utils.List;
-         New_Content : in Node_Index)
-        return Boolean
-      is
-         --  We don't require New_Content.ID = List.Element_ID; since we are
-         --  comparing result of Get_Text.
-         New_Content_Str : constant String :=
-           (if New_Content = Invalid_Node_Index
-            then "" --  Empty RHS
-            else Get_Text (Data, Tree, New_Content));
-      begin
-         for N of List loop
-            if New_Content_Str = Get_Text (Data, Tree, N) then
-               return True;
-            end if;
-         end loop;
-         return False;
-      end Duplicate;
-
-      procedure Insert_Empty_RHS
-        (RHS_List : in out WisiToken.Syntax_Trees.LR_Utils.List;
-         After    : in     Valid_Node_Index)
-      with Pre => RHS_List.List_ID = +rhs_list_ID and RHS_List.Element_ID = 
+rhs_ID and
-                  Tree.ID (After) = +rhs_ID and RHS_List.Contains (After)
-      is begin
-         RHS_List.Insert
-           (New_Element => Tree.Add_Nonterm
-              ((+rhs_ID, 0),
-               (1 .. 0 => Invalid_Node_Index)),
-            After => RHS_List.To_Cursor (After));
-      end Insert_Empty_RHS;
-
-      procedure Insert_RHS
-        (RHS_List          : in out WisiToken.Syntax_Trees.LR_Utils.List;
-         New_RHS_Item_List : in     Valid_Node_Index;
-         After             : in     Valid_Node_Index)
-      with Pre => RHS_List.List_ID = +rhs_list_ID and RHS_List.Element_ID = 
+rhs_ID and
-                  Tree.ID (New_RHS_Item_List) = +rhs_item_list_ID and
-                  Tree.ID (After) = +rhs_ID and RHS_List.Contains (After)
-      is begin
-         RHS_List.Insert
-           (New_Element => Tree.Add_Nonterm
-              (Production => (+rhs_ID, Tree.RHS_Index (After)),
-               Children =>
-                 (case Tree.RHS_Index (After) is
-                  when 1 => (1 => New_RHS_Item_List),
-                  when 2 => (New_RHS_Item_List, Tree.Copy_Subtree (Tree.Child 
(After, 2))),
-                  when 3 => (New_RHS_Item_List,
-                             Tree.Copy_Subtree (Tree.Child (After, 2)),
-                             Tree.Copy_Subtree (Tree.Child (After, 3))),
-                  when others => raise SAL.Programmer_Error)),
-            After => RHS_List.To_Cursor (After));
-      end Insert_RHS;
-
-      procedure Record_Copied_EBNF_Nodes (Node : in Valid_Node_Index)
-      is
-         procedure Record_Copied_Node
-           (Tree : in out WisiToken.Syntax_Trees.Tree;
-            Node : in WisiToken.Valid_Node_Index)
-         is begin
-            if To_Token_Enum (Tree.ID (Node)) in
-              rhs_optional_item_ID |
-              rhs_multiple_item_ID |
-              rhs_group_item_ID |
-              rhs_attribute_ID |
-              STRING_LITERAL_2_ID
-            then
-               if Trace_Generate_EBNF > Outline then
-                  Ada.Text_IO.Put_Line
-                    ("new EBNF node " & Tree.Image
-                       (Node, Wisitoken_Grammar_Actions.Descriptor,
-                        Node_Numbers => True));
-               end if;
-               Copied_EBNF_Nodes.Append (Node);
-            end if;
-         end Record_Copied_Node;
-      begin
-         Tree.Process_Tree (Record_Copied_Node'Access, Node);
-      end Record_Copied_EBNF_Nodes;
-
-      procedure Erase_Deleted_EBNF_Nodes (Node : in Valid_Node_Index)
-      is
-         procedure Erase_Deleted_Node
-           (Tree : in out WisiToken.Syntax_Trees.Tree;
-            Node : in WisiToken.Valid_Node_Index)
-         is begin
-            if To_Token_Enum (Tree.ID (Node)) in
-              rhs_optional_item_ID |
-              rhs_multiple_item_ID |
-              rhs_group_item_ID |
-              rhs_attribute_ID |
-              STRING_LITERAL_2_ID
-            then
-               if Node in Data.EBNF_Nodes.First_Index .. 
Data.EBNF_Nodes.Last_Index then
-                  --  Node is original, not copied
-                  if Trace_Generate_EBNF > Outline then
-                     Ada.Text_IO.Put_Line ("erase original deleted EBNF node" 
& Node'Image);
-                  end if;
-                  Data.EBNF_Nodes (Node) := False;
-               else
-                  Erase_Copied_EBNF_Node (Node);
-               end if;
-            end if;
-         end Erase_Deleted_Node;
-      begin
-         Tree.Process_Tree (Erase_Deleted_Node'Access, Node);
-      end Erase_Deleted_EBNF_Nodes;
-
-      function Insert_Optional_RHS (B : in Valid_Node_Index) return 
Valid_Node_Index
-      with Pre => Tree.ID (B) in +rhs_multiple_item_ID | +rhs_optional_item_ID 
| +IDENTIFIER_ID
-      is
-         --  B is an optional item in an rhs_item_list:
-         --  | A B? C
-         --
-         --  or B is a rhs_multiple_item that is allowed to be empty:
-         --  | A B* C
-         --
-         --  or B is a virtual identifier naming the new nonterm replacing the
-         --  original
-         --
-         --  A, C can be empty. The containing element may be rhs or
-         --  rhs_alternative_list.
-         --
-         --  Insert either a second rhs, or a second rhs_item_list, after the
-         --  one containing B, without B.
-         --
-         --  Return the List_Root of the edited list.
-
-         use Syntax_Trees.LR_Utils;
-         use Syntax_Trees.LR_Utils.Creators;
-         use all type Ada.Containers.Count_Type;
-
-         function Find_Skips return Skip_Info
-         is
-            Non_Empty_List : Node_Index := Invalid_Node_Index;
-            --  First (nearest) rhs_item_list ancestor of B that will not be 
empty
-            --  when B is skipped.
-
-            Skip_Last        : Positive_Index_Type'Base := 
Positive_Index_Type'First;
-            Last_Skip_Node   : Valid_Node_Index         := Tree.Find_Ancestor 
(B, +rhs_element_ID);
-            Reset_Search_For : WisiToken.Token_ID       := +rhs_item_list_ID;
-
-            procedure Search (Result : in out Skip_Info)
-            is
-               Skip_Node  : Valid_Node_Index   := Last_Skip_Node;
-               Search_For : WisiToken.Token_ID := Reset_Search_For;
-            begin
-               loop
-                  case To_Token_Enum (Search_For) is
-                  when rhs_item_list_ID =>
-                     Skip_Node := Tree.Find_Ancestor (Skip_Node, 
+rhs_item_list_ID);
-
-                     Skip_Node := List_Root (Tree, Skip_Node, 
+rhs_item_list_ID);
-
-                     Search_For := +rhs_element_ID;
-
-                     if Result.Skips'Length = 0 then
-                        declare
-                           List_Count : constant Ada.Containers.Count_Type := 
Create_List
-                             (Tree, Skip_Node, +rhs_item_list_ID, 
+rhs_element_ID).Count;
-                        begin
-                           if List_Count > 1 then
-                              Non_Empty_List := List_Root (Tree, Skip_Node, 
+rhs_item_list_ID);
-                              exit;
-
-                           elsif Skip_Last = Positive_Index_Type'First and 
List_Count = 1 then
-                              --  This list will be empty; no need to descend 
into it
-                              Last_Skip_Node   := Skip_Node;
-                              Reset_Search_For := Search_For;
-                           else
-                              Skip_Last := Skip_Last + 1;
-                           end if;
-                        end;
-                     else
-                        Result.Skips (Skip_Last) :=
-                          (Label             => Nested,
-                           Element           => Skip_Node,
-                           List_Root         => Skip_Node,
-                           List_ID           => +rhs_item_list_ID,
-                           Element_ID        => +rhs_element_ID,
-                           Separator_ID      => Invalid_Token_ID,
-                           Multi_Element_RHS => 1);
-
-                        Skip_Last := Skip_Last - 1;
-                     end if;
-
-                  when rhs_element_ID =>
-                     declare
-                        List_Node : Valid_Node_Index := Tree.Find_Ancestor
-                          (Skip_Node, (+rhs_ID, +rhs_alternative_list_ID));
-                     begin
-
-                        if Result.Skips'Length = 0 and then
-                          Tree.ID (List_Node) = +rhs_ID
-                        then
-                           Non_Empty_List := List_Root (Tree, Skip_Node, 
+rhs_item_list_ID);
-                           Skip_Last      := Skip_Last - 1;
-                           exit;
-                        end if;
-
-                        List_Node := List_Root (Tree, List_Node, 
+rhs_alternative_list_ID);
-                        Skip_Node := Tree.Find_Ancestor (Skip_Node, 
+rhs_element_ID);
-
-                        Search_For := +rhs_item_list_ID;
-
-                        if Result.Skips'Length = 0 then
-                           if Skip_Last = Positive_Index_Type'First then
-                              --  This list will be empty; no need to descend 
into it
-                              Last_Skip_Node   := Skip_Node;
-                              Reset_Search_For := Search_For;
-                           else
-                              Skip_Last := Skip_Last + 1;
-                           end if;
-                        else
-                           Result.Skips (Skip_Last) :=
-                             (Label             => Nested,
-                              Element           => Skip_Node,
-                              List_Root         => List_Node,
-                              List_ID           => +rhs_alternative_list_ID,
-                              Element_ID        => +rhs_item_list_ID,
-                              Separator_ID      => +BAR_ID,
-                              Multi_Element_RHS => 1);
-
-                           Skip_Last := Skip_Last - 1;
-                        end if;
-                     end;
-                  when others =>
-                     raise SAL.Programmer_Error;
-                  end case;
-
-               end loop;
-            end Search;
-
-            Result_1 : Skip_Info (Skip_Last => Positive_Index_Type'First - 1);
-         begin
-            --  First count the number of Skip_Items we need, and set
-            --  Non_Empty_List.
-            Search (Result_1);
-
-            declare
-               Result : Skip_Info (Skip_Last);
-            begin
-               if Result.Skips'Length = 0 then
-                  return Result;
-               end if;
-
-               Result.Start_List_Root  := Non_Empty_List;
-               Result.Start_List_ID    := +rhs_item_list_ID;
-               Result.Start_Element_ID := +rhs_element_ID;
-
-               Result.Start_Separator_ID      := Invalid_Token_ID;
-               Result.Start_Multi_Element_RHS := 1;
-
-               Result.Skips (Skip_Last) := (Skip, Last_Skip_Node);
-
-               if Result.Skips'Length = 1 then
-                  return Result;
-               end if;
-
-               Search (Result);
-               return Result;
-            end;
-         end Find_Skips;
-
-         Container : Valid_Node_Index := Tree.Find_Ancestor (B, (+rhs_ID, 
+rhs_alternative_list_ID));
-         Container_ID : WisiToken.Token_ID := Tree.ID (Container);
-
-         Container_List : Syntax_Trees.LR_Utils.List :=
-           (if Container_ID = +rhs_ID
-            then Create_From_Element
-              (Tree,
-               Element      => Container,
-               List_ID      => +rhs_list_ID,
-               Element_ID   => +rhs_ID,
-               Separator_ID => +BAR_ID)
-            else Create_List
-              (Tree,
-               Root         => List_Root (Tree, Container, 
+rhs_alternative_list_ID),
-               List_ID      => +rhs_alternative_list_ID,
-               Element_ID   => +rhs_item_list_ID,
-               Separator_ID => +BAR_ID));
-
-      begin
-         if Trace_Generate_EBNF > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Insert_Optional_RHS start:");
-            Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor, Container);
-         end if;
-
-         declare
-            Skip_List : constant Skip_Info := Find_Skips;
-
-            New_RHS_AC   : Node_Index := Invalid_Node_Index;
-            Is_Duplicate : Boolean    := False;
-         begin
-            if WisiToken.Trace_Generate_EBNF > Extra then
-               Ada.Text_IO.New_Line;
-               Ada.Text_IO.Put_Line ("skip: " & Image (Skip_List, 
Wisitoken_Grammar_Actions.Descriptor));
-            end if;
-
-            if Skip_List.Skips'Length = 0 or else
-              +rhs_ID = Tree.ID (Tree.Parent (Skip_List.Start_List_Root))
-            then
-               --  Insert an edited rhs into the rhs_list.
-               --
-               --  We can't insert an empty rhs_item_list into an
-               --  rhs_alterative_list, so we insert an empty rhs.
-
-               if Container_ID = +rhs_alternative_list_ID then
-
-                  Container := Tree.Find_Ancestor (B, +rhs_ID);
-
-                  Container_ID := +rhs_ID;
-
-                  Container_List := Create_From_Element
-                    (Tree,
-                     Element      => Container,
-                     List_ID      => +rhs_list_ID,
-                     Element_ID   => +rhs_ID,
-                     Separator_ID => +BAR_ID);
-               end if;
-
-               if Skip_List.Skips'Length = 0 then
-                  --  New rhs is empty; no rhs_item_list
-                  null;
-               else
-                  New_RHS_AC := Copy_Skip_Nested (Skip_List, Tree);
-               end if;
-
-               if Duplicate (Container_List, New_RHS_AC) then
-                  Is_Duplicate := True;
-               else
-                  if Skip_List.Skips'Length = 0 then
-                     Insert_Empty_RHS (Container_List, Container);
-                  else
-                     Insert_RHS (Container_List, New_RHS_AC, After => 
Container);
-                  end if;
-               end if;
-
-            else
-               --  Insert an edited rhs_item_list into an rhs_alternative_list
-
-               New_RHS_AC := Copy_Skip_Nested (Skip_List, Tree);
-
-               if Duplicate (Container_List, New_RHS_AC) then
-                  --  IMPROVEME: check for duplicate before do copy; requires 
version of
-                  --  Get_Text that understands Skip_Info
-                  Is_Duplicate := True;
-               else
-                  declare
-                     After : Valid_Node_Index := B;
-                  begin
-                     loop
-                        After := List_Root (Tree, Tree.Find_Ancestor (After, 
+rhs_item_list_ID), +rhs_item_list_ID);
-                        exit when Container_List.Contains (After);
-                     end loop;
-
-                     Container_List.Insert
-                       (New_Element => New_RHS_AC,
-                        After       => Container_List.To_Cursor (After));
-                  end;
-               end if;
-            end if;
-
-            if Trace_Generate_EBNF > Detail then
-               Ada.Text_IO.New_Line;
-               if Is_Duplicate then
-                  Ada.Text_IO.Put_Line ("Insert_Optional_RHS duplicate '" & 
Get_Text (Data, Tree, New_RHS_AC) & "'");
-               else
-                  if Container_ID = +rhs_ID then
-                     Ada.Text_IO.Put_Line ("Insert_Optional_RHS old rhs, new 
rhs:");
-                     Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor, 
Container_List.Root);
-                  else
-                     Ada.Text_IO.Put_Line ("Insert_Optional_RHS edited 
rhs_alternative_list:");
-                     Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor, 
Tree.Parent (Container_List.Root, 1));
-                  end if;
-               end if;
-            end if;
-
-            if not (Skip_List.Skips'Length = 0 or Is_Duplicate) then
-               Record_Copied_EBNF_Nodes (New_RHS_AC);
-            end if;
-         end;
-         return Container_List.Root;
-      end Insert_Optional_RHS;
-
-      procedure Add_Compilation_Unit (Label : in String; Unit : in 
Valid_Node_Index; Prepend : in Boolean := False)
-      with Pre => Tree.ID (Unit) in +declaration_ID | +nonterminal_ID
-      is
-         use WisiToken.Syntax_Trees.LR_Utils;
-
-         List : Syntax_Trees.LR_Utils.List := Creators.Create_List
-           (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID, Invalid_Token_ID);
-
-         Comp_Unit : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+compilation_unit_ID, (if Tree.ID (Unit) = +declaration_ID then 0 
else 1)),
-            (1 => Unit));
-
-         function Equal
-           (Target    : in String;
-            List      : in LR_Utils.Constant_List'Class;
-            Comp_Unit : in Valid_Node_Index)
-           return Boolean
-         is
-            pragma Unreferenced (List);
-            Decl : constant Valid_Node_Index := Tree.Child (Comp_Unit, 1);
-         begin
-            return Tree.ID (Decl) = +declaration_ID and then Target =
-              (case Tree.RHS_Index (Decl) is
-               when 0      => Get_Text (Data, Tree, Tree.Child (Decl, 3)),
-               when 2 | 3  => Get_Text (Data, Tree, Tree.Child (Decl, 2)),
-               when others => "");
-         end Equal;
-
-      begin
-         if Prepend then
-            --  Prepend is true for keywords, which must be declared before 
they
-            --  are used. We put them all after the %meta_syntax declaration, 
to
-            --  closer match the likely original EBNF layout.
-            declare
-               Meta_Syntax : constant Cursor := List.Find ("meta_syntax", 
Equal'Unrestricted_Access);
-            begin
-               List.Insert (Comp_Unit, After => Meta_Syntax);
-            end;
-         else
-            List.Append (Comp_Unit);
-         end if;
-
-         if Trace_Generate_EBNF > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("new " & Label & ":" & Comp_Unit'Image & ": 
'" & Get_Text (Data, Tree, Unit) & "'");
-         end if;
-      end Add_Compilation_Unit;
-
-      function To_RHS_List (RHS_Element : in Valid_Node_Index) return 
Valid_Node_Index
-      with Pre => Tree.ID (RHS_Element) = +rhs_element_ID
-      is
-         RHS_Item_List : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_item_list_ID, 0), (1 => RHS_Element));
-         RHS           : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_ID, 1),           (1 => RHS_Item_List));
-      begin
-         return Tree.Add_Nonterm ((+rhs_list_ID, 0), (1 => RHS));
-      end To_RHS_List;
-
-      function Convert_RHS_Alternative (Content : in Valid_Node_Index) return 
Valid_Node_Index
-      with Pre => Tree.ID (Content) = +rhs_alternative_list_ID
-      is
-         --  Convert rhs_alternative_list rooted at Content to an rhs_list
-         Node : Valid_Node_Index := Content;
-      begin
-         loop
-            exit when Tree.RHS_Index (Node) = 0;
-
-            --  current tree:
-            --  rhs_alternative_list : Node
-            --  | rhs_alternative_list: Node.Child (1)
-            --  | |  ...
-            --  | BAR: Node.child (2)
-            --  | rhs_item_list: Node.Child (3)
-
-            --  new tree:
-            --  rhs_list: Node
-            --  | rhs_alternative_list: keep Node.Child (1)
-            --  | |  ...
-            --  | BAR: keep
-            --  | rhs: new
-            --  | | rhs_item_list: keep Node,Child (3)
-
-            if not Tree.Has_Children (Tree.Child (Node, 3)) then
-               --  Convert empty rhs_item_list to empty rhs
-               Tree.Set_Children
-                 (Tree.Child (Node, 3),
-                  (+rhs_ID, 0),
-                  (1 .. 0 => Invalid_Node_Index));
-
-               Tree.Set_Children
-                 (Node,
-                  (+rhs_list_ID, 1),
-                  (1 => Tree.Child (Node, 1),
-                   2 => Tree.Child (Node, 2),
-                   3 => Tree.Child (Node, 3)));
-            else
-               Tree.Set_Children
-                 (Node,
-                  (+rhs_list_ID, 1),
-                  (1 => Tree.Child (Node, 1),
-                   2 => Tree.Child (Node, 2),
-                   3 => Tree.Add_Nonterm
-                     ((+rhs_ID, 1),
-                      (1 => Tree.Child (Node, 3)))));
-            end if;
-
-            Node := Tree.Child (Node, 1);
-         end loop;
-
-         --  current tree:
-         --  rhs_alternative_list : Node
-         --  | rhs_item_list: Node.Child (1)
-
-         --  new tree:
-         --  rhs_list: Node
-         --  | rhs: new
-         --  | | rhs_item_list: Node.Child (1)
-
-         Tree.Set_Children
-           (Node,
-            (+rhs_list_ID, 0),
-            (1 => Tree.Add_Nonterm ((+rhs_ID, 1), (1 => Tree.Child (Node, 
1)))));
-
-         return Content;
-      end Convert_RHS_Alternative;
-
-      procedure New_Nonterminal
-        (Label          : in String;
-         New_Identifier : in Identifier_Index;
-         Content        : in Valid_Node_Index)
-      with Pre => To_Token_Enum (Tree.ID (Content)) in rhs_alternative_list_ID 
| rhs_element_ID
-      is
-         --  Convert subtree rooted at Content to an rhs_list contained by a 
new nonterminal
-         --  named New_Identifier.
-      begin
-         declare
-            New_Nonterm : constant Valid_Node_Index := Tree_Add_Nonterminal
-              (Child_1   => Tree.Add_Identifier (+IDENTIFIER_ID, 
New_Identifier, Tree.Byte_Region (Content)),
-               Child_2   => Tree.Add_Terminal (+COLON_ID),
-               Child_3   =>
-                 (case To_Token_Enum (Tree.ID (Content)) is
-                  when rhs_element_ID          => To_RHS_List (Content),
-                  when rhs_alternative_list_ID => Convert_RHS_Alternative 
(Content),
-                  when others => raise SAL.Programmer_Error),
-               Child_4   => Tree.Add_Nonterm
-                 ((+semicolon_opt_ID, 0),
-                  (1     => Tree.Add_Terminal (+SEMICOLON_ID))));
-         begin
-            Add_Compilation_Unit (Label & New_Identifier'Image, New_Nonterm);
-         end;
-      end New_Nonterminal;
-
-      procedure New_Nonterminal_List_1
-        (List_Nonterm  : in Identifier_Index;
-         RHS_Element_1 : in Valid_Node_Index;
-         RHS_Element_3 : in Valid_Node_Index;
-         Byte_Region   : in Buffer_Region)
-      with Pre => Tree.ID (RHS_Element_1) = +rhs_element_ID and
-                  Tree.ID (RHS_Element_3) = +rhs_element_ID
-      is
-         --  nonterminal: foo_list
-         --  | IDENTIFIER: "foo_list" List_Nonterm
-         --  | COLON:
-         --  | rhs_list:
-         --  | | rhs_list: RHS_List_2
-         --  | | | rhs: RHS_2
-         --  | | | | rhs_item_list: RHS_Item_List_1
-         --  | | | | | rhs_element: RHS_Element_1
-         --  | | | | | | rhs_item: RHS_Item_1
-         --  | | | | | | | IDENTIFIER: List_Element
-         --  | | BAR:
-         --  | | rhs: RHS_3
-         --  | | | rhs_item_list: RHS_Item_List_2
-         --  | | | | | rhs_item_list: RHS_Item_List_3
-         --  | | | | | |  rhs_element: RHS_Element_2
-         --  | | | | | | | rhs_item: RHS_Item_2
-         --  | | | | | | | | IDENTIFIER: List_Nonterm
-         --  | | | | rhs_element: RHS_Element_3
-         --  | | | | | rhs_item: RHS_Item_3
-         --  | | | | | | IDENTIFIER: List_Element
-         --  | semicolon_opt:
-         --  | | SEMICOLON:
-
-         RHS_Item_2 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_ID, 0), (1 => Tree.Add_Identifier (+IDENTIFIER_ID, 
List_Nonterm, Byte_Region)));
-
-         RHS_Element_2 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_element_ID, 0), (1 => RHS_Item_2));
-
-         RHS_Item_List_1 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_item_list_ID, 0), (1 => RHS_Element_1));
-         RHS_Item_List_3 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_item_list_ID, 0), (1 => RHS_Element_2));
-         RHS_Item_List_2 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_list_ID, 1), (1 => RHS_Item_List_3, 2 => 
RHS_Element_3));
-
-         RHS_2 : constant Valid_Node_Index := Tree.Add_Nonterm ((+rhs_ID, 1), 
(1 => RHS_Item_List_1));
-         RHS_3 : constant Valid_Node_Index := Tree.Add_Nonterm ((+rhs_ID, 1), 
(1 => RHS_Item_List_2));
-
-         Bar_1 : constant Valid_Node_Index := Tree.Add_Terminal (+BAR_ID);
-
-         RHS_List_2 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_list_ID, 0), (1 => RHS_2));
-
-         List_Nonterminal : constant Valid_Node_Index := Tree_Add_Nonterminal
-           (Child_1   => Tree.Add_Identifier (+IDENTIFIER_ID, List_Nonterm, 
Byte_Region),
-            Child_2   => Tree.Add_Terminal (+COLON_ID),
-            Child_3   => Tree.Add_Nonterm
-              ((+rhs_list_ID, 1),
-               (1     => RHS_List_2,
-                2     => Bar_1,
-                3     => RHS_3)),
-            Child_4   => Tree.Add_Nonterm
-              ((+semicolon_opt_ID, 0),
-               (1     => Tree.Add_Terminal (+SEMICOLON_ID))));
-      begin
-         Add_Compilation_Unit ("canonical list" & List_Nonterm'Image, 
List_Nonterminal);
-      end New_Nonterminal_List_1;
-
-      procedure New_Nonterminal_List
-        (List_Nonterm : in Identifier_Index;
-         List_Element : in Identifier_Index;
-         Byte_Region  : in Buffer_Region)
-      is
-         RHS_Item_1 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_ID, 0), (1 => Tree.Add_Identifier (+IDENTIFIER_ID, 
List_Element, Byte_Region)));
-         RHS_Item_3 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_ID, 0), (1 => Tree.Add_Identifier (+IDENTIFIER_ID, 
List_Element, Byte_Region)));
-         RHS_Element_1 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_element_ID, 0), (1 => RHS_Item_1));
-         RHS_Element_3 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_element_ID, 0), (1 => RHS_Item_3));
-      begin
-         New_Nonterminal_List_1 (List_Nonterm, RHS_Element_1, RHS_Element_3, 
Byte_Region);
-      end New_Nonterminal_List;
-
-      procedure New_Nonterminal_List
-        (List_Nonterm : in Identifier_Index;
-         List_Element : in Token_Index;
-         Terminals    : in Base_Token_Arrays.Vector;
-         Byte_Region  : in Buffer_Region)
-      is
-         RHS_Item_1 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_ID, 0), (1 => Tree.Add_Terminal (List_Element, 
Terminals)));
-         RHS_Item_3 : constant Valid_Node_Index := Tree.Add_Nonterm
-           ((+rhs_item_ID, 0), (1 => Tree.Add_Terminal (List_Element, 
Terminals)));
-         RHS_Element_1 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_element_ID, 0), (1 => RHS_Item_1));
-         RHS_Element_3 : constant Valid_Node_Index := Tree.Add_Nonterm 
((+rhs_element_ID, 0), (1 => RHS_Item_3));
-      begin
-         New_Nonterminal_List_1 (List_Nonterm, RHS_Element_1, RHS_Element_3, 
Byte_Region);
-      end New_Nonterminal_List;
-
-      procedure Copy_Non_Grammar
-        (From : in Valid_Node_Index;
-         To   : in Valid_Node_Index)
-      is
-         From_Aug : constant Base_Token_Class_Access := Tree.Augmented (From);
-      begin
-         if From_Aug /= null then
-            declare
-               New_Aug : constant Augmented_Token_Access := new 
Augmented_Token'
-                 (ID          => Tree.ID (From),
-                  Tree_Index  => To,
-                  Non_Grammar => Augmented_Token_Access (From_Aug).Non_Grammar,
-                  others => <>);
-            begin
-               Tree.Set_Augmented (To, Base_Token_Class_Access (New_Aug));
-            end;
-         end if;
-      end Copy_Non_Grammar;
-
-      procedure Translate_RHS_Group_Item (Node : in Valid_Node_Index)
-      is
-         --  Current tree:
-         --
-         --  rhs_element: Parent (Node, 2)
-         --  | rhs_item: Parent (Node, 1)
-         --  | | rhs_group_item: Node
-         --  | | | LEFT_PAREN
-         --  | | | rhs_alternative_list: Child (Node, 2)
-         --  | | | RIGHT_PAREN
-
-         use Syntax_Trees.LR_Utils;
-
-         Element_Content  : constant String           := Get_Text (Data, Tree, 
Tree.Child (Node, 2));
-         Right_Paren_Node : constant Valid_Node_Index := Tree.Child (Node, 3);
-         List             : constant Constant_List    := Creators.Create_List
-           (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID);
-         Name_Node        : Node_Index;
-         New_Ident        : Base_Identifier_Index     := 
Invalid_Identifier_Index;
-      begin
-         --  See if there's an existing nonterminal for this content.
-         for N of List loop
-
-            if Tree.Production_ID (Tree.Child (N, 1)) = (+nonterminal_ID, 0) 
then
-               --  Target nonterm is:
-               --
-               --  (compilation_unit_1, (111 . 128))
-               --  | (nonterminal_0, (111 . 128))
-               --  | |  7;(IDENTIFIER, (111 . 128))
-               --  | | (COLON)
-               --  | | (rhs_list_1, (111 . 128))
-               --  | | | ...
-               declare
-                  RHS_List_1 : constant Node_Index := Tree.Child (Tree.Child 
(N, 1), 3);
-               begin
-                  if RHS_List_1 /= Invalid_Node_Index and then
-                    Element_Content = Get_Text (Data, Tree, RHS_List_1)
-                  then
-                     Name_Node := Tree.Child (Tree.Child (N, 1), 1);
-                     case Tree.Label (Name_Node) is
-                     when Shared_Terminal =>
-                        New_Ident := New_Identifier (Get_Text (Data, Tree, 
Name_Node));
-                     when Virtual_Identifier =>
-                        New_Ident := Tree.Identifier (Name_Node);
-                     when others =>
-                        Raise_Programmer_Error ("process_node rhs_group_item", 
Data, Tree, Name_Node);
-                     end case;
-
-                     exit;
-                  end if;
-               end;
-            end if;
-         end loop;
-
-         if New_Ident = Invalid_Identifier_Index then
-            New_Ident := Next_Nonterm_Name;
-            New_Nonterminal ("group item", New_Ident, Tree.Child (Node, 2));
-         else
-            Erase_Deleted_EBNF_Nodes (Tree.Child (Node, 2));
-         end if;
-
-         Tree.Set_Node_Identifier (Node, +IDENTIFIER_ID, New_Ident);
-         Copy_Non_Grammar (Right_Paren_Node, Node);
-         Tree.Set_Children (Tree.Parent (Node), (+rhs_item_ID, 0), (1 => 
Node));
-         Clear_EBNF_Node (Node);
-      end Translate_RHS_Group_Item;
-
-      procedure Translate_RHS_Multiple_Item (Node : in Valid_Node_Index)
-      is
-         --  We have one of:
-         --
-         --  | a { b }  c
-         --  | a { b } - c
-         --  | a ( b ) + c
-         --  | a ( b ) * c
-         --  | a b+ c
-         --  | a b* c
-         --
-         --  where a and/or c can be empty. Replace it with a new canonical
-         --  list nonterminal:
-         --
-         --  nonterminal_nnn_list
-         --  : b
-         --  | nonterminal_nnn_list b
-         --
-         --  and a second RHS if it can be empty:
-         --  | a c
-
-         --  Current tree:
-         --
-         --  rhs_element : Parent (Node, 2)
-         --  | rhs_item: Parent (Node, 1)
-         --  | | rhs_multiple_item: Node
-         --  | | | LEFT_BRACE | LEFT_PAREN
-         --  | | | rhs_alternative_list
-         --  | | | ...
-         --  | | | RIGHT_BRACE | RIGHT_PAREN
-         --  | | | [MINUS | PLUS | STAR]
-
-         --  or:
-         --
-         --  rhs_element : Parent (Node, 2)
-         --  | rhs_item: Parent (Node, 1)
-         --  | | rhs_multiple_item: Node
-         --  | | | IDENTIFIER
-         --  | | | PLUS | STAR
-
-         Done                       : Boolean                   := False;
-         Parent_RHS_Item            : constant Valid_Node_Index := Tree.Parent 
(Node);
-         List_Nonterm_Virtual_Name  : Base_Identifier_Index     := 
Invalid_Identifier_Index;
-         List_Nonterm_Terminal_Name : Base_Token_Index          := 
Invalid_Token_Index;
-
-         procedure Check_Canonical_List
-         is
-            --  In EBNF, a canonical list with a separator looks like:
-            --
-            --  enumConstants : enumConstant (',' enumConstant)* ;
-            --
-            --  or, with no separator:
-            --
-            --  SwitchLabels : SwitchLabel {SwitchLabel} ;
-            --
-            --  where Node is the rhs_multiple_item containing "(','
-            --  enumConstant)*" or "{SwitchLabel}".
-            --
-            --  The tokens may have labels.
-            --
-            --  Handling these cases specially eliminates a conflict between
-            --  reducing to enumConstants and reducing to the introduced 
nonterm
-            --  list.
-            --
-            --  Alternately, the no separator case can be:
-            --
-            --  enumConstants : enumConstant+ ;
-            --
-            --  Handling this no separator case specially would not eliminate 
any conflicts.
-
-            use Syntax_Trees.LR_Utils;
-            use Syntax_Trees.LR_Utils.Creators;
-            use all type Ada.Containers.Count_Type;
-
-            List_Name_Node : constant Valid_Node_Index := Tree.Find_Ancestor 
(Node, +nonterminal_ID);
-            RHS_List_Root  : constant Valid_Node_Index := Tree.Child 
(List_Name_Node, 3);
-
-            RHS_2 : constant Valid_Node_Index := Tree.Find_Ancestor
-              (Node, (+rhs_ID, +rhs_alternative_list_ID));
-            --  If rhs_ID, the RHS containing the canonical list candidate.
-            --  If rhs_alternative_list_ID, not useful (FIXME: actually a 
canonical list candidate)
-
-            RHS_2_Item_List_List : constant Constant_List :=
-              (if Tree.ID (RHS_2) = +rhs_ID
-               then Create_List (Tree, Tree.Child (RHS_2, 1), 
+rhs_item_list_ID, +rhs_element_ID)
-               else Invalid_List (Tree));
-
-            Alt_List_List : constant Constant_List :=
-              (case Tree.RHS_Index (Node) is
-               when 0 | 3 =>
-                  Create_List (Tree, Tree.Child (Node, 2), 
+rhs_alternative_list_ID, +rhs_item_list_ID),
-               when others => Invalid_List (Tree));
-            --  Iterator on the rhs_alternative_list of the rhs_multiple_item.
-
-            Alt_List_Item_List : constant Constant_List :=
-              (if Alt_List_List.Is_Invalid
-               then Invalid_List (Tree)
-               else Create_List (Tree, Get_Node (Alt_List_List.First), 
+rhs_item_list_ID, +rhs_element_ID));
-            --  Iterator on the content of the rhs_multiple_item. Note that we
-            --  don't support a non-empty multiple_item; a canonical list can 
be
-            --  empty.
-
-            RHS_2_Item_List_Iter : constant Constant_Iterator := 
RHS_2_Item_List_List.Iterate_Constant;
-
-            Element_2 : constant Cursor :=
-              (if Is_Invalid (RHS_2_Item_List_List)
-               then No_Element
-               else RHS_2_Item_List_List.To_Cursor (Tree.Parent (Node, 2)));
-            --  The rhs_element containing the rhs_multiple_item
-
-            Element_1 : constant Node_Index :=
-              (if Is_Invalid (RHS_2_Item_List_List)
-               then Invalid_Node_Index
-               else Get_Node (RHS_2_Item_List_Iter.Previous (Element_2)));
-            --  The list element
-         begin
-            if Tree.ID (RHS_2) = +rhs_alternative_list_ID or else
-              Create_List (Tree, RHS_List_Root, +rhs_list_ID, +rhs_ID).Count 
/= 1
-            then
-               --  Something else going on
-               return;
-            end if;
-            pragma Assert (Tree.ID (RHS_2) = +rhs_ID);
-
-            if RHS_2_Item_List_List.Count = 2 and then
-              (Tree.RHS_Index (Node) in 4 .. 5 or else
-                 Alt_List_Item_List.Count in 1 .. 2)
-            then
-               null;
-            else
-               return;
-            end if;
-
-            if Element_1 = Invalid_Node_Index or else
-              Get_Text (Data, Tree, Tree.Find_Descendant (Element_1, 
+rhs_item_ID)) /=
-              Get_Text (Data, Tree, Tree.Find_Descendant (Get_Node 
(Alt_List_Item_List.Last), +rhs_item_ID))
-            then
-               return;
-            end if;
-
-            if Trace_Generate_EBNF > Detail then
-               Ada.Text_IO.Put_Line ("canonical list");
-            end if;
-
-            --  We have a canonical list declaration. Rewrite it to:
-            --
-            --  with separator:
-            --  rhs_list: keep
-            --  | rhs_list:
-            --  | | rhs: new, RHS_1
-            --  | | | rhs_item_list: new, RHS_Item_List_1
-            --  | | | | rhs_element: keep, Element_1
-            --  | | | | | rhs_item: keep
-            --  | | | | | | IDENTIFIER: keep; element name
-            --  | BAR: new
-            --  | rhs: keep, RHS_2
-            --  | | rhs_item_list: new, RHS_Item_List_2
-            --  | | | rhs_item_list: keep, rhs_item_list_3
-            --  | | | | rhs_item_list: keep, rhs_item_list_4
-            --  | | | | | rhs_element: new
-            --  | | | | | | rhs_item: new
-            --  | | | | | | | IDENTIFIER: new, list name
-            --  | | | | rhs_element: keep
-            --  | | | | | rhs_item: keep
-            --  | | | | | | IDENTIFIER: keep, separator
-            --  | | | rhs_element: keep, alt_list_elements (last)
-            --  | | | | rhs_item: keep
-            --  | | | | | IDENTIFIER: keep, element name
-            --
-            --  no separator:
-            --  rhs_list: keep
-            --  | rhs_list:
-            --  | | rhs: new, RHS_1
-            --  | | | rhs_item_list: new, RHS_Item_List_1
-            --  | | | | rhs_element: keep, Element_1
-            --  | | | | | rhs_item: keep
-            --  | | | | | | IDENTIFIER: keep; element name
-            --  | BAR: new
-            --  | rhs: keep, RHS_2
-            --  | | rhs_item_list: keep, rhs_item_list_3
-            --  | | | rhs_item_list: new, rhs_item_list_4
-            --  | | | | rhs_element: new
-            --  | | | | | rhs_item: new
-            --  | | | | | | IDENTIFIER: new, list name
-            --  | | | rhs_element: keep, alt_list_elements (last)
-            --  | | | | rhs_item: keep
-            --  | | | | | IDENTIFIER: keep, element name
-
-            declare
-               List_Name_Tok    : constant Token_Index      := 
Tree.First_Shared_Terminal (List_Name_Node);
-               List_Name_Region : constant Buffer_Region    := 
Data.Terminals.all (List_Name_Tok).Byte_Region;
-               List_Name        : constant String           := 
Data.Grammar_Lexer.Buffer_Text (List_Name_Region);
-
-               RHS_2_Index    : constant Integer       := Tree.RHS_Index 
(RHS_2);
-               RHS_2_Children : Valid_Node_Index_Array := Tree.Children 
(RHS_2);
-
-               RHS_1_Item_List    : constant Valid_Node_Index := 
Tree.Add_Nonterm
-                 ((+rhs_item_list_ID, 0), (1 => Element_1));
-
-               RHS_1_Action : constant Node_Index :=
-                 (case RHS_2_Index is
-                  when 2 | 3 => Tree.Add_Terminal
-                    (Tree.First_Shared_Terminal (RHS_2_Children (2)), 
Data.Terminals.all),
-                  when others => Invalid_Node_Index);
-
-               RHS_1_Check : constant Node_Index :=
-                 (case RHS_2_Index is
-                  when 3 => Tree.Add_Terminal
-                    (Tree.First_Shared_Terminal (RHS_2_Children (3)), 
Data.Terminals.all),
-                  when others => Invalid_Node_Index);
-
-               RHS_1              : constant Valid_Node_Index :=
-                 (case RHS_2_Index is
-                  when 1 => Tree.Add_Nonterm ((+rhs_ID, 1), (1 => 
RHS_1_Item_List)),
-                  when 2 => Tree.Add_Nonterm ((+rhs_ID, 2), (1 => 
RHS_1_Item_List, 2 => RHS_1_Action)),
-                  when 3 => Tree.Add_Nonterm
-                    ((+rhs_ID, 3), (1 => RHS_1_Item_List, 2 => RHS_1_Action, 3 
=> RHS_1_Check)),
-                  when others => raise SAL.Programmer_Error);
-
-               Bar                   : constant Valid_Node_Index := 
Tree.Add_Terminal (+BAR_ID);
-               RHS_Item_List_3       : constant Valid_Node_Index := Tree.Child 
(RHS_2, 1);
-               RHS_Item_List_4       : constant Valid_Node_Index := Tree.Child 
(RHS_Item_List_3, 1);
-               New_List_Name_Term    : constant Valid_Node_Index := 
Tree.Add_Terminal
-                 (List_Name_Tok, Data.Terminals.all);
-               New_List_Name_Item    : constant Valid_Node_Index := 
Tree.Add_Nonterm
-                 ((+rhs_item_ID, 0),
-                  (1      => New_List_Name_Term));
-
-               New_List_Name_Label : constant Node_Index :=
-                 (if Tree.RHS_Index (Element_1) = 1
-                  then --  tokens have labels
-                     Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier 
(List_Name), List_Name_Region)
-                  else Invalid_Node_Index);
-
-               New_List_Name_Element : constant Valid_Node_Index :=
-                 (if Tree.RHS_Index (Element_1) = 1
-                  then --  tokens have labels
-                     Tree.Add_Nonterm
-                       ((+rhs_element_ID, 1),
-                        (1 => New_List_Name_Label,
-                         2 => Tree.Add_Terminal (+EQUAL_ID),
-                         3 => New_List_Name_Item))
-                  else
-                     Tree.Add_Nonterm ((+rhs_element_ID, 0), (1 => 
New_List_Name_Item)));
-
-               Alt_List_Elements : constant Valid_Node_Index_Array := 
Tree.Get_IDs (Node, +rhs_element_ID);
-               RHS_Item_List_2   : constant Node_Index       :=
-                 (if Alt_List_Elements'Last = 1
-                  then Invalid_Node_Index -- no separator
-                  else Tree.Add_Nonterm
-                    ((+rhs_item_list_ID, 1),
-                     (1 => RHS_Item_List_3,
-                      2 => Alt_List_Elements (Alt_List_Elements'Last))));
-
-            begin
-               Tree.Set_Children (RHS_Item_List_4, (+rhs_item_list_ID, 0), (1 
=> New_List_Name_Element));
-
-               Tree.Set_Children
-                 (RHS_Item_List_3,
-                  (+rhs_item_list_ID, 1),
-                  (1 => RHS_Item_List_4,
-                   2 => Alt_List_Elements (1)));
-
-               RHS_2_Children (1) :=
-                 (if Alt_List_Elements'Last = 1
-                  then RHS_Item_List_3 -- no separator
-                  else RHS_Item_List_2);
-               Tree.Set_Children (RHS_2, (+rhs_ID, Tree.RHS_Index (RHS_2)), 
RHS_2_Children);
-
-               Tree.Set_Children
-                 (Tree.Parent (RHS_2),
-                  (+rhs_list_ID, 1),
-                  (1 => Tree.Add_Nonterm ((+rhs_list_ID, 0), (1 => RHS_1)),
-                   2 => Bar,
-                   3 => RHS_2));
-            end;
-
-            Done := True;
-
-            Clear_EBNF_Node (Node);
-
-            if Trace_Generate_EBNF > Extra then
-               Ada.Text_IO.New_Line;
-               Ada.Text_IO.Put_Line ("Check_Canonical_List edited rhs_list:");
-               Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor, 
Tree.Parent (RHS_2));
-            end if;
-         end Check_Canonical_List;
-
-         procedure Find_List_Nonterminal_1 (Element_Content : in String)
-         is
-            --  Search for a nonterm (virtual or not) implementing a list for
-            --  Element_Content, which is a single rhs_element; no List_Element
-            --  Nonterminal. If found, set List_Nonterm_Virtual_Name or
-            --  List_Nonterm_Terminal_Name
-            use Syntax_Trees.LR_Utils;
-
-            List : constant Constant_List := Creators.Create_List
-              (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID);
-         begin
-            for N of List loop
-
-               if Tree.Production_ID (Tree.Child (N, 1)) = (+nonterminal_ID, 
0) then
-                  --  Target List_Nonterm is:
-                  --
-                  --  nonterminal_nnn_list
-                  --     : element
-                  --     | nonterminal_nnn_list element
-                  --
-                  --  compilation_unit
-                  --  | nonterminal
-                  --  | | IDENTIFIER : list_nonterm
-                  --  | | COLON
-                  --  | | rhs_list: rhs_list_1
-                  --  | | | rhs_list: rhs_list_2
-                  --  | | | | rhs
-                  --  | | | | | ... List_element
-                  --  | | | BAR
-                  --  | | | rhs: ... list_nonterm list_element
-                  declare
-                     Name_Node  : constant Node_Index := Tree.Child 
(Tree.Child (N, 1), 1);
-                     RHS_List_1 : constant Node_Index := Tree.Child 
(Tree.Child (N, 1), 3);
-                     RHS_List_2 : constant Node_Index :=
-                       (if RHS_List_1 = Invalid_Node_Index
-                        then Invalid_Node_Index
-                        else Tree.Child (RHS_List_1, 1));
-                  begin
-                     if RHS_List_2 /= Invalid_Node_Index and
-                       Tree.Child (RHS_List_1, 3) /= Invalid_Node_Index and -- 
second rhs present
-                       Tree.Child (RHS_List_2, 3) = Invalid_Node_Index -- no 
third rhs
-                     then
-                        declare
-                           RHS_1 : constant String := Get_Text (Data, Tree, 
RHS_List_2);
-                           RHS_2 : constant String := Get_Text (Data, Tree, 
Tree.Child (RHS_List_1, 3));
-                           Expected_RHS_2 : constant String := Get_Text (Data, 
Tree, Name_Node) & " " &
-                             Element_Content;
-                        begin
-                           if Element_Content = RHS_1 and RHS_2 = 
Expected_RHS_2 then
-                              case Tree.Label (Name_Node) is
-                              when Shared_Terminal =>
-                                 List_Nonterm_Terminal_Name := 
Tree.First_Shared_Terminal (Name_Node);
-                              when Virtual_Identifier =>
-                                 List_Nonterm_Virtual_Name := Tree.Identifier 
(Name_Node);
-                              when others =>
-                                 Raise_Programmer_Error
-                                   ("unimplemented Find_List_Nonterminal_1 
case '" & Element_Content & "'",
-                                    Data, Tree, Name_Node);
-                              end case;
-
-                              exit;
-                           end if;
-                        end;
-                     end if;
-                  end;
-               end if;
-            end loop;
-         end Find_List_Nonterminal_1;
-
-         procedure Find_List_Nonterminal_2 (Element_Content : in String)
-         is
-            --  Look for a pair of nonterms implementing a list of 
Element_Content.
-            --  If found, set List_Nonterm_*_Name
-            use Syntax_Trees.LR_Utils;
-
-            List : constant Constant_List := Creators.Create_List
-              (Tree, Tree.Child (Tree.Root, 1), +compilation_unit_list_ID, 
+compilation_unit_ID);
-         begin
-            for Comp_Unit of List loop
-               declare
-                  Nonterm : constant Valid_Node_Index := Tree.Child 
(Comp_Unit, 1);
-               begin
-                  if Tree.Production_ID (Nonterm) = (+nonterminal_ID, 0) and 
then
-                    Element_Content = Get_Text (Data, Tree, Tree.Child 
(Nonterm, 3))
-                  then
-                     Find_List_Nonterminal_1 (Get_Text (Data, Tree, Tree.Child 
(Nonterm, 1)));
-                     exit;
-                  end if;
-               end;
-            end loop;
-         end Find_List_Nonterminal_2;
-
-         Container_List_Root : Node_Index := Invalid_Node_Index;
-      begin
-         --  Check if this is a recognized pattern
-         Check_Canonical_List;
-         if Done then return; end if;
-
-         --  Check to see if there is an already declared nonterminal
-         --  list with the same content; if not, create one.
-         case Tree.RHS_Index (Node) is
-         when 0 .. 3 =>
-            --  0: { rhs_alternative_list }
-            --  1: { rhs_alternative_list } -
-            --  2: ( rhs_alternative_list ) +
-            --  3: ( rhs_alternative_list ) *
-
-            if Tree.RHS_Index (Node) in 0 | 3 then
-               Container_List_Root := Insert_Optional_RHS (Node);
-            end if;
-
-            if 0 = Tree.RHS_Index (Tree.Child (Node, 2)) and then
-              0 = Tree.RHS_Index (Tree.Child (Tree.Child (Node, 2), 1))
-            then
-               --  Only one element in the rhs_alternative_list, and in the 
rhs_item_list
-               Find_List_Nonterminal_1 (Get_Text (Data, Tree, Tree.Child 
(Node, 2)));
-
-               if List_Nonterm_Virtual_Name = Invalid_Identifier_Index and
-                 List_Nonterm_Terminal_Name = Invalid_Token_Index
-               then
-                  List_Nonterm_Virtual_Name := Next_Nonterm_Name ("_list");
-                  New_Nonterminal_List
-                    (List_Nonterm_Virtual_Name, Tree.First_Shared_Terminal 
(Tree.Child (Node, 2)),
-                     Data.Terminals.all, Tree.Byte_Region (Node));
-               else
-                  Erase_Deleted_EBNF_Nodes (Tree.Child (Node, 2));
-               end if;
-            else
-               Find_List_Nonterminal_2 (Get_Text (Data, Tree, Tree.Child 
(Node, 2)));
-
-               if List_Nonterm_Virtual_Name = Invalid_Identifier_Index then
-                  List_Nonterm_Virtual_Name := Next_Nonterm_Name ("_list");
-                  declare
-                     List_Element_Virtual_Name : constant Identifier_Index := 
Next_Nonterm_Name;
-                  begin
-                     New_Nonterminal ("canonical list element", 
List_Element_Virtual_Name, Tree.Child (Node, 2));
-                     New_Nonterminal_List
-                       (List_Nonterm_Virtual_Name, List_Element_Virtual_Name, 
Tree.Byte_Region (Node));
-                  end;
-               else
-                  Erase_Deleted_EBNF_Nodes (Tree.Child (Node, 2));
-               end if;
-            end if;
-
-         when 4 | 5 =>
-            --  IDENTIFIER + | *
-            Find_List_Nonterminal_1 (Get_Text (Data, Tree, Tree.Child (Node, 
1)));
-
-            if List_Nonterm_Virtual_Name = Invalid_Identifier_Index then
-               List_Nonterm_Virtual_Name := Next_Nonterm_Name ("_list");
-
-               New_Nonterminal_List
-                 (List_Nonterm_Virtual_Name,
-                  Tree.First_Shared_Terminal (Tree.Child (Node, 1)), 
Data.Terminals.all,
-                  Tree.Byte_Region (Node));
-            else
-               --  nothing to erase
-               null;
-            end if;
-
-            if Tree.RHS_Index (Node) = 5 then
-               Container_List_Root := Insert_Optional_RHS (Node);
-            end if;
-
-         when others =>
-            Raise_Programmer_Error ("Translate_RHS_Multiple_Item 
unimplemented", Data, Tree, Node);
-         end case;
-
-         --  Edit rhs_item to use list name
-         declare
-            Child : constant Valid_Node_Index :=
-              (if List_Nonterm_Virtual_Name /= Invalid_Identifier_Index
-               then Tree.Add_Identifier
-                 (+IDENTIFIER_ID, List_Nonterm_Virtual_Name, Tree.Byte_Region 
(Parent_RHS_Item))
-               elsif List_Nonterm_Terminal_Name /= Invalid_Token_Index
-               then Tree.Add_Terminal (List_Nonterm_Terminal_Name, 
Data.Terminals.all)
-               else raise SAL.Programmer_Error);
-         begin
-            Tree.Set_Children (Parent_RHS_Item, (+rhs_item_ID, 0), (1 => 
Child));
-         end;
-
-         Clear_EBNF_Node (Node);
-
-         if Trace_Generate_EBNF > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Translate_RHS_Multiple_Item edited:");
-            Tree.Print_Tree
-              (Wisitoken_Grammar_Actions.Descriptor,
-               (if Container_List_Root = Invalid_Node_Index
-                then Parent_RHS_Item
-                else Container_List_Root));
-         end if;
-      end Translate_RHS_Multiple_Item;
-
-      procedure Translate_RHS_Optional_Item (B : in Valid_Node_Index)
-      is
-         --  Source looks like:
-         --
-         --  | A [B] C
-         --
-         --  where A, B, C are token sequences. All are contained in one
-         --  rhs_item_list, which may be contained in an rhs or an
-         --  rhs_alternative_list. B contains an rhs_alternative_list.
-         --
-         --  First add a second rhs_item_list without B:
-         --  | A C
-         --
-         --  then for each alternative in B, splice together rhs_item_lists A,
-         --  B_i, C, copying A, C on all after the first:
-         --  | A B_i C
-         --
-         --  See nested_ebnf_optional.wy for an example of nested optional
-         --  items.
-         --
-         --  We don't create a separate nonterminal for B, so token labels stay
-         --  in the same RHS for actions.
-         --
-         --  current tree:
-         --
-         --  rhs_list:
-         --  | rhs | rhs_alternative_list:
-         --  | | rhs_item_list
-         --  | | | rhs_item_list
-         --  | | ...
-         --  | | | | | rhs_element: a.last
-         --  | | | | | | rhs_item:
-         --  | | | | rhs_element:
-         --  | | | | | rhs_item: contains b
-         --  | | | | | | rhs_optional_item: B
-         --  | | | | | | | LEFT_BRACKET: B.Children (1)
-         --  | | | | | | | rhs_alternative_list: B.Children (2) b
-         --  | | | | | | | RIGHT_BRACKET: B.Children (3)
-         --  | | | rhs_element: c.first
-         --  | | | | rhs_item:
-
-         use Syntax_Trees.LR_Utils;
-         use Syntax_Trees.LR_Utils.Creators;
-
-         Container_List_Root : constant Valid_Node_Index := 
Insert_Optional_RHS (B);
-      begin
-         if Trace_Generate_EBNF > Extra then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Translate_RHS_Optional_Item start");
-         end if;
-
-         case Tree.RHS_Index (B) is
-         when 0 | 1 =>
-            --  : LEFT_BRACKET rhs_alternative_list RIGHT_BRACKET
-            --  | LEFT_PAREN rhs_alternative_list RIGHT_PAREN QUESTION
-
-            declare
-               Container_List : Syntax_Trees.LR_Utils.List :=
-                 (if Tree.ID (Container_List_Root) = +rhs_list_ID
-                  then Create_List
-                    (Tree,
-                     Root         => Container_List_Root,
-                     List_ID      => +rhs_list_ID,
-                     Element_ID   => +rhs_ID,
-                     Separator_ID => +BAR_ID)
-                  else Create_List
-                    (Tree,
-                     Root         => Container_List_Root,
-                     List_ID      => +rhs_alternative_list_ID,
-                     Element_ID   => +rhs_item_list_ID,
-                     Separator_ID => +BAR_ID));
-
-               Container_Cur : Cursor := Container_List.Find
-                 (if Container_List.Element_ID = +rhs_ID
-                  then Tree.Find_Ancestor (B, +rhs_ID)
-                  else List_Root (Tree, Tree.Find_Ancestor (B, 
+rhs_item_list_ID), +rhs_item_list_ID));
-
-               ABC_List : List := Create_From_Element
-                 (Tree, Tree.Parent (B, 2),
-                  List_ID      => +rhs_item_list_ID,
-                  Element_ID   => +rhs_element_ID,
-                  Separator_ID => Invalid_Token_ID);
-
-               ABC_Iter : constant Iterator := ABC_List.Iterate;
-
-               ABC_B_Cur   : constant Cursor := ABC_List.To_Cursor 
(Tree.Parent (B, 2));
-               ABC_A_Last  : constant Cursor := ABC_Iter.Previous (ABC_B_Cur);
-               ABC_C_First : constant Cursor := ABC_Iter.Next (ABC_B_Cur);
-
-               B_Alternative_List : constant Constant_List := Create_List
-                 (Tree, Tree.Child (B, 2), +rhs_alternative_list_ID, 
+rhs_item_list_ID);
-
-            begin
-               --  An alternate design would be to splice together the 
existing A,
-               --  B_i, C; but it's too hard to get all the parent updates 
right.
-               for Alt of reverse B_Alternative_List loop
-
-                  declare
-                     B_Item_List : constant Constant_List := Create_List
-                       (Tree, Alt, +rhs_item_list_ID, +rhs_element_ID);
-
-                     New_ABC : List := Empty_List (ABC_List);
-                  begin
-                     if Has_Element (ABC_A_Last) then
-                        Copy (Source_List => ABC_List,
-                              Source_Last => ABC_A_Last,
-                              Dest_List   => New_ABC);
-                     end if;
-
-                     Copy (B_Item_List, Dest_List => New_ABC);
-
-                     if Has_Element (ABC_C_First) then
-                        Copy (ABC_List, Source_First => ABC_C_First, Dest_List 
=> New_ABC);
-                     end if;
-
-                     if Container_List.Element_ID = +rhs_ID then
-                        Insert_RHS (Container_List, New_ABC.Root, After => 
Get_Node (Container_Cur));
-                     else
-                        Container_List.Insert (New_ABC.Root, After => 
Container_Cur);
-                     end if;
-
-                     Record_Copied_EBNF_Nodes (New_ABC.Root);
-                  end;
-               end loop;
-
-               Erase_Deleted_EBNF_Nodes (Get_Node (Container_Cur));
-               --  This includes B, so we don't do 'Clear_EBNF_Node (B)'.
-
-               Container_List.Delete (Container_Cur);
-            end;
-
-         when 2 =>
-            --  | IDENTIFIER QUESTION
-            --
-            --  Current tree:
-            --   rhs_item_3
-            --   | rhs_optional_item_2: B
-            --   | | IDENTIFIER
-            --   | | QUESTION
-            --
-            --  Change to:
-            --   rhs_item_0
-            --   | IDENTIFIER
-
-            Tree.Set_Children (Tree.Parent (B), (+rhs_item_ID, 0), (1 => 
Tree.Child (B, 1)));
-            Clear_EBNF_Node (B);
-
-         when 3 =>
-            --  | STRING_LITERAL_2 QUESTION
-            Tree.Set_Children (Tree.Parent (B), (+rhs_item_ID, 1), (1 => 
Tree.Child (B, 1)));
-            Clear_EBNF_Node (B);
-
-         when others =>
-            Raise_Programmer_Error ("translate_ebnf_to_bnf rhs_optional_item 
unimplemented", Data, Tree, B);
-         end case;
-
-         if WisiToken.Trace_Generate_EBNF > Detail then
-            Ada.Text_IO.New_Line;
-            Ada.Text_IO.Put_Line ("Translate_RHS_Optional_Item edited:");
-            Tree.Print_Tree (Wisitoken_Grammar_Actions.Descriptor, 
Container_List_Root);
-         end if;
-      end Translate_RHS_Optional_Item;
-
-      procedure Translate_Token_Literal (Node : in Valid_Node_Index)
-      is
-         use Syntax_Trees.LR_Utils;
-
-         Name_Ident : Identifier_Index;
-
-         function Equal
-           (Target : in String;
-            List   : in Constant_List'Class;
-            N      : in Valid_Node_Index)
-           return Boolean
-         is
-            pragma Unreferenced (List);
-         begin
-            if Tree.Production_ID (Tree.Child (N, 1)) = (+declaration_ID, 0) 
then
-               declare
-                  Decl       : constant Node_Index       := Tree.Child (N, 1);
-                  Value_Node : constant Valid_Node_Index := Tree.Child 
(Tree.Child (Decl, 4), 1);
-               begin
-                  if Tree.ID (Value_Node) = +declaration_item_ID and then
-                    Tree.ID (Tree.Child (Value_Node, 1)) in
-                    +IDENTIFIER_ID | +STRING_LITERAL_1_ID | 
+STRING_LITERAL_2_ID and then
-                    Target = Get_Text (Data, Tree, Tree.Child (Value_Node, 1), 
Strip_Quotes => True)
-                  then
-                     case Tree.Label (Tree.Child (Decl, 3)) is
-                     when Shared_Terminal =>
-                        Name_Ident := New_Identifier (Get_Text (Data, Tree, 
Tree.Child (Decl, 3)));
-                     when Virtual_Identifier =>
-                        Name_Ident := Tree.Identifier (Tree.Child (Decl, 3));
-                     when others =>
-                        raise SAL.Programmer_Error;
-                     end case;
-                     return True;
-                  else
-                     return False;
-                  end if;
-               end;
-            else
-               return False;
-            end if;
-         end Equal;
-
-         Value : constant String     := Get_Text (Data, Tree, Node, 
Strip_Quotes => True);
-         Found : constant Node_Index := Find_Nonterminal (Value, 
Equal'Unrestricted_Access);
-      begin
-         if Found = Invalid_Node_Index then
-            if GNAT.Regexp.Match (Value, Symbol_Regexp) then
-               Name_Ident := New_Identifier (Ada.Characters.Handling.To_Upper 
(Value));
-            else
-               Put_Error
-                 (Error_Message
-                    (Data.Grammar_Lexer.File_Name, Get_Line (Data, Tree, Node),
-                     "punctuation token '" & Value & "' not declared"));
-               return;
-            end if;
-         end if;
-
-         --  Replace string literal in rhs_item
-         declare
-            Parent : constant Valid_Node_Index := Tree.Parent (Node);
-         begin
-            case To_Token_Enum (Tree.ID (Parent)) is
-            when rhs_item_ID =>
-               Tree.Set_Children
-                 (Tree.Parent (Node),
-                  (+rhs_item_ID, 0),
-                  (1 => Tree.Add_Identifier (+IDENTIFIER_ID, Name_Ident, 
Tree.Byte_Region (Node))));
-
-            when rhs_optional_item_ID =>
-               Tree.Set_Children
-                 (Tree.Parent (Node),
-                  (+rhs_optional_item_ID, 2),
-                  (Tree.Add_Identifier (+IDENTIFIER_ID, Name_Ident, 
Tree.Byte_Region (Node)),
-                   Tree.Child (Tree.Parent (Node), 2)));
-
-            when others =>
-               Raise_Programmer_Error ("translate_ebnf_to_bnf string_literal_2 
unimplemented", Data, Tree, Node);
-            end case;
-         end;
-
-         Clear_EBNF_Node (Node);
-         if Found /= Invalid_Node_Index then
-            return;
-         end if;
-
-         --  Declare token for keyword string literal
-         declare
-            Keyword        : constant Valid_Node_Index := Tree.Add_Identifier
-              (+KEYWORD_ID, Keyword_Ident, Tree.Byte_Region (Node));
-            Kind           : constant Valid_Node_Index := Tree.Add_Nonterm
-              ((+token_keyword_non_grammar_ID, 0),
-               (1 => Keyword));
-            Value_Literal  : constant Valid_Node_Index := Tree.Add_Identifier
-              (+STRING_LITERAL_1_ID, New_Identifier ('"' & Value & '"'), 
Tree.Byte_Region (Node));
-            Decl_Item      : constant Valid_Node_Index := Tree.Add_Nonterm
-              ((+declaration_item_ID, 1),
-               (1 => Value_Literal));
-            Decl_Item_List : constant Valid_Node_Index := Tree.Add_Nonterm
-              ((+declaration_item_list_ID, 0),
-               (1 => Decl_Item));
-
-            Percent : constant Valid_Node_Index := Tree.Add_Identifier
-              (+PERCENT_ID, Percent_Ident, Tree.Byte_Region (Node));
-            Name    : constant Valid_Node_Index := Tree.Add_Identifier
-              (+IDENTIFIER_ID, Name_Ident, Tree.Byte_Region (Node));
-            Decl    : constant Valid_Node_Index := Tree.Add_Nonterm
-              ((+declaration_ID, 0), (Percent, Kind, Name, Decl_Item_List), 
Action => declaration_0'Access);
-         begin
-            Add_Compilation_Unit ("literal token", Decl, Prepend => True);
-         end;
-
-      end Translate_Token_Literal;
-
-      procedure Process_Node (Node : in Valid_Node_Index)
-      is begin
-         case To_Token_Enum (Tree.ID (Node)) is
-         --  Token_Enum_ID alphabetical order
-         when declaration_ID =>
-            --  Must be "%meta_syntax EBNF"; change to BNF
-            declare
-               Decl_Item    : constant Valid_Node_Index       := 
Tree.Find_Descendant
-                 (Tree.Child (Node, 3), +declaration_item_ID);
-               Old_Children : constant Valid_Node_Index_Array := Tree.Children 
(Decl_Item);
-               New_Children : constant Valid_Node_Index_Array :=
-                 (1 => Tree.Add_Identifier
-                    (+IDENTIFIER_ID, New_Identifier ("BNF"), Tree.Byte_Region 
(Decl_Item)));
-            begin
-               Copy_Non_Grammar (Old_Children (1), New_Children (1));
-               Tree.Set_Children (Decl_Item, (+declaration_item_ID, 1), 
New_Children);
-            end;
-            Clear_EBNF_Node (Node);
-
-         when rhs_alternative_list_ID =>
-            --  All handled by New_Nonterminal*
-            raise SAL.Programmer_Error;
-
-         when rhs_attribute_ID =>
-            --  Just delete it
-            declare
-               use WisiToken.Syntax_Trees.LR_Utils;
-               RHS_Item_List : List := Creators.Create_From_Element
-                 (Tree, Tree.Parent (Node, 2), +rhs_item_list_ID, 
+rhs_element_ID, Invalid_Token_ID);
-               Element : Cursor := RHS_Item_List.To_Cursor (Tree.Parent (Node, 
2));
-            begin
-               RHS_Item_List.Delete (Element);
-            end;
-            Clear_EBNF_Node (Node);
-
-         when rhs_group_item_ID =>
-            Translate_RHS_Group_Item (Node);
-
-         when rhs_multiple_item_ID =>
-            Translate_RHS_Multiple_Item (Node);
-
-         when rhs_optional_item_ID =>
-            Translate_RHS_Optional_Item (Node);
-
-         when STRING_LITERAL_2_ID =>
-            Translate_Token_Literal (Node);
-
-         when others =>
-            Raise_Programmer_Error ("unimplemented EBNF node", Data, Tree, 
Node);
-         end case;
-      exception
-      when SAL.Programmer_Error =>
-         raise;
-      when E : others =>
-         Raise_Programmer_Error
-           ("unhandled exception " & Ada.Exceptions.Exception_Name (E) & ": " &
-              Ada.Exceptions.Exception_Message (E),
-            Data, Tree, Node);
-      end Process_Node;
-
-      EBNF_Allowed : Boolean := True;
-
-      procedure Validate_Node
-        (Tree              : in     Syntax_Trees.Tree;
-         Node              : in     Valid_Node_Index;
-         Node_Image_Output : in out Boolean)
-      is
-         use Ada.Text_IO;
-
-         procedure Put_Error (Msg : in String)
-         is begin
-            if not Node_Image_Output then
-               Node_Image_Output := True;
-               Put_Line
-                 (Current_Error,
-                  Error_Message
-                    (Tree, Data.Terminals, Node, Data.Grammar_Lexer.File_Name,
-                     Tree.Image
-                       (Node, Wisitoken_Grammar_Actions.Descriptor,
-                        Include_RHS_Index => True,
-                        Include_Children  => Trace_Generate_EBNF > Detail,
-                        Node_Numbers      => True)));
-            end if;
-            Put_Line (Current_Error, "... " & Msg);
-            WisiToken.Generate.Error := True;
-         end Put_Error;
-
-         procedure Check_EBNF_Allowed
-         is begin
-            if not EBNF_Allowed then
-               Put_Error ("no EBNF allowed");
-            end if;
-         end Check_EBNF_Allowed;
-
-      begin
-         if Tree.Label (Node) /= Nonterm then
-            return;
-         end if;
-
-         declare
-            use all type Ada.Containers.Count_Type;
-            Children  : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            RHS_Index : constant Natural                := Tree.RHS_Index 
(Node);
-         begin
-            case To_Token_Enum (Tree.ID (Node)) is
-            when nonterminal_ID =>
-               null;
-
-            when rhs_list_ID =>
-               case RHS_Index is
-               when 0 =>
-                  if Children'Length /= 1 then
-                     Put_Error ("expected child_count 1");
-                  elsif Tree.ID (Children (1)) /= +rhs_ID then
-                     Put_Error ("child 1 not rhs");
-                  end if;
-
-               when 1 =>
-                  if Tree.Child_Count (Node) /= 3 then
-                     Put_Error ("expected child_count 3");
-                  elsif Tree.ID (Children (1)) /= +rhs_list_ID or
-                    Tree.ID (Children (2)) /= +BAR_ID or
-                    Tree.ID (Children (3)) /= +rhs_ID
-                  then
-                     Put_Error ("expecting rhs_list BAR rhs");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_ID =>
-               case RHS_Index is
-               when 0 =>
-                  if Children'Length /= 0 then
-                     Put_Error ("expected child_count 0");
-                  end if;
-
-               when 1 =>
-                  if Tree.Child_Count (Node) /= 1 then
-                     Put_Error ("expected child_count 1");
-                  elsif Tree.ID (Children (1)) /= +rhs_item_list_ID then
-                     Put_Error ("expecting rhs_item_list");
-                  end if;
-
-               when 2 =>
-                  if Tree.Child_Count (Node) /= 2 then
-                     Put_Error ("expected child_count 2");
-                  elsif Tree.ID (Children (1)) /= +rhs_item_list_ID or
-                    Tree.ID (Children (2)) /= +ACTION_ID
-                  then
-                     Put_Error ("expecting rhs_item_list ACTION");
-                  end if;
-
-               when 3 =>
-                  if Tree.Child_Count (Node) /= 3 then
-                     Put_Error ("expected child_count 3");
-                  elsif Tree.ID (Children (1)) /= +rhs_item_list_ID or
-                    Tree.ID (Children (2)) /= +ACTION_ID or
-                    Tree.ID (Children (3)) /= +ACTION_ID
-                  then
-                     Put_Error ("expecting rhs_item_list ACTION ACTION");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_attribute_ID =>
-               Check_EBNF_Allowed;
-
-            when rhs_element_ID =>
-               case RHS_Index is
-               when 0 =>
-                  if Tree.Child_Count (Node) /= 1 then
-                     Put_Error ("expected child_count 1");
-                  elsif Tree.ID (Children (1)) /= +rhs_item_ID then
-                     Put_Error ("expecting rhs_item");
-                  end if;
-
-               when 1 =>
-                  if Tree.Child_Count (Node) /= 3 then
-                     Put_Error ("expected child_count 3");
-                  elsif Tree.ID (Children (1)) /= +IDENTIFIER_ID or
-                    Tree.ID (Children (2)) /= +EQUAL_ID or
-                    Tree.ID (Children (3)) /= +rhs_item_ID
-                  then
-                     Put_Error ("expecting IDENTIFIER EQUAL rhs_item");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_item_list_ID =>
-               case RHS_Index is
-               when 0 =>
-                  if Tree.Child_Count (Node) /= 1 then
-                     Put_Error ("expected child_count 1");
-                  elsif Tree.ID (Children (1)) /= +rhs_element_ID then
-                     Put_Error ("expecting rhs_element");
-                  end if;
-
-               when 1 =>
-                  if Tree.Child_Count (Node) /= 2 then
-                     Put_Error ("expected child_count 2");
-                  elsif Tree.ID (Children (1)) /= +rhs_item_list_ID or
-                    Tree.ID (Children (2)) /= +rhs_element_ID
-                  then
-                     Put_Error ("expecting rhs_item_list ELEMENT");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_item_ID =>
-               if Tree.Child_Count (Node) /= 1 then
-                  Put_Error ("expected child_count 1");
-               end if;
-
-               case RHS_Index is
-               when 0 =>
-                  if Tree.ID (Children (1)) /= +IDENTIFIER_ID then
-                     Put_Error ("expecting IDENTIFIER");
-                  end if;
-
-               when 1 =>
-                  if Tree.ID (Children (1)) /= +STRING_LITERAL_2_ID then
-                     Put_Error ("expecting STRING_LITERAL_2");
-                  end if;
-
-               when 2 =>
-                  if Tree.ID (Children (1)) /= +rhs_attribute_ID then
-                     Put_Error ("expecting rhs_attribute");
-                  end if;
-
-               when 3 =>
-                  if Tree.ID (Children (1)) /= +rhs_optional_item_ID then
-                     Put_Error ("expecting rhs_optional_item");
-                  end if;
-
-               when 4 =>
-                  if Tree.ID (Children (1)) /= +rhs_multiple_item_ID then
-                     Put_Error ("expecting rhs_multiple_item");
-                  end if;
-
-               when 5 =>
-                  if Tree.ID (Children (1)) /= +rhs_group_item_ID then
-                     Put_Error ("expecting rhs_group_item");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_group_item_ID =>
-               Check_EBNF_Allowed;
-               if RHS_Index /= 0 or
-                 (Children'Length /= 3 or else
-                    (Tree.ID (Children (1)) /= +LEFT_PAREN_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_PAREN_ID))
-               then
-                  Put_Error ("expecting RHS_Index 0, LEFT_PAREN 
rhs_alternative_list RIGHT_PAREN");
-               end if;
-
-            when rhs_optional_item_ID =>
-               Check_EBNF_Allowed;
-               case RHS_Index is
-               when 0 =>
-                  if Children'Length /= 3 or else
-                    (Tree.ID (Children (1)) /= +LEFT_BRACKET_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_BRACKET_ID)
-                  then
-                     Put_Error ("expecting LEFT_BRACKET rhs_alternative_list 
RIGHT_BRACKET");
-                  end if;
-
-               when 1 =>
-                  if Children'Length /= 4 or else
-                    (Tree.ID (Children (1)) /= +LEFT_PAREN_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_PAREN_ID or
-                       Tree.ID (Children (4)) /= +QUESTION_ID)
-                  then
-                     Put_Error ("expecting LEFT_PAREN rhs_alternative_list 
RIGHT_PAREN QUESTION");
-                  end if;
-
-               when 2 =>
-                  if Children'Length /= 2 or else
-                    (Tree.ID (Children (1)) /= +IDENTIFIER_ID or
-                       Tree.ID (Children (2)) /= +QUESTION_ID)
-                  then
-                     Put_Error ("expecting IDENTIFIER QUESTION");
-                  end if;
-
-               when 3 =>
-                  if Children'Length /= 2 or else
-                    (Tree.ID (Children (1)) /= +STRING_LITERAL_2_ID or
-                       Tree.ID (Children (2)) /= +QUESTION_ID)
-                  then
-                     Put_Error ("expecting STRING_LITERAL_2 QUESTION");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_multiple_item_ID =>
-               Check_EBNF_Allowed;
-               case RHS_Index is
-               when 0 =>
-                  if Children'Length /= 3 or else
-                    (Tree.ID (Children (1)) /= +LEFT_BRACE_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_BRACE_ID)
-                  then
-                     Put_Error ("expecting LEFT_BRACE rhs_alternative_list 
RIGHT_BRACE");
-                  end if;
-
-               when 1 =>
-                  if Children'Length /= 4 or else
-                    (Tree.ID (Children (1)) /= +LEFT_BRACE_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_BRACE_ID or
-                       Tree.ID (Children (4)) /= +MINUS_ID)
-                  then
-                     Put_Error ("expecting LEFT_BRACE rhs_alternative_list 
RIGHT_BRACE MINUS");
-                  end if;
-
-               when 2 =>
-                  if Children'Length /= 4 or else
-                    (Tree.ID (Children (1)) /= +LEFT_PAREN_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_PAREN_ID or
-                       Tree.ID (Children (4)) /= +PLUS_ID)
-                  then
-                     Put_Error ("expecting LEFT_PAREN rhs_alternative_list 
RIGHT_PAREN PLUS");
-                  end if;
-
-               when 3 =>
-                  if Children'Length /= 4 or else
-                    (Tree.ID (Children (1)) /= +LEFT_PAREN_ID or
-                       Tree.ID (Children (2)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (3)) /= +RIGHT_PAREN_ID or
-                       Tree.ID (Children (4)) /= +STAR_ID)
-                  then
-                     Put_Error ("expecting LEFT_PAREN rhs_alternative_list 
RIGHT_PAREN STAR");
-                  end if;
-
-               when 4 =>
-                  if Children'Length /= 2 or else
-                    (Tree.ID (Children (1)) /= +IDENTIFIER_ID or
-                       Tree.ID (Children (2)) /= +PLUS_ID)
-                  then
-                     Put_Error ("expecting IDENTIFIER PLUS");
-                  end if;
-
-               when 5 =>
-                  if Children'Length /= 2 or else
-                    (Tree.ID (Children (1)) /= +IDENTIFIER_ID or
-                       Tree.ID (Children (2)) /= +STAR_ID)
-                  then
-                     Put_Error ("expecting IDENTIFIER STAR");
-                  end if;
-
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when rhs_alternative_list_ID =>
-               Check_EBNF_Allowed;
-               case RHS_Index is
-               when 0 =>
-                  if Children'Length /= 1 or else
-                    (Tree.ID (Children (1)) /= +rhs_item_list_ID)
-                  then
-                     Put_Error ("expecting rhs_item_list");
-                  end if;
-
-               when 1 =>
-                  if Children'Length /= 3 or else
-                    (Tree.ID (Children (1)) /= +rhs_alternative_list_ID or
-                       Tree.ID (Children (2)) /= +BAR_ID or
-                       Tree.ID (Children (3)) /= +rhs_item_list_ID)
-                  then
-                     Put_Error ("expecting rhs_alternative_list BAR 
rhs_item_list");
-                  end if;
-               when others =>
-                  Put_Error ("unexpected RHS_Index");
-               end case;
-
-            when compilation_unit_ID =>
-               null;
-
-            when compilation_unit_list_ID =>
-               null;
-
-            when others =>
-               null;
-            end case;
-         end;
-      end Validate_Node;
-
-      procedure Check_Original_EBNF
-      is
-         use Ada.Text_IO;
-         Sub_Tree_Root : Node_Index;
-      begin
-         for N in Data.EBNF_Nodes.First_Index .. Data.EBNF_Nodes.Last_Index 
loop
-            if Data.EBNF_Nodes (N) then
-               Sub_Tree_Root := Tree.Sub_Tree_Root (N);
-               if Sub_Tree_Root /= Tree.Root then
-                  Put_Line
-                    (Current_Error,
-                     Error_Message
-                       (Tree, Data.Terminals, N, Data.Grammar_Lexer.File_Name,
-                        Tree.Image
-                          (N, Wisitoken_Grammar_Actions.Descriptor,
-                           Node_Numbers      => True)));
-                  Put_Line (Current_Error, "... not in tree; in root" & 
Sub_Tree_Root'Image);
-                  WisiToken.Generate.Error := True;
-               end if;
-            end if;
-         end loop;
-      end Check_Original_EBNF;
-
-      procedure Check_Copied_EBNF
-      is
-         use Ada.Text_IO;
-         Sub_Tree_Root : Node_Index;
-      begin
-         for N of Copied_EBNF_Nodes loop
-            if N /= Deleted_Child then
-               Sub_Tree_Root := Tree.Sub_Tree_Root (N);
-               if Sub_Tree_Root /= Tree.Root then
-                  Put_Line
-                    (Current_Error,
-                     Error_Message
-                       (Tree, Data.Terminals, N, Data.Grammar_Lexer.File_Name,
-                        Tree.Image
-                          (N, Wisitoken_Grammar_Actions.Descriptor,
-                           Node_Numbers      => True)));
-                  Put_Line (Current_Error, "... not in tree; in root" & 
Sub_Tree_Root'Image);
-                  WisiToken.Generate.Error := True;
-               end if;
-            end if;
-         end loop;
-      end Check_Copied_EBNF;
-
-   begin
-      --  Process nodes in node increasing order, so contained items are
-      --  translated first, so duplicates of the containing item can be found
-      for I in Data.EBNF_Nodes.First_Index .. Data.EBNF_Nodes.Last_Index loop
-         if Data.EBNF_Nodes (I) then
-            if Trace_Generate_EBNF > Outline then
-               Ada.Text_IO.New_Line;
-               Ada.Text_IO.Put_Line
-                 ("translate original node " & Tree.Image
-                    (I, Wisitoken_Grammar_Actions.Descriptor,
-                     Include_RHS_Index => True,
-                     Node_Numbers      => True));
-            end if;
-
-            Process_Node (I);
-
-            Tree.Validate_Tree
-              (Data.Terminals, Wisitoken_Grammar_Actions.Descriptor, 
Data.Grammar_Lexer.File_Name, Tree.Root,
-               Validate_Node'Unrestricted_Access);
-            Check_Original_EBNF;
-            Check_Copied_EBNF;
-         end if;
-      end loop;
-
-      declare
-         use Ada.Text_IO;
-      begin
-         for Node in Data.EBNF_Nodes.First_Index .. Data.EBNF_Nodes.Last_Index 
loop
-            if Data.EBNF_Nodes (Node) then
-               Put_Line
-                 (Current_Error,
-                  Error_Message
-                    (Tree, Data.Terminals, Node, Data.Grammar_Lexer.File_Name,
-                     Tree.Image
-                       (Node, Wisitoken_Grammar_Actions.Descriptor,
-                        Include_RHS_Index => True,
-                        Include_Children  => Trace_Generate_EBNF > Detail,
-                        Node_Numbers      => True)));
-               Put_Line (Current_Error, "... original EBNF node not 
translated");
-            end if;
-         end loop;
-      end;
-
-      declare
-         I : SAL.Base_Peek_Type := Copied_EBNF_Nodes.First_Index;
-      begin
-         --  Processing copied nodes may produce more copied nodes, so we can't
-         --  use a 'for' loop.
-         loop
-            exit when I > Copied_EBNF_Nodes.Last_Index;
-            if Copied_EBNF_Nodes (I) = Deleted_Child then
-               --  Deleted
-               if Trace_Generate_EBNF > Outline then
-                  Ada.Text_IO.New_Line;
-                  Ada.Text_IO.Put_Line
-                    ("skipping deleted copied node " & Tree.Image
-                       (Copied_EBNF_Nodes (I), 
Wisitoken_Grammar_Actions.Descriptor,
-                        Include_RHS_Index => True,
-                        Node_Numbers      => True));
-               end if;
-            else
-               if Trace_Generate_EBNF > Outline then
-                  Ada.Text_IO.New_Line;
-                  Ada.Text_IO.Put_Line
-                    ("translate copied node " & Tree.Image
-                       (Copied_EBNF_Nodes (I), 
Wisitoken_Grammar_Actions.Descriptor,
-                        Include_RHS_Index => True,
-                        Node_Numbers      => True));
-               end if;
-
-               Process_Node (Copied_EBNF_Nodes (I));
-
-               Tree.Validate_Tree
-                 (Data.Terminals, Wisitoken_Grammar_Actions.Descriptor, 
Data.Grammar_Lexer.File_Name, Tree.Root,
-                  Validate_Node'Unrestricted_Access);
-               Check_Copied_EBNF;
-            end if;
-            I := I + 1;
-         end loop;
-      end;
-
-      declare
-         use Ada.Text_IO;
-      begin
-         for Node of Copied_EBNF_Nodes loop
-            if Node /= Deleted_Child then
-               Put_Line
-                 (Current_Error,
-                  Error_Message
-                    (Tree, Data.Terminals, Node, Data.Grammar_Lexer.File_Name,
-                     Tree.Image
-                       (Node, Wisitoken_Grammar_Actions.Descriptor,
-                        Include_RHS_Index => True,
-                        Include_Children  => Trace_Generate_EBNF > Detail,
-                        Node_Numbers      => True)));
-               Put_Line (Current_Error, "... copied EBNF node not translated");
-            end if;
-         end loop;
-      end;
-
-      EBNF_Allowed := False;
-      Tree.Validate_Tree
-        (Data.Terminals, Wisitoken_Grammar_Actions.Descriptor, 
Data.Grammar_Lexer.File_Name, Tree.Root,
-         Validate_Node'Unrestricted_Access);
-
-      Data.Meta_Syntax := BNF_Syntax;
-
-      if Trace_Generate_EBNF > Detail then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line ("Identifiers:");
-         for I in Data.Tokens.Virtual_Identifiers.First_Index .. 
Data.Tokens.Virtual_Identifiers.Last_Index loop
-            Ada.Text_IO.Put_Line (Base_Identifier_Index'Image (I) & " " & 
(-Data.Tokens.Virtual_Identifiers (I)));
-         end loop;
-      end if;
-   end Translate_EBNF_To_BNF;
-
-   procedure Print_Source
-     (File_Name : in String;
-      Tree      : in WisiToken.Syntax_Trees.Tree;
-      Data      : in User_Data_Type)
-   is
-      use Ada.Text_IO;
-      use WisiToken.Syntax_Trees;
-
-      File : File_Type;
-
-      procedure Put_Comments
-        (Node           : in Valid_Node_Index;
-         Force_New_Line : in Boolean := False;
-         Force_Comment  : in String  := "")
-      is
-         Last_Term : constant Node_Index              := Tree.Last_Terminal 
(Node);
-         Aug       : constant Base_Token_Class_Access :=
-           (if Last_Term = Invalid_Node_Index
-            then null
-            else Tree.Augmented (Last_Term));
-
-         Comments_Include_Newline : Boolean := False;
-      begin
-         if Aug = null then
-            if Force_Comment /= "" then
-               Put_Line (File, Force_Comment);
-
-            elsif Force_New_Line then
-               New_Line (File);
-            end if;
-         else
-            for Token of Augmented_Token_Access (Aug).Non_Grammar loop
-               if Token.ID = +NEW_LINE_ID then
-                  Comments_Include_Newline := True;
-               end if;
-               Put (File, Data.Grammar_Lexer.Buffer_Text (Token.Byte_Region));
-            end loop;
-            if Force_New_Line and not Comments_Include_Newline then
-               New_Line (File);
-            end if;
-         end if;
-      end Put_Comments;
-
-      procedure Put_Declaration_Item (Node : in Valid_Node_Index)
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         case To_Token_Enum (Tree.ID (Children (1))) is
-         when IDENTIFIER_ID | NUMERIC_LITERAL_ID | STRING_LITERAL_1_ID | 
STRING_LITERAL_2_ID =>
-            Put (File, ' ' & Get_Text (Data, Tree, Children (1)));
-         when REGEXP_ID =>
-            Put (File, " %[" & Get_Text (Data, Tree, Children (1)) & "]%");
-         when others =>
-            Put (File, Image (Tree.ID (Children (1)), 
Wisitoken_Grammar_Actions.Descriptor));
-         end case;
-      end Put_Declaration_Item;
-
-      procedure Put_Declaration_Item_List (Node : in Valid_Node_Index)
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         if Children'Length = 1 then
-            Put_Declaration_Item (Children (1));
-         else
-            Put_Declaration_Item_List (Children (1));
-            Put_Declaration_Item (Children (2));
-         end if;
-      end Put_Declaration_Item_List;
-
-      procedure Put_Identifier_List (Node : in Valid_Node_Index)
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         if Children'Length = 1 then
-            Put (File, Get_Text (Data, Tree, Children (1)));
-         else
-            Put_Identifier_List (Children (1));
-            Put (File, ' ');
-            Put (File, Get_Text (Data, Tree, Children (2)));
-         end if;
-      end Put_Identifier_List;
-
-      procedure Put_RHS_Element (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_element_ID
-      is begin
-         --  We don't raise an exception for errors here; it's easier to debug 
from the
-         --  mangled source listing.
-
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put (File, Get_Text (Data, Tree, Node));
-
-         when 1 =>
-            --  Output no spaces around "="
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            begin
-               Put (File, Get_Text (Data, Tree, Children (1)) & "=" & Get_Text 
(Data, Tree, Children (3)));
-            end;
-
-         when others =>
-            New_Line (File);
-            Put (File, " ;; not translated: " & Node_Index'Image (Node) & ":" &
-                   Tree.Image (Node, Wisitoken_Grammar_Actions.Descriptor,
-                               Include_Children  => True,
-                               Include_RHS_Index => True,
-                               Node_Numbers      => True));
-         end case;
-      exception
-      when SAL.Programmer_Error =>
-         raise;
-
-      when E : others =>
-         declare
-            use Ada.Exceptions;
-         begin
-            Raise_Programmer_Error
-              ("Put_RHS_Element: " & Exception_Name (E) & ": " & 
Exception_Message (E), Data, Tree, Node);
-         end;
-      end Put_RHS_Element;
-
-      procedure Put_RHS_Item_List (Node : in Valid_Node_Index)
-      with Pre => Tree.ID (Node) = +rhs_item_list_ID
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         if Children'Length = 1 then
-            Put_RHS_Element (Children (1));
-         else
-            Put_RHS_Item_List (Children (1));
-            Put (File, ' ');
-            Put_RHS_Element (Children (2));
-         end if;
-      exception
-      when SAL.Programmer_Error =>
-         raise;
-
-      when E : others =>
-         declare
-            use Ada.Exceptions;
-         begin
-            Raise_Programmer_Error
-              ("Put_RHS_Item_List: " & Exception_Name (E) & ": " & 
Exception_Message (E), Data, Tree, Node);
-         end;
-      end Put_RHS_Item_List;
-
-      procedure Put_RHS
-        (Node  : in Valid_Node_Index;
-         First : in Boolean)
-      with Pre => Tree.ID (Node) = +rhs_ID
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         Put (File, (if First then "  : " else "  | "));
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put_Comments (Tree.Parent (Node), Force_Comment => ";; empty");
-
-         when 1 .. 3 =>
-            Put_RHS_Item_List (Children (1));
-            Put_Comments (Children (1), Force_New_Line => True);
-
-            if Tree.RHS_Index (Node) > 1 then
-               Put (File, "    %(" & Get_Text (Data, Tree, Children (2)) & 
")%"); -- action
-               Put_Comments (Children (2), Force_New_Line => True);
-
-               if Tree.RHS_Index (Node) > 2 then
-                  Put (File, "    %(" & Get_Text (Data, Tree, Children (3)) & 
")%"); -- check
-                  Put_Comments (Children (3), Force_New_Line => True);
-               end if;
-            end if;
-
-         when others =>
-            Raise_Programmer_Error ("Put_RHS", Data, Tree, Node);
-         end case;
-      exception
-      when SAL.Programmer_Error =>
-         raise;
-
-      when E : others =>
-         declare
-            use Ada.Exceptions;
-         begin
-            Raise_Programmer_Error ("Put_RHS: " & Exception_Name (E) & ": " & 
Exception_Message (E), Data, Tree, Node);
-         end;
-      end Put_RHS;
-
-      procedure Put_RHS_List
-        (Node    : in     Valid_Node_Index;
-         First   : in out Boolean;
-         Virtual : in     Boolean)
-      with Pre => Tree.ID (Node) = +rhs_list_ID
-      is
-         Children : constant Valid_Node_Index_Array := Tree.Children (Node);
-      begin
-         case Tree.RHS_Index (Node) is
-         when 0 =>
-            Put_RHS (Children (1), First);
-            First := False;
-         when 1 =>
-            Put_RHS_List (Children (1), First, Virtual);
-            Put_RHS (Children (3), First => False);
-         when 2 =>
-            Put
-              (File, "%if " & Get_Text (Data, Tree, Children (3)) & " = " & 
Get_Text (Data, Tree, Children (4)));
-            Put_Comments (Node);
-
-         when 3 =>
-            Put (File, "%end if");
-            Put_Comments (Node);
-
-         when others =>
-            Raise_Programmer_Error ("Put_RHS_List", Data, Tree, Node);
-         end case;
-      exception
-      when SAL.Programmer_Error =>
-         raise;
-
-      when E : others =>
-         declare
-            use Ada.Exceptions;
-         begin
-            Raise_Programmer_Error
-              ("Put_RHS_List: " & Exception_Name (E) & ": " & 
Exception_Message (E), Data, Tree, Node);
-         end;
-      end Put_RHS_List;
-
-      procedure Process_Node (Node : in Valid_Node_Index)
-      is begin
-         case To_Token_Enum (Tree.ID (Node)) is
-         --  Enum_Token_ID alphabetical order
-         when compilation_unit_ID =>
-            Process_Node (Tree.Child (Node, 1));
-
-         when compilation_unit_list_ID =>
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            begin
-               case To_Token_Enum (Tree.ID (Children (1))) is
-               when compilation_unit_list_ID =>
-                  Process_Node (Children (1));
-                  Process_Node (Children (2));
-               when compilation_unit_ID =>
-                  Process_Node (Children (1));
-               when others =>
-                  raise SAL.Programmer_Error;
-               end case;
-            end;
-
-         when declaration_ID =>
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-            begin
-               case Tree.RHS_Index (Node) is
-               when 0 =>
-                  case Tree.RHS_Index (Children (2)) is
-                  when 0 =>
-                     Put (File, "%keyword");
-                  when 1 =>
-                     Put (File, "%non_grammar <" & Get_Text (Data, Tree, 
Tree.Child (Children (2), 3)) & ">");
-                  when 2 =>
-                     Put (File, "%token <" & Get_Text (Data, Tree, Tree.Child 
(Children (2), 3)) & ">");
-                  when others =>
-                     raise SAL.Programmer_Error;
-                  end case;
-
-                  Put (File, " " & Get_Text (Data, Tree, Children (3)));
-                  Put_Declaration_Item_List (Children (4));
-                  Put_Comments (Children (4), Force_New_Line => True);
-
-               when 1 =>
-                  Put (File, "%code ");
-                  Put_Identifier_List (Children (3));
-                  Put (File, " %{" & Get_Text (Data, Tree, Children (4)) & 
"}%"); -- RAW_CODE
-                  Put_Comments (Node);
-
-               when 2 =>
-                  declare
-                     Key : constant String := Get_Text (Data, Tree, Children 
(2));
-                  begin
-                     if Key = "conflict" then
-                        Put (File, Data.Grammar_Lexer.Buffer_Text 
(Tree.Byte_Region (Node)));
-                     else
-                        Put (File, "%" & Key);
-                        Put_Declaration_Item_List (Children (3));
-                     end if;
-                  end;
-                  Put_Comments (Children (3));
-
-               when 3 =>
-                  Put (File, "%" & Get_Text (Data, Tree, Children (2)));
-                  Put_Comments (Children (2));
-
-               when 4 =>
-                  Put
-                    (File, "%if" & Get_Text (Data, Tree, Children (2)) & " = " 
& Get_Text (Data, Tree, Children (4)));
-                  Put_Comments (Node);
-
-               when 5 =>
-                  Put (File, "%end if");
-                  Put_Comments (Node);
-
-               when others =>
-                  raise SAL.Programmer_Error;
-               end case;
-            end;
-
-         when nonterminal_ID =>
-            declare
-               Children : constant Valid_Node_Index_Array := Tree.Children 
(Node);
-               Virtual  : constant Boolean                := Tree.Label 
(Children (1)) = Virtual_Identifier;
-               First    : Boolean                         := True;
-            begin
-               Put (File, Get_Text (Data, Tree, Children (1)));
-               Put_Comments (Children (1), Force_New_Line => True);
-
-               Put_RHS_List (Children (3), First, Virtual);
-
-               if Tree.Children (Children (4))'Length > 0 then
-                  if Virtual then
-                     Put_Line (File, "  ;");
-                  else
-                     Put (File, "  ;");
-                     Put_Comments (Children (4));
-                  end if;
-               end if;
-            end;
-
-         when wisitoken_accept_ID =>
-            Process_Node (Tree.Child (Node, 1));
-
-         when others =>
-            raise SAL.Not_Implemented with Image (Tree.ID (Node), 
Wisitoken_Grammar_Actions.Descriptor);
-         end case;
-      end Process_Node;
-   begin
-      Create (File, Out_File, File_Name);
-      Put_Line (File, ";;; generated from " & Data.Grammar_Lexer.File_Name & " 
-*- buffer-read-only:t -*-");
-      Put_Line (File, ";;;");
-
-      for Token of Data.Leading_Non_Grammar loop
-         Put (File, Data.Grammar_Lexer.Buffer_Text (Token.Byte_Region));
-      end loop;
-
-      Process_Node (Tree.Root);
-
-      Close (File);
-   exception
-   when E : SAL.Not_Implemented =>
-      Close (File);
-      Ada.Text_IO.Put_Line
-        (Ada.Text_IO.Standard_Error, "Print_Source not implemented: " & 
Ada.Exceptions.Exception_Message (E));
-   end Print_Source;
-
-end WisiToken_Grammar_Runtime;
---  Local Variables:
---  ada-which-func-parse-size: 50000
---  End:
diff --git a/packages/wisi/wisitoken_grammar_runtime.ads 
b/packages/wisi/wisitoken_grammar_runtime.ads
deleted file mode 100644
index a9de950..0000000
--- a/packages/wisi/wisitoken_grammar_runtime.ads
+++ /dev/null
@@ -1,166 +0,0 @@
---  Abstract :
---
---  Runtime utils for wisi_grammar.wy actions.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with WisiToken.BNF;
-with WisiToken.Lexer;
-with WisiToken.Syntax_Trees;
-with Wisitoken_Grammar_Actions;
-with WisiToken.Syntax_Trees.LR_Utils;
-package WisiToken_Grammar_Runtime is
-
-   type Meta_Syntax is (Unknown, BNF_Syntax, EBNF_Syntax);
-   --  Syntax used in grammar file.
-
-   type Action_Phase is (Meta, Other);
-
-   type User_Data_Type is new WisiToken.Syntax_Trees.User_Data_Type with
-   record
-      Grammar_Lexer : WisiToken.Lexer.Handle; -- used to read the .wy file now.
-
-      User_Lexer : WisiToken.BNF.Lexer_Type := WisiToken.BNF.None;
-      --  Used to read the user language file, after user parser is generated;
-      --  used now in '%if lexer' statements.
-
-      User_Parser : WisiToken.BNF.Generate_Algorithm := WisiToken.BNF.None;
-      --  Used to generate the user parser; used now in '%if parser'
-      --  statements.
-
-      Generate_Set : WisiToken.BNF.Generate_Set_Access;
-      --  As specified by %generate directives or command line.
-
-      Phase : Action_Phase := Meta;
-      --  Determines which actions Execute_Actions executes:
-      --  Meta  - meta declarations, like %meta_syntax, %generate
-      --  Other - everything else
-
-      Meta_Syntax      : WisiToken_Grammar_Runtime.Meta_Syntax := Unknown;
-      Terminals        : WisiToken.Base_Token_Array_Access_Constant;
-      Raw_Code         : WisiToken.BNF.Raw_Code;
-      Language_Params  : WisiToken.BNF.Language_Param_Type;
-      Tokens           : aliased WisiToken.BNF.Tokens;
-      Conflicts        : WisiToken.BNF.Conflict_Lists.List;
-      McKenzie_Recover : WisiToken.BNF.McKenzie_Recover_Param_Type;
-
-      Leading_Non_Grammar : WisiToken.Base_Token_Arrays.Vector;
-      --  leading blank lines and comments
-
-      Last_Terminal_Node : WisiToken.Node_Index := 
WisiToken.Invalid_Node_Index;
-
-      Rule_Count   : Integer                   := 0;
-      Action_Count : Integer                   := 0;
-      Check_Count  : Integer                   := 0;
-      Label_Count  : Ada.Containers.Count_Type := 0;
-
-      EBNF_Nodes : WisiToken.Syntax_Trees.Node_Sets.Vector;
-
-      If_Lexer_Present  : Boolean := False;
-      If_Parser_Present : Boolean := False;
-      --  Set True by %if statements in Execute_Actions.
-
-      Ignore_Lines : Boolean := False;
-      --  An '%if' specified a different lexer, during Execute_Actions
-   end record;
-
-   type Augmented_Token is new WisiToken.Base_Token with
-   record
-      Non_Grammar : WisiToken.Base_Token_Arrays.Vector;
-   end record;
-   type Augmented_Token_Access is access all Augmented_Token;
-
-   function Image (Item : in WisiToken.Base_Token_Class_Access) return String
-     is (WisiToken.Image (Augmented_Token_Access (Item).Non_Grammar, 
Wisitoken_Grammar_Actions.Descriptor));
-
-   overriding
-   procedure Set_Lexer_Terminals
-     (User_Data : in out User_Data_Type;
-      Lexer     : in     WisiToken.Lexer.Handle;
-      Terminals : in     WisiToken.Base_Token_Array_Access_Constant);
-
-   overriding procedure Reset (Data : in out User_Data_Type);
-
-   overriding
-   procedure Initialize_Actions
-     (Data : in out User_Data_Type;
-      Tree : in WisiToken.Syntax_Trees.Tree'Class);
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          User_Data_Type;
-      Tree  : in out          WisiToken.Syntax_Trees.Tree'Class;
-      Token : in              WisiToken.Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class);
-
-   procedure Start_If
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array);
-
-   procedure End_If (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class);
-
-   procedure Add_Declaration
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array);
-
-   procedure Add_Nonterminal
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array);
-
-   function Image_Grammar_Action (Action : in 
WisiToken.Syntax_Trees.Semantic_Action) return String;
-   --  For Syntax_Trees.Print_Tree.
-
-   procedure Check_EBNF
-     (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
-      Tree      : in     WisiToken.Syntax_Trees.Tree;
-      Tokens    : in     WisiToken.Valid_Node_Index_Array;
-      Token     : in     WisiToken.Positive_Index_Type);
-
-   procedure Raise_Programmer_Error
-     (Label : in String;
-      Data  : in User_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree;
-      Node  : in WisiToken.Node_Index);
-   pragma No_Return (Raise_Programmer_Error);
-
-   function Find_Declaration
-     (Data : in     User_Data_Type;
-      Tree : in out WisiToken.Syntax_Trees.Tree;
-      Name : in     String)
-     return WisiToken.Node_Index;
-   --  Return the node that declares Name, Invalid_Node_Index if none.
-   --  The node is either a declaration or a nonterminal.
-
-   procedure Translate_EBNF_To_BNF
-     (Tree : in out WisiToken.Syntax_Trees.Tree;
-      Data : in out User_Data_Type);
-   --  Process EBNF nonterms, adding new nonterms as needed, resulting in
-   --  a BNF tree.
-   --
-   --  Generator.LR.*_Generate requires a BNF grammar.
-
-   procedure Print_Source
-     (File_Name : in String;
-      Tree      : in WisiToken.Syntax_Trees.Tree;
-      Data      : in User_Data_Type);
-   --  Print the wisitoken grammar source represented by Tree, Terminals
-   --  to a new file File_Name.
-
-end WisiToken_Grammar_Runtime;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]