[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/parser-generator 0e54a88 148/434: Optimized away one gl
From: |
ELPA Syncer |
Subject: |
[elpa] externals/parser-generator 0e54a88 148/434: Optimized away one global variable |
Date: |
Mon, 29 Nov 2021 15:59:29 -0500 (EST) |
branch: externals/parser-generator
commit 0e54a88eeb564d9c45944b9d32d65f510158c9f3
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>
Optimized away one global variable
---
parser-generator-lr.el | 378 +++++++++++++++++++--------------------
test/parser-generator-lr-test.el | 174 ++++++++----------
2 files changed, 259 insertions(+), 293 deletions(-)
diff --git a/parser-generator-lr.el b/parser-generator-lr.el
index 9b68e2f..4447d81 100644
--- a/parser-generator-lr.el
+++ b/parser-generator-lr.el
@@ -22,217 +22,205 @@
nil
"Goto-tables for grammar.")
-(defvar parser-generator-lr--items
- nil
- "Hash-table for distinct LR-items in grammar.")
-
-
-;; Helper Functions
-
-
-(defun parser-generator-lr--reset ()
- "Reset variables."
- (setq parser-generator-lr--action-tables nil)
- (setq parser-generator-lr--goto-tables nil)
- (setq parser-generator-lr--items nil))
-
;; Main Algorithms
+(defun parser-generator-lr-generate-parser-tables ()
+ "Generate parsing tables for grammar."
+ (let ((table-lr-items (parser-generator-lr--generate-goto-tables)))
+ (parser-generator-lr--generate-action-tables table-lr-items)
+ table-lr-items))
+
;; Algorithm 5.11, p. 393
-(defun parser-generator-lr--generate-action-tables ()
- "Generate action-tables for lr-grammar."
- (unless parser-generator-lr--action-tables
- (let ((action-tables)
- (states '(shift reduce error))
- (added-actions (make-hash-table :test 'equal))
- (goto-tables (parser-generator--hash-to-list
parser-generator-lr--goto-tables)))
- (dolist (goto-table goto-tables)
- (let ((goto-index (car goto-table))
- (found-action nil)
- (action-table))
- (let ((lr-items (gethash goto-index parser-generator-lr--items)))
- (let ((lr-items-length (length lr-items)))
- ;; Where u is in (T U e)*k
- (dolist (state states)
- (let ((lr-item)
- (lr-item-index 0)
- (continue-loop t))
- (while (and
- (< lr-item-index lr-items-length)
- continue-loop)
- (setq lr-item (nth lr-item-index lr-items))
- (cond
-
- ((eq state 'shift)
- ;; (a) f(u) = shift if [A -> B . C, v] is in LR-items, C
!= e and u is in EFF(Cv)
- (when (nth 2 lr-item)
- (let ((C (nth 2 lr-item))
- (v (nth 3 lr-item)))
- (let ((Cv (append C v)))
- (when Cv
- (let ((eff (parser-generator--e-free-first Cv)))
- (when eff
- ;; Go through eff-items and see if any item
is a valid look-ahead of grammar
- ;; in that case save in action table a shift
action here
- (let ((eff-index 0)
- (eff-item)
- (eff-length (length eff))
- (searching-match t))
- (while (and
- searching-match
- (< eff-index eff-length))
- (setq eff-item (nth eff-index eff))
- (when
(parser-generator--valid-look-ahead-p eff-item)
- (let ((hash-key (format "%s-%s-%s"
goto-index state eff-item)))
- (unless (gethash hash-key
added-actions)
- (puthash hash-key t added-actions)
- (setq searching-match nil))))
- (setq eff-index (1+ eff-index)))
-
- (unless searching-match
- (push (list eff-item 'shift)
action-table)
- (setq found-action t))))))))))
-
- ((eq state 'reduce)
- ;; (b) f(u) = reduce i if [A -> B ., u] is in a and A ->
B is production i in P, i > 1
- (when (and
- (nth 0 lr-item)
- (not (nth 2 lr-item)))
- (let ((A (nth 0 lr-item))
- (B (nth 1 lr-item))
- (u (nth 3 lr-item)))
- (unless B
- (setq B (list parser-generator--e-identifier)))
- (when (parser-generator--valid-look-ahead-p u)
- (let ((hash-key (format "%s-%s-%s" goto-index
state u)))
- (unless (gethash hash-key added-actions)
- (puthash hash-key t added-actions)
- (let ((production (list A B)))
- (let ((production-number
(parser-generator--get-grammar-production-number production)))
- (unless production-number
- (error "Expecting production number for
%s from LR-item %s!" production lr-item))
-
- (if (and
- (= production-number 0)
- (= (length u) 1)
- (parser-generator--valid-e-p (car u)))
- (progn
- ;; Reduction by first production
- ;; of empty look-ahead means grammar
has been accepted
- (push (list u 'accept) action-table)
- (setq found-action t))
-
- ;; save reduction action in action table
- (push (list u 'reduce production-number)
action-table)
- (setq found-action t))))))))))
-
- ((eq state 'error)
- (unless found-action
- (error (format "Failed to find any action in set %s"
lr-items)))
- (setq continue-loop nil)))
- (setq lr-item-index (1+ lr-item-index)))))))
- (parser-generator--debug
- (message "%s actions %s" goto-index action-table))
- (when action-table
- (push (list goto-index (sort action-table
'parser-generator--sort-list)) action-tables))))
- (setq action-tables (nreverse action-tables))
- (setq parser-generator-lr--action-tables (make-hash-table :test 'equal))
- (let ((table-length (length action-tables))
- (table-index 0))
- (while (< table-index table-length)
- (puthash table-index (car (cdr (nth table-index action-tables)))
parser-generator-lr--action-tables)
- (setq table-index (1+ table-index)))))))
+(defun parser-generator-lr--generate-action-tables (table-lr-items)
+ "Generate action-tables for lr-grammar based on TABLE-LR-ITEMS."
+ (let ((action-tables)
+ (states '(shift reduce error))
+ (added-actions (make-hash-table :test 'equal))
+ (goto-tables (parser-generator--hash-to-list
parser-generator-lr--goto-tables)))
+ (dolist (goto-table goto-tables)
+ (let ((goto-index (car goto-table))
+ (found-action nil)
+ (action-table))
+ (let ((lr-items (gethash goto-index table-lr-items)))
+ (let ((lr-items-length (length lr-items)))
+ ;; Where u is in (T U e)*k
+ (dolist (state states)
+ (let ((lr-item)
+ (lr-item-index 0)
+ (continue-loop t))
+ (while (and
+ (< lr-item-index lr-items-length)
+ continue-loop)
+ (setq lr-item (nth lr-item-index lr-items))
+ (cond
+
+ ((eq state 'shift)
+ ;; (a) f(u) = shift if [A -> B . C, v] is in LR-items, C
!= e and u is in EFF(Cv)
+ (when (nth 2 lr-item)
+ (let ((C (nth 2 lr-item))
+ (v (nth 3 lr-item)))
+ (let ((Cv (append C v)))
+ (when Cv
+ (let ((eff (parser-generator--e-free-first Cv)))
+ (when eff
+ ;; Go through eff-items and see if any item is
a valid look-ahead of grammar
+ ;; in that case save in action table a shift
action here
+ (let ((eff-index 0)
+ (eff-item)
+ (eff-length (length eff))
+ (searching-match t))
+ (while (and
+ searching-match
+ (< eff-index eff-length))
+ (setq eff-item (nth eff-index eff))
+ (when
(parser-generator--valid-look-ahead-p eff-item)
+ (let ((hash-key (format "%s-%s-%s"
goto-index state eff-item)))
+ (unless (gethash hash-key
added-actions)
+ (puthash hash-key t added-actions)
+ (setq searching-match nil))))
+ (setq eff-index (1+ eff-index)))
+
+ (unless searching-match
+ (push (list eff-item 'shift) action-table)
+ (setq found-action t))))))))))
+
+ ((eq state 'reduce)
+ ;; (b) f(u) = reduce i if [A -> B ., u] is in a and A -> B
is production i in P, i > 1
+ (when (and
+ (nth 0 lr-item)
+ (not (nth 2 lr-item)))
+ (let ((A (nth 0 lr-item))
+ (B (nth 1 lr-item))
+ (u (nth 3 lr-item)))
+ (unless B
+ (setq B (list parser-generator--e-identifier)))
+ (when (parser-generator--valid-look-ahead-p u)
+ (let ((hash-key (format "%s-%s-%s" goto-index state
u)))
+ (unless (gethash hash-key added-actions)
+ (puthash hash-key t added-actions)
+ (let ((production (list A B)))
+ (let ((production-number
(parser-generator--get-grammar-production-number production)))
+ (unless production-number
+ (error "Expecting production number for %s
from LR-item %s!" production lr-item))
+
+ (if (and
+ (= production-number 0)
+ (= (length u) 1)
+ (parser-generator--valid-e-p (car u)))
+ (progn
+ ;; Reduction by first production
+ ;; of empty look-ahead means grammar
has been accepted
+ (push (list u 'accept) action-table)
+ (setq found-action t))
+
+ ;; save reduction action in action table
+ (push (list u 'reduce production-number)
action-table)
+ (setq found-action t))))))))))
+
+ ((eq state 'error)
+ (unless found-action
+ (error (format "Failed to find any action in set %s"
lr-items)))
+ (setq continue-loop nil)))
+ (setq lr-item-index (1+ lr-item-index)))))))
+ (parser-generator--debug
+ (message "%s actions %s" goto-index action-table))
+ (when action-table
+ (push (list goto-index (sort action-table
'parser-generator--sort-list)) action-tables))))
+ (setq action-tables (nreverse action-tables))
+ (setq parser-generator-lr--action-tables (make-hash-table :test 'equal))
+ (let ((table-length (length action-tables))
+ (table-index 0))
+ (while (< table-index table-length)
+ (puthash table-index (car (cdr (nth table-index action-tables)))
parser-generator-lr--action-tables)
+ (setq table-index (1+ table-index))))))
;; Algorithm 5.9, p. 389
(defun parser-generator-lr--generate-goto-tables ()
"Calculate set of valid LR(k) items for grammar and a GOTO-table."
- (unless (or
- parser-generator-lr--goto-tables
- parser-generator-lr--items)
- (setq parser-generator-lr--goto-tables nil)
- (setq parser-generator-lr--items (make-hash-table :test 'equal))
- (let ((lr-item-set-new-index 0)
- (goto-table)
- (unmarked-lr-item-sets)
- (marked-lr-item-sets (make-hash-table :test 'equal))
- (symbols (append (parser-generator--get-grammar-non-terminals)
(parser-generator--get-grammar-terminals))))
-
- (let ((e-set (parser-generator-lr--items-for-prefix
parser-generator--e-identifier)))
- ;;(1) Place V(e) in S. The set V(e) is initially unmarked.
- (push `(,lr-item-set-new-index ,e-set) unmarked-lr-item-sets)
- (setq lr-item-set-new-index (1+ lr-item-set-new-index)))
-
- ;; (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-set-index)
- (lr-items)
- (goto-table-table))
- (while unmarked-lr-item-sets
-
- (setq popped-item (pop unmarked-lr-item-sets))
- (setq lr-item-set-index (car popped-item))
- (setq lr-items (car (cdr popped-item)))
- (parser-generator--debug
- (message "lr-item-set-index: %s" lr-item-set-index)
- (message "lr-items: %s" lr-items)
- (message "popped-item: %s" popped-item))
+ (let ((lr-item-set-new-index 0)
+ (goto-table)
+ (unmarked-lr-item-sets)
+ (marked-lr-item-sets (make-hash-table :test 'equal))
+ (symbols (append (parser-generator--get-grammar-non-terminals)
(parser-generator--get-grammar-terminals)))
+ (table-lr-items (make-hash-table :test 'equal)))
+
+ (let ((e-set (parser-generator-lr--items-for-prefix
parser-generator--e-identifier)))
+ ;;(1) Place V(e) in S. The set V(e) is initially unmarked.
+ (push `(,lr-item-set-new-index ,e-set) unmarked-lr-item-sets)
+ (setq lr-item-set-new-index (1+ lr-item-set-new-index)))
+
+ ;; (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-set-index)
+ (lr-items)
+ (goto-table-table))
+ (while unmarked-lr-item-sets
+
+ (setq popped-item (pop unmarked-lr-item-sets))
+ (setq lr-item-set-index (car popped-item))
+ (setq lr-items (car (cdr popped-item)))
+ (parser-generator--debug
+ (message "lr-item-set-index: %s" lr-item-set-index)
+ (message "lr-items: %s" lr-items)
+ (message "popped-item: %s" popped-item))
- ;; (2) Mark a
- (puthash lr-items lr-item-set-index marked-lr-item-sets)
+ ;; (2) Mark a
+ (puthash lr-items lr-item-set-index marked-lr-item-sets)
- (puthash lr-item-set-index lr-items parser-generator-lr--items)
- (setq goto-table-table nil)
+ (puthash lr-item-set-index lr-items 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)
- (parser-generator--debug
- (message "symbol: %s" symbol))
+ ;; (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)
+ (parser-generator--debug
+ (message "symbol: %s" symbol))
- (let ((prefix-lr-items (parser-generator-lr--items-for-goto
lr-items symbol)))
+ (let ((prefix-lr-items (parser-generator-lr--items-for-goto lr-items
symbol)))
- ;; If a' = GOTO(a, X) is nonempty
- (when prefix-lr-items
+ ;; If a' = GOTO(a, X) is nonempty
+ (when prefix-lr-items
- (parser-generator--debug
- (message "GOTO(%s, %s) = %s" lr-items symbol prefix-lr-items))
+ (parser-generator--debug
+ (message "GOTO(%s, %s) = %s" lr-items symbol prefix-lr-items))
- ;; and is not already in S
- (let ((goto (gethash prefix-lr-items marked-lr-item-sets)))
- (if goto
- (progn
- (parser-generator--debug
- (message "Set already exists in: %s" goto))
- (push `(,symbol ,goto) goto-table-table))
+ ;; and is not already in S
+ (let ((goto (gethash prefix-lr-items marked-lr-item-sets)))
+ (if goto
+ (progn
+ (parser-generator--debug
+ (message "Set already exists in: %s" goto))
+ (push `(,symbol ,goto) goto-table-table))
- (parser-generator--debug
- (message "Set is new"))
-
- ;; 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-set-new-index) goto-table-table)
- (push `(,lr-item-set-new-index ,prefix-lr-items)
unmarked-lr-item-sets)
- (setq lr-item-set-new-index (1+
lr-item-set-new-index)))))))
-
- (setq goto-table-table (sort goto-table-table
'parser-generator--sort-list))
- (push `(,lr-item-set-index ,goto-table-table) goto-table)))
-
- (setq goto-table (sort goto-table 'parser-generator--sort-list))
- (setq parser-generator-lr--goto-tables (make-hash-table :test 'equal))
- (let ((table-length (length goto-table))
- (table-index 0))
- (while (< table-index table-length)
- (puthash table-index (car (cdr (nth table-index goto-table)))
parser-generator-lr--goto-tables)
- (setq table-index (1+ table-index)))))
+ (parser-generator--debug
+ (message "Set is new"))
+
+ ;; 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-set-new-index) goto-table-table)
+ (push `(,lr-item-set-new-index ,prefix-lr-items)
unmarked-lr-item-sets)
+ (setq lr-item-set-new-index (1+ lr-item-set-new-index)))))))
+
+ (setq goto-table-table (sort goto-table-table
'parser-generator--sort-list))
+ (push `(,lr-item-set-index ,goto-table-table) goto-table)))
+
+ (setq goto-table (sort goto-table 'parser-generator--sort-list))
+ (setq parser-generator-lr--goto-tables (make-hash-table :test 'equal))
+ (let ((table-length (length goto-table))
+ (table-index 0))
+ (while (< table-index table-length)
+ (puthash table-index (car (cdr (nth table-index goto-table)))
parser-generator-lr--goto-tables)
+ (setq table-index (1+ table-index))))
(unless
(parser-generator-lr--items-valid-p
- (parser-generator--hash-values-to-list parser-generator-lr--items t))
;; TODO Should not use this debug function
- (error "Inconsistent grammar!"))))
+ (parser-generator--hash-values-to-list table-lr-items t)) ;; TODO
Should not use this debug function
+ (error "Inconsistent grammar!"))
+ table-lr-items))
;; Algorithm 5.10, p. 391
(defun parser-generator-lr--items-valid-p (lr-item-sets)
@@ -504,8 +492,10 @@
(parser-generator-lex-analyzer--reset))
;; Make sure tables exists
- (parser-generator-lr--generate-goto-tables)
- (parser-generator-lr--generate-action-tables)
+ (unless parser-generator-lr--action-tables
+ (error "Missing action-tables for grammar!"))
+ (unless parser-generator-lr--goto-tables
+ (error "Missing GOTO-tables for grammar!"))
(let ((accept))
(while (and
diff --git a/test/parser-generator-lr-test.el b/test/parser-generator-lr-test.el
index f7150b5..7a873a0 100644
--- a/test/parser-generator-lr-test.el
+++ b/test/parser-generator-lr-test.el
@@ -18,34 +18,7 @@
(parser-generator--set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b)) (S e))
Sp))
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
-
- (parser-generator-lr--reset)
- (parser-generator-lr--generate-goto-tables)
- (parser-generator-lr--generate-action-tables)
-
- (should
- (equal
- '((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-generator--hash-to-list parser-generator-lr--goto-tables)))
-
- (should
- (equal
- '((0 ((S nil (S a S b) (a)) (S nil (S a S b) (e)) (S nil nil (a)) (S nil
nil (e)) (Sp nil (S) (e))))
- (1 ((S (S) (a S b) (a)) (S (S) (a S b) (e)) (Sp (S) nil (e))))
- (2 ((S (S a) (S b) (a)) (S (S a) (S b) (e)) (S nil (S a S b) (a)) (S nil
(S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
- (3 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S a
S) (b) (e))))
- (4 ((S (S a) (S b) (a)) (S (S a) (S b) (b)) (S nil (S a S b) (a)) (S nil
(S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
- (5 ((S (S a S b) nil (a)) (S (S a S b) nil (e))))
- (6 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S a
S) (b) (b))))
- (7 ((S (S a S b) nil (a)) (S (S a S b) nil (b)))))
- (parser-generator--hash-to-list parser-generator-lr--items)))
+ (parser-generator-lr-generate-parser-tables)
;; Fig. 5.9 p. 374
(should
@@ -70,36 +43,34 @@
(parser-generator--set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b)) (S e))
Sp))
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
-
- (parser-generator-lr--reset)
- (parser-generator-lr--generate-goto-tables)
-
- ;; (message "GOTO-table: %s" parser-generator-lr--goto-tables)
- ;; (message "LR-items: %s" (parser-generator--hash-to-list
parser-generator-lr--items))
-
- (should
- (equal
- '((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-generator--hash-to-list parser-generator-lr--goto-tables)))
-
- (should
- (equal
- '((0 ((S nil (S a S b) (a)) (S nil (S a S b) (e)) (S nil nil (a)) (S nil
nil (e)) (Sp nil (S) (e))))
- (1 ((S (S) (a S b) (a)) (S (S) (a S b) (e)) (Sp (S) nil (e))))
- (2 ((S (S a) (S b) (a)) (S (S a) (S b) (e)) (S nil (S a S b) (a)) (S nil
(S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
- (3 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S a
S) (b) (e))))
- (4 ((S (S a) (S b) (a)) (S (S a) (S b) (b)) (S nil (S a S b) (a)) (S nil
(S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
- (5 ((S (S a S b) nil (a)) (S (S a S b) nil (e))))
- (6 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S a
S) (b) (b))))
- (7 ((S (S a S b) nil (a)) (S (S a S b) nil (b)))))
- (parser-generator--hash-to-list parser-generator-lr--items)))
+ (let ((table-lr-items (parser-generator-lr-generate-parser-tables)))
+
+ ;; (message "GOTO-table: %s" parser-generator-lr--goto-tables)
+ ;; (message "LR-items: %s" (parser-generator--hash-to-list
parser-generator-lr--items))
+
+ (should
+ (equal
+ '((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-generator--hash-to-list parser-generator-lr--goto-tables)))
+
+ (should
+ (equal
+ '((0 ((S nil (S a S b) (a)) (S nil (S a S b) (e)) (S nil nil (a)) (S nil
nil (e)) (Sp nil (S) (e))))
+ (1 ((S (S) (a S b) (a)) (S (S) (a S b) (e)) (Sp (S) nil (e))))
+ (2 ((S (S a) (S b) (a)) (S (S a) (S b) (e)) (S nil (S a S b) (a)) (S
nil (S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
+ (3 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S
a S) (b) (e))))
+ (4 ((S (S a) (S b) (a)) (S (S a) (S b) (b)) (S nil (S a S b) (a)) (S
nil (S a S b) (b)) (S nil nil (a)) (S nil nil (b))))
+ (5 ((S (S a S b) nil (a)) (S (S a S b) nil (e))))
+ (6 ((S (S) (a S b) (a)) (S (S) (a S b) (b)) (S (S a S) (b) (a)) (S (S
a S) (b) (b))))
+ (7 ((S (S a S b) nil (a)) (S (S a S b) nil (b)))))
+ (parser-generator--hash-to-list table-lr-items))))
(message "Passed LR-items for example 5.30")
@@ -108,35 +79,34 @@
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
- (parser-generator-lr--reset)
- (parser-generator-lr--generate-goto-tables)
-
- ;; (message "GOTO-table: %s" (parser-generator--hash-to-list
parser-generator-lr--goto-tables))
- ;; (message "LR-items: %s" (parser-generator--hash-to-list
parser-generator-lr--items))
-
- (should
- (equal
- '((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-generator--hash-to-list parser-generator-lr--goto-tables)))
-
- (should
- (equal
- '((0 ((S nil (S "a" S "b") ("a")) (S nil (S "a" S "b") (e)) (S nil nil
("a")) (S nil nil (e)) (Sp nil (S) (e))))
- (1 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") (e)) (Sp (S) nil (e))))
- (2 ((S (S "a") (S "b") ("a")) (S (S "a") (S "b") (e)) (S nil (S "a" S
"b") ("a")) (S nil (S "a" S "b") ("b")) (S nil nil ("a")) (S nil nil ("b"))))
- (3 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") ("b")) (S (S "a" S)
("b") ("a")) (S (S "a" S) ("b") (e))))
- (4 ((S (S "a") (S "b") ("a")) (S (S "a") (S "b") ("b")) (S nil (S "a" S
"b") ("a")) (S nil (S "a" S "b") ("b")) (S nil nil ("a")) (S nil nil ("b"))))
- (5 ((S (S "a" S "b") nil ("a")) (S (S "a" S "b") nil (e))))
- (6 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") ("b")) (S (S "a" S)
("b") ("a")) (S (S "a" S) ("b") ("b"))))
- (7 ((S (S "a" S "b") nil ("a")) (S (S "a" S "b") nil ("b")))))
- (parser-generator--hash-to-list parser-generator-lr--items)))
+ (let ((table-lr-items (parser-generator-lr-generate-parser-tables)))
+
+ ;; (message "GOTO-table: %s" (parser-generator--hash-to-list
parser-generator-lr--goto-tables))
+ ;; (message "LR-items: %s" (parser-generator--hash-to-list
parser-generator-lr--items))
+
+ (should
+ (equal
+ '((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-generator--hash-to-list parser-generator-lr--goto-tables)))
+
+ (should
+ (equal
+ '((0 ((S nil (S "a" S "b") ("a")) (S nil (S "a" S "b") (e)) (S nil nil
("a")) (S nil nil (e)) (Sp nil (S) (e))))
+ (1 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") (e)) (Sp (S) nil
(e))))
+ (2 ((S (S "a") (S "b") ("a")) (S (S "a") (S "b") (e)) (S nil (S "a" S
"b") ("a")) (S nil (S "a" S "b") ("b")) (S nil nil ("a")) (S nil nil ("b"))))
+ (3 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") ("b")) (S (S "a" S)
("b") ("a")) (S (S "a" S) ("b") (e))))
+ (4 ((S (S "a") (S "b") ("a")) (S (S "a") (S "b") ("b")) (S nil (S "a"
S "b") ("a")) (S nil (S "a" S "b") ("b")) (S nil nil ("a")) (S nil nil ("b"))))
+ (5 ((S (S "a" S "b") nil ("a")) (S (S "a" S "b") nil (e))))
+ (6 ((S (S) ("a" S "b") ("a")) (S (S) ("a" S "b") ("b")) (S (S "a" S)
("b") ("a")) (S (S "a" S) ("b") ("b"))))
+ (7 ((S (S "a" S "b") nil ("a")) (S (S "a" S "b") nil ("b")))))
+ (parser-generator--hash-to-list table-lr-items))))
(message "Passed LR-items for example 5.30 but with tokens as strings")
@@ -151,8 +121,6 @@
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
- (parser-generator-lr--reset)
-
(should
(equal
'((S nil (S a S b) (a))
@@ -236,16 +204,16 @@
(parser-generator--set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b)) (S e))
Sp))
(parser-generator--set-look-ahead-number 1)
- (parser-generator--process-grammar)
+
- (parser-generator-lr--reset)
- (parser-generator-lr--generate-goto-tables)
- (should
- (equal
- t
- (parser-generator-lr--items-valid-p (parser-generator--hash-values-to-list
parser-generator-lr--items t))))
+ (let ((table-lr-items (parser-generator--process-grammar)))
- (message "Passed first")
+ (should
+ (equal
+ t
+ (parser-generator-lr--items-valid-p
(parser-generator--hash-values-to-list table-lr-items t))))
+
+ (message "Passed first"))
(should
(equal
@@ -262,7 +230,7 @@
(parser-generator--set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b)) (S e))
Sp))
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
- (parser-generator-lr--reset)
+ (parser-generator-lr-generate-parser-tables)
(setq
parser-generator-lex-analyzer--function
@@ -283,6 +251,8 @@
'((2 2 2 1 1) nil)
(parser-generator-lr--parse)))
+ (message "Passed test with terminals as symbols")
+
(setq
parser-generator-lex-analyzer--function
(lambda (index)
@@ -300,12 +270,14 @@
(should-error
(parser-generator-lr--parse))
+ (message "Passed test with terminals as symbols, invalid syntax")
+
;; Test with terminals as strings here
(parser-generator--set-grammar '((Sp S) ("a" "b") ((Sp S) (S (S "a" S "b"))
(S e)) Sp))
(parser-generator--set-look-ahead-number 1)
(parser-generator--process-grammar)
- (parser-generator-lr--reset)
+ (parser-generator-lr-generate-parser-tables)
(setq
parser-generator-lex-analyzer--function
@@ -326,6 +298,8 @@
'((2 2 2 1 1) nil)
(parser-generator-lr--parse)))
+ (message "Passed test with terminals as string")
+
(setq
parser-generator-lex-analyzer--function
(lambda (index)
@@ -343,6 +317,8 @@
(should-error
(parser-generator-lr--parse))
+ (message "Passed test with terminals as string, invalid syntax")
+
(message "Passed tests for (parser-generator-lr--parse)"))
(defun parser-generator-lr-test ()
- [elpa] externals/parser-generator 76e30f1 210/434: Sorted lines in test file, (continued)
- [elpa] externals/parser-generator 76e30f1 210/434: Sorted lines in test file, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator e88abf0 117/434: More work on parser, added error-handling, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 8328ab3 130/434: Added unit test for failing LRk Grammar Parse, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator e89a740 138/434: Fixed bug with goto-table generation were tokens were strings, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator c667e18 121/434: Work on shift action in parsing algorithm, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator fab7e46 128/434: Fixed link to LRk grammar, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator bd06863 132/434: LR-parser now uses lex-analyzer for parsing, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator d14d427 140/434: Moved more about lex-analysis to separate document, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 1613e89 146/434: Added lex-analyzer get function, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 5c8a7a5 147/434: Preparations for SDT support, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 0e54a88 148/434: Optimized away one global variable,
ELPA Syncer <=
- [elpa] externals/parser-generator 60e9c8a 153/434: Preparations for translation-support in LR-parser, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 7ba32ff 154/434: Only save translation if it produces anything, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator f621e77 161/434: Preparations for testing incremental parse, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 944819d 163/434: More debugging incremental parsing, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator 668e738 164/434: More work on tests for incremental parse, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator ac7a9ab 168/434: Added TODO items, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator a18a23d 172/434: Updated info about SDT and SA, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator d6afd0b 180/434: Added TODO items, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator bbcb22f 182/434: Optimized memory usage for f-sets, ELPA Syncer, 2021/11/29
- [elpa] externals/parser-generator e2f4347 183/434: More work on f-set generation with e-identifiers, ELPA Syncer, 2021/11/29