[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/parser-generator 6ce0dd9429 04/82: Improved function to
From: |
Christian Johansson |
Subject: |
[elpa] externals/parser-generator 6ce0dd9429 04/82: Improved function to calculate merge max terminal sets |
Date: |
Thu, 12 May 2022 13:28:12 -0400 (EDT) |
branch: externals/parser-generator
commit 6ce0dd9429fbc0c4178eb34df4f4c072693d9199
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>
Improved function to calculate merge max terminal sets
---
parser-generator-ll.el | 67 ++++----------------------------
parser-generator.el | 88 ++++++++++++++++++++++++++++++++-----------
test/parser-generator-test.el | 30 ++++++---------
3 files changed, 85 insertions(+), 100 deletions(-)
diff --git a/parser-generator-ll.el b/parser-generator-ll.el
index 2b2a22ff7d..bdbc0ca76a 100644
--- a/parser-generator-ll.el
+++ b/parser-generator-ll.el
@@ -66,74 +66,21 @@
look-aheads
(parser-generator--merge-max-terminals
first-production
- nil
- k)))
+ nil)))
((and first-dot-look-ahead
(not first-production))
(setq
look-aheads
(parser-generator--merge-max-terminals
nil
- first-dot-look-ahead
- k)))
+ first-dot-look-ahead)))
((and first-production
first-dot-look-ahead)
- ;; Generate a new list of all permutations
- ;; of first-production
- ;; and first-dot-look-ahead
- ;; with maximum length k
- (let ((first-production-length
- (length first-production))
- (first-production-index 0)
- (first-dot-look-ahead-length
- (length first-dot-look-ahead))
- (merged-look-aheds))
- (while
- (<
- first-production-index
- first-production-length)
- (let ((first-production-element
- (nth
- first-production-index
- first-production))
- (first-dot-look-ahead-index 0))
- (while
- (<
- first-dot-look-ahead-index
- first-dot-look-ahead-length)
- (let ((first-dot-look-ahead-element
- (nth
- first-dot-look-ahead-index
- first-dot-look-ahead)))
- (let ((merged-first-element
- (parser-generator--merge-max-terminals
- first-production-element
- first-dot-look-ahead-element)))
- (if merged-look-aheads
- (setq
- merged-look-aheads
- (append
- merged-look-aheads
- merged-first-element))
- (setq
- merged-look-aheads
- merged-first-element))))
- (setq
- first-dot-look-ahead-index
- (1+ first-dot-look-ahead-index)))
- (setq
- first-production-index
- (1+ first-production-index))))
- (setq
- merged-look-aheads
- (parser-generator--distinct
- merged-look-aheads))
- (setq
- look-aheads
- merged-look-aheads))
-
-
- )
+ (setq
+ look-aheads
+ (parser-generator--merge-max-terminal-sets
+ first-production
+ first-dot-look-ahead))))
(t (error
"Unexpected empty FIRST for production: %S and dot-look-ahead: %S"
production
diff --git a/parser-generator.el b/parser-generator.el
index 9bd2035a62..5cf4d9374f 100644
--- a/parser-generator.el
+++ b/parser-generator.el
@@ -1230,35 +1230,79 @@
look-ahead)))
(nreverse look-ahead)))
-(defun parser-generator--merge-max-terminals (a b k)
- "Merge terminals from A and B to a maximum length of K."
- (let ((merged)
+(defun parser-generator--merge-max-terminal-sets (a b)
+ "Calculate list of all lists of L1 (+) L2 which is a merge of all terminals
in lists A combined with all terminals in lists B but with maximum length of
the set look-ahead number."
+ (let ((a-length
+ (length a))
+ (a-index 0)
+ (b-length
+ (length b))
+ (merged-lists))
+ (while (< a-index a-length)
+ (let ((a-element (nth a-index a))
+ (b-index 0))
+ (while (< b-index b-length)
+ (let ((b-element (nth b-index b)))
+ (let ((merged-element
+ (parser-generator--merge-max-terminals
+ a-element
+ b-element)))
+ (if merged-lists
+ (setq
+ merged-lists
+ (append
+ merged-lists
+ (list merged-element)))
+ (setq
+ merged-lists
+ (list merged-element)))))
+ (setq b-index (1+ b-index)))
+ (setq a-index (1+ a-index))))
+ (setq
+ merged-lists
+ (parser-generator--distinct
+ merged-lists))
+ (setq
+ merged-lists
+ (sort
+ merged-lists
+ 'parser-generator--sort-list))
+ merged-lists))
+
+;; Lemma 5.1 p. 348
+(defun parser-generator--merge-max-terminals (a b)
+ "Calculate L1 (+) L2 which is a merge of all terminals in A and B but with
maximum length of the set look-ahead number."
+ (let ((k (max 1 parser-generator--look-ahead-number))
+ (merged)
(merge-count 0)
- (continue t)
(a-element)
(a-index 0)
(a-length (length a))
(b-element)
(b-index 0)
(b-length (length b)))
- (while (and
- (< a-index a-length)
- (< merge-count k)
- continue)
- (setq a-element (nth a-index a))
- (when (parser-generator--valid-e-p a-element)
- (setq continue nil))
- (push a-element merged)
- (setq a-index (1+ a-index)))
- (while (and
- (< b-index b-length)
- (< merge-count k)
- continue)
- (setq b-element (nth b-index b))
- (when (parser-generator--valid-e-p b-element)
- (setq continue nil))
- (push b-element merged)
- (setq b-index (1+ b-index)))
+ (let ((continue t))
+ (while (and
+ (< a-index a-length)
+ (< merge-count k)
+ continue)
+ (setq a-element (nth a-index a))
+ (if (parser-generator--valid-e-p a-element)
+ (setq continue nil)
+ (push a-element merged)
+ (setq a-index (1+ a-index))
+ (setq merge-count (1+ merge-count)))))
+ (let ((continue t))
+ (while (and
+ (< b-index b-length)
+ (< merge-count k)
+ continue)
+ (setq b-element (nth b-index b))
+ (if (parser-generator--valid-e-p b-element)
+ (setq continue nil)
+ (push b-element merged)
+ (setq b-index (1+ b-index))
+ (setq merge-count (1+ merge-count)))))
(nreverse merged)))
;; p. 357
diff --git a/test/parser-generator-test.el b/test/parser-generator-test.el
index 1fab673dc2..c6165fd311 100644
--- a/test/parser-generator-test.el
+++ b/test/parser-generator-test.el
@@ -967,27 +967,21 @@
(message "Passed tests for (parser-generator--valid-terminal-p)"))
-(defun parser-generator-test--merge-max-terminals ()
- "Test `parser-generator--merge-max-terminals'."
- (message "Starting tests for (parser-generator--merge-max-terminals)")
-
- (should
- (equal
- '(a b e)
- (parser-generator--merge-max-terminals
- '(a)
- '(b e)
- 3)))
+(defun parser-generator-test--merge-max-terminal-sets ()
+ "Test `parser-generator--merge-max-terminal-sets'."
+ (message "Starting tests for (parser-generator--merge-max-terminal-sets)")
+ ;; Example 5.13 p. 348
+ (parser-generator-set-e-identifier 'e)
+ (parser-generator-set-look-ahead-number 2)
(should
(equal
- '(a e)
- (parser-generator--merge-max-terminals
- '(a e)
- '(b e)
- 3)))
+ '((a b) (b) (b a))
+ (parser-generator--merge-max-terminal-sets
+ '((a b b) (e))
+ '((b) (b a b)))))
- (message "Passed tests for (parser-generator--merge-max-terminals)"))
+ (message "Passed tests for (parser-generator--merge-max-terminal-sets)"))
(defun parser-generator-test--get-list-permutations ()
"Test `parser-generator--get-list-permutations'."
@@ -1061,7 +1055,7 @@
(parser-generator-test--get-grammar-look-aheads)
(parser-generator-test--get-grammar-rhs)
(parser-generator-test--get-list-permutations)
- (parser-generator-test--merge-max-terminals)
+ (parser-generator-test--merge-max-terminal-sets)
(parser-generator-test--sort-list)
(parser-generator-test--valid-context-sensitive-attribute-p)
(parser-generator-test--valid-context-sensitive-attributes-p)
- [elpa] externals/parser-generator af3740c46a 59/82: More refactoring, (continued)
- [elpa] externals/parser-generator af3740c46a 59/82: More refactoring, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 3d373f4dfa 60/82: Updated docs, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 020969094c 61/82: More refactoring, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 08ed55d35a 62/82: More work on k=1, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 4f85cc5616 66/82: Passes byte-compilation tests, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 7a265c9a84 67/82: LL-tests now runs on make tests command, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator a046c8584d 73/82: Started on documentation for LL(k) and LL(1), Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator f07939a440 76/82: Added example from Wikipedia and passing test, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 03a11c4369 14/82: Started test for LL(k) parser-table generation, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 9d6ca94d0e 02/82: More work on LL(k) parser, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 6ce0dd9429 04/82: Improved function to calculate merge max terminal sets,
Christian Johansson <=
- [elpa] externals/parser-generator 52734d7160 16/82: Updated TODO items, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 7b77032f71 22/82: Parser table generation for LLk now works for productions, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator fe728f8ad8 23/82: Passing test for generating LLk parser table, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 3b9977b51b 28/82: More work on LLk test, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator f23bc217d8 30/82: More wrestling, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 6e91a4b498 32/82: More work on helper functions, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator 80dd506b65 33/82: More work on LL-helper functions, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator e6f9ac545f 37/82: Cleanup after byte-compilation, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator cf4332ef0e 40/82: Started on LLk parsing algorithm, Christian Johansson, 2022/05/12
- [elpa] externals/parser-generator f5f7b2c82b 41/82: Added TODO items, Christian Johansson, 2022/05/12