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

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

[elpa] externals/parser-generator 181b499 178/434: Fixed bug in FIRST ge


From: ELPA Syncer
Subject: [elpa] externals/parser-generator 181b499 178/434: Fixed bug in FIRST generation where multiple equal LHS:s
Date: Mon, 29 Nov 2021 15:59:35 -0500 (EST)

branch: externals/parser-generator
commit 181b49961892f451c1ac88b27fcf4143e41f8316
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>

    Fixed bug in FIRST generation where multiple equal LHS:s
---
 parser-generator.el           | 58 +++++++++++++++++++++++++++++++++++--------
 test/parser-generator-test.el |  9 +++++++
 2 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/parser-generator.el b/parser-generator.el
index 138bd59..96d017e 100644
--- a/parser-generator.el
+++ b/parser-generator.el
@@ -602,28 +602,63 @@
                   (let ((production-lhs (car p))
                         (production-rhs (cdr p)))
                     (parser-generator--debug
-                     (message "Production: %s -> %s" production-lhs 
production-rhs))
+                     (message
+                      "Production: %s -> %s"
+                      production-lhs
+                      production-rhs))
 
                     ;; Iterate all blocks in RHS
                     (let ((f-p-set))
                       (dolist (rhs-p production-rhs)
                         (let ((rhs-string rhs-p))
                           (let ((rhs-leading-terminals
-                                 (parser-generator--f-set rhs-string `(,k ,i 
,f-sets ,disallow-e-first) '(("" t 0)))))
+                                 (parser-generator--f-set
+                                  rhs-string
+                                  `(
+                                    ,k
+                                    ,i
+                                    ,f-sets
+                                    ,disallow-e-first)
+                                  '(("" t 0)))))
                             (parser-generator--debug
-                             (message "Leading %d terminals at index %s (%s) 
-> %s = %s" k i production-lhs rhs-string rhs-leading-terminals))
+                             (message
+                              "Leading %d terminals at index %s (%s) -> %s = 
%s"
+                              k
+                              i
+                              production-lhs
+                              rhs-string
+                              rhs-leading-terminals))
                             (when rhs-leading-terminals
                               (when (and
                                      (listp rhs-leading-terminals)
                                      (> (length rhs-leading-terminals) 0))
-                                (dolist (rhs-leading-terminals-element 
rhs-leading-terminals)
-                                  (push rhs-leading-terminals-element 
f-p-set)))))))
+                                (dolist
+                                    (rhs-leading-terminals-element 
rhs-leading-terminals)
+                                  (push
+                                   rhs-leading-terminals-element
+                                   f-p-set)))))))
+
+                      ;; If we have multiple equal LHS
+                      ;; merge them
+                      (when (gethash production-lhs f-set)
+                        (setq f-p-set
+                              (append
+                               f-p-set
+                               (gethash production-lhs f-set))))
 
                       ;; Make set distinct
                       (setq f-p-set (parser-generator--distinct f-p-set))
                       (parser-generator--debug
-                       (message "F_%s_%s(%s) = %s" i k production-lhs f-p-set))
-                      (puthash production-lhs (nreverse f-p-set) f-set))))
+                       (message
+                        "F_%s_%s(%s) = %s"
+                        i
+                        k
+                        production-lhs
+                        f-p-set))
+                      (puthash
+                       production-lhs
+                       (nreverse f-p-set)
+                       f-set))))
                 (puthash i f-set f-sets)
                 (setq i (+ i 1))))
             (if disallow-e-first
@@ -757,10 +792,11 @@
 
                  ((equal rhs-type 'EMPTY)
                   (if disallow-e-first
-                      (if (= leading-terminals-count 0)
-                          (setq all-leading-terminals-p nil)
-                        (setq leading-terminals (append leading-terminals 
rhs-element))
-                        (setq leading-terminals-count (1+ 
leading-terminals-count)))
+                      (when (= leading-terminals-count 0)
+                          (setq all-leading-terminals-p nil))
+                    ;; Add e-identifier to first when
+                    ;; we have not found any leading terminals
+                    ;; and we are at the last symbol in input-tape
                     (when (and
                            (= leading-terminals-count 0)
                            (= input-tape-index (1- input-tape-length)))
diff --git a/test/parser-generator-test.el b/test/parser-generator-test.el
index 943606d..3a5b5d2 100644
--- a/test/parser-generator-test.el
+++ b/test/parser-generator-test.el
@@ -305,6 +305,15 @@
     (parser-generator--first 'S)))
   (message "Passed first 4 with complex grammar with starting e-identifier 
variant 1")
 
+  (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)
+  (should
+   (equal
+    '((a) (e))
+    (parser-generator--first 'S)))
+  (message "Passed first 5 with complex grammar with starting e-identifier 
variant 2")
+
   
   (parser-generator-set-grammar '((Sp S) (a b) ((Sp S) (S (S a S b) e)) Sp))
   (parser-generator-set-look-ahead-number 2)



reply via email to

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