branch: externals/parser-generator commit 65d9ce2d5161c70b6c1ae861a57919dffbc84672 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Fixed a bug with E-FREE-FIRST function and function that validates a set of LR-items --- parser-lr.el | 4 +++- parser.el | 21 ++++++++++++++++++--- test/parser-test.el | 8 ++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/parser-lr.el b/parser-lr.el index b46fb9d..9a33364 100644 --- a/parser-lr.el +++ b/parser-lr.el @@ -269,7 +269,9 @@ (message "a-look-ahead: %s" a-look-ahead)) ;; The only sets of LR items which need to be tested are those that contain a dot at the right end of a production - (unless a-look-ahead + (when (and + (nth 1 a) + (not a-look-ahead)) (setq a-follow (nth 3 a)) (parser--debug diff --git a/parser.el b/parser.el index 61df8fd..d4a110b 100644 --- a/parser.el +++ b/parser.el @@ -29,6 +29,10 @@ nil "Generated F-sets for grammar.") +(defvar parser--f-free-sets + nil + "Generated e-free F-sets for grammar.") + (defvar parser--look-ahead-number nil "Current look-ahead number used.") @@ -68,7 +72,8 @@ (defun parser--clear-cache () "Clear cache." - (setq parser--f-sets nil)) + (setq parser--f-sets nil) + (setq parser--f-free-sets nil)) (defun parser--distinct (elements) "Return distinct of ELEMENTS." @@ -658,8 +663,13 @@ (let ((productions (parser--get-grammar-productions)) (k parser--look-ahead-number)) (let ((i-max (length productions))) + ;; Generate F-sets only once per grammar - (unless parser--f-sets + (unless (or + (and (not disallow-e-first) + parser--f-sets) + (and disallow-e-first + parser--f-free-sets)) (let ((f-sets (make-hash-table :test 'equal)) (i 0)) (while (< i i-max) @@ -695,6 +705,8 @@ (puthash production-lhs (nreverse f-p-set) f-set)))) (puthash i f-set f-sets) (setq i (+ i 1)))) + (if disallow-e-first + (setq parser--f-free-sets f-sets)) (setq parser--f-sets f-sets))) (parser--debug @@ -723,7 +735,10 @@ ((parser--valid-non-terminal-p symbol) (parser--debug (message "non-terminal symbol: %s" symbol)) - (let ((symbol-f-set (gethash symbol (gethash (1- i-max) parser--f-sets)))) + (let ((symbol-f-set)) + (if disallow-e-first + (setq symbol-f-set (gethash symbol (gethash (1- i-max) parser--f-free-sets))) + (setq symbol-f-set (gethash symbol (gethash (1- i-max) parser--f-sets)))) (parser--debug (message "symbol-f-set: %s" symbol-f-set)) (when (> (length symbol-f-set) 1) diff --git a/test/parser-test.el b/test/parser-test.el index 7cb3ee8..681709c 100644 --- a/test/parser-test.el +++ b/test/parser-test.el @@ -313,6 +313,14 @@ (parser--e-free-first 'S))) (message "Passed empty-free-first 2 with complex grammar") + (parser--set-look-ahead-number 1) + (parser--process-grammar) + (should + (equal + '((c)) + (parser--e-free-first '(S b a)))) + (message "Passed empty-free-first 1 with complex grammar") + (message "Passed tests for (parser--empty-free-first)")) (defun parser-test--valid-grammar-p ()