summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Leake <stephen_leake@stephe-leake.org>2023-10-26 10:53:42 -0700
committerStephen Leake <stephen_leake@stephe-leake.org>2023-10-26 10:53:42 -0700
commitcf8a92cec4df3d6be562ddd2e92f8014974f9c68 (patch)
tree5f3fac586569c23a0143090439eb2accdcf97552
parentdb272eca5c7cce620e19c1040cd97f79e0bd30b4 (diff)
parent1c4b099bf1f93cebee523b0ba75ccab6c6c2a2f0 (diff)
merge from externals/wisi to externals-release/wisiexternals-release/wisi
-rw-r--r--.elpaignore1
-rw-r--r--NEWS10
-rw-r--r--README2
-rw-r--r--emacs_wisi_common_parse.adb2
-rw-r--r--emacs_wisi_common_parse.ads10
-rw-r--r--run_wisi_common_parse.adb6
-rw-r--r--standard_common.gpr13
-rw-r--r--wisi-parse-common.el19
-rw-r--r--wisi-process-parse.el89
-rw-r--r--wisi-run-indent-test.el22
-rw-r--r--wisi.adb21
-rw-r--r--wisi.ads6
-rw-r--r--wisi.el4
-rw-r--r--wisi.texi10
-rw-r--r--wisitoken-bnf-generate.adb538
-rw-r--r--wisitoken-bnf-generate_packrat.adb4
-rw-r--r--wisitoken-bnf-generate_utils.adb75
-rw-r--r--wisitoken-bnf-generate_utils.ads12
-rw-r--r--wisitoken-bnf-output_ada.adb110
-rw-r--r--wisitoken-bnf-output_ada_common.adb77
-rw-r--r--wisitoken-bnf-output_ada_common.ads37
-rw-r--r--wisitoken-bnf-output_ada_emacs.adb539
-rw-r--r--wisitoken-bnf-output_elisp_common.adb4
-rw-r--r--wisitoken-bnf-utils.adb6
-rw-r--r--wisitoken-bnf-utils.ads4
-rw-r--r--wisitoken-bnf.adb13
-rw-r--r--wisitoken-bnf.ads52
-rw-r--r--wisitoken-generate-lr-lalr_generate.adb70
-rw-r--r--wisitoken-generate-lr-lalr_generate.ads3
-rw-r--r--wisitoken-generate-lr-lr1_generate.adb117
-rw-r--r--wisitoken-generate-lr-lr1_generate.ads3
-rw-r--r--wisitoken-generate-lr.adb210
-rw-r--r--wisitoken-generate-lr.ads5
-rw-r--r--wisitoken-generate-packrat.ads3
-rw-r--r--wisitoken-generate-tree_sitter.adb1183
-rw-r--r--wisitoken-generate-tree_sitter.ads17
-rw-r--r--wisitoken-in_parse_actions.adb38
-rw-r--r--wisitoken-in_parse_actions.ads10
-rw-r--r--wisitoken-lexer.adb4
-rw-r--r--wisitoken-parse-lr-mckenzie_recover-explore.adb36
-rw-r--r--wisitoken-parse-lr-mckenzie_recover-parse.adb4
-rw-r--r--wisitoken-parse-lr-mckenzie_recover.adb21
-rw-r--r--wisitoken-parse-lr-mckenzie_recover.ads13
-rw-r--r--wisitoken-parse-lr-parser-parse.adb6
-rw-r--r--wisitoken-parse-lr-parser.adb55
-rw-r--r--wisitoken-parse-lr-parser_no_recover.adb7
-rw-r--r--wisitoken-parse-lr.ads7
-rw-r--r--wisitoken-parse-packrat-generated.adb6
-rw-r--r--wisitoken-parse-packrat-procedural.adb6
-rw-r--r--wisitoken-parse.adb4
-rw-r--r--wisitoken-productions.adb43
-rw-r--r--wisitoken-productions.ads33
-rw-r--r--wisitoken-syntax_trees-lr_utils.adb7
-rw-r--r--wisitoken-syntax_trees.adb86
-rw-r--r--wisitoken-syntax_trees.ads144
-rw-r--r--wisitoken-user_guide.texinfo120
-rw-r--r--wisitoken-wisi_ada.adb13
-rw-r--r--wisitoken.adb94
-rw-r--r--wisitoken.ads52
-rw-r--r--wisitoken_grammar_actions.adb44
-rw-r--r--wisitoken_grammar_actions.ads44
-rw-r--r--wisitoken_grammar_editing.adb1673
-rw-r--r--wisitoken_grammar_editing.ads51
-rw-r--r--wisitoken_grammar_main.adb1523
-rw-r--r--wisitoken_grammar_main.ads4
-rw-r--r--wisitoken_grammar_re2c.c4
-rw-r--r--wisitoken_grammar_re2c_c.ads4
-rw-r--r--wisitoken_grammar_runtime.adb445
-rw-r--r--wisitoken_grammar_runtime.ads92
69 files changed, 5132 insertions, 2858 deletions
diff --git a/.elpaignore b/.elpaignore
new file mode 100644
index 0000000..ce56bc2
--- /dev/null
+++ b/.elpaignore
@@ -0,0 +1 @@
+alire.toml
diff --git a/NEWS b/NEWS
index e9b4614..bbd9f62 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,16 @@ 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 4.3.2
+21 Oct 2023
+
+** wisi-incremental-parse-enable is now t by default.
+
+* wisi 4.3.0
+15 Sep 2023
+
+** Use WisiToken 4.2.0.
+
* wisi 4.2.3
26 Jan 2023
diff --git a/README b/README
index 3fe3d2b..08fe597 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Emacs wisi package 4.2.2
+Emacs wisi package 4.3.2
The wisi package provides utilities for using generalized
error-correcting LR parsers (in external processes) to do indentation,
diff --git a/emacs_wisi_common_parse.adb b/emacs_wisi_common_parse.adb
index 5fc3877..4bedff3 100644
--- a/emacs_wisi_common_parse.adb
+++ b/emacs_wisi_common_parse.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
diff --git a/emacs_wisi_common_parse.ads b/emacs_wisi_common_parse.ads
index a5fb958..d39c1ff 100644
--- a/emacs_wisi_common_parse.ads
+++ b/emacs_wisi_common_parse.ads
@@ -2,7 +2,7 @@
--
-- Common utilities for Gen_Emacs_Wisi_*_Parse
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -37,10 +37,10 @@ package Emacs_Wisi_Common_Parse is
-- the implementation of the protocol.
--
-- Only changes once per wisi release. Increment as soon as required,
- -- record new version in NEWS-wisi.text. If working on a branch and
- -- main has already incremented, increment again, in case main is
- -- released before branch is merged; leave two "increment protocol"
- -- lines in NEWS-wisi.text to indicate the issue.
+ -- record new version in NEWS. If working on a branch and main has
+ -- already incremented, increment again, in case main is released
+ -- before branch is merged; leave two "increment protocol" lines in
+ -- NEWS to indicate the issue.
Prompt : constant String := ";;> ";
diff --git a/run_wisi_common_parse.adb b/run_wisi_common_parse.adb
index a3ece4c..ab7fc69 100644
--- a/run_wisi_common_parse.adb
+++ b/run_wisi_common_parse.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -94,7 +94,7 @@ package body Run_Wisi_Common_Parse is
Put_Line (" <action_begin_byte> <action_end_byte> [options]");
Put_Line (" or: refactor <refactor_action> <file_name> <edit_begin> [options]");
Put_Line (" or: command_file <command_file_name> [source_file_name]");
- Put_Line ("post_parse_action: {Navigate | Face | Indent}");
+ Put_Line ("post_parse_action: {None | Navigate | Face | Indent}");
New_Line;
Put_Line ("partial parse params: begin_byte_pos end_byte_pos goal_byte_pos begin_char_pos end_char_pos" &
@@ -496,7 +496,6 @@ package body Run_Wisi_Common_Parse is
-- Force a dispatching call.
Wisi.Parse_Data_Type'Class (Parse_Context.Parser.User_Data.all).Initialize;
- Parse_Context.Parser.User_Data.Reset;
Parse_Context.Parser.Tree.Lexer.Reset;
begin
Parse_Context.Parser.Parse (Log_File);
@@ -782,7 +781,6 @@ package body Run_Wisi_Common_Parse is
for I in 1 .. Cl_Params.Repeat_Count loop
begin
- Parse_Data.Reset;
Parser.Tree.Lexer.Reset;
Parser.Parse (Log_File);
diff --git a/standard_common.gpr b/standard_common.gpr
index 6553e95..0387cfe 100644
--- a/standard_common.gpr
+++ b/standard_common.gpr
@@ -2,7 +2,7 @@
--
-- Standard settings for all of Stephe's Ada projects.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -67,18 +67,21 @@ project Standard_Common is
-- -gnatVa causes some inline procedures to be non-inlineable;
-- suppress that warning with -gnatwP.
- Base_Debug_Switches := Common_Switches &
+ Base_Debug_Switches :=
(
"-O0", -- we don't use -Og because that causes gdb to report incorrect results in some cases in Ada.
"-gnatVa", -- validity checks
"-gnateE", -- extra info in exceptions
"-gnatwaP" -- no warn on Inline
- );
+ ) &
+ Common_Switches; -- last because turns of some of -gnatwa
case Assertions is
when "Build" =>
- Base_Debug_Switches := Base_Debug_Switches &
- ("-gnata"); -- assertions, pre/post-conditions
+ Base_Debug_Switches :=
+ ("-gnata") & -- assertions, pre/post-conditions
+ Base_Debug_Switches;
+
when "Off" =>
-- Allow turning off assertions with debug on, for execution speed.
null;
diff --git a/wisi-parse-common.el b/wisi-parse-common.el
index c78d244..d565c71 100644
--- a/wisi-parse-common.el
+++ b/wisi-parse-common.el
@@ -1,6 +1,6 @@
;;; 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 - 2022 Free Software Foundation, Inc.
+;; Copyright (C) 2014, 2015, 2017 - 2023 Free Software Foundation, Inc.
;;
;; Author: Stephen Leake <stephen_leake@member.fsf.org>
;;
@@ -22,7 +22,7 @@
;;; Code:
(require 'cl-lib)
-(defcustom wisi-incremental-parse-enable nil
+(defcustom wisi-incremental-parse-enable t
"If non-nil, use incremental parse when possible."
:type 'boolean
:group 'wisi
@@ -69,7 +69,7 @@ can be dumped to a file via the tree query dump-prev."
)
(cl-defstruct (wisi--parse-error-repair)
- pos ;; position (integer) in buffer where insert/delete is done.
+ pos ;; position (integer or marker) 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
@@ -240,6 +240,11 @@ The value is a list (source-buffer (font-lock-begin
region font-lock attempted to fontify while the parser was
busy.")
+(defvar wisi-parse-full-read-only nil
+ ;; Only one buffer can be doing a full parse.
+ "Non-nil if `wisi-parse-full-active is t and the buffer was
+originally read-only.")
+
(cl-defgeneric wisi-parse-incremental (parser parser-action &key full nowait)
"Incrementally parse current buffer.
PARSER-ACTION (one of `wisi-post-parse-actions') is used to
@@ -291,8 +296,12 @@ have been previously parsed by `wisi-parse-current' or
backend.
- ancestor: ARGS are a buffer position and a list of ids. Return
- the wisi-tree-node for the ancestor of the terminal at that pos
- that is one of the ids, or nil if no such ancestor.
+ the wisi-tree-node for the first ancestor of the terminal at
+ that pos that is one of the ids, or nil if no such ancestor. To
+ handle LR lists, if the parent of the result is the same as the
+ result, return the parent (iteratively); this returns the root
+ of the list. The char-region does not contain trailing
+ non-grammar.
- parent: ARGS are (node-address n). Return the wisi-tree-node
for the nth parent of the node, or nil if no such parent.
diff --git a/wisi-process-parse.el b/wisi-process-parse.el
index 210f19f..60bbdaa 100644
--- a/wisi-process-parse.el
+++ b/wisi-process-parse.el
@@ -151,7 +151,9 @@ Otherwise add PARSER to `wisi-process--alist', return it."
(wisi-parse-log-message wisi-parser-shared "parse--filter found prompt - initial full"))
(if (buffer-live-p (car wisi-parse-full-active))
(with-current-buffer (car wisi-parse-full-active)
- (read-only-mode -1)
+ (if wisi-parse-full-read-only
+ (setq wisi-parse-full-read-only nil)
+ (read-only-mode -1))
(let ((region (cdr wisi-parse-full-active)))
(font-lock-flush (max (point-min) (car region)) (min (point-max) (cdr region))))
@@ -556,6 +558,10 @@ PARSER will respond with one or more Query messages."
;; sexp is [Indent line-number line-begin-char-pos indent]
;; see `wisi-process-parse--execute'
(let ((pos (aref sexp 2)))
+ (when (< 0 wisi-debug)
+ (unless (= (aref sexp 1) (line-number-at-pos pos))
+ (error "indent: line/pos mismatch at %d" pos)))
+
(with-silent-modifications
(when (< (point-min) pos)
(put-text-property
@@ -626,8 +632,8 @@ PARSER will respond with one or more Query messages."
(file-name (if (buffer-file-name) (file-name-nondirectory (buffer-file-name)) "")))
;; file-name can be nil during vc-resolve-conflict
- (when (not name-1-pos)
- (setq name-1-pos name-2-pos)
+ (when (or (not name-1-pos) (= 0 name-1-pos))
+ (setq name-1-pos (min name-2-pos (point-max)))
(setq name-2-pos 0))
(when (not name-2-pos)
@@ -635,15 +641,15 @@ PARSER will respond with one or more Query messages."
(push (make-wisi--parse-error
:pos (copy-marker name-1-pos)
- :pos-2 (copy-marker name-2-pos)
+ :pos-2 (when (< 0 name-2-pos) (copy-marker name-2-pos))
:message
- (format
- (concat "%s:%d:%d: %s"
- (when (> 0 name-2-pos) " %s:%d:%d"))
- file-name (line-number-at-pos name-1-pos t) (funcall column-at-pos name-1-pos)
- (aref sexp 4)
- (when (> 0 name-2-pos)
- file-name (line-number-at-pos name-2-pos t) (funcall column-at-pos name-2-pos))))
+ (concat
+ (format "%s:%d:%d: %s"
+ file-name (line-number-at-pos name-1-pos t) (funcall column-at-pos name-1-pos)
+ (aref sexp 4))
+ (when (< 0 name-2-pos)
+ (format " %s:%d:%d"
+ file-name (line-number-at-pos name-2-pos t) (funcall column-at-pos name-2-pos)))))
(wisi-parser-local-parse-errors wisi-parser-local))
))
@@ -667,19 +673,20 @@ PARSER will respond with one or more Query messages."
(edit-pos (aref (aref sexp i) 1))
(err (wisi-process-parse--find-err error-pos (wisi-parser-local-parse-errors wisi-parser-local))))
(when err
- (cl-nsubst
- (push
- (make-wisi--parse-error-repair
- :pos (copy-marker edit-pos)
- :inserted (mapcar (lambda (id) (aref token-table id)) (aref (aref sexp i) 2))
- :deleted (mapcar (lambda (id) (aref token-table id)) (aref (aref sexp i) 3))
- :deleted-region (aref (aref sexp i) 4))
- (wisi--parse-error-repair err)) ;; new
- err ;; old
- (wisi-parser-local-parse-errors wisi-parser-local) ;; tree
- :test (lambda (old _el)
- (= (wisi--parse-error-pos old)
- (wisi--parse-error-pos err)))))
+ (with-no-warnings ;; byte-compiler complains that "result of cl-nsubst is not used", but it's not useful!
+ (cl-nsubst
+ (push
+ (make-wisi--parse-error-repair
+ :pos (copy-marker edit-pos)
+ :inserted (mapcar (lambda (id) (aref token-table id)) (aref (aref sexp i) 2))
+ :deleted (mapcar (lambda (id) (aref token-table id)) (aref (aref sexp i) 3))
+ :deleted-region (aref (aref sexp i) 4))
+ (wisi--parse-error-repair err)) ;; new
+ err ;; old
+ (wisi-parser-local-parse-errors wisi-parser-local) ;; tree
+ :test (lambda (old _el)
+ (= (wisi--parse-error-pos old)
+ (wisi--parse-error-pos err))))))
)))
))
@@ -837,7 +844,15 @@ Source buffer is current."
;; the process to die.
(setf (wisi-process--parser-busy parser) t)
(wisi-parse-log-message parser "kill process")
- (kill-process (wisi-process--parser-process parser)))
+ (let ((process (wisi-process--parser-process parser)))
+ (kill-process process)
+ (while (process-live-p process)
+ (accept-process-output
+ process
+ wisi-process-time-out
+ nil ;; milliseconds
+ nil) ;; just-this-one
+ )))
(setf (wisi-process--parser-busy parser) nil))
(cl-defun wisi-process-parse--prepare (parser parse-action &key nowait)
@@ -917,7 +932,7 @@ Source buffer is current."
(source-buffer (wisi-process--parser-source-buffer parser))
log-start)
(defvar w32-pipe-read-delay)
- (condition-case err
+ (condition-case-unless-debug err
(let* ((process (wisi-process--parser-process parser))
(w32-pipe-read-delay 0) ;; fastest subprocess read
response
@@ -1199,6 +1214,7 @@ Source buffer is current."
((and full nowait)
(set-process-filter (wisi-process--parser-process parser) #'wisi-process-parse--filter)
(setq wisi-parse-full-active (cons (current-buffer) (cons (point-min) (point-max))))
+ (setq wisi-parse-full-read-only buffer-read-only)
(read-only-mode 1)
(wisi-process-parse--send-incremental-parse parser full))
(t
@@ -1506,19 +1522,18 @@ prompt for it."
(string-equal (match-string 2) source-file))
(goto-char (match-end 0))
(looking-at " \\([0-9]+\\) \\([0-9]+\\)")
- (let ((label (string-to-number (match-string 1)))
- (pos (match-string 2)))
+ (let* ((label (string-to-number (match-string 1)))
+ (pos (match-string 2))
+ (rest-of-line (buffer-substring (match-end 2) (line-end-position))))
(set-buffer cmd-buffer)
(goto-char (point-max))
- (insert "-- query_tree "
- (cl-ecase label
- (0 "node ")
- (1 "containing_statement ")
- (2 "ancestor ")
- (3 "parent ")
- (4 "child ")
- (5 "print "))
- pos "\n\n")
+ (cl-ecase label
+ (0 (insert "-- query_tree node " pos "\n\n"))
+ (1 (insert "-- query_tree containing_statement " pos "\n\n"))
+ (2 (insert "-- query_tree ancestor " pos rest-of-line "\n\n"))
+ (3 (insert "-- query_tree parent " pos "\n\n"))
+ (4 (insert "-- query_tree child " pos "\n\n"))
+ (5 (insert "-- query_tree print " pos "\n\n")))
(set-buffer log-buffer)))
((and (string-equal (match-string 1) "refactor")
diff --git a/wisi-run-indent-test.el b/wisi-run-indent-test.el
index 0f3090c..5b9e0d8 100644
--- a/wisi-run-indent-test.el
+++ b/wisi-run-indent-test.el
@@ -1,6 +1,6 @@
;;; wisi-run-indent-test.el --- utils for automating indentation and casing tests -*- lexical-binding: t; -*-
;;
-;; Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+;; Copyright (C) 2018 - 2023 Free Software Foundation, Inc.
;;
;; This file is part of GNU Emacs.
;;
@@ -222,11 +222,8 @@ Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
(defun run-test-here ()
"Run an indentation and casing test on the current buffer."
(interactive)
- (when wisi-incremental-parse-enable
- ;; wait for the parser to finish the initial parse
- (wisi-wait-parser))
- (condition-case err
+ (condition-case-unless-debug err
(progn
(setq indent-tabs-mode nil)
@@ -372,9 +369,11 @@ Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
(length last-result)
(length expected-result)))))
- (let ((i 0))
+ (let ((i 0)
+ (fail nil))
(while (< i (length expected-result))
(unless (equal (nth i expected-result) (nth i last-result))
+ (setq fail t)
(setq error-count (1+ error-count))
(push (line-number-at-pos) error-lines)
(message
@@ -386,7 +385,10 @@ Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
(nth i last-result)
(nth i expected-result))
)))
- (setq i (1+ i)))))
+ (setq i (1+ i)))
+ (unless fail
+ (setq pass-count (1+ pass-count))
+ (message (format "test passes %s:%d:\n" (buffer-file-name) (line-number-at-pos))))))
((string= (match-string 1) "_SKIP_UNLESS")
(looking-at ".*$")
@@ -408,7 +410,9 @@ Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
(t
(setq error-count (1+ error-count))
(push (line-number-at-pos) error-lines)
- (error (concat "Unexpected EMACS test command " (match-string 1))))))
+ (error (concat "error: Unexpected EMACS test command " (match-string 1)))))
+
+ )
(let ((msg (format "%s:%d tests passed %d"
(buffer-file-name) (line-number-at-pos (point)) pass-count)))
@@ -517,7 +521,7 @@ Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
(let ((dir default-directory))
;; Always wait for initial full parse to complete.
- (setq wisi-parse-full-background nil)
+ (setq-default wisi-parse-full-background nil)
(find-file file-name) ;; sets default-directory
diff --git a/wisi.adb b/wisi.adb
index e75d4dc..f58a877 100644
--- a/wisi.adb
+++ b/wisi.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -859,7 +859,7 @@ package body Wisi is
overriding
function Copy_Augmented
(User_Data : in Parse_Data_Type;
- Augmented : in Syntax_Trees.Augmented_Class_Access)
+ Augmented : in not null Syntax_Trees.Augmented_Class_Access)
return Syntax_Trees.Augmented_Class_Access
is
Old_Aug : constant Augmented_Access := Augmented_Access (Augmented);
@@ -1970,6 +1970,15 @@ package body Wisi is
return;
end if;
+ if Query.Label = Ancestor then
+ -- Handle LR list; return list root.
+ loop
+ exit when Tree.Parent (Result) = Invalid_Node_Access or else
+ Tree.ID (Tree.Parent (Result)) /= Tree.ID (Result);
+ Result := Tree.Parent (Result);
+ end loop;
+ end if;
+
Char_Region := Tree.Char_Region (Result, Trailing_Non_Grammar => False);
when Containing_Statement =>
@@ -2197,8 +2206,12 @@ package body Wisi is
(case Item.Status.Label is
when WisiToken.Syntax_Trees.In_Parse_Actions.Ok => "",
when WisiToken.Syntax_Trees.In_Parse_Actions.Error =>
- Safe_Pos (Tree.Child (Error_Node, Item.Status.Begin_Name))'Image &
- Safe_Pos (Tree.Child (Error_Node, Item.Status.End_Name))'Image & " """ &
+ (if Item.Status.Begin_Name = 0
+ then " 0"
+ else Safe_Pos (Tree.Child (Error_Node, Item.Status.Begin_Name))'Image) &
+ (if Item.Status.End_Name = 0
+ then " 0"
+ else Safe_Pos (Tree.Child (Error_Node, Item.Status.End_Name))'Image) & " """ &
(case WisiToken.Syntax_Trees.In_Parse_Actions.Error'(Item.Status.Label) is
when Missing_Name_Error => "missing",
when Extra_Name_Error => "extra",
diff --git a/wisi.ads b/wisi.ads
index cd0c689..8295f7d 100644
--- a/wisi.ads
+++ b/wisi.ads
@@ -10,7 +10,7 @@
--
-- [3] wisi-process-parse.el - defines elisp/process API
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -122,7 +122,7 @@ package Wisi is
overriding
function Copy_Augmented
(User_Data : in Parse_Data_Type;
- Augmented : in WisiToken.Syntax_Trees.Augmented_Class_Access)
+ Augmented : in not null WisiToken.Syntax_Trees.Augmented_Class_Access)
return WisiToken.Syntax_Trees.Augmented_Class_Access;
overriding
@@ -170,7 +170,7 @@ package Wisi is
--
-- 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.
+ -- navigate cache; Motion_Action silently fails if not.
end record;
package Index_ID_Vectors is new Ada.Containers.Vectors (Ada.Containers.Count_Type, Index_ID);
diff --git a/wisi.el b/wisi.el
index 9ba44a3..ba704d3 100644
--- a/wisi.el
+++ b/wisi.el
@@ -7,7 +7,7 @@
;; Keywords: parser
;; indentation
;; navigation
-;; Version: 4.2.2
+;; Version: 4.3.2
;; package-requires: ((emacs "25.3") (seq "2.20"))
;; URL: https://stephe-leake.org/ada/wisitoken.html
;;
@@ -883,7 +883,7 @@ Run the parser first if needed."
(when (get-buffer-window wisi-error-buffer)
(delete-window (get-buffer-window wisi-error-buffer)))))
- (condition-case err
+ (condition-case-unless-debug err
(save-excursion
(cond
(partial-parse-p
diff --git a/wisi.texi b/wisi.texi
index 684b2db..adda2a7 100644
--- a/wisi.texi
+++ b/wisi.texi
@@ -29,7 +29,7 @@ developing GNU and promoting software freedom.''
@node Top
@top Top
-Wisi Version 4.2
+Wisi Version 4.3
@end ifnottex
@menu
@@ -304,9 +304,9 @@ amount. When all productions in a parse tree have been processed, the
indent has been computed for all lines.
Indent actions specify a delta indent for each token in a
-production. If the token is a nonterminal, it can contain multiple
-lines of text; the delta indent applies to the lines where the first
-token on the line is contained by the nonterminal.
+production. If the token is a nonterminal that contains multiple lines
+of text, the delta indent applies to the lines where the first token
+on the line is contained by the nonterminal.
When a delta indent is applied to the indent for a line, it is either
added or ignored. We call the token whose delta indent is being
@@ -396,7 +396,7 @@ thus all tokens in the production must be labeled. This
can improve readability in a long production.
When the grammar file uses EBNF meta-syntax, implicit labels are
-automatically generated for all tokens, unless they are explicitly
+automatically generated for all tokens that are not explicitly
labeled; this allows keeping track of which optional tokens are left
out when the production is converted to BNF internally.
diff --git a/wisitoken-bnf-generate.adb b/wisitoken-bnf-generate.adb
index 9c45c28..fa5f128 100644
--- a/wisitoken-bnf-generate.adb
+++ b/wisitoken-bnf-generate.adb
@@ -54,7 +54,7 @@ is
use Ada.Text_IO;
First : Boolean := True;
begin
- Put_Line (Standard_Error, "version 4.1"); -- matches release version in Docs/wisitoken.html
+ Put_Line (Standard_Error, "version 4.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);
@@ -116,7 +116,6 @@ is
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 : output translated EBNF source to <grammar file name base>_bnf.wy");
- 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");
@@ -124,12 +123,12 @@ is
Enable_Trace_Help;
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;
- Output_BNF : Boolean := False;
- Ignore_Conflicts : Boolean := False;
- Test_Main : Boolean := False;
+ Language_Name : Ada.Strings.Unbounded.Unbounded_String; -- The language the grammar defines
+ Grammar_File_Name_Base : Ada.Strings.Unbounded.Unbounded_String;
+ Need_Gen_Alg_In_Actions_Name : Boolean := False;
+ Output_BNF : Boolean := False;
+ Ignore_Conflicts : Boolean := False;
+ Test_Main : Boolean := False;
Command_Generate_Set : Generate_Set_Access; -- override grammar file declarations
@@ -141,10 +140,9 @@ is
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;
+ Grammar_File_Name_Base := +Ada.Directories.Base_Name (File_Name);
Grammar_Parser.Tree.Lexer.Reset_With_File (File_Name);
@@ -239,11 +237,6 @@ begin
Output_BNF := True;
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;
@@ -310,29 +303,22 @@ begin
declare
Time_Start : constant Ada.Calendar.Time := Ada.Calendar.Clock;
- Tree : WisiToken.Syntax_Trees.Tree renames Grammar_Parser.Tree;
begin
Syntax_Trees.Copy_Tree
- (Source => Tree,
+ (Source => Grammar_Parser.Tree,
Destination => BNF_Tree,
User_Data => Input_Data'Unchecked_Access);
- if Trace_Generate_EBNF > Detail then
- Ada.Text_IO.Put_Line ("EBNF tree:");
- BNF_Tree.Print_Tree;
- end if;
-
WisiToken_Grammar_Editing.Translate_EBNF_To_BNF (BNF_Tree, Input_Data);
if Trace_Generate_EBNF > Detail then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("BNF tree:");
- BNF_Tree.Print_Tree;
+ BNF_Tree.Print_Tree (Augmented => True);
end if;
if Output_BNF then
- -- FIXME: if %if is present, it can change the bnf tree; output one for each tuple.
- WisiToken_Grammar_Editing.Print_Source (-Output_File_Name_Root & "_bnf.wy", BNF_Tree, Input_Data);
+ WisiToken_Grammar_Editing.Print_Source (-Grammar_File_Name_Base & "_bnf.wy", BNF_Tree, Input_Data);
end if;
if Trace_Time then
@@ -355,19 +341,15 @@ begin
use all type Ada.Containers.Count_Type;
use all type WisiToken_Grammar_Runtime.Action_Phase;
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;
+ Input_Data.Reset (Lexer, Parser, Phase);
case Phase is
when Meta =>
if Trace_Generate > Outline then
- Trace.Put_Line ("post-parse grammar file META");
+ Trace.Put_Line ("post-parse main grammar tree META");
end if;
Grammar_Parser.Execute_Actions;
@@ -381,36 +363,24 @@ begin
end case;
when Other =>
- case Valid_Generate_Algorithm'(Parser) is
- when LR_Generate_Algorithm | Packrat_Generate_Algorithm =>
- -- IMPROVEME: for now, Packrat requires a BNF tree; eventually, it
- -- will use the EBNF tree.
+ if Input_Data.Meta_Syntax = EBNF_Syntax and BNF_Tree.Is_Empty then
+ Translate_To_BNF;
+ end if;
- if Input_Data.Meta_Syntax = EBNF_Syntax and BNF_Tree.Is_Empty then
- Translate_To_BNF;
+ if BNF_Tree.Is_Empty then
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("post-parse main grammar tree OTHER");
end if;
- if BNF_Tree.Is_Empty then
- if Trace_Generate > Outline then
- Trace.Put_Line ("post-parse grammar file OTHER, main tree");
- end if;
-
- Grammar_Parser.Execute_Actions;
- else
- if Trace_Generate > Outline then
- Trace.Put_Line ("post-parse grammar file OTHER, bnf tree");
- end if;
-
- WisiToken.Parse.Execute_Actions
- (BNF_Tree, Grammar_Parser.Productions, Input_Data'Unchecked_Access);
+ Grammar_Parser.Execute_Actions;
+ else
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("post-parse bnf grammar tree OTHER");
end if;
- when External =>
- null;
-
- when Tree_Sitter =>
- null;
- end case;
+ WisiToken.Parse.Execute_Actions
+ (BNF_Tree, Grammar_Parser.Productions, Input_Data'Unchecked_Access);
+ end if;
if Input_Data.Rule_Count = 0 or Input_Data.Tokens.Rules.Length = 0 then
raise WisiToken.Grammar_Error with "no rules";
@@ -428,6 +398,8 @@ begin
-- Get the generate tuples
Parse_Check (None, None, WisiToken_Grammar_Runtime.Meta);
+ Need_Gen_Alg_In_Actions_Name := Input_Data.If_Lexer_Present;
+
if Command_Generate_Set = null then
if Input_Data.Generate_Set = null then
raise User_Error with
@@ -447,211 +419,246 @@ begin
(if Command_Generate_Set = null then False else Command_Generate_Set'Length > 1);
for Tuple of Generate_Set.all loop
- if Trace_Generate > Outline then
- Trace.New_Line;
- Trace.Put_Line ("process tuple " & Image (Tuple));
- end if;
-
- case Tuple.Gen_Alg is
- when None | External =>
- if Input_Data.Meta_Syntax = EBNF_Syntax and BNF_Tree.Is_Empty then
- -- 'none' is used in unit tests to test bnf translation.
- Translate_To_BNF;
+ declare
+ -- We could use a cached Generate_Data if not
+ -- (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present), but
+ -- that would not save much time, and would complicate this logic. We
+ -- do cache Recursions.
+ Generate_Data : WisiToken.BNF.Generate_Utils.Generate_Data_Access;
+ Packrat_Data : WisiToken.Generate.Packrat.Data_Access;
+ begin
+ if Trace_Generate > Outline then
+ Trace.New_Line;
+ Trace.Put_Line ("process tuple " & Image (Tuple));
end if;
+ case Tuple.Gen_Alg is
+ when None | External =>
+ if Input_Data.Meta_Syntax = EBNF_Syntax and BNF_Tree.Is_Empty then
+ -- 'none' is used in unit tests to test bnf translation.
+ Translate_To_BNF;
+ end if;
- when Tree_Sitter =>
- Parse_Check
- (Lexer => Tuple.Lexer,
- Parser => Tuple.Gen_Alg,
- Phase => WisiToken_Grammar_Runtime.Other);
-
- declare
- use WisiToken.Generate.Tree_Sitter;
+ when Tree_Sitter =>
+ Parse_Check
+ (Lexer => Tuple.Lexer,
+ Parser => Tuple.Gen_Alg,
+ Phase => WisiToken_Grammar_Runtime.Other);
+
+ -- Generate_Data.Grammar is built from BNF_Tree; if we are generating
+ -- actions, the check in Eliminate_Empty_Productions ensures that is
+ -- the same as TS_Tree.
+ Generate_Data := new WisiToken.BNF.Generate_Utils.Generate_Data'
+ (WisiToken.BNF.Generate_Utils.Initialize
+ (Input_Data'Unchecked_Access, Grammar_Parser.Tree.Lexer.File_Name, Ignore_Conflicts));
+
+ declare
+ use WisiToken.Generate.Tree_Sitter;
+ TS_Tree : Syntax_Trees.Tree;
+ begin
+ Syntax_Trees.Copy_Tree
+ (Source => Grammar_Parser.Tree,
+ Destination => TS_Tree,
+ User_Data => Input_Data'Unchecked_Access);
- procedure Translate (Tree : in out Syntax_Trees.Tree)
- is begin
if Trace_Generate > Outline then
- Ada.Text_IO.New_Line;
- Ada.Text_IO.Put_Line ("output tree_sitter grammar");
+ Trace.Put_Line ("post-parse tree_sitter grammar tree OTHER");
end if;
- Eliminate_Empty_Productions (Input_Data, Tree);
+ -- FIXME: something is screwing up augmented; if we don't clear it
+ -- here, finalizing the other two trees crashes on a double free of
+ -- some augmented.
+ TS_Tree.Clear_Augmented;
+
+ Eliminate_Empty_Productions (Input_Data, TS_Tree, No_Empty => Tuple.Out_Lang /= None);
Print_Tree_Sitter
(Input_Data,
- Tree,
- Tree.Lexer,
- Output_File_Name => -Output_File_Name_Root & ".js",
+ TS_Tree,
+ TS_Tree.Lexer,
+ Output_File_Name => -Grammar_File_Name_Base & ".js",
Language_Name => -Language_Name);
if WisiToken.Generate.Error then
-- FIXME: support --warning=error
raise WisiToken.Grammar_Error with "errors during translating grammar to tree-sitter: aborting";
end if;
- end Translate;
- begin
- Translate (Grammar_Parser.Tree);
+ end;
- Create_Test_Main (-Output_File_Name_Root);
- end;
+ when LR_Packrat_Generate_Algorithm =>
+ Parse_Check
+ (Lexer => Tuple.Lexer,
+ Parser => Tuple.Gen_Alg,
+ Phase => WisiToken_Grammar_Runtime.Other);
- when LR_Packrat_Generate_Algorithm =>
- Parse_Check
- (Lexer => Tuple.Lexer,
- Parser => Tuple.Gen_Alg,
- Phase => WisiToken_Grammar_Runtime.Other);
+ Generate_Data := new WisiToken.BNF.Generate_Utils.Generate_Data'
+ (WisiToken.BNF.Generate_Utils.Initialize
+ (Input_Data'Unchecked_Access, Grammar_Parser.Tree.Lexer.File_Name, Ignore_Conflicts));
- declare
- use all type WisiToken.Parse.LR.Parse_Table_Ptr;
- use Ada.Real_Time;
-
- Time_Start : Time;
- Time_End : Time;
-
- -- We could use a cached Generate_Data if not
- -- (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present), but
- -- that would not save much time, and would complicate this logic. We
- -- do cache Recursions.
- Generate_Data : aliased WisiToken.BNF.Generate_Utils.Generate_Data :=
- WisiToken.BNF.Generate_Utils.Initialize
- (Input_Data'Unchecked_Access, Grammar_Parser.Tree.Lexer.File_Name, 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 Tuple.Gen_Alg in LALR .. Packrat_Proc
- then -Output_File_Name_Root & "_" & To_Lower (Tuple.Gen_Alg'Image) &
+ declare
+ use all type WisiToken.Parse.LR.Parse_Table_Ptr;
+ use Ada.Real_Time;
+
+ Parse_Table_File_Name : constant String := -Grammar_File_Name_Base &
+ "_" & To_Lower (Tuple.Gen_Alg'Image) &
(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_File
- (Input_Data, Tuple, Generate_Data, -Output_File_Name_Root);
- when others =>
- null;
- end case;
- end if;
-
- case LR_Packrat_Generate_Algorithm'(Tuple.Gen_Alg) is
- when LALR =>
+ else "") & ".parse_table";
- Time_Start := Clock;
+ Time_Start : Time;
+ Time_End : Time;
- if Generate_Data.Grammar (Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
+ 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.all);
+ Set_Output (Standard_Output);
+ Close (Parse_Table_File);
+ end Parse_Table_Append_Stats;
+
+ function To_McKenzie return WisiToken.Parse.LR.McKenzie_Param_Type
+ is begin
+ return Generate_Utils.To_McKenzie_Param (Generate_Data.all, Input_Data.McKenzie_Recover);
+ exception
+ when E : Not_Found =>
WisiToken.Generate.Put_Error
(WisiToken.Generate.Error_Message
(Grammar_Parser.Tree.Lexer.File_Name, 1,
- "%start token not specified or not found; no LALR parse table generated"));
- else
- if Trace_Generate > Outline then
- Trace.Put_Line ("generate LALR parse table");
- end if;
+ "In some %mckenzie_*; " & Ada.Exceptions.Exception_Message (E)));
+ return WisiToken.Parse.LR.Default_McKenzie_Param;
+ end To_McKenzie;
- Generate_Data.LR_Parse_Table := WisiToken.Generate.LR.LALR_Generate.Generate
- (Generate_Data.Grammar,
- Generate_Data.Descriptor.all,
- Grammar_Parser.Tree.Lexer.File_Name,
- Input_Data.Language_Params.Error_Recover,
- Generate_Data.Conflicts,
- Generate_Utils.To_McKenzie_Param (Generate_Data, Input_Data.McKenzie_Recover),
- Input_Data.Max_Parallel,
- Parse_Table_File_Name,
- Include_Extra => Test_Main,
- Ignore_Conflicts => Ignore_Conflicts,
- Recursion_Strategy => Input_Data.Language_Params.Recursion_Strategy,
- Use_Cached_Recursions => not (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present),
- Recursions => Cached_Recursions);
-
- 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;
+ 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_File
+ (Input_Data, Tuple, Generate_Data.all, -Grammar_File_Name_Base);
+ when others =>
+ null;
+ end case;
end if;
- when LR1 =>
- Time_Start := Clock;
+ case LR_Packrat_Generate_Algorithm'(Tuple.Gen_Alg) is
+ 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.Tree.Lexer.File_Name, 1,
+ "%start token not specified or not found; no LALR parse table generated"));
+ else
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("generate LALR parse table");
+
+ if Trace_Generate > Detail or Trace_Generate_Conflicts > Detail then
+ Trace.New_Line;
+ Trace.Put_Line ("Tokens:");
+ WisiToken.Put_Tokens (Generate_Data.Descriptor.all);
+ Trace.Put_Line ("Precedences:");
+ WisiToken.Put (Input_Data.Precedence_Lists, Input_Data.Precedence_Map);
+ Trace.Put_Line ("grammar:");
+ WisiToken.Productions.Put (Generate_Data.Grammar, Generate_Data.Descriptor.all);
+ Trace.New_Line;
+ if Trace_Generate > Extra or Trace_Generate_Conflicts > Extra then
+ Trace.Put_Line ("tree:");
+ Grammar_Parser.Tree.Print_Tree;
+ Trace.New_Line;
+ end if;
+ end if;
+ end if;
- if Generate_Data.Grammar (Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
- WisiToken.Generate.Put_Error
- (WisiToken.Generate.Error_Message
- (Grammar_Parser.Tree.Lexer.File_Name, 1,
- "%start token not specified or not found; no LALR parse table generated"));
- else
- if Trace_Generate > Outline then
- Trace.Put_Line ("generate LR1 parse table");
- end if;
+ Generate_Data.LR_Parse_Table := WisiToken.Generate.LR.LALR_Generate.Generate
+ (Generate_Data.Grammar,
+ Input_Data.Precedence_Lists,
+ Generate_Data.Descriptor.all,
+ Grammar_Parser.Tree.Lexer.File_Name,
+ Input_Data.Language_Params.Error_Recover,
+ Generate_Data.Conflicts,
+ To_McKenzie,
+ Input_Data.Max_Parallel,
+ Parse_Table_File_Name,
+ Include_Extra => Test_Main,
+ Ignore_Conflicts => Ignore_Conflicts,
+ Recursion_Strategy => Input_Data.Language_Params.Recursion_Strategy,
+ Use_Cached_Recursions => not (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present),
+ Recursions => Cached_Recursions);
+
+ 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;
- Generate_Data.LR_Parse_Table := WisiToken.Generate.LR.LR1_Generate.Generate
- (Generate_Data.Grammar,
- Generate_Data.Descriptor.all,
- Grammar_Parser.Tree.Lexer.File_Name,
- Input_Data.Language_Params.Error_Recover,
- Generate_Data.Conflicts,
- Generate_Utils.To_McKenzie_Param (Generate_Data, Input_Data.McKenzie_Recover),
- Input_Data.Max_Parallel,
- Parse_Table_File_Name,
- Include_Extra => Test_Main,
- Ignore_Conflicts => Ignore_Conflicts,
- Recursion_Strategy => Input_Data.Language_Params.Recursion_Strategy,
- Use_Cached_Recursions => not (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present),
- Recursions => Cached_Recursions);
-
- 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)));
+ Parse_Table_Append_Stats;
end if;
- if Parse_Table_File_Name /= "" then
+ 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.Tree.Lexer.File_Name, 1,
+ "%start token not specified or not found; no LALR parse table generated"));
+ else
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("generate LR1 parse table");
+ end if;
+
+ Generate_Data.LR_Parse_Table := WisiToken.Generate.LR.LR1_Generate.Generate
+ (Generate_Data.Grammar,
+ Input_Data.Precedence_Lists,
+ Generate_Data.Descriptor.all,
+ Grammar_Parser.Tree.Lexer.File_Name,
+ Input_Data.Language_Params.Error_Recover,
+ Generate_Data.Conflicts,
+ To_McKenzie,
+ Input_Data.Max_Parallel,
+ Parse_Table_File_Name,
+ Include_Extra => Test_Main,
+ Ignore_Conflicts => Ignore_Conflicts,
+ Recursion_Strategy => Input_Data.Language_Params.Recursion_Strategy,
+ Use_Cached_Recursions => not (Input_Data.If_Lexer_Present or Input_Data.If_Parser_Present),
+ Recursions => Cached_Recursions);
+
+ 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;
+
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.
+ 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
- (Grammar_Parser.Tree.Lexer.File_Name, Generate_Data.Grammar, Generate_Data.Source_Line_Map,
- Generate_Data.Descriptor.First_Terminal);
+ Packrat_Data := new WisiToken.Generate.Packrat.Data'
+ (WisiToken.Generate.Packrat.Initialize
+ (Grammar_Parser.Tree.Lexer.File_Name, Generate_Data.Grammar, Generate_Data.Source_Line_Map,
+ Generate_Data.Descriptor.First_Terminal));
- if Parse_Table_File_Name /= "" then
declare
+ -- There is no parse_table for packrat, but it's useful to have a
+ -- definitive list of tokens and productions (after all %if are
+ -- processed).
Parse_Table_File : File_Type;
begin
Create (Parse_Table_File, Out_File, Parse_Table_File_Name);
@@ -664,59 +671,64 @@ begin
Set_Output (Standard_Output);
Close (Parse_Table_File);
end;
- end if;
- Packrat_Data.Check_All (Generate_Data.Descriptor.all, Input_Data.Suppress);
+ Packrat_Data.Check_All (Generate_Data.Descriptor.all, Input_Data.Suppress);
+
+ if WisiToken.Generate.Warning then
+ WisiToken.Generate.Put_Warning ("warnings during packrat generation");
+ end if;
+ end case;
- if WisiToken.Generate.Warning then
- WisiToken.Generate.Put_Warning ("warnings during packrat generation");
+ if WisiToken.Generate.Error then
+ raise WisiToken.Grammar_Error with "errors: aborting";
end if;
- 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 =>
+ pragma Assert
+ (Generate_Data.LR_Parse_Table /= null and then
+ Generate_Data.LR_Parse_Table.Error_Recover_Enabled =
+ Input_Data.Language_Params.Error_Recover);
+
+ if Tuple.Text_Rep then
+ WisiToken.Generate.LR.Put_Text_Rep
+ (Generate_Data.LR_Parse_Table.all,
+ Text_Rep_File_Name (-Grammar_File_Name_Base, Tuple, Input_Data.If_Lexer_Present));
+ end if;
- case Tuple.Gen_Alg is
- when LR_Generate_Algorithm =>
- pragma Assert
- (Generate_Data.LR_Parse_Table /= null and then
- Generate_Data.LR_Parse_Table.Error_Recover_Enabled = Input_Data.Language_Params.Error_Recover);
+ when others =>
+ null;
+ end case;
+ end;
+ end case;
- if Tuple.Text_Rep then
- WisiToken.Generate.LR.Put_Text_Rep
- (Generate_Data.LR_Parse_Table.all,
- Text_Rep_File_Name (-Output_File_Name_Root, Tuple, Input_Data.If_Lexer_Present));
- end if;
+ case Tuple.Out_Lang is
+ when None =>
+ null;
- when others =>
- null;
- end case;
+ when Ada_Lang =>
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("output Ada");
+ end if;
- case Tuple.Out_Lang is
- when Ada_Lang =>
- if Trace_Generate > Outline then
- Trace.Put_Line ("output Ada");
- end if;
+ WisiToken.BNF.Output_Ada
+ (Input_Data, Grammar_Parser.Tree.Lexer.File_Name, -Grammar_File_Name_Base, Generate_Data.all,
+ Packrat_Data, Tuple, Test_Main, Multiple_Tuples, Need_Gen_Alg_In_Actions_Name);
- WisiToken.BNF.Output_Ada
- (Input_Data, Grammar_Parser.Tree.Lexer.File_Name, -Output_File_Name_Root, Generate_Data,
- Packrat_Data, Tuple, Test_Main, Multiple_Tuples);
+ when Ada_Emacs_Lang =>
+ if Trace_Generate > Outline then
+ Trace.Put_Line ("output Ada for Emacs");
+ end if;
+ WisiToken.BNF.Output_Ada_Emacs
+ (Input_Data, Grammar_Parser.Tree.Lexer.File_Name, -Grammar_File_Name_Base, Generate_Data.all,
+ Packrat_Data, Tuple, Test_Main, Multiple_Tuples, Need_Gen_Alg_In_Actions_Name, -Language_Name);
- when Ada_Emacs_Lang =>
- if Trace_Generate > Outline then
- Trace.Put_Line ("output Ada for Emacs");
- end if;
- WisiToken.BNF.Output_Ada_Emacs
- (Input_Data, Grammar_Parser.Tree.Lexer.File_Name, -Output_File_Name_Root, Generate_Data,
- Packrat_Data, Tuple, Test_Main, Multiple_Tuples, -Language_Name);
+ end case;
- end case;
- if WisiToken.Generate.Error then
- raise WisiToken.Grammar_Error with "errors: aborting";
- end if;
- end;
- end case;
+ if WisiToken.Generate.Error then
+ raise WisiToken.Grammar_Error with "errors: aborting";
+ end if;
+ end;
end loop;
end;
exception
diff --git a/wisitoken-bnf-generate_packrat.adb b/wisitoken-bnf-generate_packrat.adb
index 2bc59eb..daebc36 100644
--- a/wisitoken-bnf-generate_packrat.adb
+++ b/wisitoken-bnf-generate_packrat.adb
@@ -6,7 +6,7 @@
--
-- See wisitoken-parse-packrat.ads.
--
--- Copyright (C) 2018, 2020 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018, 2020 - 2023 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
@@ -213,7 +213,7 @@ is
end Finish;
begin
- Indent_Wrap_Comment (Productions.Image (Prod.LHS, RHS_Index, RHS.Tokens, Descriptor), Ada_Comment);
+ Indent_Wrap_Comment (Productions.Image (Prod.LHS, RHS_Index, RHS, Descriptor), Ada_Comment);
Indent_Line ("Pos := Last_Pos;");
Indent_Line ("Next_Pos := Tree.Stream_Next (Tree.Shared_Stream, Pos);");
diff --git a/wisitoken-bnf-generate_utils.adb b/wisitoken-bnf-generate_utils.adb
index 3b089c1..b831577 100644
--- a/wisitoken-bnf-generate_utils.adb
+++ b/wisitoken-bnf-generate_utils.adb
@@ -2,7 +2,7 @@
--
-- see spec
--
--- Copyright (C) 2014, 2015, 2017 - 2022 All Rights Reserved.
+-- Copyright (C) 2014, 2015, 2017 - 2023 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
@@ -117,8 +117,10 @@ package body WisiToken.BNF.Generate_Utils is
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);
+ Data.Post_Parse_Action_Names := new Names_Array_Array
+ (Descriptor.First_Nonterminal .. Descriptor.Last_Nonterminal);
+ Data.In_Parse_Action_Names := new Names_Array_Array
+ (Descriptor.First_Nonterminal .. Descriptor.Last_Nonterminal);
pragma Assert (Descriptor.Accept_ID = Descriptor.First_Nonterminal);
@@ -144,13 +146,13 @@ package body WisiToken.BNF.Generate_Utils is
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;
+ RHS_Index : Natural := 0;
+ RHSs : WisiToken.Productions.RHS_Arrays.Vector;
+ LHS : Token_ID; -- not initialized for exception handler
+ Post_Parse_Action_Names : Names_Array (0 .. Integer (Rule.Right_Hand_Sides.Length) - 1);
+ Post_Parse_Action_All_Empty : Boolean := True;
+ In_Parse_Action_Names : Names_Array (0 .. Integer (Rule.Right_Hand_Sides.Length) - 1);
+ In_Parse_Action_All_Empty : Boolean := True;
begin
LHS := Find_Token_ID (Data, -Rule.Left_Hand_Side);
@@ -174,15 +176,21 @@ package body WisiToken.BNF.Generate_Utils is
end loop;
end if;
RHSs (RHS_Index) :=
- (Tokens => Tokens, Post_Parse_Action => null, In_Parse_Action => null, Recursion => <>);
- if Length (Right_Hand_Side.Action) > 0 then
- Action_All_Empty := False;
- Action_Names (RHS_Index) := new String'
+ (Tokens => Tokens,
+ Post_Parse_Action => null,
+ In_Parse_Action => null,
+ Recursion => <>,
+ Associativity => Right_Hand_Side.Associativity,
+ Precedence => Right_Hand_Side.Precedence);
+
+ if Length (Right_Hand_Side.Post_Parse_Action) > 0 then
+ Post_Parse_Action_All_Empty := False;
+ Post_Parse_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'
+ if Length (Right_Hand_Side.In_Parse_Action) > 0 then
+ In_Parse_Action_All_Empty := False;
+ In_Parse_Action_Names (RHS_Index) := new String'
(-Rule.Left_Hand_Side & '_' & WisiToken.Trimmed_Image (RHS_Index) & "_check");
end if;
@@ -197,13 +205,13 @@ package body WisiToken.BNF.Generate_Utils is
RHS_Index := RHS_Index + 1;
end loop;
- Data.Grammar (LHS) := (LHS, Rule.Optimized_List, RHSs);
+ Data.Grammar (LHS) := (LHS, Rule.Optimized_List, RHSs, Rule.Precedence);
- if not Action_All_Empty then
- Data.Action_Names (LHS) := new Names_Array'(Action_Names);
+ if not Post_Parse_Action_All_Empty then
+ Data.Post_Parse_Action_Names (LHS) := new Names_Array'(Post_Parse_Action_Names);
end if;
- if not Check_All_Empty then
- Data.Check_Names (LHS) := new Names_Array'(Check_Names);
+ if not In_Parse_Action_All_Empty then
+ Data.In_Parse_Action_Names (LHS) := new Names_Array'(In_Parse_Action_Names);
end if;
exception
@@ -293,9 +301,11 @@ package body WisiToken.BNF.Generate_Utils is
To_Grammar (Result, Grammar_File_Name, -Input_Data.Language_Params.Start_Token);
Result.Ignore_Conflicts := Ignore_Conflicts;
- Result.Conflicts := To_Conflicts
- ((Result.Tokens, Descriptor_Access_Constant (Result.Descriptor)), Ignore_Conflicts, Input_Data.Conflicts,
- Grammar_File_Name);
+ if Input_Data.User_Parser in LR_Generate_Algorithm then
+ Result.Conflicts := To_Conflicts
+ ((Result.Tokens, Descriptor_Access_Constant (Result.Descriptor)), Ignore_Conflicts, Input_Data.Conflicts,
+ Grammar_File_Name);
+ end if;
if WisiToken.Generate.Error then
raise WisiToken.Grammar_Error with "errors during initializing grammar: aborting";
@@ -350,10 +360,10 @@ package body WisiToken.BNF.Generate_Utils is
end if;
end if;
- Input_Data.Reset;
- Input_Data.Phase := WisiToken_Grammar_Runtime.Other;
- Input_Data.User_Parser := Generate_Algorithm;
- Input_Data.User_Lexer := Lexer;
+ Input_Data.Reset
+ (Phase => WisiToken_Grammar_Runtime.Other,
+ User_Parser => Generate_Algorithm,
+ User_Lexer => Lexer);
Grammar_Parser.Execute_Actions; -- populates Input_Data.Tokens
@@ -865,6 +875,9 @@ package body WisiToken.BNF.Generate_Utils is
(Error_Message
(Source_File_Name, Item.Source_Line, Ada.Exceptions.Exception_Message (E)));
end if;
+
+ when SAL.Duplicate_Key =>
+ Put_Error (Error_Message (Source_File_Name, Item.Source_Line, "duplicate conflict"));
end;
end loop;
return Result;
@@ -935,8 +948,8 @@ package body WisiToken.BNF.Generate_Utils is
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," &
+ Integer'Image (Input_Data.Post_Parse_Action_Count) & " post_parse actions," &
+ Integer'Image (Input_Data.In_Parse_Action_Count) & " in_parse actions," &
WisiToken.State_Index'Image (Generate_Data.Parser_State_Count) & " states");
end Put_Stats;
diff --git a/wisitoken-bnf-generate_utils.ads b/wisitoken-bnf-generate_utils.ads
index 7379308..6744f37 100644
--- a/wisitoken-bnf-generate_utils.ads
+++ b/wisitoken-bnf-generate_utils.ads
@@ -3,7 +3,7 @@
-- Utilities for translating input file structures to WisiToken
-- structures needed for LALR.Generate.
--
--- Copyright (C) 2014, 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2014, 2015, 2017 - 2023 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
@@ -40,12 +40,11 @@ package WisiToken.BNF.Generate_Utils is
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.
+ Post_Parse_Action_Names : Names_Array_Array_Access;
+ In_Parse_Action_Names : Names_Array_Array_Access;
+ -- Names of subprograms for each grammar post_parse and in_parse
+ -- action; non-null only if there is an action 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
@@ -56,6 +55,7 @@ package WisiToken.BNF.Generate_Utils is
LR_Parse_Table : WisiToken.Parse.LR.Parse_Table_Ptr;
Parser_State_Count : WisiToken.Unknown_State_Index := 0;
end record;
+ type Generate_Data_Access is access Generate_Data;
function Initialize
(Input_Data : in WisiToken_Grammar_Runtime.User_Data_Access;
diff --git a/wisitoken-bnf-output_ada.adb b/wisitoken-bnf-output_ada.adb
index 6069c84..9882a5f 100644
--- a/wisitoken-bnf-output_ada.adb
+++ b/wisitoken-bnf-output_ada.adb
@@ -4,7 +4,7 @@
-- parameters, and a parser for that grammar. The grammar parser
-- actions must be Ada.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -27,19 +27,21 @@ 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.Generate.Tree_Sitter;
with WisiToken_Grammar_Runtime;
procedure WisiToken.BNF.Output_Ada
- (Input_Data : in WisiToken_Grammar_Runtime.User_Data_Type;
- Grammar_File_Name : in String;
- 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)
+ (Input_Data : in WisiToken_Grammar_Runtime.User_Data_Type;
+ Grammar_File_Name : in String;
+ Output_File_Name_Root : in String;
+ Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data;
+ Packrat_Data : in WisiToken.Generate.Packrat.Data_Access;
+ Tuple : in Generate_Tuple;
+ Test_Main : in Boolean;
+ Multiple_Tuples : in Boolean;
+ Need_Gen_Alg_In_Actions_Name : in Boolean)
is
- Common_Data : Output_Ada_Common.Common_Data := WisiToken.BNF.Output_Ada_Common.Initialize
- (Input_Data, Tuple, Grammar_File_Name, Output_File_Name_Root, Check_Interface => False);
+ Common_Data : constant Output_Ada_Common.Common_Data := WisiToken.BNF.Output_Ada_Common.Initialize
+ (Input_Data, Tuple, Grammar_File_Name, Check_Interface => False);
Gen_Alg_Name : constant String :=
(if Test_Main or Multiple_Tuples
@@ -57,8 +59,8 @@ is
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;
+ (Post_Parse_Action_Names : not null access WisiToken.Names_Array_Array;
+ In_Parse_Action_Names : not null access WisiToken.Names_Array_Array;
Label_Count : in Ada.Containers.Count_Type;
Package_Name : in String)
is
@@ -67,15 +69,14 @@ is
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);
Body_File : File_Type;
begin
- Create (Body_File, Out_File, File_Name);
+ Create (Body_File, Out_File, To_Lower (Package_Name) & ".adb");
+
Set_Output (Body_File);
Indent := 1;
Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
@@ -88,7 +89,7 @@ is
-- because some declared labels are not actually used in actions. The
-- user will have to add 'with SAL;' in a code declaration.
- if Input_Data.Check_Count > 0 then
+ if Input_Data.In_Parse_Action_Count > 0 then
-- For Match_Names etc
Indent_Line ("with WisiToken.In_Parse_Actions; use WisiToken.In_Parse_Actions;");
New_Line;
@@ -100,7 +101,7 @@ is
Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Pre));
- -- generate Action and Check subprograms.
+ -- generate Post_Parse_Action and In_Parse_Action subprograms.
for Rule of Input_Data.Tokens.Rules loop
-- No need for a Token_Cursor here, since we only need the
@@ -149,12 +150,12 @@ is
begin
for RHS of Rule.Right_Hand_Sides loop
- if Length (RHS.Action) > 0 then
+ if Length (RHS.Post_Parse_Action) > 0 then
declare
- Line : constant String := -RHS.Action;
+ Line : constant String := -RHS.Post_Parse_Action;
-- Actually multiple lines; we assume the formatting is adequate.
- Name : constant String := Action_Names (LHS_ID)(RHS_Index).all;
+ Name : constant String := Post_Parse_Action_Names (LHS_ID)(RHS_Index).all;
Unref_User_Data : Boolean := True;
Unref_Tree : Boolean := True;
@@ -212,11 +213,11 @@ is
end;
end if;
- if Length (RHS.Check) > 0 then
+ if Length (RHS.In_Parse_Action) > 0 then
declare
use Ada.Strings.Fixed;
- Line : constant String := -RHS.Check;
- Name : constant String := Check_Names (LHS_ID)(RHS_Index).all;
+ Line : constant String := -RHS.In_Parse_Action;
+ Name : constant String := In_Parse_Action_Names (LHS_ID)(RHS_Index).all;
Unref_Tree : constant Boolean := 0 = Index (Line, "Tree");
Unref_Nonterm : constant Boolean := 0 = Index (Line, "Nonterm");
Unref_Tokens : constant Boolean := 0 = Index (Line, "Tokens");
@@ -287,12 +288,12 @@ is
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";
+ -- This is lowercase to match the C name.
+ re2c_Package_Name : constant String := Output_File_Name_Root & "_re2c_c";
Body_File : File_Type;
begin
- Create (Body_File, Out_File, File_Name);
+ Create (Body_File, Out_File, To_Lower (Main_Package_Name) & ".adb");
Set_Output (Body_File);
Indent := 1;
@@ -348,13 +349,13 @@ is
LR_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data);
when Packrat_Gen =>
- WisiToken.BNF.Generate_Packrat (Packrat_Data, Generate_Data);
+ WisiToken.BNF.Generate_Packrat (Packrat_Data.all, Generate_Data);
Create_Create_Productions (Generate_Data);
- Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data);
+ Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data.all);
when Packrat_Proc =>
Create_Create_Productions (Generate_Data);
- Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data);
+ Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data.all);
when External =>
External_Create_Create_Grammar (Generate_Data);
@@ -368,7 +369,7 @@ is
Set_Output (Standard_Output);
end Create_Ada_Main_Body;
- procedure Create_Ada_Test_Main (Main_Package_Name : in String)
+ procedure Create_LR_Test_Main (Main_Package_Name : in String)
is
use WisiToken.Generate;
@@ -394,11 +395,9 @@ is
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);
+ Create (File, Out_File, To_Lower (Unit_Name) & ".ads");
Set_Output (File);
Indent := 1;
@@ -409,7 +408,7 @@ is
Put_Line ("with " & Main_Package_Name & ";");
if Common_Data.Generate_Algorithm in LR_Generate_Algorithm and
- Input_Data.Language_Params.Error_Recover and
+ Input_Data.Language_Params.Error_Recover and
Input_Data.Language_Params.Use_Language_Runtime
then
declare
@@ -425,6 +424,9 @@ is
end if;
Put_Line ("procedure " & Unit_Name & " is new " & Generic_Package_Name);
+ -- Just "Put" would be nicer here, but then we'd have to worry about
+ -- not outputing the leading spaces in the following. It's just a
+ -- test main.
Put_Line (" (");
case Common_Data.Generate_Algorithm is
when LR_Generate_Algorithm =>
@@ -450,7 +452,7 @@ is
end case;
Close (File);
Set_Output (Standard_Output);
- end Create_Ada_Test_Main;
+ end Create_LR_Test_Main;
begin
case Tuple.Interface_Kind is
@@ -464,29 +466,43 @@ begin
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";
+ Actions_Package_Name : constant String := File_Name_To_Ada (Output_File_Name_Root) &
+ (if Need_Gen_Alg_In_Actions_Name
+ then "_" & Generate_Algorithm_Image (Tuple.Gen_Alg).all
+ else "") &
+ "_Actions";
begin
- if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
- -- Some WisiToken tests have no actions or checks.
+ if Input_Data.Post_Parse_Action_Count > 0 or Input_Data.In_Parse_Action_Count > 0 then
+ -- Some WisiToken tests have no post_parse or in_parse actions.
Create_Ada_Actions_Body
- (Generate_Data.Action_Names, Generate_Data.Check_Names, Input_Data.Label_Count, Actions_Package_Name);
+ (Generate_Data.Post_Parse_Action_Names, Generate_Data.In_Parse_Action_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);
+ Create_Ada_Actions_Spec (Actions_Package_Name, Input_Data, Common_Data, Generate_Data);
- if Tuple.Gen_Alg = External then
+ case Tuple.Gen_Alg is
+ when None =>
+ null;
+
+ when External =>
Create_External_Main_Spec (Main_Package_Name, Tuple, Input_Data);
Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name, Input_Data);
- else
+
+ when LR_Generate_Algorithm | Packrat_Generate_Algorithm =>
Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name, Input_Data);
- Create_Ada_Main_Spec (To_Lower (Main_Package_Name) & ".ads", Main_Package_Name, Input_Data, Common_Data);
+ Create_Ada_Main_Spec (Main_Package_Name, Input_Data, Common_Data);
if Test_Main then
- Create_Ada_Test_Main (Main_Package_Name);
+ Create_LR_Test_Main (Main_Package_Name);
end if;
- end if;
+
+ when Tree_Sitter =>
+ -- FIXME: generate *_tree_sitter_main
+ WisiToken.Generate.Tree_Sitter.Create_Test_Main (Output_File_Name_Root);
+
+ end case;
end;
exception
diff --git a/wisitoken-bnf-output_ada_common.adb b/wisitoken-bnf-output_ada_common.adb
index 853b690..651036f 100644
--- a/wisitoken-bnf-output_ada_common.adb
+++ b/wisitoken-bnf-output_ada_common.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -86,11 +86,10 @@ package body WisiToken.BNF.Output_Ada_Common is
-- 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)
+ (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;
@@ -99,7 +98,7 @@ package body WisiToken.BNF.Output_Ada_Common is
Paren_Done : Boolean := False;
Cursor : Token_Cursor := First (Generate_Data);
begin
- Create (Spec_File, Out_File, Output_File_Name);
+ Create (Spec_File, Out_File, To_Lower (Package_Name) & ".ads");
Set_Output (Spec_File);
Indent := 1;
@@ -110,10 +109,10 @@ package body WisiToken.BNF.Output_Ada_Common is
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
+ if not (Input_Data.Post_Parse_Action_Count > 0 or Input_Data.In_Parse_Action_Count > 0) then
Put_Line ("with WisiToken;");
end if;
- if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
+ if Input_Data.Post_Parse_Action_Count > 0 or Input_Data.In_Parse_Action_Count > 0 then
Put_Line ("with WisiToken.Syntax_Trees;");
end if;
Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Context));
@@ -200,7 +199,7 @@ package body WisiToken.BNF.Output_Ada_Common is
end if;
- for Name_List of Generate_Data.Action_Names.all loop
+ for Name_List of Generate_Data.Post_Parse_Action_Names.all loop
if Name_List /= null then
for Name of Name_List.all loop
if Name /= null then
@@ -213,7 +212,7 @@ package body WisiToken.BNF.Output_Ada_Common is
end if;
end loop;
- for Name_List of Generate_Data.Check_Names.all loop
+ for Name_List of Generate_Data.In_Parse_Action_Names.all loop
if Name_List /= null then
for Name of Name_List.all loop
if Name /= null then
@@ -240,8 +239,7 @@ package body WisiToken.BNF.Output_Ada_Common is
end Create_Ada_Actions_Spec;
procedure Create_Ada_Main_Spec
- (Output_File_Name : in String;
- Main_Package_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
@@ -300,7 +298,7 @@ package body WisiToken.BNF.Output_Ada_Common is
raise SAL.Programmer_Error;
end if;
- Create (Spec_File, Out_File, Output_File_Name);
+ Create (Spec_File, Out_File, To_Lower (Main_Package_Name) & ".ads");
Set_Output (Spec_File);
Indent := 1;
@@ -383,10 +381,9 @@ package body WisiToken.BNF.Output_Ada_Common is
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);
+ Create (Spec_File, Out_File, To_Lower (Main_Package_Name) & ".ads");
Set_Output (Spec_File);
Indent := 1;
@@ -648,9 +645,9 @@ package body WisiToken.BNF.Output_Ada_Common is
end Create_LR_Parser_Table;
procedure LR_Create_Create_Parse_Table
- (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)
+ (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
Table : WisiToken.Parse.LR.Parse_Table_Ptr renames Generate_Data.LR_Parse_Table;
begin
@@ -706,9 +703,9 @@ package body WisiToken.BNF.Output_Ada_Common is
end LR_Create_Create_Parse_Table;
procedure LR_Create_Create_Parser
- (Actions_Package_Name : in String;
- Common_Data : in out Output_Ada_Common.Common_Data;
- Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data)
+ (Actions_Package_Name : in String;
+ Common_Data : in Output_Ada_Common.Common_Data;
+ Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data)
is
Parser_Type : constant String :=
"WisiToken.Parse.LR.Parser" &
@@ -765,10 +762,10 @@ package body WisiToken.BNF.Output_Ada_Common is
end LR_Create_Create_Parser;
procedure Packrat_Create_Create_Parser
- (Actions_Package_Name : in String;
- 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)
+ (Actions_Package_Name : in String;
+ Common_Data : in Output_Ada_Common.Common_Data;
+ Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data;
+ Packrat_Data : in WisiToken.Generate.Packrat.Data)
is
Descriptor : WisiToken.Descriptor renames Generate_Data.Descriptor.all;
@@ -841,7 +838,7 @@ package body WisiToken.BNF.Output_Ada_Common is
Indent := Indent - 3;
Indent_Line ("begin");
Indent := Indent + 3;
- WisiToken.BNF.Generate_Grammar (Generate_Data.Grammar, Generate_Data.Action_Names.all);
+ WisiToken.BNF.Generate_Grammar (Generate_Data.Grammar, Generate_Data.Post_Parse_Action_Names.all);
Indent_Line
("return Parser : WisiToken.Parse.Packrat.Procedural.Parser (" &
@@ -873,7 +870,7 @@ package body WisiToken.BNF.Output_Ada_Common is
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);
+ WisiToken.BNF.Generate_Grammar (Generate_Data.Grammar, Generate_Data.Post_Parse_Action_Names.all);
Indent := Indent - 3;
Indent_Line ("end return;");
Indent := Indent - 3;
@@ -906,8 +903,8 @@ package body WisiToken.BNF.Output_Ada_Common is
Actions_Present := True;
end if;
- if Generate_Data.Check_Names (P.LHS) /= null or
- Generate_Data.Action_Names (P.LHS) /= null
+ if Generate_Data.In_Parse_Action_Names (P.LHS) /= null or
+ Generate_Data.Post_Parse_Action_Names (P.LHS) /= null
then
Indent_Line
("Result (" & Trimmed_Image (P.LHS) & ").RHSs.Set_First_Last (" &
@@ -915,7 +912,7 @@ package body WisiToken.BNF.Output_Ada_Common is
Trimmed_Image (P.RHSs.Last_Index) & ");");
for J in P.RHSs.First_Index .. P.RHSs.Last_Index loop
- if Generate_Data.Check_Names (P.LHS) = null then
+ if Generate_Data.In_Parse_Action_Names (P.LHS) = null then
Indent_Line
("Result (" & Trimmed_Image (P.LHS) & ").RHSs (" & Trimmed_Image (J) &
").In_Parse_Action := null;");
@@ -923,11 +920,11 @@ package body WisiToken.BNF.Output_Ada_Common is
Actions_Present := True;
Indent_Line
("Result (" & Trimmed_Image (P.LHS) & ").RHSs (" & Trimmed_Image (J) & ").In_Parse_Action := " &
- (if Generate_Data.Check_Names (P.LHS)(J) = null then "null"
- else Generate_Data.Check_Names (P.LHS)(J).all & "'Access") &
+ (if Generate_Data.In_Parse_Action_Names (P.LHS)(J) = null then "null"
+ else Generate_Data.In_Parse_Action_Names (P.LHS)(J).all & "'Access") &
";");
end if;
- if Generate_Data.Action_Names (P.LHS) = null then
+ if Generate_Data.Post_Parse_Action_Names (P.LHS) = null then
Indent_Line
("Result (" & Trimmed_Image (P.LHS) & ").RHSs (" & Trimmed_Image (J) &
").Post_Parse_Action := null;");
@@ -936,8 +933,8 @@ package body WisiToken.BNF.Output_Ada_Common is
Indent_Line
("Result (" & Trimmed_Image (P.LHS) & ").RHSs (" & Trimmed_Image (J) &
").Post_Parse_Action := " &
- (if Generate_Data.Action_Names (P.LHS)(J) = null then "null"
- else Generate_Data.Action_Names (P.LHS)(J).all & "'Access") &
+ (if Generate_Data.Post_Parse_Action_Names (P.LHS)(J) = null then "null"
+ else Generate_Data.Post_Parse_Action_Names (P.LHS)(J).all & "'Access") &
";");
end if;
end loop;
@@ -1349,9 +1346,8 @@ package body WisiToken.BNF.Output_Ada_Common is
Close (File);
declare
+ -- This is lowercase to match the C file.
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);
@@ -1447,7 +1443,7 @@ package body WisiToken.BNF.Output_Ada_Common is
Kind (Generate_Data, I) = "comment-one-line" or
Kind (Generate_Data, I) = "string-double-one-line" or
Kind (Generate_Data, I) = "string-single-one-line"
- -- comment-one-line, strings do not always contain a new_line, but
+ -- comment-one-line strings do not always contain a new_line, but
-- the preconditions in WisiToken.Lexer guarantee it does if we ask
-- for Line_Begin_Char_Pos from one.
then
@@ -2105,7 +2101,6 @@ package body WisiToken.BNF.Output_Ada_Common is
(Input_Data : in WisiToken_Grammar_Runtime.User_Data_Type;
Tuple : in Generate_Tuple;
Grammar_File_Name : in String;
- Output_File_Root : in String;
Check_Interface : in Boolean)
return Common_Data
is begin
@@ -2132,8 +2127,6 @@ package body WisiToken.BNF.Output_Ada_Common is
end if;
Data.Text_Rep := Tuple.Text_Rep;
-
- Data.Lower_File_Name_Root := +To_Lower (Output_File_Root);
end return;
end Initialize;
diff --git a/wisitoken-bnf-output_ada_common.ads b/wisitoken-bnf-output_ada_common.ads
index 005cfdc..10a4d72 100644
--- a/wisitoken-bnf-output_ada_common.ads
+++ b/wisitoken-bnf-output_ada_common.ads
@@ -2,7 +2,7 @@
--
-- Types and operations shared by Ada and Ada_Emacs outputs.
--
--- Copyright (C) 2017, 2018, 2020 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017, 2018, 2020 - 2023 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
@@ -31,30 +31,25 @@ package WisiToken.BNF.Output_Ada_Common is
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;
Grammar_File_Name : in String;
- 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);
+ (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;
+ (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;
@@ -65,23 +60,23 @@ package WisiToken.BNF.Output_Ada_Common is
Input_Data : in WisiToken_Grammar_Runtime.User_Data_Type);
procedure LR_Create_Create_Parse_Table
- (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);
+ (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);
-- 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 LR_Create_Create_Parser
- (Actions_Package_Name : in String;
- Common_Data : in out Output_Ada_Common.Common_Data;
- Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data);
+ (Actions_Package_Name : in String;
+ Common_Data : in Output_Ada_Common.Common_Data;
+ Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data);
procedure Packrat_Create_Create_Parser
- (Actions_Package_Name : in String;
- 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);
+ (Actions_Package_Name : in String;
+ Common_Data : in 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);
diff --git a/wisitoken-bnf-output_ada_emacs.adb b/wisitoken-bnf-output_ada_emacs.adb
index 7d386ae..0dd2ed7 100644
--- a/wisitoken-bnf-output_ada_emacs.adb
+++ b/wisitoken-bnf-output_ada_emacs.adb
@@ -12,7 +12,7 @@
-- If run in an Emacs dynamically loaded module, the parser actions
-- call the elisp actions directly.
--
--- Copyright (C) 2012 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2012 - 2015, 2017 - 2023 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
@@ -28,6 +28,7 @@
pragma License (Modified_GPL);
+with Ada.Assertions;
with Ada.Exceptions;
with Ada.Strings.Fixed;
with Ada.Strings.Maps;
@@ -39,15 +40,16 @@ 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;
- Grammar_File_Name : in String;
- 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)
+ (Input_Data : in WisiToken_Grammar_Runtime.User_Data_Type;
+ Grammar_File_Name : in String;
+ Output_File_Name_Root : in String;
+ Generate_Data : aliased in WisiToken.BNF.Generate_Utils.Generate_Data;
+ Packrat_Data : in WisiToken.Generate.Packrat.Data_Access;
+ Tuple : in Generate_Tuple;
+ Test_Main : in Boolean;
+ Multiple_Tuples : in Boolean;
+ Need_Gen_Alg_In_Actions_Name : in Boolean;
+ Language_Name : in String)
is
use all type Ada.Containers.Count_Type;
@@ -56,8 +58,8 @@ is
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, Grammar_File_Name, Output_File_Name_Root, Check_Interface => True);
+ Common_Data : constant Output_Ada_Common.Common_Data := WisiToken.BNF.Output_Ada_Common.Initialize
+ (Input_Data, Tuple, Grammar_File_Name, Check_Interface => True);
Gen_Alg_Name : constant String :=
(if Test_Main or Multiple_Tuples
@@ -159,17 +161,23 @@ is
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;
- Empty : out Boolean;
- Check : in Boolean)
+ (Name : in String;
+ RHS : in RHS_Type;
+ Prod_ID : in WisiToken.Production_ID;
+ Unsplit_Lines : in Ada.Strings.Unbounded.Unbounded_String;
+ Rule : in BNF.Rule_Type;
+ Empty : out Boolean;
+ In_Parse_Action : 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 all type SAL.Base_Peek_Type;
+
+ -- Create Post_Parse_Action (if In_Parse_Action = False; Lines must
+ -- be RHS.Action) or In_Parse_Action (if In_Parse_Action = True;
+ -- Lines must be RHS.In_Parse_Action) subprogram named Name for RHS.
+ --
+ -- Labels is collection of all labels used in any RHS in the nonterm;
+ -- _not_ in RHS token order. RHS.Tokens(I).Label contains explicit
+ -- and automatic token labels.
use Ada.Strings;
use Ada.Strings.Fixed;
@@ -184,38 +192,72 @@ is
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;
+ Navigate_Lines : String_Lists.List;
+ Face_Line : Unbounded_String;
+ Indent_Action_Line : Unbounded_String;
+ In_Parse_Action_Line : Unbounded_String;
- Label_Needed : array (Labels.First_Index .. Labels.Last_Index) of Boolean := (others => False);
+ Label_Needed : array (Rule.Labels.First_Index .. Rule.Labels.Last_Index) of Boolean := (others => False);
Nonterm_Needed : Boolean := False;
- Last_Token_Index : Base_Identifier_Index := 0;
- function Next_Token_Label return String
- is begin
- -- Only called from Indent_Params when RHS.Auto_Token_Labels is True.
- Last_Token_Index := @ + 1;
- return "T" & Trimmed_Image (Last_Token_Index);
- end Next_Token_Label;
+ function Find_RHS (RHS_Index : in Natural) return RHS_Lists.Cursor
+ is
+ use RHS_Lists;
+ Result : Cursor := Rule.Right_Hand_Sides.First;
+ begin
+ for I in 1 .. RHS_Index loop
+ Next (Result);
+ end loop;
+ return Result;
+ end Find_RHS;
+
+ EBNF_RHS : RHS_Type renames RHS_Lists.Element (Find_RHS (RHS.EBNF_RHS_Index));
function Get_Label (Token_Param : in String; Integer : in Boolean := False) return String
- is begin
+ is
+ function Finish (Label : in String; Force_Integer : in Boolean) return String
+ is (if Force_Integer
+ then "Integer (" & Label & ")"
+ else Label);
+
+ begin
if RHS.Auto_Token_Labels then
- return
- (if Integer
- then "Integer (T" & Token_Param & ")"
- else "T" & Token_Param);
+ if 0 = Index (Token_Param, Numeric, Outside) then
+ -- Token_param is an integer token index, not a label
+ begin
+ declare
+ Index : constant Positive_Index_Type := Positive_Index_Type'Value (Token_Param);
+ Label : constant String := -EBNF_RHS.Tokens (Index).Label;
+ begin
+ if Label'Length = 0 then
+ return Finish (Token_Param, Force_Integer => False);
+ else
+ return Finish (Label, Force_Integer => Integer);
+ end if;
+ end;
+ exception
+ when Ada.Assertions.Assertion_Error | Constraint_Error =>
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line,
+ "token index '" & Token_Param & "' not in range" & EBNF_RHS.Tokens.First_Index'Image &
+ " .." & EBNF_RHS.Tokens.Last_Index'Image));
+ return "";
+ end;
+ else
+ -- Token_Param is a label
+ return Finish (Token_Param, Force_Integer => Integer);
+ end if;
else
- return Token_Param;
+ return Finish
+ (Token_Param, Force_Integer => Integer and then (0 /= Index (Token_Param, Numeric, Outside)));
end if;
end Get_Label;
procedure Mark_Label_Used (Label : in String)
is begin
- for I in Labels.First_Index .. Labels.Last_Index loop
- if Label = Labels (I) then
+ for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index loop
+ if Label = Rule.Labels (I) then
Label_Needed (I) := True;
end if;
end loop;
@@ -241,8 +283,8 @@ is
return False;
end if;
- for I in Labels.First_Index .. Labels.Last_Index loop
- if Label = Labels (I) then
+ for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index loop
+ if Label = Rule.Labels (I) then
Label_Needed (I) := True;
return True;
end if;
@@ -252,7 +294,7 @@ is
function Find_Token_Index (I : in Base_Identifier_Index) return SAL.Base_Peek_Type
is
- Rule_Label : constant String := -Labels (I);
+ Rule_Label : constant String := -Rule.Labels (I);
begin
for I in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index loop
if Length (RHS.Tokens (I).Label) > 0 and then
@@ -585,7 +627,7 @@ is
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:
+ -- Params is a vector, one item for each token in EBNF tokens. Each item is one of:
--
-- - an integer; copy to output
--
@@ -596,6 +638,11 @@ is
-- - a vector with two elements [code_indent comment_indent]; convert to Indent_Pair.
--
-- - a cons of a token label with any of the above.
+ --
+ -- When EBNF is converted to BNF, one ENBF RHS is typically expanded
+ -- to several RHS, each missing some tokens. However, the action
+ -- still has indent parameters for all of the original tokens. They
+ -- are matched by the token labels.
use Ada.Strings.Maps;
use Ada.Containers;
@@ -777,7 +824,7 @@ is
Declared_Args_Last := Declared_Args'Last;
end if;
- Declared_Arg_Count := Count_Type'Value
+ Declared_Arg_Count := Count_Type'Value
(Declared_Args (Declared_Args_First .. Declared_Args_Last));
Get_Next_Token_Arg;
@@ -900,16 +947,25 @@ is
end if;
end Ensure_Indent_Param;
- Param_Label_Count : Ada.Containers.Count_Type := 0;
+ RHS_Token_Index : SAL.Base_Peek_Type := RHS.Tokens.First_Index; -- Index of current token in current RHS.
- procedure One_Param (Label : in String := "")
+ Param_Index : SAL.Base_Peek_Type := 1; -- Index of current indent parameter.
+
+ procedure One_Param (Skip : in Boolean; Label : in String := "")
+ -- If not Skip, current indent param is for a token actually in RHS; add it to
+ -- Param_List.
+ --
+ -- If Skip, current indent param is not in RHS; parse the param but
+ -- don't add it.
+ --
+ -- Label is non-"" only for recursive calls.
is
Pair : String_Pair_Type;
begin
- if Label = "" then
- if RHS.Auto_Token_Labels then
- Pair.Name := +Next_Token_Label;
- end if;
+ if Skip then
+ Pair.Name := +"";
+ elsif Label = "" then
+ Pair.Name := RHS.Tokens (RHS_Token_Index).Label;
else
Pair.Name := +Label;
end if;
@@ -922,14 +978,12 @@ is
begin
if Label_Last > 0 then
-- cons; manual label
- pragma Assert (not RHS.Auto_Token_Labels);
declare
Label : constant String := Params (Last + 1 .. Label_Last);
begin
Last := Index_Non_Blank (Params, Label_Last + 3);
- One_Param (Label);
+ One_Param (Skip, Label);
end;
- Param_Label_Count := @ + 1;
if Params (Last) /= ')' then
Put_Error
@@ -941,7 +995,9 @@ is
else
-- function
Pair.Value := +"(False, " & Ensure_Indent_Param (Expression (Last)) & ')';
- Param_List.Append (Pair);
+ if not Skip then
+ Param_List.Append (Pair);
+ end if;
end if;
end;
@@ -950,8 +1006,9 @@ is
Pair.Value := +"(True, " & Ensure_Indent_Param (Expression (Last + 1));
Pair.Value := @ & ", " & Ensure_Indent_Param (Expression (Last + 1)) & ')';
- Param_List.Append (Pair);
-
+ if not Skip then
+ Param_List.Append (Pair);
+ end if;
if Params (Last) /= ']' then
Put_Error
(Error_Message
@@ -962,7 +1019,9 @@ is
when others =>
-- integer or symbol
Pair.Value := +"(False, " & Ensure_Indent_Param (Expression (Last)) & ')';
- Param_List.Append (Pair);
+ if not Skip then
+ Param_List.Append (Pair);
+ end if;
end case;
end One_Param;
@@ -978,25 +1037,51 @@ is
exit when Params (Last) = ']';
- One_Param;
+ if RHS_Token_Index > EBNF_RHS.Tokens.Last_Index then
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, Image (Prod_ID, Generate_Data.Descriptor.all)) &
+ " extra indent parameters");
+ exit;
+ end if;
+ if RHS.Orig_EBNF_RHS or else
+ (RHS_Token_Index <= RHS.Tokens.Last_Index and then
+ RHS.Tokens (RHS_Token_Index).Orig_Token_Index = Param_Index)
+ then
+ One_Param (Skip => False);
+ RHS_Token_Index := @ + 1;
+ else
+ One_Param (Skip => True);
+ end if;
+ Param_Index := @ + 1;
+
end loop;
- -- Now we have Param_List; match it against RHS.Tokens and create Result.
+ if RHS.Orig_EBNF_RHS and Param_Index < EBNF_RHS.Tokens.Last_Index then
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, Image (Prod_ID, Generate_Data.Descriptor.all)) &
+ " missing indent parameters");
+ end if;
- if RHS.Auto_Token_Labels or Param_Label_Count = Param_List.Length then
- -- All tokens are either manually or automatically labeled, and if
- -- manual then all parameters are manually labeled, and we can detect
- -- extra params in edited RHS.
+ if RHS.Auto_Token_Labels then
+ -- If the original RHS had any EBNF, all tokens are either manually
+ -- or automatically labeled and RHS.Auto_Token_Labels is true.
+ -- Otherwise RHS.Auto_Token_Labels is False.
declare
use String_Pair_Lists;
- use all type SAL.Base_Peek_Type;
Token_I : Positive_Index_Type := RHS.Tokens.First_Index;
Param_Cur : String_Pair_Lists.Cursor := Param_List.First;
- Param_I : Positive_Index_Type := RHS.Tokens.First_Index;
-
- Nil_Indent : constant String := "(False, (Simple, (Label => None)))";
begin
+ if not Has_Element (Param_Cur) then
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name,
+ RHS.Source_Line, "empty param_list"));
+ raise SAL.Programmer_Error;
+ end if;
+
loop
exit when Token_I > RHS.Tokens.Last_Index or not Has_Element (Param_Cur);
@@ -1004,59 +1089,36 @@ is
Token_Label : constant String := -RHS.Tokens (Token_I).Label;
Param_Label : constant String := -Element (Param_Cur).Name;
begin
- if Token_Label = Param_Label then
- Result := Result & (if Need_Comma then ", " else "") & Param_Label & " => " &
- Element (Param_Cur).Value;
-
- Mark_Label_Used (Token_Label);
-
- Need_Comma := True;
+ if Token_Label'Length = 0 and then Param_Label'Length = 0 then
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, Image (Prod_ID, Generate_Data.Descriptor.all)) &
+ " missing or misplaced indent label");
+ end if;
- Token_I := @ + 1;
- Next (Param_Cur);
- Param_I := @ + 1;
+ -- IMPROVEME: if there is a manual param label, verify that there is
+ -- a matching token label.
+ Result := Result &
+ (if Need_Comma then ", " else "") &
+ (if Token_Label'Length > 0 then Token_Label else Param_Label) & " => " &
+ Element (Param_Cur).Value;
- elsif RHS.Auto_Token_Labels and
- (Token_Label'Length > 0 and then Token_Label (1) /= 'T') and
- Token_I = Param_I
- then
- Result := Result & (if Need_Comma then ", " else "") & Token_Label & " => " & Nil_Indent;
- Mark_Label_Used (Token_Label);
- Need_Comma := True;
+ Mark_Label_Used (Token_Label);
- Token_I := @ + 1;
- Next (Param_Cur);
- Param_I := @ + 1;
+ Need_Comma := True;
- else
- Next (Param_Cur);
- Param_I := @ + 1;
- end if;
+ Token_I := @ + 1;
+ Next (Param_Cur);
end;
end loop;
-
- if (not RHS.Edited_Token_List or Prod_ID.RHS = 0) and then
- (Token_I /= RHS.Tokens.Last_Index + 1 or Has_Element (Param_Cur))
- then
- -- We don't check 'Has_Element (Param_Cur)' when edited_token_list
- -- and RHS_Index /= 0, because we expect to have more params than
- -- tokens. RHS_Index = 0 always has all optional tokens.
- if RHS.Auto_Token_Labels then
- Put_Error
- (Error_Message
- (Grammar_File_Name, RHS.Source_Line, Image (Prod_ID, Generate_Data.Descriptor.all)) &
- (if Token_I <= RHS.Tokens.Last_Index then " missing" else " extra") & " indent parameters");
- else
- Put_Error
- (Error_Message
- (Grammar_File_Name, RHS.Source_Line, Image (Prod_ID, Generate_Data.Descriptor.all) &
- ": missing or extra indent parameter, or missing token label"));
- end if;
- end if;
end;
else
- -- No labels; assume Param_List is correct.
+ -- No auto labels; ignore manual labels and assume Param_List is
+ -- correct. IMPROVEME: We could check that manual labels match
+ -- between the RHS and the action. IMPROVEME: if all specified params
+ -- have manual labels, allow indent for remaining tokens to default
+ -- to nil.
for Pair of Param_List loop
Result := Result & (if Need_Comma then ", " else "") & Pair.Value;
Need_Comma := True;
@@ -1065,7 +1127,7 @@ is
Nonterm_Needed := True;
if Param_List.Length = 1 then
- Result := Prefix & "1 => " & Result;
+ Result := Prefix & (if RHS.Auto_Token_Labels then "" else "1 => ") & Result;
else
Result := Prefix & Result;
end if;
@@ -1108,16 +1170,33 @@ is
Label_Second : constant String := Get_Label (Params (Second + 1 .. Params'Last - 1));
Label_Used_First : constant Boolean := Label_Used (Label_First);
Label_Used_Second : constant Boolean := Label_Used (Label_Second);
+
+ Result : Unbounded_String := +" (Tree, Tokens, ";
begin
- if Label_Used_First and Label_Used_Second then
- return " (Tree, Tokens, " &
- Label_First & ", " & Label_Second & ", " &
- (if Length (Input_Data.Language_Params.End_Names_Optional_Option) > 0
- then -Input_Data.Language_Params.End_Names_Optional_Option
- else "False") & ")";
+ -- Match_Names accepts 0 for absent token
+
+ if Label_Used_First then
+ Append (Result, Label_First);
else
- return "";
+ Append (Result, "0");
end if;
+ Append (Result, ", ");
+
+ if Label_Used_Second then
+ Append (Result, Label_Second);
+ else
+ Append (Result, "0");
+ end if;
+ Append (Result, ", ");
+
+ if Length (Input_Data.Language_Params.End_Names_Optional_Option) > 0 then
+ Append (Result, -Input_Data.Language_Params.End_Names_Optional_Option);
+ else
+ Append (Result, "False");
+ end if;
+ Append (Result, ")");
+
+ return -Result;
end Match_Names_Params;
function Language_Action_Params (Params : in String; Action_Name : in String) return String
@@ -1185,18 +1264,18 @@ is
end if;
end Assert_Indent_Empty;
- procedure Assert_Check_Empty
+ procedure Assert_In_Parse_Action_Empty
is begin
- if Length (Check_Line) > 0 then
+ if Length (In_Parse_Action_Line) > 0 then
Put_Error
(Error_Message
- (Grammar_File_Name, RHS.Source_Line, "multiple check actions"));
+ (Grammar_File_Name, RHS.Source_Line, "multiple in_parse actions"));
end if;
- end Assert_Check_Empty;
+ end Assert_In_Parse_Action_Empty;
begin
-- wisi action/check functions, in same order as typically used in
- -- .wy files; Navigate, Face, Indent, Check.
+ -- .wy files; Navigate, Face, Indent, actions.
if Elisp_Name = "wisi-statement-action" then
declare
Params : constant String := Statement_Params (Line (Last + 1 .. Line'Last));
@@ -1286,16 +1365,16 @@ is
Label : constant String := Get_Label (Line (Last + 1 .. Line'Last - 1));
begin
if Label_Used (Label) then
- Assert_Check_Empty;
+ Assert_In_Parse_Action_Empty;
Nonterm_Needed := True;
- Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, Trim => 5) &
+ In_Parse_Action_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, Trim => 5) &
" (Tree, Nonterm, Tokens, " & Label & ");";
end if;
end;
elsif Elisp_Name = "wisi-merge-names" then
- Assert_Check_Empty;
- Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, Trim => 5) &
+ Assert_In_Parse_Action_Empty;
+ In_Parse_Action_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
@@ -1303,16 +1382,17 @@ is
Params : constant String := Match_Names_Params (Line (Last + 1 .. Line'Last));
begin
if Params'Length > 0 then
- Assert_Check_Empty;
- Check_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, Trim => 5) &
+ Assert_In_Parse_Action_Empty;
+ In_Parse_Action_Line := +"return " & Elisp_Name_To_Ada (Elisp_Name, False, Trim => 5) &
Params & ";";
end if;
end;
elsif Elisp_Name = "wisi-terminate-partial-parse" then
- Assert_Check_Empty;
+ Assert_In_Parse_Action_Empty;
Nonterm_Needed := True;
- Check_Line := +"return Terminate_Partial_Parse (Tree, Partial_Parse_Active, Partial_Parse_Byte_Goal, " &
+ In_Parse_Action_Line :=
+ +"return Terminate_Partial_Parse (Tree, Partial_Parse_Active, Partial_Parse_Byte_Goal, " &
"Recover_Active, Nonterm);";
elsif Input_Data.Tokens.Actions.Contains (+Elisp_Name) then
@@ -1370,12 +1450,23 @@ is
Put_Error
(Error_Message
(Grammar_File_Name, RHS.Source_Line, Ada.Exceptions.Exception_Message (E)));
+
+ when E : others =>
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, "RHS: '" & Image (RHS.Tokens)));
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, "... Sexp: '" & Sexp));
+ Put_Error
+ (Error_Message
+ (Grammar_File_Name, RHS.Source_Line, "... " & Ada.Exceptions.Exception_Message (E)));
+ raise;
end;
end loop;
- if Check then
- -- In an in-parse check action
- if Length (Check_Line) = 0 then
+ if In_Parse_Action then
+ if Length (In_Parse_Action_Line) = 0 then
Empty := True; -- don't output a spec for this.
else
@@ -1388,10 +1479,10 @@ is
Indent_Line (" Recover_Active : in Boolean)");
Indent_Line (" return WisiToken.Syntax_Trees.In_Parse_Actions.Status");
declare
- Unref_Tree : constant Boolean := 0 = Index (Check_Line, "Tree");
- 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");
+ Unref_Tree : constant Boolean := 0 = Index (In_Parse_Action_Line, "Tree");
+ Unref_Nonterm : constant Boolean := 0 = Index (In_Parse_Action_Line, "Nonterm");
+ Unref_Tokens : constant Boolean := 0 = Index (In_Parse_Action_Line, "Tokens");
+ Unref_Recover : constant Boolean := 0 = Index (In_Parse_Action_Line, "Recover_Active");
Need_Comma : Boolean := False;
begin
if Unref_Tree or Unref_Nonterm or Unref_Tokens or Unref_Recover or
@@ -1425,7 +1516,7 @@ is
for I in Label_Needed'Range loop
if Label_Needed (I) then
Indent_Line
- (-Labels (I) & " : constant SAL.Peek_Type :=" &
+ (-Rule.Labels (I) & " : constant SAL.Peek_Type :=" &
SAL.Peek_Type'Image (Find_Token_Index (I)) & ";");
end if;
end loop;
@@ -1437,7 +1528,7 @@ is
end if;
end;
Indent := Indent + 3;
- Indent_Line (-Check_Line);
+ Indent_Line (-In_Parse_Action_Line);
end if;
else
-- In an action
@@ -1460,7 +1551,7 @@ is
for I in Label_Needed'Range loop
if Label_Needed (I) then
Indent_Line
- (-Labels (I) & " : constant SAL.Peek_Type :=" &
+ (-Rule.Labels (I) & " : constant SAL.Peek_Type :=" &
SAL.Peek_Type'Image (Find_Token_Index (I)) & ";");
end if;
end loop;
@@ -1513,7 +1604,7 @@ is
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, Grammar_File_Name, RHS.Source_Line) loop
+ for Sexp of Split_Sexp (-RHS.Post_Parse_Action, Grammar_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);
@@ -1529,20 +1620,16 @@ is
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)
+ (Post_Parse_Action_Names : not null access WisiToken.Names_Array_Array;
+ In_Parse_Action_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";
+ File_Name : constant String := To_Lower (Package_Name) & ".adb";
Motion_Actions : constant Boolean := Any_Motion_Actions;
@@ -1573,7 +1660,7 @@ is
end;
end if;
- if Input_Data.Check_Count > 0 then
+ if Input_Data.In_Parse_Action_Count > 0 then
Indent_Line ("with WisiToken.In_Parse_Actions; use WisiToken.In_Parse_Actions;"); -- Match_Names etc.
end if;
case Common_Data.Interface_Kind is
@@ -1590,7 +1677,7 @@ is
Indent := Indent + 3;
New_Line;
- if Input_Data.Check_Count > 0 then
+ if Input_Data.In_Parse_Action_Count > 0 then
Indent_Line ("use WisiToken.Syntax_Trees.In_Parse_Actions;");
end if;
if Motion_Actions then
@@ -1598,35 +1685,43 @@ is
end if;
New_Line;
- -- generate Action and Check subprograms.
+ -- generate Post_Parse_Action and In_Parse_Action 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
+ RHS_Index : Integer := 0;
Empty : Boolean;
begin
for RHS of Rule.Right_Hand_Sides loop
- if Length (RHS.Action) > 0 then
+ if Length (RHS.Post_Parse_Action) > 0 then
declare
- Name : constant String := Action_Names (LHS_ID)(RHS_Index).all;
+ Name : constant String := Post_Parse_Action_Names (LHS_ID)(RHS_Index).all;
begin
- Create_Ada_Action (Name, RHS, (LHS_ID, RHS_Index), RHS.Action, Rule.Labels, Empty, Check => False);
+ Create_Ada_Action
+ (Name, RHS, (LHS_ID, RHS_Index), RHS.Post_Parse_Action, Rule, Empty,
+ In_Parse_Action => False);
if Empty then
- Action_Names (LHS_ID)(RHS_Index) := null;
+ Post_Parse_Action_Names (LHS_ID)(RHS_Index) := null;
end if;
+ exception
+ when others =>
+ Put_Error (Error_Message (Grammar_File_Name, RHS.Source_Line, "fatal internal error"));
+ raise;
end;
end if;
- if Length (RHS.Check) > 0 then
+ if Length (RHS.In_Parse_Action) > 0 then
declare
- Name : constant String := Check_Names (LHS_ID)(RHS_Index).all;
+ Name : constant String := In_Parse_Action_Names (LHS_ID)(RHS_Index).all;
begin
- Create_Ada_Action (Name, RHS, (LHS_ID, RHS_Index), RHS.Check, Rule.Labels, Empty, Check => True);
+ Create_Ada_Action
+ (Name, RHS, (LHS_ID, RHS_Index), RHS.In_Parse_Action, Rule, Empty,
+ In_Parse_Action => True);
if Empty then
- Check_Names (LHS_ID)(RHS_Index) := null;
+ In_Parse_Action_Names (LHS_ID)(RHS_Index) := null;
end if;
end;
end if;
@@ -1649,10 +1744,9 @@ is
use WisiToken.Generate;
use Generate_Utils;
- File_Name : constant String := To_Lower (Main_Package_Name) & ".adb";
Body_File : File_Type;
begin
- Create (Body_File, Out_File, File_Name);
+ Create (Body_File, Out_File, To_Lower (Main_Package_Name) & ".adb");
Set_Output (Body_File);
Indent := 1;
@@ -1708,13 +1802,13 @@ is
LR_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data);
when Packrat_Gen =>
- WisiToken.BNF.Generate_Packrat (Packrat_Data, Generate_Data);
+ WisiToken.BNF.Generate_Packrat (Packrat_Data.all, Generate_Data);
Create_Create_Productions (Generate_Data);
- Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data);
+ Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data.all);
when Packrat_Proc =>
Create_Create_Productions (Generate_Data);
- Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data);
+ Packrat_Create_Create_Parser (Actions_Package_Name, Common_Data, Generate_Data, Packrat_Data.all);
when External =>
External_Create_Create_Grammar (Generate_Data);
@@ -1796,24 +1890,32 @@ is
File : File_Type;
+ File_Name_Root : constant String := Output_File_Name_Root &
+ "-process" &
+ (if Need_Gen_Alg_In_Actions_Name
+ then "-" & To_Lower (Tuple.Gen_Alg'Image)
+ else "");
+
+ File_Name : constant String := File_Name_Root & ".el";
+
Paren_1_Done : Boolean := False;
begin
- Create (File, Out_File, Output_File_Name_Root & "-process.el");
+ Create (File, Out_File, File_Name);
+
Set_Output (File);
Indent := 1;
-- We can't use Put_File_Header here because it does not output the
-- file name.
Put_Line
- (";;; " & Output_File_Name_Root &
- "-process.el --- Generated parser support file -*- buffer-read-only:t lexical-binding:t -*-");
+ (";;; " & File_Name & " --- Generated parser support file -*- buffer-read-only:t 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_Line ("(defconst " & File_Name_Root & "-token-table");
Indent_Start (" [");
Indent := Indent + 3;
for Cursor in All_Tokens (Generate_Data).Iterate loop
@@ -1829,15 +1931,14 @@ is
Indent := Indent - 3;
New_Line;
- Output_Elisp_Common.Indent_Name_Table
- (Output_File_Name_Root, "process-face-table", Input_Data.Tokens.Faces);
+ Output_Elisp_Common.Indent_Name_Table (File_Name_Root, "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);
+ Output_Elisp_Common.Indent_Repair_Image (File_Name_Root, "", Input_Data.Tokens);
New_Line;
- Put_Line ("(provide '" & Output_File_Name_Root & "-process)");
+ Put_Line ("(provide '" & File_Name_Root & ")");
Set_Output (Standard_Output);
Close (File);
@@ -1849,8 +1950,6 @@ is
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
@@ -1894,30 +1993,30 @@ is
New_Line;
Indent_Line
- ("(cl-defstruct (" & Lower_Package_Name_Root &
+ ("(cl-defstruct (" & Output_File_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 ("(defun " & Output_File_Name_Root & "-wisi-module-parser-make (dll-name)");
Indent_Line (" (module-load dll-name)");
- Indent_Line (" (make-" & Lower_Package_Name_Root & "-wisi-module-parser))");
+ Indent_Line (" (make-" & Output_File_Name_Root & "-wisi-module-parser))");
New_Line;
- Indent_Line ("(defvar " & Lower_Package_Name_Root & "-module-lexer nil)");
+ Indent_Line ("(defvar " & Output_File_Name_Root & "-module-lexer nil)");
Indent_Line
("(declare-function " &
- Lower_Package_Name_Root &
+ Output_File_Name_Root &
"-wisi-module-parse """ &
- Lower_Package_Name_Root &
+ Output_File_Name_Root &
"-wisi-module-parse.c"")");
New_Line;
Indent_Line
("(cl-defmethod wisi-parse-current ((parser " &
- Lower_Package_Name_Root &
+ Output_File_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)))");
+ Indent_Line ("(let* ((wisi-lexer " & Output_File_Name_Root & "-module-lexer)");
+ Indent_Line (" (result (" & Output_File_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");
@@ -1935,8 +2034,7 @@ is
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);
+ Package_Name_Root : constant String := File_Name_To_Ada (Output_File_Name_Root);
File : File_Type;
begin
@@ -1960,13 +2058,13 @@ is
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_Line ("""" & Output_File_Name_Root & "_module.adb"",");
+ Indent_Line ("""" & Output_File_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_Name use """ & Output_File_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
@@ -1982,12 +2080,12 @@ is
-- '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 (" for Switches (""" & Output_File_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 (" for Switches (""" & Output_File_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"");");
@@ -2013,7 +2111,7 @@ is
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 (" for Project_files use (""" & Output_File_Name_Root & "_wisi_module_parse.gpr"");");
Indent_Line ("end " & Package_Name_Root & "_Wisi_Module_Parse_Agg;");
Set_Output (Standard_Output);
Close (File);
@@ -2028,22 +2126,22 @@ is
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 ("extern int " & Output_File_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 ("extern emacs_value " & Output_File_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 (" return " & Output_File_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 &
+ (" env->bind_function (env, """ & Output_File_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 (" return " & Output_File_Name_Root & "_wisi_module_parse_init (env);");
Indent_Line ("}");
Set_Output (Standard_Output);
Close (File);
@@ -2053,8 +2151,12 @@ begin
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");
+ when Process => "_Process",
+ when Module => "_Module") &
+ (if Need_Gen_Alg_In_Actions_Name
+ then "_" & Generate_Algorithm_Image (Tuple.Gen_Alg).all
+ else "") &
+ "_Actions";
Main_Package_Name : constant String := File_Name_To_Ada (Output_File_Name_Root) &
(case Common_Data.Interface_Kind is
@@ -2062,21 +2164,18 @@ begin
when Module => "_Module") &
Gen_Alg_Name & "_Main";
begin
- if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
+ if Input_Data.Post_Parse_Action_Count > 0 or Input_Data.In_Parse_Action_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);
+ (Generate_Data.Post_Parse_Action_Names, Generate_Data.In_Parse_Action_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);
+ (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);
@@ -2086,13 +2185,13 @@ begin
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,
+ (Main_Package_Name => Main_Package_Name,
Common_Data => Common_Data,
Input_Data => Input_Data);
end if;
+
+ -- We can't create a test_main here, because we don't have the wisi
+ -- package for the actions.
end;
case Common_Data.Interface_Kind is
diff --git a/wisitoken-bnf-output_elisp_common.adb b/wisitoken-bnf-output_elisp_common.adb
index a74efd3..e28dec3 100644
--- a/wisitoken-bnf-output_elisp_common.adb
+++ b/wisitoken-bnf-output_elisp_common.adb
@@ -2,7 +2,7 @@
--
-- See spec
--
--- Copyright (C) 2012, 2013, 2015, 2017 - 2019, 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2012, 2013, 2015, 2017 - 2019, 2022, 2023 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
@@ -190,7 +190,7 @@ package body WisiToken.BNF.Output_Elisp_Common is
end re2c_To_Elisp;
begin
- Indent_Line ("(defconst " & Output_File_Root & "-" & Label & "-repair-image");
+ Indent_Line ("(defconst " & Output_File_Root & (if Label'Length > 0 then "-" & Label else "") & "-repair-image");
Indent_Line (" '(");
Indent := Indent + 3;
for Pair of Tokens.Keywords loop
diff --git a/wisitoken-bnf-utils.adb b/wisitoken-bnf-utils.adb
index 71e340f..7a875ae 100644
--- a/wisitoken-bnf-utils.adb
+++ b/wisitoken-bnf-utils.adb
@@ -2,7 +2,7 @@
--
-- See spec
--
--- Copyright (C) 2012, 2013, 2015, 2017, 2018 Free Software Foundation, Inc.
+-- Copyright (C) 2012, 2013, 2015, 2017, 2018, 2023 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
@@ -26,8 +26,8 @@ package body WisiToken.BNF.Utils is
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));
+ ((if Item (Item'First) in '"' | ''' then Item'First + 1 else Item'First) ..
+ (if Item (Item'Last) in '"' | ''' then Item'Last - 1 else Item'Last));
end if;
end Strip_Quotes;
diff --git a/wisitoken-bnf-utils.ads b/wisitoken-bnf-utils.ads
index 6062ff9..0c4e26d 100644
--- a/wisitoken-bnf-utils.ads
+++ b/wisitoken-bnf-utils.ads
@@ -2,7 +2,7 @@
--
-- Utilities for generating source code from BNF source files
--
--- Copyright (C) 2012, 2013, 2015, 2017, 2018 Free Software Foundation, Inc.
+-- Copyright (C) 2012, 2013, 2015, 2017, 2018, 2023 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
@@ -21,7 +21,7 @@ pragma License (Modified_GPL);
package WisiToken.BNF.Utils is
function Strip_Quotes (Item : in String) return String;
- -- Remove leading and trailing '"', if any.
+ -- Remove leading and trailing '"' and ''', if any.
function Strip_Parens (Item : in String) return String;
-- Remove leading and trailing '()', if any.
diff --git a/wisitoken-bnf.adb b/wisitoken-bnf.adb
index ee98bf4..7f8eedc 100644
--- a/wisitoken-bnf.adb
+++ b/wisitoken-bnf.adb
@@ -2,7 +2,7 @@
--
-- see spec
--
--- Copyright (C) 2012 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2012 - 2015, 2017 - 2023 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
@@ -71,11 +71,11 @@ package body WisiToken.BNF is
function From_Generate_Env_Var return Generate_Algorithm_Set
is
- Gen_String : constant String := Ada.Environment_Variables.Value ("GENERATE", "BNF_EBNF");
+ Gen_String : constant String := Ada.Environment_Variables.Value ("GENERATE", "");
begin
-- GENERATE env var defined in wisitoken_test.gpr
if Gen_String = "" then
- return (Tree_Sitter => False, others => True);
+ return (others => True);
elsif Gen_String = "BNF_EBNF_Tree_Sitter" then
return (others => True);
elsif Gen_String = "BNF_EBNF" or
@@ -204,6 +204,13 @@ package body WisiToken.BNF is
Put_Line (Comment_Syntax);
end Put_File_Header;
+ function Image (Item : in Labeled_Token) return String
+ is
+ use Ada.Strings.Unbounded;
+ begin
+ return (if Length (Item.Label) > 0 then -Item.Label & "=" else "") & (-Item.Identifier);
+ end Image;
+
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;
diff --git a/wisitoken-bnf.ads b/wisitoken-bnf.ads
index 5275e2c..0ad32c3 100644
--- a/wisitoken-bnf.ads
+++ b/wisitoken-bnf.ads
@@ -10,7 +10,7 @@
-- [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 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2012 - 2015, 2017 - 2023 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
@@ -30,9 +30,9 @@ 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 SAL.Gen_Unbounded_Definite_Vectors.Gen_Image;
with WisiToken.Parse.LR;
with WisiToken.Syntax_Trees;
package WisiToken.BNF is
@@ -57,7 +57,7 @@ package WisiToken.BNF is
Packrat_Proc => new String'("Packrat_Proc"),
External => new String'("External"),
Tree_Sitter => new String'("Tree_Sitter"));
- -- Suitable for Ada package names.
+ -- Suitable for Ada package names. For file names, use To_Lower (Gen_Alg'Image).
function To_Generate_Algorithm (Item : in String) return Generate_Algorithm;
-- Raises User_Error for invalid Item
@@ -67,13 +67,14 @@ package WisiToken.BNF is
function From_Generate_Env_Var return Generate_Algorithm_Set;
- type Output_Language is (Ada_Lang, Ada_Emacs_Lang);
+ type Output_Language is (None, 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"),
+ (None => new String'("None"),
+ Ada_Lang => new String'("Ada"),
Ada_Emacs_Lang => new String'("Ada_Emacs"));
function To_Output_Language (Item : in String) return Output_Language;
@@ -110,7 +111,7 @@ package WisiToken.BNF is
type Generate_Tuple is record
Gen_Alg : Generate_Algorithm := None;
- Out_Lang : Output_Language := Ada_Lang;
+ Out_Lang : Output_Language := None;
Lexer : Lexer_Type := None;
Interface_Kind : Interface_Type := None;
Text_Rep : Boolean := False;
@@ -286,32 +287,49 @@ package WisiToken.BNF is
package Conflict_Lists is new Ada.Containers.Doubly_Linked_Lists (Conflict);
type Labeled_Token is record
- Label : Ada.Strings.Unbounded.Unbounded_String;
+ Label : Ada.Strings.Unbounded.Unbounded_String;
+
+ Orig_Token_Index : SAL.Base_Peek_Type := 0;
+ -- Index of this token in Orig_EBNF_RHS; 0 if this is that RHS, or if
+ -- this token is added by translating to BNF.
+
Identifier : Ada.Strings.Unbounded.Unbounded_String;
end record;
- package Labeled_Token_Arrays is new Ada.Containers.Vectors (Positive_Index_Type, Labeled_Token);
+ package Labeled_Token_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
+ (Positive_Index_Type, Labeled_Token, Default_Element => (others => <>));
-- Index matches Syntax_Trees.Valid_Node_Index_Array, used for Tokens
-- in call to post parse grammar action.
+ function Image (Item : in Labeled_Token) return String;
+ function Image is new Labeled_Token_Arrays.Gen_Image (Image);
+
type RHS_Type is record
- Tokens : Labeled_Token_Arrays.Vector;
- Auto_Token_Labels : Boolean := False;
- -- Token labels generated by Translate_EBNF_To_BNF
+ Associativity : WisiToken.Associativity := WisiToken.None;
+ Precedence : WisiToken.Base_Precedence_ID := WisiToken.No_Precedence;
- Edited_Token_List : Boolean := False;
- -- RHS modified by Translate_EBNF_To_BNF; RHS_Index 0 has all tokens.
+ Tokens : Labeled_Token_Arrays.Vector;
+
+ Orig_EBNF_RHS : Boolean := False;
+
+ EBNF_RHS_Index : Natural := Natural'Last;
+ -- Index of RHS containing EBNF RHS that this was copied from by
+ -- Translate_EBNF_To_BNF; used to map tokens in actions.
+
+ Auto_Token_Labels : Boolean := False;
+ -- True if some token labels generated by Translate_EBNF_To_BNF
- Action : Ada.Strings.Unbounded.Unbounded_String;
- Check : Ada.Strings.Unbounded.Unbounded_String;
- Source_Line : WisiToken.Line_Number_Type := WisiToken.Line_Number_Type'First;
+ Post_Parse_Action : Ada.Strings.Unbounded.Unbounded_String;
+ In_Parse_Action : Ada.Strings.Unbounded.Unbounded_String;
+ Source_Line : WisiToken.Line_Number_Type := WisiToken.Line_Number_Type'First;
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;
+ Precedence : WisiToken.Base_Precedence_ID;
Right_Hand_Sides : RHS_Lists.List;
- Labels : String_Arrays.Vector;
+ Labels : String_Arrays.Vector; -- All labels used in any RHS
Optimized_List : Boolean := False;
Source_Line : WisiToken.Line_Number_Type;
end record;
diff --git a/wisitoken-generate-lr-lalr_generate.adb b/wisitoken-generate-lr-lalr_generate.adb
index 358ab85..068c4fd 100644
--- a/wisitoken-generate-lr-lalr_generate.adb
+++ b/wisitoken-generate-lr-lalr_generate.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -446,6 +446,7 @@ package body WisiToken.Generate.LR.LALR_Generate is
procedure Add_Actions
(Kernels : in LR1_Items.Item_Set_List;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Has_Empty_Production : in Token_ID_Set;
First_Terminal_Sequence : in Token_Sequence_Arrays.Vector;
First_Nonterm_Set : in Token_Array_Token_Set;
@@ -466,7 +467,8 @@ package body WisiToken.Generate.LR.LALR_Generate is
Closure := LR1_Items.Closure (Kernel, Has_Empty_Production, First_Terminal_Sequence, Grammar, Descriptor);
Add_Actions
- (Closure, Table, Grammar, Descriptor, Declared_Conflicts, Unknown_Conflicts, First_Nonterm_Set, File_Name,
+ (Closure, Table, Grammar, Precedence_Lists, Descriptor, Declared_Conflicts, Unknown_Conflicts,
+ First_Nonterm_Set, File_Name,
Ignore_Conflicts);
end loop;
@@ -477,17 +479,18 @@ package body WisiToken.Generate.LR.LALR_Generate is
function Generate
(Grammar : in out WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Grammar_File_Name : in String;
Error_Recover : in Boolean;
- Known_Conflicts : in Conflict_Lists.Tree := Conflict_Lists.Empty_Tree;
- McKenzie_Param : in McKenzie_Param_Type := Default_McKenzie_Param;
- Max_Parallel : in SAL.Base_Peek_Type := 15;
- Parse_Table_File_Name : in String := "";
- Include_Extra : in Boolean := False;
- Ignore_Conflicts : in Boolean := False;
+ Known_Conflicts : in Conflict_Lists.Tree := Conflict_Lists.Empty_Tree;
+ McKenzie_Param : in McKenzie_Param_Type := Default_McKenzie_Param;
+ Max_Parallel : in SAL.Base_Peek_Type := 15;
+ Parse_Table_File_Name : in String := "";
+ Include_Extra : in Boolean := False;
+ Ignore_Conflicts : in Boolean := False;
Recursion_Strategy : in WisiToken.Recursion_Strategy := Full;
- Use_Cached_Recursions : in Boolean := False;
+ Use_Cached_Recursions : in Boolean := False;
Recursions : in out WisiToken.Generate.Recursions)
return Parse_Table_Ptr
is
@@ -506,12 +509,6 @@ package body WisiToken.Generate.LR.LALR_Generate is
Recursions_Time : Ada.Calendar.Time;
- Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
- Compute_Minimal_Terminal_Sequences (Descriptor, Grammar, Grammar_File_Name);
-
- 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);
@@ -524,7 +521,7 @@ package body WisiToken.Generate.LR.LALR_Generate is
Known_Conflicts_Edit : Conflict_Lists.Tree := Known_Conflicts;
begin
- if not Use_Cached_Recursions or Recursions = Empty_Recursions then
+ if Error_Recover and then (not Use_Cached_Recursions or Recursions = Empty_Recursions) then
case Recursion_Strategy is
when None =>
null;
@@ -537,6 +534,7 @@ package body WisiToken.Generate.LR.LALR_Generate is
end case;
end if;
+
Set_Grammar_Recursions (Recursions, Grammar);
Recursions_Time := Ada.Calendar.Clock;
@@ -603,8 +601,8 @@ package body WisiToken.Generate.LR.LALR_Generate is
Table.Max_Parallel := Max_Parallel;
Add_Actions
- (Kernels, Grammar, Has_Empty_Production, First_Terminal_Sequence, First_Nonterm_Set, Table.all,
- Descriptor, Known_Conflicts_Edit, Unknown_Conflicts, Grammar_File_Name, Ignore_Conflicts);
+ (Kernels, Grammar, Precedence_Lists, Has_Empty_Production, First_Terminal_Sequence, First_Nonterm_Set,
+ Table.all, Descriptor, Known_Conflicts_Edit, Unknown_Conflicts, Grammar_File_Name, Ignore_Conflicts);
if Trace_Time then
Table_Time := Ada.Calendar.Clock;
@@ -612,20 +610,30 @@ package body WisiToken.Generate.LR.LALR_Generate is
("compute parse table time:" & Duration'Image (Ada.Calendar."-" (Table_Time, Recursions_Time)));
end if;
- 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 Table.Error_Recover_Enabled then
+ declare
+ Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
+ Compute_Minimal_Terminal_Sequences (Descriptor, Grammar, Grammar_File_Name);
- if Trace_Time then
- Minimal_Actions_Time := Ada.Calendar.Clock;
- Ada.Text_IO.Put_Line
- ("compute minimal actions time:" & Duration'Image
- (Ada.Calendar."-" (Minimal_Actions_Time, Table_Time)));
+ Minimal_Terminal_First : constant Token_Array_Token_ID :=
+ Compute_Minimal_Terminal_First (Descriptor, Minimal_Terminal_Sequences);
+
+ begin
+ 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;
+ end;
+ if Trace_Time then
+ Minimal_Actions_Time := Ada.Calendar.Clock;
+ Ada.Text_IO.Put_Line
+ ("compute minimal actions time:" & Duration'Image
+ (Ada.Calendar."-" (Minimal_Actions_Time, Table_Time)));
+ end if;
end if;
if Parse_Table_File_Name /= "" then
diff --git a/wisitoken-generate-lr-lalr_generate.ads b/wisitoken-generate-lr-lalr_generate.ads
index ce4115b..37d954c 100644
--- a/wisitoken-generate-lr-lalr_generate.ads
+++ b/wisitoken-generate-lr-lalr_generate.ads
@@ -2,7 +2,7 @@
--
-- Generalized LALR parse table generator.
--
--- Copyright (C) 2002 - 2003, 2009 - 2010, 2013 - 2015, 2017 - 2020, 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002 - 2003, 2009 - 2010, 2013 - 2015, 2017 - 2020, 2022, 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -26,6 +26,7 @@ package WisiToken.Generate.LR.LALR_Generate is
function Generate
(Grammar : in out WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Grammar_File_Name : in String;
Error_Recover : in Boolean;
diff --git a/wisitoken-generate-lr-lr1_generate.adb b/wisitoken-generate-lr-lr1_generate.adb
index 2226fc2..47166b3 100644
--- a/wisitoken-generate-lr-lr1_generate.adb
+++ b/wisitoken-generate-lr-lr1_generate.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -202,6 +202,7 @@ package body WisiToken.Generate.LR.LR1_Generate is
(Item_Sets : in LR1_Items.Item_Set_List;
Table : in out Parse_Table;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -213,8 +214,8 @@ package body WisiToken.Generate.LR.LR1_Generate is
begin
for Item_Set of Item_Sets loop
Add_Actions
- (Item_Set, Table, Grammar, Descriptor, Declared_Conflicts, Unknown_Conflicts, First_Nonterm_Set, File_Name,
- Ignore_Conflicts);
+ (Item_Set, Table, Grammar, Precedence_Lists, Descriptor, Declared_Conflicts, Unknown_Conflicts,
+ First_Nonterm_Set, File_Name, Ignore_Conflicts);
end loop;
if Trace_Generate_Table > Outline then
@@ -224,24 +225,24 @@ package body WisiToken.Generate.LR.LR1_Generate is
function Generate
(Grammar : in out WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Grammar_File_Name : in String;
Error_Recover : in Boolean;
- Known_Conflicts : in Conflict_Lists.Tree := Conflict_Lists.Empty_Tree;
- McKenzie_Param : in McKenzie_Param_Type := Default_McKenzie_Param;
- Max_Parallel : in SAL.Base_Peek_Type := 15;
- Parse_Table_File_Name : in String := "";
- Include_Extra : in Boolean := False;
- Ignore_Conflicts : in Boolean := False;
- Recursion_Strategy : in WisiToken.Recursion_Strategy := Full;
- Use_Cached_Recursions : in Boolean := False;
+ Known_Conflicts : in Conflict_Lists.Tree := Conflict_Lists.Empty_Tree;
+ McKenzie_Param : in McKenzie_Param_Type := Default_McKenzie_Param;
+ Max_Parallel : in SAL.Base_Peek_Type := 15;
+ Parse_Table_File_Name : in String := "";
+ Include_Extra : in Boolean := False;
+ Ignore_Conflicts : in Boolean := False;
+ Recursion_Strategy : in WisiToken.Recursion_Strategy := Full;
+ Use_Cached_Recursions : in Boolean := False;
Recursions : in out WisiToken.Generate.Recursions)
return Parse_Table_Ptr
is
- Time_Start : constant Ada.Calendar.Time := Ada.Calendar.Clock;
- Add_Actions_Time : Ada.Calendar.Time;
- Minimal_Actions_Time : Ada.Calendar.Time;
- Collect_Conflict_Time : Ada.Calendar.Time;
+ Time_Start : constant Ada.Calendar.Time := Ada.Calendar.Clock;
+ Add_Actions_Time : Ada.Calendar.Time;
+ Minimal_Actions_Time : Ada.Calendar.Time;
Ignore_Unused_Tokens : constant Boolean := WisiToken.Trace_Generate_Table > Detail;
Ignore_Unknown_Conflicts : constant Boolean := Ignore_Conflicts or WisiToken.Trace_Generate_Table > Detail;
@@ -254,12 +255,6 @@ package body WisiToken.Generate.LR.LR1_Generate is
Recursions_Time : Ada.Calendar.Time := Ada.Calendar.Clock;
- Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
- Compute_Minimal_Terminal_Sequences (Descriptor, Grammar, Grammar_File_Name);
-
- 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);
@@ -275,7 +270,7 @@ package body WisiToken.Generate.LR.LR1_Generate is
Initial_Item_Sets_Time : constant Ada.Calendar.Time := Ada.Calendar.Clock;
begin
- if not Use_Cached_Recursions or Recursions = Empty_Recursions then
+ if Error_Recover and then (not Use_Cached_Recursions or Recursions = Empty_Recursions) then
case Recursion_Strategy is
when None =>
null;
@@ -285,6 +280,7 @@ package body WisiToken.Generate.LR.LR1_Generate is
when Full =>
Recursions := WisiToken.Generate.Compute_Full_Recursion (Grammar, Descriptor);
+
end case;
end if;
@@ -345,8 +341,8 @@ package body WisiToken.Generate.LR.LR1_Generate is
Table.Max_Parallel := Max_Parallel;
Add_Actions
- (Item_Sets, Table.all, Grammar, Descriptor, Known_Conflicts_Edit, Unknown_Conflicts, First_Nonterm_Set,
- Grammar_File_Name, Ignore_Conflicts);
+ (Item_Sets, Table.all, Grammar, Precedence_Lists, Descriptor, Known_Conflicts_Edit, Unknown_Conflicts,
+ First_Nonterm_Set, Grammar_File_Name, Ignore_Conflicts);
if Trace_Time then
Add_Actions_Time := Ada.Calendar.Clock;
@@ -354,28 +350,46 @@ package body WisiToken.Generate.LR.LR1_Generate is
("add_actions time:" & Duration'Image (Ada.Calendar."-" (Add_Actions_Time, Initial_Item_Sets_Time)));
end if;
- 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 Table.Error_Recover_Enabled then
+ declare
+ Minimal_Terminal_Sequences : constant Minimal_Sequence_Array :=
+ Compute_Minimal_Terminal_Sequences (Descriptor, Grammar, Grammar_File_Name);
- if Trace_Time then
- Minimal_Actions_Time := Ada.Calendar.Clock;
- Ada.Text_IO.Put_Line
- ("compute minimal actions time:" & Duration'Image
- (Ada.Calendar."-" (Minimal_Actions_Time, Add_Actions_Time)));
- end if;
+ Minimal_Terminal_First : constant Token_Array_Token_ID :=
+ Compute_Minimal_Terminal_First (Descriptor, Minimal_Terminal_Sequences);
+ begin
+ 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 Trace_Time then
+ Minimal_Actions_Time := Ada.Calendar.Clock;
+ Ada.Text_IO.Put_Line
+ ("compute minimal actions time:" & Duration'Image
+ (Ada.Calendar."-" (Minimal_Actions_Time, Add_Actions_Time)));
+ end if;
- if Trace_Time then
- Collect_Conflict_Time := Ada.Calendar.Clock;
- Ada.Text_IO.Put_Line
- ("compute conflicts time:" & Duration'Image
- (Ada.Calendar."-" (Collect_Conflict_Time, Minimal_Actions_Time)));
+ if Trace_Generate_Table > Detail 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;
+ end;
end if;
if Parse_Table_File_Name /= "" then
@@ -384,21 +398,6 @@ package body WisiToken.Generate.LR.LR1_Generate is
Unknown_Conflicts, Descriptor, Include_Extra);
end if;
- if Trace_Generate_Table > Detail 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;
-
Check_Conflicts
("LR1", Unknown_Conflicts, Known_Conflicts_Edit, Grammar_File_Name, Descriptor, Ignore_Unknown_Conflicts);
diff --git a/wisitoken-generate-lr-lr1_generate.ads b/wisitoken-generate-lr-lr1_generate.ads
index 42004e7..8a9ef02 100644
--- a/wisitoken-generate-lr-lr1_generate.ads
+++ b/wisitoken-generate-lr-lr1_generate.ads
@@ -7,7 +7,7 @@
-- [dragon] "Compilers Principles, Techniques, and Tools" by Aho,
-- Sethi, and Ullman (aka: "The [Red] Dragon Book").
--
--- Copyright (C) 2017 - 2020, 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2020, 2022, 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -30,6 +30,7 @@ package WisiToken.Generate.LR.LR1_Generate is
function Generate
(Grammar : in out WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Grammar_File_Name : in String;
Error_Recover : in Boolean;
diff --git a/wisitoken-generate-lr.adb b/wisitoken-generate-lr.adb
index 9a5aa54..2520421 100644
--- a/wisitoken-generate-lr.adb
+++ b/wisitoken-generate-lr.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -320,7 +320,7 @@ package body WisiToken.Generate.LR is
function Apply_Optimized_List_Conflict
(Conflict : in out Parse.LR.Action_Node;
- Conflict_Count : in Integer;
+ Conflict_Count : in out Integer;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
First_Nonterm_Set : in WisiToken.Token_Array_Token_Set;
@@ -328,9 +328,9 @@ package body WisiToken.Generate.LR is
return Boolean
with Pre => Conflict_Count /= 0
-- If Conflict is due to an optimized_list, it is modified to
- -- implement the appropriate conflict resolution, and the function
- -- returns True. Otherwize, Conflict is not modified, and the
- -- function returns False.
+ -- implement the appropriate conflict resolution, Conflict_Count is
+ -- decremented, and the function returns True. Otherwise, Conflict,
+ -- Conflict_Count are not modified, and the function returns False.
is
use all type Ada.Containers.Count_Type;
@@ -533,11 +533,14 @@ package body WisiToken.Generate.LR is
end if;
end if;
end loop;
+
if Delete_Count = 0 then
return False;
+
elsif Delete_Count + 1 = Conflict_Count then
-- Fully resolved; a pure optimized_list conflict. Do deletes below.
null;
+
else
-- Mixed optimized_list and grammar conflicts. FIXME: need test case.
-- FIXME: also apply declared resolutions to this conflict.
@@ -609,6 +612,7 @@ package body WisiToken.Generate.LR is
for I in 1 .. Conflict_Count loop
if Delete (I) then
Parse.LR.Delete (Conflict, Prev, Temp);
+ Conflict_Count := @ - 1;
else
Prev := Temp;
Temp := Temp.Next;
@@ -707,20 +711,17 @@ package body WisiToken.Generate.LR is
end Check_Conflicts;
- ----------
- -- Build parse table
-
function Apply_Declared_Resolution
(Conflict : in out Parse.LR.Action_Node;
Found : in Conflict_Lists.Cursor;
- Conflict_Count : in Integer;
+ Conflict_Count : in out Integer;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree)
return Boolean
with Pre => Conflict.Actions.Next /= null and Found /= Conflict_Lists.No_Element
- -- If Conflict is matches a declared %conflict_resolution, it is
- -- modified to implement the conflict resolution, and the function
- -- returns True. Otherwize, Conflict is not modified, and the
- -- function returns False.
+ -- If Conflict matches a declared %conflict_resolution, it is
+ -- modified to implement the conflict resolution, conflict_Count is
+ -- decremented, and the function returns True. Otherwise, Conflict,
+ -- Conflict_Count are not modified, and the function returns False.
is
use Conflict_Lists;
Declared : WisiToken.Generate.LR.Conflict renames Declared_Conflicts (Found);
@@ -754,6 +755,7 @@ package body WisiToken.Generate.LR is
for I in 1 .. Conflict_Count loop
if Delete (I) then
Parse.LR.Delete (Conflict, Prev, Temp);
+ Conflict_Count := @ - 1;
else
Prev := Temp;
Temp := Temp.Next;
@@ -763,12 +765,140 @@ package body WisiToken.Generate.LR is
return True;
end Apply_Declared_Resolution;
+ function Apply_Precedence
+ (Conflict : in out Parse.LR.Action_Node;
+ Conflict_Count : in out Integer;
+ Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector)
+ return Boolean
+ with Pre => Conflict.Actions.Next /= null and Conflict_Count > 1
+ -- If a precedence relation applies to Conflict, it is modified to
+ -- implement the precedence resolution, Conflict_Count is
+ -- decremented, and the function returns True. Otherwise, Conflict,
+ -- Conflict_Count are not modified, and the function returns False.
+ is
+ Found_Precedence : array (1 .. Conflict_Count) of Base_Precedence_ID := (others => No_Precedence);
+ Delete : array (1 .. Conflict_Count) of Boolean := (others => False);
+
+ Temp : Parse_Action_Node_Ptr := Conflict.Actions;
+ Prev : Parse_Action_Node_Ptr := null;
+
+ Non_None_Count : Integer := 0;
+ begin
+ for I in 1 .. Conflict_Count loop
+ Found_Precedence (I) := WisiToken.Productions.Get_Precedence (Grammar, Temp.Item.Production);
+ if Found_Precedence (I) /= No_Precedence then
+ Non_None_Count := @ + 1;
+ end if;
+
+ Temp := Temp.Next;
+ end loop;
+
+ if Non_None_Count <= 1 then
+ return False;
+ end if;
+
+ if Conflict_Count > 2 then
+ raise SAL.Not_Implemented with "generate apply_precedence conflict_count > 2; must do all combinations.";
+ end if;
+
+ declare
+ Relation : constant Precedence_Compare_Result := Compare
+ (Found_Precedence (1), Found_Precedence (2), Precedence_Lists);
+ begin
+ case Relation is
+ when None =>
+ return False;
+
+ when Left =>
+ Delete (2) := True;
+
+ when Right =>
+ Delete (1) := True;
+ end case;
+ end;
+
+ Temp := Conflict.Actions;
+ for I in 1 .. Conflict_Count loop
+ if Delete (I) then
+ Parse.LR.Delete (Conflict, Prev, Temp);
+ Conflict_Count := @ - 1;
+ else
+ Prev := Temp;
+ Temp := Temp.Next;
+ end if;
+ end loop;
+
+ return True;
+ end Apply_Precedence;
+
+ function Apply_Associativity
+ (Conflict : in out Parse.LR.Action_Node;
+ Conflict_Count : in out Integer;
+ Grammar : in WisiToken.Productions.Prod_Arrays.Vector)
+ return Boolean
+ with Pre => Conflict.Actions.Next /= null and Conflict_Count > 1
+ -- If an associativity attribute applies to Conflict, it is modified to
+ -- implement the associativity, Conflict_Count is
+ -- decremented, and the function returns True. Otherwise, Conflict,
+ -- Conflict_Count are not modified, and the function returns False.
+ is
+ Temp : Parse_Action_Node_Ptr := Conflict.Actions;
+ Prev : Parse_Action_Node_Ptr := null;
+
+ Delete : array (1 .. Conflict_Count) of Boolean := (others => False);
+ begin
+ -- See precedence.wy
+ if Conflict_Count > 2 then
+ return False;
+ end if;
+
+ if Temp.Item.Verb /= Shift then
+ return False;
+ end if;
+
+ Temp := Temp.Next;
+
+ declare
+ List_Production : constant Production_ID := Temp.Item.Production;
+ List_Associativity : constant Associativity := WisiToken.Productions.Get_Associativity
+ (Grammar, List_Production);
+ begin
+ case List_Associativity is
+ when None =>
+ return False;
+
+ when Left =>
+ -- Keep the reduce production; always second
+ Delete (1) := True;
+
+ when Right =>
+ -- Keep the shift production; always first
+ Delete (2) := True;
+ end case;
+ end;
+
+ Temp := Conflict.Actions;
+ for I in 1 .. Conflict_Count loop
+ if Delete (I) then
+ Parse.LR.Delete (Conflict, Prev, Temp);
+ Conflict_Count := @ - 1;
+ else
+ Prev := Temp;
+ Temp := Temp.Next;
+ end if;
+ end loop;
+
+ return True;
+ end Apply_Associativity;
+
procedure Add_Action
(State : in State_Index;
Symbol : in Token_ID;
Action : in Parse_Action_Rec;
Action_List : in out Action_Arrays.Vector;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -835,14 +965,12 @@ package body WisiToken.Generate.LR is
Conflict_Count := @ + 1;
Temp := Temp.Next;
end loop;
- pragma Assert (Conflict_Count > 0);
+ pragma Assert (Conflict_Count > 1);
if Trace_Generate_Conflicts > Detail then
if Trace_Generate_Conflicts > Extra or Conflict_Count > 2 then
Ada.Text_IO.Put_Line
- ("conflict on " & Image (Matching_Action_Node.Symbol, Descriptor) &
- ", length :" & Conflict_Count'Image);
- Ada.Text_IO.Put_Line (Image (WY_Conflict, Descriptor));
+ ("state" & State'Image & ": " & Image (WY_Conflict, Descriptor));
Put (Ada.Text_IO.Current_Output, Matching_Action_Node.Actions, Descriptor);
Ada.Text_IO.New_Line;
if Found_Declared /= Conflict_Lists.No_Element then
@@ -859,9 +987,9 @@ package body WisiToken.Generate.LR is
Put (Ada.Text_IO.Current_Output, Matching_Action_Node.Actions, Descriptor);
Ada.Text_IO.New_Line;
end if;
+ end if;
- -- FIXME: apply both resolutions to one conflict. Need test case. must update Conflct_Count.
- elsif Apply_Optimized_List_Conflict
+ if Conflict_Count > 1 and then Apply_Optimized_List_Conflict
(Matching_Action_Node, Conflict_Count, Grammar, Descriptor, First_Nonterm_Set, File_Name)
then
if Trace_Generate_Conflicts > Detail then
@@ -869,8 +997,28 @@ package body WisiToken.Generate.LR is
Put (Ada.Text_IO.Current_Output, Matching_Action_Node.Actions, Descriptor);
Ada.Text_IO.New_Line;
end if;
+ end if;
- else
+ if Conflict_Count > 1 and then Apply_Precedence
+ (Matching_Action_Node, Conflict_Count, Grammar, Precedence_Lists)
+ then
+ if Trace_Generate_Conflicts > Detail then
+ Ada.Text_IO.Put_Line ("... precedence resolved:");
+ Put (Ada.Text_IO.Current_Output, Matching_Action_Node.Actions, Descriptor);
+ Ada.Text_IO.New_Line;
+ end if;
+ end if;
+
+ if Conflict_Count > 1 and then Apply_Associativity (Matching_Action_Node, Conflict_Count, Grammar)
+ then
+ if Trace_Generate_Conflicts > Detail then
+ Ada.Text_IO.Put_Line ("... associativity resolved:");
+ Put (Ada.Text_IO.Current_Output, Matching_Action_Node.Actions, Descriptor);
+ Ada.Text_IO.New_Line;
+ end if;
+ end if;
+
+ if Conflict_Count > 1 then
if Found_Declared = Conflict_Lists.No_Element then
declare
Found_Unknown : constant Conflict_Lists.Cursor :=
@@ -916,6 +1064,7 @@ package body WisiToken.Generate.LR is
(Closure : in LR1_Items.Item_Set;
Table : in out Parse_Table;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -938,8 +1087,8 @@ package body WisiToken.Generate.LR is
begin
if Item.Dot not in Item_Tokens.First_Index .. Item_Tokens.Last_Index then
Add_Lookahead_Actions
- (State, Item, Table.States (State).Action_List, Grammar, Descriptor, Declared_Conflicts,
- Unknown_Conflicts, First_Nonterm_Set, File_Name, Ignore_Conflicts);
+ (State, Item, Table.States (State).Action_List, Grammar, Precedence_Lists, Descriptor,
+ Declared_Conflicts, Unknown_Conflicts, First_Nonterm_Set, File_Name, Ignore_Conflicts);
elsif Item_Tokens (Item.Dot) in Descriptor.First_Terminal .. Descriptor.Last_Terminal
then
@@ -965,7 +1114,8 @@ package body WisiToken.Generate.LR is
-- EOF is not pushed on stack in parser, because the action for EOF
-- is Accept, not Shift.
Table.States (State).Action_List,
- Grammar, Descriptor, Declared_Conflicts, Unknown_Conflicts, First_Nonterm_Set, File_Name,
+ Grammar, Precedence_Lists, Descriptor, Declared_Conflicts, Unknown_Conflicts,
+ First_Nonterm_Set, File_Name,
Ignore_Conflicts);
end;
else
@@ -974,7 +1124,8 @@ package body WisiToken.Generate.LR is
(State, Dot_ID,
(Shift, P_ID, Goto_State),
Table.States (State).Action_List,
- Grammar, Descriptor, Declared_Conflicts, Unknown_Conflicts, First_Nonterm_Set, File_Name,
+ Grammar, Precedence_Lists, Descriptor, Declared_Conflicts, Unknown_Conflicts,
+ First_Nonterm_Set, File_Name,
Ignore_Conflicts);
end if;
end if;
@@ -1007,6 +1158,7 @@ package body WisiToken.Generate.LR is
Item : in LR1_Items.Item;
Action_List : in out Action_Arrays.Vector;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -1029,7 +1181,7 @@ package body WisiToken.Generate.LR is
null;
else
Add_Action
- (State, Lookahead, Action, Action_List, Grammar, Descriptor, Declared_Conflicts,
+ (State, Lookahead, Action, Action_List, Grammar, Precedence_Lists, Descriptor, Declared_Conflicts,
Unknown_Conflicts, First_Nonterm_Set, File_Name, Ignore_Conflicts);
end if;
end if;
@@ -1113,7 +1265,7 @@ package body WisiToken.Generate.LR is
Error_Message
(File_Name => Grammar_File_Name,
File_Line => Line_Number_Type'First,
- Message => "terminal sequences not resolved:"));
+ Message => "Compute_Minimal_Terminal_Sequences: terminal sequences not resolved:"));
Ada.Text_IO.Put_Line
(Ada.Text_IO.Current_Error,
@@ -1325,7 +1477,7 @@ package body WisiToken.Generate.LR is
-- considering recursion.
--
-- Insert_Minimal_Complete_Actions does not need any recursion
- -- information at runtim, because we elminate all cases where it
+ -- information at runtime, because we elminate all cases where it
-- might here.
--
-- The strategy in Insert_Minimal_Complete_Actions when
@@ -1400,7 +1552,7 @@ package body WisiToken.Generate.LR is
-- the true Length_After_Dot must be computed at runtime. Recursion
-- is not considered, because any other McKensie operation would also
-- need to do a reduce to the LHS here. Label is Keep_Always,
- -- Minimal_Action is Reduce_Production.
+ -- Minimal_Action is Reduce.
--
-- In state 68 production 115.0, Length_After_Dot is 0 because
-- parameter_profile_opt is nullable. We don't ignore recursion in
@@ -1931,7 +2083,7 @@ package body WisiToken.Generate.LR is
end if;
end;
- if Include_Extra then
+ if Include_Extra and Recursions.Recursions.Length > 0 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
diff --git a/wisitoken-generate-lr.ads b/wisitoken-generate-lr.ads
index b2d34f3..6c99b58 100644
--- a/wisitoken-generate-lr.ads
+++ b/wisitoken-generate-lr.ads
@@ -2,7 +2,7 @@
--
-- Common utilities for LR parser table generators.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -122,6 +122,7 @@ package WisiToken.Generate.LR is
Action : in Parse_Action_Rec;
Action_List : in out Action_Arrays.Vector;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -135,6 +136,7 @@ package WisiToken.Generate.LR is
(Closure : in LR1_Items.Item_Set;
Table : in out Parse_Table;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
@@ -148,6 +150,7 @@ package WisiToken.Generate.LR is
Item : in LR1_Items.Item;
Action_List : in out Action_Arrays.Vector;
Grammar : in WisiToken.Productions.Prod_Arrays.Vector;
+ Precedence_Lists : in WisiToken.Precedence_Lists_Arrays.Vector;
Descriptor : in WisiToken.Descriptor;
Declared_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
Unknown_Conflicts : in out WisiToken.Generate.LR.Conflict_Lists.Tree;
diff --git a/wisitoken-generate-packrat.ads b/wisitoken-generate-packrat.ads
index 2bb50bc..2363d62 100644
--- a/wisitoken-generate-packrat.ads
+++ b/wisitoken-generate-packrat.ads
@@ -10,7 +10,7 @@
--
-- See wisitoken-parse-packrat.ads.
--
--- Copyright (C) 2018, 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018, 2022, 2023 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
@@ -43,6 +43,7 @@ package WisiToken.Generate.Packrat is
Involved : Token_Array_Token_Set
(First_Nonterminal .. Last_Nonterminal, First_Nonterminal .. Last_Nonterminal);
end record;
+ type Data_Access is access Data;
function Initialize
(Source_File_Name : in String;
diff --git a/wisitoken-generate-tree_sitter.adb b/wisitoken-generate-tree_sitter.adb
index e7ff08e..80f0b51 100644
--- a/wisitoken-generate-tree_sitter.adb
+++ b/wisitoken-generate-tree_sitter.adb
@@ -1,12 +1,12 @@
-- Abstract :
--
--- Translate a wisitoken grammar file to a tree-sitter grammar file.
+-- See spec.
--
-- References:
--
-- [1] tree-sitter grammar: https://tree-sitter.github.io/tree-sitter/creating-parsers#the-grammar-dsl
--
--- Copyright (C) 2020 - 2022 Stephen Leake All Rights Reserved.
+-- Copyright (C) 2020 - 2023 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
@@ -17,6 +17,7 @@
pragma License (GPL);
+with Ada.Strings.Fixed;
with Ada.Text_IO; use Ada.Text_IO;
with SAL.Gen_Unbounded_Definite_Vectors;
with WisiToken.BNF.Output_Ada_Common;
@@ -26,16 +27,28 @@ with Wisitoken_Grammar_Actions; use Wisitoken_Grammar_Actions;
package body WisiToken.Generate.Tree_Sitter is
use WisiToken.Syntax_Trees;
+ function Is_Possibly_Empty_ID (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Access) return Boolean
+ is (To_Token_Enum (Tree.ID (Node)) in rhs_ID | rhs_item_list_ID | rhs_item_ID);
+
procedure Eliminate_Empty_Productions
- (Data : in out WisiToken_Grammar_Runtime.User_Data_Type;
- Tree : in out WisiToken.Syntax_Trees.Tree)
+ (Data : in out WisiToken_Grammar_Runtime.User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ No_Empty : in Boolean)
is
- Ignore_Lines : Boolean := False;
+ use all type Ada.Containers.Count_Type;
+
+ Ignore_Lines : Boolean := False;
type Empty_Nonterm is record
- Name : Ada.Strings.Unbounded.Unbounded_String;
+ Name : Ada.Strings.Unbounded.Unbounded_String;
+ -- The nonterm name, for trace messages.
+
Empty_Node : WisiToken.Syntax_Trees.Node_Access := WisiToken.Syntax_Trees.Invalid_Node_Access;
- end record;
+ -- The first element of an RHS that can be empty.
+ end record
+ with Dynamic_Predicate =>
+ Empty_Node = Invalid_Node_Access or else
+ Is_Possibly_Empty_ID (Tree, Empty_Node);
package Empty_Nonterm_Lists is new SAL.Gen_Unbounded_Definite_Vectors
(Positive_Index_Type, Empty_Nonterm, Default_Element => (others => <>));
@@ -61,14 +74,16 @@ package body WisiToken.Generate.Tree_Sitter is
case To_Token_Enum (Tree.ID (Node)) is
when rhs_list_ID =>
declare
+ use all type SAL.Base_Peek_Type;
RHS_List : constant Constant_List := Creators.Create_List (Tree, Node, +rhs_list_ID, +rhs_ID);
begin
for RHS of RHS_List loop
- if Tree.RHS_Index (RHS) = 0 then
+ if Tree.Child_Count (RHS) = 0 then
return RHS;
end if;
declare
- Empty_Node : constant Node_Access := Can_Be_Empty (Tree.Child (RHS, 1));
+ Empty_Node : constant Node_Access := Can_Be_Empty
+ (Tree.Child (RHS, (if Tree.ID (Tree.Child (RHS, 1)) = +rhs_item_list_ID then 1 else 2)));
begin
if Empty_Node /= Invalid_Node_Access then
return Empty_Node;
@@ -99,34 +114,51 @@ package body WisiToken.Generate.Tree_Sitter is
when rhs_element_ID =>
declare
- Item : constant Valid_Node_Access := Tree.Find_Descendant (Node, +rhs_item_ID);
+ Item : constant Valid_Node_Access := Tree.Child (Tree.Find_Descendant (Node, +rhs_item_ID), 1);
begin
- case Tree.RHS_Index (Item) is
- when 0 | 1 =>
+ case To_Token_Enum (Tree.ID (Item)) is
+ when IDENTIFIER_ID | STRING_LITERAL_SINGLE_ID =>
return Invalid_Node_Access;
- when 2 =>
+ when attribute_ID =>
-- If the only elements in an rhs_item_list are attributes, the list
-- is empty for LR generation purposes.
return Item;
- when 3 =>
+ when rhs_optional_item_ID =>
return Item;
- when 4 =>
- case Tree.RHS_Index (Tree.Child (Item, 1)) is
- when 0 | 3 | 5 =>
- return Item;
- when 1 | 2 =>
- return Can_Be_Empty (Tree.Child (Tree.Child (Item, 1), 2));
- when 4 =>
- return Invalid_Node_Access;
- when others =>
- raise SAL.Programmer_Error;
- end case;
+ when rhs_multiple_item_ID =>
+ declare
+ use all type SAL.Base_Peek_Type;
+ First_Child : constant Valid_Node_Access := Tree.Child (Item, 1);
+ begin
+ case To_Token_Enum (Tree.ID (First_Child)) is
+ when LEFT_BRACE_ID =>
+ return
+ (if Tree.Child_Count (Item) = 3
+ then Item
+ else Invalid_Node_Access);
+
+ when LEFT_PAREN_ID =>
+ return
+ (if To_Token_Enum (Tree.ID (Tree.Child (Item, 4))) = STAR_ID
+ then Item
+ else Invalid_Node_Access);
+
+ when IDENTIFIER_ID =>
+ return
+ (if To_Token_Enum (Tree.ID (Tree.Child (Item, 2))) = STAR_ID
+ then Item
+ else Invalid_Node_Access);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+ end;
- when 5 =>
- return Can_Be_Empty (Tree.Child (Tree.Child (Item, 1), 2));
+ when rhs_group_item_ID =>
+ return Can_Be_Empty (Tree.Child (Item, 2));
when others =>
raise SAL.Programmer_Error;
@@ -135,10 +167,10 @@ package body WisiToken.Generate.Tree_Sitter is
when rhs_alternative_list_ID =>
declare
- RHS_Alt_List : constant Constant_List := Creators.Create_List
- (Tree, Node, +rhs_alternative_list_ID, +rhs_item_list_ID);
+ RHS_Alt_List_1 : constant Constant_List := Creators.Create_List
+ (Tree, Tree.Child (Node, Tree.Child_Count (Node)), +rhs_alternative_list_1_ID, +rhs_item_list_ID);
begin
- for Item_List of RHS_Alt_List loop
+ for Item_List of RHS_Alt_List_1 loop
declare
Empty_Node : constant Node_Access := Can_Be_Empty (Item_List);
begin
@@ -221,8 +253,11 @@ package body WisiToken.Generate.Tree_Sitter is
end case;
end;
+ when rhs_list_ID =>
+ Generate.Put_Error
+ (Tree.Error_Message (Node, "%if in rhs_list not supported with tree_sitter."));
+
when others =>
- -- FIXME tree-sitter: handle rhs_list %if, %end if
null;
end case;
return;
@@ -274,7 +309,7 @@ package body WisiToken.Generate.Tree_Sitter is
if Ignore_Lines and Trace_Generate_EBNF > Outline then
Ada.Text_IO.Put_Line
- ("ignore lines true line" &
+ ("ignore lines TRUE line" &
Tree.Line_Region (Tree.Child (Node, 1), Trailing_Non_Grammar => True).First'Image);
end if;
@@ -289,14 +324,9 @@ package body WisiToken.Generate.Tree_Sitter is
end case;
when nonterminal_ID =>
- -- FIXME tree-sitter: handle %if in rhs_list; need test case
-
- -- tree-sitter allows the start nonterm of the grammar to be empty.
- -- For WisiToken, that's always wisitoken_accept_ID, which is not in
- -- the grammar file. So we ignore that case.
-
declare
- Empty_Node : constant Node_Access := Can_Be_Empty (Tree.Child (Node, 3));
+ Empty_Node : constant Node_Access := Can_Be_Empty
+ (Tree.Child (Node, (if Tree.ID (Tree.Child (Node, 3)) = +rhs_list_ID then 3 else 4)));
begin
if Empty_Node /= Invalid_Node_Access then
Empty_Nonterms.Append
@@ -309,7 +339,7 @@ package body WisiToken.Generate.Tree_Sitter is
Find_Empty_Nodes (Tree.Child (Node, 2));
when others =>
- raise SAL.Not_Implemented with Image (Tree.ID (Node), Wisitoken_Grammar_Actions.Descriptor);
+ raise SAL.Not_Implemented with Tree.Image (Node, Node_Numbers => True);
end case;
end Find_Empty_Nodes;
@@ -338,7 +368,7 @@ package body WisiToken.Generate.Tree_Sitter is
when rhs_list_ID =>
-- %if in an rhs_list is not a canonical list element, so we can't
- -- use LR_Utils.Delete.
+ -- use LR_Utils.Delete. Which is why it's not supported.
raise SAL.Not_Implemented;
when rhs_ID =>
@@ -356,27 +386,30 @@ package body WisiToken.Generate.Tree_Sitter is
end Delete_Node;
procedure Make_Non_Empty (Empty_Node : in Valid_Node_Access)
- with Pre => To_Token_Enum (Tree.ID (Empty_Node)) in
- rhs_ID | rhs_item_list_ID | rhs_item_ID
+ with Pre => Is_Possibly_Empty_ID (Tree, Empty_Node)
+ -- Empty_Node is the first item in an RHS that can be empty; change
+ -- the RHS to be non-empty.
is
use WisiToken.Syntax_Trees.LR_Utils;
use all type SAL.Base_Peek_Type;
procedure Make_Non_Empty_RHS_Item (Item : in Valid_Node_Access)
- with Pre => Tree.ID (Item) = +rhs_item_ID
+ with Pre =>
+ Tree.ID (Item) = +rhs_item_ID and
+ To_Token_Enum (Tree.ID (Tree.Child (Item, 1))) in rhs_optional_item_ID | rhs_multiple_item_ID
+ -- Edit Item so it cannot be empty. Higher level code promotes the
+ -- empty case to a higher level nonterm.
is
Item_Var : Valid_Node_Access := Item;
begin
- case Tree.RHS_Index (Item) is
- when 0 | 1 | 2 =>
- raise SAL.Programmer_Error;
-
- when 3 => -- rhs_optional_item
+ case To_Token_Enum (Tree.ID (Tree.Child (Item, 1))) is
+ when rhs_optional_item_ID =>
declare
Optional_Item : Valid_Node_Access := Tree.Child (Item, 1);
begin
- case Tree.RHS_Index (Optional_Item) is
- when 0 =>
+ case To_Token_Enum (Tree.ID (Tree.Child (Optional_Item, 1))) is
+ when LEFT_BRACKET_ID =>
+
Tree.Set_Children
(Node => Optional_Item,
New_ID => (+rhs_group_item_ID, 0),
@@ -387,11 +420,12 @@ package body WisiToken.Generate.Tree_Sitter is
Tree.Set_Children
(Node => Item_Var,
- New_ID => (+rhs_item_ID, 5),
+ New_ID => (+rhs_item_ID, 4),
Children =>
(1 => Optional_Item));
- when 1 =>
+ when LEFT_PAREN_ID =>
+
Tree.Set_Children
(Node => Optional_Item,
New_ID => (+rhs_group_item_ID, 0),
@@ -399,17 +433,19 @@ package body WisiToken.Generate.Tree_Sitter is
Tree.Set_Children
(Node => Item_Var,
- New_ID => (+rhs_item_ID, 5),
+ New_ID => (+rhs_item_ID, 4),
Children =>
(1 => Optional_Item));
- when 2 =>
+ when IDENTIFIER_ID =>
+
Tree.Set_Children
(Node => Item_Var,
New_ID => (+rhs_item_ID, 0),
Children => (1 => Tree.Child (Optional_Item, 1)));
- when 3 =>
+ when STRING_LITERAL_SINGLE_ID =>
+
Tree.Set_Children
(Node => Item_Var,
New_ID => (+rhs_item_ID, 1),
@@ -420,36 +456,41 @@ package body WisiToken.Generate.Tree_Sitter is
end case;
end;
- when 4 =>
+ when rhs_multiple_item_ID =>
declare
- Multiple_Item : Valid_Node_Access := Tree.Child (Item, 1);
+ Multiple_Item : Valid_Node_Access := Tree.Child (Item, 1);
+ First_Child : constant Valid_Node_Access := Tree.Child (Multiple_Item, 1);
+ First_Child_ID : constant Token_Enum_ID := To_Token_Enum (Tree.ID (First_Child));
begin
- case Tree.RHS_Index (Multiple_Item) is
- when 0 | 3 | 5 =>
- Tree.Set_Children
- (Multiple_Item,
- (+rhs_multiple_item_ID,
- (case Tree.RHS_Index (Multiple_Item) is
- when 0 => 1,
- when 3 => 2,
- when 5 => 4,
- when others => raise SAL.Programmer_Error)),
- (case Tree.RHS_Index (Multiple_Item) is
- when 0 | 3 =>
- (1 => Tree.Child (Multiple_Item, 1),
- 2 => Tree.Child (Multiple_Item, 2),
- 3 => Tree.Child (Multiple_Item, 3),
- 4 => (case Tree.RHS_Index (Multiple_Item) is
- when 0 => Tree.Add_Terminal (+MINUS_ID),
- when 3 => Tree.Add_Terminal (+PLUS_ID),
- when others => raise SAL.Programmer_Error)),
- when 5 => (1 => Tree.Child (Multiple_Item, 1)),
- when others => raise SAL.Programmer_Error));
+ pragma Assert
+ (case First_Child_ID is
+ when LEFT_BRACE_ID => Tree.Child_Count (Multiple_Item) = 3,
+ when LEFT_PAREN_ID => Tree.ID (Tree.Child (Multiple_Item, 4)) = +STAR_ID,
+ when IDENTIFIER_ID => Tree.ID (Tree.Child (Multiple_Item, 2)) = +STAR_ID,
+ when others => raise SAL.Programmer_Error);
- when others =>
- raise SAL.Programmer_Error with "make_non_empty_rhs_item " & Tree.Image
- (Multiple_Item, RHS_Index => True, Node_Numbers => True);
- end case;
+ Tree.Set_Children
+ (Node => Multiple_Item,
+ New_ID =>
+ (LHS => +rhs_multiple_item_ID,
+ RHS =>
+ (case Tree.RHS_Index (Multiple_Item) is
+ when 0 => 1,
+ when 3 => 2,
+ when 5 => 4,
+ when others => raise SAL.Programmer_Error)),
+ Children =>
+ (case Tree.RHS_Index (Multiple_Item) is
+ when 0 | 3 =>
+ (1 => Tree.Child (Multiple_Item, 1),
+ 2 => Tree.Child (Multiple_Item, 2),
+ 3 => Tree.Child (Multiple_Item, 3),
+ 4 => (case Tree.RHS_Index (Multiple_Item) is
+ when 0 => Tree.Add_Terminal (+MINUS_ID),
+ when 3 => Tree.Add_Terminal (+PLUS_ID),
+ when others => raise SAL.Programmer_Error)),
+ when 5 => (1 => Tree.Child (Multiple_Item, 1)),
+ when others => raise SAL.Programmer_Error));
end;
when others =>
@@ -459,23 +500,22 @@ package body WisiToken.Generate.Tree_Sitter is
begin
case To_Token_Enum (Tree.ID (Empty_Node)) is
- when rhs_item_ID =>
- Make_Non_Empty_RHS_Item (Empty_Node);
+ when rhs_ID =>
+ -- An empty RHS.
+ Delete_Node (Empty_Node);
when rhs_item_list_ID =>
- -- Entire item_list can be empty
declare
- Item_List : constant Constant_List := Creators.Create_List
+ Item_List : constant Constant_List := Creators.Create_List
(Tree, Empty_Node, +rhs_item_list_ID, +rhs_element_ID);
+ First_Item : constant Valid_Node_Access := Element (Item_List.First);
+ Item : constant Valid_Node_Access := Tree.Find_Descendant (First_Item, +rhs_item_ID);
begin
- -- If there is more than one item in the rhs_item_list, we can
- -- arbitrarily make the first non-empty. See ada_lite_ebnf.wy
- -- handled_sequence_of_statements.
- Make_Non_Empty_RHS_Item (Tree.Find_Descendant (Element (Item_List.First), +rhs_item_ID));
+ Make_Non_Empty_RHS_Item (Item);
end;
- when rhs_ID =>
- Delete_Node (Empty_Node);
+ when rhs_item_ID =>
+ Make_Non_Empty_RHS_Item (Empty_Node);
when others =>
raise SAL.Programmer_Error;
@@ -483,8 +523,12 @@ package body WisiToken.Generate.Tree_Sitter is
end Make_Non_Empty;
procedure Make_Optional (Name : in String)
+ -- Convert all occurences of Name in RHS to optional, because it used
+ -- to be possibly empty. Add edited nonterms to Node_To_Check; they
+ -- may now be possibly empty.
is
procedure Find_Nodes (Node : in Valid_Node_Access)
+ -- Search subtree at Node for Name
is
use all type SAL.Base_Peek_Type;
Node_Var : Node_Access := Node;
@@ -495,30 +539,25 @@ package body WisiToken.Generate.Tree_Sitter is
when wisitoken_accept_ID =>
Find_Nodes (Tree.Child (Node, 2));
+ when rhs_alternative_list_ID =>
+ Find_Nodes (Tree.Child (Node, Tree.Child_Count (Node)));
+
when compilation_unit_ID =>
Find_Nodes (Tree.Child (Node, 1));
- when compilation_unit_list_ID | rhs_alternative_list_ID | rhs_item_list_ID | rhs_list_ID =>
+ when compilation_unit_list_ID | rhs_alternative_list_1_ID | rhs_item_list_ID | rhs_list_ID =>
declare
Children : constant Node_Access_Array := Tree.Children (Node);
begin
- case Tree.RHS_Index (Node) is
- when 0 =>
- Find_Nodes (Children (1));
-
- when 1 =>
- Find_Nodes (Children (1));
+ Find_Nodes (Children (1));
+ if Tree.Child_Count (Node) > 1 then
Find_Nodes
(Children
- ((if To_Token_Enum (Tree.ID (Node)) in rhs_list_ID | rhs_alternative_list_ID then 3 else 2)));
-
- when others =>
- -- rhs_list can have other rhs_index, but those nodes should have been
- -- deleted by now.
- raise SAL.Programmer_Error with "Make_Optional.Find_Nodes list: rhs_index" &
- Tree.RHS_Index (Node)'Image & " node " & Tree.Image
- (Node, Node_Numbers => True);
- end case;
+ (case To_Token_Enum (Tree.ID (Node)) is
+ when compilation_unit_list_ID | rhs_item_list_ID => 2,
+ when rhs_alternative_list_1_ID | rhs_list_ID => 3,
+ when others => raise SAL.Programmer_Error));
+ end if;
end;
when declaration_ID =>
@@ -538,24 +577,29 @@ package body WisiToken.Generate.Tree_Sitter is
Find_Nodes (Tree.Child (Node, 2));
when rhs_item_ID =>
- case Tree.RHS_Index (Node) is
- when 0 | 1 =>
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when IDENTIFIER_ID =>
if Name = Get_Text (Tree.Child (Node, 1)) then
+ -- IMPROVEME: could check if already optional (ie parent is single
+ -- rhs_item_list contained in single rhs_alternative_list contained
+ -- in rhs_optional_item), which means the source grammar should be
+ -- changed.
+
Nodes_To_Check.Append (Node);
declare
Child : constant Valid_Node_Access := WisiToken_Grammar_Editing.Add_RHS_Optional_Item
(Tree,
- RHS_Index => (if Tree.RHS_Index (Node) = 0 then 2 else 3),
+ RHS_Index => 2, -- IDENTIFIER QUESTION
Content => Tree.Child (Node, 1));
begin
- Tree.Set_Children (Node_Var, (+rhs_item_ID, 3), (1 => Child));
+ Tree.Set_Children (Node_Var, (+rhs_item_ID, 2), (1 => Child));
end;
end if;
- when 2 =>
+ when STRING_LITERAL_SINGLE_ID =>
null;
- when 3 | 4 | 5 =>
+ when attribute_ID | rhs_optional_item_ID | rhs_multiple_item_ID | rhs_group_item_ID =>
Find_Nodes (Tree.Child (Node, 1));
when others =>
@@ -563,19 +607,18 @@ package body WisiToken.Generate.Tree_Sitter is
end case;
when rhs_multiple_item_ID =>
- case Tree.RHS_Index (Node) is
- when 0 | 1 | 2 | 3 =>
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when LEFT_BRACE_ID | LEFT_PAREN_ID =>
Find_Nodes (Tree.Child (Node, 2));
- when 4 =>
- Nodes_To_Check.Append (Node);
-
- Tree.Set_Children
- (Node_Var, (+rhs_multiple_item_ID, 5), (Tree.Child (Node, 1), Tree.Add_Terminal (+STAR_ID)));
+ when IDENTIFIER_ID =>
+ if Name = Get_Text (Tree.Child (Node, 1)) and
+ To_Token_Enum (Tree.ID (Tree.Child (Node, 2))) = STAR_ID
+ then
+ Generate.Put_Error
+ (Tree.Error_Message (Node, "'" & Name & "' is both optional and possibly empty."));
+ end if;
- when 5 =>
- -- already optional
- null;
when others =>
raise SAL.Programmer_Error;
end case;
@@ -610,17 +653,33 @@ package body WisiToken.Generate.Tree_Sitter is
end Make_Optional;
begin
+ WisiToken_Grammar_Editing.EBNF_Allowed := True;
+
if Trace_Generate_EBNF > Outline then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("tree_sitter eliminate empty productions start");
if Trace_Generate_EBNF > Detail then
Tree.Print_Tree (Tree.Root);
+ Ada.Text_IO.New_Line;
end if;
end if;
Find_Empty_Nodes (Tree.Root);
-- Also finds %if etc, adds them to Nodes_To_Delete.
+ if No_Empty and Empty_Nonterms.Length > 0 then
+ declare
+ use Ada.Strings.Unbounded;
+ Empty_Image : Unbounded_String;
+ begin
+ for Nonterm of Empty_Nonterms loop
+ Append (Empty_Image, Nonterm.Name);
+ Append (Empty_Image, " ");
+ end loop;
+ raise Grammar_Error with "Tree_Sitter forbids possibly empty nonterms: " & (-Empty_Image);
+ end;
+ end if;
+
if Trace_Generate_EBNF > Outline then
Ada.Text_IO.Put_Line ("nodes to delete:" & Nodes_To_Delete.Length'Image);
end if;
@@ -628,14 +687,18 @@ package body WisiToken.Generate.Tree_Sitter is
for Node of Nodes_To_Delete loop
Delete_Node (Node);
end loop;
+ Nodes_To_Delete.Clear;
Data.Error_Reported.Clear;
- Tree.Validate_Tree
- (Data, Data.Error_Reported,
- Root => Tree.Root,
- Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
- Node_Index_Order => True);
+ if Debug_Mode then
+ Tree.Validate_Tree
+ (Data'Unchecked_Access, Data.Error_Reported,
+ Root => Tree.Root,
+ Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
+ Node_Index_Order => True,
+ Line_Number_Order => False);
+ end if;
if Trace_Generate_EBNF > Outline then
Ada.Text_IO.Put_Line ("empty nonterms:");
@@ -646,6 +709,8 @@ package body WisiToken.Generate.Tree_Sitter is
end if;
for Nonterm of Empty_Nonterms loop
+ -- IMPROVEME: tree-sitter allows the start nonterm of the grammar to be empty,
+ -- but no other nonterms may be empty. But we don't find Start_Node until we are in Print_Tree_Sitter.
Make_Non_Empty (Nonterm.Empty_Node);
end loop;
@@ -654,11 +719,13 @@ package body WisiToken.Generate.Tree_Sitter is
Ada.Text_IO.New_Line;
end if;
- Tree.Validate_Tree
- (Data, Data.Error_Reported,
- Root => Tree.Root,
- Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
- Node_Index_Order => False);
+ if Debug_Mode then
+ Tree.Validate_Tree
+ (Data'Unchecked_Access, Data.Error_Reported,
+ Root => Tree.Root,
+ Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
+ Node_Index_Order => False); -- Implies Line_Number_Order = False
+ end if;
for Nonterm of Empty_Nonterms loop
Make_Optional (-Nonterm.Name);
@@ -669,11 +736,13 @@ package body WisiToken.Generate.Tree_Sitter is
Ada.Text_IO.New_Line;
end if;
- Tree.Validate_Tree
- (Data, Data.Error_Reported,
- Root => Tree.Root,
- Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
- Node_Index_Order => False);
+ if Debug_Mode then
+ Tree.Validate_Tree
+ (Data'Unchecked_Access, Data.Error_Reported,
+ Root => Tree.Root,
+ Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
+ Node_Index_Order => False);
+ end if;
declare
use Valid_Node_Access_Lists;
@@ -712,16 +781,18 @@ package body WisiToken.Generate.Tree_Sitter is
Ada.Text_IO.New_Line;
end if;
- Tree.Validate_Tree
- (Data, Data.Error_Reported,
- Root => Tree.Root,
- Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
- Node_Index_Order => False);
+ if Debug_Mode then
+ Tree.Validate_Tree
+ (Data'Unchecked_Access, Data.Error_Reported,
+ Root => Tree.Root,
+ Validate_Node => WisiToken_Grammar_Editing.Validate_Node'Access,
+ Node_Index_Order => False);
+ end if;
if Trace_Generate_EBNF > Detail then
- Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("tree_sitter eliminate empty productions end");
Tree.Print_Tree (Tree.Root);
+ Ada.Text_IO.New_Line;
end if;
end Eliminate_Empty_Productions;
@@ -734,7 +805,24 @@ package body WisiToken.Generate.Tree_Sitter is
is
use all type Ada.Containers.Count_Type;
- File : File_Type;
+ -- We process the EBNF tree, not the grammar description in Data, to
+ -- take advantage of the higher-level tree_sitter grammar
+ -- descriptions like 'optional' and 'repeat'.
+
+ -- 'hidden rules'
+ -- (https://tree-sitter.github.io/tree-sitter/creating-parsers#hiding-rules)
+ -- are different from 'inline'
+ -- (https://tree-sitter.github.io/tree-sitter/creating-parsers#the-grammar-dsl);
+ -- hidden rules are in the parse table, inline are not. The parse
+ -- action for hidden rules does not create a syntax tree node. We
+ -- don't support them in the wisi parser generator, because that
+ -- would mean Undo_Reduce cannot be implemented, which is required
+ -- for our error recover algorithm. (IMPROVEME: maybe undo_reduce
+ -- is just more complicated?).
+ --
+ -- For now, we don't use them in the generated tree-sitter grammar,
+ -- so client code doesn't care whether it's a wisi or tree-sitter
+ -- parser.
Extras : WisiToken.BNF.String_Lists.List;
Conflicts : WisiToken.BNF.String_Lists.List;
@@ -748,6 +836,13 @@ package body WisiToken.Generate.Tree_Sitter is
-- Local bodies
+ procedure Put_Commented (Text : in WisiToken.BNF.String_Lists.List)
+ is begin
+ for Line of Text loop
+ Put_Line ("// " & Line);
+ end loop;
+ end Put_Commented;
+
function Get_Text (Tree_Index : in Valid_Node_Access) return String
is
function Strip_Delimiters (Tree_Index : in Valid_Node_Access) return String
@@ -796,15 +891,15 @@ package body WisiToken.Generate.Tree_Sitter is
procedure Not_Translated (Label : in String; Node : in Valid_Node_Access)
is begin
- New_Line (File);
- Put (File, "// " & Label & ": not translated: " & Node_Access'Image (Node) & ":" &
+ New_Line;
+ Put ("// " & Label & ": not translated: " & Node_Access'Image (Node) & ":" &
Tree.Image (Node, Children => True));
Put_Line
(Current_Error,
Tree.Error_Message
(Node,
- "not translated: " &
+ Label & ": not translated: " &
Tree.Image
(Node,
RHS_Index => True,
@@ -812,50 +907,85 @@ package body WisiToken.Generate.Tree_Sitter is
Node_Numbers => True)));
end Not_Translated;
- procedure Put_RHS_Alternative_List (Node : in Valid_Node_Access; First : in Boolean)
- with Pre => Tree.ID (Node) = +rhs_alternative_list_ID
+ procedure Put_Attr_List (Attr_List : in Valid_Node_Access)
+ is
+ Prec : constant WisiToken.Base_Precedence_ID := WisiToken_Grammar_Runtime.Get_Precedence
+ (Data, Tree, Attr_List);
+ Assoc : constant WisiToken.Associativity := WisiToken_Grammar_Runtime.Get_Associativity
+ (Data, Tree, Attr_List);
+ begin
+ case Assoc is
+ when Left =>
+ Put ("prec.left(");
+
+ when Right =>
+ Put ("prec.right(");
+
+ when None =>
+ pragma Assert (Prec /= No_Precedence);
+ Put ("prec(");
+ end case;
+ if Prec /= No_Precedence then
+ Put ("'" & (-Data.Precedence_Inverse_Map (Prec)) & "', ");
+ end if;
+ end Put_Attr_List;
+
+ procedure Put_RHS_Alternative_List_1 (Node : in Valid_Node_Access; First : in Boolean)
+ with Pre => Tree.ID (Node) = +rhs_alternative_list_1_ID
is begin
- case Tree.RHS_Index (Node) is
- when 0 =>
- -- If only alternative, don't need "choice()".
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when rhs_item_list_ID =>
+ -- Only one alternative, don't need "choice()".
Put_RHS_Item_List (Tree.Child (Node, 1), First => True);
- when 1 =>
+ when rhs_alternative_list_1_ID =>
if First then
- Put (File, "choice(");
+ Put ("choice(");
end if;
- Put_RHS_Alternative_List (Tree.Child (Node, 1), First => False);
- Put (File, ", ");
+ Put_RHS_Alternative_List_1 (Tree.Child (Node, 1), First => False);
+ Put (", ");
Put_RHS_Item_List (Tree.Child (Node, 3), First => True);
if First then
- Put (File, ")");
+ Put (")");
end if;
when others =>
- Not_Translated ("Put_RHS_Alternative_List", Node);
+ Not_Translated ("Put_RHS_Alternative_List_1", Node);
end case;
+ end Put_RHS_Alternative_List_1;
+
+ procedure Put_RHS_Alternative_List (Node : in Valid_Node_Access)
+ with Pre => Tree.ID (Node) = +rhs_alternative_list_ID
+ is
+ RHS_Alt_List_1 : Valid_Node_Access := Tree.Child (Node, 1);
+ begin
+ if Tree.ID (Tree.Child (Node, 1)) = +attribute_list_ID then
+ Put_Attr_List (Tree.Child (Node, 1));
+ RHS_Alt_List_1 := Tree.Child (Node, 2);
+ end if;
+
+ Put_RHS_Alternative_List_1 (RHS_Alt_List_1, First => True);
end Put_RHS_Alternative_List;
procedure Put_RHS_Optional_Item (Node : in Valid_Node_Access)
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)));
+ Put ("optional(");
+
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when LEFT_BRACKET_ID | LEFT_PAREN_ID =>
+ Put_RHS_Alternative_List (Tree.Child (Node, 2));
+ when IDENTIFIER_ID =>
+ Put ("$." & Get_Text (Tree.Child (Node, 1)));
+ when STRING_LITERAL_SINGLE_ID =>
+ Put (Get_Text (Tree.Child (Node, 1)));
when others =>
- Not_Translated ("Put_RHS_Optional_Item", Node);
+ raise SAL.Programmer_Error;
end case;
- Put (File, ")");
+ Put (")");
end Put_RHS_Optional_Item;
procedure Put_RHS_Multiple_Item (Node : in Valid_Node_Access)
@@ -863,24 +993,24 @@ package body WisiToken.Generate.Tree_Sitter is
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, ")");
+ Put ("repeat(");
+ Put_RHS_Alternative_List (Tree.Child (Node, 2));
+ Put (")");
when 1 | 2 =>
- Put (File, "repeat1(");
- Put_RHS_Alternative_List (Tree.Child (Node, 2), First => True);
- Put (File, ")");
+ Put ("repeat1(");
+ Put_RHS_Alternative_List (Tree.Child (Node, 2));
+ Put (")");
when 4 =>
- Put (File, "repeat1(");
- Put (File, "$." & Get_Text (Tree.Child (Node, 1)));
- Put (File, ")");
+ Put ("repeat1(");
+ Put ("$." & Get_Text (Tree.Child (Node, 1)));
+ Put (")");
when 5 =>
- Put (File, "repeat(");
- Put (File, "$." & Get_Text (Tree.Child (Node, 1)));
- Put (File, ")");
+ Put ("repeat(");
+ Put ("$." & Get_Text (Tree.Child (Node, 1)));
+ Put (")");
when others =>
Not_Translated ("Put_RHS_Multiple_Item", Node);
@@ -890,84 +1020,63 @@ package body WisiToken.Generate.Tree_Sitter is
procedure Put_RHS_Group_Item (Node : in Valid_Node_Access)
with Pre => Tree.ID (Node) = +rhs_group_item_ID
is begin
- Put_RHS_Alternative_List (Tree.Child (Node, 2), First => True);
+ Put_RHS_Alternative_List (Tree.Child (Node, 2));
end Put_RHS_Group_Item;
procedure Put_RHS_Item (Node : in Valid_Node_Access)
with Pre => Tree.ID (Node) = +rhs_item_ID
- is begin
- case Tree.RHS_Index (Node) is
- when 0 =>
+ is
+ function Keyword_Name (Decl : in Valid_Node_Access) return String
+ with Pre => KEYWORD_ID = To_Token_Enum (Tree.ID (Tree.Child (Decl, 2)))
+ is begin
+ return Get_Text (Tree.Child (Decl, 3));
+ end Keyword_Name;
+
+ begin
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when IDENTIFIER_ID =>
+ Put ("$." & Get_Text (Node));
+
+ when STRING_LITERAL_SINGLE_ID =>
+ -- Case insensitive
declare
- Ident : constant String := Get_Text (Node);
- Decl : constant Node_Access := WisiToken_Grammar_Editing.Find_Declaration (Data, Tree, Ident);
+ Text : constant String := Get_Text (Node);
+
+ -- Token may be declared with "...", but referenced with '...'.
+ Decl : constant Node_Access := WisiToken_Grammar_Editing.Find_Declaration_By_Value
+ (Data, Tree, Text (Text'First + 1 .. Text'Last - 1), Strip_Quotes => True);
begin
if Decl = Invalid_Node_Access then
- Generate.Put_Error (Tree.Error_Message (Node, "decl for '" & Ident & "' not found"));
-
- elsif Tree.ID (Decl) = +nonterminal_ID then
- Put (File, "$." & Get_Text (Tree.Child (Decl, 1)));
-
+ Put ("caseInsensitive(" & Text & ")");
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;
- List : constant Constant_List := Creators.Create_List
- (Tree, Tree.Child (Decl, 4), +declaration_item_list_ID, +declaration_item_ID);
- Item : constant Valid_Node_Access := Tree.Child (Element (List.First), 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 tree-sitter: STRING_LITERAL_1_ID in regexp is case insensitive; not
- -- clear how to do that in tree-sitter.
- Put (File, Get_Text (Item));
-
- when others =>
- Not_Translated ("put_rhs_item ident token", Node);
- end case;
- end;
+ case To_Token_Enum (Tree.ID (Tree.Child (Decl, 2))) is
+ when Wisitoken_Grammar_Actions.TOKEN_ID =>
+ -- Assume it's punctuation or similar where case doesn't matter.
+ Put (Text);
- when others =>
- Not_Translated ("put_rhs_item ident", Node);
- end case;
+ when KEYWORD_ID =>
+ Put ("$." & Keyword_Name (Decl));
when others =>
- Not_Translated ("put_rhs_item 0", Node);
+ raise SAL.Programmer_Error;
end case;
end if;
end;
- when 1 =>
- -- STRING_LITERAL_2
- Put (File, Get_Text (Node));
-
- when 2 =>
- -- ignore attribute
+ when attribute_ID =>
null;
- when 3 =>
+ when rhs_optional_item_ID =>
Put_RHS_Optional_Item (Tree.Child (Node, 1));
- when 4 =>
+ when rhs_multiple_item_ID =>
Put_RHS_Multiple_Item (Tree.Child (Node, 1));
- when 5 =>
+ when rhs_group_item_ID =>
Put_RHS_Group_Item (Tree.Child (Node, 1));
when others =>
- Not_Translated ("Put_RHS_Item", Node);
+ raise SAL.Programmer_Error with "node: " & Trimmed_Image (Node);
end case;
end Put_RHS_Item;
@@ -979,11 +1088,12 @@ package body WisiToken.Generate.Tree_Sitter is
Put_RHS_Item (Tree.Child (Node, 1));
when 1 =>
- -- Ignore the label
+ Put ("field('" & Get_Text (Tree.Child (Node, 1)) & "', ");
Put_RHS_Item (Tree.Child (Node, 3));
+ Put (")");
when others =>
- Not_Translated ("Put_RHS_Element", Node);
+ raise SAL.Programmer_Error;
end case;
end Put_RHS_Element;
@@ -995,14 +1105,14 @@ package body WisiToken.Generate.Tree_Sitter is
Put_RHS_Element (Children (1));
else
if First then
- Put (File, "seq(");
+ Put ("seq(");
end if;
Put_RHS_Item_List (Children (1), First => False);
- Put (File, ", ");
+ Put (", ");
Put_RHS_Element (Children (2));
if First then
- Put (File, ")");
+ Put (")");
end if;
end if;
end Put_RHS_Item_List;
@@ -1022,12 +1132,21 @@ package body WisiToken.Generate.Tree_Sitter is
when others => Tree.Child (RHS_List, 2))),
"empty RHS forbidden by tree-sitter"));
- when 1 .. 3 =>
- Put_RHS_Item_List (Tree.Child (Node, 1), First => True);
- -- tree-sitter does not have actions in the grammar
+ when 1 .. 6 =>
+ if Tree.ID (Tree.Child (Node, 1)) = +attribute_list_ID then
+ Put_Attr_List (Tree.Child (Node, 1));
+ Put_RHS_Item_List (Tree.Child (Node, 2), First => True);
+ Put (')');
+ else
+ Put_RHS_Item_List (Tree.Child (Node, 1), First => True);
+ end if;
+
+ -- tree-sitter does not have actions in the grammar. FIXME: output
+ -- actions map to separate file for Emacs wisi with tree-sitter
+ -- parser.
when others =>
- Not_Translated ("put_rhs", Node);
+ raise SAL.Programmer_Error;
end case;
end Put_RHS;
@@ -1042,27 +1161,46 @@ package body WisiToken.Generate.Tree_Sitter is
when 1 =>
if First then
- Put (File, "choice(");
+ Put ("choice(");
+ Indent := @ + 2;
end if;
Put_RHS_List (Children (1), First => False);
- Put (File, ",");
+ Put (", ");
Put_RHS (Children (3));
if First then
- Put (File, ")");
+ Put (")");
+ Indent := @ - 2;
end if;
- when 2 .. 4 =>
- -- Should have been eliminated by Eliminate_Empty_Productions
- raise SAL.Programmer_Error with "Print_Tree_Sitter rhs_list %if " &
- Tree.Image (Node, Node_Numbers => True);
+ when 2 .. 6 =>
+ -- Could have been eliminated by Eliminate_Empty_Productions, but that's hard.
+ Generate.Put_Error
+ (Tree.Error_Message (Node, "%if in rhs_list not supported with tree_sitter."));
when others =>
raise SAL.Programmer_Error;
end case;
end Put_RHS_List;
+ function String_Regexp (Value : in Valid_Node_Access) return String
+ with Pre => To_Token_Enum (Tree.ID (Value)) in STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID | REGEXP_ID
+ -- Return a javascript expression for Value
+ is
+ use Ada.Strings, Ada.Strings.Fixed;
+ begin
+ return
+ (case To_Token_Enum (Tree.ID (Value)) is
+ when STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID => Get_Text (Value),
+
+ when REGEXP_ID =>
+ -- Value must be '/.../' or 'new RegExp("...")' as needed; not checked here.
+ Trim (Get_Text (Value), Both),
+
+ when others => raise SAL.Programmer_Error);
+ end String_Regexp;
+
procedure Process_Node (Node : in Valid_Node_Access)
is begin
if Node = Start_Node then
@@ -1079,143 +1217,224 @@ package body WisiToken.Generate.Tree_Sitter is
Process_Node (Tree.Child (Node, 1));
when compilation_unit_list_ID =>
- declare
- Children : constant Node_Access_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;
+ raise SAL.Programmer_Error;
when declaration_ID =>
- raise SAL.Not_Implemented with "FIXME: match current wisitoken_grammar.wy";
- -- case To_Token_Enum (Tree.ID (Tree.Child (Node, 2))) is
- -- when Wisitoken_Grammar_Actions.TOKEN_ID | NON_GRAMMAR_ID =>
- -- -- We need tokens with 'regexp' values because they are not defined
- -- -- elsewhere, 'punctuation' tokens for consistent names, and
- -- -- 'line-comment' to allow comments. tree-sitter default 'extras'
- -- -- handles whitespace and newline, but if we define 'comment', we
- -- -- also need 'new-line' and 'whitespace'.
- -- declare
- -- use Ada.Strings;
- -- use Ada.Strings.Fixed;
- -- use WisiToken.Syntax_Trees.LR_Utils;
- -- Name : constant String := Get_Text (Tree.Child (Node, 3));
- -- Class : constant Token_Enum_ID := To_Token_Enum (Tree.ID (Tree.Child (Tree.Child (Node, 2), 1)));
- -- Kind : constant String :=
- -- (if Class in NON_GRAMMAR_ID | Wisitoken_Grammar_Actions.TOKEN_ID
- -- then Get_Text (Tree.Child (Tree.Child (Node, 2), 3))
- -- else "keyword");
- -- List : constant Constant_List := Creators.Create_List
- -- (Tree, Tree.Child (Node, 4), +declaration_item_list_ID, +declaration_item_ID);
- -- Value : constant Valid_Node_Access := Tree.Child (Element (List.First), 1);
- -- -- We are ignoring any repair image
- -- begin
- -- if Class = NON_GRAMMAR_ID then
- -- if Kind = "line-comment" then
- -- -- WORKAROUND: tree-sitter 0.16.6 treats rule "token(seq('--',
- -- -- /.*/))" correctly for an Ada comment, but not extra "/--.*/". See
- -- -- github tree-sitter issue 651 - closed without resolving this
- -- -- question, but it does provide a workaround.
- -- Put_Line (File, Name & ": $ => token(seq(" & Get_Text (Value) & ", /.*/)),");
- -- Extras.Append ("$." & Name);
- -- else
- -- Extras.Append ("/" & Trim (Get_Text (Value), Both) & "/");
- -- end if;
-
- -- elsif Kind = "punctuation" then
- -- Put_Line (File, Name & ": $ => " & Get_Text (Value) & ",");
-
- -- elsif To_Token_Enum (Tree.ID (Value)) = REGEXP_ID then
- -- Put_Line (File, Name & ": $ => /" & Trim (Get_Text (Value), Both) & "/,");
-
- -- end if;
- -- end;
-
- -- when 1 =>
- -- -- new-line with no regexp; tree-sitter defaults to DOS, Unix newline.
- -- null;
-
- -- when 2 =>
- -- -- FIXME tree-sitter: CODE copyright_license
- -- null;
-
- -- when 3 =>
- -- declare
- -- Kind : constant String := Get_Text (Tree.Child (Node, 2));
- -- begin
- -- -- FIXME tree-sitter: lexer_regexp
- -- if Kind = "conflict" then
- -- -- .wy LR format:
- -- -- %conflict action LHS [| action LHS]* 'on token' on
- -- -- I I+1
- -- --
- -- -- .wy Tree_Sitter format:
- -- -- %conflict LHS (LHS)*
- -- --
- -- -- .js format:
- -- -- [$.LHS, $.LHS, ...]
-
- -- declare
- -- use Ada.Strings.Unbounded;
-
- -- Tree_Indices : constant Valid_Node_Access_Array := Tree.Get_Terminals (Tree.Child (Node, 3));
- -- Result : Unbounded_String := +"[";
- -- begin
- -- if Tree_Indices'Length < 3 or else Tree.ID (Tree_Indices (3)) /= +BAR_ID then
- -- -- Tree_Sitter format
- -- for LHS of Tree_Indices loop
- -- Result := @ & "$." & Get_Text (LHS) & ", ";
- -- end loop;
-
- -- else
- -- -- LR format
- -- declare
- -- use all type SAL.Base_Peek_Type;
- -- I : SAL.Peek_Type := Tree_Indices'First;
- -- begin
- -- loop
- -- Result := @ & "$." & Get_Text (Tree_Indices (I + 1)) & ", ";
-
- -- I := I + 2;
- -- exit when Tree.ID (Tree_Indices (I)) /= +BAR_ID;
- -- I := I + 1;
- -- end loop;
- -- end;
- -- end if;
- -- Conflicts.Append (-Result & ']');
- -- end;
- -- end if;
- -- end;
-
- -- when 4 =>
- -- -- %case_insensitive
- -- null;
-
- -- when 5 .. 9 =>
- -- -- Should have been eliminated by Eliminate_Empty_Productions
- -- raise SAL.Programmer_Error with "Print_Tree_Sitter declaration %if " &
- -- Tree.Image (Node, Node_Numbers => True);
-
- -- when others =>
- -- raise SAL.Programmer_Error;
- -- end case;
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 2))) is
+ when Wisitoken_Grammar_Actions.TOKEN_ID | NON_GRAMMAR_ID =>
+ declare
+ Kind : constant String := Get_Text (Tree.Child (Node, 4));
+ Name : constant String := Get_Text (Tree.Child (Node, 6));
+ Regexp_String : constant Node_Access := Tree.Child (Node, 7);
+ Value : constant Node_Access :=
+ (if Regexp_String = Invalid_Node_Access
+ then Invalid_Node_Access
+ else Tree.Child (Regexp_String, 1));
+ -- We are ignoring any repair image; tree_sitter grammar does not
+ -- support that.
+ begin
+
+ if Kind = "comment-new-line" then
+ if not (To_Token_Enum (Tree.ID (Value)) in
+ STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID)
+ then
+ Generate.Put_Error
+ (Tree.Error_Message
+ (Node, "string literal required for comment-new-line; found " &
+ Image (Tree.ID (Value), Tree.Lexer.Descriptor.all)));
+ else
+
+ -- WORKAROUND: tree-sitter 0.16.6 treats rule "token(seq('--',
+ -- /.*/))" correctly for an Ada comment, but not extra "/--.*/". See
+ -- github tree-sitter issue 651 - closed without resolving this
+ -- question, but it does provide a workaround.
+ Indent_Line (Name & ": $ => token(seq(" & Get_Text (Value) & ", /.*/)),");
+ New_Line;
+ Extras.Append ("$." & Name);
+ end if;
+
+ elsif Kind = "comment-one-line" then
+ -- FIXME: We need to provide an external scanner for this.
+ raise SAL.Not_Implemented with "comment-one-line not implemented in tree_sitter";
+
+ elsif Kind = "delimited-text" then
+ -- FIXME: We need to provide an external scanner for this.
+ raise SAL.Not_Implemented with "comment-one-line not implemented in tree_sitter";
+
+ elsif Value = Invalid_Node_Access then
+ -- new-line with no regexp; tree-sitter defaults to DOS and Unix newline.
+ null;
+
+ else
+ -- If the source grammar uses string literals in the nonterminal
+ -- RHSs, we don't need to define this token. However, some code using
+ -- this parser may rely on the token names, so we define them to
+ -- ensure they are the same for wisi and tree-sitter parsers.
+ Indent_Line (Name & ": $ => " & String_Regexp (Value) & ",");
+ New_Line;
+ end if;
+ end;
+
+ when KEYWORD_ID =>
+ declare
+ Name : constant String := Get_Text (Tree.Child (Node, 3));
+ Value : constant Node_Access := Tree.Child (Tree.Child (Node, 4), 1);
+ begin
+ -- Value is a string or regular expression.
+ case To_Token_Enum (Tree.ID (Value)) is
+ when STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID =>
+
+ if To_Token_Enum (Tree.ID (Value)) = STRING_LITERAL_SINGLE_ID or
+ Data.Language_Params.Case_Insensitive
+ then
+ Indent_Line (Name & ": $ => reservedInsensitive(" & Get_Text (Value) & "),");
+
+ else
+ -- Case sensitive
+ --
+ -- Wisitoken follows the re2c convention; single quoted strings are
+ -- case insensitive. See comment at definition of
+ -- 'reservedInsenstive' below for 'reserved' use.
+ Indent_Line (Name & ": $ => reserved(" & Get_Text (Value) & "),");
+ end if;
+
+ when REGEXP_ID =>
+ Indent_Line (Name & ": $ => " & String_Regexp (Value) & ",");
+
+ when others =>
+ raise SAL.Programmer_Error with "node: " & Trimmed_Image (Node)'Image;
+ end case;
+ New_Line;
+ end;
+
+ when CODE_ID =>
+ declare
+ Loc_List : constant Syntax_Trees.Valid_Node_Access_Array :=
+ WisiToken_Grammar_Runtime.Get_Code_Location_List (Tree, Node);
+ begin
+ if Get_Text (Loc_List (Loc_List'First)) = "copyright_license" then
+ -- handled in Print_Tree_Sitter top level
+ null;
+ else
+ Generate.Put_Error (Tree.Error_Message (Node, "%code with tree-sitter not supported."));
+ end if;
+ end;
+
+ when CONFLICT_ID =>
+ -- .wy LR format:
+ -- %conflict action LHS (| action LHS)* 'on token' on
+ -- I I+1
+ --
+ -- .wy Tree_Sitter format:
+ -- %conflict LHS (LHS)*
+ --
+ -- .js format:
+ -- [$.LHS, $.LHS, ...]
+
+ declare
+ use Ada.Strings.Unbounded;
+
+ Tree_Indices : constant Valid_Node_Access_Array := Tree.Get_Terminals (Tree.Child (Node, 3));
+ Result : Unbounded_String := +"[";
+ begin
+ if Tree_Indices'Length < 3 or else Tree.ID (Tree_Indices (3)) /= +BAR_ID then
+ -- Tree_Sitter format
+ for LHS of Tree_Indices loop
+ Result := @ & "$." & Get_Text (LHS) & ", ";
+ end loop;
+
+ else
+ -- LR format
+ declare
+ use all type SAL.Base_Peek_Type;
+ I : SAL.Peek_Type := Tree_Indices'First;
+ begin
+ loop
+ Result := @ & "$." & Get_Text (Tree_Indices (I + 1)) & ", ";
+
+ I := I + 3;
+ exit when I > Tree_Indices'Last;
+ end loop;
+ end;
+ end if;
+ Conflicts.Append (-Result & ']');
+ end;
+
+ when CONFLICT_RESOLUTION_ID =>
+ null;
+
+ when IDENTIFIER_ID =>
+ declare
+ Kind : constant String := Get_Text (Tree.Child (Node, 2));
+ begin
+ if Kind = "case_insensitive" then
+ -- The meta phase grammar file parse sets
+ -- Data.Language_Params.Case_Insensitive.
+ null;
+
+ elsif Kind = "elisp_action" then
+ -- Used in generating Action code
+ null;
+
+ elsif Kind = "elisp_face" then
+ -- Used in generating Action code
+ null;
+
+ elsif Kind = "elisp_indent" then
+ -- Used in generating Action code
+ null;
+
+ elsif Kind = "generate" then
+ -- Handled in meta phase grammar parser.
+ null;
+
+ elsif Kind = "lexer_regexp" then
+ -- Handled in Print_Tree_Sitter top level
+ null;
+
+ elsif Kind = "meta_syntax" then
+ -- Handled in meta phase grammar parser.
+ null;
+
+ elsif Kind = "precedence" then
+ -- Handled in Print_Tree_Sitter top level
+ null;
+
+ elsif Kind = "start" then
+ -- Handled in Print_Tree_Sitter top level.
+ null;
+
+ else
+ Generate.Put_Error
+ (Tree.Error_Message (Node, "declaration not supported with tree_sitter."));
+ end if;
+ end;
+
+ when IF_ID | ELSIF_ID | END_ID =>
+ -- Should have been eliminated by Eliminate_Empty_Productions
+ raise SAL.Programmer_Error with "Print_Tree_Sitter declaration %if " &
+ Tree.Image (Node, Node_Numbers => True);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
when nonterminal_ID =>
declare
Children : constant Node_Access_Array := Tree.Children (Node);
begin
- Put (File, Get_Text (Children (1)) & ": $ => ");
+ Indent_Start (Get_Text (Children (1)) & ": $ => ");
- Put_RHS_List (Children (3), First => True);
+ if Tree.ID (Tree.Child (Node, 2)) = +attribute_list_ID then
+ Put_Attr_List (Tree.Child (Node, 2));
+ Put_RHS_List (Children (4), First => True);
+ Put (')');
+ else
+ Put_RHS_List (Children (3), First => True);
+ end if;
- Put_Line (File, ",");
+ Put_Line (",");
+ New_Line;
end;
when wisitoken_accept_ID =>
@@ -1226,58 +1445,176 @@ package body WisiToken.Generate.Tree_Sitter is
raise SAL.Not_Implemented with Image (Tree.ID (Node), Wisitoken_Grammar_Actions.Descriptor);
end case;
end Process_Node;
+
+ use Syntax_Trees.LR_Utils;
+ Compilation_Unit_List : constant Constant_List := Creators.Create_List
+ (Tree, Tree.Find_Descendant (Tree.Root, +compilation_unit_list_ID),
+ +compilation_unit_list_ID, +compilation_unit_ID);
+
begin
if Trace_Generate_EBNF > Outline then
- Ada.Text_IO.Put_Line ("translate to tree_sitter");
+ Put_Line ("translate to tree_sitter");
end if;
- Create (File, Out_File, Output_File_Name);
- Put_Line (File, "// generated from " & Tree.Lexer.File_Name & " -*- buffer-read-only:t -*-");
-
- Put_Line (File, "module.exports = grammar({");
- Put_Line (File, " name: '" & Language_Name & "',");
+ declare
+ File : File_Type;
+ begin
+ Create (File, Out_File, Output_File_Name);
+ Set_Output (File);
- Put_Line (File, " rules: {");
+ Indent := 1;
+ Indent_Line ("// generated from " & Tree.Lexer.File_Name & " -*- buffer-read-only:t js-indent-level:3 -*-");
+ New_Line;
- -- Start symbol must be the first rule; that's how tree-sitter knows
- -- it's the start symbol. accept rule with wisi-eoi is implicit in
- -- tree-sitter (as in .wy).
- if -Data.Language_Params.Start_Token = "" then
- Generate.Put_Error (Generate.Error_Message (Tree.Lexer.File_Name, 1, "%start not specified"));
- else
- declare
- Temp : constant Node_Access := WisiToken_Grammar_Editing.Find_Declaration
- (Data, Tree, -Data.Language_Params.Start_Token);
- begin
- Process_Node (Temp);
- Start_Node := Temp;
- end;
- end if;
+ for Unit of Compilation_Unit_List loop
+ declare
+ Node : constant Valid_Node_Access := Tree.Child (Unit, 1);
+ begin
+ if To_Token_Enum (Tree.ID (Node)) = declaration_ID and then
+ To_Token_Enum (Tree.ID (Tree.Child (Node, 2))) = CODE_ID
+ then
+ declare
+ Loc_List : constant Syntax_Trees.Valid_Node_Access_Array :=
+ WisiToken_Grammar_Runtime.Get_Code_Location_List (Tree, Node);
+ begin
+ if Get_Text (Loc_List (Loc_List'First)) = "copyright_license" then
+ Put_Commented (WisiToken.BNF.Split_Lines (Get_Text (Tree.Child (Node, 4))));
+ else
+ Generate.Put_Error (Tree.Error_Message (Node, "%code with tree-sitter not supported."));
+ end if;
+ end;
+ exit;
+ end if;
+ end;
+ end loop;
- Process_Node (Tree.Root);
- Put (File, " }");
+ -- First some useful functions
+
+ -- 'word' is reserved in tree-sitter;
+ -- https://tree-sitter.github.io/tree-sitter/creating-parsers#keywords.
+ --
+ -- However, since we support case insensitive keywords, we can't rely
+ -- on that mechanism to ignore keywords that are not bounded by word
+ -- separators. So we use precedence. The only way we can tell if a
+ -- STRING_LITERAL_SINGLE token in an RHS needs this is to find the
+ -- declaration for it, and check if it is %keyword. So all reserved
+ -- keywords must be declared.
+
+ Indent_Line ("const reserved = regex => token(prec(2, new RegExp(regex)));");
+ Indent_Line
+ ("const caseInsensitive = word => word.split('')" &
+ " .map(letter => `[${letter}${letter.toUpperCase()}]`) .join('');");
+ Indent_Line ("const reservedInsensitive = word => alias(reserved(caseInsensitive(word)), word) ;");
+ New_Line;
+
+ -- Now any lexer_regexp
+ for Unit of Compilation_Unit_List loop
+ declare
+ Node : constant Valid_Node_Access := Tree.Child (Unit, 1);
+ begin
+ if To_Token_Enum (Tree.ID (Node)) = declaration_ID and then
+ To_Token_Enum (Tree.ID (Tree.Child (Node, 2))) = IDENTIFIER_ID and then
+ Get_Text (Tree.Child (Node, 2)) = "lexer_regexp"
+ then
+ declare
+ Terminals : constant Valid_Node_Access_Array := Tree.Get_Terminals (Tree.Child (Node, 3));
- if Conflicts.Length > 0 then
- Put_Line (File, ",");
- Put_Line (File, " conflicts: $ => [");
- for Item of Conflicts loop
- Put_Line (File, " " & Item & ",");
+ Name : constant String := Get_Text (Terminals (1));
+ Value : constant Node_Access := Terminals (2);
+ begin
+ Put_Line ("const " & Name & " = " & String_Regexp (Value) & ";");
+ end;
+ end if;
+ end;
end loop;
- Put (File, " ]");
- end if;
- if Extras.Length > 0 then
- Put_Line (File, ",");
- Put_Line (File, " extras: $ => [");
- for Item of Extras loop
- Put_Line (File, " " & Item & ",");
+ Indent_Line ("module.exports = grammar({");
+ Indent := @ + 3;
+
+ Indent_Line ("name: '" & Language_Name & "',");
+ New_Line;
+
+ if not Data.Precedence_Lists.Is_Empty then
+ Indent_Line ("precedences: () => [");
+ Indent := @ + 2;
+ for List of Data.Precedence_Lists loop
+ Indent_Line ("[");
+ Indent := @ + 2;
+ for ID of List loop
+ Indent_Line ("'" & (-Data.Precedence_Inverse_Map (ID)) & "',");
+ end loop;
+ Indent := @ - 2;
+ Indent_Line ("],");
+ end loop;
+ Indent := @ - 2;
+
+ Indent_Line ("],");
+ New_Line;
+ end if;
+
+ Indent_Line ("rules: {");
+ Indent := @ + 3;
+
+ -- Start symbol must be the first rule; that's how tree-sitter knows
+ -- it's the start symbol. accept rule with wisi-eoi is implicit in
+ -- tree-sitter (as in .wy).
+ if -Data.Language_Params.Start_Token = "" then
+ Generate.Put_Error (Generate.Error_Message (Tree.Lexer.File_Name, 1, "%start not specified"));
+ else
+ declare
+ Temp : constant Node_Access := WisiToken_Grammar_Editing.Find_Declaration
+ (Data, Tree, -Data.Language_Params.Start_Token);
+ begin
+ Process_Node (Temp);
+ Start_Node := Temp;
+ end;
+ end if;
+
+ -- A grammar typically consists of a large number of
+ -- compilation_units, each one fairly short. Process_Node is
+ -- recursive; if we use that to process the compilation_Units, it can
+ -- overflow the stack (it did for ada_full.wy). So we handle the
+ -- compilation_Units as a list here, and use recursion for the
+ -- declarations and nonterms.
+ for Unit of Compilation_Unit_List loop
+ Process_Node (Unit);
end loop;
- Put_Line (File, " ],");
- end if;
- Put (File, " }");
- Put_Line (File, ");");
- Close (File);
+ Put (" }");
+ Indent := @ - 3;
+
+ if Conflicts.Length > 0 then
+ Put_Line (",");
+ Put_Line (" conflicts: $ => [");
+ Indent := @ + 3;
+ for Item of Conflicts loop
+ Indent_Line (Item & ",");
+ end loop;
+ Put (" ]");
+ Indent := @ - 3;
+ end if;
+
+ if Extras.Length > 0 then
+ -- Since we have an explicit 'extras', we need to specify space and newline.
+ Extras.Append ("/\s|\\\r?\n/");
+ Put_Line (",");
+ Put_Line (" extras: $ => [");
+ Indent := @ + 3;
+ for Item of Extras loop
+ Indent_Line (Item & ",");
+ end loop;
+ Put_Line (" ],");
+ Indent := @ - 3;
+ end if;
+ Put ("}");
+ Indent := @ - 3;
+ pragma Assert (Indent = 1);
+
+ Indent_Line (");");
+ Set_Output (Standard_Output);
+
+ Close (File);
+ end;
end Print_Tree_Sitter;
procedure Create_Test_Main (Output_File_Name_Root : in String)
diff --git a/wisitoken-generate-tree_sitter.ads b/wisitoken-generate-tree_sitter.ads
index 3107539..9a5b9c3 100644
--- a/wisitoken-generate-tree_sitter.ads
+++ b/wisitoken-generate-tree_sitter.ads
@@ -1,8 +1,8 @@
-- Abstract :
--
--- WisiToken utilities for using the tree-sitter parser.
+-- Translate a wisitoken grammar file to a tree-sitter grammar file.
--
--- Copyright (C) 2020, 2021, 2022 Free Software Foundation All Rights Reserved.
+-- Copyright (C) 2020 - 2023 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
@@ -19,10 +19,13 @@ with WisiToken_Grammar_Runtime;
package WisiToken.Generate.Tree_Sitter is
procedure Eliminate_Empty_Productions
- (Data : in out WisiToken_Grammar_Runtime.User_Data_Type;
- Tree : in out WisiToken.Syntax_Trees.Tree);
- -- Edit Tree to eliminate productions that can be empty, which are
- -- forbidden by the tree-sitter generator.
+ (Data : in out WisiToken_Grammar_Runtime.User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ No_Empty : in Boolean);
+ -- If No_Empty, raise Grammar_Error if Tree has productions that can
+ -- be empty, which are forbidden by the tree-sitter generator.
+ --
+ -- Otherwise, edit Tree to eliminate productions that can be empty.
--
-- Also processes %if, so subsequent passes don't have to.
@@ -32,6 +35,8 @@ package WisiToken.Generate.Tree_Sitter is
Lexer : in WisiToken.Lexer.Handle;
Output_File_Name : in String;
Language_Name : in String);
+ -- Output tree-sitter grammar to Output_File_Name.
+ --
-- Tree is 'in out' because we use WisiToken.Syntax_Tree.LR_Utils lists.
procedure Create_Test_Main (Output_File_Name_Root : in String);
diff --git a/wisitoken-in_parse_actions.adb b/wisitoken-in_parse_actions.adb
index e9e5d63..70ded77 100644
--- a/wisitoken-in_parse_actions.adb
+++ b/wisitoken-in_parse_actions.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -34,14 +34,23 @@ package body WisiToken.In_Parse_Actions is
return Syntax_Trees.In_Parse_Actions.Status_Label'Image (Item.Label);
when Syntax_Trees.In_Parse_Actions.Error =>
declare
- Begin_Node : constant Valid_Node_Access := Tree.Child (Error_Node, Item.Begin_Name);
- End_Node : constant Valid_Node_Access := Tree.Child (Error_Node, Item.End_Name);
+ use all type SAL.Base_Peek_Type;
+ Begin_Node : constant Node_Access :=
+ (if Item.Begin_Name = 0
+ then Invalid_Node_Access
+ else Tree.Child (Error_Node, Item.Begin_Name));
+ End_Node : constant Node_Access :=
+ (if Item.End_Name = 0
+ then Invalid_Node_Access
+ else Tree.Child (Error_Node, Item.End_Name));
begin
return '(' & Syntax_Trees.In_Parse_Actions.Status_Label'Image (Item.Label) & ", " &
- Tree.Image (Begin_Node) & "'" & Tree.Lexer.Buffer_Text
- (Tree.Byte_Region (Begin_Node, Trailing_Non_Grammar => False)) & "'," &
- Tree.Image (End_Node) & "'" & Tree.Lexer.Buffer_Text
- (Tree.Byte_Region (End_Node, Trailing_Non_Grammar => False)) & "')";
+ (if Item.Begin_Name = 0 then "<absent>"
+ else Tree.Image (Begin_Node) & "'" & Tree.Lexer.Buffer_Text
+ (Tree.Byte_Region (Begin_Node, Trailing_Non_Grammar => False))) & "'," &
+ (if Item.End_Name = 0 then "<absent>"
+ else Tree.Image (End_Node) & "'" & Tree.Lexer.Buffer_Text
+ (Tree.Byte_Region (End_Node, Trailing_Non_Grammar => False))) & "')";
end;
end case;
end Image;
@@ -49,22 +58,25 @@ package body WisiToken.In_Parse_Actions is
function Match_Names
(Tree : in Syntax_Trees.Tree;
Tokens : in Syntax_Trees.Recover_Token_Array;
- Start_Index : in Positive_Index_Type;
- End_Index : in Positive_Index_Type;
+ Start_Index : in SAL.Base_Peek_Type;
+ End_Index : in SAL.Base_Peek_Type;
End_Optional : in Boolean)
return Syntax_Trees.In_Parse_Actions.Status
is
+ use all type SAL.Base_Peek_Type;
use Syntax_Trees;
begin
- if Tree.Contains_Virtual_Terminal (Tokens (Start_Index)) or
- Tree.Contains_Virtual_Terminal (Tokens (End_Index))
+ if (Start_Index > 0 and then Tree.Contains_Virtual_Terminal (Tokens (Start_Index))) or
+ (End_Index > 0 and then Tree.Contains_Virtual_Terminal (Tokens (End_Index)))
then
return (Label => Syntax_Trees.In_Parse_Actions.Ok);
end if;
declare
- Start_Name_Region : constant Buffer_Region := Tree.Name (Tokens (Start_Index));
- End_Name_Region : constant Buffer_Region := Tree.Name (Tokens (End_Index));
+ Start_Name_Region : constant Buffer_Region :=
+ (if Start_Index > 0 then Tree.Name (Tokens (Start_Index)) else Null_Buffer_Region);
+ End_Name_Region : constant Buffer_Region :=
+ (if End_Index > 0 then Tree.Name (Tokens (End_Index)) else Null_Buffer_Region);
function Equal return Boolean
is
diff --git a/wisitoken-in_parse_actions.ads b/wisitoken-in_parse_actions.ads
index 49428ff..b70a010 100644
--- a/wisitoken-in_parse_actions.ads
+++ b/wisitoken-in_parse_actions.ads
@@ -2,7 +2,7 @@
--
-- Grammar in parse action routines.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -29,13 +29,17 @@ package WisiToken.In_Parse_Actions is
function Match_Names
(Tree : in Syntax_Trees.Tree;
Tokens : in Syntax_Trees.Recover_Token_Array;
- Start_Index : in Positive_Index_Type;
- End_Index : in Positive_Index_Type;
+ Start_Index : in SAL.Base_Peek_Type;
+ End_Index : in SAL.Base_Peek_Type;
End_Optional : in Boolean)
return Syntax_Trees.In_Parse_Actions.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.
+ --
+ -- Start_, End_Index may be 0; in that case the corresponding token
+ -- is absent in the production; Match_Names treats it as an empty
+ -- name.
function Propagate_Name
(Tree : in Syntax_Trees.Tree;
diff --git a/wisitoken-lexer.adb b/wisitoken-lexer.adb
index 1d0981b..6d7096c 100644
--- a/wisitoken-lexer.adb
+++ b/wisitoken-lexer.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -240,7 +240,7 @@ package body WisiToken.Lexer is
return Base_Buffer_Pos
is begin
for I in To_Buffer_Index (Source, Region.First) .. To_Buffer_Index (Source, Region.Last) loop
- if Source.Buffer (I) = ASCII.LF then
+ if Buffer (Source)(I) = ASCII.LF then
return From_Buffer_Index (Source, I);
end if;
end loop;
diff --git a/wisitoken-parse-lr-mckenzie_recover-explore.adb b/wisitoken-parse-lr-mckenzie_recover-explore.adb
index ebc5308..1c61409 100644
--- a/wisitoken-parse-lr-mckenzie_recover-explore.adb
+++ b/wisitoken-parse-lr-mckenzie_recover-explore.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -47,7 +47,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (Config.Ops) then
Super.Config_Full (Shared, "do_shift ops", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
Append (Config.Ops, Op);
end if;
@@ -70,7 +70,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Config.Stack.Is_Full then
Super.Config_Full (Shared, "do_shift stack", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
Config.Stack.Push ((State, (Virtual => True, ID => ID, others => <>)));
end if;
@@ -290,7 +290,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (Item.Config.Ops) then
Super.Config_Full (Shared, "fast_forward 1", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
declare
Next_Node : constant Syntax_Trees.Valid_Node_Access :=
@@ -361,7 +361,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
else
if Is_Full (Item.Config.Ops) then
Super.Config_Full (Shared, "check 1", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
declare
Next_Node : constant Syntax_Trees.Node_Access := Parse.Peek_Current_First_Sequential_Terminal
@@ -456,7 +456,11 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Item.Shift_Count = 0 then
-- Parse did not process any Deletes from Insert_Delete; Fast_Forward
-- did that. So the very first token caused an error, and Config is
- -- unchanged. Just set the error.
+ -- unchanged. Just set the error. FIXME:
+ -- ada_mode-recover_repair_2.adb language_fixes solution is pure
+ -- delete; we get here, and should enqueue for another Language_Fixes
+ -- try. But in other cases fast_forward was a pure no-op. Enqueue in
+ -- fast_forward if pure delete?
Config.Error_Token := Item.Config.Error_Token;
Config.In_Parse_Action_Status := (Label => Ok);
return Continue;
@@ -590,7 +594,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (New_Config.Ops) then
Super.Config_Full (Shared, "push_back 1", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Do_Push_Back (Shared.Tree, New_Config);
@@ -693,7 +697,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (New_Config.Ops) then
Super.Config_Full (Shared, "undo_reduce 1", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Unchecked_Undo_Reduce (Super, Shared, New_Config);
@@ -866,7 +870,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
is begin
if Is_Full (Work) then
Super.Config_Full (Shared, "Minimal_Complete_Actions " & Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
Add (Work, Item);
end if;
@@ -894,7 +898,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
Inserted (Inserted_Last) := Action.ID;
else
Super.Config_Full (Shared, "minimal_do_shift Inserted", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Do_Shift
@@ -1343,7 +1347,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
-- Parser to delete it.
if Is_Full (Config.Ops) then
Super.Config_Full (Shared, "insert quote 2 a " & Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Append (Config.Ops, (Delete, Shared.Tree.ID (Node), Index));
@@ -1378,7 +1382,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
begin
if Is_Full (Config.Ops) then
Super.Config_Full (Shared, "insert quote 2 b " & Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
pragma Assert (Is_Terminal (Shared.Tree.ID (Stream (To_Delete)), Shared.Tree.Lexer.Descriptor.all));
@@ -1480,7 +1484,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if not Has_Space (Config.Ops, Ada.Containers.Count_Type (Matching)) then
Super.Config_Full (Shared, "insert quote 1 " & Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
for I in 1 .. Matching loop
if not Push_Back_Valid (Super, Shared, Config, Push_Back_Undo_Reduce => False) then
@@ -1552,7 +1556,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (Config.Ops) then
Super.Config_Full (Shared, Full_Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Item := Config.Stack.Peek;
@@ -1600,7 +1604,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
begin
if not Has_Space (Config.Ops, Ada.Containers.Count_Type (Last - First + 1)) then
Super.Config_Full (Shared, "insert quote 3 " & Label, Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Find_First;
@@ -2085,7 +2089,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Explore is
if Is_Full (New_Config.Ops) then
Super.Config_Full (Shared, "delete", Parser_Index);
- raise Bad_Config;
+ raise Invalid_Case;
else
Append (New_Config.Ops, (Delete, Next_ID, Next_Index));
end if;
diff --git a/wisitoken-parse-lr-mckenzie_recover-parse.adb b/wisitoken-parse-lr-mckenzie_recover-parse.adb
index 51066b2..d8b8cb5 100644
--- a/wisitoken-parse-lr-mckenzie_recover-parse.adb
+++ b/wisitoken-parse-lr-mckenzie_recover-parse.adb
@@ -2,7 +2,7 @@
--
-- See spec
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -791,7 +791,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Parse is
if Trace_McKenzie > Outline then
Put_Line (Tree, Super.Stream (Parser_Index),
Trace_Prefix & ": too many conflicts; abandoning");
- raise Bad_Config;
+ raise Invalid_Case;
end if;
else
if Trace_McKenzie > Detail then
diff --git a/wisitoken-parse-lr-mckenzie_recover.adb b/wisitoken-parse-lr-mckenzie_recover.adb
index 02356ce..f1cc583 100644
--- a/wisitoken-parse-lr-mckenzie_recover.adb
+++ b/wisitoken-parse-lr-mckenzie_recover.adb
@@ -2,7 +2,7 @@
--
-- See spec
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -380,6 +380,8 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
-- parser recovered from the error.
Parser_State.Set_Verb (Shift);
+ -- We do this now so Parser_State tracks changes to the current error
+ -- node when we apply ops like Delete.
Parser_State.Set_Current_Error_Features (Tree);
pragma Assert (Parser_State.Current_Recover_Op = No_Insert_Delete);
@@ -828,7 +830,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
Check (Shared_Parser.Tree.ID (Node), Expected_ID, Shared_Parser.Tree.Lexer.Descriptor.all);
end if;
if Is_Full (Config.Ops) or Is_Full (Config.Insert_Delete) then
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Append (Config.Ops, Op);
Append (Config.Insert_Delete, Op);
@@ -1411,7 +1413,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
Op : constant Recover_Op := (Insert, ID, Shared_Parser.Tree.Get_Sequential_Index (Before));
begin
if Is_Full (Config.Ops) or Is_Full (Config.Insert_Delete) then
- raise Bad_Config;
+ raise Invalid_Case;
end if;
Append (Config.Ops, Op);
Append (Config.Insert_Delete, Op);
@@ -1668,6 +1670,11 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
Config : in out Configuration;
Push_Back_Undo_Reduce : in Boolean)
is begin
+ if Recover_Op_Arrays.Is_Full (Config.Ops) then
+ -- We don't call Super.Config_Full here, because we don't have Parser_Index.
+ raise Invalid_Case;
+ end if;
+
-- We relax the "don't push back into previous recover" restriction
-- for Language_Fixes; see test_mckenzie_recover.adb Missing_Name_5.
if not Push_Back_Valid (Super, Shared_Parser, Config, Push_Back_Undo_Reduce => Push_Back_Undo_Reduce) then
@@ -1720,7 +1727,9 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
Descriptor : WisiToken.Descriptor renames Tree.Lexer.Descriptor.all;
Result : Ada.Strings.Unbounded.Unbounded_String :=
- +" " & Tree.Trimmed_Image (Parser_Label) & ": " & -- leading space for consistency with existing tests.
+ -- Leading space for consistency with existing tests. Add space to
+ -- other messages for consistency.
+ " " & (+Tree.Trimmed_Image (Parser_Label)) & ": " &
(if Message'Length > 0 then Message & ":" else "");
begin
Result := Result & Natural'Image (Config.Cost);
@@ -1832,6 +1841,10 @@ package body WisiToken.Parse.LR.McKenzie_Recover is
Prev_State := Goto_For (Table, Prev_State, Tree.ID (C));
end if;
if Stack.Is_Full then
+ -- Stack size is a design constraint, so this could be Invalid_Case.
+ -- But the required size depends on the nesting level of user code,
+ -- not the complexity of the error recover config. So it's a serious
+ -- error to hit it.
raise Bad_Config;
end if;
Stack.Push ((Prev_State, Tree.Get_Recover_Token (C)));
diff --git a/wisitoken-parse-lr-mckenzie_recover.ads b/wisitoken-parse-lr-mckenzie_recover.ads
index 219c87d..5684621 100644
--- a/wisitoken-parse-lr-mckenzie_recover.ads
+++ b/wisitoken-parse-lr-mckenzie_recover.ads
@@ -11,7 +11,7 @@
-- [Grune 2008] Parsing Techniques, A Practical Guide, Second
-- Edition. Dick Grune, Ceriel J.H. Jacobs.
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 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
@@ -40,9 +40,10 @@ package WisiToken.Parse.LR.McKenzie_Recover is
-- programming bug can easily be ignored by abandoning the config.
Invalid_Case : exception;
- -- Raised to abandon error recover cases that don't apply, when they
- -- are not easily abandoned by 'if' or 'case'. We don't use
- -- Bad_Config for that, because it is not a programmer error.
+ -- Raised to abandon error recover cases that don't apply or violate
+ -- some design constraint like Config.Ops full, when they are not
+ -- easily abandoned by 'if' or 'case'. We don't use Bad_Config for
+ -- that, because it is not a programmer error.
type Recover_Status is (Fail_Check_Delta, Fail_Enqueue_Limit, Fail_No_Configs_Left, Fail_Programmer_Error, Success);
@@ -317,8 +318,8 @@ private
Shared_Parser : in out LR.Parser.Parser;
Config : in out Configuration;
Push_Back_Undo_Reduce : in Boolean);
- -- If not Push_Back_Valid, raise Invalid_Case. Otherwise do
- -- Push_Back.
+ -- If not Push_Back_Valid, or if Config.Ops full, raise Invalid_Case.
+ -- Otherwise do Push_Back.
--
-- Normally Push_Back_Valid forbids push_back of an entire
-- Undo_Reduce; Language_Fixes may override that by setting
diff --git a/wisitoken-parse-lr-parser-parse.adb b/wisitoken-parse-lr-parser-parse.adb
index e9cd8f2..75d98ec 100644
--- a/wisitoken-parse-lr-parser-parse.adb
+++ b/wisitoken-parse-lr-parser-parse.adb
@@ -2,7 +2,7 @@
--
-- see spec.
--
--- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2023 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
@@ -34,10 +34,6 @@ begin
Trace.Put_Clock ("start");
end if;
- if Shared_Parser.User_Data /= null then
- Shared_Parser.User_Data.Reset;
- end if;
-
Shared_Parser.Tree.Lexer.Errors.Clear;
Shared_Parser.String_Quote_Checked := Invalid_Line_Number;
diff --git a/wisitoken-parse-lr-parser.adb b/wisitoken-parse-lr-parser.adb
index 914d08b..72fb4e0 100644
--- a/wisitoken-parse-lr-parser.adb
+++ b/wisitoken-parse-lr-parser.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -989,14 +989,22 @@ package body WisiToken.Parse.LR.Parser is
if Debug_Mode then
declare
- I : Integer := 1;
+ Error_Reported : WisiToken.Syntax_Trees.Node_Sets.Set;
begin
- for Node of Parser_State.Recover_Insert_Delete loop
- if not Parser.Tree.In_Tree (Node) then
- raise SAL.Programmer_Error with "recover_insert_delete node" & I'Image & " not in tree";
- end if;
- I := @ + 1;
- end loop;
+ if Parser.User_Data = null then
+ Parser.Tree.Validate_Tree
+ (null, Error_Reported,
+ Node_Index_Order => not Incremental_Parse,
+ Validate_Node => Syntax_Trees.Mark_In_Tree'Access);
+ Parser.Tree.Clear_Augmented;
+ else
+ Parser.Tree.Validate_Tree
+ (Parser.User_Data, Error_Reported, Node_Index_Order => not Incremental_Parse);
+ end if;
+
+ if Error_Reported.Count /= 0 then
+ raise WisiToken.Validate_Error with "pre execute_actions: validate_tree failed";
+ end if;
end;
end if;
@@ -1011,6 +1019,19 @@ package body WisiToken.Parse.LR.Parser is
Parser.Tree.Lexer.Trace.New_Line;
end if;
+ if Debug_Mode then
+ declare
+ I : Integer := 1;
+ begin
+ for Node of Parser_State.Recover_Insert_Delete loop
+ if not Parser.Tree.In_Tree (Node) then
+ raise SAL.Programmer_Error with "recover_insert_delete node" & I'Image & " not in tree";
+ end if;
+ I := @ + 1;
+ end loop;
+ end;
+ end if;
+
-- ada-mode-recover_33.adb requires calling Insert_Token,
-- Delete_Token in lexical order, which is Recover_Insert_Delete
-- order. Other use cases would benefit from calling all Delete
@@ -1066,22 +1087,18 @@ package body WisiToken.Parse.LR.Parser is
Error_Reported : WisiToken.Syntax_Trees.Node_Sets.Set;
begin
if Parser.User_Data = null then
- declare
- Dummy : User_Data_Type;
- begin
- Parser.Tree.Validate_Tree
- (Dummy, Error_Reported,
- Node_Index_Order => not Incremental_Parse,
- Validate_Node => Syntax_Trees.Mark_In_Tree'Access);
- end;
+ Parser.Tree.Validate_Tree
+ (null, Error_Reported,
+ Node_Index_Order => not Incremental_Parse,
+ Validate_Node => Syntax_Trees.Mark_In_Tree'Access);
Parser.Tree.Clear_Augmented;
else
Parser.Tree.Validate_Tree
- (Parser.User_Data.all, Error_Reported, Node_Index_Order => not Incremental_Parse);
+ (Parser.User_Data, Error_Reported, Node_Index_Order => not Incremental_Parse);
end if;
if Error_Reported.Count /= 0 then
- raise WisiToken.Validate_Error with "parser: validate_tree failed";
+ raise WisiToken.Validate_Error with "post execute_actions: validate_tree failed";
end if;
end;
end if;
@@ -3442,7 +3459,7 @@ package body WisiToken.Parse.LR.Parser is
declare
Error_Reported : WisiToken.Syntax_Trees.Node_Sets.Set;
begin
- Parser.Tree.Validate_Tree (Parser.User_Data.all, Error_Reported, Node_Index_Order => False);
+ Parser.Tree.Validate_Tree (Parser.User_Data, Error_Reported, Node_Index_Order => False);
if Error_Reported.Count /= 0 then
if Trace_Incremental_Parse > Outline then
Tree.Lexer.Trace.New_Line;
diff --git a/wisitoken-parse-lr-parser_no_recover.adb b/wisitoken-parse-lr-parser_no_recover.adb
index d1296e9..003ee40 100644
--- a/wisitoken-parse-lr-parser_no_recover.adb
+++ b/wisitoken-parse-lr-parser_no_recover.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002 - 2005, 2008 - 2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -224,7 +224,6 @@ package body WisiToken.Parse.LR.Parser_No_Recover is
use all type KMN_Lists.List;
use all type WisiToken.Syntax_Trees.Terminal_Ref;
- use all type Syntax_Trees.User_Data_Access;
Trace : WisiToken.Trace'Class renames Shared_Parser.Tree.Lexer.Trace.all;
@@ -253,10 +252,6 @@ package body WisiToken.Parse.LR.Parser_No_Recover is
raise SAL.Programmer_Error;
end if;
- if Shared_Parser.User_Data /= null then
- Shared_Parser.User_Data.Reset;
- end if;
-
Shared_Parser.Tree.Clear;
Shared_Parser.Lex_All;
diff --git a/wisitoken-parse-lr.ads b/wisitoken-parse-lr.ads
index bcc4b2f..aae0c7c 100644
--- a/wisitoken-parse-lr.ads
+++ b/wisitoken-parse-lr.ads
@@ -9,7 +9,7 @@
--
-- See wisitoken.ads
--
--- Copyright (C) 2002, 2003, 2009, 2010, 2013 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2002, 2003, 2009, 2010, 2013 - 2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -69,8 +69,9 @@ package WisiToken.Parse.LR is
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.
+ -- The production that produced this action. Used to find precedence
+ -- during grammar generation conflict resolution, in_parse actions
+ -- during parse, and kernel items during error recovery.
case Verb is
when Shift =>
diff --git a/wisitoken-parse-packrat-generated.adb b/wisitoken-parse-packrat-generated.adb
index 81589db..ff82edf 100644
--- a/wisitoken-parse-packrat-generated.adb
+++ b/wisitoken-parse-packrat-generated.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -26,7 +26,6 @@ package body WisiToken.Parse.Packrat.Generated is
Pre_Edited : in Boolean := False)
is
pragma Unreferenced (Log_File, Pre_Edited);
- use all type WisiToken.Syntax_Trees.User_Data_Access;
use all type Ada.Containers.Count_Type;
Trace : WisiToken.Trace'Class renames Parser.Tree.Lexer.Trace.all;
Result : Memo_Entry;
@@ -42,9 +41,6 @@ package body WisiToken.Parse.Packrat.Generated is
Clear (Parser.Derivs);
Parser.Tree.Clear;
- if Parser.User_Data /= null then
- Parser.User_Data.Reset;
- end if;
Parser.Lex_All; -- Creates Tree.Shared_Stream
-- FIXME: ref_count fails in this usage; works in procedural.
diff --git a/wisitoken-parse-packrat-procedural.adb b/wisitoken-parse-packrat-procedural.adb
index be74ebe..856ad17 100644
--- a/wisitoken-parse-packrat-procedural.adb
+++ b/wisitoken-parse-packrat-procedural.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -388,7 +388,6 @@ package body WisiToken.Parse.Packrat.Procedural is
is
pragma Unreferenced (Log_File, Pre_Edited);
use all type Ada.Containers.Count_Type;
- use all type WisiToken.Syntax_Trees.User_Data_Access;
Trace : WisiToken.Trace'Class renames Parser.Tree.Lexer.Trace.all;
Result : Memo_Entry;
@@ -407,9 +406,6 @@ package body WisiToken.Parse.Packrat.Procedural is
Clear (Parser.Derivs);
- if Parser.User_Data /= null then
- Parser.User_Data.Reset;
- end if;
Parser.Lex_All;
Result := Apply_Rule
diff --git a/wisitoken-parse.adb b/wisitoken-parse.adb
index 108df00..c4bbf1c 100644
--- a/wisitoken-parse.adb
+++ b/wisitoken-parse.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -218,7 +218,7 @@ package body WisiToken.Parse is
when Insert =>
(if Item.Ins_Node = Invalid_Node_Access
then Image (Item.Ins_ID, Tree.Lexer.Descriptor.all)
- else Tree.Image (Item.Ins_Node)) &
+ else Tree.Image (Item.Ins_Node, Node_Numbers => True)) &
"," & Item.Ins_Before'Image,
when Delete =>
(if Item.Del_Node = Invalid_Node_Access
diff --git a/wisitoken-productions.adb b/wisitoken-productions.adb
index 2f1892f..7fdb400 100644
--- a/wisitoken-productions.adb
+++ b/wisitoken-productions.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018, 2020 Free Software Foundation, Inc.
+-- Copyright (C) 2018, 2020, 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -51,14 +51,20 @@ package body WisiToken.Productions is
function Image
(LHS : in Token_ID;
RHS_Index : in Natural;
- RHS : in Token_ID_Arrays.Vector;
+ RHS : in Right_Hand_Side;
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
+ if RHS.Associativity /= None then
+ Append (Result, " <" & RHS.Associativity'Image & ">");
+ end if;
+ if RHS.Precedence /= No_Precedence then
+ Append (Result, " <" & Trimmed_Image (RHS.Precedence) & ">");
+ end if;
+ for ID of RHS.Tokens loop
Result := Result & ' ' & Image (ID, Descriptor);
end loop;
return To_String (Result);
@@ -70,7 +76,10 @@ package body WisiToken.Productions is
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 P.Precedence /= No_Precedence then
+ Put ('<' & P.Precedence'Image & "> ");
+ end if;
+ Put (Image (P.LHS, R, P.RHSs (R), Descriptor));
if (for all Item of Grammar (P.LHS).RHSs (R).Recursion => Item = None) then
New_Line;
else
@@ -80,4 +89,30 @@ package body WisiToken.Productions is
end loop;
end Put;
+ function Get_Associativity
+ (Grammar : in Prod_Arrays.Vector;
+ ID : in Production_ID)
+ return WisiToken.Associativity
+ is begin
+ if Grammar (ID.LHS).RHSs.Is_Empty then
+ return None;
+ else
+ return Grammar (ID.LHS).RHSs (ID.RHS).Associativity;
+ end if;
+ end Get_Associativity;
+
+ function Get_Precedence
+ (Grammar : in Prod_Arrays.Vector;
+ ID : in Production_ID)
+ return Base_Precedence_ID
+ is begin
+ if Grammar (ID.LHS).RHSs.Is_Empty then
+ return Grammar (ID.LHS).Precedence;
+ elsif Grammar (ID.LHS).RHSs (ID.RHS).Precedence /= No_Precedence then
+ return Grammar (ID.LHS).RHSs (ID.RHS).Precedence;
+ else
+ return Grammar (ID.LHS).Precedence;
+ end if;
+ end Get_Precedence;
+
end WisiToken.Productions;
diff --git a/wisitoken-productions.ads b/wisitoken-productions.ads
index f3412b2..7f1f4cf 100644
--- a/wisitoken-productions.ads
+++ b/wisitoken-productions.ads
@@ -2,7 +2,7 @@
--
-- Type and operations for building grammar productions.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -39,6 +39,9 @@ package WisiToken.Productions is
Post_Parse_Action : Syntax_Trees.Post_Parse_Action := null;
In_Parse_Action : Syntax_Trees.In_Parse_Actions.In_Parse_Action := null;
+
+ Associativity : WisiToken.Associativity := WisiToken.None;
+ Precedence : WisiToken.Base_Precedence_ID := WisiToken.No_Precedence;
end record
with Dynamic_Predicate =>
(Tokens.Length = 0 or Tokens.First_Index = 1) and
@@ -49,9 +52,10 @@ package WisiToken.Productions is
(Natural, Right_Hand_Side, Default_Element => (others => <>));
type Instance is record
- LHS : Token_ID := Invalid_Token_ID;
- Optimized_List : Boolean := False;
+ LHS : Token_ID := Invalid_Token_ID;
+ Optimized_List : Boolean := False;
RHSs : RHS_Arrays.Vector;
+ Precedence : WisiToken.Base_Precedence_ID := WisiToken.No_Precedence;
end record;
package Prod_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
@@ -63,16 +67,31 @@ package WisiToken.Productions is
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)
+ (LHS : in Token_ID;
+ RHS_Index : in Natural;
+ RHS : in Right_Hand_Side;
+ 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.
+ function Get_Associativity
+ (Grammar : in Prod_Arrays.Vector;
+ ID : in Production_ID)
+ return WisiToken.Associativity
+ with Pre => not Grammar.Is_Empty;
+ -- Return the associativity that applies to ID.
+
+ function Get_Precedence
+ (Grammar : in Prod_Arrays.Vector;
+ ID : in Production_ID)
+ return Base_Precedence_ID
+ with Pre => not Grammar.Is_Empty;
+ -- Return the precedence that applies to ID; the RHS precedence if
+ -- not No_Precedence, else the LHS precedence.
+
package Line_Number_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
(Natural, Line_Number_Type, Default_Element => Line_Number_Type'First);
diff --git a/wisitoken-syntax_trees-lr_utils.adb b/wisitoken-syntax_trees-lr_utils.adb
index 1960eaa..76755f4 100644
--- a/wisitoken-syntax_trees-lr_utils.adb
+++ b/wisitoken-syntax_trees-lr_utils.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2019 - 2022 Stephen Leake All Rights Reserved.
+-- Copyright (C) 2019 - 2023 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
@@ -86,7 +86,8 @@ package body WisiToken.Syntax_Trees.LR_Utils is
Result := Child;
exit;
else
- raise SAL.Programmer_Error with "node" & Result'Image & " is not an element of the list";
+ raise SAL.Programmer_Error with "node " & Tree.Image (Result, Node_Numbers => True) &
+ " is not an element of the list at " & Tree.Image (Root, Node_Numbers => True);
end if;
end;
end loop;
@@ -650,7 +651,7 @@ package body WisiToken.Syntax_Trees.LR_Utils is
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
+ loop
exit when not Has_Element (Item);
Dest_List.Append (Dest_List.Tree.Copy_Subtree (Item.Node, User_Data));
diff --git a/wisitoken-syntax_trees.adb b/wisitoken-syntax_trees.adb
index 4a1e376..7bcbcc3 100644
--- a/wisitoken-syntax_trees.adb
+++ b/wisitoken-syntax_trees.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -224,6 +224,11 @@ package body WisiToken.Syntax_Trees is
Prev_Terminal.Ref.Node.Following_Deleted.Append (Deleted_Node);
+ for Node of Deleted_Node.Following_Deleted loop
+ Prev_Terminal.Ref.Node.Following_Deleted.Append (Node);
+ end loop;
+ Deleted_Node.Following_Deleted.Clear;
+
-- We need to move the non_grammar now, so they are correct for later
-- error recover sessions. test_incremental.adb : Edit_String_10
@@ -1919,7 +1924,7 @@ package body WisiToken.Syntax_Trees is
function Copy_Augmented
(User_Data : in User_Data_Type;
- Augmented : in Augmented_Class_Access)
+ Augmented : in not null Augmented_Class_Access)
return Augmented_Class_Access
is begin
raise SAL.Programmer_Error;
@@ -1940,6 +1945,13 @@ package body WisiToken.Syntax_Trees is
is
use all type Error_Data_Lists.List;
New_Node : Node_Access;
+ Actual_Error_List : constant Error_List_Access :=
+ (if Set_Error_List
+ then New_Error_List
+ else
+ (if Node.Error_List = null
+ then null
+ else new Error_Data_Lists.List'(Node.Error_List.all)));
begin
case Node.Label is
when Source_Terminal =>
@@ -1957,13 +1969,7 @@ package body WisiToken.Syntax_Trees is
(if Node.Augmented = null or User_Data = null
then null
else Copy_Augmented (User_Data.all, Node.Augmented)),
- Error_List =>
- (if Set_Error_List
- then New_Error_List
- else
- (if Node.Error_List = null
- then null
- else new Error_Data_Lists.List'(Node.Error_List.all))),
+ Error_List => Actual_Error_List,
Non_Grammar => Node.Non_Grammar,
Sequential_Index => Node.Sequential_Index,
Following_Deleted => Valid_Node_Access_Lists.Empty_List);
@@ -1994,7 +2000,7 @@ package body WisiToken.Syntax_Trees is
(if Node.Augmented = null or User_Data = null
then null
else Copy_Augmented (User_Data.all, Node.Augmented)),
- Error_List => New_Error_List,
+ Error_List => Actual_Error_List,
Non_Grammar => Node.Non_Grammar,
Sequential_Index => Node.Sequential_Index,
Insert_Location => Node.Insert_Location);
@@ -2012,7 +2018,7 @@ package body WisiToken.Syntax_Trees is
(if Node.Augmented = null or User_Data = null
then null
else Copy_Augmented (User_Data.all, Node.Augmented)),
- Error_List => New_Error_List,
+ Error_List => Actual_Error_List,
Non_Grammar => Node.Non_Grammar,
Sequential_Index => Node.Sequential_Index,
Identifier => Node.Identifier,
@@ -2044,7 +2050,7 @@ package body WisiToken.Syntax_Trees is
(if Node.Augmented = null or User_Data = null
then null
else Copy_Augmented (User_Data.all, Node.Augmented)),
- Error_List => New_Error_List,
+ Error_List => Actual_Error_List,
Virtual => Node.Virtual,
Recover_Conflict => Node.Recover_Conflict,
RHS_Index => Node.RHS_Index,
@@ -2502,7 +2508,7 @@ package body WisiToken.Syntax_Trees is
-- terminal of a nonterm.
--
-- So we assume the worst case, and use first/last terminal
- -- sequential_index to guide the search when descenting a subtree.
+ -- sequential_index to guide the search when descending a subtree.
Result.Ref.Ref := (Stream, (Cur => Parse_Stream.Stack_Top), Element (Parse_Stream.Stack_Top).Node);
Last_Terminal := Result.Ref;
@@ -6625,7 +6631,7 @@ package body WisiToken.Syntax_Trees is
procedure Mark_In_Tree
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
- Data : in out User_Data_Type'Class;
+ Data : in User_Data_Access;
Node_Error_Reported : in out Boolean)
is
pragma Unreferenced (Data, Node_Error_Reported);
@@ -7528,6 +7534,10 @@ package body WisiToken.Syntax_Trees is
Shared_Link => Tree.Stream_First (Tree.Shared_Stream, Skip_SOI => True).Element.Cur,
Elements => <>)))
do
+ -- WORKAROUND: This is broken by gnat 13; ada-mode
+ -- test/ada_mode-function_2.adb fails with a ref_count error.
+ Tree.Enable_Ref_Count_Check (Result, Enable => False);
+
Tree.Next_Stream_Label := @ + 1;
end return;
end New_Stream;
@@ -8039,6 +8049,12 @@ package body WisiToken.Syntax_Trees is
Node : in out Node_Access;
Parents : in out Node_Stacks.Stack)
is
+ -- WORKAROUND: if the postcondition and this pragma is uncommented,
+ -- GNAT 13 complains that Tree is referenced in the postcondition; if
+ -- the postcondition is uncommented and this pragma commented, it
+ -- complains that it is referenced in the body. previous versions of
+ -- GNAT did not complain about the postcondition. So we comment out the postcondition
+ --
pragma Unreferenced (Tree);
function Last_Child (Node : in Valid_Node_Access) return Node_Access
@@ -8225,7 +8241,9 @@ package body WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Root : in Node_Access := Invalid_Node_Access;
Line_Numbers : in Boolean := False;
- Non_Grammar : in Boolean := False)
+ Non_Grammar : in Boolean := False;
+ Augmented : in Boolean := False;
+ Safe_Only : in Boolean := False)
is
procedure Print_Node (Node : in Valid_Node_Access; Level : in Integer)
is begin
@@ -8233,13 +8251,15 @@ package body WisiToken.Syntax_Trees is
Tree.Lexer.Trace.Put ("| ", Prefix => False);
end loop;
Tree.Lexer.Trace.Put
- (Image (Tree, Node, Children => False, RHS_Index => True, Node_Numbers => True,
- Line_Numbers => Line_Numbers, Non_Grammar => Non_Grammar),
- Prefix => False);
-
- if Node.Augmented /= null then
- Tree.Lexer.Trace.Put (Image_Augmented (Node.Augmented.all), Prefix => False);
- end if;
+ (Image (Tree, Node,
+ Children => False,
+ RHS_Index => True,
+ Node_Numbers => True,
+ Line_Numbers => Line_Numbers,
+ Non_Grammar => Non_Grammar,
+ Augmented => Augmented,
+ Safe_Only => Safe_Only),
+ Prefix => False);
Tree.Lexer.Trace.New_Line;
if Node.Label = Nonterm then
@@ -9756,14 +9776,14 @@ package body WisiToken.Syntax_Trees is
procedure Validate_Tree
(Tree : in out Syntax_Trees.Tree;
- User_Data : in out User_Data_Type'Class;
+ User_Data : in User_Data_Access;
Error_Reported : in out Node_Sets.Set;
Node_Index_Order : in Boolean;
Byte_Region_Order : in Boolean := True;
+ Line_Number_Order : in Boolean := True;
Root : in Node_Access := Invalid_Node_Access;
Validate_Node : in Syntax_Trees.Validate_Node := null)
is
-
Real_Root : Node_Access;
Last_Source_Terminal_Pos : Base_Buffer_Pos := Buffer_Pos'First;
@@ -9788,7 +9808,8 @@ package body WisiToken.Syntax_Trees is
(Node,
Image (Tree, Node,
Children => False,
- Node_Numbers => True)));
+ Node_Numbers => True,
+ Safe_Only => True)));
Node_Image_Output := True;
end if;
@@ -9801,6 +9822,14 @@ package body WisiToken.Syntax_Trees is
-- Source_Terminal since that is set by lexer. Node_Index on Virtual
-- terminals not checked.
+ -- For some reason, this loop hangs in some cases
+ -- (ada_mode-recover_partial_28.adb). it hasn't caught a bug in a
+ -- while, so we're leaving it out.
+ --
+ -- if not (for some N of Tree.Nodes => N = Node) then
+ -- Put_Error ("node " & Tree.Image (Node, Node_Numbers => True) & " not in Tree.Nodes");
+ -- end if;
+
if Node = Real_Root then
if Node.Parent /= null then
Put_Error ("root parent set expecting null");
@@ -9845,7 +9874,12 @@ package body WisiToken.Syntax_Trees is
Last_Source_Terminal_Pos := Node.Non_Grammar (Node.Non_Grammar.Last_Index).Byte_Region.Last;
if Tree.Lexer.Descriptor.New_Line_ID /= Invalid_Token_ID then
for Token of Node.Non_Grammar loop
- if Token.Line_Region.First /= Last_Line then
+
+ -- If node_index_order is changed, so is line_number order, but not
+ -- vice-versa; normally due to %if in grammar, or grammar
+ -- re-writting. See wisitoken-generate-tree_sitter.adb
+ if (Line_Number_Order and Node_Index_Order) and then Token.Line_Region.First /= Last_Line
+ then
Put_Error ("line_number missing/out of order");
end if;
Last_Line := Token.Line_Region.Last;
diff --git a/wisitoken-syntax_trees.ads b/wisitoken-syntax_trees.ads
index 796af1a..aa35a07 100644
--- a/wisitoken-syntax_trees.ads
+++ b/wisitoken-syntax_trees.ads
@@ -364,7 +364,7 @@ package WisiToken.Syntax_Trees is
Stream : in Stream_ID;
Node : in Valid_Node_Access)
return Stream_Node_Ref
- with Pre => Tree.Parents_Set,
+ with Pre => Tree_Parents_Set (Tree),
Post => Tree.Valid_Stream_Node (To_Stream_Node_Ref'Result);
subtype Terminal_Ref is Stream_Node_Ref
@@ -430,7 +430,7 @@ package WisiToken.Syntax_Trees is
return Boolean;
function To_Stream_Node_Parents (Tree : in Syntax_Trees.Tree; Ref : in Stream_Node_Ref) return Stream_Node_Parents
- with Pre => Ref = Invalid_Stream_Node_Ref or else Tree.Parents_Set or else
+ with Pre => Ref = Invalid_Stream_Node_Ref or else Tree_Parents_Set (Tree) or else
(Rooted (Ref) or Ref.Node = Tree.First_Terminal (Get_Node (Ref.Element))),
Post => Parents_Valid (To_Stream_Node_Parents'Result);
@@ -565,9 +565,6 @@ package WisiToken.Syntax_Trees is
type User_Data_Access is access all User_Data_Type'Class;
type User_Data_Access_Constant is access constant User_Data_Type'Class;
- 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)
@@ -589,9 +586,8 @@ package WisiToken.Syntax_Trees is
function Copy_Augmented
(User_Data : in User_Data_Type;
- Augmented : in Augmented_Class_Access)
- return Augmented_Class_Access
- with Pre => Augmented /= null;
+ Augmented : in not null Augmented_Class_Access)
+ return Augmented_Class_Access;
-- Default implementation raises SAL.Programmer_Error.
function Insert_After
@@ -621,7 +617,7 @@ package WisiToken.Syntax_Trees is
Tree : in out Syntax_Trees.Tree'Class;
Inserted_Token : in Syntax_Trees.Valid_Node_Access)
is null
- with Pre'Class => Tree.Parents_Set and Tree.Is_Virtual_Terminal (Inserted_Token);
+ with Pre'Class => Tree_Parents_Set (Tree) and Tree.Is_Virtual_Terminal (Inserted_Token);
-- Inserted_Token was inserted in error recovery. Move
-- Inserted_Token.Non_Grammar as needed to control which line the
-- token is on.
@@ -635,7 +631,7 @@ package WisiToken.Syntax_Trees is
Prev_Token : in Valid_Node_Access)
is null
with Pre'Class =>
- Tree.Parents_Set and
+ Tree_Parents_Set (Tree) and
Tree.Has_Following_Deleted (Prev_Token);
-- Prev_Token.Following_Deleted contains tokens that were deleted in
-- error recovery; Prev_Token is the non-deleted terminal token
@@ -687,8 +683,10 @@ package WisiToken.Syntax_Trees is
null;
when Error =>
- Begin_Name : Positive_Index_Type;
- End_Name : Positive_Index_Type;
+ Begin_Name : SAL.Base_Peek_Type;
+ End_Name : SAL.Base_Peek_Type;
+ -- Begin, End are 0 if the corresponding token is absent (not just
+ -- empty) in the production.
end case;
end record;
@@ -732,7 +730,7 @@ package WisiToken.Syntax_Trees is
return Stream_ID
with
Pre => Old_Stream = Invalid_Stream_ID or else
- (not Tree.Parents_Set and Tree.Stream_Count > 1 and Tree.Is_Valid (Old_Stream)),
+ (not Tree_Parents_Set (Tree) and Tree.Stream_Count > 1 and Tree.Is_Valid (Old_Stream)),
Post => Tree.Is_Valid (New_Stream'Result);
-- Create a new parse stream, initially copied from Old_Stream.
@@ -829,7 +827,9 @@ package WisiToken.Syntax_Trees is
State : in State_Index;
Recover_Conflict : in Boolean)
return Rooted_Ref
- with Pre => not Tree.Traversing and not Tree.Parents_Set and Tree.Is_Valid (Stream) and Stream /= Tree.Shared_Stream,
+ with
+ Pre => not Tree.Traversing and not Tree_Parents_Set (Tree) and Tree.Is_Valid (Stream) and
+ Stream /= Tree.Shared_Stream,
Post => Reduce'Result.Stream = Stream and Tree.Valid_Stream_Node (Reduce'Result);
-- Reduce Child_Count tokens on Stream top of stack to a new Nonterm
-- node on Stream top of stack. Result points to the new Nonterm
@@ -1263,6 +1263,8 @@ package WisiToken.Syntax_Trees is
Child_Index : in Positive_Index_Type)
return Node_Access
with Pre => Tree.Is_Nonterm (Node);
+ -- Returns Invalid_Node_Access if Child_Index is outside range of
+ -- Node.Children.
function Has_Children (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Access) return Boolean
with Pre => Tree.Is_Nonterm (Node);
@@ -1347,7 +1349,7 @@ package WisiToken.Syntax_Trees is
Ref : in Stream_Node_Ref;
Trailing_Non_Grammar : in Boolean := False)
return WisiToken.Buffer_Region
- with Pre => Tree.Parents_Set and Valid_Stream_Node (Tree, Ref);
+ with Pre => Tree_Parents_Set (Tree) and Valid_Stream_Node (Tree, Ref);
-- Return Byte_Region of Ref.Node, using stream to find prev, next
-- non_grammar if needed.
@@ -1414,7 +1416,7 @@ package WisiToken.Syntax_Trees is
Trailing_Non_Grammar : in Boolean)
return WisiToken.Line_Region
with Pre => Tree.Valid_Stream_Node (Ref) and
- (Tree.Parents_Set or else
+ (Tree_Parents_Set (Tree) or else
Rooted (Ref) or else
Ref.Node = Tree.First_Terminal (Get_Node (Ref.Element)));
-- Same as Line_Region (Ref.Node), using Ref.Stream to find
@@ -1427,7 +1429,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Ref : in Stream_Node_Ref)
return WisiToken.Buffer_Region
- with Pre => Tree.Valid_Stream_Node (Ref) and Tree.Parents_Set;
+ with Pre => Tree.Valid_Stream_Node (Ref) and Tree_Parents_Set (Tree);
function Line_Region
(Tree : in Syntax_Trees.Tree;
@@ -1495,7 +1497,8 @@ package WisiToken.Syntax_Trees is
procedure Set_Augmented
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
- Value : in Augmented_Class_Access);
+ Value : in Augmented_Class_Access)
+ with Pre => Tree.Augmented (Node) = null;
-- Value will be deallocated when Tree is finalized.
function Augmented
@@ -1518,14 +1521,14 @@ package WisiToken.Syntax_Trees is
ID : in Token_ID;
Max_Parent : in Boolean := False)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
function Find_Ancestor
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
IDs : in Token_ID_Array;
Max_Parent : in Boolean := False)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return the ancestor of Node that contains one of IDs (starting
-- search with Node.Parent), or Invalid_Node_Access if none match.
--
@@ -1537,7 +1540,7 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
ID : in Token_ID)
return Node_Access
- with Pre => Tree.Parents_Set and Tree.Has_Parent (Node);
+ with Pre => Tree_Parents_Set (Tree) and Tree.Has_Parent (Node);
-- Return the sibling of Node that contains ID, or Invalid_Node_Access if
-- none match.
@@ -1572,10 +1575,10 @@ package WisiToken.Syntax_Trees is
Root : in Valid_Node_Access;
Descendant : in Valid_Node_Access)
return Boolean
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
function Subtree_Root (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Access) return Valid_Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return top ancestor of Node.
procedure Process_Tree
@@ -1596,7 +1599,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return first node before Node that has a non-empty Non_Grammar.
-- If Node = Tree.Root or Tree.SOI, return Tree.SOI.
--
@@ -1634,7 +1637,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access)
return Valid_Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return first node after Last_Terminal (Node) that has a non-empty
-- Non_Grammar. If Node = Tree.Root or Tree.EOI, return Tree.EOI.
@@ -1674,7 +1677,7 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
Start_Line : in Base_Line_Number_Type := Invalid_Line_Number)
return New_Line_Ref
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- If Node is SOI, returns reference to SOI.Non_Grammar (1).
-- Otherwise, return a reference to the first New_Line preceding
-- First_Terminal (Node).Byte_Region.First.
@@ -1696,7 +1699,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access)
return Line_Number_Type
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return line at first byte of Node.
function Line_At_Node
@@ -1721,7 +1724,7 @@ package WisiToken.Syntax_Trees is
Trailing_Non_Grammar : in Boolean;
Following : in Boolean)
return Node_Access
- with Pre => (if Following then Tree.Parents_Set else True),
+ with Pre => (if Following then Tree_Parents_Set (Tree) else True),
Post =>
(if Following
then First_Source_Terminal'Result /= Invalid_Node_Access and then
@@ -1741,7 +1744,7 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
Trailing_Non_Grammar : in Boolean)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return the next terminal node after Node that can give byte or
-- char pos; Invalid_Node_Access if there is no such node.
--
@@ -1754,7 +1757,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Ref : in out Stream_Node_Ref;
Trailing_Non_Grammar : in Boolean)
- with Pre => Valid_Stream_Node (Tree, Ref) and Tree.Parents_Set,
+ with Pre => Valid_Stream_Node (Tree, Ref) and Tree_Parents_Set (Tree),
Post => Tree.Correct_Stream_Node (Ref);
-- Update Ref to the next terminal node that can give byte or char
-- pos.
@@ -1769,14 +1772,14 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
Trailing_Non_Grammar : in Boolean)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
function Prev_Source_Terminal
(Tree : in Syntax_Trees.Tree;
Ref : in Stream_Node_Ref;
Trailing_Non_Grammar : in Boolean)
return Stream_Node_Ref
- with Pre => Valid_Stream_Node (Tree, Ref) and Tree.Parents_Set,
+ with Pre => Valid_Stream_Node (Tree, Ref) and Tree_Parents_Set (Tree),
Post => Tree.Correct_Stream_Node (Prev_Source_Terminal'Result);
-- Return the previous terminal node that can give byte or char pos.
--
@@ -1888,14 +1891,15 @@ package WisiToken.Syntax_Trees is
-- Preceding, preceding element.
procedure Prev_Terminal (Tree : in Syntax_Trees.Tree; Node : in out Node_Access)
- with Pre => Tree.Parents_Set,
+ with Pre => Tree_Parents_Set (Tree),
Post => Node = Invalid_Node_Access or else
Tree.Label (Node) in Terminal_Label;
function Prev_Terminal (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Access) return Node_Access
- with Pre => Tree.Parents_Set,
- Post => Prev_Terminal'Result = Invalid_Node_Access or else
- Tree.Label (Prev_Terminal'Result) in Terminal_Label;
+ with Pre => Tree_Parents_Set (Tree);
+ -- WORKAROUND: See comment in body on why this postcondition is commented out.
+ -- Post => Prev_Terminal'Result = Invalid_Node_Access or else
+ -- Tree.Label (Prev_Terminal'Result) in Terminal_Label;
-- Return the terminal that is immediately before Node in subtree
-- containing Node; Invalid_Node_Access if Node is the first terminal
-- in that subtree.
@@ -1904,13 +1908,13 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Ref : in Terminal_Ref)
return Terminal_Ref
- with Pre => Tree.Parents_Set and Tree.Valid_Terminal (Ref),
+ with Pre => Tree_Parents_Set (Tree) and Tree.Valid_Terminal (Ref),
Post => Tree.Correct_Stream_Node (Prev_Terminal'Result);
procedure Prev_Terminal
(Tree : in Syntax_Trees.Tree;
Ref : in out Terminal_Ref)
- with Pre => Tree.Parents_Set and Tree.Valid_Terminal (Ref),
+ with Pre => Tree_Parents_Set (Tree) and Tree.Valid_Terminal (Ref),
Post => Tree.Correct_Stream_Node (Ref);
procedure Prev_Terminal
@@ -1927,14 +1931,15 @@ package WisiToken.Syntax_Trees is
-- invalid_Node_Access.
procedure Next_Terminal (Tree : in Syntax_Trees.Tree; Node : in out Node_Access)
- with Pre => Tree.Parents_Set,
+ with Pre => Tree_Parents_Set (Tree),
Post => Node = Invalid_Node_Access or else
Tree.Label (Node) in Terminal_Label;
function Next_Terminal (Tree : in Syntax_Trees.Tree; Node : in Valid_Node_Access) return Node_Access
- with Pre => Tree.Parents_Set,
- Post => Next_Terminal'Result = Invalid_Node_Access or else
- Tree.Label (Next_Terminal'Result) in Terminal_Label;
+ with Pre => Tree_Parents_Set (Tree);
+ -- WORKAROUND: See comment in Prev_Terminal body on why this postcondition is commented out.
+ -- Post => Next_Terminal'Result = Invalid_Node_Access or else
+ -- Tree.Label (Next_Terminal'Result) in Terminal_Label;
-- Return the terminal that is immediately after Node in subtree
-- containing Node; Invalid_Node_Access if Node is the last terminal
-- in that subtree.
@@ -1942,7 +1947,7 @@ package WisiToken.Syntax_Trees is
procedure Next_Terminal
(Tree : in Syntax_Trees.Tree;
Ref : in out Terminal_Ref)
- with Pre => Tree.Parents_Set and Valid_Terminal (Tree, Ref),
+ with Pre => Tree_Parents_Set (Tree) and Valid_Terminal (Tree, Ref),
Post => Correct_Stream_Node (Tree, Ref);
-- Update Ref to the next terminal that is after Ref.Node in Stream.
-- Continues search in Shared_Stream; will always find EOI. Result is
@@ -1964,7 +1969,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Ref : in Terminal_Ref)
return Terminal_Ref
- with Pre => Tree.Parents_Set and Valid_Terminal (Tree, Ref),
+ with Pre => Tree_Parents_Set (Tree) and Valid_Terminal (Tree, Ref),
Post => Correct_Stream_Node (Tree, Next_Terminal'Result);
-- Same as procedure Next_Terminal, but return result.
@@ -2026,7 +2031,7 @@ package WisiToken.Syntax_Trees is
procedure First_Sequential_Terminal
(Tree : in Syntax_Trees.Tree;
Ref : in out Stream_Node_Ref)
- with Pre => Valid_Stream_Node (Tree, Ref) and Tree.Parents_Set,
+ with Pre => Valid_Stream_Node (Tree, Ref) and Tree_Parents_Set (Tree),
Post => Correct_Stream_Node (Tree, Ref);
-- Return first terminal with valid Sequential_Index in Ref.Node or a
-- following stream element; continues search in Tree.Shared_Stream.
@@ -2078,7 +2083,7 @@ package WisiToken.Syntax_Trees is
procedure Next_Sequential_Terminal
(Tree : in Syntax_Trees.Tree;
Ref : in out Syntax_Trees.Stream_Node_Ref)
- with Pre => Valid_Stream_Node (Tree, Ref) and Tree.Parents_Set,
+ with Pre => Valid_Stream_Node (Tree, Ref) and Tree_Parents_Set (Tree),
Post => Correct_Stream_Node (Tree, Ref);
procedure Next_Sequential_Terminal
@@ -2198,6 +2203,10 @@ package WisiToken.Syntax_Trees is
-- not reachable from the root. Call Set_Parents if not
-- Tree.Parents_Set.
+ function Tree_Parents_Set (Tree : in Syntax_Trees.Tree) return Boolean;
+ -- WORKAROUND: gnat 13 is confused about Tree.Parents_Set in aspects,
+ -- so we use an unambiguous name.
+
function Parents_Set (Tree : in Syntax_Trees.Tree) return Boolean;
procedure Set_Parents
@@ -2247,7 +2256,7 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
Count : in Positive := 1)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return Count parent of Node.
function Find_Byte_Pos
@@ -2267,7 +2276,7 @@ package WisiToken.Syntax_Trees is
Stream : in Stream_ID := Invalid_Stream_ID)
return Terminal_Ref
with Pre =>
- Tree.Parents_Set and
+ Tree_Parents_Set (Tree) and
(Start_At /= Invalid_Stream_Node_Ref or Stream /= Invalid_Stream_ID);
-- Return the terminal that contains (including non_grammar if
-- Trailing_Non_Grammar) or is first after Byte_Pos.
@@ -2350,7 +2359,7 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Line : in Line_Number_Type)
return Node_Access
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return the node under Tree.Root of the first terminal token on
-- line Line; Invalid_Node_Access if there are no grammar tokens on
-- the line (ie only comment or whitespace), or the line is outside
@@ -2412,7 +2421,7 @@ package WisiToken.Syntax_Trees is
Tree.Valid_Stream_Node_Parents (Prev_Terminal) and
Prev_Terminal.Ref.Stream /= Tree.Shared_Stream and
Tree.Label (Prev_Terminal.Ref.Node) = Source_Terminal;
- -- Copy Prev_Terminal.Ref.Node, add Deleted_Node to
+ -- Copy Prev_Terminal.Ref.Node and any ancestors, add Deleted_Node to
-- Prev_Terminal.Ref.Node.Following_Deleted. Update Prev_Terminal to
-- point to copied node. Move any non_grammar from Deleted_Node to
-- Prev_Terminal.Ref.Node.
@@ -2518,13 +2527,13 @@ package WisiToken.Syntax_Trees is
function First_Recover_Conflict (Tree : in Syntax_Trees.Tree) return Stream_Node_Ref
with
- Pre => Tree.Parents_Set,
+ Pre => Tree_Parents_Set (Tree),
Post => First_Recover_Conflict'Result = Invalid_Stream_Node_Ref or else
Tree.Recover_Conflict (First_Recover_Conflict'Result.Node);
-- First recover conflict node in Tree; Invalid_Stream_Node_Ref if none.
procedure First_Recover_Conflict (Tree : in Syntax_Trees.Tree; Ref : in out Stream_Node_Ref)
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- First recover conflict node at or after Ref; Invalid_Stream_Ref if none.
----------
@@ -2610,7 +2619,7 @@ package WisiToken.Syntax_Trees is
procedure Delete_Error
(Tree : in out Syntax_Trees.Tree;
Error : in out Error_Ref)
- with Pre => Tree.Parents_Set and Has_Error (Error);
+ with Pre => Tree_Parents_Set (Tree) and Has_Error (Error);
-- Delete Error from its containing node. Error is updated to next
-- error (Invalid_Error_Ref if none).
@@ -2659,7 +2668,7 @@ package WisiToken.Syntax_Trees is
procedure Delete_Error
(Tree : in out Syntax_Trees.Tree;
Error : in out Stream_Error_Ref)
- with Pre => Tree.Parents_Set and Has_Error (Error);
+ with Pre => Tree_Parents_Set (Tree) and Has_Error (Error);
-- Delete Error from its containing node. Error is updated to next
-- error (Invalid_Stream_Error_Ref if none).
@@ -2670,7 +2679,7 @@ package WisiToken.Syntax_Trees is
Data : in Error_Data'Class;
User_Data : in User_Data_Access_Constant)
with
- Pre => not Tree.Parents_Set and Tree.Contains_Error (Error_Node (Error_Ref), Data),
+ Pre => not Tree_Parents_Set (Tree) and Tree.Contains_Error (Error_Node (Error_Ref), Data),
Post => Tree.Contains_Error (Error_Node (Error_Ref), Data);
-- Update error list element matching Data.
--
@@ -2702,14 +2711,14 @@ package WisiToken.Syntax_Trees is
function Error_Deleted (Error : in Stream_Error_Ref) return Valid_Node_Access_Lists.Cursor;
function First_Error (Tree : in Syntax_Trees.Tree) return Error_Ref
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- Return first error node in Tree.
function First_Error (Tree : in Syntax_Trees.Tree; Stream : in Stream_ID) return Stream_Error_Ref;
-- Return first error node in Stream.
procedure Next_Error (Tree : in Syntax_Trees.Tree; Error : in out Error_Ref)
- with Pre => Tree.Parents_Set and Error /= Invalid_Error_Ref;
+ with Pre => Tree_Parents_Set (Tree) and Error /= Invalid_Error_Ref;
-- Update Error to next error node.
procedure Next_Error (Tree : in Syntax_Trees.Tree; Error : in out Stream_Error_Ref)
@@ -2717,7 +2726,7 @@ package WisiToken.Syntax_Trees is
-- Update Error to next error node.
function Error_Count (Tree : in Syntax_Trees.Tree) return Ada.Containers.Count_Type
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
function Error_Count (Tree : in Syntax_Trees.Tree; Stream : in Stream_ID) return Ada.Containers.Count_Type;
function Has_Errors (Tree : in Syntax_Trees.Tree) return Boolean;
@@ -2824,7 +2833,8 @@ package WisiToken.Syntax_Trees is
Expecting : in Boolean := False;
Safe_Only : in Boolean := False)
return String;
- -- If Safe_Only, assume Node is not in tree, so can't use Prev_/Next_ anything.
+ -- If Safe_Only, assume Node is not in tree or some children were
+ -- deleted, so can't use Prev_/Next_ anything.
function Image
(Tree : in Syntax_Trees.Tree;
@@ -2893,7 +2903,7 @@ package WisiToken.Syntax_Trees is
Node : in Valid_Node_Access;
Message : in String)
return String
- with Pre => Tree.Parents_Set;
+ with Pre => Tree_Parents_Set (Tree);
-- File_Name from Tree.Lexer, line, column from Node
function Error_Message
@@ -2906,7 +2916,7 @@ package WisiToken.Syntax_Trees is
type Validate_Node is access procedure
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
- Data : in out User_Data_Type'Class;
+ Data : in User_Data_Access;
Node_Error_Reported : in out Boolean);
-- Called by Validate_Tree for each node visited; perform checks
-- other than parent/child, output error messages to
@@ -2920,7 +2930,7 @@ package WisiToken.Syntax_Trees is
procedure Mark_In_Tree
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
- Data : in out User_Data_Type'Class;
+ Data : in User_Data_Access;
Node_Error_Reported : in out Boolean);
-- Mark Node as being "in tree".
--
@@ -2933,10 +2943,11 @@ package WisiToken.Syntax_Trees is
procedure Validate_Tree
(Tree : in out Syntax_Trees.Tree;
- User_Data : in out User_Data_Type'Class;
+ User_Data : in User_Data_Access;
Error_Reported : in out Node_Sets.Set;
Node_Index_Order : in Boolean;
Byte_Region_Order : in Boolean := True;
+ Line_Number_Order : in Boolean := True;
Root : in Node_Access := Invalid_Node_Access;
Validate_Node : in Syntax_Trees.Validate_Node := null);
-- Verify that no children are Invalid_Node_Access. Verify
@@ -2955,7 +2966,9 @@ package WisiToken.Syntax_Trees is
(Tree : in Syntax_Trees.Tree;
Root : in Node_Access := Invalid_Node_Access;
Line_Numbers : in Boolean := False;
- Non_Grammar : in Boolean := False);
+ Non_Grammar : in Boolean := False;
+ Augmented : in Boolean := False;
+ Safe_Only : in Boolean := False);
-- Print tree rooted at Root (default Tree.Root) to
-- Tree.Lexer.Trace, for debugging.
--
@@ -3187,6 +3200,9 @@ private
procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
+ function Tree_Parents_Set (Tree : in Syntax_Trees.Tree) return Boolean
+ is (Tree.Parents_Set);
+
Dummy_Node : constant Node_Access := new Node'(Label => Virtual_Identifier, Child_Count => 0, others => <>);
type Token_Array_Var_Ref (Element : not null access WisiToken.Lexer.Token_Arrays.Vector) is record
diff --git a/wisitoken-user_guide.texinfo b/wisitoken-user_guide.texinfo
index a0b41c5..a77b5e4 100644
--- a/wisitoken-user_guide.texinfo
+++ b/wisitoken-user_guide.texinfo
@@ -1,6 +1,5 @@
\input texinfo
@c Author : Stephen Leake stephen_leake@stephe-leake.org
-@c Web : http://stephe-leake.org/ada/opentoken.html
@setfilename wisi-generate
@settitle WisiToken User Guide
@@ -33,7 +32,7 @@ section entitled "GNU Free Documentation License".
@contents
@node Top
-@top WisiToken User Guide version 4.1
+@top WisiToken User Guide version 4.2
@ifnottex
@insertcopying
@@ -73,7 +72,7 @@ available in the GNU ELPA package @code{wisi}.
You will also need to install a lexer generator. WisiToken supports
re2c, and other lexers can be added.
-re2c is available from @url{http://re2c.org/}; it is also packaged in
+re2c is available from @url{https://re2c.org/}; it is also packaged in
Mingw64 and Debian. WisiToken requires at least version 1.3.
The WisiToken makefile assumes the executable @code{re2c} is in
@code{$PATH}.
@@ -211,6 +210,9 @@ example:
``Keywords'' are reserved words or symbols in the target language; the
lexers recognize them by the given string.
+The keyword is case insensisitive if the string delimiters are single
+quotes or the @code{case_insensitive} declaration is present.
+
@node Tokens
@subsection Tokens
@verbatim
@@ -224,7 +226,10 @@ example:
@end verbatim
The syntax of the regular expression is determined by the lexer
-generator.
+generator. For @code{tree_sitter}, it is a Javascript expression that
+evaluates to a regexp object; @code{/foo/u} or @code{new RegExp
+("foo", "u")}. See @url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet
+}
@code{repair_image} is used in error repair information; it should be
inserted by an editor at the place of the expected but missing token.
@@ -324,7 +329,7 @@ first end delimiter.
%token <delimited-text> RAW_CODE "%{" "}%"
@end verbatim
A token that contains arbitrary text (including new-line), delimited
-by the two strings. The arguments provide the comment start and end -
+by the two strings. The arguments provide the start and end delimiters -
the rest of the regular expression is provided by the generator. The
delimiters must be different; this is checked at grammar generation
time.
@@ -475,6 +480,17 @@ than once, first with two branches, then with one more, etc. This is
due to the way conflicts are found during the parse table generation
process.
+When translating a wisitoken grammar to a tree-sitter grammar, it is
+sometimes necessary to express the conflicts differently. In that
+case, the syntax is:
+@verbatim
+%conflict abstract_limited_opt abstract_limited_synchronized_opt
+@end verbatim
+which translates to one item in the conflicts list:
+@verbatim
+ [$.abstract_limited_opt, $.abstract_limited_synchronized_opt]
+@end verbatim
+
Resolving conflicts in the grammar can be difficult, but leaving them
in can increase parse time and cause ambiguous parses.
@@ -485,9 +501,9 @@ resolve the conflict. @code{wisitoken-grammar-mode} binds that command
to @key{^c .}.
@item %conflict_resolution <conflict description> : <resolution>
-Declare a conflict resolution. The conflict description is the same as
-in a @code{%conflict} declaration; the resolution says which branch of
-the conflict to take.
+Declare a conflict and a resolution for it. The conflict description
+is the same as in a @code{%conflict} declaration; the resolution says
+which branch of the conflict to take.
Only one kind of resolution is supported: a token name, which must
match one of the token names in the conflict description; the branch
@@ -511,7 +527,7 @@ code aggree on what they mean.
@item %elisp_indent <elisp name> <Ada name> [<arg_count> [token_arg_index]...]
Declare elisp and Ada names for an indent variable or function.
-When generating Ada code for Emacs, names used in @code{wisi-indent}
+When generating Ada code for Emacs, names used in @code{wisi-indent-action}
actions that are not recognized are assumed to be elisp and Ada
variables, with the Ada name derived from elisp name by replacing
@code{-} with @code{_}, and converting to @code{Mixed_Case}.
@@ -562,8 +578,8 @@ end loop Get_Inputs;
@end verbatim
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.
+improves error recovery; the McKenzie recovery algorithm can use
+matching names to isolate the error.
@item %escape_delimiter_doubled <token_name>
The named token escapes embedded delimiters by doubling them, as for
@@ -617,6 +633,12 @@ a parser that is generated by an external program.
Translates the grammar file to a tree-sitter grammar file, and
generates code that impements the grammar actions.
+The grammar should define a nonterminal @code{word}; see
+@url{https://tree-sitter.github.io/tree-sitter/creating-parsers#keywords}.
+
+In addition, if keywords are case insensitive, they must all be
+explicitly declared.
+
@end table
@code{<output_language>} determines both what code is generated, and
@@ -668,6 +690,11 @@ 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.
+@item %precedence <name> ...
+Specifies a list of precedence names, and the order relation between
+them. All precedence names must be declared in a @code{%precedence}
+declaration before being used in a nonterminal.
+
@item %partial_recursion
The error recovery algorithm requires computing the recursion present
in the language grammar. For some grammars (such as Java), this is too
@@ -688,8 +715,9 @@ message. The supported warnings are:
@end itemize
@item %lexer_regexp <name> <value>
-Declare a named regular expression with name and current lexer
-syntax. The name may then occur in another lexer regular expression.
+Declare a named regular expression (or fragment) with name and current
+lexer syntax. The name may then occur in another lexer regular
+expression.
@end table
@node Nonterminals
@@ -739,11 +767,12 @@ rhs_item
| '(' rhs {| rhs} ')'
;
@end verbatim
-Here @code{token} is either defined by a token
+Here @code{token} is either an identifier 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.
+The second option is an attribute; these are used in wisitoken to
+express precedence and associativity, which are used in grammar
+conflict resolution.
Parentheses are used to group items.
@@ -771,6 +800,65 @@ rhs_multiple_item
times. ''@{@}-'', ''()+'', and ''token+'' mean the content is present one or
more times.
+@node Precedence attributes
+@c https://github.com/tree-sitter/tree-sitter/pull/939
+@c https://tree-sitter.github.io/tree-sitter/creating-parsers#using-precedence
+@c https://github.com/tree-sitter/tree-sitter-javascript/blob/master/grammar.js
+Some ambiguous LR grammars can be made non-ambiguous by adding precedence
+and/or associativity attributes (these attributes have no meaning for
+packrat parsers). Consider an expression grammar that
+includes binary add and multiply, and unary negate:
+
+@example
+%precedence unary binary_multiply binary_add
+
+expression
+ : primary
+ | <prec=unary> '-' expression
+ | <prec=binary_multiply><assoc=left> expression ('*' expression)+
+ | <prec=binary_add><assoc=left> expression ('+' expression)+
+ ;
+
+@end example
+
+Without the attributes, this is ambiguous: the statement @code{1 + 2 *
+3} can be parsed as @code{(1 + 2) * 3} or @code{(1 + (2 *
+3)}. Similarly @code{1 + -2 + 3} can be parsed as @code{(1 + (-2)) + 3)} or
+@code{1 + -(2 + 3)}, etc.
+
+The @code{%precedence} declaration gives an order for the list of
+precedence labels; here unary operations are done before binary, and
+multiply before add. More complex grammars may have more than one
+@code{%precedence} declaration; there is no order between separate
+@code{%precedence} declarations.
+
+The @code{prec} attribute applies a precedence label to a
+production. If the LR parser generation algorithm encounters a
+conflict involving productions with precedence labels, the labels are
+compared, and the higher precedence production is used. If there is no
+higher precedence, either because both productions have the same
+label, or the labels are from different precedence declarations, the
+conflict is kept, and resolved at runtime via the generalized parser
+algorithm.
+
+This resolves the first example conflict; @code{1 + 2 * 3} is parsed
+as @code{(1 + (2 * 3)} because multiply has higher precedence than
+add.
+
+It also resolves the unary minus in the second conflict example;
+@code{-2} is always parsed as @code{(-2)} because unary has higher
+precendence than the other operators.
+
+The @code{assoc} attribute is similar; it specifies how to choose
+between two productions. It must be applied to a token sequence that
+generates a list. @code{assoc=left} says to build the list as
+@code{list operator element} (the list is on the left);
+@code{assoc=right} says to build the list as @code{element operator
+list} (the list is on the right);
+
+This resolves the second conflict example; @code{1 + -2 + 3} is parsed
+as @code{(1 + (-2)) + 3)}.
+
@node Conditional code
@section Conditional code
diff --git a/wisitoken-wisi_ada.adb b/wisitoken-wisi_ada.adb
index 1178ca8..7a3eb86 100644
--- a/wisitoken-wisi_ada.adb
+++ b/wisitoken-wisi_ada.adb
@@ -2,7 +2,7 @@
--
-- see spec
--
--- Copyright (C) 2013, 2014, 2015, 2017 - 2020, 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2013, 2014, 2015, 2017 - 2020, 2022, 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -47,17 +47,20 @@ package body WisiToken.Wisi_Ada is
function "+" (Tokens : in Token_ID_Arrays.Vector; Action : in Syntax_Trees.Post_Parse_Action) return Right_Hand_Side
is begin
- return (Tokens, Recursion => <>, Post_Parse_Action => Action, In_Parse_Action => null);
+ return (Tokens, Post_Parse_Action => Action, In_Parse_Action => null,
+ Recursion => <>, Associativity => <>, Precedence => <>);
end "+";
function "+" (Tokens : in Token_ID; Action : in Syntax_Trees.Post_Parse_Action) return Right_Hand_Side
is begin
- return (Only (Tokens), Recursion => <>, Post_Parse_Action => Action, In_Parse_Action => null);
+ return (Only (Tokens), Post_Parse_Action => Action, In_Parse_Action => null,
+ Recursion => <>, Associativity => <>, Precedence => <>);
end "+";
function "+" (Action : in Syntax_Trees.Post_Parse_Action) return Right_Hand_Side
is begin
- return (Tokens => <>, Recursion => <>, Post_Parse_Action => Action, In_Parse_Action => null);
+ return (Tokens => <>, Post_Parse_Action => Action, In_Parse_Action => null,
+ Recursion => <>, Associativity => <>, Precedence => <>);
end "+";
function Only (Item : in WisiToken.Productions.Right_Hand_Side) return WisiToken.Productions.RHS_Arrays.Vector
@@ -79,7 +82,7 @@ package body WisiToken.Wisi_Ada is
function "<=" (LHS : in Token_ID; RHSs : in WisiToken.Productions.RHS_Arrays.Vector) return Instance
is begin
- return (LHS, Optimized_List => False, RHSs => RHSs);
+ return (LHS, Optimized_List => False, RHSs => RHSs, Precedence => <>);
end "<=";
function Only (Subject : in Instance) return Prod_Arrays.Vector
diff --git a/wisitoken.adb b/wisitoken.adb
index 558ce13..112db5b 100644
--- a/wisitoken.adb
+++ b/wisitoken.adb
@@ -2,7 +2,7 @@
--
-- See spec
--
--- Copyright (C) 2009, 2014-2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2009, 2014-2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -349,21 +349,6 @@ package body WisiToken is
Trace.New_Line;
end Report_Memory;
- function Error_Message
- (File_Name : in String;
- Line : in Base_Line_Number_Type;
- Column : in Ada.Text_IO.Count;
- Message : in String)
- return String
- is
- use all type Ada.Text_IO.Count;
- begin
- return File_Name & ":" &
- Trimmed_Image (if Line = Invalid_Line_Number then Integer'(0) else Integer (Line)) & ":" &
- Trimmed_Image (Integer (Column + 1)) & ": " &
- Message;
- end Error_Message;
-
function Image (Item : in Buffer_Region) return String
is begin
return "(" & Trimmed_Image (Item.First) & " ." & Base_Buffer_Pos'Image (Item.Last) & ")";
@@ -520,6 +505,83 @@ package body WisiToken is
Put_Line (Current_Error, "time=n - output times of various operations");
end Enable_Trace_Help;
+ procedure Put
+ (Lists : in Precedence_Lists_Arrays.Vector;
+ Map : in Precedence_Maps.Map)
+ is
+ use Ada.Text_IO;
+ use Precedence_Maps;
+ begin
+ Put_Line ("Precedence_IDs:");
+ for Cur in Map.Iterate loop
+ Put_Line (Element (Cur)'Image & ": " & Key (Cur));
+ end loop;
+
+ Put_Line ("Precedence relations:");
+ for List of Lists loop
+ for P of List loop
+ Put (P'Image & " ");
+ end loop;
+ New_Line;
+ end loop;
+ end Put;
+
+ function Compare
+ (Left : in Precedence_ID;
+ Right : in Precedence_ID;
+ Precedences : in Precedence_Lists_Arrays.Vector)
+ return Precedence_Compare_Result
+ is
+ begin
+ if Left = Right then
+ return None;
+ end if;
+
+ for List of Precedences loop
+ declare
+ I : Integer := 0;
+ Left_Index : Integer := 0;
+ Right_Index : Integer := 0;
+ begin
+ for Prec of List loop
+ I := @ + 1;
+ if Left = Prec then
+ Left_Index := I;
+ end if;
+ if Right = Prec then
+ Right_Index := I;
+ end if;
+ end loop;
+
+ if Left_Index /= 0 and Right_Index /= 0 then
+ if Left_Index < Right_Index then
+ return WisiToken.Left;
+ elsif Left_Index > Right_Index then
+ return WisiToken.Right;
+ else
+ return WisiToken.None;
+ end if;
+ end if;
+ end;
+ end loop;
+ return None;
+ end Compare;
+
+ function Error_Message
+ (File_Name : in String;
+ Line : in Base_Line_Number_Type;
+ Column : in Ada.Text_IO.Count;
+ Message : in String)
+ return String
+ is
+ use all type Ada.Text_IO.Count;
+ begin
+ return File_Name & ":" &
+ Trimmed_Image (if Line = Invalid_Line_Number then Integer'(0) else Integer (Line)) & ":" &
+ Trimmed_Image (Integer (Column + 1)) & ": " &
+ Message;
+ end Error_Message;
+
function Next_Value
(Stream : not null access Ada.Streams.Root_Stream_Type'Class;
Delims : in Ada.Strings.Maps.Character_Set)
diff --git a/wisitoken.ads b/wisitoken.ads
index b8a4b0c..ea86bee 100644
--- a/wisitoken.ads
+++ b/wisitoken.ads
@@ -26,7 +26,7 @@
-- Efficient and flexible incremental parsing. ACM Transactions on
-- Programming Languages and Systems,20(5):980-1013, 1998
--
--- Copyright (C) 2009, 2010, 2013 - 2015, 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2009, 2010, 2013 - 2015, 2017 - 2023 Free Software Foundation, Inc.
--
-- This file is part of the WisiToken package.
--
@@ -51,7 +51,11 @@
pragma License (Modified_GPL);
with Ada.Containers.Doubly_Linked_Lists;
+with Ada.Containers.Indefinite_Hashed_Maps;
+with Ada.Containers.Vectors;
with Ada.Streams;
+with Ada.Strings.Equal_Case_Insensitive;
+with Ada.Strings.Hash_Case_Insensitive;
with Ada.Strings.Maps;
with Ada.Strings.Unbounded;
with Ada.Text_IO;
@@ -414,11 +418,14 @@ package WisiToken is
Extreme : constant := 3; -- add ?
Trace_McKenzie : Integer := 0;
- -- If Trace_McKenzie > 0, Parse prints messages helpful for debugging error recovery.
+ -- 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
+ --
+ -- See also wisitoken-parse-lr.ads Set_McKenzie_Options.
Trace_Lexer : Integer := 0;
@@ -499,6 +506,47 @@ package WisiToken is
----------
-- Misc
+ type Associativity is (Left, Right, None);
+
+ type Base_Precedence_ID is range 0 .. 255;
+ subtype Precedence_ID is Base_Precedence_ID range 1 .. 255;
+ No_Precedence : constant Base_Precedence_ID := 0;
+
+ function Trimmed_Image is new SAL.Gen_Trimmed_Image (Base_Precedence_ID);
+
+ type Precedence_List_ID is range 1 .. 255;
+
+ package Precedence_Maps is new Ada.Containers.Indefinite_Hashed_Maps
+ (Key_Type => String,
+ Element_Type => Precedence_ID,
+ Hash => Ada.Strings.Hash_Case_Insensitive,
+ Equivalent_Keys => Ada.Strings.Equal_Case_Insensitive);
+
+ package Precedence_Inverse_Maps is new Ada.Containers.Vectors
+ (Index_Type => Precedence_ID,
+ Element_Type => Ada.Strings.Unbounded.Unbounded_String,
+ "=" => Ada.Strings.Unbounded."=");
+
+ package Precedence_Lists is new Ada.Containers.Doubly_Linked_Lists (Precedence_ID);
+
+ package Precedence_Lists_Arrays is new Ada.Containers.Vectors
+ (Precedence_List_ID, Precedence_Lists.List, Precedence_Lists."=");
+ -- Actual precedence relation is given by order of two Precedence_IDs
+ -- in a Precedence_List; earlier ID has higher precedence.
+
+ procedure Put
+ (Lists : in Precedence_Lists_Arrays.Vector;
+ Map : in Precedence_Maps.Map);
+ -- Put Lists, Map to Ada.Text_IO.Current_Ouput, for debugging.
+
+ type Precedence_Compare_Result is (Left, Right, None);
+
+ function Compare
+ (Left : in Precedence_ID;
+ Right : in Precedence_ID;
+ Precedences : in Precedence_Lists_Arrays.Vector)
+ return Precedence_Compare_Result;
+
type Cache_Version is mod 2**16;
type Boolean_Access is access all Boolean;
diff --git a/wisitoken_grammar_actions.adb b/wisitoken_grammar_actions.adb
index 9c53fba..31668ad 100644
--- a/wisitoken_grammar_actions.adb
+++ b/wisitoken_grammar_actions.adb
@@ -2,7 +2,7 @@
-- command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c wisitoken_grammar.wy
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- Author: Stephen Leake <stephe-leake@stephe-leake.org>
--
@@ -19,7 +19,7 @@
-- 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/>.
+-- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
with WisiToken_Grammar_Runtime; use WisiToken_Grammar_Runtime;
@@ -130,7 +130,7 @@ package body Wisitoken_Grammar_Actions is
Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
is
begin
- Start_If (User_Data, Tree, Nonterm);
+ Add_Declaration (User_Data, Tree, Nonterm);
end declaration_11;
procedure declaration_12
@@ -165,10 +165,19 @@ package body Wisitoken_Grammar_Actions is
Tree : in out WisiToken.Syntax_Trees.Tree;
Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
is
+ begin
+ Start_If (User_Data, Tree, Nonterm);
+ end declaration_15;
+
+ procedure declaration_16
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ is
pragma Unreferenced (Tree, Nonterm);
begin
End_If (User_Data);
- end declaration_15;
+ end declaration_16;
procedure nonterminal_0
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
@@ -188,6 +197,24 @@ package body Wisitoken_Grammar_Actions is
Add_Nonterminal (User_Data, Tree, Nonterm);
end nonterminal_1;
+ procedure nonterminal_2
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ is
+ begin
+ Add_Nonterminal (User_Data, Tree, Nonterm);
+ end nonterminal_2;
+
+ procedure nonterminal_3
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ is
+ begin
+ Add_Nonterminal (User_Data, Tree, Nonterm);
+ end nonterminal_3;
+
procedure rhs_item_1
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
@@ -224,15 +251,6 @@ package body Wisitoken_Grammar_Actions is
Check_EBNF (User_Data, Tree, Nonterm, 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.Syntax_Trees.Valid_Node_Access)
- is
- begin
- Check_EBNF (User_Data, Tree, Nonterm, 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;
diff --git a/wisitoken_grammar_actions.ads b/wisitoken_grammar_actions.ads
index f8a7654..50f90ad 100644
--- a/wisitoken_grammar_actions.ads
+++ b/wisitoken_grammar_actions.ads
@@ -2,7 +2,7 @@
-- command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c PROCESS wisitoken_grammar.wy
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- Author: Stephen Leake <stephe-leake@stephe-leake.org>
--
@@ -19,7 +19,7 @@
-- 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/>.
+-- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
with WisiToken.Syntax_Trees;
package Wisitoken_Grammar_Actions is
@@ -28,8 +28,8 @@ package Wisitoken_Grammar_Actions is
(First_Terminal => 3,
Last_Terminal => 42,
First_Nonterminal => 43,
- Last_Nonterminal => 66,
- SOI_ID => 67,
+ Last_Nonterminal => 68,
+ SOI_ID => 69,
EOI_ID => 42,
Accept_ID => 43,
Case_Insensitive => False,
@@ -77,8 +77,8 @@ package Wisitoken_Grammar_Actions is
new String'("STAR"),
new String'("NUMERIC_LITERAL"),
new String'("IDENTIFIER"),
- new String'("STRING_LITERAL_1"),
- new String'("STRING_LITERAL_2"),
+ new String'("STRING_LITERAL_DOUBLE"),
+ new String'("STRING_LITERAL_SINGLE"),
new String'("Wisi_EOI"),
new String'("wisitoken_accept"),
new String'("regexp_string"),
@@ -94,7 +94,8 @@ package Wisitoken_Grammar_Actions is
new String'("semicolon_opt"),
new String'("rhs_list"),
new String'("rhs"),
- new String'("rhs_attribute"),
+ new String'("attribute"),
+ new String'("attribute_list"),
new String'("rhs_element"),
new String'("rhs_item_list"),
new String'("rhs_item"),
@@ -102,11 +103,12 @@ package Wisitoken_Grammar_Actions is
new String'("rhs_optional_item"),
new String'("rhs_multiple_item"),
new String'("rhs_alternative_list"),
+ new String'("rhs_alternative_list_1"),
new String'("compilation_unit"),
new String'("compilation_unit_list"),
new String'("Wisi_SOI")),
- Terminal_Image_Width => 19,
- Image_Width => 21,
+ Terminal_Image_Width => 21,
+ Image_Width => 22,
Last_Lookahead => 43);
type Token_Enum_ID is
@@ -150,8 +152,8 @@ package Wisitoken_Grammar_Actions is
STAR_ID,
NUMERIC_LITERAL_ID,
IDENTIFIER_ID,
- STRING_LITERAL_1_ID,
- STRING_LITERAL_2_ID,
+ STRING_LITERAL_DOUBLE_ID,
+ STRING_LITERAL_SINGLE_ID,
Wisi_EOI_ID,
wisitoken_accept_ID,
regexp_string_ID,
@@ -167,7 +169,8 @@ package Wisitoken_Grammar_Actions is
semicolon_opt_ID,
rhs_list_ID,
rhs_ID,
- rhs_attribute_ID,
+ attribute_ID,
+ attribute_list_ID,
rhs_element_ID,
rhs_item_list_ID,
rhs_item_ID,
@@ -175,6 +178,7 @@ package Wisitoken_Grammar_Actions is
rhs_optional_item_ID,
rhs_multiple_item_ID,
rhs_alternative_list_ID,
+ rhs_alternative_list_1_ID,
compilation_unit_ID,
compilation_unit_list_ID,
Wisi_SOI_ID);
@@ -251,6 +255,10 @@ package Wisitoken_Grammar_Actions is
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
+ procedure declaration_16
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
procedure nonterminal_0
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
@@ -259,6 +267,14 @@ package Wisitoken_Grammar_Actions is
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
+ procedure nonterminal_2
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
+ procedure nonterminal_3
+ (User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
procedure rhs_item_1
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
@@ -275,10 +291,6 @@ package Wisitoken_Grammar_Actions is
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
- 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.Syntax_Trees.Valid_Node_Access);
procedure rhs_optional_item_3
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
diff --git a/wisitoken_grammar_editing.adb b/wisitoken_grammar_editing.adb
index 8d0ad09..5f23c47 100644
--- a/wisitoken_grammar_editing.adb
+++ b/wisitoken_grammar_editing.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -121,9 +121,10 @@ package body WisiToken_Grammar_Editing is
end Add_RHS_Item;
function Add_RHS_Element
- (Tree : in out Syntax_Trees.Tree;
- Item : in Valid_Node_Access;
- Label : in Identifier_Token := Invalid_Identifier_Token)
+ (Tree : in out Syntax_Trees.Tree;
+ Item : in Valid_Node_Access;
+ Label : in Identifier_Token := Invalid_Identifier_Token;
+ Augmented : in WisiToken.Syntax_Trees.Augmented_Class_Access := null)
return Valid_Node_Access
is
Label_Node : constant Node_Access :=
@@ -131,12 +132,17 @@ package body WisiToken_Grammar_Editing is
then Invalid_Node_Access
else Add_Identifier_Token (Tree, Label));
begin
- return Tree.Add_Nonterm
+ return Result : constant Valid_Node_Access := Tree.Add_Nonterm
((+rhs_element_ID, (if Label = Invalid_Identifier_Token then 0 else 1)),
(if Label = Invalid_Identifier_Token
then (1 => Item)
else (Label_Node, Tree.Add_Terminal (+EQUAL_ID), Item)),
- Clear_Parents => False);
+ Clear_Parents => False)
+ do
+ if Augmented /= null then
+ Tree.Set_Augmented (Result, Augmented);
+ end if;
+ end return;
end Add_RHS_Element;
function Empty_RHS_Item_List
@@ -146,7 +152,7 @@ package body WisiToken_Grammar_Editing is
return LR_Utils.Creators.Empty_List
(Tree,
List_ID => +rhs_item_list_ID,
- Multi_Element_RHS => 1,
+ Multi_Element_RHS => 0,
Element_ID => +rhs_element_ID,
Separator_ID => Invalid_Token_ID);
end Empty_RHS_Item_List;
@@ -158,15 +164,10 @@ package body WisiToken_Grammar_Editing is
with Pre => Tree.ID (List_Element) = +rhs_element_ID
is
use LR_Utils;
- Result : List := Creators.Empty_List
- (Tree,
- List_ID => +rhs_item_list_ID,
- Multi_Element_RHS => 1,
- Element_ID => +rhs_element_ID,
- Separator_ID => Invalid_Token_ID);
begin
- Result.Append (List_Element);
- return Result;
+ return Result : List := Empty_RHS_Item_List (Tree) do
+ Result.Append (List_Element);
+ end return;
end To_RHS_Item_List;
function Empty_RHS_List
@@ -183,9 +184,9 @@ package body WisiToken_Grammar_Editing is
function Add_RHS
(Tree : in out Syntax_Trees.Tree;
- Item : in Valid_Node_Access;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access;
+ Item_List : in WisiToken.Syntax_Trees.Valid_Node_Access;
Auto_Token_Labels : in Boolean;
- Edited_Token_List : in Boolean;
Post_Parse_Action : in Node_Access := Invalid_Node_Access;
In_Parse_Action : in Node_Access := Invalid_Node_Access)
return Valid_Node_Access
@@ -193,20 +194,60 @@ package body WisiToken_Grammar_Editing is
Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'
(EBNF => False,
Auto_Token_Labels => Auto_Token_Labels,
- Edited_Token_List => Edited_Token_List);
-
- RHS : constant Valid_Node_Access :=
- (if In_Parse_Action = Invalid_Node_Access
- then
- (if Post_Parse_Action = Invalid_Node_Access
- then Tree.Add_Nonterm ((+rhs_ID, 1), (1 => Item), Clear_Parents => True)
- else Tree.Add_Nonterm ((+rhs_ID, 2), (Item, Post_Parse_Action), Clear_Parents => True))
- else
- (if Post_Parse_Action = Invalid_Node_Access
- then Tree.Add_Nonterm
- ((+rhs_ID, 3), (Item, Tree.Add_Terminal (+ACTION_ID), In_Parse_Action), Clear_Parents => True)
- else Tree.Add_Nonterm
- ((+rhs_ID, 3), (Item, Post_Parse_Action, In_Parse_Action), Clear_Parents => True)));
+ Orig_EBNF_RHS => False,
+ EBNF_RHS_Index => <>,
+ Orig_Token_Index => <>);
+
+ function RHS_Index return Natural
+ is begin
+ return
+ (if In_Parse_Action /= Invalid_Node_Access
+ then (if Attr_List = Invalid_Node_Access then 5 else 6)
+ elsif Post_Parse_Action /= Invalid_Node_Access
+ then (if Attr_List = Invalid_Node_Access then 3 else 4)
+ else (if Attr_List = Invalid_Node_Access then 1 else 2));
+ end RHS_Index;
+
+ function Children return Valid_Node_Access_Array
+ is
+ use all type SAL.Base_Peek_Type;
+ Count : Positive_Index_Type := 1;
+ Next : Positive_Index_Type := 1;
+ begin
+ if Attr_List /= Invalid_Node_Access then
+ Count := @ + 1;
+ end if;
+
+ if Post_Parse_Action /= Invalid_Node_Access then
+ Count := @ + 1;
+ end if;
+
+ if In_Parse_Action /= Invalid_Node_Access then
+ Count := @ + 1;
+ end if;
+
+ return Result : Valid_Node_Access_Array (1 .. Count) := (others => WisiToken.Syntax_Trees.Dummy_Node)
+ do
+ if Attr_List /= Invalid_Node_Access then
+ Result (Next) := Attr_List;
+ Next := @ + 1;
+ end if;
+
+ Result (Next) := Item_List;
+ Next := @ + 1;
+
+ if Post_Parse_Action /= Invalid_Node_Access then
+ Result (Next) := Post_Parse_Action;
+ Next := @ + 1;
+ end if;
+
+ if In_Parse_Action /= Invalid_Node_Access then
+ Result (Next) := In_Parse_Action;
+ end if;
+ end return;
+ end Children;
+
+ RHS : constant Valid_Node_Access := Tree.Add_Nonterm ((+rhs_ID, RHS_Index), Children, Clear_Parents => True);
begin
Tree.Set_Augmented (RHS, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
return RHS;
@@ -230,15 +271,12 @@ package body WisiToken_Grammar_Editing is
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 1 =>
+ case To_Token_Enum (Tree.ID (Tree.Child (Decl, 2))) is
+ when Wisitoken_Grammar_Actions.TOKEN_ID | NON_GRAMMAR_ID =>
return Get_Text (Data, Tree, Tree.Child (Decl, 6));
- when 3 | 4 =>
- return Get_Text (Data, Tree, Tree.Child (Decl, 2));
+ when KEYWORD_ID =>
+ return Get_Text (Data, Tree, Tree.Child (Decl, 3));
when others =>
return "";
@@ -268,16 +306,61 @@ package body WisiToken_Grammar_Editing is
return Invalid_Node_Access;
end Find_Declaration;
- EBNF_Allowed : Boolean := True;
+ function Find_Declaration_By_Value
+ (Data : in WisiToken_Grammar_Runtime.User_Data_Type;
+ Tree : in out Syntax_Trees.Tree;
+ Value : in String;
+ Strip_Quotes : in Boolean)
+ return Node_Access
+ is
+ use LR_Utils;
+ use LR_Utils.Creators;
+
+ function Decl_Value (Decl : in Valid_Node_Access) return String
+ is
+ Value : constant Node_Access :=
+ (case To_Token_Enum (Tree.ID (Decl)) is
+ when declaration_ID =>
+ (case To_Token_Enum (Tree.ID (Tree.Child (Decl, 2))) is
+ when Wisitoken_Grammar_Actions.TOKEN_ID |
+ NON_GRAMMAR_ID => Tree.Child (Decl, 7),
+ when KEYWORD_ID => Tree.Child (Decl, 4),
+ when others => Invalid_Node_Access),
+ when others => Invalid_Node_Access);
+ begin
+ if Value = Invalid_Node_Access then
+ return "";
+ else
+ return Get_Text (Data, Tree, Value, Strip_Quotes);
+ end if;
+ end Decl_Value;
+
+ -- Tree.Root is wisitoken_accept, first child is SOI
+ List : constant Constant_List := Create_List
+ (Tree, Tree.Child (Tree.Root, 2), +compilation_unit_list_ID, +compilation_unit_ID);
+ begin
+ for N of List loop
+ declare
+ Decl : constant Valid_Node_Access := Tree.Child (N, 1);
+ begin
+ if Value = Decl_Value (Decl) then
+ return Decl;
+ end if;
+ end;
+ end loop;
+ return Invalid_Node_Access;
+ end Find_Declaration_By_Value;
+
procedure Validate_Node
(Tree : in Syntax_Trees.Tree;
Node : in Valid_Node_Access;
- User_Data : in out Syntax_Trees.User_Data_Type'Class;
+ User_Data : in WisiToken.Syntax_Trees.User_Data_Access;
Node_Error_Reported : in out Boolean)
is
use Ada.Text_IO;
- Data : WisiToken_Grammar_Runtime.User_Data_Type renames WisiToken_Grammar_Runtime.User_Data_Type (User_Data);
+ Data : WisiToken_Grammar_Runtime.User_Data_Type renames
+ WisiToken_Grammar_Runtime.User_Data_Access (User_Data).all;
procedure Put_Error (Msg : in String)
is begin
@@ -347,7 +430,7 @@ package body WisiToken_Grammar_Editing is
when others =>
-- The reset are for %if .. %endif, which are supposed to be translated before now.
- Put_Error ("unexpected RHS_Index");
+ Put_Error ("unexpected RHS_Index" & RHS_Index'Image);
end case;
when rhs_ID =>
@@ -367,13 +450,32 @@ package body WisiToken_Grammar_Editing is
when 2 =>
if Tree.Child_Count (Node) /= 2 then
Put_Error ("expected child_count 2");
+ elsif Tree.ID (Children (1)) /= +attribute_list_ID or
+ Tree.ID (Children (2)) /= +rhs_item_list_ID
+ then
+ Put_Error ("expecting rhs_attribute_list rhs_item_list");
+ end if;
+
+ when 3 =>
+ 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 =>
+ when 4 =>
+ 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)) /= +rhs_item_list_ID or
+ Tree.ID (Children (3)) /= +ACTION_ID
+ then
+ Put_Error ("expecting rhs_attribute_list rhs_item_list ACTION");
+ end if;
+
+ when 5 =>
if Tree.Child_Count (Node) /= 3 then
Put_Error ("expected child_count 3");
elsif Tree.ID (Children (1)) /= +rhs_item_list_ID or
@@ -383,13 +485,21 @@ package body WisiToken_Grammar_Editing is
Put_Error ("expecting rhs_item_list ACTION ACTION");
end if;
+ when 6 =>
+ if Tree.Child_Count (Node) /= 4 then
+ Put_Error ("expected child_count 4");
+ elsif Tree.ID (Children (1)) /= +rhs_item_list_ID or
+ Tree.ID (Children (2)) /= +rhs_item_list_ID or
+ Tree.ID (Children (3)) /= +ACTION_ID or
+ Tree.ID (Children (4)) /= +ACTION_ID
+ then
+ Put_Error ("expecting rhs_attribute_list 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 =>
@@ -416,13 +526,6 @@ package body WisiToken_Grammar_Editing is
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
@@ -431,6 +534,13 @@ package body WisiToken_Grammar_Editing is
Put_Error ("expecting rhs_item_list ELEMENT");
end if;
+ when 1 =>
+ 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 others =>
Put_Error ("unexpected RHS_Index");
end case;
@@ -447,26 +557,21 @@ package body WisiToken_Grammar_Editing is
end if;
when 1 =>
- if Tree.ID (Children (1)) /= +STRING_LITERAL_2_ID then
- Put_Error ("expecting STRING_LITERAL_2");
+ if Tree.ID (Children (1)) /= +STRING_LITERAL_SINGLE_ID then
+ Put_Error ("expecting STRING_LITERAL_SINGLE");
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 =>
+ when 3 =>
if Tree.ID (Children (1)) /= +rhs_multiple_item_ID then
Put_Error ("expecting rhs_multiple_item");
end if;
- when 5 =>
+ when 4 =>
if Tree.ID (Children (1)) /= +rhs_group_item_ID then
Put_Error ("expecting rhs_group_item");
end if;
@@ -518,10 +623,10 @@ package body WisiToken_Grammar_Editing is
when 3 =>
if Children'Length /= 2 or else
- (Tree.ID (Children (1)) /= +STRING_LITERAL_2_ID or
+ (Tree.ID (Children (1)) /= +STRING_LITERAL_SINGLE_ID or
Tree.ID (Children (2)) /= +QUESTION_ID)
then
- Put_Error ("expecting STRING_LITERAL_2 QUESTION");
+ Put_Error ("expecting STRING_LITERAL_SINGLE QUESTION");
end if;
when others =>
@@ -594,20 +699,43 @@ package body WisiToken_Grammar_Editing is
Check_EBNF_Allowed;
case RHS_Index is
when 0 =>
- if Children'Length /= 1 or else
- (Tree.ID (Children (1)) /= +rhs_item_list_ID)
+ if Children'Length /= 2 or else
+ (Tree.ID (Children (1)) /= +attribute_list_ID or
+ Tree.ID (Children (2)) /= +rhs_alternative_list_1_ID)
then
- Put_Error ("expecting rhs_item_list");
+ Put_Error ("expecting rhs_attribute_list rhs_alternative_list_1");
end if;
when 1 =>
+ if Children'Length /= 1 or else
+ (Tree.ID (Children (1)) /= +rhs_alternative_list_1_ID)
+ then
+ Put_Error ("expecting rhs_alternative_list_1");
+ end if;
+
+ when others =>
+ Put_Error ("unexpected RHS_Index");
+ end case;
+
+ when rhs_alternative_list_1_ID =>
+ Check_EBNF_Allowed;
+ case RHS_Index is
+ when 0 =>
if Children'Length /= 3 or else
- (Tree.ID (Children (1)) /= +rhs_alternative_list_ID or
+ (Tree.ID (Children (1)) /= +rhs_alternative_list_1_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");
+ Put_Error ("expecting rhs_alternative_list_1 BAR rhs_item_list");
end if;
+
+ when 1 =>
+ if Children'Length /= 1 or else
+ (Tree.ID (Children (1)) /= +rhs_item_list_ID)
+ then
+ Put_Error ("expecting rhs_item_list");
+ end if;
+
when others =>
Put_Error ("unexpected RHS_Index");
end case;
@@ -683,37 +811,35 @@ package body WisiToken_Grammar_Editing is
end Next_Nonterm_Name;
function Needs_Token_Labels (RHS : in Valid_Node_Access) return Boolean
+ with Pre => Tree.ID (RHS) = +rhs_ID
is
- Has_EBNF : Boolean := False;
- Has_Manual_Label : Boolean := False;
+ Has_EBNF : Boolean := False;
- procedure Any_EBNF_Manual_Label
+ procedure Any_EBNF
(Tree : in out Syntax_Trees.Tree;
Node : in Valid_Node_Access)
- is begin
- Has_Manual_Label := Has_Manual_Label or
- (Tree.ID (Node) = +rhs_element_ID and then Tree.RHS_Index (Node) = 1);
-
+ is
+ pragma Unreferenced (Tree);
+ begin
Has_EBNF := Has_EBNF or EBNF_Nodes.Contains (Node);
-- Not every ebnf node requires auto-labels (ie literal tokens), but
-- it's not easy to tell from here.
- end Any_EBNF_Manual_Label;
+ end Any_EBNF;
begin
- case Tree.RHS_Index (RHS) is
- when 0 | 1 =>
+ if Tree.Child_Count (RHS) = 0 then
return False;
- when 2 | 3 =>
- Tree.Process_Tree (Any_EBNF_Manual_Label'Unrestricted_Access, RHS);
- return Has_EBNF and not Has_Manual_Label;
+ elsif Tree.ID (Tree.Child (RHS, Tree.Child_Count (RHS))) = +ACTION_ID then
+ Tree.Process_Tree (Any_EBNF'Unrestricted_Access, RHS);
+ return Has_EBNF;
- when others =>
- raise SAL.Programmer_Error;
- end case;
+ else
+ return False;
+ end if;
end Needs_Token_Labels;
- Last_Token_Index : Integer := 0;
+ Last_Token_Index : SAL.Base_Peek_Type := 0;
function Next_Token_Label (Prefix : in String := "T") return WisiToken.Identifier_Index
is begin
@@ -731,7 +857,10 @@ package body WisiToken_Grammar_Editing is
end Next_Token_Label;
procedure Add_Token_Labels (RHS : in Valid_Node_Access)
- with Pre => Tree.ID (RHS) = +rhs_ID
+ with Pre =>
+ Tree.ID (RHS) = +rhs_ID and
+ (Tree.Child_Count (RHS) > 0 and then
+ To_Token_Enum (Tree.ID (Tree.Child (RHS, Tree.Child_Count (RHS)))) = ACTION_ID)
is
use LR_Utils;
@@ -744,20 +873,56 @@ package body WisiToken_Grammar_Editing is
Tree.Set_Children (Element, (+rhs_element_ID, 1), (Ident, Equal, Tree.Child (Element, 1)));
end Add_Token_Label;
+ procedure Add_Orig_Token_Index (Element : in Valid_Node_Access)
+ with Pre => Tree.ID (Element) = +rhs_element_ID
+ is
+ Aug : Augmented_Access := Augmented_Access (Tree.Augmented (Element));
+ begin
+ if Aug = null then
+ Aug := new WisiToken_Grammar_Runtime.Augmented'
+ (Orig_Token_Index => Last_Token_Index,
+ others => <>);
+ Tree.Set_Augmented (Element, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
+ else
+ Aug.Orig_Token_Index := Last_Token_Index;
+ end if;
+ end Add_Orig_Token_Index;
+
procedure Add_Token_Labels_1 (Node : in Valid_Node_Access)
- with Pre => To_Token_Enum (Tree.ID (Node)) in rhs_alternative_list_ID | rhs_item_list_ID
+ with Pre =>
+ To_Token_Enum (Tree.ID (Node)) in rhs_alternative_list_ID | rhs_alternative_list_1_ID | rhs_item_list_ID
is begin
case To_Token_Enum (Tree.ID (Node)) is
when rhs_alternative_list_ID =>
+ case To_Token_Enum (Tree.ID (Tree.Child (Node, 1))) is
+ when rhs_alternative_list_1_ID =>
+ Add_Token_Labels_1 (Tree.Child (Node, 1));
+
+ when attribute_list_ID =>
+ Add_Token_Labels_1 (Tree.Child (Node, 2));
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+
+ when rhs_alternative_list_1_ID =>
+ -- Translate_RHS_Optional_Item creates one new RHS for each
+ -- alternative, so they all start with the same token index. See
+ -- subprograms.wy iterator_specification ['in' | 'of'].
declare
+ Init_Index : constant SAL.Base_Peek_Type := Last_Token_Index;
Alt_List : constant Constant_List := Creators.Create_List
- (Tree, Node, +rhs_alternative_list_ID, +rhs_item_list_ID);
+ (Tree, Node, +rhs_alternative_list_1_ID, +rhs_item_list_ID);
begin
for Item_List of Alt_List loop
+ Last_Token_Index := Init_Index;
Add_Token_Labels_1 (Item_List);
end loop;
end;
+ when attribute_list_ID =>
+ null;
+
when rhs_item_list_ID =>
declare
RHS_Item_List : constant Constant_List := Creators.Create_List
@@ -766,93 +931,117 @@ package body WisiToken_Grammar_Editing is
for Cur in RHS_Item_List.Iterate_Constant loop
declare
Element : Valid_Node_Access := WisiToken.Syntax_Trees.LR_Utils.Element (Cur);
- Item : constant Valid_Node_Access := Tree.Child (Element, 1);
+ Item : constant Valid_Node_Access := Tree.Child (Element, Tree.Child_Count (Element));
begin
- case Tree.RHS_Index (Item) is
- when 0 | 1 =>
- Add_Token_Label (Element);
+ if Tree.Child_Count (Element) = 3 then
+ -- Already has a manual label; preserve it, and preserve
+ -- auto label numbering.
+ Last_Token_Index := @ + 1;
+ Add_Orig_Token_Index (Element);
- when 2 =>
- null;
-
- when 3 =>
- declare
- Opt_Item : constant Valid_Node_Access := Tree.Child (Item, 1);
- begin
- case Tree.RHS_Index (Opt_Item) is
- when 0 | 1 =>
- Add_Token_Labels_1 (Tree.Child (Opt_Item, 2));
-
- when 2 | 3 =>
- Add_Token_Label (Element);
- when others =>
- raise SAL.Programmer_Error;
- end case;
- end;
-
- when 4 =>
- declare
- Mult_Item : constant Valid_Node_Access := Tree.Child (Item, 1);
- begin
- case Tree.RHS_Index (Mult_Item) is
- when 0 .. 3 =>
- declare
- Content_List : constant Constant_List := Creators.Create_List
- (Tree, Tree.Child (Mult_Item, 2), +rhs_alternative_list_ID, +rhs_item_list_ID);
- begin
- if Content_List.Count = 1 then
- Add_Token_Label (Element);
- else
- Add_Token_Labels_1 (Tree.Child (Mult_Item, 2));
- end if;
- end;
-
- when 4 .. 5 =>
- Add_Token_Label (Element);
- when others =>
- raise SAL.Programmer_Error;
- end case;
- end;
-
- when 5 =>
- -- rhs_group_item
- Add_Token_Labels_1 (Tree.Child (Tree.Child (Item, 1), 2));
-
- when others =>
- raise SAL.Programmer_Error;
- end case;
+ else
+ -- Element has no manual label; add next auto one.
+
+ case To_Token_Enum (Tree.ID (Tree.Child (Item, 1))) is
+ when IDENTIFIER_ID | STRING_LITERAL_SINGLE_ID =>
+ Add_Token_Label (Element);
+ Add_Orig_Token_Index (Element);
+
+ when rhs_optional_item_ID =>
+ declare
+ Opt_Item : constant Valid_Node_Access := Tree.Child (Item, 1);
+ begin
+ case Tree.RHS_Index (Opt_Item) is
+ when 0 | 1 =>
+ Add_Token_Labels_1 (Tree.Child (Opt_Item, 2));
+
+ when 2 | 3 =>
+ Add_Token_Label (Element);
+ Add_Orig_Token_Index (Element);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+ end;
+
+ when rhs_multiple_item_ID =>
+ declare
+ Mult_Item : constant Valid_Node_Access := Tree.Child (Item, 1);
+ begin
+ case Tree.RHS_Index (Mult_Item) is
+ when 0 .. 3 =>
+ -- If there is only one rhs_element in the multiple_item, it will be
+ -- replaced by a list nonterm; the label must be on that. See
+ -- subprograms.wy compilation_unit. IMPROVEME: there are probably
+ -- other cases like this.
+ declare
+ RHS_Alt_List : constant Valid_Node_Access := Tree.Child (Mult_Item, 2);
+ RHS_Alt_List_1 : constant Valid_Node_Access := Tree.Child
+ (RHS_Alt_List, Tree.Child_Count (RHS_Alt_List));
+ Content_List : constant Constant_List := Creators.Create_List
+ (Tree, RHS_Alt_List_1, +rhs_alternative_list_1_ID, +rhs_item_list_ID);
+ begin
+ if Content_List.Count = 1 then
+ Add_Token_Label (Element);
+ Add_Orig_Token_Index (Element);
+
+ else
+ Add_Token_Labels_1 (Tree.Child (Mult_Item, 2));
+ end if;
+ end;
+
+ when 4 .. 5 =>
+ Add_Token_Label (Element);
+ Add_Orig_Token_Index (Element);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+ end;
+
+ when rhs_group_item_ID =>
+ -- The group is either replaced by a nonterm (label the nonterm), or
+ -- expanded in a list of RHS (apply the label here; it is copied in
+ -- Translate_RHS_Group_Item). ada_annex_p.wy object_declaration,
+ -- subtype_declaration.
+ Add_Token_Label (Element);
+ Add_Orig_Token_Index (Element);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+ end if;
end;
end loop;
end;
when others =>
- raise SAL.Programmer_Error;
+ raise SAL.Programmer_Error with "Add_Token_Labels_1 " & Tree.Image (Node, Node_Numbers => True);
end case;
end Add_Token_Labels_1;
+
+ Aug : Augmented_Access := Augmented_Access (Tree.Augmented (RHS));
begin
if Trace_Generate_EBNF > Outline then
Ada.Text_IO.Put_Line ("add token labels " & Tree.Image (RHS, Node_Numbers => True));
end if;
- case Tree.RHS_Index (RHS) is
- when 0 | 1 =>
- null;
+ if Aug = null then
+ Aug := new WisiToken_Grammar_Runtime.Augmented'
+ (Orig_EBNF_RHS => True,
+ Auto_Token_Labels => True,
+ others => <>);
+ Tree.Set_Augmented (RHS, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
+ else
+ Aug.Auto_Token_Labels := True;
+ end if;
- when 2 | 3 =>
- declare
- Aug : Augmented_Access := Augmented_Access (Tree.Augmented (RHS));
- begin
- if Aug = null then
- Aug := new WisiToken_Grammar_Runtime.Augmented'(Auto_Token_Labels => True, others => <>);
- Tree.Set_Augmented (RHS, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
- else
- Aug.Auto_Token_Labels := True;
- end if;
- Add_Token_Labels_1 (Tree.Child (RHS, 1));
- -- Labels in actions will be applied in wisitoken-bnf-output_ada_emacs.adb
- end;
- when others =>
- raise SAL.Programmer_Error;
- end case;
+ Add_Token_Labels_1
+ (Tree.Child
+ (RHS,
+ (if To_Token_Enum (Tree.ID (Tree.Child (RHS, 1))) = rhs_item_list_ID
+ then 1
+ else 2)));
+ -- Labels in actions will be applied in wisitoken-bnf-output_ada_emacs.adb
end Add_Token_Labels;
function Nonterm_Content_Equal
@@ -860,6 +1049,7 @@ package body WisiToken_Grammar_Editing is
List : in LR_Utils.Constant_List'Class;
Node : in Valid_Node_Access)
return Boolean
+ -- Ignores attributes.
is
pragma Unreferenced (List);
begin
@@ -869,14 +1059,18 @@ package body WisiToken_Grammar_Editing is
-- (compilation_unit_1, (111 . 128))
-- | (nonterminal_0, (111 . 128))
-- | | 7;(IDENTIFIER, (111 . 128))
+ -- | | [attribute_list]
-- | | (COLON)
-- | | (rhs_list_1, (111 . 128))
-- | | | ...
declare
- RHS_List_1 : constant Node_Access := Tree.Child (Tree.Child (Node, 1), 3);
+ Nonterm : constant Valid_Node_Access := Tree.Child (Node, 1);
+ RHS_List : constant Node_Access := Tree.Child
+ (Nonterm,
+ (if Tree.ID (Tree.Child (Nonterm, 3)) = +rhs_list_ID then 3 else 4));
begin
- if RHS_List_1 /= Invalid_Node_Access and then
- Target = Get_Text (Data, Tree, RHS_List_1)
+ if RHS_List /= Invalid_Node_Access and then
+ Target = Get_Text (Data, Tree, RHS_List)
then
return True;
end if;
@@ -899,19 +1093,31 @@ package body WisiToken_Grammar_Editing is
end Find_Nonterminal;
function Tree_Add_Nonterminal
- (Child_1 : in Valid_Node_Access;
- Child_2 : in Valid_Node_Access;
- Child_3 : in Valid_Node_Access;
- Child_4 : in Valid_Node_Access)
+ (Identifier : in Valid_Node_Access;
+ Attr_List : in Node_Access;
+ Colon : in Valid_Node_Access;
+ RHS_List : in Valid_Node_Access;
+ Semicolon : in Valid_Node_Access)
return Valid_Node_Access
+ with Pre =>
+ (Tree.Label (Identifier) in Terminal_Label and
+ Is_Terminal (Tree.ID (Identifier), Tree.Lexer.Descriptor.all)) and
+ (Attr_List = Invalid_Node_Access or else Tree.ID (Attr_List) = +attribute_list_ID) and
+ Tree.ID (Colon) = +COLON_ID and
+ Tree.ID (RHS_List) = +rhs_list_ID and
+ Tree.ID (Semicolon) in +SEMICOLON_ID | +semicolon_opt_ID
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),
- Clear_Parents => False);
+ if Attr_List = Invalid_Node_Access then
+ return Tree.Add_Nonterm
+ (Production => (+nonterminal_ID, 0),
+ Children => (Identifier, Colon, RHS_List, Semicolon),
+ Clear_Parents => False);
+ else
+ return Tree.Add_Nonterm
+ (Production => (+nonterminal_ID, 1),
+ Children => (Identifier, Attr_List, Colon, RHS_List, Semicolon),
+ Clear_Parents => False);
+ end if;
end Tree_Add_Nonterminal;
function Duplicate
@@ -952,32 +1158,62 @@ package body WisiToken_Grammar_Editing is
(RHS_List : in out LR_Utils.List;
New_RHS_Item_List : in Valid_Node_Access;
After : in Valid_Node_Access;
+ Orig_EBNF_RHS : in Boolean;
Auto_Token_Labels : in Boolean)
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)
+ -- Insert in RHS_List a new RHS containing New_RHS_Item_List, after
+ -- After. Attributes and Actions are copied from After.
is
- Child_3 : constant Valid_Node_Access :=
- (if Tree.RHS_Index (After) = 3
- then Tree.Copy_Subtree (Tree.Child (After, 3), Data_Access)
- else Dummy_Node);
+ Attr_List : constant Node_Access :=
+ (if Tree.ID (Tree.Child (After, 1)) = +attribute_list_ID
+ then Tree.Copy_Subtree (Tree.Child (After, 1), Data_Access)
+ else Invalid_Node_Access);
+
+ Action_1 : constant Valid_Node_Access :=
+ (if Attr_List = Invalid_Node_Access then
+ (if Tree.Child_Count (After) >= 2
+ then Tree.Copy_Subtree (Tree.Child (After, 2), Data_Access)
+ else Dummy_Node)
+ else
+ (if Tree.Child_Count (After) >= 3
+ then Tree.Copy_Subtree (Tree.Child (After, 3), Data_Access)
+ else Dummy_Node));
+
+ Action_2 : constant Valid_Node_Access :=
+ (if Attr_List = Invalid_Node_Access then
+ (if Tree.Child_Count (After) >= 3
+ then Tree.Copy_Subtree (Tree.Child (After, 3), Data_Access)
+ else Dummy_Node)
+ else
+ (if Tree.Child_Count (After) >= 4
+ then Tree.Copy_Subtree (Tree.Child (After, 4), Data_Access)
+ else Dummy_Node));
RHS : constant Valid_Node_Access := 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), Data_Access)),
- when 3 => (New_RHS_Item_List,
- Tree.Copy_Subtree (Tree.Child (After, 2), Data_Access),
- Child_3),
- when others => raise SAL.Programmer_Error),
+ (if Attr_List = Invalid_Node_Access then
+ (case Tree.Child_Count (After) is
+ when 1 => (1 => New_RHS_Item_List),
+ when 2 => (New_RHS_Item_List, Action_1),
+ when 3 => (New_RHS_Item_List, Action_1, Action_2),
+ when others => raise SAL.Programmer_Error)
+ else
+ (case Tree.Child_Count (After) is
+ when 2 => (Attr_List, New_RHS_Item_List),
+ when 3 => (Attr_List, New_RHS_Item_List, Action_1),
+ when 4 => (Attr_List, New_RHS_Item_List, Action_1, Action_2),
+ when others => raise SAL.Programmer_Error)),
Clear_Parents => True);
Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'
(EBNF => False,
Auto_Token_Labels => Auto_Token_Labels,
- Edited_Token_List => True);
+ Orig_EBNF_RHS => Orig_EBNF_RHS,
+ EBNF_RHS_Index => <>,
+ Orig_Token_Index => <>);
begin
Tree.Set_Augmented (RHS, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
@@ -996,8 +1232,7 @@ package body WisiToken_Grammar_Editing is
rhs_optional_item_ID |
rhs_multiple_item_ID |
rhs_group_item_ID |
- rhs_attribute_ID |
- STRING_LITERAL_2_ID
+ STRING_LITERAL_SINGLE_ID
then
if Trace_Generate_EBNF > Outline then
Ada.Text_IO.Put_Line ("new EBNF node " & Tree.Image (Node, Node_Numbers => True));
@@ -1019,19 +1254,23 @@ package body WisiToken_Grammar_Editing is
rhs_optional_item_ID |
rhs_multiple_item_ID |
rhs_group_item_ID |
- rhs_attribute_ID |
- STRING_LITERAL_2_ID
+ STRING_LITERAL_SINGLE_ID
then
if EBNF_Nodes.Contains (Node) then
-- Node is original, not copied
if Trace_Generate_EBNF > Outline then
- Ada.Text_IO.Put_Line ("erase original deleted EBNF node" & Trimmed_Image (Get_Node_Index (Node)));
+ Ada.Text_IO.Put_Line ("erase original deleted EBNF node " & Trimmed_Image (Get_Node_Index (Node)));
end if;
EBNF_Nodes.Delete (Node);
else
Copied_EBNF_Nodes.Delete (Node);
end if;
end if;
+ exception
+ when SAL.Not_Found =>
+ Ada.Text_IO.Put_Line
+ ("delete requested for node " & Trimmed_Image (Get_Node_Index (Node)) & ": not found.");
+ raise SAL.Programmer_Error;
end Erase_Deleted_Node;
begin
Tree.Process_Tree (Erase_Deleted_Node'Access, Node);
@@ -1122,7 +1361,7 @@ package body WisiToken_Grammar_Editing is
List_ID => +rhs_item_list_ID,
Element_ID => +rhs_element_ID,
Separator_ID => Invalid_Token_ID,
- Multi_Element_RHS => 1);
+ Multi_Element_RHS => 0);
Skip_Last := Skip_Last - 1;
end if;
@@ -1130,7 +1369,7 @@ package body WisiToken_Grammar_Editing is
when rhs_element_ID =>
declare
List_Node : Valid_Node_Access := Tree.Find_Ancestor
- (Skip_Node, (+rhs_ID, +rhs_alternative_list_ID));
+ (Skip_Node, (+rhs_ID, +rhs_alternative_list_1_ID));
begin
if Result.Skips'Length = 0 and then
@@ -1141,7 +1380,7 @@ package body WisiToken_Grammar_Editing is
exit;
end if;
- List_Node := List_Root (Tree, List_Node, +rhs_alternative_list_ID);
+ List_Node := List_Root (Tree, List_Node, +rhs_alternative_list_1_ID);
Skip_Node := Tree.Find_Ancestor (Skip_Node, +rhs_element_ID);
Search_For := +rhs_item_list_ID;
@@ -1159,10 +1398,10 @@ package body WisiToken_Grammar_Editing is
(Label => Nested,
Element => Skip_Node,
List_Root => List_Node,
- List_ID => +rhs_alternative_list_ID,
+ List_ID => +rhs_alternative_list_1_ID,
Element_ID => +rhs_item_list_ID,
Separator_ID => +BAR_ID,
- Multi_Element_RHS => 1);
+ Multi_Element_RHS => 0);
Skip_Last := Skip_Last - 1;
end if;
@@ -1192,7 +1431,7 @@ package body WisiToken_Grammar_Editing is
Result.Start_Element_ID := +rhs_element_ID;
Result.Start_Separator_ID := Invalid_Token_ID;
- Result.Start_Multi_Element_RHS := 1;
+ Result.Start_Multi_Element_RHS := 0;
Result.Skips (Skip_Last) := (Skip, Last_Skip_Node);
@@ -1205,7 +1444,7 @@ package body WisiToken_Grammar_Editing is
end;
end Find_Skips;
- Container : Valid_Node_Access := Tree.Find_Ancestor (B, (+rhs_ID, +rhs_alternative_list_ID));
+ Container : Valid_Node_Access := Tree.Find_Ancestor (B, (+rhs_ID, +rhs_alternative_list_1_ID));
Container_ID : WisiToken.Token_ID := Tree.ID (Container);
Container_List : LR_Utils.List :=
@@ -1218,8 +1457,8 @@ package body WisiToken_Grammar_Editing is
Separator_ID => +BAR_ID)
else Create_List
(Tree,
- Root => List_Root (Tree, Container, +rhs_alternative_list_ID),
- List_ID => +rhs_alternative_list_ID,
+ Root => List_Root (Tree, Container, +rhs_alternative_list_1_ID),
+ List_ID => +rhs_alternative_list_1_ID,
Element_ID => +rhs_item_list_ID,
Separator_ID => +BAR_ID));
@@ -1227,7 +1466,7 @@ package body WisiToken_Grammar_Editing is
if Trace_Generate_EBNF > Extra then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("Insert_Optional_RHS start: " & Get_Text (Data, Tree, Container));
- Tree.Print_Tree (Container);
+ Tree.Print_Tree (Container, Augmented => True);
end if;
declare
@@ -1249,7 +1488,7 @@ package body WisiToken_Grammar_Editing is
-- 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
+ if Container_ID = +rhs_alternative_list_1_ID then
Container := Tree.Find_Ancestor (B, +rhs_ID);
@@ -1280,6 +1519,7 @@ package body WisiToken_Grammar_Editing is
(Container_List,
New_RHS_AC,
After => Container,
+ Orig_EBNF_RHS => False,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B));
end if;
end if;
@@ -1300,7 +1540,9 @@ package body WisiToken_Grammar_Editing is
Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'
(EBNF => False,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B),
- Edited_Token_List => True);
+ Orig_EBNF_RHS => False,
+ EBNF_RHS_Index => <>,
+ Orig_Token_Index => <>);
begin
loop
After := List_Root (Tree, Tree.Find_Ancestor (After, +rhs_item_list_ID), +rhs_item_list_ID);
@@ -1328,12 +1570,12 @@ package body WisiToken_Grammar_Editing is
if Container_ID = +rhs_ID then
Ada.Text_IO.Put_Line
("Insert_Optional_RHS old rhs, new rhs: " & Get_Text (Data, Tree, Container_List.Root));
- Tree.Print_Tree (Container_List.Root);
+ Tree.Print_Tree (Container_List.Root, Augmented => True);
else
Ada.Text_IO.Put_Line
("Insert_Optional_RHS edited rhs_alternative_list: " & Get_Text
(Data, Tree, Tree.Parent (Container_List.Root)));
- Tree.Print_Tree (Tree.Parent (Container_List.Root));
+ Tree.Print_Tree (Tree.Parent (Container_List.Root), Augmented => True);
end if;
end if;
end if;
@@ -1396,7 +1638,7 @@ package body WisiToken_Grammar_Editing is
("new " & Label & ":" & Trimmed_Image (Get_Node_Index (Comp_Unit)) & ": '" &
Get_Text (Data, Tree, Unit) & "'");
if Trace_Generate_EBNF > Extra then
- Tree.Print_Tree (Comp_Unit);
+ Tree.Print_Tree (Comp_Unit, Augmented => True);
end if;
end if;
end Add_Compilation_Unit;
@@ -1413,13 +1655,13 @@ package body WisiToken_Grammar_Editing is
-- Post_Parse_Action, _2 are not copied.
is
RHS_Item_List : constant Valid_Node_Access := Tree.Add_Nonterm
- ((+rhs_item_list_ID, 0), (1 => RHS_Element), Clear_Parents => True);
+ ((+rhs_item_list_ID, 1), (1 => RHS_Element), Clear_Parents => True);
RHS : constant Valid_Node_Access := Add_RHS
(Tree,
- RHS_Item_List,
- Auto_Token_Labels,
- Edited_Token_List => True,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List,
+ Auto_Token_Labels => Auto_Token_Labels,
Post_Parse_Action => Post_Parse_Action,
In_Parse_Action => In_Parse_Action);
begin
@@ -1433,26 +1675,35 @@ package body WisiToken_Grammar_Editing is
In_Parse_Action : in Node_Access := Invalid_Node_Access)
return Valid_Node_Access
with Pre => Tree.ID (Content) = +rhs_alternative_list_ID
- -- Convert Content to an rhs_list; Content is edited.
+ -- Return a new rhs_list constructed by editing Content.
+ -- Caller is responsible for promoting attribute_list in Content to
+ -- the nonterm attribute_list; result rhs's have null attr_list.
--
- -- Post_Parse_Action, _2 are not copied for the first RHS; they are copied
+ -- Actions are not copied for the first RHS; they are copied
-- for any more.
is
- Node : Valid_Node_Access := Content;
- Copy_Actions : Boolean := False;
+ Node : Valid_Node_Access := Tree.Child (Content, Tree.Child_Count (Content));
+ pragma Assert (Tree.ID (Node) = +rhs_alternative_list_1_ID);
+
+ Result : constant Valid_Node_Access := Node;
+
+ Copy_Actions : Boolean := False;
begin
loop
- exit when Tree.RHS_Index (Node) = 0;
+ exit when Tree.Child_Count (Node) = 1; -- only one RHS left
-- 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 : Content
+ -- | rhs_attribute_list : Attr_List
+ -- | rhs_alternative_list_1: Node
+ -- | | rhs_alternative_list_1: Node.Child(1)
+ -- | | | ...
+ -- | | BAR: Node.child (2)
+ -- | | rhs_item_list: Node.Child (3)
+
+ -- new tree for 1 RHS:
+ -- rhs_list: Content
+ -- | rhs_attribute_list : Attr_List
-- | rhs_alternative_list: keep Node.Child (1)
-- | | ...
-- | BAR: keep
@@ -1480,8 +1731,10 @@ package body WisiToken_Grammar_Editing is
else
declare
RHS : constant Valid_Node_Access := Add_RHS
- (Tree, Tree.Child (Node, 3), Auto_Token_Labels,
- Edited_Token_List => True,
+ (Tree,
+ Attr_List => Invalid_Node_Access,
+ Item_List => Tree.Child (Node, 3),
+ Auto_Token_Labels => Auto_Token_Labels,
Post_Parse_Action =>
(if Copy_Actions then Tree.Copy_Subtree (Post_Parse_Action, Data_Access) else Post_Parse_Action),
In_Parse_Action =>
@@ -1502,18 +1755,23 @@ package body WisiToken_Grammar_Editing is
end loop;
-- current tree:
- -- rhs_alternative_list : Node
- -- | rhs_item_list: Node.Child (1)
+ -- rhs_alternative_list : Content
+ -- | rhs_attribute_list : Content.Child (1) or not present
+ -- | rhs_alternative_list_1 : Content.child (last)
+ -- | | edited above
-- new tree:
-- rhs_list: Node
-- | rhs: new
- -- | | rhs_item_list: Node.Child (1)
+ -- | | rhs_attribute_list : Content.Child (1) or not present
+ -- | | rhs_item_list: Node.Child (last)
declare
RHS : constant Valid_Node_Access := Add_RHS
- (Tree, Tree.Child (Node, 1), Auto_Token_Labels,
- Edited_Token_List => True,
+ (Tree,
+ Attr_List => Invalid_Node_Access,
+ Item_List => Tree.Child (Node, Tree.Child_Count (Node)),
+ Auto_Token_Labels => Auto_Token_Labels,
Post_Parse_Action =>
(if Copy_Actions then Tree.Copy_Subtree (Post_Parse_Action, Data_Access) else Post_Parse_Action),
In_Parse_Action =>
@@ -1522,7 +1780,7 @@ package body WisiToken_Grammar_Editing is
Tree.Set_Children (Node, (+rhs_list_ID, 0), (1 => RHS));
end;
- return Content;
+ return Result;
end Convert_RHS_Alternative;
procedure New_Nonterminal
@@ -1535,25 +1793,25 @@ package body WisiToken_Grammar_Editing is
--
-- We don't copy actions to a new nonterminal; they will not make sense.
is
- Child_1 : constant Valid_Node_Access := Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier);
+ Identifier : constant Valid_Node_Access := Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier);
- Child_2 : constant Valid_Node_Access := Tree.Add_Terminal (+COLON_ID);
+ Colon : constant Valid_Node_Access := Tree.Add_Terminal (+COLON_ID);
- Child_3 : constant Valid_Node_Access :=
+ RHS_List : constant Valid_Node_Access :=
(case To_Token_Enum (Tree.ID (Content)) is
when rhs_element_ID => To_RHS_List (Content, Get_RHS_Auto_Token_Labels (Content)),
when rhs_alternative_list_ID => Convert_RHS_Alternative
(Content, Get_RHS_Auto_Token_Labels (Content)),
when others => raise SAL.Programmer_Error);
- Child_4 : constant Valid_Node_Access := Tree.Add_Nonterm
+ Semicolon : constant Valid_Node_Access := Tree.Add_Nonterm
((+semicolon_opt_ID, 0),
(1 => Tree.Add_Terminal (+SEMICOLON_ID)),
Clear_Parents => True);
New_Nonterm : constant Valid_Node_Access := Tree.Add_Nonterm
(Production => (+nonterminal_ID, 0),
- Children => (Child_1, Child_2, Child_3, Child_4),
+ Children => (Identifier, Colon, RHS_List, Semicolon),
Clear_Parents => True); -- Child_3 can be Content
begin
Add_Compilation_Unit (Label & New_Identifier'Image, New_Nonterm);
@@ -1573,23 +1831,33 @@ package body WisiToken_Grammar_Editing is
if Data.User_Parser in WisiToken.BNF.LR_Generate_Algorithm and Data.Language_Params.Error_Recover then
-- FIXME: these should have different labels? need test case
RHS_Item_List_3.Append
- (Add_RHS_Element (Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)), Label));
+ (Add_RHS_Element
+ (Tree,
+ Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)),
+ Label,
+ Augmented => new WisiToken_Grammar_Runtime.Augmented'(Orig_Token_Index => 0, others => <>)));
if Separator /= Invalid_Identifier_Token then
RHS_Item_List_3.Append
(Add_RHS_Element
- (Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, Separator)), Label));
+ (Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, Separator)),
+ Label,
+ Augmented => new WisiToken_Grammar_Runtime.Augmented'(Orig_Token_Index => 0, others => <>)));
end if;
RHS_Item_List_3.Append
- (Add_RHS_Element (Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)), Label));
+ (Add_RHS_Element
+ (Tree,
+ Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)),
+ Label,
+ Augmented => new WisiToken_Grammar_Runtime.Augmented'(Orig_Token_Index => 0, others => <>)));
RHS_List.Append
(Add_RHS
(Tree,
- RHS_Item_List_3.Root,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List_3.Root,
Auto_Token_Labels => Auto_Token_Labels,
- Edited_Token_List => True,
Post_Parse_Action => Invalid_Node_Access,
In_Parse_Action => Invalid_Node_Access));
end if;
@@ -1598,6 +1866,7 @@ package body WisiToken_Grammar_Editing is
procedure New_Nonterminal_List
(List_Nonterm : in Identifier_Token;
+ Attr_List : in Node_Access;
RHS_Item_List_1_Root : in Valid_Node_Access;
Separator : in Identifier_Token;
Auto_Token_Labels : in Boolean)
@@ -1625,25 +1894,42 @@ package body WisiToken_Grammar_Editing is
RHS_Item_List_2.Append (Tree.Copy_Subtree (Element, Data_Access));
end loop;
- RHS_List.Append (Add_RHS (Tree, RHS_Item_List_1.Root, Auto_Token_Labels, Edited_Token_List => True));
- RHS_List.Append (Add_RHS (Tree, RHS_Item_List_2.Root, Auto_Token_Labels, Edited_Token_List => True));
+ RHS_List.Append
+ (Add_RHS
+ (Tree,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List_1.Root,
+ Auto_Token_Labels => Auto_Token_Labels));
+
+ RHS_List.Append
+ (Add_RHS
+ (Tree,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List_2.Root,
+ Auto_Token_Labels => Auto_Token_Labels));
- Maybe_Optimized_List (RHS_List, List_Nonterm, Separator, Auto_Token_Labels);
+ Maybe_Optimized_List
+ (RHS_List => RHS_List,
+ List_Name => List_Nonterm,
+ Separator => Separator,
+ Auto_Token_Labels => Auto_Token_Labels);
Add_Compilation_Unit
("canonical list",
Tree_Add_Nonterminal
- (Child_1 => Add_Identifier_Token (Tree, List_Nonterm),
- Child_2 => Tree.Add_Terminal (+COLON_ID),
- Child_3 => RHS_List.Root,
- Child_4 => Tree.Add_Nonterm
+ (Identifier => Add_Identifier_Token (Tree, List_Nonterm),
+ Attr_List => Attr_List,
+ Colon => Tree.Add_Terminal (+COLON_ID),
+ RHS_List => RHS_List.Root,
+ Semicolon => Tree.Add_Nonterm
((+semicolon_opt_ID, 0),
- (1 => Tree.Add_Terminal (+SEMICOLON_ID)),
+ (1 => Tree.Add_Terminal (+SEMICOLON_ID)),
Clear_Parents => False)));
end New_Nonterminal_List;
procedure New_Nonterminal_List
(List_Nonterm : in Identifier_Token;
+ Attr_List : in Node_Access;
List_Element : in Identifier_Token;
Separator : in Identifier_Token;
Auto_Token_Labels : in Boolean)
@@ -1651,6 +1937,7 @@ package body WisiToken_Grammar_Editing is
-- Add a nonterminal declaration for a canonical list:
--
-- foo_list ;; List_Nonterm
+ -- <attributes>
-- : foo ;; List_Element
-- | foo_list separator foo ;; List_Nonterm Separator List_Element
@@ -1661,7 +1948,7 @@ package body WisiToken_Grammar_Editing is
RHS_Item_List_1.Append
(Add_RHS_Element
(Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Element))));
- New_Nonterminal_List (List_Nonterm, RHS_Item_List_1.Root, Separator, Auto_Token_Labels);
+ New_Nonterminal_List (List_Nonterm, Attr_List, RHS_Item_List_1.Root, Separator, Auto_Token_Labels);
end New_Nonterminal_List;
function List_Matches
@@ -1670,7 +1957,7 @@ package body WisiToken_Grammar_Editing is
Element_Content : in String)
return Node_Access
with Pre => Element_Content'Length > 0
- -- Return True if the declaration at N is a nonterminal for a
+ -- Return the name node if the declaration N is a nonterminal for a
-- canonical list matching Separator_Content, Element_Content,
-- possibly optimized.
is
@@ -1680,13 +1967,14 @@ package body WisiToken_Grammar_Editing is
declare
-- Target List_Nonterm is:
--
- -- list_nonterm
+ -- list_nonterm [<attr>]
-- : element
-- | list_nonterm separator? element
- -- | list_nonterm list_nonterm
+ -- [| list_nonterm list_nonterm]
--
-- nonterminal: N
-- | IDENTIFIER : Name_Node
+ -- [| attr_list : Attr_List]
-- | COLON
-- | rhs_list: RHS_List
-- | | rhs_list:
@@ -1696,8 +1984,14 @@ package body WisiToken_Grammar_Editing is
-- | | rhs: ... list_nonterm separator? list_element
Name_Node : constant Node_Access := Tree.Child (N, 1);
+ Attr_List : constant Node_Access :=
+ (if Tree.ID (Tree.Child (N, 2)) = +attribute_list_ID
+ then Tree.Child (N, 2)
+ else Invalid_Node_Access);
RHS_List : constant Constant_List := Creators.Create_List
- (Tree, Tree.Child (N, 3), +rhs_list_ID, +rhs_ID);
+ (Tree,
+ Tree.Child (N, (if Attr_List = Invalid_Node_Access then 3 else 4)),
+ +rhs_list_ID, +rhs_ID);
Iter : constant Constant_Iterator := RHS_List.Iterate_Constant;
begin
if RHS_List.Count in 2 | 3 then
@@ -1806,12 +2100,18 @@ package body WisiToken_Grammar_Editing is
when rhs_item_list_ID =>
pragma Assert (Separator_Ident_Tok = Invalid_Identifier_Token);
- New_Nonterminal_List (List_Nonterm_Name, Element, Separator_Ident_Tok, Auto_Token_Labels);
+ New_Nonterminal_List
+ (List_Nonterm_Name,
+ Attr_List => Invalid_Node_Access,
+ RHS_Item_List_1_Root => Element,
+ Separator => Separator_Ident_Tok,
+ Auto_Token_Labels => Auto_Token_Labels);
when rhs_element_ID =>
New_Nonterminal_List
(List_Nonterm => List_Nonterm_Name,
+ Attr_List => Invalid_Node_Access,
List_Element => To_Identifier_Token
(Tree.Find_Descendant (Element, +rhs_item_ID), Tree),
Separator => Separator_Ident_Tok,
@@ -1821,6 +2121,7 @@ package body WisiToken_Grammar_Editing is
New_Nonterminal_List
(List_Nonterm => List_Nonterm_Name,
+ Attr_List => Invalid_Node_Access,
List_Element => To_Identifier_Token (Element, Tree),
Separator => Separator_Ident_Tok,
Auto_Token_Labels => Auto_Token_Labels);
@@ -1852,6 +2153,7 @@ package body WisiToken_Grammar_Editing is
end Copy_Non_Grammar;
procedure Translate_RHS_Group_Item (Node : in Valid_Node_Access)
+ with Pre => Tree.ID (Node) = +rhs_group_item_ID
is
-- Current tree:
--
@@ -1862,58 +2164,295 @@ package body WisiToken_Grammar_Editing is
-- | | | rhs_alternative_list: Child (Node, 2)
-- | | | RIGHT_PAREN
- RHS : constant Valid_Node_Access := Tree.Find_Ancestor (Node, +rhs_ID);
- Has_Actions : constant Boolean := Tree.RHS_Index (RHS) in 2 .. 3;
- Element_Content : constant String := Get_Text (Data, Tree, Tree.Child (Node, 2));
- Right_Paren_Node : constant Valid_Node_Access := Tree.Child (Node, 3);
- Found_Unit : constant Node_Access :=
- (if Has_Actions then Invalid_Node_Access
- else Find_Nonterminal
- (Element_Content, Nonterm_Content_Equal'Unrestricted_Access));
- New_Ident : Base_Identifier_Index := Invalid_Identifier_Index;
+ -- If Node contains a simple alternative list, and is not contained
+ -- in a nested alternative list, expand it into a list of RHSs.
+ -- Otherwise replace it by a nonterminal. ada_ebnf.wy
+ -- subtype_declaration.
+
+ use LR_Utils;
+ use LR_Utils.Creators;
+
+ RHS : constant Valid_Node_Access := Tree.Find_Ancestor (Node, +rhs_ID);
+ Has_Actions : constant Boolean := +ACTION_ID =
+ Tree.ID (Tree.Child (RHS, Tree.Child_Count (RHS)));
+
+ function Is_Simple (List_Node : in Valid_Node_Access) return Boolean
+ with Pre => Tree.ID (List_Node) = +rhs_alternative_list_ID
+ is begin
+ if Tree.ID (Tree.Find_Ancestor (Node, (+rhs_ID, +rhs_alternative_list_ID))) = +rhs_alternative_list_ID then
+ -- Nested.
+ return False;
+ end if;
+
+ if +attribute_list_ID = Tree.ID (Tree.Child (List_Node, 1)) then
+ -- We assume these do not map to the alternatives individually.
+ return False;
+ end if;
+
+ declare
+ Alt_List : constant Constant_List := Create_List
+ (Tree, Tree.Child (List_Node, Tree.Child_Count (List_Node)),
+ +rhs_alternative_list_1_ID, +rhs_item_list_ID);
+ begin
+ for Item_List_Node of Alt_List loop
+ declare
+ Item_List : constant Constant_List := Create_List
+ (Tree, Item_List_Node, +rhs_item_list_ID, +rhs_element_ID);
+ begin
+ if Item_List.Count /= 1 then
+ return False;
+ end if;
+ declare
+ El : constant Valid_Node_Access := Element (Item_List.First);
+ Item : constant Valid_Node_Access := Tree.Child (El, Tree.Child_Count (El));
+ begin
+ if not (To_Token_Enum (Tree.ID (Tree.Child (Item, 1))) in
+ IDENTIFIER_ID | STRING_LITERAL_SINGLE_ID)
+ then
+ return False;
+ end if;
+ end;
+ end;
+ end loop;
+ end;
+ return True;
+ end Is_Simple;
begin
- if Found_Unit = Invalid_Node_Access then
- New_Ident := Next_Nonterm_Name;
- New_Nonterminal ("group item", New_Ident, Tree.Child (Node, 2));
- else
+ if Is_Simple (Tree.Child (Node, 2)) then
+ -- Expand into a list of RHSs.
+ --
+ -- IMPROVEME: Much of this is similar to Translate_RHS_Optional_Item;
+ -- factor out common parts.
+ --
+ -- Source looks like:
+ --
+ -- | A (B) C
+ --
+ -- B contains a simple rhs_alternative_list.
+ --
+ -- 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
+ --
+ -- current tree:
+ --
+ -- rhs_list:
+ -- | rhs:
+ -- | | rhs_item_list
+ -- | | | rhs_item_list
+ -- | | ...
+ -- | | | | | rhs_element: A.last
+ -- | | | | | | rhs_item:
+ -- | | | | rhs_element:
+ -- | | | | | rhs_item: contains
+ -- | | | | | | rhs_group_item: B
+ -- | | | | | | | LEFT_PAREN: B.Children (1)
+ -- | | | | | | | rhs_alternative_list: B.Children (2)
+ -- | | | | | | | RIGHT_PAREN: B.Children (3)
+ -- | | | rhs_element: C.first
+ -- | | | | rhs_item:
+ -- ...
+
+ -- tests: ada_ebnf.wy subtype_declaration, java_expressions_antlr.wy
+ -- expression, java_ebnf.wy expression, python_ebnf.wy testlist_comp,
+ -- dictorsetmaker
+ if Trace_Generate_EBNF > Extra then
+ Ada.Text_IO.Put_Line ("... simple");
+ end if;
+
declare
- Name_Node : constant Node_Access := Tree.Child (Tree.Child (Found_Unit, 1), 1);
+ B : Valid_Node_Access renames Node; -- same as Translate_RHS_Optional_Item
+
+ Group_Label : constant Node_Access :=
+ (if +IDENTIFIER_ID = Tree.ID (Tree.Child (Tree.Parent (Node, 2), 1))
+ then Tree.Child (Tree.Parent (Node, 2), 1)
+ else Invalid_Node_Access);
+ -- We assume this label maps to the alternatives.
+
+ RHS_List : LR_Utils.List := Create_From_Element
+ (Tree, RHS,
+ List_ID => +rhs_list_ID,
+ Element_ID => +rhs_ID,
+ Separator_ID => +BAR_ID);
+
+ RHS_Cur : Cursor := RHS_List.Find (RHS);
+
+ 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_Alt_List : constant Valid_Node_Access := Tree.Child (B, 2);
+ B_Alternative_List : constant Constant_List := Create_List
+ (Tree, Tree.Child (B_Alt_List, Tree.Child_Count (B_Alt_List)),
+ +rhs_alternative_list_1_ID, +rhs_item_list_ID);
begin
- case Tree.Label (Name_Node) is
- when Source_Terminal =>
- New_Ident := New_Identifier (Get_Text (Data, Tree, Name_Node));
- when Virtual_Identifier =>
- New_Ident := Tree.Identifier (Name_Node);
- when others =>
- WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error ("translate_rhs_group_item", Tree, Name_Node);
- end case;
+ for B_Item_List_Root of reverse B_Alternative_List loop
+ declare
+ B_Item_List_List : constant Constant_List := Create_List
+ (Tree, B_Item_List_Root, +rhs_item_list_ID, +rhs_element_ID);
+
+ B_El : constant Valid_Node_Access := Element (B_Item_List_List.First);
+
+ New_ABC : List := Empty_List (ABC_List);
+
+ function Is_Orig_EBNF_RHS return Boolean
+ is begin
+ -- Consider subprograms.wy iteration_scheme, which has a nested
+ -- rhs_optional_item. Translating the nested optional gives an
+ -- rhs_alternative_list with two elements, which are copied to two
+ -- RHSs when translating the outer optional item; the first has all
+ -- the tokens (and thus Orig_EBNF_RHS is True), the second is missing
+ -- some (and thus Orig_EBNF_RHS is False).
+ if B_Item_List_Root /= Element (First (B_Alternative_List)) then
+ return False;
+ end if;
+
+ if Tree.Augmented (RHS) = null then
+ -- This is an edited RHS with some optional left out.
+ return False;
+ else
+ return WisiToken_Grammar_Runtime.Augmented
+ (Tree.Augmented (RHS).all).Orig_EBNF_RHS;
+ end if;
+ end Is_Orig_EBNF_RHS;
+ begin
+ if Has_Element (ABC_A_Last) then
+ Copy (Source_List => ABC_List,
+ Source_Last => ABC_A_Last,
+ Dest_List => New_ABC,
+ User_Data => Data_Access);
+ end if;
+
+ declare
+ -- Use appropriate label for B item.
+
+ function Create_New_B_El return Valid_Node_Access
+ with Post => Tree.ID (Create_New_B_El'Result) = +rhs_element_ID
+ is begin
+ if +IDENTIFIER_ID = Tree.ID (Tree.Child (B_El, 1)) -- Already has a label; preserve it.
+ or Group_Label = Invalid_Node_Access -- No label
+ then
+ return Tree.Copy_Subtree (B_El, User_Data => Data_Access);
+
+ else
+ -- Add group label
+ declare
+ New_B_Item : constant Valid_Node_Access := Tree.Copy_Subtree
+ (Tree.Child (B_El, 1), User_Data => Data_Access);
+ Containing_El : constant Valid_Node_Access := Tree.Find_Ancestor (B, +rhs_element_ID);
+
+ begin
+ -- Copy Orig_Token_Index from parent rhs_element
+ return Add_RHS_Element
+ (Tree, New_B_Item, To_Identifier_Token (Group_Label, Tree),
+ Augmented =>
+ (if Tree.Augmented (Containing_El) = null
+ then null
+ else new WisiToken_Grammar_Runtime.Augmented'
+ (Orig_Token_Index => Augmented_Access_Constant
+ (Tree.Augmented (Containing_El)).Orig_Token_Index,
+ others => <>)));
+ end;
+ end if;
+ end Create_New_B_El;
+
+ begin
+ New_ABC.Append (Create_New_B_El);
+ end;
+
+ if Has_Element (ABC_C_First) then
+ Copy (ABC_List, Source_First => ABC_C_First, Dest_List => New_ABC, User_Data => Data_Access);
+ end if;
+
+ Insert_RHS
+ (RHS_List,
+ New_ABC.Root,
+ After => Element (RHS_Cur),
+ Orig_EBNF_RHS => Is_Orig_EBNF_RHS,
+ Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B));
+
+ Record_Copied_EBNF_Nodes (New_ABC.Root);
+ end;
+ end loop;
+
+ Erase_Deleted_EBNF_Nodes (Element (RHS_Cur));
+ -- This includes B, so we don't do 'Clear_EBNF_Node (B)'.
+
+ RHS_List.Delete (RHS_Cur);
+
+ if Trace_Generate_EBNF > Extra then
+ declare
+ Nonterm : constant Valid_Node_Access := Tree.Find_Ancestor (RHS_List.Root, +nonterminal_ID);
+ begin
+ Ada.Text_IO.New_Line;
+ Ada.Text_IO.Put_Line ("edited group item containing nonterm:");
+ Ada.Text_IO.Put_Line (Get_Text (Data, Tree, Nonterm));
+ Tree.Print_Tree (Nonterm, Augmented => True);
+ end;
+ end if;
end;
- Erase_Deleted_EBNF_Nodes (Tree.Child (Node, 2));
- end if;
- declare
- Ident_Node : constant Node_Access := Tree.Add_Identifier (+IDENTIFIER_ID, New_Ident);
- Element_Node : Valid_Node_Access := Tree.Parent (Node, 2);
- Item_Node : Valid_Node_Access := Tree.Parent (Node, 1);
- begin
- Tree.Set_Children (Item_Node, (+rhs_item_ID, 0), (1 => Ident_Node));
- Copy_Non_Grammar (Right_Paren_Node, Ident_Node);
+ else
+ if Trace_Generate_EBNF > Extra then
+ Ada.Text_IO.Put_Line ("... not simple");
+ end if;
+
+ -- Create or find a nonterm for the content, replace the group item by
+ -- the nonterm name.
+ declare
+ Element_Content : constant String := Get_Text (Data, Tree, Tree.Child (Node, 2));
+ Right_Paren_Node : constant Valid_Node_Access := Tree.Child (Node, 3);
+ Found_Unit : constant Node_Access :=
+ (if Has_Actions then Invalid_Node_Access
+ else Find_Nonterminal
+ (Element_Content, Nonterm_Content_Equal'Unrestricted_Access));
+ New_Ident : Base_Identifier_Index := Invalid_Identifier_Index;
+ begin
+ if Found_Unit = Invalid_Node_Access then
+ New_Ident := Next_Nonterm_Name;
+ New_Nonterminal ("group item", New_Ident, Tree.Child (Node, 2));
+ else
+ declare
+ Name_Node : constant Node_Access := Tree.Child (Tree.Child (Found_Unit, 1), 1);
+ begin
+ case Tree.Label (Name_Node) is
+ when Source_Terminal =>
+ New_Ident := New_Identifier (Get_Text (Data, Tree, Name_Node));
+ when Virtual_Identifier =>
+ New_Ident := Tree.Identifier (Name_Node);
+ when others =>
+ WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error
+ ("translate_rhs_group_item", Tree, Name_Node);
+ end case;
+ end;
+ Erase_Deleted_EBNF_Nodes (Tree.Child (Node, 2));
+ end if;
- if Get_RHS_Auto_Token_Labels (RHS) then
declare
- Label : constant Valid_Node_Access := Tree.Add_Identifier
- (+IDENTIFIER_ID, Next_Token_Label ("G"));
- Equal : constant Valid_Node_Access := Tree.Add_Terminal (+EQUAL_ID);
+ Ident_Node : constant Node_Access := Tree.Add_Identifier (+IDENTIFIER_ID, New_Ident);
+ Item_Node : Valid_Node_Access := Tree.Parent (Node, 1);
begin
- Tree.Set_Children (Element_Node, (+rhs_element_ID, 1), (Label, Equal, Item_Node));
- end;
- end if;
- end;
+ Tree.Set_Children (Item_Node, (+rhs_item_ID, 0), (1 => Ident_Node));
+ Copy_Non_Grammar (Right_Paren_Node, Ident_Node);
- Clear_EBNF_Node (Node);
+ -- Add_Token_Labels has already set the right label. ada_annex_p.wy
+ -- object_declaration.
+ end;
+ end;
+ Clear_EBNF_Node (Node);
+ end if;
end Translate_RHS_Group_Item;
procedure Translate_RHS_Multiple_Item (B : in Valid_Node_Access)
+ with Pre => Tree.ID (B) = +rhs_multiple_item_ID
is
-- We have one of:
--
@@ -1923,6 +2462,7 @@ package body WisiToken_Grammar_Editing is
-- | a ( b ) * c
-- | a b+ c
-- | a b* c
+ -- | e (a b* c) f
--
-- where a and/or c can be empty. Replace it with a new canonical
-- list nonterminal:
@@ -1937,6 +2477,10 @@ package body WisiToken_Grammar_Editing is
--
-- and a second RHS if it can be empty:
-- | a c
+ -- | e (a c) f
+
+ -- FIXME: this assumes left associativity; implement right when we
+ -- find a test case.
-- Current tree:
--
@@ -1955,7 +2499,7 @@ package body WisiToken_Grammar_Editing is
-- | rhs_item: Parent (B, 1)
-- | | rhs_multiple_item: B
-- | | | IDENTIFIER
- -- | | | PLUS | STAR
+ -- | | | [PLUS | STAR]
use LR_Utils;
use LR_Utils.Creators;
@@ -1969,20 +2513,40 @@ package body WisiToken_Grammar_Editing is
Parent_RHS_Item : Valid_Node_Access := Tree.Parent (B);
List_Nonterm_Name : Identifier_Token := Invalid_Identifier_Token;
- B_Alt_List_List : constant Constant_List :=
+ B_Attr_List : constant Node_Access :=
(case Tree.RHS_Index (B) is
when 0 .. 3 =>
- Create_List (Tree, Tree.Child (B, 2), +rhs_alternative_list_ID, +rhs_item_list_ID),
- when others => Invalid_List (Tree));
- -- The rhs_alternative_list of the rhs_multiple_item.
+ (if Tree.ID (Tree.Child (Tree.Child (B, 2), 1)) = +attribute_list_ID
+ then Tree.Child (Tree.Child (B, 2), 1) else Invalid_Node_Access),
+
+ when others => Invalid_Node_Access);
+
+ B_Alt_List : constant Node_Access :=
+ -- The rhs_alternative_list_1 node of the rhs_multiple_item.
+ (case Tree.RHS_Index (B) is
+ when 0 .. 3 => Tree.Child (Tree.Child (B, 2), (if B_Attr_List = Invalid_Node_Access then 1 else 2)),
+ when others => Invalid_Node_Access);
+
+ B_Alt_List_List : constant Constant_List :=
+ (if B_Alt_List /= Invalid_Node_Access then
+ Create_List (Tree, B_Alt_List, +rhs_alternative_list_1_ID, +rhs_item_list_ID)
+ else Invalid_List (Tree));
B_Alt_List_Item_List : List :=
+ -- The first rhs_item_list of the rhs_multiple_item.
(if B_Alt_List_List.Is_Invalid
then Invalid_List (Tree)
else Create_List
(Tree, Element (B_Alt_List_List.First), +rhs_item_list_ID, +rhs_element_ID,
Separator_ID => Invalid_Token_ID));
- -- The first rhs_item_list of the rhs_multiple_item.
+
+ RHS_0 : constant Valid_Node_Access := Tree.Find_Ancestor (B, +rhs_ID);
+ -- The top level RHS containing this multiple_item; any attributes on
+ -- this RHS apply to the new nonterm.
+
+ RHS_0_Attr_List : constant Node_Access :=
+ (if Tree.ID (Tree.Child (RHS_0, 1)) = +attribute_list_ID
+ then Tree.Child (RHS_0, 1) else Invalid_Node_Access);
Container_List_Root : Node_Access := Invalid_Node_Access;
-- Updated by Insert_Optional_RHS.
@@ -1997,8 +2561,9 @@ package body WisiToken_Grammar_Editing is
--
-- SwitchLabels : SwitchLabel {SwitchLabel}
--
- -- where B is the rhs_multiple_item containing "(','
- -- enumConstant)*" or "{SwitchLabel}".
+ -- where B is the rhs_multiple_item containing "(',' enumConstant)*"
+ -- or "{SwitchLabel}". SwitchLabels is a named list; enumConstant is
+ -- unnamed.
--
-- The tokens may have labels.
--
@@ -2006,24 +2571,34 @@ package body WisiToken_Grammar_Editing is
-- reducing to enumConstants and reducing to the introduced nonterm
-- list.
--
- -- Alternately, the no separator case can be:
+ -- Alternately, the no separator case can be one of:
--
-- enumConstants : enumConstant+ ;
+ -- (']' ('[' ']')* c) from java_ebnf.wy
+ --
+ -- Here enumConstants is named, the java_ebnf.wy case is unnamed. In
+ -- the java_ebnf.wy case, '[' looks like a separator, but is not;
+ -- fortunately, that distinction does not matter for our purposes.
--
-- Handling this no separator case specially does not eliminate any
-- conflicts, but it does reduce the number of added nonterminals,
-- and keeps the names simpler.
List_Nonterm_Decl : constant Valid_Node_Access := Tree.Find_Ancestor (B, +nonterminal_ID);
- RHS_List_Root : constant Valid_Node_Access := Tree.Child (List_Nonterm_Decl, 3);
+
+ List_Nonterm_RHS_List_Index : constant SAL.Peek_Type :=
+ (if Tree.ID (Tree.Child (List_Nonterm_Decl, 2)) = +attribute_list_ID then 4 else 3);
+
+ RHS_List_Root : constant Valid_Node_Access := Tree.Child
+ (List_Nonterm_Decl, List_Nonterm_RHS_List_Index);
RHS_List : List := Create_List
(Tree, RHS_List_Root, +rhs_list_ID, +rhs_ID, Separator_ID => +BAR_ID);
RHS : constant Valid_Node_Access := Tree.Find_Ancestor
(B, (+rhs_ID, +rhs_alternative_list_ID));
- -- If rhs_ID, the RHS containing the canonical list candidate.
- -- If rhs_alternative_list_ID, an unnamed canonical list candidate
+ -- If rhs_ID, the RHS containing the named canonical list candidate (= RHS_0) (ie a { b } c).
+ -- If rhs_alternative_list_ID, an unnamed canonical list candidate (ie (a b* c) ).
RHS_Item_List_Root : constant Valid_Node_Access := List_Root
(Tree, Tree.Find_Ancestor (B, +rhs_item_list_ID), +rhs_item_list_ID);
@@ -2037,18 +2612,17 @@ package body WisiToken_Grammar_Editing is
Element_2 : constant Cursor := RHS_Item_List_List.To_Cursor (Tree.Parent (B, 2));
-- The rhs_element containing the rhs_multiple_item
- Element_1 : constant Node_Access :=
- (if Tree.RHS_Index (B) in 4 .. 5
- then Invalid_Node_Access
- else Element (RHS_Item_List_Iter.Previous (Element_2)));
- -- The rhs_element containing the first list element
+ Element_1 : constant Node_Access := Element (RHS_Item_List_Iter.Previous (Element_2));
+ -- If there is a separator, the rhs_element containing the first list
+ -- (after 'a'); invalid if a is not present and there is no separator.
- Can_Be_Empty : constant Boolean := Element_1 = Invalid_Node_Access and Tree.RHS_Index (B) in 0 | 3 | 5;
+ Can_Be_Empty : constant Boolean := Element_1 = Invalid_Node_Access and
+ To_Token_Enum (Tree.ID (Tree.Child (B, Tree.Child_Count (B)))) in RIGHT_BRACE_ID | STAR_ID;
procedure Do_Simple_Named (List_Elements : in Valid_Node_Access)
with Pre => To_Token_Enum (Tree.ID (List_Elements)) in rhs_element_ID | rhs_item_list_ID | IDENTIFIER_ID
is
- pragma Assert (Tree.ID (RHS) = +rhs_ID);
+ pragma Assert (Tree.ID (RHS) = +rhs_ID and RHS = RHS_0);
-- The existing nonterminal declaration is one of:
--
@@ -2123,18 +2697,21 @@ package body WisiToken_Grammar_Editing is
when rhs_element_ID => To_RHS_Item_List (Tree, List_Elements),
when rhs_item_list_ID => Creators.Create_List
(Tree, List_Elements, +rhs_item_list_ID, +rhs_element_ID, Invalid_Token_ID),
- when IDENTIFIER_ID => Empty_List (Tree, +rhs_item_list_ID, 1, +rhs_element_ID, Invalid_Token_ID),
+ when IDENTIFIER_ID => Empty_RHS_Item_List (Tree),
when others => raise SAL.Programmer_Error);
RHS_Item_List_2 : List :=
(if B_Alt_List_Item_List.Is_Invalid
- then Empty_List (Tree, +rhs_item_list_ID, 1, +rhs_element_ID, Invalid_Token_ID)
+ then Empty_RHS_Item_List (Tree)
else B_Alt_List_Item_List);
New_RHS_List : List := Empty_RHS_List (Tree);
+ -- The edited RHS list. The original RHS list is removed from the tree.
- Post_Parse_Action : constant Node_Access := Tree.Child (RHS, 2); -- deleted by first Add_RHS
- In_Parse_Action : constant Node_Access := Tree.Child (RHS, 3);
+ Post_Parse_Action : constant Node_Access := Tree.Child
+ (RHS, (if RHS_0_Attr_List = Invalid_Node_Access then 2 else 3)); -- deleted by first Add_RHS
+ In_Parse_Action : constant Node_Access := Tree.Child
+ (RHS, (if RHS_0_Attr_List = Invalid_Node_Access then 3 else 4));
Auto_Token_Labels : constant Boolean := Get_RHS_Auto_Token_Labels (RHS);
Label : constant Identifier_Token :=
@@ -2157,46 +2734,66 @@ package body WisiToken_Grammar_Editing is
if Tree.ID (List_Elements) = +IDENTIFIER_ID then
RHS_Item_List_1.Append
(Add_RHS_Element
- (Tree, Add_RHS_Item (Tree, Tree.Copy_Subtree (List_Elements, Data_Access)), Label));
-
- RHS_Item_List_2.Append (Add_RHS_Element (Tree, Add_RHS_Item (Tree, List_Elements)));
+ (Tree,
+ Add_RHS_Item (Tree, Tree.Copy_Subtree (List_Elements, Data_Access)),
+ Label,
+ Augmented =>
+ (if Tree.Augmented (Element (Element_2)) = null
+ then null
+ else Copy_Augmented (Data, Tree.Augmented (Element (Element_2))))));
+
+ RHS_Item_List_2.Append
+ (Add_RHS_Element
+ (Tree,
+ Add_RHS_Item (Tree, List_Elements),
+ Label,
+ Augmented =>
+ (if Tree.Augmented (Element (Element_2)) = null
+ then null
+ else Copy_Augmented (Data, Tree.Augmented (Element (Element_2))))));
end if;
New_RHS_List.Append
(Add_RHS
- (Tree, RHS_Item_List_1.Root,
+ (Tree,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List_1.Root,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B),
- Edited_Token_List => True,
- Post_Parse_Action => Post_Parse_Action,
- In_Parse_Action => In_Parse_Action));
+ Post_Parse_Action => Tree.Copy_Subtree (Post_Parse_Action, Data_Access),
+ In_Parse_Action => Tree.Copy_Subtree (In_Parse_Action, Data_Access)));
RHS_Item_List_2.Prepend
- (Add_RHS_Element (Tree, Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)), Label));
+ (Add_RHS_Element
+ (Tree,
+ Add_RHS_Item (Tree, Add_Identifier_Token (Tree, List_Name)),
+ Label => Invalid_Identifier_Token,
+ Augmented => new WisiToken_Grammar_Runtime.Augmented'(Orig_Token_Index => 0, others => <>)));
New_RHS_List.Append
(Add_RHS
(Tree,
- RHS_Item_List_2.Root,
+ Attr_List => Invalid_Node_Access,
+ Item_List => RHS_Item_List_2.Root,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B),
- Edited_Token_List => True,
Post_Parse_Action => Tree.Copy_Subtree (Post_Parse_Action, Data_Access),
In_Parse_Action => Tree.Copy_Subtree (In_Parse_Action, Data_Access)));
Maybe_Optimized_List
(New_RHS_List, List_Name, Separator_Token,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B),
- Label => Label);
+ Label => Invalid_Identifier_Token);
if Can_Be_Empty then
Add_Compilation_Unit
("canonical list",
Tree_Add_Nonterminal
- (Child_1 => Add_Identifier_Token (Tree, List_Name),
- Child_2 => Tree.Add_Terminal (+COLON_ID),
- Child_3 => New_RHS_List.Root,
- Child_4 => Tree.Add_Nonterm
+ (Identifier => Add_Identifier_Token (Tree, List_Name),
+ Attr_List => B_Attr_List,
+ Colon => Tree.Add_Terminal (+COLON_ID),
+ RHS_List => New_RHS_List.Root,
+ Semicolon => Tree.Add_Nonterm
((+semicolon_opt_ID, 0),
- (1 => Tree.Add_Terminal (+SEMICOLON_ID)),
+ (1 => Tree.Add_Terminal (+SEMICOLON_ID)),
Clear_Parents => False)));
Tree.Replace_Child
@@ -2208,7 +2805,7 @@ package body WisiToken_Grammar_Editing is
(Tree, Add_Identifier_Token (Tree, List_Name)),
Label),
Old_Child => Element (Element_2),
- Old_Child_New_Parent => Invalid_Node_Access);
+ Old_Child_New_Parent => Invalid_Node_Access);
-- This goes on RHS_List, _not_ New_RHS_List.
RHS_List.Append (Empty_RHS (Tree));
@@ -2216,7 +2813,7 @@ package body WisiToken_Grammar_Editing is
else
Tree.Replace_Child
(Parent => List_Nonterm_Decl,
- Child_Index => 3,
+ Child_Index => List_Nonterm_RHS_List_Index,
Old_Child => RHS_List_Root,
New_Child => New_RHS_List.Root,
Old_Child_New_Parent => Invalid_Node_Access);
@@ -2227,7 +2824,7 @@ package body WisiToken_Grammar_Editing is
if Trace_Generate_EBNF > Extra then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("Simple_Named Canonical_List edited nonterm:");
- Tree.Print_Tree (List_Nonterm_Decl);
+ Tree.Print_Tree (List_Nonterm_Decl, Augmented => True);
end if;
end Do_Simple_Named;
@@ -2244,10 +2841,8 @@ package body WisiToken_Grammar_Editing is
if Element_1 = Invalid_Node_Access then
Has_Separator := False;
else
- if Tree.RHS_Index (B) in 4 .. 5 then
- Has_Separator := False;
-
- elsif B_Alt_List_Item_List.Count in 1 .. 2 and then
+ if not B_Alt_List_List.Is_Invalid and then
+ B_Alt_List_Item_List.Count in 1 .. 2 and then
Get_Item_Text (Data, Tree, Element_1) =
Get_Item_Text (Data, Tree, Element (B_Alt_List_Item_List.Last))
then
@@ -2276,7 +2871,7 @@ package body WisiToken_Grammar_Editing is
return;
end if;
- if (RHS_List.Count = 1 and Tree.ID (RHS) = +rhs_ID and Tree.RHS_Index (RHS) = 1) and then
+ if (RHS_List.Count = 1 and Tree.ID (RHS) = +rhs_ID) and then
((RHS_Item_List_List.Count = 1 and
(B_Alt_List_List.Is_Invalid or else B_Alt_List_Item_List.Count = 1)) or
(RHS_Item_List_List.Count = 2 and Element_2 = RHS_Item_List_List.Last))
@@ -2284,7 +2879,9 @@ package body WisiToken_Grammar_Editing is
Simple_Named := True;
end if;
- if Tree.RHS_Index (B) in 4 .. 5 and not Simple_Named then
+ if not (To_Token_Enum (Tree.ID (Tree.Child (B, 1))) in LEFT_BRACE_ID | LEFT_PAREN_ID) and
+ not Simple_Named
+ then
-- Handled below
return;
end if;
@@ -2322,23 +2919,14 @@ package body WisiToken_Grammar_Editing is
end if;
declare
- pragma Assert
- (Element_1 = Invalid_Node_Access or else Tree.ID
- (case Tree.RHS_Index (Element_1) is
- when 0 => Tree.Child (Tree.Child (Element_1, 1), 1),
- when 1 => Tree.Child (Tree.Child (Element_1, 3), 1),
- when others => raise SAL.Programmer_Error)
- = +IDENTIFIER_ID);
- -- So we can use it as a nonterm name. If the source text has a
- -- terminal literal (see java_ebnf.wy arrayCreatorRest), it should
- -- have been translated to a token name by now.
-
List_Nonterm_String : constant String :=
- (if Has_Separator
+ (if B_Alt_List_Item_List.Is_Invalid
+ then Get_Text (Data, Tree, Tree.Child (B, 1))
+ elsif Has_Separator
then Get_Item_Text (Data, Tree, Element_1) & "_" & Get_Item_Text (Data, Tree, Separator_Node)
elsif Element_1 /= Invalid_Node_Access
then Get_Item_Text (Data, Tree, Element_1) & "_" &
- Get_Item_Text (Data, Tree, Element (B_Alt_List_Item_List.First))
+ Get_Item_Text (Data, Tree, Element (B_Alt_List_Item_List.First))
else Get_Item_Text (Data, Tree, Element (B_Alt_List_Item_List.First)) &
(if B_Alt_List_Item_List.Count = 1
then ""
@@ -2351,7 +2939,9 @@ package body WisiToken_Grammar_Editing is
Element =>
(if Element_1 /= Invalid_Node_Access
then Tree.Find_Descendant (Element_1, +rhs_item_ID)
- else B_Alt_List_Item_List.Root),
+ elsif not B_Alt_List_Item_List.Is_Invalid
+ then B_Alt_List_Item_List.Root
+ else Tree.Child (B, 1)),
Separator => Separator_Node,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B));
@@ -2398,6 +2988,12 @@ package body WisiToken_Grammar_Editing is
end Find_List_Nonterminal_2;
begin
+ if RHS_0_Attr_List /= Invalid_Node_Access then
+ if Get_Associativity (Data, Tree, RHS_0_Attr_List) = WisiToken.Right then
+ raise SAL.Not_Implemented with "right assoc not implemented for rhs_multiple_item";
+ end if;
+ end if;
+
-- Check if this is a recognized pattern
Check_Canonical_List;
if Done then
@@ -2469,10 +3065,15 @@ package body WisiToken_Grammar_Editing is
then New_Identifier (List_Nonterm_Name_String)
else Next_Nonterm_Name ("list")));
- New_Nonterminal ("canonical list element", List_Element_Name, Tree.Child (B, 2));
+ New_Nonterminal
+ (Label => "canonical list element",
+ New_Identifier => List_Element_Name,
+ Content => Tree.Child (B, 2));
+
New_Nonterminal_List
(List_Nonterm_Name,
- To_Identifier_Token (List_Element_Name),
+ Attr_List => RHS_0_Attr_List,
+ List_Element => To_Identifier_Token (List_Element_Name),
Separator => Invalid_Identifier_Token,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B));
end;
@@ -2518,13 +3119,14 @@ package body WisiToken_Grammar_Editing is
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("Translate_RHS_Multiple_Item edited: " & Get_Text (Data, Tree, Item));
if Trace_Generate_EBNF > Extra then
- Tree.Print_Tree (Item);
+ Tree.Print_Tree (Item, Augmented => True);
end if;
end;
end if;
end Translate_RHS_Multiple_Item;
procedure Translate_RHS_Optional_Item (B : in Valid_Node_Access)
+ with Pre => Tree.ID (B) = +rhs_optional_item_ID
is
-- Source looks like:
--
@@ -2587,7 +3189,7 @@ package body WisiToken_Grammar_Editing is
else Create_List
(Tree,
Root => Container_List_Root,
- List_ID => +rhs_alternative_list_ID,
+ List_ID => +rhs_alternative_list_1_ID,
Element_ID => +rhs_item_list_ID,
Separator_ID => +BAR_ID));
@@ -2608,9 +3210,10 @@ package body WisiToken_Grammar_Editing is
ABC_A_Last : constant Cursor := ABC_Iter.Previous (ABC_B_Cur);
ABC_C_First : constant Cursor := ABC_Iter.Next (ABC_B_Cur);
+ B_Alt_List : constant Valid_Node_Access := Tree.Child (B, 2);
B_Alternative_List : constant Constant_List := Create_List
- (Tree, Tree.Child (B, 2), +rhs_alternative_list_ID, +rhs_item_list_ID);
-
+ (Tree, Tree.Child (B_Alt_List, Tree.Child_Count (B_Alt_List)),
+ +rhs_alternative_list_1_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.
@@ -2621,6 +3224,55 @@ package body WisiToken_Grammar_Editing is
(Tree, Alt, +rhs_item_list_ID, +rhs_element_ID);
New_ABC : List := Empty_List (ABC_List);
+
+ function Is_Orig_EBNF_RHS return Boolean
+ is begin
+ -- Consider subprograms.wy iteration_scheme, which has a nested
+ -- rhs_optional_item. Translating the nested optional gives an
+ -- rhs_alternative_list with two elements, which are copied to two
+ -- RHSs when translating the outer optional item; the first has all
+ -- the tokens (and thus Orig_EBNF_RHS is True), the second is missing
+ -- some (and thus Orig_EBNF_RHS is False).
+ if Alt /= Element (First (B_Alternative_List)) then
+ return False;
+ end if;
+
+ if Container_List.Element_ID = +rhs_ID then
+ -- If B originally contained literal alternatives (ie uses '|'), then
+ -- mapping the token indices to an action is not possible. But if B
+ -- contained nested optional items, leading to multiple alternatives
+ -- that are simple edits of the original, then mapping is possible.
+ -- That's too complex to check for here, and nested optional is
+ -- common in Ada, so we don't try to check; we assume testing will
+ -- identify cases where mapping doesn't work. See subprograms.wy
+ -- iteration_Scheme.
+ declare
+ RHS_Node : constant Valid_Node_Access := Element (Container_Cur);
+ begin
+ if Tree.Augmented (RHS_Node) = null then
+ -- This is an edited RHS with some optional left out.
+ return False;
+ else
+ return WisiToken_Grammar_Runtime.Augmented
+ (Tree.Augmented (RHS_Node).all).Orig_EBNF_RHS;
+ end if;
+ end;
+ else
+ -- B is nested in an alternatives list, so
+ -- mapping the token indices to an action is not possible.
+ declare
+ RHS : constant Valid_Node_Access := Element (Container_Cur);
+ begin
+ if Tree.ID (Tree.Child (RHS, Tree.Child_Count (RHS))) = +ACTION_ID then
+ WisiToken.Generate.Put_Error
+ (Tree.Error_Message
+ (RHS, "complex optional item with action; can't map token indices to action"));
+ end if;
+ end;
+ return False;
+ end if;
+ end Is_Orig_EBNF_RHS;
+
begin
if Has_Element (ABC_A_Last) then
Copy (Source_List => ABC_List,
@@ -2640,6 +3292,7 @@ package body WisiToken_Grammar_Editing is
(Container_List,
New_ABC.Root,
After => Element (Container_Cur),
+ Orig_EBNF_RHS => Is_Orig_EBNF_RHS,
Auto_Token_Labels => Get_RHS_Auto_Token_Labels (B));
else
Container_List.Insert (New_ABC.Root, After => Container_Cur);
@@ -2676,7 +3329,7 @@ package body WisiToken_Grammar_Editing is
end;
when 3 =>
- -- | STRING_LITERAL_2 QUESTION
+ -- | STRING_LITERAL_SINGLE QUESTION
declare
Parent_Var : Node_Access := Tree.Parent (B);
begin
@@ -2692,7 +3345,7 @@ package body WisiToken_Grammar_Editing is
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 (Container_List_Root);
+ Tree.Print_Tree (Container_List_Root, Augmented => True);
end if;
end Translate_RHS_Optional_Item;
@@ -2735,7 +3388,7 @@ package body WisiToken_Grammar_Editing is
return False;
elsif To_Token_Enum (Tree.ID (Value_Node)) in
- IDENTIFIER_ID | REGEXP_ID | STRING_LITERAL_1_ID | STRING_LITERAL_2_ID and then
+ IDENTIFIER_ID | REGEXP_ID | STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID and then
Target = Get_Text (Data, Tree, Value_Node, Strip_Quotes => True)
then
case Tree.Label (Name_Node) is
@@ -2807,7 +3460,7 @@ package body WisiToken_Grammar_Editing is
declare
Keyword : constant Valid_Node_Access := Tree.Add_Identifier (+KEYWORD_ID, Keyword_Ident);
Value_Literal : constant Valid_Node_Access := Tree.Add_Identifier
- (+STRING_LITERAL_1_ID, New_Identifier ('"' & Value & '"'));
+ (+STRING_LITERAL_DOUBLE_ID, New_Identifier ('"' & Value & '"'));
Regexp_String : constant Valid_Node_Access := Tree.Add_Nonterm
((+regexp_string_ID, 1),
(1 => Value_Literal),
@@ -2846,18 +3499,6 @@ package body WisiToken_Grammar_Editing is
-- All handled by New_Nonterminal*
raise SAL.Programmer_Error;
- when rhs_attribute_ID =>
- -- Just delete it
- declare
- use 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);
@@ -2867,7 +3508,7 @@ package body WisiToken_Grammar_Editing is
when rhs_optional_item_ID =>
Translate_RHS_Optional_Item (Node);
- when STRING_LITERAL_2_ID =>
+ when STRING_LITERAL_SINGLE_ID =>
Translate_Token_Literal (Node);
when others =>
@@ -2889,6 +3530,51 @@ package body WisiToken_Grammar_Editing is
end if;
end Process_Node;
+ procedure Set_EBNF_RHS_Index (Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ is
+ use LR_Utils;
+
+ RHS_List : constant Constant_List := Creators.Create_List
+ (Tree,
+ Tree.Child (Nonterm, (if Tree.ID (Tree.Child (Nonterm, 3)) = +rhs_list_ID then 3 else 4)),
+ +rhs_list_ID, +rhs_ID);
+
+ RHS_Index : Natural := 0;
+ EBNF_RHS_Index : Natural := 0;
+ begin
+ for RHS of RHS_List loop
+ if Tree.Augmented (RHS) = null then
+ -- This is an unedited RHS, with no EBNF or auto token labels.
+ declare
+ Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'
+ (EBNF => False,
+ Auto_Token_Labels => False,
+ Orig_EBNF_RHS => True,
+ EBNF_RHS_Index => RHS_Index,
+ Orig_Token_Index => <>);
+ begin
+ Tree.Set_Augmented (RHS, WisiToken.Syntax_Trees.Augmented_Class_Access (Aug));
+ EBNF_RHS_Index := RHS_Index;
+ end;
+
+ else
+ -- Either the first RHS, or an edited RHS.
+ declare
+ Aug : WisiToken_Grammar_Runtime.Augmented renames WisiToken_Grammar_Runtime.Augmented
+ (Tree.Augmented (RHS).all);
+ begin
+ if Aug.Orig_EBNF_RHS then
+ EBNF_RHS_Index := RHS_Index;
+ end if;
+
+ Aug.EBNF_RHS_Index := EBNF_RHS_Index;
+ end;
+ end if;
+
+ RHS_Index := @ + 1;
+ end loop;
+ end Set_EBNF_RHS_Index;
+
procedure Check_Original_Copied_EBNF
is
use Ada.Text_IO;
@@ -2912,7 +3598,7 @@ package body WisiToken_Grammar_Editing is
Put_Line (Current_Error, Tree.Error_Message (N, Tree.Image (N, Node_Numbers => True)));
Put_Line
(Current_Error,
- "... Copied_EBNF not in tree; in root" & Trimmed_Image (Get_Node_Index (Subtree_Root)));
+ "... Copied_EBNF not in tree; in root " & Trimmed_Image (Get_Node_Index (Subtree_Root)));
WisiToken.Generate.Error := True;
Error_Present := True;
end if;
@@ -2920,15 +3606,20 @@ package body WisiToken_Grammar_Editing is
if Error_Present then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("tree:");
- Tree.Print_Tree;
+ Tree.Print_Tree (Augmented => True);
end if;
end Check_Original_Copied_EBNF;
begin
EBNF_Allowed := True;
+ if Trace_Generate_EBNF > Detail then
+ Ada.Text_IO.Put_Line ("EBNF tree:");
+ Tree.Print_Tree (Augmented => True);
+ end if;
+
if Debug_Mode then
Tree.Validate_Tree
- (Data, Data.Error_Reported,
+ (Data'Unchecked_Access, Data.Error_Reported,
Root => Tree.Root,
Validate_Node => Validate_Node'Access,
Node_Index_Order => True,
@@ -2937,7 +3628,7 @@ package body WisiToken_Grammar_Editing is
if Data.Error_Reported.Count > 0 then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("initial invalid tree:");
- Tree.Print_Tree (Line_Numbers => True, Non_Grammar => True);
+ Tree.Print_Tree (Line_Numbers => True, Non_Grammar => True, Augmented => True, Safe_Only => True);
end if;
end if;
@@ -2955,6 +3646,10 @@ package body WisiToken_Grammar_Editing is
Tree.Process_Tree (Process_Node'Access);
end;
+ if Trace_Generate_EBNF > Outline then
+ Ada.Text_IO.Put_Line ("EBNF node count:" & EBNF_Nodes.Count'Image);
+ end if;
+
-- Apply labels if needed, so they are consistent in copied RHS
declare
use LR_Utils;
@@ -2971,7 +3666,9 @@ package body WisiToken_Grammar_Editing is
if Tree.ID (Nonterm) = +nonterminal_ID then
declare
RHS_List : constant Constant_List := Creators.Create_List
- (Tree, Tree.Child (Nonterm, 3), +rhs_list_ID, +rhs_ID);
+ (Tree,
+ Tree.Child (Nonterm, (if Tree.ID (Tree.Child (Nonterm, 3)) = +rhs_list_ID then 3 else 4)),
+ +rhs_list_ID, +rhs_ID);
begin
for RHS of RHS_List loop
Last_Token_Index := 0;
@@ -2991,7 +3688,7 @@ package body WisiToken_Grammar_Editing is
-- no longer valid. We've reused name tokens, so byte_region_order is
-- not valid.
Tree.Validate_Tree
- (Data, Data.Error_Reported,
+ (Data'Unchecked_Access, Data.Error_Reported,
Root => Tree.Root,
Validate_Node => Validate_Node'Access,
Node_Index_Order => False,
@@ -2999,7 +3696,7 @@ package body WisiToken_Grammar_Editing is
if Data.Error_Reported.Count /= 0 then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("invalid tree after Add_Token_Labels:");
- Tree.Print_Tree;
+ Tree.Print_Tree (Augmented => True, Safe_Only => True);
end if;
end if;
@@ -3037,15 +3734,15 @@ package body WisiToken_Grammar_Editing is
if Debug_Mode then
Tree.Validate_Tree
- (Data, Data.Error_Reported,
+ (Data'Unchecked_Access, Data.Error_Reported,
Root => Tree.Root,
Validate_Node => Validate_Node'Access,
Node_Index_Order => False,
Byte_Region_Order => False);
if Data.Error_Reported.Count /= 0 then
Ada.Text_IO.New_Line;
- Ada.Text_IO.Put_Line ("invalid tree after translate one node:");
- Tree.Print_Tree;
+ Ada.Text_IO.Put_Line ("invalid tree:");
+ Tree.Print_Tree (Augmented => True, Safe_Only => True);
end if;
Check_Original_Copied_EBNF;
end if;
@@ -3099,7 +3796,7 @@ package body WisiToken_Grammar_Editing is
if Debug_Mode then
Tree.Validate_Tree
- (Data, Data.Error_Reported,
+ (Data'Unchecked_Access, Data.Error_Reported,
Root => Tree.Root,
Validate_Node => Validate_Node'Access,
Node_Index_Order => False,
@@ -3107,7 +3804,7 @@ package body WisiToken_Grammar_Editing is
if Data.Error_Reported.Count /= 0 then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("invalid tree after translate copied node:");
- Tree.Print_Tree;
+ Tree.Print_Tree (Augmented => True, Safe_Only => True);
end if;
Check_Original_Copied_EBNF;
end if;
@@ -3117,6 +3814,19 @@ package body WisiToken_Grammar_Editing is
end loop;
declare
+ use LR_Utils;
+ use LR_Utils.Creators;
+ List : constant Constant_List := Create_List
+ (Tree, Tree.Child (Tree.Root, 2), +compilation_unit_list_ID, +compilation_unit_ID);
+ begin
+ for Unit of List loop
+ if Tree.ID (Tree.Child (Unit, 1)) = +nonterminal_ID then
+ Set_EBNF_RHS_Index (Tree.Child (Unit, 1));
+ end if;
+ end loop;
+ end;
+
+ declare
use Ada.Text_IO;
begin
for Node of Copied_EBNF_Nodes loop
@@ -3136,7 +3846,7 @@ package body WisiToken_Grammar_Editing is
EBNF_Allowed := False;
if Debug_Mode then
Tree.Validate_Tree
- (Data, Data.Error_Reported,
+ (Data'Unchecked_Access, Data.Error_Reported,
Root => Tree.Root,
Validate_Node => Validate_Node'Access,
Node_Index_Order => False,
@@ -3144,7 +3854,7 @@ package body WisiToken_Grammar_Editing is
if Data.Error_Reported.Count /= 0 then
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("invalid tree after Data.EBNF_Allowed False:");
- Tree.Print_Tree;
+ Tree.Print_Tree (Augmented => True, Safe_Only => True);
end if;
end if;
Data.Meta_Syntax := BNF_Syntax;
@@ -3159,9 +3869,9 @@ package body WisiToken_Grammar_Editing is
end Translate_EBNF_To_BNF;
procedure Print_Source
- (File_Name : in String;
- Tree : in Syntax_Trees.Tree;
- Data : in WisiToken_Grammar_Runtime.User_Data_Type)
+ (File_Name : in String;
+ Tree : in out Syntax_Trees.Tree;
+ Data : in WisiToken_Grammar_Runtime.User_Data_Type)
is
use Ada.Text_IO;
@@ -3217,7 +3927,7 @@ package body WisiToken_Grammar_Editing is
begin
pragma Assert (Children'Length = 1);
case To_Token_Enum (Tree.ID (Children (1))) is
- when STRING_LITERAL_1_ID | STRING_LITERAL_2_ID =>
+ when STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID =>
Put (File, ' ' & Get_Text (Data, Tree, Children (1)));
when REGEXP_ID =>
Put (File, " %[" & Get_Text (Data, Tree, Children (1)) & "]%");
@@ -3266,23 +3976,42 @@ package body WisiToken_Grammar_Editing is
end if;
end Put_Identifier_List;
+ procedure Put_Attr_List (Attr_List : in Valid_Node_Access)
+ is
+ Prec : constant WisiToken.Base_Precedence_ID := WisiToken_Grammar_Runtime.Get_Precedence
+ (Data, Tree, Attr_List);
+ Assoc : constant WisiToken.Associativity := WisiToken_Grammar_Runtime.Get_Associativity
+ (Data, Tree, Attr_List);
+ begin
+ case Assoc is
+ when Left =>
+ Put (File, "<assoc=left>");
+
+ when Right =>
+ Put (File, "<assoc=right>");
+
+ when None =>
+ pragma Assert (Prec /= No_Precedence);
+ null;
+ end case;
+ if Prec /= No_Precedence then
+ Put (File, "<prec=" & (-Data.Precedence_Inverse_Map (Prec)) & ">");
+ end if;
+ end Put_Attr_List;
+
procedure Put_RHS_Element (Node : in Valid_Node_Access)
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 Node_Access_Array := Tree.Children (Node);
begin
- Put
- (File, Get_Text (Data, Tree, Children (1)) & "=" & Get_Text (Data, Tree, Children (3)));
+ -- Output no spaces around "="
+ Put (File, Get_Text (Data, Tree, Children (1)) & "=" & Get_Text (Data, Tree, Children (3)));
end;
when others =>
@@ -3337,30 +4066,33 @@ package body WisiToken_Grammar_Editing is
First : in Boolean)
with Pre => Tree.ID (Node) = +rhs_ID
is
+ use all type SAL.Base_Peek_Type;
Children : constant Node_Access_Array := Tree.Children (Node);
+ Last : SAL.Base_Peek_Type := Children'First - 1;
begin
Put (File, (if First then " : " else " | "));
- case Tree.RHS_Index (Node) is
- when 0 =>
+ if Tree.Child_Count (Node) = 0 then
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);
+ else
+ if Tree.ID (Tree.Child (Node, 1)) = +attribute_list_ID then
+ Put_Attr_List (Tree.Child (Node, 1));
+ Put (File, " ");
+ Last := 1;
+ end if;
- if Tree.RHS_Index (Node) > 1 then
- Put (File, " %(" & Get_Text (Data, Tree, Children (2)) & ")%"); -- action
- Put_Comments (Children (2), Force_New_Line => True);
+ Last := @ + 1;
+ Put_RHS_Item_List (Children (Last));
+ Put_Comments (Children (Last), 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);
+ for I in 1 .. 2 loop
+ Last := @ + 1;
+ if Last <= Tree.Child_Count (Node) then
+ Put (File, " %(" & Get_Text (Data, Tree, Children (Last)) & ")%");
+ Put_Comments (Children (Last), Force_New_Line => True);
end if;
- end if;
-
- when others =>
- WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error ("Put_RHS", Tree, Node);
- end case;
+ end loop;
+ end if;
exception
when SAL.Programmer_Error =>
raise;
@@ -3382,37 +4114,52 @@ package body WisiToken_Grammar_Editing is
is
Children : constant Node_Access_Array := Tree.Children (Node);
begin
- case Tree.RHS_Index (Node) is
- when 0 =>
+ case To_Token_Enum (Tree.ID (Children (1))) is
+ when rhs_ID =>
Put_RHS (Children (1), First);
First := False;
- when 1 =>
+
+ when rhs_list_ID =>
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);
+ case To_Token_Enum (Tree.ID (Children (2))) is
+ when BAR_ID =>
+ Put_RHS (Children (3), First => False);
+
+ when PERCENT_ID =>
+ case To_Token_Enum (Tree.ID (Children (3))) is
+ when IF_ID | ELSIF_ID =>
+ Put
+ (File,
+ (case To_Token_Enum (Tree.ID (Children (3))) is
+ when IF_ID => "%if",
+ when ELSIF_ID => "$elsif",
+ when others => raise SAL.Programmer_Error) &
+ Get_Text (Data, Tree, Children (4)) &
+ (case To_Token_Enum (Tree.ID (Children (5))) is
+ when EQUAL_ID => " = ",
+ when IN_ID => "in",
+ when others => raise SAL.Programmer_Error) &
+ Get_Text (Data, Tree, Children (6)));
+ Put_Comments (Node);
+ when END_ID =>
+ Put (File, "%end if");
+ Put_Comments (Node);
+
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
+ when others =>
+ raise SAL.Programmer_Error;
+ end case;
when others =>
- WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error ("Put_RHS_List", Tree, Node);
+ raise SAL.Programmer_Error;
end case;
+
exception
when SAL.Programmer_Error =>
- raise;
-
- when E : others =>
- declare
- use Ada.Exceptions;
- begin
- WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error
- ("Put_RHS_List: " & Exception_Name (E) & ": " & Exception_Message (E), Tree, Node);
- end;
+ Syntax_Trees.LR_Utils.Raise_Programmer_Error ("put_rhs_list", Tree, Node);
end Put_RHS_List;
procedure Process_Node (Node : in Valid_Node_Access)
@@ -3478,12 +4225,16 @@ package body WisiToken_Grammar_Editing is
then "%conflict "
else "%conflict_resolution "));
Put (File, Get_Text (Data, Tree, Children (3))); -- conflict_item_list
- Put (File, " on token " & Get_Text (Data, Tree, Children (6)));
- if Children'Last = 8 then
- Put (File, " : " & Get_Text (Data, Tree, Children (8)));
- Put_Comments (Children (8), Force_New_Line => True);
- else
- Put_Comments (Children (6), Force_New_Line => True);
+ if Children'Last >= 6 then
+ -- wisi format
+ Put (File, " on token " & Get_Text (Data, Tree, Children (6)));
+ if Children'Last = 8 then
+ Put (File, " : " & Get_Text (Data, Tree, Children (8)));
+ Put_Comments (Children (8), Force_New_Line => True);
+ else
+ Put_Comments (Children (6), Force_New_Line => True);
+ end if;
+ -- else tree_sitter format
end if;
when IDENTIFIER_ID =>
@@ -3514,6 +4265,7 @@ package body WisiToken_Grammar_Editing is
Put_Comments (Node);
when END_ID =>
+ New_Line (File);
Put (File, "%end if");
Put_Comments (Node);
@@ -3531,16 +4283,26 @@ package body WisiToken_Grammar_Editing is
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.ID (Children (2)) = +attribute_list_ID then
+ Put_Attr_List (Children (2));
+ New_Line (File);
+ Put_RHS_List (Children (4), First, Virtual);
+ else
+ Put_RHS_List (Children (3), First, Virtual);
+ end if;
-- We force a terminating ";" here, to speed parsing in _bnf.wy files.
- if Tree.RHS_Index (Children (4)) = 1 then
+ if Tree.RHS_Index (Children (Children'Last)) = 1 then
-- Empty
Put_Line (File, " ;");
else
-- ";" present, including trailing newline, unless virtual.
+
+ -- FIXME: for some reason, this 'put' gets lost if there is a
+ -- comment. sigh. Changing to 'put_line' keeps the semicolon, but is
+ -- annoying.
Put (File, " ;");
- Put_Comments (Children (4), Force_New_Line => True);
+ Put_Comments (Children (Children'Last), Force_New_Line => True);
end if;
end;
@@ -3585,10 +4347,9 @@ package body WisiToken_Grammar_Editing is
Close (File);
exception
- when E : SAL.Not_Implemented =>
+ when others =>
Close (File);
- Ada.Text_IO.Put_Line
- (Ada.Text_IO.Standard_Error, "Print_Source not implemented: " & Ada.Exceptions.Exception_Message (E));
+ raise;
end Print_Source;
end WisiToken_Grammar_Editing;
diff --git a/wisitoken_grammar_editing.ads b/wisitoken_grammar_editing.ads
index 7dea2a8..1328e30 100644
--- a/wisitoken_grammar_editing.ads
+++ b/wisitoken_grammar_editing.ads
@@ -2,7 +2,7 @@
--
-- Utilities for editing wisitoken grammars.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -85,7 +85,8 @@ package WisiToken_Grammar_Editing is
RHS_Index : in Natural;
Content : in WisiToken.Syntax_Trees.Valid_Node_Access)
return WisiToken.Syntax_Trees.Valid_Node_Access
- with Pre => To_Token_Enum (Tree.ID (Content)) in rhs_alternative_list_ID | IDENTIFIER_ID | STRING_LITERAL_2_ID and
+ with Pre => To_Token_Enum (Tree.ID (Content)) in
+ rhs_alternative_list_ID | IDENTIFIER_ID | STRING_LITERAL_SINGLE_ID and
RHS_Index <= 3,
Post => Tree.ID (Add_RHS_Optional_Item'Result) = +rhs_optional_item_ID;
@@ -98,13 +99,14 @@ package WisiToken_Grammar_Editing is
(Tree : in out WisiToken.Syntax_Trees.Tree;
Item : in WisiToken.Syntax_Trees.Valid_Node_Access)
return WisiToken.Syntax_Trees.Valid_Node_Access
- with Pre => To_Token_Enum (Tree.ID (Item)) in IDENTIFIER_ID | STRING_LITERAL_2_ID,
+ with Pre => To_Token_Enum (Tree.ID (Item)) in IDENTIFIER_ID | STRING_LITERAL_SINGLE_ID,
Post => Tree.ID (Add_RHS_Item'Result) = +rhs_item_ID;
function Add_RHS_Element
- (Tree : in out WisiToken.Syntax_Trees.Tree;
- Item : in WisiToken.Syntax_Trees.Valid_Node_Access;
- Label : in Identifier_Token := Invalid_Identifier_Token)
+ (Tree : in out WisiToken.Syntax_Trees.Tree;
+ Item : in WisiToken.Syntax_Trees.Valid_Node_Access;
+ Label : in Identifier_Token := Invalid_Identifier_Token;
+ Augmented : in WisiToken.Syntax_Trees.Augmented_Class_Access := null)
return WisiToken.Syntax_Trees.Valid_Node_Access
with Pre => Tree.ID (Item) = +rhs_item_ID,
Post => Tree.Production_ID (Add_RHS_Element'Result) =
@@ -120,18 +122,22 @@ package WisiToken_Grammar_Editing is
function Add_RHS
(Tree : in out WisiToken.Syntax_Trees.Tree;
- Item : in WisiToken.Syntax_Trees.Valid_Node_Access;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access;
+ Item_List : in WisiToken.Syntax_Trees.Valid_Node_Access;
Auto_Token_Labels : in Boolean;
- Edited_Token_List : in Boolean;
Post_Parse_Action : in WisiToken.Syntax_Trees.Node_Access := WisiToken.Syntax_Trees.Invalid_Node_Access;
In_Parse_Action : in WisiToken.Syntax_Trees.Node_Access := WisiToken.Syntax_Trees.Invalid_Node_Access)
return WisiToken.Syntax_Trees.Valid_Node_Access
- with Pre => Tree.ID (Item) = +rhs_item_list_ID and
+ with Pre => (Attr_List = WisiToken.Syntax_Trees.Invalid_Node_Access or else
+ Tree.ID (Attr_List) = +attribute_list_ID) and
+ Tree.ID (Item_List) = +rhs_item_list_ID and
(Post_Parse_Action = WisiToken.Syntax_Trees.Invalid_Node_Access or else
- Tree.ID (Post_Parse_Action) = +ACTION_ID) and
+ Tree.ID (Post_Parse_Action) = +ACTION_ID) and
(In_Parse_Action = WisiToken.Syntax_Trees.Invalid_Node_Access or else
- Tree.ID (In_Parse_Action) = +ACTION_ID),
+ Tree.ID (In_Parse_Action) = +ACTION_ID),
Post => Tree.ID (Add_RHS'Result) = +rhs_ID;
+ -- If Post_, In_Parse_Action are non-null, they are moved to the new
+ -- RHS, not copied.
function Find_Declaration
(Data : in WisiToken_Grammar_Runtime.User_Data_Type;
@@ -142,14 +148,27 @@ package WisiToken_Grammar_Editing is
To_Token_Enum (Tree.ID (Find_Declaration'Result)) in declaration_ID | nonterminal_ID;
-- Return the node that declares Name, Invalid_Node_Access if none.
+ function Find_Declaration_By_Value
+ (Data : in WisiToken_Grammar_Runtime.User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Value : in String;
+ Strip_Quotes : in Boolean)
+ return WisiToken.Syntax_Trees.Node_Access
+ with Post => Find_Declaration_By_Value'Result = WisiToken.Syntax_Trees.Invalid_Node_Access or else
+ To_Token_Enum (Tree.ID (Find_Declaration_By_Value'Result)) in declaration_ID;
+ -- Return the node that declares a token with value Value,
+ -- Invalid_Node_Access if none.
+
+ EBNF_Allowed : Boolean := True;
+
procedure Validate_Node
(Tree : in WisiToken.Syntax_Trees.Tree;
Node : in WisiToken.Syntax_Trees.Valid_Node_Access;
- User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
+ User_Data : in WisiToken.Syntax_Trees.User_Data_Access;
Node_Error_Reported : in out Boolean);
-- Verify that all nodes match wisitoken_grammar.wy. Data must be of
-- type WisiToken_Grammar_Runtime.User_Data_Type. Uses
- -- Data.EBNF_Allowed.
+ -- EBNF_Allowed.
--
-- For use with Syntax_Trees.Validate_Tree.
@@ -166,9 +185,9 @@ package WisiToken_Grammar_Editing is
-- Generator.LR.*_Generate requires a BNF grammar.
procedure Print_Source
- (File_Name : in String;
- Tree : in WisiToken.Syntax_Trees.Tree;
- Data : in WisiToken_Grammar_Runtime.User_Data_Type);
+ (File_Name : in String;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Data : in WisiToken_Grammar_Runtime.User_Data_Type);
-- Print the wisitoken grammar source represented by Tree, Terminals
-- to a new file File_Name.
diff --git a/wisitoken_grammar_main.adb b/wisitoken_grammar_main.adb
index 4816a20..04ca2f3 100644
--- a/wisitoken_grammar_main.adb
+++ b/wisitoken_grammar_main.adb
@@ -2,7 +2,7 @@
-- command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c wisitoken_grammar.wy
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- Author: Stephen Leake <stephe-leake@stephe-leake.org>
--
@@ -19,7 +19,7 @@
-- 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/>.
+-- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
with SAL;
with WisiToken.Lexer.re2c;
@@ -36,8 +36,8 @@ package body Wisitoken_Grammar_Main is
RAW_CODE_ID |
REGEXP_ID |
ACTION_ID |
- STRING_LITERAL_1_ID |
- STRING_LITERAL_2_ID => return True;
+ STRING_LITERAL_DOUBLE_ID |
+ STRING_LITERAL_SINGLE_ID => return True;
when others => return False;
end case;
end Is_Block_Delimited;
@@ -49,8 +49,8 @@ package body Wisitoken_Grammar_Main is
when RAW_CODE_ID => return False;
when REGEXP_ID => return False;
when ACTION_ID => return False;
- when STRING_LITERAL_1_ID => return True;
- when STRING_LITERAL_2_ID => return True;
+ when STRING_LITERAL_DOUBLE_ID => return True;
+ when STRING_LITERAL_SINGLE_ID => return True;
when others => return False;
end case;
end Same_Block_Delimiters;
@@ -69,8 +69,8 @@ package body Wisitoken_Grammar_Main is
when RAW_CODE_ID => return 2;
when REGEXP_ID => return 2;
when ACTION_ID => return 2;
- when STRING_LITERAL_1_ID => return 1;
- when STRING_LITERAL_2_ID => return 1;
+ when STRING_LITERAL_DOUBLE_ID => return 1;
+ when STRING_LITERAL_SINGLE_ID => return 1;
when others => raise SAL.Programmer_Error; return 0;
end case;
end Start_Delimiter_Length;
@@ -80,8 +80,8 @@ package body Wisitoken_Grammar_Main is
case To_Token_Enum (ID) is
when
COMMENT_ID |
- STRING_LITERAL_1_ID |
- STRING_LITERAL_2_ID => return 1;
+ STRING_LITERAL_DOUBLE_ID |
+ STRING_LITERAL_SINGLE_ID => return 1;
when RAW_CODE_ID => return 2;
when REGEXP_ID => return 2;
when ACTION_ID => return 2;
@@ -97,8 +97,8 @@ package body Wisitoken_Grammar_Main is
when RAW_CODE_ID => False,
when REGEXP_ID => False,
when ACTION_ID => False,
- when STRING_LITERAL_1_ID => True,
- when STRING_LITERAL_2_ID => True,
+ when STRING_LITERAL_DOUBLE_ID => True,
+ when STRING_LITERAL_SINGLE_ID => True,
when others => raise SAL.Programmer_Error);
end New_Line_Is_End_Delimiter;
@@ -114,8 +114,8 @@ package body Wisitoken_Grammar_Main is
when RAW_CODE_ID => WisiToken.Lexer.Find_String (Source, Token_Start, "}%"),
when REGEXP_ID => WisiToken.Lexer.Find_String (Source, Token_Start, "]%"),
when ACTION_ID => WisiToken.Lexer.Find_String (Source, Token_Start, ")%"),
- when STRING_LITERAL_1_ID => WisiToken.Lexer.Find_String_Or_New_Line (Source, Token_Start, """"),
- when STRING_LITERAL_2_ID => WisiToken.Lexer.Find_String_Or_New_Line (Source, Token_Start, """"),
+ when STRING_LITERAL_DOUBLE_ID => WisiToken.Lexer.Find_String_Or_New_Line (Source, Token_Start, """"),
+ when STRING_LITERAL_SINGLE_ID => WisiToken.Lexer.Find_String_Or_New_Line (Source, Token_Start, """"),
when others => raise SAL.Programmer_Error);
end Find_End_Delimiter;
@@ -147,8 +147,8 @@ package body Wisitoken_Grammar_Main is
(if Inserted then Region.Last
elsif Start then Region.Last
else Lexer.Find_String (Source, Region.First, ")%")),
- when STRING_LITERAL_1_ID => Lexer.Find_New_Line (Source, Region.Last),
- when STRING_LITERAL_2_ID => Lexer.Find_New_Line (Source, Region.Last),
+ when STRING_LITERAL_DOUBLE_ID => Lexer.Find_New_Line (Source, Region.Last),
+ when STRING_LITERAL_SINGLE_ID => Lexer.Find_New_Line (Source, Region.Last),
when others => raise SAL.Programmer_Error);
end Find_Scan_End;
@@ -166,8 +166,8 @@ package body Wisitoken_Grammar_Main is
when RAW_CODE_ID => Lexer.Find_String_Or_New_Line (Source, Region, "}%"),
when REGEXP_ID => Lexer.Find_String_Or_New_Line (Source, Region, "]%"),
when ACTION_ID => Lexer.Find_String_Or_New_Line (Source, Region, ")%"),
- when STRING_LITERAL_1_ID => Lexer.Find_String_Or_New_Line (Source, Region, """"),
- when STRING_LITERAL_2_ID => Lexer.Find_String_Or_New_Line (Source, Region, "'"),
+ when STRING_LITERAL_DOUBLE_ID => Lexer.Find_String_Or_New_Line (Source, Region, """"),
+ when STRING_LITERAL_SINGLE_ID => Lexer.Find_String_Or_New_Line (Source, Region, "'"),
when others => raise SAL.Programmer_Error);
end Contains_End_Delimiter;
@@ -206,8 +206,8 @@ package body Wisitoken_Grammar_Main is
case To_Token_Enum (ID) is
when NEW_LINE_ID => return True;
when COMMENT_ID => return True;
- when STRING_LITERAL_1_ID => return True;
- when STRING_LITERAL_2_ID => return True;
+ when STRING_LITERAL_DOUBLE_ID => return True;
+ when STRING_LITERAL_SINGLE_ID => return True;
when others => return False;
end case;
end Terminated_By_New_Line;
@@ -238,11 +238,11 @@ package body Wisitoken_Grammar_Main is
use WisiToken.Parse.LR;
Table : constant Parse_Table_Ptr := new Parse_Table
(State_First => 0,
- State_Last => 145,
+ State_Last => 162,
First_Terminal => 3,
Last_Terminal => 42,
First_Nonterminal => 43,
- Last_Nonterminal => 66);
+ Last_Nonterminal => 68);
begin
declare
procedure Subr_1
@@ -253,28 +253,32 @@ package body Wisitoken_Grammar_Main is
Table.States (0).Goto_List.Set_Capacity (4);
Add_Goto (Table.States (0), 48, 3);
Add_Goto (Table.States (0), 53, 4);
- Add_Goto (Table.States (0), 65, 5);
- Add_Goto (Table.States (0), 66, 6);
+ Add_Goto (Table.States (0), 67, 5);
+ Add_Goto (Table.States (0), 68, 6);
Table.States (1).Action_List.Set_Capacity (10);
Add_Action (Table.States (1), 4, (48, 6), 7);
Add_Action (Table.States (1), 5, (48, 7), 8);
- Add_Action (Table.States (1), 6, (48, 8), 9);
- Add_Action (Table.States (1), 7, (48, 15), 10);
- Add_Action (Table.States (1), 8, (48, 13), 11);
- Add_Action (Table.States (1), 9, (48, 11), 12);
+ Add_Action (Table.States (1), 6, (48, 9), 9);
+ Add_Action (Table.States (1), 7, (48, 16), 10);
+ Add_Action (Table.States (1), 8, (48, 14), 11);
+ Add_Action (Table.States (1), 9, (48, 12), 12);
Add_Action (Table.States (1), 11, (48, 5), 13);
Add_Action (Table.States (1), 12, (48, 2), 14);
Add_Action (Table.States (1), 16, (48, 0), 15);
- Add_Action (Table.States (1), 39, (48, 9), 16);
- Table.States (2).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (1), 39, (48, 10), 16);
+ Table.States (2).Action_List.Set_Capacity (3);
Add_Action (Table.States (2), 21, (53, 0), 17);
- Add_Action (Table.States (2), 22, (53, 1), 18);
+ Add_Action (Table.States (2), 22, (53, 3), 18);
+ Add_Action (Table.States (2), 28, (57, 0), 19);
+ Table.States (2).Goto_List.Set_Capacity (2);
+ Add_Goto (Table.States (2), 57, 20);
+ Add_Goto (Table.States (2), 58, 21);
Table.States (3).Action_List.Set_Capacity (3);
- Add_Action (Table.States (3), (30, 39, 42), (65, 0), 1);
+ Add_Action (Table.States (3), (30, 39, 42), (67, 0), 1);
Table.States (4).Action_List.Set_Capacity (3);
- Add_Action (Table.States (4), (30, 39, 42), (65, 1), 1);
+ Add_Action (Table.States (4), (30, 39, 42), (67, 1), 1);
Table.States (5).Action_List.Set_Capacity (3);
- Add_Action (Table.States (5), (30, 39, 42), (66, 0), 1);
+ Add_Action (Table.States (5), (30, 39, 42), (68, 1), 1);
Table.States (6).Action_List.Set_Capacity (3);
Add_Action (Table.States (6), 30, (48, 0), 1);
Add_Action (Table.States (6), 39, (53, 0), 2);
@@ -282,673 +286,820 @@ package body Wisitoken_Grammar_Main is
Table.States (6).Goto_List.Set_Capacity (3);
Add_Goto (Table.States (6), 48, 3);
Add_Goto (Table.States (6), 53, 4);
- Add_Goto (Table.States (6), 65, 19);
+ Add_Goto (Table.States (6), 67, 22);
Table.States (7).Action_List.Set_Capacity (1);
- Add_Action (Table.States (7), 39, (49, 0), 20);
+ Add_Action (Table.States (7), 39, (49, 0), 23);
Table.States (7).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (7), 49, 21);
+ Add_Goto (Table.States (7), 49, 24);
Table.States (8).Action_List.Set_Capacity (4);
- Add_Action (Table.States (8), 3, (45, 2), 22);
- Add_Action (Table.States (8), 14, (45, 1), 23);
- Add_Action (Table.States (8), 15, (45, 0), 24);
- Add_Action (Table.States (8), 39, (45, 3), 25);
- Table.States (8).Goto_List.Set_Capacity (2);
- Add_Goto (Table.States (8), 45, 26);
- Add_Goto (Table.States (8), 46, 27);
+ Add_Action (Table.States (8), 3, (45, 2), 25);
+ Add_Action (Table.States (8), 14, (45, 1), 26);
+ Add_Action (Table.States (8), 15, (45, 0), 27);
+ Add_Action (Table.States (8), 39, (45, 3), 28);
+ Table.States (8).Goto_List.Set_Capacity (3);
+ Add_Goto (Table.States (8), 45, 29);
+ Add_Goto (Table.States (8), 46, 30);
+ Add_Goto (Table.States (8), 49, 31);
Table.States (9).Action_List.Set_Capacity (4);
- Add_Action (Table.States (9), 3, (45, 2), 22);
- Add_Action (Table.States (9), 14, (45, 1), 23);
- Add_Action (Table.States (9), 15, (45, 0), 24);
- Add_Action (Table.States (9), 39, (45, 3), 25);
+ Add_Action (Table.States (9), 3, (45, 2), 25);
+ Add_Action (Table.States (9), 14, (45, 1), 26);
+ Add_Action (Table.States (9), 15, (45, 0), 27);
+ Add_Action (Table.States (9), 39, (45, 3), 32);
Table.States (9).Goto_List.Set_Capacity (2);
- Add_Goto (Table.States (9), 45, 26);
- Add_Goto (Table.States (9), 46, 28);
+ Add_Goto (Table.States (9), 45, 29);
+ Add_Goto (Table.States (9), 46, 33);
Table.States (10).Action_List.Set_Capacity (1);
- Add_Action (Table.States (10), 9, (48, 15), 29);
+ Add_Action (Table.States (10), 9, (48, 16), 34);
Table.States (11).Action_List.Set_Capacity (1);
- Add_Action (Table.States (11), 39, (48, 13), 30);
+ Add_Action (Table.States (11), 39, (48, 14), 35);
Table.States (12).Action_List.Set_Capacity (1);
- Add_Action (Table.States (12), 39, (48, 11), 31);
+ Add_Action (Table.States (12), 39, (48, 12), 36);
Table.States (13).Action_List.Set_Capacity (1);
- Add_Action (Table.States (13), 39, (48, 5), 32);
+ Add_Action (Table.States (13), 39, (48, 5), 37);
Table.States (14).Action_List.Set_Capacity (1);
- Add_Action (Table.States (14), 28, (48, 2), 33);
+ Add_Action (Table.States (14), 28, (48, 2), 38);
Table.States (15).Action_List.Set_Capacity (1);
- Add_Action (Table.States (15), 28, (48, 0), 34);
+ Add_Action (Table.States (15), 28, (48, 0), 39);
Table.States (16).Action_List.Set_Capacity (7);
- Add_Action (Table.States (16), 18, (44, 0), 35);
- Add_Action (Table.States (16), 30, Reduce, (48, 10), 2);
- Add_Action (Table.States (16), 38, (51, 1), 36);
- Add_Action (Table.States (16), 39, (51, 0), 37);
- Add_Conflict (Table.States (16), 39, (48, 10), 2);
- Add_Action (Table.States (16), 40, (44, 1), 38);
- Add_Action (Table.States (16), 41, (44, 2), 39);
- Add_Action (Table.States (16), 42, Reduce, (48, 10), 2);
+ Add_Action (Table.States (16), 18, (44, 0), 40);
+ Add_Action (Table.States (16), 30, Reduce, (48, 11), 2);
+ Add_Action (Table.States (16), 38, (51, 1), 41);
+ Add_Action (Table.States (16), 39, (51, 0), 42);
+ Add_Conflict (Table.States (16), 39, (48, 11), 2);
+ Add_Action (Table.States (16), 40, (44, 1), 43);
+ Add_Action (Table.States (16), 41, (44, 2), 44);
+ Add_Action (Table.States (16), 42, Reduce, (48, 11), 2);
Table.States (16).Goto_List.Set_Capacity (3);
- Add_Goto (Table.States (16), 44, 40);
- Add_Goto (Table.States (16), 51, 41);
- Add_Goto (Table.States (16), 52, 42);
+ Add_Goto (Table.States (16), 44, 45);
+ Add_Goto (Table.States (16), 51, 46);
+ Add_Goto (Table.States (16), 52, 47);
Table.States (17).Action_List.Set_Capacity (10);
Add_Action (Table.States (17), 20, Reduce, (56, 0), 0);
- Add_Action (Table.States (17), 25, (63, 0), 43);
- Add_Action (Table.States (17), 26, (62, 0), 44);
- Add_Action (Table.States (17), 27, (61, 0), 45);
- Add_Action (Table.States (17), 28, (57, 0), 46);
+ Add_Action (Table.States (17), 25, (64, 0), 48);
+ Add_Action (Table.States (17), 26, (63, 0), 49);
+ Add_Action (Table.States (17), 27, (62, 0), 50);
+ Add_Action (Table.States (17), 28, (57, 0), 19);
Add_Action (Table.States (17), 30, Reduce, (56, 0), 0);
Add_Action (Table.States (17), 36, Reduce, (56, 0), 0);
- Add_Action (Table.States (17), 39, (58, 1), 47);
+ Add_Action (Table.States (17), 39, (59, 1), 51);
Add_Conflict (Table.States (17), 39, (56, 0), 0);
- Add_Action (Table.States (17), 41, (60, 1), 48);
+ Add_Action (Table.States (17), 41, (61, 1), 52);
Add_Action (Table.States (17), 42, Reduce, (56, 0), 0);
- Table.States (17).Goto_List.Set_Capacity (9);
- Add_Goto (Table.States (17), 55, 49);
- Add_Goto (Table.States (17), 56, 50);
- Add_Goto (Table.States (17), 57, 51);
- Add_Goto (Table.States (17), 58, 52);
- Add_Goto (Table.States (17), 59, 53);
- Add_Goto (Table.States (17), 60, 54);
- Add_Goto (Table.States (17), 61, 55);
- Add_Goto (Table.States (17), 62, 56);
- Add_Goto (Table.States (17), 63, 57);
+ Table.States (17).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (17), 55, 53);
+ Add_Goto (Table.States (17), 56, 54);
+ Add_Goto (Table.States (17), 57, 20);
+ Add_Goto (Table.States (17), 58, 55);
+ Add_Goto (Table.States (17), 59, 56);
+ Add_Goto (Table.States (17), 60, 57);
+ Add_Goto (Table.States (17), 61, 58);
+ Add_Goto (Table.States (17), 62, 59);
+ Add_Goto (Table.States (17), 63, 60);
+ Add_Goto (Table.States (17), 64, 61);
Table.States (18).Action_List.Set_Capacity (10);
Add_Action (Table.States (18), 20, Reduce, (56, 0), 0);
- Add_Action (Table.States (18), 25, (63, 0), 43);
- Add_Action (Table.States (18), 26, (62, 0), 44);
- Add_Action (Table.States (18), 27, (61, 0), 45);
- Add_Action (Table.States (18), 28, (57, 0), 46);
+ Add_Action (Table.States (18), 25, (64, 0), 48);
+ Add_Action (Table.States (18), 26, (63, 0), 49);
+ Add_Action (Table.States (18), 27, (62, 0), 50);
+ Add_Action (Table.States (18), 28, (57, 0), 19);
Add_Action (Table.States (18), 30, Reduce, (56, 0), 0);
Add_Action (Table.States (18), 36, Reduce, (56, 0), 0);
- Add_Action (Table.States (18), 39, (58, 1), 47);
+ Add_Action (Table.States (18), 39, (59, 1), 51);
Add_Conflict (Table.States (18), 39, (56, 0), 0);
- Add_Action (Table.States (18), 41, (60, 1), 48);
+ Add_Action (Table.States (18), 41, (61, 1), 52);
Add_Action (Table.States (18), 42, Reduce, (56, 0), 0);
- Table.States (18).Goto_List.Set_Capacity (9);
- Add_Goto (Table.States (18), 55, 58);
- Add_Goto (Table.States (18), 56, 50);
- Add_Goto (Table.States (18), 57, 51);
- Add_Goto (Table.States (18), 58, 52);
- Add_Goto (Table.States (18), 59, 53);
- Add_Goto (Table.States (18), 60, 54);
- Add_Goto (Table.States (18), 61, 55);
- Add_Goto (Table.States (18), 62, 56);
- Add_Goto (Table.States (18), 63, 57);
- Table.States (19).Action_List.Set_Capacity (3);
- Add_Action (Table.States (19), (30, 39, 42), (66, 1), 2);
- Table.States (20).Action_List.Set_Capacity (2);
- Add_Action (Table.States (20), (17, 39), (49, 0), 1);
- Table.States (21).Action_List.Set_Capacity (2);
- Add_Action (Table.States (21), 17, (48, 6), 59);
- Add_Action (Table.States (21), 39, (49, 1), 60);
- Table.States (22).Action_List.Set_Capacity (1);
- Add_Action (Table.States (22), 39, (45, 2), 61);
- Table.States (23).Action_List.Set_Capacity (1);
- Add_Action (Table.States (23), 39, (45, 1), 62);
- Table.States (24).Action_List.Set_Capacity (1);
- Add_Action (Table.States (24), 39, (45, 0), 63);
- Table.States (25).Action_List.Set_Capacity (2);
- Add_Action (Table.States (25), (13, 20), (45, 3), 1);
- Table.States (26).Action_List.Set_Capacity (2);
- Add_Action (Table.States (26), (13, 20), (46, 0), 1);
- Table.States (27).Action_List.Set_Capacity (2);
- Add_Action (Table.States (27), 13, (48, 7), 64);
- Add_Action (Table.States (27), 20, (46, 1), 65);
- Table.States (28).Action_List.Set_Capacity (2);
- Add_Action (Table.States (28), 13, (48, 8), 66);
- Add_Action (Table.States (28), 20, (46, 1), 65);
- Table.States (29).Action_List.Set_Capacity (3);
- Add_Action (Table.States (29), (30, 39, 42), (48, 15), 3);
+ Table.States (18).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (18), 55, 62);
+ Add_Goto (Table.States (18), 56, 54);
+ Add_Goto (Table.States (18), 57, 20);
+ Add_Goto (Table.States (18), 58, 55);
+ Add_Goto (Table.States (18), 59, 56);
+ Add_Goto (Table.States (18), 60, 57);
+ Add_Goto (Table.States (18), 61, 58);
+ Add_Goto (Table.States (18), 62, 59);
+ Add_Goto (Table.States (18), 63, 60);
+ Add_Goto (Table.States (18), 64, 61);
+ Table.States (19).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (19), 39, (57, 0), 63);
+ Table.States (20).Action_List.Set_Capacity (8);
+ Add_Action (Table.States (20), (21, 22, 25, 26, 27, 28, 39, 41), (58, 1), 1);
+ Table.States (21).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (21), 21, (53, 1), 64);
+ Add_Action (Table.States (21), 22, (53, 2), 65);
+ Add_Action (Table.States (21), 28, (57, 0), 19);
+ Table.States (21).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (21), 57, 66);
+ Table.States (22).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (22), (30, 39, 42), (68, 0), 2);
+ Table.States (23).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (23), (17, 39), (49, 0), 1);
+ Table.States (24).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (24), 17, (48, 6), 67);
+ Add_Action (Table.States (24), 39, (49, 1), 68);
+ Table.States (25).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (25), 39, (45, 2), 69);
+ Table.States (26).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (26), 39, (45, 1), 70);
+ Table.States (27).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (27), 39, (45, 0), 71);
+ Table.States (28).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (28), 13, Reduce, (45, 3), 1);
+ Add_Action (Table.States (28), 20, Reduce, (45, 3), 1);
+ Add_Action (Table.States (28), 30, Reduce, (49, 0), 1);
+ Add_Action (Table.States (28), 39, Reduce, (49, 0), 1);
+ Add_Action (Table.States (28), 42, Reduce, (49, 0), 1);
+ Table.States (29).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (29), (13, 20), (46, 0), 1);
Table.States (30).Action_List.Set_Capacity (2);
- Add_Action (Table.States (30), 10, (48, 14), 67);
- Add_Action (Table.States (30), 23, (48, 13), 68);
- Table.States (31).Action_List.Set_Capacity (2);
- Add_Action (Table.States (31), 10, (48, 12), 69);
- Add_Action (Table.States (31), 23, (48, 11), 70);
- Table.States (32).Action_List.Set_Capacity (3);
- Add_Action (Table.States (32), 18, (44, 0), 35);
- Add_Action (Table.States (32), 40, (44, 1), 38);
- Add_Action (Table.States (32), 41, (44, 2), 39);
- Table.States (32).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (32), 44, 71);
- Table.States (33).Action_List.Set_Capacity (1);
- Add_Action (Table.States (33), 39, (48, 2), 72);
- Table.States (34).Action_List.Set_Capacity (1);
- Add_Action (Table.States (34), 39, (48, 0), 73);
- Table.States (35).Action_List.Set_Capacity (7);
- Add_Action (Table.States (35), (18, 30, 38, 39, 40, 41, 42), (44, 0), 1);
- Table.States (36).Action_List.Set_Capacity (7);
- Add_Action (Table.States (36), (18, 30, 38, 39, 40, 41, 42), (51, 1), 1);
- Table.States (37).Action_List.Set_Capacity (7);
- Add_Action (Table.States (37), (18, 30, 38, 39, 40, 41, 42), (51, 0), 1);
- Table.States (38).Action_List.Set_Capacity (7);
- Add_Action (Table.States (38), (18, 30, 38, 39, 40, 41, 42), (44, 1), 1);
- Table.States (39).Action_List.Set_Capacity (7);
- Add_Action (Table.States (39), (18, 30, 38, 39, 40, 41, 42), (44, 2), 1);
+ Add_Action (Table.States (30), 13, (48, 8), 72);
+ Add_Action (Table.States (30), 20, (46, 1), 73);
+ Table.States (31).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (31), 30, Reduce, (48, 7), 3);
+ Add_Action (Table.States (31), 39, (49, 1), 68);
+ Add_Conflict (Table.States (31), 39, (48, 7), 3);
+ Add_Action (Table.States (31), 42, Reduce, (48, 7), 3);
+ Table.States (32).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (32), (13, 20), (45, 3), 1);
+ Table.States (33).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (33), 13, (48, 9), 74);
+ Add_Action (Table.States (33), 20, (46, 1), 73);
+ Table.States (34).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (34), (30, 39, 42), (48, 16), 3);
+ Table.States (35).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (35), 10, (48, 15), 75);
+ Add_Action (Table.States (35), 23, (48, 14), 76);
+ Table.States (36).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (36), 10, (48, 13), 77);
+ Add_Action (Table.States (36), 23, (48, 12), 78);
+ Table.States (37).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (37), 18, (44, 0), 40);
+ Add_Action (Table.States (37), 40, (44, 1), 43);
+ Add_Action (Table.States (37), 41, (44, 2), 44);
+ Table.States (37).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (37), 44, 79);
+ Table.States (38).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (38), 39, (48, 2), 80);
+ Table.States (39).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (39), 39, (48, 0), 81);
Table.States (40).Action_List.Set_Capacity (7);
- Add_Action (Table.States (40), (18, 30, 38, 39, 40, 41, 42), (51, 2), 1);
+ Add_Action (Table.States (40), (18, 30, 38, 39, 40, 41, 42), (44, 0), 1);
Table.States (41).Action_List.Set_Capacity (7);
- Add_Action (Table.States (41), (18, 30, 38, 39, 40, 41, 42), (52, 0), 1);
+ Add_Action (Table.States (41), (18, 30, 38, 39, 40, 41, 42), (51, 1), 1);
Table.States (42).Action_List.Set_Capacity (7);
- Add_Action (Table.States (42), 18, (44, 0), 35);
- Add_Action (Table.States (42), 30, Reduce, (48, 9), 3);
- Add_Action (Table.States (42), 38, (51, 1), 36);
- Add_Action (Table.States (42), 39, (51, 0), 37);
- Add_Conflict (Table.States (42), 39, (48, 9), 3);
- Add_Action (Table.States (42), 40, (44, 1), 38);
- Add_Action (Table.States (42), 41, (44, 2), 39);
- Add_Action (Table.States (42), 42, Reduce, (48, 9), 3);
- Table.States (42).Goto_List.Set_Capacity (2);
- Add_Goto (Table.States (42), 44, 40);
- Add_Goto (Table.States (42), 51, 74);
- Table.States (43).Action_List.Set_Capacity (6);
- Add_Action (Table.States (43), 25, (63, 0), 43);
- Add_Action (Table.States (43), 26, (62, 0), 44);
- Add_Action (Table.States (43), 27, (61, 0), 45);
- Add_Action (Table.States (43), 28, (57, 0), 46);
- Add_Action (Table.States (43), 39, (58, 1), 47);
- Add_Action (Table.States (43), 41, (60, 1), 48);
- Table.States (43).Goto_List.Set_Capacity (8);
- Add_Goto (Table.States (43), 57, 51);
- Add_Goto (Table.States (43), 58, 52);
- Add_Goto (Table.States (43), 59, 75);
- Add_Goto (Table.States (43), 60, 54);
- Add_Goto (Table.States (43), 61, 55);
- Add_Goto (Table.States (43), 62, 56);
- Add_Goto (Table.States (43), 63, 57);
- Add_Goto (Table.States (43), 64, 76);
- Table.States (44).Action_List.Set_Capacity (6);
- Add_Action (Table.States (44), 25, (63, 0), 43);
- Add_Action (Table.States (44), 26, (62, 0), 44);
- Add_Action (Table.States (44), 27, (61, 0), 45);
- Add_Action (Table.States (44), 28, (57, 0), 46);
- Add_Action (Table.States (44), 39, (58, 1), 47);
- Add_Action (Table.States (44), 41, (60, 1), 48);
- Table.States (44).Goto_List.Set_Capacity (8);
- Add_Goto (Table.States (44), 57, 51);
- Add_Goto (Table.States (44), 58, 52);
- Add_Goto (Table.States (44), 59, 75);
- Add_Goto (Table.States (44), 60, 54);
- Add_Goto (Table.States (44), 61, 55);
- Add_Goto (Table.States (44), 62, 56);
- Add_Goto (Table.States (44), 63, 57);
- Add_Goto (Table.States (44), 64, 77);
- Table.States (45).Action_List.Set_Capacity (6);
- Add_Action (Table.States (45), 25, (63, 0), 43);
- Add_Action (Table.States (45), 26, (62, 0), 44);
- Add_Action (Table.States (45), 27, (61, 0), 45);
- Add_Action (Table.States (45), 28, (57, 0), 46);
- Add_Action (Table.States (45), 39, (58, 1), 47);
- Add_Action (Table.States (45), 41, (60, 1), 48);
- Table.States (45).Goto_List.Set_Capacity (8);
- Add_Goto (Table.States (45), 57, 51);
- Add_Goto (Table.States (45), 58, 52);
- Add_Goto (Table.States (45), 59, 75);
- Add_Goto (Table.States (45), 60, 54);
- Add_Goto (Table.States (45), 61, 55);
- Add_Goto (Table.States (45), 62, 56);
- Add_Goto (Table.States (45), 63, 57);
- Add_Goto (Table.States (45), 64, 78);
- Table.States (46).Action_List.Set_Capacity (1);
- Add_Action (Table.States (46), 39, (57, 0), 79);
- Table.States (47).Action_List.Set_Capacity (18);
- Add_Action (Table.States (47), 19, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 20, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 23, (58, 1), 80);
- Add_Action (Table.States (47), 25, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 26, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 27, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 28, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 30, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 31, (63, 4), 81);
- Add_Action (Table.States (47), 32, (62, 2), 82);
- Add_Action (Table.States (47), 33, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 34, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 35, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 36, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 37, (63, 5), 83);
- Add_Action (Table.States (47), 39, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 41, Reduce, (60, 0), 1);
- Add_Action (Table.States (47), 42, Reduce, (60, 0), 1);
- Table.States (48).Action_List.Set_Capacity (15);
- Add_Action (Table.States (48), 19, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 20, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 25, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 26, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 27, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 28, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 30, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 32, (62, 3), 84);
- Add_Action (Table.States (48), 33, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 34, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 35, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 36, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 39, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 41, Reduce, (60, 1), 1);
- Add_Action (Table.States (48), 42, Reduce, (60, 1), 1);
- Table.States (49).Action_List.Set_Capacity (5);
- Add_Action (Table.States (49), 20, (55, 1), 85);
- Add_Action (Table.States (49), 30, (55, 2), 86);
- Add_Conflict (Table.States (49), 30, (54, 1), 0);
- Add_Action (Table.States (49), 36, (54, 0), 87);
- Add_Action (Table.States (49), 39, Reduce, (54, 1), 0);
- Add_Action (Table.States (49), 42, Reduce, (54, 1), 0);
- Table.States (49).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (49), 54, 88);
- Table.States (50).Action_List.Set_Capacity (5);
- Add_Action (Table.States (50), (20, 30, 36, 39, 42), (55, 0), 1);
- Table.States (51).Action_List.Set_Capacity (14);
- Add_Action (Table.States (51), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (60, 2), 1);
+ Add_Action (Table.States (42), (18, 30, 38, 39, 40, 41, 42), (51, 0), 1);
+ Table.States (43).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (43), (18, 30, 38, 39, 40, 41, 42), (44, 1), 1);
+ Table.States (44).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (44), (18, 30, 38, 39, 40, 41, 42), (44, 2), 1);
+ Table.States (45).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (45), (18, 30, 38, 39, 40, 41, 42), (51, 2), 1);
+ Table.States (46).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (46), (18, 30, 38, 39, 40, 41, 42), (52, 0), 1);
+ Table.States (47).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (47), 18, (44, 0), 40);
+ Add_Action (Table.States (47), 30, Reduce, (48, 10), 3);
+ Add_Action (Table.States (47), 38, (51, 1), 41);
+ Add_Action (Table.States (47), 39, (51, 0), 42);
+ Add_Conflict (Table.States (47), 39, (48, 10), 3);
+ Add_Action (Table.States (47), 40, (44, 1), 43);
+ Add_Action (Table.States (47), 41, (44, 2), 44);
+ Add_Action (Table.States (47), 42, Reduce, (48, 10), 3);
+ Table.States (47).Goto_List.Set_Capacity (2);
+ Add_Goto (Table.States (47), 44, 45);
+ Add_Goto (Table.States (47), 51, 82);
+ Table.States (48).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (48), 25, (64, 0), 48);
+ Add_Action (Table.States (48), 26, (63, 0), 49);
+ Add_Action (Table.States (48), 27, (62, 0), 50);
+ Add_Action (Table.States (48), 28, (57, 0), 19);
+ Add_Action (Table.States (48), 39, (59, 1), 51);
+ Add_Action (Table.States (48), 41, (61, 1), 52);
+ Table.States (48).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (48), 57, 20);
+ Add_Goto (Table.States (48), 58, 83);
+ Add_Goto (Table.States (48), 59, 56);
+ Add_Goto (Table.States (48), 60, 84);
+ Add_Goto (Table.States (48), 61, 58);
+ Add_Goto (Table.States (48), 62, 59);
+ Add_Goto (Table.States (48), 63, 60);
+ Add_Goto (Table.States (48), 64, 61);
+ Add_Goto (Table.States (48), 65, 85);
+ Add_Goto (Table.States (48), 66, 86);
+ Table.States (49).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (49), 25, (64, 0), 48);
+ Add_Action (Table.States (49), 26, (63, 0), 49);
+ Add_Action (Table.States (49), 27, (62, 0), 50);
+ Add_Action (Table.States (49), 28, (57, 0), 19);
+ Add_Action (Table.States (49), 39, (59, 1), 51);
+ Add_Action (Table.States (49), 41, (61, 1), 52);
+ Table.States (49).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (49), 57, 20);
+ Add_Goto (Table.States (49), 58, 83);
+ Add_Goto (Table.States (49), 59, 56);
+ Add_Goto (Table.States (49), 60, 84);
+ Add_Goto (Table.States (49), 61, 58);
+ Add_Goto (Table.States (49), 62, 59);
+ Add_Goto (Table.States (49), 63, 60);
+ Add_Goto (Table.States (49), 64, 61);
+ Add_Goto (Table.States (49), 65, 87);
+ Add_Goto (Table.States (49), 66, 86);
+ Table.States (50).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (50), 25, (64, 0), 48);
+ Add_Action (Table.States (50), 26, (63, 0), 49);
+ Add_Action (Table.States (50), 27, (62, 0), 50);
+ Add_Action (Table.States (50), 28, (57, 0), 19);
+ Add_Action (Table.States (50), 39, (59, 1), 51);
+ Add_Action (Table.States (50), 41, (61, 1), 52);
+ Table.States (50).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (50), 57, 20);
+ Add_Goto (Table.States (50), 58, 83);
+ Add_Goto (Table.States (50), 59, 56);
+ Add_Goto (Table.States (50), 60, 84);
+ Add_Goto (Table.States (50), 61, 58);
+ Add_Goto (Table.States (50), 62, 59);
+ Add_Goto (Table.States (50), 63, 60);
+ Add_Goto (Table.States (50), 64, 61);
+ Add_Goto (Table.States (50), 65, 88);
+ Add_Goto (Table.States (50), 66, 86);
+ Table.States (51).Action_List.Set_Capacity (17);
+ Add_Action (Table.States (51), 19, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 20, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 23, (59, 1), 89);
+ Add_Action (Table.States (51), 25, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 26, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 27, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 30, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 31, (64, 4), 90);
+ Add_Action (Table.States (51), 32, (63, 2), 91);
+ Add_Action (Table.States (51), 33, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 34, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 35, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 36, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 37, (64, 5), 92);
+ Add_Action (Table.States (51), 39, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 41, Reduce, (61, 0), 1);
+ Add_Action (Table.States (51), 42, Reduce, (61, 0), 1);
Table.States (52).Action_List.Set_Capacity (14);
- Add_Action (Table.States (52), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (59, 0), 1);
- Table.States (53).Action_List.Set_Capacity (11);
- Add_Action (Table.States (53), 19, (56, 2), 89);
- Add_Action (Table.States (53), 20, Reduce, (56, 1), 1);
- Add_Action (Table.States (53), 25, (63, 0), 43);
- Add_Action (Table.States (53), 26, (62, 0), 44);
- Add_Action (Table.States (53), 27, (61, 0), 45);
- Add_Action (Table.States (53), 28, (57, 0), 46);
- Add_Action (Table.States (53), 30, Reduce, (56, 1), 1);
- Add_Action (Table.States (53), 36, Reduce, (56, 1), 1);
- Add_Action (Table.States (53), 39, (58, 1), 47);
- Add_Conflict (Table.States (53), 39, (56, 1), 1);
- Add_Action (Table.States (53), 41, (60, 1), 48);
- Add_Action (Table.States (53), 42, Reduce, (56, 1), 1);
- Table.States (53).Goto_List.Set_Capacity (6);
- Add_Goto (Table.States (53), 57, 51);
- Add_Goto (Table.States (53), 58, 90);
- Add_Goto (Table.States (53), 60, 54);
- Add_Goto (Table.States (53), 61, 55);
- Add_Goto (Table.States (53), 62, 56);
- Add_Goto (Table.States (53), 63, 57);
- Table.States (54).Action_List.Set_Capacity (14);
- Add_Action (Table.States (54), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (58, 0), 1);
- Table.States (55).Action_List.Set_Capacity (14);
- Add_Action (Table.States (55), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (60, 5), 1);
- Table.States (56).Action_List.Set_Capacity (14);
- Add_Action (Table.States (56), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (60, 3), 1);
- Table.States (57).Action_List.Set_Capacity (14);
- Add_Action (Table.States (57), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (60, 4), 1);
- Table.States (58).Action_List.Set_Capacity (5);
- Add_Action (Table.States (58), 20, (55, 1), 85);
- Add_Action (Table.States (58), 30, (55, 2), 86);
- Add_Conflict (Table.States (58), 30, (54, 1), 0);
- Add_Action (Table.States (58), 36, (54, 0), 87);
- Add_Action (Table.States (58), 39, Reduce, (54, 1), 0);
- Add_Action (Table.States (58), 42, Reduce, (54, 1), 0);
- Table.States (58).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (58), 54, 91);
+ Add_Action (Table.States (52), 19, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 20, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 25, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 26, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 27, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 30, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 32, (63, 3), 93);
+ Add_Action (Table.States (52), 33, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 34, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 35, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 36, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 39, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 41, Reduce, (61, 1), 1);
+ Add_Action (Table.States (52), 42, Reduce, (61, 1), 1);
+ Table.States (53).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (53), 20, (55, 1), 94);
+ Add_Action (Table.States (53), 30, (55, 2), 95);
+ Add_Conflict (Table.States (53), 30, (54, 1), 0);
+ Add_Action (Table.States (53), 36, (54, 0), 96);
+ Add_Action (Table.States (53), 39, Reduce, (54, 1), 0);
+ Add_Action (Table.States (53), 42, Reduce, (54, 1), 0);
+ Table.States (53).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (53), 54, 97);
+ Table.States (54).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (54), (20, 30, 36, 39, 42), (55, 0), 1);
+ Table.States (55).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (55), 25, (64, 0), 48);
+ Add_Action (Table.States (55), 26, (63, 0), 49);
+ Add_Action (Table.States (55), 27, (62, 0), 50);
+ Add_Action (Table.States (55), 28, (57, 0), 19);
+ Add_Action (Table.States (55), 39, (59, 1), 51);
+ Add_Action (Table.States (55), 41, (61, 1), 52);
+ Table.States (55).Goto_List.Set_Capacity (7);
+ Add_Goto (Table.States (55), 57, 66);
+ Add_Goto (Table.States (55), 59, 56);
+ Add_Goto (Table.States (55), 60, 98);
+ Add_Goto (Table.States (55), 61, 58);
+ Add_Goto (Table.States (55), 62, 59);
+ Add_Goto (Table.States (55), 63, 60);
+ Add_Goto (Table.States (55), 64, 61);
end Subr_1;
procedure Subr_2
is begin
- Table.States (59).Action_List.Set_Capacity (3);
- Add_Action (Table.States (59), (30, 39, 42), (48, 6), 4);
- Table.States (60).Action_List.Set_Capacity (2);
- Add_Action (Table.States (60), (17, 39), (49, 1), 2);
- Table.States (61).Action_List.Set_Capacity (2);
- Add_Action (Table.States (61), (13, 20), (45, 2), 2);
- Table.States (62).Action_List.Set_Capacity (2);
- Add_Action (Table.States (62), (13, 20), (45, 1), 2);
- Table.States (63).Action_List.Set_Capacity (2);
- Add_Action (Table.States (63), (13, 20), (45, 0), 2);
- Table.States (64).Action_List.Set_Capacity (1);
- Add_Action (Table.States (64), 16, (48, 7), 92);
- Table.States (65).Action_List.Set_Capacity (4);
- Add_Action (Table.States (65), 3, (45, 2), 22);
- Add_Action (Table.States (65), 14, (45, 1), 23);
- Add_Action (Table.States (65), 15, (45, 0), 24);
- Add_Action (Table.States (65), 39, (45, 3), 25);
- Table.States (65).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (65), 45, 93);
- Table.States (66).Action_List.Set_Capacity (1);
- Add_Action (Table.States (66), 16, (48, 8), 94);
- Table.States (67).Action_List.Set_Capacity (1);
- Add_Action (Table.States (67), 39, (50, 0), 95);
- Table.States (67).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (67), 50, 96);
- Table.States (68).Action_List.Set_Capacity (1);
- Add_Action (Table.States (68), 39, (48, 13), 97);
- Table.States (69).Action_List.Set_Capacity (1);
- Add_Action (Table.States (69), 39, (50, 0), 95);
- Table.States (69).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (69), 50, 98);
- Table.States (70).Action_List.Set_Capacity (1);
- Add_Action (Table.States (70), 39, (48, 11), 99);
- Table.States (71).Action_List.Set_Capacity (3);
- Add_Action (Table.States (71), (30, 39, 42), (48, 5), 4);
+ Table.States (56).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (56), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (60, 1), 1);
+ Table.States (57).Action_List.Set_Capacity (10);
+ Add_Action (Table.States (57), 19, (56, 3), 99);
+ Add_Action (Table.States (57), 20, Reduce, (56, 1), 1);
+ Add_Action (Table.States (57), 25, (64, 0), 48);
+ Add_Action (Table.States (57), 26, (63, 0), 49);
+ Add_Action (Table.States (57), 27, (62, 0), 50);
+ Add_Action (Table.States (57), 30, Reduce, (56, 1), 1);
+ Add_Action (Table.States (57), 36, Reduce, (56, 1), 1);
+ Add_Action (Table.States (57), 39, (59, 1), 51);
+ Add_Conflict (Table.States (57), 39, (56, 1), 1);
+ Add_Action (Table.States (57), 41, (61, 1), 52);
+ Add_Action (Table.States (57), 42, Reduce, (56, 1), 1);
+ Table.States (57).Goto_List.Set_Capacity (5);
+ Add_Goto (Table.States (57), 59, 100);
+ Add_Goto (Table.States (57), 61, 58);
+ Add_Goto (Table.States (57), 62, 59);
+ Add_Goto (Table.States (57), 63, 60);
+ Add_Goto (Table.States (57), 64, 61);
+ Table.States (58).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (58), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (59, 0), 1);
+ Table.States (59).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (59), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (61, 4), 1);
+ Table.States (60).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (60), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (61, 2), 1);
+ Table.States (61).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (61), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (61, 3), 1);
+ Table.States (62).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (62), 20, (55, 1), 94);
+ Add_Action (Table.States (62), 30, (55, 2), 95);
+ Add_Conflict (Table.States (62), 30, (54, 1), 0);
+ Add_Action (Table.States (62), 36, (54, 0), 96);
+ Add_Action (Table.States (62), 39, Reduce, (54, 1), 0);
+ Add_Action (Table.States (62), 42, Reduce, (54, 1), 0);
+ Table.States (62).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (62), 54, 101);
+ Table.States (63).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (63), 23, (57, 0), 102);
+ Table.States (64).Action_List.Set_Capacity (10);
+ Add_Action (Table.States (64), 20, Reduce, (56, 0), 0);
+ Add_Action (Table.States (64), 25, (64, 0), 48);
+ Add_Action (Table.States (64), 26, (63, 0), 49);
+ Add_Action (Table.States (64), 27, (62, 0), 50);
+ Add_Action (Table.States (64), 28, (57, 0), 19);
+ Add_Action (Table.States (64), 30, Reduce, (56, 0), 0);
+ Add_Action (Table.States (64), 36, Reduce, (56, 0), 0);
+ Add_Action (Table.States (64), 39, (59, 1), 51);
+ Add_Conflict (Table.States (64), 39, (56, 0), 0);
+ Add_Action (Table.States (64), 41, (61, 1), 52);
+ Add_Action (Table.States (64), 42, Reduce, (56, 0), 0);
+ Table.States (64).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (64), 55, 103);
+ Add_Goto (Table.States (64), 56, 54);
+ Add_Goto (Table.States (64), 57, 20);
+ Add_Goto (Table.States (64), 58, 55);
+ Add_Goto (Table.States (64), 59, 56);
+ Add_Goto (Table.States (64), 60, 57);
+ Add_Goto (Table.States (64), 61, 58);
+ Add_Goto (Table.States (64), 62, 59);
+ Add_Goto (Table.States (64), 63, 60);
+ Add_Goto (Table.States (64), 64, 61);
+ Table.States (65).Action_List.Set_Capacity (10);
+ Add_Action (Table.States (65), 20, Reduce, (56, 0), 0);
+ Add_Action (Table.States (65), 25, (64, 0), 48);
+ Add_Action (Table.States (65), 26, (63, 0), 49);
+ Add_Action (Table.States (65), 27, (62, 0), 50);
+ Add_Action (Table.States (65), 28, (57, 0), 19);
+ Add_Action (Table.States (65), 30, Reduce, (56, 0), 0);
+ Add_Action (Table.States (65), 36, Reduce, (56, 0), 0);
+ Add_Action (Table.States (65), 39, (59, 1), 51);
+ Add_Conflict (Table.States (65), 39, (56, 0), 0);
+ Add_Action (Table.States (65), 41, (61, 1), 52);
+ Add_Action (Table.States (65), 42, Reduce, (56, 0), 0);
+ Table.States (65).Goto_List.Set_Capacity (10);
+ Add_Goto (Table.States (65), 55, 104);
+ Add_Goto (Table.States (65), 56, 54);
+ Add_Goto (Table.States (65), 57, 20);
+ Add_Goto (Table.States (65), 58, 55);
+ Add_Goto (Table.States (65), 59, 56);
+ Add_Goto (Table.States (65), 60, 57);
+ Add_Goto (Table.States (65), 61, 58);
+ Add_Goto (Table.States (65), 62, 59);
+ Add_Goto (Table.States (65), 63, 60);
+ Add_Goto (Table.States (65), 64, 61);
+ Table.States (66).Action_List.Set_Capacity (8);
+ Add_Action (Table.States (66), (21, 22, 25, 26, 27, 28, 39, 41), (58, 0), 2);
+ Table.States (67).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (67), (30, 39, 42), (48, 6), 4);
+ Table.States (68).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (68), (17, 30, 39, 42), (49, 1), 2);
+ Table.States (69).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (69), (13, 20), (45, 2), 2);
+ Table.States (70).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (70), (13, 20), (45, 1), 2);
+ Table.States (71).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (71), (13, 20), (45, 0), 2);
Table.States (72).Action_List.Set_Capacity (1);
- Add_Action (Table.States (72), 24, (48, 2), 100);
- Table.States (73).Action_List.Set_Capacity (1);
- Add_Action (Table.States (73), 24, (48, 0), 101);
- Table.States (74).Action_List.Set_Capacity (7);
- Add_Action (Table.States (74), (18, 30, 38, 39, 40, 41, 42), (52, 1), 2);
- Table.States (75).Action_List.Set_Capacity (10);
- Add_Action (Table.States (75), 20, Reduce, (64, 0), 1);
- Add_Action (Table.States (75), 25, (63, 0), 43);
- Add_Action (Table.States (75), 26, (62, 0), 44);
- Add_Action (Table.States (75), 27, (61, 0), 45);
- Add_Action (Table.States (75), 28, (57, 0), 46);
- Add_Action (Table.States (75), 33, Reduce, (64, 0), 1);
- Add_Action (Table.States (75), 34, Reduce, (64, 0), 1);
- Add_Action (Table.States (75), 35, Reduce, (64, 0), 1);
- Add_Action (Table.States (75), 39, (58, 1), 47);
- Add_Action (Table.States (75), 41, (60, 1), 48);
- Table.States (75).Goto_List.Set_Capacity (6);
- Add_Goto (Table.States (75), 57, 51);
- Add_Goto (Table.States (75), 58, 90);
- Add_Goto (Table.States (75), 60, 54);
- Add_Goto (Table.States (75), 61, 55);
- Add_Goto (Table.States (75), 62, 56);
- Add_Goto (Table.States (75), 63, 57);
- Table.States (76).Action_List.Set_Capacity (2);
- Add_Action (Table.States (76), 20, (64, 1), 102);
- Add_Action (Table.States (76), 33, (63, 0), 103);
- Table.States (77).Action_List.Set_Capacity (2);
- Add_Action (Table.States (77), 20, (64, 1), 102);
- Add_Action (Table.States (77), 34, (62, 0), 104);
- Table.States (78).Action_List.Set_Capacity (2);
- Add_Action (Table.States (78), 20, (64, 1), 102);
- Add_Action (Table.States (78), 35, (61, 0), 105);
- Table.States (79).Action_List.Set_Capacity (1);
- Add_Action (Table.States (79), 23, (57, 0), 106);
- Table.States (80).Action_List.Set_Capacity (6);
- Add_Action (Table.States (80), 25, (63, 0), 43);
- Add_Action (Table.States (80), 26, (62, 0), 44);
- Add_Action (Table.States (80), 27, (61, 0), 45);
- Add_Action (Table.States (80), 28, (57, 0), 46);
- Add_Action (Table.States (80), 39, (60, 0), 107);
- Add_Action (Table.States (80), 41, (60, 1), 48);
- Table.States (80).Goto_List.Set_Capacity (5);
- Add_Goto (Table.States (80), 57, 51);
- Add_Goto (Table.States (80), 60, 108);
- Add_Goto (Table.States (80), 61, 55);
- Add_Goto (Table.States (80), 62, 56);
- Add_Goto (Table.States (80), 63, 57);
- Table.States (81).Action_List.Set_Capacity (14);
- Add_Action (Table.States (81), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (63, 4), 2);
- Table.States (82).Action_List.Set_Capacity (14);
- Add_Action (Table.States (82), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (62, 2), 2);
- Table.States (83).Action_List.Set_Capacity (14);
- Add_Action (Table.States (83), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (63, 5), 2);
- Table.States (84).Action_List.Set_Capacity (14);
- Add_Action (Table.States (84), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (62, 3), 2);
- Table.States (85).Action_List.Set_Capacity (10);
- Add_Action (Table.States (85), 20, Reduce, (56, 0), 0);
- Add_Action (Table.States (85), 25, (63, 0), 43);
- Add_Action (Table.States (85), 26, (62, 0), 44);
- Add_Action (Table.States (85), 27, (61, 0), 45);
- Add_Action (Table.States (85), 28, (57, 0), 46);
- Add_Action (Table.States (85), 30, Reduce, (56, 0), 0);
- Add_Action (Table.States (85), 36, Reduce, (56, 0), 0);
- Add_Action (Table.States (85), 39, (58, 1), 47);
- Add_Conflict (Table.States (85), 39, (56, 0), 0);
- Add_Action (Table.States (85), 41, (60, 1), 48);
- Add_Action (Table.States (85), 42, Reduce, (56, 0), 0);
- Table.States (85).Goto_List.Set_Capacity (8);
- Add_Goto (Table.States (85), 56, 109);
- Add_Goto (Table.States (85), 57, 51);
- Add_Goto (Table.States (85), 58, 52);
- Add_Goto (Table.States (85), 59, 53);
- Add_Goto (Table.States (85), 60, 54);
- Add_Goto (Table.States (85), 61, 55);
- Add_Goto (Table.States (85), 62, 56);
- Add_Goto (Table.States (85), 63, 57);
- Table.States (86).Action_List.Set_Capacity (3);
- Add_Action (Table.States (86), 7, (55, 6), 110);
- Add_Action (Table.States (86), 8, (55, 4), 111);
- Add_Action (Table.States (86), 9, (55, 2), 112);
- Table.States (87).Action_List.Set_Capacity (3);
- Add_Action (Table.States (87), (30, 39, 42), (54, 0), 1);
- Table.States (88).Action_List.Set_Capacity (3);
- Add_Action (Table.States (88), (30, 39, 42), (53, 0), 4);
- Table.States (89).Action_List.Set_Capacity (6);
- Add_Action (Table.States (89), 19, (56, 3), 113);
- Add_Action (Table.States (89), 20, Reduce, (56, 2), 2);
- Add_Action (Table.States (89), 30, Reduce, (56, 2), 2);
- Add_Action (Table.States (89), 36, Reduce, (56, 2), 2);
- Add_Action (Table.States (89), 39, Reduce, (56, 2), 2);
- Add_Action (Table.States (89), 42, Reduce, (56, 2), 2);
- Table.States (90).Action_List.Set_Capacity (14);
- Add_Action (Table.States (90), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (59, 1), 2);
- Table.States (91).Action_List.Set_Capacity (3);
- Add_Action (Table.States (91), (30, 39, 42), (53, 1), 4);
- Table.States (92).Action_List.Set_Capacity (2);
- Add_Action (Table.States (92), 39, (47, 0), 114);
- Add_Action (Table.States (92), 41, (47, 1), 115);
- Table.States (92).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (92), 47, 116);
- Table.States (93).Action_List.Set_Capacity (2);
- Add_Action (Table.States (93), (13, 20), (46, 1), 3);
- Table.States (94).Action_List.Set_Capacity (2);
- Add_Action (Table.States (94), 39, (47, 0), 114);
- Add_Action (Table.States (94), 41, (47, 1), 115);
- Table.States (94).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (94), 47, 117);
- Table.States (95).Action_List.Set_Capacity (5);
- Add_Action (Table.States (95), (20, 30, 36, 39, 42), (50, 0), 1);
- Table.States (96).Action_List.Set_Capacity (4);
- Add_Action (Table.States (96), 20, (50, 1), 118);
- Add_Action (Table.States (96), 30, Reduce, (48, 14), 5);
- Add_Action (Table.States (96), 39, Reduce, (48, 14), 5);
- Add_Action (Table.States (96), 42, Reduce, (48, 14), 5);
+ Add_Action (Table.States (72), 16, (48, 8), 105);
+ Table.States (73).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (73), 3, (45, 2), 25);
+ Add_Action (Table.States (73), 14, (45, 1), 26);
+ Add_Action (Table.States (73), 15, (45, 0), 27);
+ Add_Action (Table.States (73), 39, (45, 3), 32);
+ Table.States (73).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (73), 45, 106);
+ Table.States (74).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (74), 16, (48, 9), 107);
+ Table.States (75).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (75), 39, (50, 0), 108);
+ Table.States (75).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (75), 50, 109);
+ Table.States (76).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (76), 39, (48, 14), 110);
+ Table.States (77).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (77), 39, (50, 0), 108);
+ Table.States (77).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (77), 50, 111);
+ Table.States (78).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (78), 39, (48, 12), 112);
+ Table.States (79).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (79), (30, 39, 42), (48, 5), 4);
+ Table.States (80).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (80), 24, (48, 2), 113);
+ Table.States (81).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (81), 24, (48, 0), 114);
+ Table.States (82).Action_List.Set_Capacity (7);
+ Add_Action (Table.States (82), (18, 30, 38, 39, 40, 41, 42), (52, 1), 2);
+ Table.States (83).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (83), 25, (64, 0), 48);
+ Add_Action (Table.States (83), 26, (63, 0), 49);
+ Add_Action (Table.States (83), 27, (62, 0), 50);
+ Add_Action (Table.States (83), 28, (57, 0), 19);
+ Add_Action (Table.States (83), 39, (59, 1), 51);
+ Add_Action (Table.States (83), 41, (61, 1), 52);
+ Table.States (83).Goto_List.Set_Capacity (8);
+ Add_Goto (Table.States (83), 57, 66);
+ Add_Goto (Table.States (83), 59, 56);
+ Add_Goto (Table.States (83), 60, 84);
+ Add_Goto (Table.States (83), 61, 58);
+ Add_Goto (Table.States (83), 62, 59);
+ Add_Goto (Table.States (83), 63, 60);
+ Add_Goto (Table.States (83), 64, 61);
+ Add_Goto (Table.States (83), 66, 115);
+ Table.States (84).Action_List.Set_Capacity (9);
+ Add_Action (Table.States (84), 20, Reduce, (66, 1), 1);
+ Add_Action (Table.States (84), 25, (64, 0), 48);
+ Add_Action (Table.States (84), 26, (63, 0), 49);
+ Add_Action (Table.States (84), 27, (62, 0), 50);
+ Add_Action (Table.States (84), 33, Reduce, (66, 1), 1);
+ Add_Action (Table.States (84), 34, Reduce, (66, 1), 1);
+ Add_Action (Table.States (84), 35, Reduce, (66, 1), 1);
+ Add_Action (Table.States (84), 39, (59, 1), 51);
+ Add_Action (Table.States (84), 41, (61, 1), 52);
+ Table.States (84).Goto_List.Set_Capacity (5);
+ Add_Goto (Table.States (84), 59, 100);
+ Add_Goto (Table.States (84), 61, 58);
+ Add_Goto (Table.States (84), 62, 59);
+ Add_Goto (Table.States (84), 63, 60);
+ Add_Goto (Table.States (84), 64, 61);
+ Table.States (85).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (85), 33, (64, 0), 116);
+ Table.States (86).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (86), 20, (66, 0), 117);
+ Add_Action (Table.States (86), 33, Reduce, (65, 1), 1);
+ Add_Action (Table.States (86), 34, Reduce, (65, 1), 1);
+ Add_Action (Table.States (86), 35, Reduce, (65, 1), 1);
+ Table.States (87).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (87), 34, (63, 0), 118);
+ Table.States (88).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (88), 35, (62, 0), 119);
+ Table.States (89).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (89), 25, (64, 0), 48);
+ Add_Action (Table.States (89), 26, (63, 0), 49);
+ Add_Action (Table.States (89), 27, (62, 0), 50);
+ Add_Action (Table.States (89), 39, (61, 0), 120);
+ Add_Action (Table.States (89), 41, (61, 1), 52);
+ Table.States (89).Goto_List.Set_Capacity (4);
+ Add_Goto (Table.States (89), 61, 121);
+ Add_Goto (Table.States (89), 62, 59);
+ Add_Goto (Table.States (89), 63, 60);
+ Add_Goto (Table.States (89), 64, 61);
+ Table.States (90).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (90), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (64, 4), 2);
+ Table.States (91).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (91), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (63, 2), 2);
+ Table.States (92).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (92), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (64, 5), 2);
+ Table.States (93).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (93), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (63, 3), 2);
+ Table.States (94).Action_List.Set_Capacity (10);
+ Add_Action (Table.States (94), 20, Reduce, (56, 0), 0);
+ Add_Action (Table.States (94), 25, (64, 0), 48);
+ Add_Action (Table.States (94), 26, (63, 0), 49);
+ Add_Action (Table.States (94), 27, (62, 0), 50);
+ Add_Action (Table.States (94), 28, (57, 0), 19);
+ Add_Action (Table.States (94), 30, Reduce, (56, 0), 0);
+ Add_Action (Table.States (94), 36, Reduce, (56, 0), 0);
+ Add_Action (Table.States (94), 39, (59, 1), 51);
+ Add_Conflict (Table.States (94), 39, (56, 0), 0);
+ Add_Action (Table.States (94), 41, (61, 1), 52);
+ Add_Action (Table.States (94), 42, Reduce, (56, 0), 0);
+ Table.States (94).Goto_List.Set_Capacity (9);
+ Add_Goto (Table.States (94), 56, 122);
+ Add_Goto (Table.States (94), 57, 20);
+ Add_Goto (Table.States (94), 58, 55);
+ Add_Goto (Table.States (94), 59, 56);
+ Add_Goto (Table.States (94), 60, 57);
+ Add_Goto (Table.States (94), 61, 58);
+ Add_Goto (Table.States (94), 62, 59);
+ Add_Goto (Table.States (94), 63, 60);
+ Add_Goto (Table.States (94), 64, 61);
+ Table.States (95).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (95), 7, (55, 6), 123);
+ Add_Action (Table.States (95), 8, (55, 4), 124);
+ Add_Action (Table.States (95), 9, (55, 2), 125);
+ Table.States (96).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (96), (30, 39, 42), (54, 0), 1);
Table.States (97).Action_List.Set_Capacity (3);
- Add_Action (Table.States (97), (30, 39, 42), (48, 13), 5);
- Table.States (98).Action_List.Set_Capacity (4);
- Add_Action (Table.States (98), 20, (50, 1), 118);
- Add_Action (Table.States (98), 30, Reduce, (48, 12), 5);
- Add_Action (Table.States (98), 39, Reduce, (48, 12), 5);
- Add_Action (Table.States (98), 42, Reduce, (48, 12), 5);
- Table.States (99).Action_List.Set_Capacity (3);
- Add_Action (Table.States (99), (30, 39, 42), (48, 11), 5);
- Table.States (100).Action_List.Set_Capacity (1);
- Add_Action (Table.States (100), 39, (48, 2), 119);
- Table.States (101).Action_List.Set_Capacity (1);
- Add_Action (Table.States (101), 39, (48, 0), 120);
- Table.States (102).Action_List.Set_Capacity (6);
- Add_Action (Table.States (102), 25, (63, 0), 43);
- Add_Action (Table.States (102), 26, (62, 0), 44);
- Add_Action (Table.States (102), 27, (61, 0), 45);
- Add_Action (Table.States (102), 28, (57, 0), 46);
- Add_Action (Table.States (102), 39, (58, 1), 47);
- Add_Action (Table.States (102), 41, (60, 1), 48);
- Table.States (102).Goto_List.Set_Capacity (7);
- Add_Goto (Table.States (102), 57, 51);
- Add_Goto (Table.States (102), 58, 52);
- Add_Goto (Table.States (102), 59, 121);
- Add_Goto (Table.States (102), 60, 54);
- Add_Goto (Table.States (102), 61, 55);
- Add_Goto (Table.States (102), 62, 56);
- Add_Goto (Table.States (102), 63, 57);
- Table.States (103).Action_List.Set_Capacity (15);
- Add_Action (Table.States (103), 19, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 20, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 25, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 26, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 27, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 28, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 29, (63, 1), 122);
- Add_Action (Table.States (103), 30, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 33, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 34, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 35, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 36, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 39, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 41, Reduce, (63, 0), 3);
- Add_Action (Table.States (103), 42, Reduce, (63, 0), 3);
- Table.States (104).Action_List.Set_Capacity (14);
- Add_Action (Table.States (104), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (62, 0), 3);
- Table.States (105).Action_List.Set_Capacity (17);
- Add_Action (Table.States (105), 19, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 20, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 25, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 26, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 27, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 28, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 30, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 31, (63, 2), 123);
- Add_Action (Table.States (105), 32, (62, 1), 124);
- Add_Action (Table.States (105), 33, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 34, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 35, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 36, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 37, (63, 3), 125);
- Add_Action (Table.States (105), 39, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 41, Reduce, (61, 0), 3);
- Add_Action (Table.States (105), 42, Reduce, (61, 0), 3);
- Table.States (106).Action_List.Set_Capacity (1);
- Add_Action (Table.States (106), 39, (57, 0), 126);
- Table.States (107).Action_List.Set_Capacity (17);
- Add_Action (Table.States (107), 19, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 20, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 25, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 26, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 27, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 28, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 30, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 31, (63, 4), 81);
- Add_Action (Table.States (107), 32, (62, 2), 82);
- Add_Action (Table.States (107), 33, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 34, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 35, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 36, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 37, (63, 5), 83);
- Add_Action (Table.States (107), 39, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 41, Reduce, (60, 0), 1);
- Add_Action (Table.States (107), 42, Reduce, (60, 0), 1);
- Table.States (108).Action_List.Set_Capacity (14);
- Add_Action (Table.States (108), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (58, 1), 3);
- Table.States (109).Action_List.Set_Capacity (5);
- Add_Action (Table.States (109), (20, 30, 36, 39, 42), (55, 1), 3);
- Table.States (110).Action_List.Set_Capacity (1);
- Add_Action (Table.States (110), 9, (55, 6), 127);
- Table.States (111).Action_List.Set_Capacity (1);
- Add_Action (Table.States (111), 39, (55, 4), 128);
- Table.States (112).Action_List.Set_Capacity (1);
- Add_Action (Table.States (112), 39, (55, 2), 129);
- Table.States (113).Action_List.Set_Capacity (5);
- Add_Action (Table.States (113), (20, 30, 36, 39, 42), (56, 3), 3);
- Table.States (114).Action_List.Set_Capacity (4);
- Add_Action (Table.States (114), (21, 30, 39, 42), (47, 0), 1);
+ Add_Action (Table.States (97), (30, 39, 42), (53, 0), 4);
+ Table.States (98).Action_List.Set_Capacity (10);
+ Add_Action (Table.States (98), 19, (56, 4), 126);
+ Add_Action (Table.States (98), 20, Reduce, (56, 2), 2);
+ Add_Action (Table.States (98), 25, (64, 0), 48);
+ Add_Action (Table.States (98), 26, (63, 0), 49);
+ Add_Action (Table.States (98), 27, (62, 0), 50);
+ Add_Action (Table.States (98), 30, Reduce, (56, 2), 2);
+ Add_Action (Table.States (98), 36, Reduce, (56, 2), 2);
+ Add_Action (Table.States (98), 39, (59, 1), 51);
+ Add_Conflict (Table.States (98), 39, (56, 2), 2);
+ Add_Action (Table.States (98), 41, (61, 1), 52);
+ Add_Action (Table.States (98), 42, Reduce, (56, 2), 2);
+ Table.States (98).Goto_List.Set_Capacity (5);
+ Add_Goto (Table.States (98), 59, 100);
+ Add_Goto (Table.States (98), 61, 58);
+ Add_Goto (Table.States (98), 62, 59);
+ Add_Goto (Table.States (98), 63, 60);
+ Add_Goto (Table.States (98), 64, 61);
+ Table.States (99).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (99), 19, (56, 5), 127);
+ Add_Action (Table.States (99), 20, Reduce, (56, 3), 2);
+ Add_Action (Table.States (99), 30, Reduce, (56, 3), 2);
+ Add_Action (Table.States (99), 36, Reduce, (56, 3), 2);
+ Add_Action (Table.States (99), 39, Reduce, (56, 3), 2);
+ Add_Action (Table.States (99), 42, Reduce, (56, 3), 2);
+ Table.States (100).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (100), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (60, 0), 2);
+ Table.States (101).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (101), (30, 39, 42), (53, 3), 4);
+ Table.States (102).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (102), 39, (57, 0), 128);
+ Table.States (103).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (103), 20, (55, 1), 94);
+ Add_Action (Table.States (103), 30, (55, 2), 95);
+ Add_Conflict (Table.States (103), 30, (54, 1), 0);
+ Add_Action (Table.States (103), 36, (54, 0), 96);
+ Add_Action (Table.States (103), 39, Reduce, (54, 1), 0);
+ Add_Action (Table.States (103), 42, Reduce, (54, 1), 0);
+ Table.States (103).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (103), 54, 129);
+ Table.States (104).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (104), 20, (55, 1), 94);
+ Add_Action (Table.States (104), 30, (55, 2), 95);
+ Add_Conflict (Table.States (104), 30, (54, 1), 0);
+ Add_Action (Table.States (104), 36, (54, 0), 96);
+ Add_Action (Table.States (104), 39, Reduce, (54, 1), 0);
+ Add_Action (Table.States (104), 42, Reduce, (54, 1), 0);
+ Table.States (104).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (104), 54, 130);
+ Table.States (105).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (105), 39, (47, 0), 131);
+ Add_Action (Table.States (105), 41, (47, 1), 132);
+ Table.States (105).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (105), 47, 133);
+ Table.States (106).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (106), (13, 20), (46, 1), 3);
+ Table.States (107).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (107), 39, (47, 0), 131);
+ Add_Action (Table.States (107), 41, (47, 1), 132);
+ Table.States (107).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (107), 47, 134);
+ Table.States (108).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (108), (20, 30, 36, 39, 42), (50, 0), 1);
+ Table.States (109).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (109), 20, (50, 1), 135);
+ Add_Action (Table.States (109), 30, Reduce, (48, 15), 5);
+ Add_Action (Table.States (109), 39, Reduce, (48, 15), 5);
+ Add_Action (Table.States (109), 42, Reduce, (48, 15), 5);
+ Table.States (110).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (110), (30, 39, 42), (48, 14), 5);
+ Table.States (111).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (111), 20, (50, 1), 135);
+ Add_Action (Table.States (111), 30, Reduce, (48, 13), 5);
+ Add_Action (Table.States (111), 39, Reduce, (48, 13), 5);
+ Add_Action (Table.States (111), 42, Reduce, (48, 13), 5);
+ Table.States (112).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (112), (30, 39, 42), (48, 12), 5);
+ Table.States (113).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (113), 39, (48, 2), 136);
+ Table.States (114).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (114), 39, (48, 0), 137);
Table.States (115).Action_List.Set_Capacity (4);
- Add_Action (Table.States (115), (21, 30, 39, 42), (47, 1), 1);
- Table.States (116).Action_List.Set_Capacity (3);
- Add_Action (Table.States (116), (30, 39, 42), (48, 7), 6);
- Table.States (117).Action_List.Set_Capacity (1);
- Add_Action (Table.States (117), 21, (48, 8), 130);
- Table.States (118).Action_List.Set_Capacity (1);
- Add_Action (Table.States (118), 39, (50, 1), 131);
- Table.States (119).Action_List.Set_Capacity (6);
- Add_Action (Table.States (119), 18, (44, 0), 35);
- Add_Action (Table.States (119), 30, Reduce, (48, 4), 6);
- Add_Action (Table.States (119), 39, Reduce, (48, 4), 6);
- Add_Action (Table.States (119), 40, (44, 1), 38);
- Add_Action (Table.States (119), 41, (44, 2), 39);
- Add_Action (Table.States (119), 42, Reduce, (48, 4), 6);
- Table.States (119).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (119), 44, 132);
- Table.States (120).Action_List.Set_Capacity (3);
- Add_Action (Table.States (120), 18, (44, 0), 35);
- Add_Action (Table.States (120), 40, (44, 1), 38);
- Add_Action (Table.States (120), 41, (44, 2), 39);
- Table.States (120).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (120), 44, 133);
- Table.States (121).Action_List.Set_Capacity (10);
- Add_Action (Table.States (121), 20, Reduce, (64, 1), 3);
- Add_Action (Table.States (121), 25, (63, 0), 43);
- Add_Action (Table.States (121), 26, (62, 0), 44);
- Add_Action (Table.States (121), 27, (61, 0), 45);
- Add_Action (Table.States (121), 28, (57, 0), 46);
- Add_Action (Table.States (121), 33, Reduce, (64, 1), 3);
- Add_Action (Table.States (121), 34, Reduce, (64, 1), 3);
- Add_Action (Table.States (121), 35, Reduce, (64, 1), 3);
- Add_Action (Table.States (121), 39, (58, 1), 47);
- Add_Action (Table.States (121), 41, (60, 1), 48);
- Table.States (121).Goto_List.Set_Capacity (6);
- Add_Goto (Table.States (121), 57, 51);
- Add_Goto (Table.States (121), 58, 90);
- Add_Goto (Table.States (121), 60, 54);
- Add_Goto (Table.States (121), 61, 55);
- Add_Goto (Table.States (121), 62, 56);
- Add_Goto (Table.States (121), 63, 57);
- Table.States (122).Action_List.Set_Capacity (14);
- Add_Action (Table.States (122), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (63, 1), 4);
- Table.States (123).Action_List.Set_Capacity (14);
- Add_Action (Table.States (123), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (63, 2), 4);
- Table.States (124).Action_List.Set_Capacity (14);
- Add_Action (Table.States (124), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (62, 1), 4);
- Table.States (125).Action_List.Set_Capacity (14);
- Add_Action (Table.States (125), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (63, 3), 4);
- Table.States (126).Action_List.Set_Capacity (1);
- Add_Action (Table.States (126), 24, (57, 0), 134);
- Table.States (127).Action_List.Set_Capacity (5);
- Add_Action (Table.States (127), (20, 30, 36, 39, 42), (55, 6), 4);
- Table.States (128).Action_List.Set_Capacity (2);
- Add_Action (Table.States (128), 10, (55, 5), 135);
- Add_Action (Table.States (128), 23, (55, 4), 136);
- Table.States (129).Action_List.Set_Capacity (2);
- Add_Action (Table.States (129), 10, (55, 3), 137);
- Add_Action (Table.States (129), 23, (55, 2), 138);
- Table.States (130).Action_List.Set_Capacity (1);
- Add_Action (Table.States (130), 39, (48, 8), 139);
- Table.States (131).Action_List.Set_Capacity (5);
- Add_Action (Table.States (131), (20, 30, 36, 39, 42), (50, 1), 3);
+ Add_Action (Table.States (115), 20, (66, 0), 117);
+ Add_Action (Table.States (115), 33, Reduce, (65, 0), 2);
+ Add_Action (Table.States (115), 34, Reduce, (65, 0), 2);
+ Add_Action (Table.States (115), 35, Reduce, (65, 0), 2);
+ Table.States (116).Action_List.Set_Capacity (14);
+ Add_Action (Table.States (116), 19, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 20, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 25, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 26, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 27, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 29, (64, 1), 138);
+ Add_Action (Table.States (116), 30, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 33, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 34, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 35, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 36, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 39, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 41, Reduce, (64, 0), 3);
+ Add_Action (Table.States (116), 42, Reduce, (64, 0), 3);
end Subr_2;
procedure Subr_3
is begin
- Table.States (132).Action_List.Set_Capacity (6);
- Add_Action (Table.States (132), 18, (44, 0), 35);
- Add_Action (Table.States (132), 30, Reduce, (48, 3), 7);
- Add_Action (Table.States (132), 39, Reduce, (48, 3), 7);
- Add_Action (Table.States (132), 40, (44, 1), 38);
- Add_Action (Table.States (132), 41, (44, 2), 39);
- Add_Action (Table.States (132), 42, Reduce, (48, 3), 7);
- Table.States (132).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (132), 44, 140);
- Table.States (133).Action_List.Set_Capacity (6);
- Add_Action (Table.States (133), 18, (44, 0), 35);
- Add_Action (Table.States (133), 30, Reduce, (48, 1), 7);
- Add_Action (Table.States (133), 39, Reduce, (48, 1), 7);
- Add_Action (Table.States (133), 40, (44, 1), 38);
- Add_Action (Table.States (133), 41, (44, 2), 39);
- Add_Action (Table.States (133), 42, Reduce, (48, 1), 7);
- Table.States (133).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (133), 44, 141);
- Table.States (134).Action_List.Set_Capacity (14);
- Add_Action (Table.States (134), (19, 20, 25, 26, 27, 28, 30, 33, 34, 35, 36, 39, 41, 42), (57, 0), 5);
+ Table.States (117).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (117), 25, (64, 0), 48);
+ Add_Action (Table.States (117), 26, (63, 0), 49);
+ Add_Action (Table.States (117), 27, (62, 0), 50);
+ Add_Action (Table.States (117), 39, (59, 1), 51);
+ Add_Action (Table.States (117), 41, (61, 1), 52);
+ Table.States (117).Goto_List.Set_Capacity (6);
+ Add_Goto (Table.States (117), 59, 56);
+ Add_Goto (Table.States (117), 60, 139);
+ Add_Goto (Table.States (117), 61, 58);
+ Add_Goto (Table.States (117), 62, 59);
+ Add_Goto (Table.States (117), 63, 60);
+ Add_Goto (Table.States (117), 64, 61);
+ Table.States (118).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (118), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (63, 0), 3);
+ Table.States (119).Action_List.Set_Capacity (16);
+ Add_Action (Table.States (119), 19, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 20, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 25, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 26, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 27, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 30, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 31, (64, 2), 140);
+ Add_Action (Table.States (119), 32, (63, 1), 141);
+ Add_Action (Table.States (119), 33, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 34, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 35, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 36, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 37, (64, 3), 142);
+ Add_Action (Table.States (119), 39, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 41, Reduce, (62, 0), 3);
+ Add_Action (Table.States (119), 42, Reduce, (62, 0), 3);
+ Table.States (120).Action_List.Set_Capacity (16);
+ Add_Action (Table.States (120), 19, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 20, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 25, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 26, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 27, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 30, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 31, (64, 4), 90);
+ Add_Action (Table.States (120), 32, (63, 2), 91);
+ Add_Action (Table.States (120), 33, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 34, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 35, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 36, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 37, (64, 5), 92);
+ Add_Action (Table.States (120), 39, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 41, Reduce, (61, 0), 1);
+ Add_Action (Table.States (120), 42, Reduce, (61, 0), 1);
+ Table.States (121).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (121), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (59, 1), 3);
+ Table.States (122).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (122), (20, 30, 36, 39, 42), (55, 1), 3);
+ Table.States (123).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (123), 9, (55, 6), 143);
+ Table.States (124).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (124), 39, (55, 4), 144);
+ Table.States (125).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (125), 39, (55, 2), 145);
+ Table.States (126).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (126), 19, (56, 6), 146);
+ Add_Action (Table.States (126), 20, Reduce, (56, 4), 3);
+ Add_Action (Table.States (126), 30, Reduce, (56, 4), 3);
+ Add_Action (Table.States (126), 36, Reduce, (56, 4), 3);
+ Add_Action (Table.States (126), 39, Reduce, (56, 4), 3);
+ Add_Action (Table.States (126), 42, Reduce, (56, 4), 3);
+ Table.States (127).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (127), (20, 30, 36, 39, 42), (56, 5), 3);
+ Table.States (128).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (128), 24, (57, 0), 147);
+ Table.States (129).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (129), (30, 39, 42), (53, 1), 5);
+ Table.States (130).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (130), (30, 39, 42), (53, 2), 5);
+ Table.States (131).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (131), (21, 30, 39, 42), (47, 0), 1);
+ Table.States (132).Action_List.Set_Capacity (4);
+ Add_Action (Table.States (132), (21, 30, 39, 42), (47, 1), 1);
+ Table.States (133).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (133), (30, 39, 42), (48, 8), 6);
+ Table.States (134).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (134), 21, (48, 9), 148);
Table.States (135).Action_List.Set_Capacity (1);
- Add_Action (Table.States (135), 39, (50, 0), 95);
- Table.States (135).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (135), 50, 142);
- Table.States (136).Action_List.Set_Capacity (1);
- Add_Action (Table.States (136), 39, (55, 4), 143);
- Table.States (137).Action_List.Set_Capacity (1);
- Add_Action (Table.States (137), 39, (50, 0), 95);
+ Add_Action (Table.States (135), 39, (50, 1), 149);
+ Table.States (136).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (136), 18, (44, 0), 40);
+ Add_Action (Table.States (136), 30, Reduce, (48, 4), 6);
+ Add_Action (Table.States (136), 39, Reduce, (48, 4), 6);
+ Add_Action (Table.States (136), 40, (44, 1), 43);
+ Add_Action (Table.States (136), 41, (44, 2), 44);
+ Add_Action (Table.States (136), 42, Reduce, (48, 4), 6);
+ Table.States (136).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (136), 44, 150);
+ Table.States (137).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (137), 18, (44, 0), 40);
+ Add_Action (Table.States (137), 40, (44, 1), 43);
+ Add_Action (Table.States (137), 41, (44, 2), 44);
Table.States (137).Goto_List.Set_Capacity (1);
- Add_Goto (Table.States (137), 50, 144);
- Table.States (138).Action_List.Set_Capacity (1);
- Add_Action (Table.States (138), 39, (55, 2), 145);
- Table.States (139).Action_List.Set_Capacity (3);
- Add_Action (Table.States (139), (30, 39, 42), (48, 8), 8);
- Table.States (140).Action_List.Set_Capacity (3);
- Add_Action (Table.States (140), (30, 39, 42), (48, 2), 8);
- Table.States (141).Action_List.Set_Capacity (3);
- Add_Action (Table.States (141), (30, 39, 42), (48, 0), 8);
- Table.States (142).Action_List.Set_Capacity (5);
- Add_Action (Table.States (142), 20, (50, 1), 118);
- Add_Conflict (Table.States (142), 20, (55, 5), 6);
- Add_Action (Table.States (142), 30, Reduce, (55, 5), 6);
- Add_Action (Table.States (142), 36, Reduce, (55, 5), 6);
- Add_Action (Table.States (142), 39, Reduce, (55, 5), 6);
- Add_Action (Table.States (142), 42, Reduce, (55, 5), 6);
+ Add_Goto (Table.States (137), 44, 151);
+ Table.States (138).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (138), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (64, 1), 4);
+ Table.States (139).Action_List.Set_Capacity (9);
+ Add_Action (Table.States (139), 20, Reduce, (66, 0), 3);
+ Add_Action (Table.States (139), 25, (64, 0), 48);
+ Add_Action (Table.States (139), 26, (63, 0), 49);
+ Add_Action (Table.States (139), 27, (62, 0), 50);
+ Add_Action (Table.States (139), 33, Reduce, (66, 0), 3);
+ Add_Action (Table.States (139), 34, Reduce, (66, 0), 3);
+ Add_Action (Table.States (139), 35, Reduce, (66, 0), 3);
+ Add_Action (Table.States (139), 39, (59, 1), 51);
+ Add_Action (Table.States (139), 41, (61, 1), 52);
+ Table.States (139).Goto_List.Set_Capacity (5);
+ Add_Goto (Table.States (139), 59, 100);
+ Add_Goto (Table.States (139), 61, 58);
+ Add_Goto (Table.States (139), 62, 59);
+ Add_Goto (Table.States (139), 63, 60);
+ Add_Goto (Table.States (139), 64, 61);
+ Table.States (140).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (140), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (64, 2), 4);
+ Table.States (141).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (141), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (63, 1), 4);
+ Table.States (142).Action_List.Set_Capacity (13);
+ Add_Action (Table.States (142), (19, 20, 25, 26, 27, 30, 33, 34, 35, 36, 39, 41, 42), (64, 3), 4);
Table.States (143).Action_List.Set_Capacity (5);
- Add_Action (Table.States (143), (20, 30, 36, 39, 42), (55, 4), 6);
- Table.States (144).Action_List.Set_Capacity (5);
- Add_Action (Table.States (144), 20, (50, 1), 118);
- Add_Conflict (Table.States (144), 20, (55, 3), 6);
- Add_Action (Table.States (144), 30, Reduce, (55, 3), 6);
- Add_Action (Table.States (144), 36, Reduce, (55, 3), 6);
- Add_Action (Table.States (144), 39, Reduce, (55, 3), 6);
- Add_Action (Table.States (144), 42, Reduce, (55, 3), 6);
- Table.States (145).Action_List.Set_Capacity (5);
- Add_Action (Table.States (145), (20, 30, 36, 39, 42), (55, 2), 6);
+ Add_Action (Table.States (143), (20, 30, 36, 39, 42), (55, 6), 4);
+ Table.States (144).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (144), 10, (55, 5), 152);
+ Add_Action (Table.States (144), 23, (55, 4), 153);
+ Table.States (145).Action_List.Set_Capacity (2);
+ Add_Action (Table.States (145), 10, (55, 3), 154);
+ Add_Action (Table.States (145), 23, (55, 2), 155);
+ Table.States (146).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (146), (20, 30, 36, 39, 42), (56, 6), 4);
+ Table.States (147).Action_List.Set_Capacity (8);
+ Add_Action (Table.States (147), (21, 22, 25, 26, 27, 28, 39, 41), (57, 0), 5);
+ Table.States (148).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (148), 39, (48, 9), 156);
+ Table.States (149).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (149), (20, 30, 36, 39, 42), (50, 1), 3);
+ Table.States (150).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (150), 18, (44, 0), 40);
+ Add_Action (Table.States (150), 30, Reduce, (48, 3), 7);
+ Add_Action (Table.States (150), 39, Reduce, (48, 3), 7);
+ Add_Action (Table.States (150), 40, (44, 1), 43);
+ Add_Action (Table.States (150), 41, (44, 2), 44);
+ Add_Action (Table.States (150), 42, Reduce, (48, 3), 7);
+ Table.States (150).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (150), 44, 157);
+ Table.States (151).Action_List.Set_Capacity (6);
+ Add_Action (Table.States (151), 18, (44, 0), 40);
+ Add_Action (Table.States (151), 30, Reduce, (48, 1), 7);
+ Add_Action (Table.States (151), 39, Reduce, (48, 1), 7);
+ Add_Action (Table.States (151), 40, (44, 1), 43);
+ Add_Action (Table.States (151), 41, (44, 2), 44);
+ Add_Action (Table.States (151), 42, Reduce, (48, 1), 7);
+ Table.States (151).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (151), 44, 158);
+ Table.States (152).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (152), 39, (50, 0), 108);
+ Table.States (152).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (152), 50, 159);
+ Table.States (153).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (153), 39, (55, 4), 160);
+ Table.States (154).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (154), 39, (50, 0), 108);
+ Table.States (154).Goto_List.Set_Capacity (1);
+ Add_Goto (Table.States (154), 50, 161);
+ Table.States (155).Action_List.Set_Capacity (1);
+ Add_Action (Table.States (155), 39, (55, 2), 162);
+ Table.States (156).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (156), (30, 39, 42), (48, 9), 8);
+ Table.States (157).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (157), (30, 39, 42), (48, 2), 8);
+ Table.States (158).Action_List.Set_Capacity (3);
+ Add_Action (Table.States (158), (30, 39, 42), (48, 0), 8);
+ Table.States (159).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (159), 20, (50, 1), 135);
+ Add_Conflict (Table.States (159), 20, (55, 5), 6);
+ Add_Action (Table.States (159), 30, Reduce, (55, 5), 6);
+ Add_Action (Table.States (159), 36, Reduce, (55, 5), 6);
+ Add_Action (Table.States (159), 39, Reduce, (55, 5), 6);
+ Add_Action (Table.States (159), 42, Reduce, (55, 5), 6);
+ Table.States (160).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (160), (20, 30, 36, 39, 42), (55, 4), 6);
+ Table.States (161).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (161), 20, (50, 1), 135);
+ Add_Conflict (Table.States (161), 20, (55, 3), 6);
+ Add_Action (Table.States (161), 30, Reduce, (55, 3), 6);
+ Add_Action (Table.States (161), 36, Reduce, (55, 3), 6);
+ Add_Action (Table.States (161), 39, Reduce, (55, 3), 6);
+ Add_Action (Table.States (161), 42, Reduce, (55, 3), 6);
+ Table.States (162).Action_List.Set_Capacity (5);
+ Add_Action (Table.States (162), (20, 30, 36, 39, 42), (55, 2), 6);
end Subr_3;
begin
Subr_1;
@@ -964,8 +1115,8 @@ package body Wisitoken_Grammar_Main is
function Create_Productions return WisiToken.Syntax_Trees.Production_Info_Trees.Vector
is begin
return Result : WisiToken.Syntax_Trees.Production_Info_Trees.Vector do
- Result.Set_First_Last (43, 66);
- Result (48).RHSs.Set_First_Last (0, 15);
+ Result.Set_First_Last (43, 68);
+ Result (48).RHSs.Set_First_Last (0, 16);
Result (48).RHSs (0).In_Parse_Action := null;
Result (48).RHSs (0).Post_Parse_Action := declaration_0'Access;
Result (48).RHSs (1).In_Parse_Action := null;
@@ -998,33 +1149,37 @@ package body Wisitoken_Grammar_Main is
Result (48).RHSs (14).Post_Parse_Action := declaration_14'Access;
Result (48).RHSs (15).In_Parse_Action := null;
Result (48).RHSs (15).Post_Parse_Action := declaration_15'Access;
- Result (53).RHSs.Set_First_Last (0, 1);
+ Result (48).RHSs (16).In_Parse_Action := null;
+ Result (48).RHSs (16).Post_Parse_Action := declaration_16'Access;
+ Result (53).RHSs.Set_First_Last (0, 3);
Result (53).RHSs (0).In_Parse_Action := null;
Result (53).RHSs (0).Post_Parse_Action := nonterminal_0'Access;
Result (53).RHSs (1).In_Parse_Action := null;
Result (53).RHSs (1).Post_Parse_Action := nonterminal_1'Access;
- Result (60).RHSs.Set_First_Last (0, 5);
- Result (60).RHSs (0).In_Parse_Action := null;
- Result (60).RHSs (0).Post_Parse_Action := null;
- Result (60).RHSs (1).In_Parse_Action := null;
- Result (60).RHSs (1).Post_Parse_Action := rhs_item_1'Access;
- Result (60).RHSs (2).In_Parse_Action := null;
- Result (60).RHSs (2).Post_Parse_Action := rhs_item_2'Access;
- Result (60).RHSs (3).In_Parse_Action := null;
- Result (60).RHSs (3).Post_Parse_Action := rhs_item_3'Access;
- Result (60).RHSs (4).In_Parse_Action := null;
- Result (60).RHSs (4).Post_Parse_Action := rhs_item_4'Access;
- Result (60).RHSs (5).In_Parse_Action := null;
- Result (60).RHSs (5).Post_Parse_Action := rhs_item_5'Access;
- Result (62).RHSs.Set_First_Last (0, 3);
- Result (62).RHSs (0).In_Parse_Action := null;
- Result (62).RHSs (0).Post_Parse_Action := null;
- Result (62).RHSs (1).In_Parse_Action := null;
- Result (62).RHSs (1).Post_Parse_Action := null;
- Result (62).RHSs (2).In_Parse_Action := null;
- Result (62).RHSs (2).Post_Parse_Action := null;
- Result (62).RHSs (3).In_Parse_Action := null;
- Result (62).RHSs (3).Post_Parse_Action := rhs_optional_item_3'Access;
+ Result (53).RHSs (2).In_Parse_Action := null;
+ Result (53).RHSs (2).Post_Parse_Action := nonterminal_2'Access;
+ Result (53).RHSs (3).In_Parse_Action := null;
+ Result (53).RHSs (3).Post_Parse_Action := nonterminal_3'Access;
+ Result (61).RHSs.Set_First_Last (0, 4);
+ Result (61).RHSs (0).In_Parse_Action := null;
+ Result (61).RHSs (0).Post_Parse_Action := null;
+ Result (61).RHSs (1).In_Parse_Action := null;
+ Result (61).RHSs (1).Post_Parse_Action := rhs_item_1'Access;
+ Result (61).RHSs (2).In_Parse_Action := null;
+ Result (61).RHSs (2).Post_Parse_Action := rhs_item_2'Access;
+ Result (61).RHSs (3).In_Parse_Action := null;
+ Result (61).RHSs (3).Post_Parse_Action := rhs_item_3'Access;
+ Result (61).RHSs (4).In_Parse_Action := null;
+ Result (61).RHSs (4).Post_Parse_Action := rhs_item_4'Access;
+ Result (63).RHSs.Set_First_Last (0, 3);
+ Result (63).RHSs (0).In_Parse_Action := null;
+ Result (63).RHSs (0).Post_Parse_Action := null;
+ Result (63).RHSs (1).In_Parse_Action := null;
+ Result (63).RHSs (1).Post_Parse_Action := null;
+ Result (63).RHSs (2).In_Parse_Action := null;
+ Result (63).RHSs (2).Post_Parse_Action := null;
+ Result (63).RHSs (3).In_Parse_Action := null;
+ Result (63).RHSs (3).Post_Parse_Action := rhs_optional_item_3'Access;
end return;
end Create_Productions;
diff --git a/wisitoken_grammar_main.ads b/wisitoken_grammar_main.ads
index 1e7b6f9..c5a6cda 100644
--- a/wisitoken_grammar_main.ads
+++ b/wisitoken_grammar_main.ads
@@ -2,7 +2,7 @@
-- command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c PROCESS wisitoken_grammar.wy
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- Author: Stephen Leake <stephe-leake@stephe-leake.org>
--
@@ -19,7 +19,7 @@
-- 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/>.
+-- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
with WisiToken.Syntax_Trees;
with WisiToken.Parse.LR.Parser_No_Recover;
diff --git a/wisitoken_grammar_re2c.c b/wisitoken_grammar_re2c.c
index 712d5eb..23eebce 100644
--- a/wisitoken_grammar_re2c.c
+++ b/wisitoken_grammar_re2c.c
@@ -4,7 +4,7 @@
// command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c wisitoken_grammar.wy
//
-// Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+// Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
//
// Author: Stephen Leake <stephe-leake@stephe-leake.org>
//
@@ -21,7 +21,7 @@
// 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/>.
+// along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
#include <stddef.h>
#include <stdio.h>
diff --git a/wisitoken_grammar_re2c_c.ads b/wisitoken_grammar_re2c_c.ads
index c9d4c55..5807322 100644
--- a/wisitoken_grammar_re2c_c.ads
+++ b/wisitoken_grammar_re2c_c.ads
@@ -2,7 +2,7 @@
-- command line: wisitoken-bnf-generate.exe --generate LALR Ada re2c wisitoken_grammar.wy
--
--- Copyright (C) 2017 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2017 - 2023 Free Software Foundation, Inc.
--
-- Author: Stephen Leake <stephe-leake@stephe-leake.org>
--
@@ -19,7 +19,7 @@
-- 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/>.
+-- along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
with Interfaces.C;
with WisiToken;
diff --git a/wisitoken_grammar_runtime.adb b/wisitoken_grammar_runtime.adb
index 6639f88..8972f29 100644
--- a/wisitoken_grammar_runtime.adb
+++ b/wisitoken_grammar_runtime.adb
@@ -2,7 +2,7 @@
--
-- See spec.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -113,7 +113,7 @@ package body WisiToken_Grammar_Runtime is
function Get_RHS
(Data : in out User_Data_Type;
- Tree : in Syntax_Trees.Tree;
+ Tree : in out Syntax_Trees.Tree;
Labels : in out WisiToken.BNF.String_Arrays.Vector;
Token : in Syntax_Trees.Valid_Node_Access)
return WisiToken.BNF.RHS_Type
@@ -126,60 +126,108 @@ package body WisiToken_Grammar_Runtime is
return RHS : WisiToken.BNF.RHS_Type do
RHS.Source_Line := Tree.Line_Region (Token, Trailing_Non_Grammar => True).First;
- if Tree.Augmented (Token) /= null then
+ if Tree.Augmented (Token) = null then
+ RHS.Orig_EBNF_RHS := True;
+ else
declare
Aug : constant Augmented_Access := Augmented_Access (Tree.Augmented (Token));
begin
+ RHS.Orig_EBNF_RHS := Aug.Orig_EBNF_RHS;
+ RHS.EBNF_RHS_Index := Aug.EBNF_RHS_Index;
RHS.Auto_Token_Labels := Aug.Auto_Token_Labels;
- RHS.Edited_Token_List := Aug.Edited_Token_List;
end;
end if;
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
- (WisiToken.BNF.Labeled_Token'
- (Label => +"",
- Identifier => +Get_Text (Data, Tree, Tree.Child (I, 1))));
-
- when 1 =>
- -- IDENTIFIER = rhs_item
+ declare
+ use WisiToken.Syntax_Trees;
+
+ Attr_List : Node_Access := Invalid_Node_Access;
+ RHS_Item_List : Node_Access;
+ Action_1 : Node_Access := Invalid_Node_Access;
+ Action_2 : Node_Access := Invalid_Node_Access;
+ begin
+ if Tree.ID (Children (1)) = +rhs_item_list_ID then
+ RHS_Item_List := Children (1);
+ if Children'Last > 1 then
+ Action_1 := Children (2);
+ end if;
+ if Children'Last > 2 then
+ Action_2 := Children (3);
+ end if;
+
+ else
+ Attr_List := Children (1);
+ RHS_Item_List := Children (2);
+ if Children'Last > 2 then
+ Action_1 := Children (3);
+ end if;
+ if Children'Last > 3 then
+ Action_2 := Children (4);
+ end if;
+ end if;
+
+ RHS.Associativity := Get_Associativity (Data, Tree, Attr_List);
+ RHS.Precedence := Get_Precedence (Data, Tree, Attr_List);
+
+ for I of Tree.Get_IDs (RHS_Item_List, +rhs_element_ID) loop
declare
- Label : constant String := Get_Text (Data, Tree, Tree.Child (I, 1));
+ Orig_Token_Index : constant SAL.Base_Peek_Type :=
+ (if RHS.Orig_EBNF_RHS or Tree.Augmented (I) = null then 0
+ else WisiToken_Grammar_Runtime.Augmented (Tree.Augmented (I).all).Orig_Token_Index);
begin
- RHS.Tokens.Append
- (WisiToken.BNF.Labeled_Token'
- (Label => +Label,
- Identifier => +Get_Text (Data, Tree, Tree.Child (I, 3))));
+ -- We don't check for non-zero Orig_Token_Index here; that just
+ -- indicates it's a new item. See subprograms.wy compilation_unit.
- if (for all L of Labels => -L /= Label) then
- Labels.Append (+Label);
- end if;
- end;
+ case Tree.RHS_Index (I) is
+ when 0 =>
- when others =>
- WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error ("Get_RHS; unimplemented token", Tree, I);
- end case;
- end loop;
+ -- rhs_item
+ RHS.Tokens.Append
+ (WisiToken.BNF.Labeled_Token'
+ (Label => +"",
+ Orig_Token_Index => Orig_Token_Index,
+ Identifier => +Get_Text (Data, Tree, Tree.Child (I, 1))));
- 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;
+ when 1 =>
+ -- IDENTIFIER = rhs_item
+ declare
+ Label : constant String := Get_Text (Data, Tree, Tree.Child (I, 1));
+ begin
+ RHS.Tokens.Append
+ (WisiToken.BNF.Labeled_Token'
+ (Label => +Label,
+ Orig_Token_Index => Orig_Token_Index,
+ Identifier => +Get_Text (Data, Tree, Tree.Child (I, 3))));
+
+ if (for all L of Labels => -L /= Label) then
+ Labels.Append (+Label);
+ end if;
+ end;
- if Children'Last >= 3 then
- RHS.Check := +Get_Text (Data, Tree, Children (3));
- Data.Check_Count := Data.Check_Count + 1;
- end if;
+ when others =>
+ WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error
+ ("Get_RHS; unimplemented token", Tree, I);
+ end case;
+ end;
+ end loop;
+
+ if Action_1 /= Invalid_Node_Access then
+ declare
+ Text : constant String := Get_Text (Data, Tree, Action_1);
+ begin
+ if Text'Length > 0 and (for some C of Text => C /= ' ') then
+ RHS.Post_Parse_Action := +Text;
+ Data.Post_Parse_Action_Count := Data.Post_Parse_Action_Count + 1;
+ end if;
+ end;
+ end if;
+
+ if Action_2 /= Invalid_Node_Access then
+ RHS.In_Parse_Action := +Get_Text (Data, Tree, Action_2);
+ Data.In_Parse_Action_Count := Data.In_Parse_Action_Count + 1;
+ end if;
+ end;
end if;
end return;
exception
@@ -194,7 +242,12 @@ package body WisiToken_Grammar_Runtime is
begin
WisiToken.Syntax_Trees.LR_Utils.Raise_Programmer_Error
("Get_RHS: " & Exception_Name (E) & ": " & Exception_Message (E), Tree, Token);
- raise; -- WORKAROUND; GNAT pro_22.0w-20201222 ignores 'pragma no_return' on Raise_Programmer_Error
+
+ -- WORKAROUND; GNAT pro_22.0w-20201222 ignores 'pragma
+ -- no_return' on Raise_Programmer_Error; uncomment 'raise' for that
+ -- compiler.
+ --
+ -- raise;
end;
end if;
end Get_RHS;
@@ -250,47 +303,74 @@ package body WisiToken_Grammar_Runtime is
overriding
function Copy_Augmented
(User_Data : in User_Data_Type;
- Augmented : in WisiToken.Syntax_Trees.Augmented_Class_Access)
+ Augmented : in not null WisiToken.Syntax_Trees.Augmented_Class_Access)
return WisiToken.Syntax_Trees.Augmented_Class_Access
is
Old_Aug : WisiToken_Grammar_Runtime.Augmented renames Augmented_Access (Augmented).all;
- New_Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'
- (Old_Aug.EBNF, Old_Aug.Auto_Token_Labels, Old_Aug.Edited_Token_List);
+ New_Aug : constant Augmented_Access := new WisiToken_Grammar_Runtime.Augmented'(Old_Aug);
begin
return WisiToken.Syntax_Trees.Augmented_Class_Access (New_Aug);
end Copy_Augmented;
- overriding procedure Reset (Data : in out User_Data_Type)
+ overriding
+ function Image_Augmented (Item : in Augmented) return String
+ -- This is for debugging, so it is only updated to match current code
+ -- when needed for a debugging session.
+ is
+ use all type SAL.Base_Peek_Type;
+ begin
+ return
+ "(" &
+ (if Item.EBNF then "EBNF, " else "") &
+ (if Item.Auto_Token_Labels then "Auto_Token_Labels, " else "") &
+ (if Item.Orig_EBNF_RHS then "Orig_EBNF_RHS, " else "") &
+ (if not Item.Orig_EBNF_RHS and Item.EBNF_RHS_Index /= Natural'Last
+ then "EBNF_RHS_Index =>" & Item.EBNF_RHS_Index'Image & ", "
+ else "") &
+ (if Item.Orig_Token_Index /= 0 then "Orig_Token_Index =>" & Item.Orig_Token_Index'Image & ", " else "") &
+ ")";
+ end Image_Augmented;
+
+ procedure Reset
+ (Data : in out User_Data_Type;
+ User_Lexer : in WisiToken.BNF.Lexer_Type;
+ User_Parser : in WisiToken.BNF.Generate_Algorithm;
+ Phase : in Action_Phase)
is begin
- -- Preserve data set in Phase Meta, or by Set_Lexer_Terminals, or by
- -- wisitoken-bnf-generate.
-
- -- Preserve Lexer
- -- Preserve User_Lexer
- -- Preserve User_Parser
- -- Perserve Generate_Set
- -- Preserve Meta_Syntax
- -- Preserve Phase
- -- Preserve Terminals
- -- Preserve Non_Grammar
- Data.Raw_Code := (others => <>);
- Data.Language_Params :=
- (Case_Insensitive => Data.Language_Params.Case_Insensitive,
- Error_Recover => Data.Language_Params.Error_Recover,
- others => <>);
- Data.Tokens :=
+ Data.User_Parser := User_Parser;
+ Data.User_Lexer := User_Lexer;
+ Data.Phase := Phase;
+
+ if Phase = Meta then
+ WisiToken.BNF.Free (Data.Generate_Set);
+ Data.EBNF_Ok := False;
+ Data.Meta_Syntax := Unknown;
+ Data.Precedence_Map.Clear;
+ Data.Precedence_Inverse_Map.Clear;
+ Data.Precedence_Lists.Clear;
+ end if;
+
+ Data.Raw_Code := (others => <>);
+
+ Data.Language_Params :=
+ (Case_Insensitive => Data.Language_Params.Case_Insensitive,
+ Error_Recover => Data.Language_Params.Error_Recover,
+ others => <>);
+
+ Data.Tokens :=
(Virtual_Identifiers => Data.Tokens.Virtual_Identifiers,
- others => <>);
+ others => <>);
+
Data.Suppress.Clear;
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;
+ Data.McKenzie_Recover := (others => <>);
+ Data.Rule_Count := 0;
+ Data.Post_Parse_Action_Count := 0;
+ Data.In_Parse_Action_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
@@ -420,7 +500,7 @@ package body WisiToken_Grammar_Runtime is
end if;
for I in 3 .. SAL.Base_Peek_Type (Children'Length) loop
declare
- Text : constant String := Get_Text (Data, Tree, Children (I));
+ Text : constant String := WisiToken.BNF.To_Lower (Get_Text (Data, Tree, Children (I)));
begin
if Text = "text_rep" then
Tuple.Text_Rep := True;
@@ -459,6 +539,34 @@ package body WisiToken_Grammar_Runtime is
end if;
end;
end if;
+
+ elsif Kind = "precedence" then
+ -- Translate_To_BNF needs this done.
+ declare
+ use WisiToken.Syntax_Trees.LR_Utils;
+ Name_List : constant Constant_List := Creators.Create_List
+ (Tree, Tree.Child (Nonterm, 3), +declaration_item_list_ID, +declaration_item_ID);
+ P_List : WisiToken.Precedence_Lists.List;
+ begin
+ for Item of Name_List loop
+ declare
+ Name : constant String := Get_Text (Data, Tree, Item);
+ Found : constant Precedence_Maps.Cursor := Data.Precedence_Map.Find (Name);
+ P_ID : WisiToken.Precedence_ID;
+ begin
+ if not Precedence_Maps.Has_Element (Found) then
+ P_ID := 1 + WisiToken.Base_Precedence_ID (Data.Precedence_Map.Length);
+ Data.Precedence_Map.Insert (Name, P_ID);
+ Data.Precedence_Inverse_Map.Append (+Name);
+ else
+ P_ID := Data.Precedence_Map (Found);
+ end if;
+ P_List.Append (P_ID);
+ end;
+ end loop;
+ Data.Precedence_Lists.Append (P_List);
+ end;
+
end if;
end;
when others =>
@@ -532,41 +640,7 @@ package body WisiToken_Grammar_Runtime is
-- identifier_list children = identifier_list IDENTIFIER_ID
-- children = identifier_list IDENTIFIER_ID
-- children = IDENTIFIER_ID
- function Get_Loc_List return Syntax_Trees.Valid_Node_Access_Array
- with Pre => Tree.ID (Tree.Child (Nonterm, 3)) = +identifier_list_ID
- is
- use WisiToken.Syntax_Trees;
- Node : Valid_Node_Access := Tree.Child (Nonterm, 3);
- Result : Valid_Node_Access_Array (1 .. 3) := (others => Dummy_Node);
- 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 Node_Access_Array := Tree.Children (Node);
- begin
- if Children'Length = 1 then
- -- identifier_list : IDENTIFIER
- First := First - 1;
- Result (First) := Children (1);
- exit;
-
- elsif Children'Length = 2 then
- -- identifier_list : identifier_list IDENTIFIER
- First := First - 1;
- Result (First) := 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 Syntax_Trees.Valid_Node_Access_Array := Get_Loc_List;
+ Loc_List : constant Syntax_Trees.Valid_Node_Access_Array := Get_Code_Location_List (Tree, Nonterm);
function Get_Loc (Index : in SAL.Peek_Type) return String
is (Tree.Lexer.Buffer_Text (Tree.Byte_Region (Loc_List (Index), Trailing_Non_Grammar => False)));
@@ -609,7 +683,8 @@ package body WisiToken_Grammar_Runtime is
-- % CONFLICT conflict_item_list ON TOKEN on_symbol [: resolution]
-- 1 2 3 4 5 6 7 8
--
- -- conflict_item_list : [action] LHS (| [action] LHS)*
+ -- conflict_item_list : action LHS (| action LHS)*
+ -- conflict_item_list : LHS*
Conflict_Items : constant Syntax_Trees.Valid_Node_Access_Array := Tree.Get_Terminals
(Tree.Child (Nonterm, 3));
@@ -815,6 +890,10 @@ package body WisiToken_Grammar_Runtime is
elsif Kind = "partial_recursion" then
Data.Language_Params.Recursion_Strategy := Partial;
+ elsif Kind = "precedence" then
+ -- Done in meta phase
+ null;
+
elsif Kind = "start" then
Data.Language_Params.Start_Token := +Get_Text (Data, Tree, Tree.Child (Nonterm, 3));
@@ -852,6 +931,11 @@ package body WisiToken_Grammar_Runtime is
LHS_Node : constant Valid_Node_Access := Tree.Child (Nonterm, 1);
LHS_String : constant String := Get_Text (Data, Tree, LHS_Node);
+ Attr_List : constant Node_Access :=
+ (if Tree.ID (Tree.Child (Nonterm, 2)) = +attribute_list_ID
+ then Tree.Child (Nonterm, 2)
+ else Invalid_Node_Access);
+
Right_Hand_Sides : WisiToken.BNF.RHS_Lists.List;
Labels : WisiToken.BNF.String_Arrays.Vector;
@@ -983,7 +1067,9 @@ package body WisiToken_Grammar_Runtime is
Data.Rule_Count := Data.Rule_Count + 1;
- Get_Right_Hand_Sides (Data, Tree, Right_Hand_Sides, Labels, Tree.Child (Nonterm, 3));
+ Get_Right_Hand_Sides
+ (Data, Tree, Right_Hand_Sides, Labels, Tree.Child
+ (Nonterm, (if Attr_List = Invalid_Node_Access then 3 else 4)));
if WisiToken.BNF.Is_Present (Data.Tokens.Rules, LHS_String) then
case Tree.Label (LHS_Node) is
@@ -999,14 +1085,22 @@ package body WisiToken_Grammar_Runtime is
else
Data.Label_Count := Data.Label_Count + Labels.Length;
- Data.Tokens.Rules.Append
- ((+LHS_String, Right_Hand_Sides, Labels,
- Optimized_List => Is_Optimized_List,
- Source_Line =>
- (case Tree.Label (LHS_Node) is
- when Source_Terminal => Tree.Line_Region (LHS_Node, Trailing_Non_Grammar => True).First,
- when Virtual_Identifier => Line_Number_Type'First, -- IMPROVEME: get line from Right_Hand_Sides
- when others => raise SAL.Programmer_Error)));
+ declare
+ -- Work around "unspecified order" warning; Tree is 'in out' in Get_Precedence.
+ Prec : constant WisiToken.Base_Precedence_ID := Get_Precedence (Data, Tree, Attr_List);
+ begin
+ Data.Tokens.Rules.Append
+ ((Left_Hand_Side => +LHS_String,
+ Precedence => Prec,
+ Right_Hand_Sides => Right_Hand_Sides,
+ Labels => Labels,
+ Optimized_List => Is_Optimized_List,
+ Source_Line =>
+ (case Tree.Label (LHS_Node) is
+ when Source_Terminal => Tree.Line_Region (LHS_Node, Trailing_Non_Grammar => True).First,
+ when Virtual_Identifier => Line_Number_Type'First, -- IMPROVEME: get line from Right_Hand_Sides
+ when others => raise SAL.Programmer_Error)));
+ end;
end if;
end Add_Nonterminal;
@@ -1037,6 +1131,80 @@ package body WisiToken_Grammar_Runtime is
end case;
end Check_EBNF;
+ function Get_Associativity
+ (Data : in User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access)
+ return WisiToken.Associativity
+ is
+ use WisiToken.Syntax_Trees;
+ begin
+ if Attr_List = Invalid_Node_Access then
+ return WisiToken.None;
+ else
+ declare
+ List : constant LR_Utils.Constant_List := LR_Utils.Creators.Create_List
+ (Tree => Tree,
+ Root => Attr_List,
+ List_ID => +attribute_list_ID,
+ Element_ID => +attribute_ID);
+ begin
+ for Attr of List loop
+ if Get_Text (Data, Tree, Tree.Child (Attr, 2)) = "assoc" then
+ declare
+ Name : constant String := Get_Text (Data, Tree, Tree.Child (Attr, 4));
+ begin
+ return WisiToken.Associativity'Value (Name);
+ exception
+ when Constraint_Error =>
+ Put_Error
+ (Tree.Error_Message
+ (Attr_List, "invalid associativity name '" & Name & "'; must be 'left' or 'right'"));
+ end;
+ end if;
+ end loop;
+ end;
+ return WisiToken.None;
+ end if;
+ end Get_Associativity;
+
+ function Get_Precedence
+ (Data : in User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access)
+ return WisiToken.Base_Precedence_ID
+ is
+ use WisiToken.Syntax_Trees;
+ begin
+ if Attr_List = Invalid_Node_Access then
+ return WisiToken.No_Precedence;
+ else
+ declare
+ List : constant LR_Utils.Constant_List := LR_Utils.Creators.Create_List
+ (Tree => Tree,
+ Root => Attr_List,
+ List_ID => +attribute_list_ID,
+ Element_ID => +attribute_ID);
+ begin
+ for Attr of List loop
+ if Get_Text (Data, Tree, Tree.Child (Attr, 2)) = "prec" then
+ declare
+ Name : constant String := Get_Text (Data, Tree, Tree.Child (Attr, 4));
+ Found : constant WisiToken.Precedence_Maps.Cursor := Data.Precedence_Map.Find (Name);
+ begin
+ if WisiToken.Precedence_Maps.Has_Element (Found) then
+ return Data.Precedence_Map (Found);
+ else
+ Put_Error (Tree.Error_Message (Attr_List, "undeclared precedence name '" & Name & "'"));
+ end if;
+ end;
+ end if;
+ end loop;
+ end;
+ return WisiToken.No_Precedence;
+ end if;
+ end Get_Precedence;
+
function Get_Text
(Virtual_Identifiers : in WisiToken.BNF.String_Arrays.Vector;
Tree : in WisiToken.Syntax_Trees.Tree;
@@ -1054,7 +1222,7 @@ package body WisiToken_Grammar_Runtime is
-- Strip delimiters. We don't strip leading/trailing spaces to preserve indent.
return Tree.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
+ elsif -Tree.ID (Tree_Index) in STRING_LITERAL_DOUBLE_ID | STRING_LITERAL_SINGLE_ID and Strip_Quotes then
return Tree.Lexer.Buffer_Text ((Region.First + 1, Region.Last - 1));
else
return Tree.Lexer.Buffer_Text (Region);
@@ -1103,6 +1271,43 @@ package body WisiToken_Grammar_Runtime is
end case;
end Get_Text;
+ function Get_Code_Location_List
+ (Tree : in WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ return Syntax_Trees.Valid_Node_Access_Array
+ is
+ use all type SAL.Base_Peek_Type;
+ use WisiToken.Syntax_Trees;
+ Node : Valid_Node_Access := Tree.Child (Nonterm, 3);
+ Result : Valid_Node_Access_Array (1 .. 3) := (others => Dummy_Node);
+ 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 Node_Access_Array := Tree.Children (Node);
+ begin
+ if Children'Length = 1 then
+ -- identifier_list : IDENTIFIER
+ First := First - 1;
+ Result (First) := Children (1);
+ exit;
+
+ elsif Children'Length = 2 then
+ -- identifier_list : identifier_list IDENTIFIER
+ First := First - 1;
+ Result (First) := Children (2);
+
+ Node := Children (1);
+ else
+ raise SAL.Programmer_Error;
+ end if;
+ end;
+ end loop;
+ return Result (First .. Result'Last);
+ end Get_Code_Location_List;
+
end WisiToken_Grammar_Runtime;
-- Local Variables:
-- ada-case-strict: nil
diff --git a/wisitoken_grammar_runtime.ads b/wisitoken_grammar_runtime.ads
index 24fbe23..8b12178 100644
--- a/wisitoken_grammar_runtime.ads
+++ b/wisitoken_grammar_runtime.ads
@@ -2,7 +2,7 @@
--
-- Runtime utils for wisitoken_grammar.wy actions.
--
--- Copyright (C) 2018 - 2022 Free Software Foundation, Inc.
+-- Copyright (C) 2018 - 2023 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
@@ -23,6 +23,7 @@ with WisiToken.BNF;
with WisiToken.Syntax_Trees;
with Wisitoken_Grammar_Actions;
package WisiToken_Grammar_Runtime is
+ use all type WisiToken.Token_ID;
use all type WisiToken.Syntax_Trees.Node_Access;
use all type Wisitoken_Grammar_Actions.Token_Enum_ID;
@@ -41,18 +42,22 @@ package WisiToken_Grammar_Runtime is
-- Used to read the user language file; 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, %if, %generate
-- Other - everything else
+ Generate_Set : WisiToken.BNF.Generate_Set_Access;
+ -- As specified by %generate directives or command line.
+
EBNF_Ok : Boolean := False;
-- Set True when don't need to translate EBNF to BNF.
- Meta_Syntax : WisiToken_Grammar_Runtime.Meta_Syntax := Unknown;
+ Meta_Syntax : WisiToken_Grammar_Runtime.Meta_Syntax := Unknown;
+ Precedence_Map : WisiToken.Precedence_Maps.Map;
+ Precedence_Inverse_Map : WisiToken.Precedence_Inverse_Maps.Vector;
+ Precedence_Lists : WisiToken.Precedence_Lists_Arrays.Vector;
+
Raw_Code : WisiToken.BNF.Raw_Code;
Language_Params : WisiToken.BNF.Language_Param_Type;
Tokens : aliased WisiToken.BNF.Tokens;
@@ -60,14 +65,14 @@ package WisiToken_Grammar_Runtime is
Suppress : WisiToken.BNF.String_Pair_Lists.List;
-- Declaration name, warning label; suppress warnings.
- Conflicts : WisiToken.BNF.Conflict_Lists.List;
- McKenzie_Recover : WisiToken.BNF.McKenzie_Recover_Param_Type;
- Max_Parallel : SAL.Base_Peek_Type := 15;
+ Conflicts : WisiToken.BNF.Conflict_Lists.List;
+ McKenzie_Recover : WisiToken.BNF.McKenzie_Recover_Param_Type;
+ Max_Parallel : SAL.Base_Peek_Type := 15;
- Rule_Count : Integer := 0;
- Action_Count : Integer := 0;
- Check_Count : Integer := 0;
- Label_Count : Ada.Containers.Count_Type := 0;
+ Rule_Count : Integer := 0;
+ Post_Parse_Action_Count : Integer := 0;
+ In_Parse_Action_Count : Integer := 0;
+ Label_Count : Ada.Containers.Count_Type := 0;
If_Lexer_Present : Boolean := False;
If_Parser_Present : Boolean := False;
@@ -90,24 +95,40 @@ package WisiToken_Grammar_Runtime is
-- Valid in an RHS node; True when token labels are generated by
-- Translate_EBNF_To_BNF
- Edited_Token_List : Boolean := False;
- -- Valid in an RHS node; matches Wisitoken.BNF RHS.Edited_Token_List
+ Orig_EBNF_RHS : Boolean := False;
+ -- Valid in an rhs node; True if this RHS is either an unedited RHS,
+ -- or the only edits were to substitute token literals and keep
+ -- optional items or items from a simple group. This means the token
+ -- count is the same as in the original, which is used by
+ -- Output_Ada_Emacs to map tokens to actions.
+
+ EBNF_RHS_Index : Natural := Natural'Last;
+ -- Valid in an rhs node; Index of RHS containing EBNF RHS that this
+ -- RHS was copied from.
+
+ Orig_Token_Index : SAL.Base_Peek_Type := 0;
+ -- Valid in an rhs_element node; index in EBNF_RHS.Tokens that this
+ -- token was copied from.
+
end record;
type Augmented_Access is access all Augmented;
type Augmented_Access_Constant is access constant Augmented;
- function Image (Item : in WisiToken.Syntax_Trees.Augmented_Class_Access_Constant) return String
- is (Augmented_Access_Constant (Item).EBNF'Image & " " &
- Augmented_Access_Constant (Item).Auto_Token_Labels'Image & " " &
- Augmented_Access_Constant (Item).Edited_Token_List'Image);
+ overriding
+ function Image_Augmented (Item : in Augmented) return String;
overriding
function Copy_Augmented
(User_Data : in User_Data_Type;
- Augmented : in WisiToken.Syntax_Trees.Augmented_Class_Access)
+ Augmented : in not null WisiToken.Syntax_Trees.Augmented_Class_Access)
return WisiToken.Syntax_Trees.Augmented_Class_Access;
- overriding procedure Reset (Data : in out User_Data_Type);
+ procedure Reset
+ (Data : in out User_Data_Type;
+ User_Lexer : in WisiToken.BNF.Lexer_Type;
+ User_Parser : in WisiToken.BNF.Generate_Algorithm;
+ Phase : in Action_Phase);
+ -- If Phase is Other, preserve data set in phase Meta.
overriding
procedure Initialize_Actions
@@ -143,7 +164,10 @@ package WisiToken_Grammar_Runtime is
procedure Add_Nonterminal
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
Tree : in out WisiToken.Syntax_Trees.Tree;
- Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access);
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ with Pre => Tree.ID (Nonterm) = +nonterminal_ID;
+ -- Nonterm is a nonterminal definition in the parsed grammar tree;
+ -- add it to User_Data.Rules.
procedure Check_EBNF
(User_Data : in out WisiToken.Syntax_Trees.User_Data_Type'Class;
@@ -154,6 +178,24 @@ package WisiToken_Grammar_Runtime is
----------
-- Visible for WisiToken_Grammar_Editing
+ function Get_Associativity
+ (Data : in User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access)
+ return WisiToken.Associativity
+ with Pre => Attr_List = WisiToken.Syntax_Trees.Invalid_Node_Access or else Tree.ID (Attr_List) = +attribute_list_ID;
+ -- If Attr_List is an attr_list, return the associativity it specifies;
+ -- otherwise No_Precedence.
+
+ function Get_Precedence
+ (Data : in User_Data_Type;
+ Tree : in out WisiToken.Syntax_Trees.Tree;
+ Attr_List : in WisiToken.Syntax_Trees.Node_Access)
+ return WisiToken.Base_Precedence_ID
+ with Pre => Attr_List = WisiToken.Syntax_Trees.Invalid_Node_Access or else Tree.ID (Attr_List) = +attribute_list_ID;
+ -- If Attr_List is an attr_list, return the precedence it specifies;
+ -- otherwise No_Precedence.
+
function Get_Text
(Virtual_Identifiers : in WisiToken.BNF.String_Arrays.Vector;
Tree : in WisiToken.Syntax_Trees.Tree;
@@ -181,4 +223,12 @@ package WisiToken_Grammar_Runtime is
-- Find first descendant of Node that has rhs_item_ID, return source
-- text for it.
+ function Get_Code_Location_List
+ (Tree : in WisiToken.Syntax_Trees.Tree;
+ Nonterm : in WisiToken.Syntax_Trees.Valid_Node_Access)
+ return WisiToken.Syntax_Trees.Valid_Node_Access_Array
+ with Pre => Tree.ID (Tree.Child (Nonterm, 3)) = +identifier_list_ID;
+ -- Return location from a %code declaration.
+
+
end WisiToken_Grammar_Runtime;