[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/parser-generator 3373881 085/434: More work on GOTO-tab
From: |
ELPA Syncer |
Subject: |
[elpa] externals/parser-generator 3373881 085/434: More work on GOTO-table generation |
Date: |
Mon, 29 Nov 2021 15:59:14 -0500 (EST) |
branch: externals/parser-generator
commit 3373881017c69654c2b245c87bcf90f1dd29a698
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>
More work on GOTO-table generation
---
parser.el | 121 ++++++++++++++++++++++++++++++++--------------------
test/parser-test.el | 30 ++++---------
2 files changed, 84 insertions(+), 67 deletions(-)
diff --git a/parser.el b/parser.el
index 4d4c0f0..597470a 100644
--- a/parser.el
+++ b/parser.el
@@ -26,10 +26,18 @@
nil
"Generated F-sets for grammar.")
+(defvar parser--goto-table
+ nil
+ "GOTO-table for grammar.")
+
(defvar parser--look-ahead-number
nil
"Current look-ahead number used.")
+(defvar parser--table-lr-items
+ nil
+ "Hash-table for distinct LR-items in grammar.")
+
(defvar parser--table-non-terminal-p
nil
"Hash-table of terminals for quick checking.")
@@ -57,7 +65,9 @@
(defun parser--clear-cache ()
"Clear cache."
- (setq parser--f-sets nil))
+ (setq parser--f-sets nil)
+ (setq parser--goto-table nil)
+ (setq parser--table-lr-items nil))
(defun parser--distinct (elements)
"Return distinct of ELEMENTS."
@@ -650,49 +660,69 @@
;; Algorithm 5.9, p. 389
(defun parser--lr-items-for-grammar ()
"Calculate set of valid LR(k) items for grammar."
- (let ((lr-items)
- (unmarked-lr-items)
- (marked-lr-items (make-hash-table :test 'equal))
- (symbols (append (parser--get-grammar-non-terminals)
(parser--get-grammar-terminals))))
-
- (let ((e-set (parser--lr-items-for-prefix parser--e-identifier)))
- ;;(1) Place V(e) in S. The set V(e) is initially unmarked.
- (setq unmarked-lr-items e-set))
-
- ;; (2) If a set of items a in S is unmarked
- ;; (3) Repeat step (2) until all sets of items in S are marked.
- (let ((lr-item))
- (while unmarked-lr-items
-
- ;; (2) Mark a
- (setq lr-item (pop unmarked-lr-items))
- (puthash lr-item t marked-lr-items)
- (push lr-item lr-items)
- ;; (message "lr-item: %s" lr-item)
-
- ;; (2) By computing for each X in N u E, GOTO (a, X). (Algorithm 5.8
can be used here.)
- ;; V(X1,...,Xi) = GOTO(V(X1,...,Xi-1), Xi)
- (dolist (symbol symbols)
- ;; (message "symbol: %s" symbol)
-
- (let ((prefix-lr-items (parser--lr-items-for-goto (list lr-item)
symbol)))
-
- (parser--debug
- (message "GOTO(%s, %s) = %s" lr-item symbol prefix-lr-items))
- ;; If a' = GOTO(a, X) is nonempty
- (when prefix-lr-items
- (dolist (prefix-lr-item prefix-lr-items)
- ;; (message "prefix-lr-item: %s" prefix-lr-item)
-
- ;; and is not already in S
- (unless (gethash prefix-lr-item marked-lr-items)
- ;; Note that GOTO(a, X) will always be empty if all items in
a
- ;; have the dot at the right end of the production
-
- ;; then add a' to S as an unmarked set of items
- (push prefix-lr-item unmarked-lr-items))))))))
-
- (sort lr-items 'parser--sort-list)))
+ (unless parser--goto-table
+ (setq parser--goto-table nil)
+ (setq parser--table-lr-items (make-hash-table :test 'equal))
+ (let ((lr-item-new-index 0)
+ (goto-table)
+ (unmarked-lr-items)
+ (marked-lr-items (make-hash-table :test 'equal))
+ (symbols (append (parser--get-grammar-non-terminals)
(parser--get-grammar-terminals))))
+
+ (let ((e-set (parser--lr-items-for-prefix parser--e-identifier)))
+ (dolist (e-item e-set)
+ ;;(1) Place V(e) in S. The set V(e) is initially unmarked.
+ (push `(,lr-item-new-index ,e-item) unmarked-lr-items)))
+
+ ;; (2) If a set of items a in S is unmarked
+ ;; (3) Repeat step (2) until all sets of items in S are marked.
+ (let ((popped-item)
+ (lr-item-index)
+ (lr-item)
+ (goto-table-table))
+ (while unmarked-lr-items
+
+ ;; (2) Mark a
+ (setq popped-item (pop unmarked-lr-items))
+ (setq lr-item-index (car popped-item))
+ (setq lr-item (car (cdr popped-item)))
+ (message "lr-item-index: %s" lr-item-index)
+ (message "lr-item: %s" lr-item)
+ (message "popped-item: %s" popped-item)
+ (puthash lr-item lr-item-index marked-lr-items)
+ (puthash lr-item-index lr-item parser--table-lr-items)
+ (setq goto-table-table nil)
+
+ ;; (2) By computing for each X in N u E, GOTO (a, X). (Algorithm 5.8
can be used here.)
+ ;; V(X1,...,Xi) = GOTO(V(X1,...,Xi-1), Xi)
+ (dolist (symbol symbols)
+ ;; (message "symbol: %s" symbol)
+
+ (let ((prefix-lr-items (parser--lr-items-for-goto (list lr-item)
symbol)))
+
+ (parser--debug
+ (message "GOTO(%s, %s) = %s" lr-item symbol prefix-lr-items))
+ ;; If a' = GOTO(a, X) is nonempty
+ (when prefix-lr-items
+ (dolist (prefix-lr-item prefix-lr-items)
+ ;; (message "prefix-lr-item: %s" prefix-lr-item)
+
+ ;; and is not already in S
+ (let ((goto (gethash prefix-lr-item marked-lr-items)))
+ (if goto
+ (push `(,symbol ,goto) goto-table-table)
+
+ ;; Note that GOTO(a, X) will always be empty if all
items in a
+ ;; have the dot at the right end of the production
+ ;; then add a' to S as an unmarked set of items
+ (push `(,symbol ,lr-item-new-index) goto-table-table)
+ (push `(,lr-item-new-index ,prefix-lr-item)
unmarked-lr-items)
+ (setq lr-item-new-index (1+ lr-item-new-index))))))))
+
+ (push `(,lr-item-index ,goto-table-table) goto-table)))
+ (setq parser--goto-table (nreverse goto-table))))
+
+ parser--goto-table)
;; Algorithm 5.8, p. 386
(defun parser--lr-items-for-prefix (γ)
@@ -781,8 +811,7 @@
;; 2 Suppose that we have constructed V(X1,X2,...,Xi-1) we construct
V(X1,X2,...,Xi) as follows:
;; Only do this step if prefix is not the e-identifier
- (let ((prefix-acc)
- (prefix-previous lr-items-e))
+ (let ((prefix-previous lr-items-e))
(unless (and
(= (length γ) 1)
(parser--valid-e-p (car γ)))
diff --git a/test/parser-test.el b/test/parser-test.el
index 6821ed5..8effcf3 100644
--- a/test/parser-test.el
+++ b/test/parser-test.el
@@ -230,30 +230,18 @@
;; Example 5.30, p. 389
(parser--set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b)) (S e)) Sp))
(parser--set-look-ahead-number 1)
+ (message "GOTO-table: %s" (parser--lr-items-for-grammar))
(should
(equal
- '((S (S a) (S b) (a))
- (S (S a) (S b) (b))
- (S (S a) (S b) (e))
- (S (S) (a S b) (a))
- (S (S) (a S b) (b))
- (S (S) (a S b) (e))
- (S (S a S) (b) (a))
- (S (S a S) (b) (b))
- (S (S a S) (b) (e))
- (S (S a S b) nil (a))
- (S (S a S b) nil (b))
- (S (S a S b) nil (e))
- (S nil (S a S b) (a))
- (S nil (S a S b) (b))
- (S nil (S a S b) (e))
- (S nil nil (a))
- (S nil nil (a))
- (S nil nil (b))
- (S nil nil (e))
- (Sp (S) nil (e))
- (Sp nil (S) (e)))
+ '((0 (S 1))
+ (1 (a 2))
+ (2 (S 3))
+ (3 (a 4) (b 5))
+ (4 (S 6))
+ (5 nil)
+ (6 (a 4) (b 7))
+ (7 nil))
(parser--lr-items-for-grammar)))
(message "Passed LR-items for example 5.30")
- [elpa] externals/parser-generator f940be9 033/434: Added list of functions and usage examples, (continued)
- [elpa] externals/parser-generator f940be9 033/434: Added list of functions and usage examples, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator b8d6476 038/434: Setting look-ahead-number clears cache storage, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 2829d36 039/434: More work on FOLLOW, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 0f8b422 043/434: Added another unit test for follow function, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator f8f5fe2 046/434: Started on function to calculate lk-items for a viable prefix, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 8d0a93e 053/434: More work on algorithm, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 6d2e231 059/434: Added two more failing valid LR-set calculation tests, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 15dc472 067/434: Added TODO items, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 44eb5a3 062/434: Passing unit test for V(e) and V(S), ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator a7d1cc0 070/434: Updated README, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 3373881 085/434: More work on GOTO-table generation,
ELPA Syncer <=
- [elpa] externals/parser-generator 5957fad 076/434: First implementation of generating LR-items for grammar, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 7689ec5 086/434: More work, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator c992a54 093/434: Added info in README.md about LR-items, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 4c75f65 101/434: Added TODO items, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 6ee548e 005/434: Updated README, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 5150b91 075/434: Started working on lr-items for grammar function, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 59aea4d 077/434: More tweaking new algorithm, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator d0c9663 082/434: Passing test for distinct LR-items for grammar, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 7a48197 084/434: Removed obsolete variable, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 7fe7318 087/434: Passed test for distinct LR-items for grammar, ELPA Syncer, 2021/11/29