branch: externals/parser-generator commit 5d9b98ce39e27b6a28c690b950e302e5f2c08b8d Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Added functions to validate G and k and tests --- parser.el | 50 +++++++++++++++++++++++++--- test/parser-test.el | 96 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 126 insertions(+), 20 deletions(-) diff --git a/parser.el b/parser.el index 1a6fb09..9f305e0 100644 --- a/parser.el +++ b/parser.el @@ -201,11 +201,53 @@ "Calculate empty-free-first K tokens of PRODUCTION in PRODUCTIONS." (parser--first k production productions t)) -(defun parser--v-set (viable-prefix productions start) - "Calculate valid LR-sets for each VIABLE-PREFIX of PRODUCTIONS from START." +(defun parser--valid-look-ahead-number-p (k) + "Return if look-ahead number K is valid or not." + (and + (integerp k) + (>= k 0))) + +(defun parser--valid-grammar-p (G) + "Return if grammar G is valid or not. Grammar should contain list with 4 elements: non-terminals (N), terminals (T), productions (P), start (S) where N, T and P are lists and S is a symbol." + (let ((valid-p t)) + (unless (listp G) + (setq valid-p nil)) + (when (and + valid-p + (not (= (length G) 4))) + (setq valid-p nil)) + (when (and + valid-p + (or + (not (listp (nth 0 G))) + (not (listp (nth 1 G))) + (not (listp (nth 2 G))) + (not (symbolp (nth 3 G))))) + (setq valid-p nil)) + valid-p)) + +(defun parser--get-grammar-nonterminals (G) + "Return non-terminals of grammar G." + (nth 0 G)) + +(defun parser--get-grammar-terminals (G) + "Return terminals of grammar G." + (nth 1 G)) + +(defun parser--get-grammar-productions (G) + "Return productions of grammar G." + (nth 2 G)) + +(defun parser--get-grammar-start (G) + "Return start of grammar G." + (nth 3 G)) + +(defun parser--v-set (y G k) + "Calculate valid LRk-sets for the viable-prefix Y in grammar G with look-ahead K." (let ((v-set)) - (dolist (production productions) - ) + (unless (parser--valid-grammar-p G) + (error "Invalid grammar G!")) + v-set)) diff --git a/test/parser-test.el b/test/parser-test.el index 6ded36e..d12a4e5 100644 --- a/test/parser-test.el +++ b/test/parser-test.el @@ -172,7 +172,7 @@ ;; Example 5.28 page 402 (defun parser-test--empty-free-first () "Test `parser--empty-free-first'." - (message "Starting tests for (parser-test--empty-free-first)") + (message "Starting tests for (parser--empty-free-first)") ;; Example 5.28 p 402 (should @@ -188,33 +188,97 @@ (C c e))))) (message "Passed empty-free-first 2 with complex grammar") - (message "Passed tests for (parser-test--empty-free-first)")) + (message "Passed tests for (parser--empty-free-first)")) -(defun parser-test--v-set () - "Test `parser--v-set'." - (message "Starting tests for (parser-test--v-set)") +;; (defun parser-test--v-set () +;; "Test `parser--v-set'." +;; (message "Starting tests for (parser-test--v-set)") + +;; ;; Example 5.29 p 407 +;; (should +;; (equal +;; '("ca" "cb") +;; (parser--v-set +;; 'e +;; '((S' S) +;; (S SaSb) +;; (S e)) +;; 'S'))) +;; (message "Passed empty-free-first 2 with complex grammar") + +;; (message "Passed tests for (parser-test--v-set)")) + +(defun parser-test--valid-grammar-p () + "Test function `parser--valid-grammar-p'." + (message "Starting tests for (parser--valid-grammar-p)") - ;; Example 5.29 p 407 (should (equal - '("ca" "cb") - (parser--v-set - 'e - '((S' S) - (S SaSb) - (S e)) - 'S'))) - (message "Passed empty-free-first 2 with complex grammar") + nil + (parser--valid-grammar-p 'B))) - (message "Passed tests for (parser-test--v-set)")) + (should + (equal + nil + (parser--valid-grammar-p "A"))) + + (should + (equal + nil + (parser--valid-grammar-p '(A B C)))) + + (should + (equal + t + (parser--valid-grammar-p '((A B C) (a b c) ((A ab a)(B b)(C c)) A)))) + + (message "Passed tests for (parser--valid-grammar-p)")) + +(defun parser-test--valid-look-ahead-number-p () + "Test function `parser--valid-look-ahead-number-p'." + (message "Starting tests for (parser--valid-look-ahead-number-p)") + + (should + (equal + nil + (parser--valid-look-ahead-number-p 'A))) + + (should + (equal + nil + (parser--valid-look-ahead-number-p "A"))) + + (should + (equal + nil + (parser--valid-look-ahead-number-p -2))) + + (should + (equal + nil + (parser--valid-look-ahead-number-p 3.3))) + + (should + (equal + t + (parser--valid-look-ahead-number-p 2))) + + (should + (equal + t + (parser--valid-look-ahead-number-p 1))) + (message "Passed tests for (parser--valid-look-ahead-number-p)")) (defun parser-test () "Run test." + (parser-test--valid-look-ahead-number-p) + (parser-test--valid-grammar-p) (parser-test--distinct) (parser-test--first) (parser-test--empty-free-first) - (parser-test--v-set)) + ;; (parser-test--v-set) + ) (provide 'parser-test)