branch: externals/parser-generator commit f5f7b2c82b5f997a64e783229f27c9e0c0f94804 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Added TODO items --- parser-generator-ll.el | 138 ++++++++++++++++++++------------------- test/parser-generator-ll-test.el | 26 +++++++- 2 files changed, 96 insertions(+), 68 deletions(-) diff --git a/parser-generator-ll.el b/parser-generator-ll.el index 674d7378cd..5c830d728e 100644 --- a/parser-generator-ll.el +++ b/parser-generator-ll.el @@ -30,13 +30,80 @@ (message "\n;; Starting generation of LL(k) parser-tables..\n") (unless (parser-generator-ll--valid-grammar-p) (error "Invalid grammar specified!")) - (setq - parser-generator-ll--parsing-table - (parser-generator-ll--generate-parsing-table - (parser-generator-ll--generate-tables))) + (let ((parsing-table) + (parser-generator-ll--generate-parsing-table + (parser-generator-ll--generate-tables))) + ;; TODO Generate hash-based parsing table here + (setq + parser-generator-ll--parsing-table + parsing-table)) (message "\n;; Completed generation of LL(k) parser-tables.\n")) +;; Generally described at .p 339 +(defun parser-generator-ll-parse () + "Parse input via lex-analyzer and return parse trail." + (let ((accept) + (stack + (list + (list + (parser-generator--get-grammar-start) + parser-generator--eof-identifier))) + (output)) + (while accept + (let* ((state (car stack)) + (state-action-table + (gethash + state + parser-generator-ll--parsing-table)) + (look-ahead + (parser-generator-lex-analyzer--peek-next-look-ahead))) + + (unless look-ahead + (signal + 'error + (format + "Reached end of input without accepting!"))) + + (unless (gethash look-ahead state-action-table) + (let ((possible-look-aheads)) + (maphash + (lambda (k _v) (push k possible-look-aheads)) + state-action-table) + (setq + possible-look-aheads + (sort state-action-table)) + (signal + 'error + (format + "Invalid look-ahead '%S' in state: '%S', valid look-aheads: '%S'" + look-ahead + state + possible-look-aheads)))) + + (let* ((action (gethash look-ahead state-action-table)) + (action-type action)) + (when (listp action) + (setq action-type (car action))) + (cond + ((equal action-type 'pop) + (push + (parser-generator-lex-analyzer--pop-token) + stack)) + + ((equal action-type 'reduce) + (push + (nth 1 action) + stack) + (push + (nth 2 action) + output)) + + ((equal action-type 'accept) + (setq accept t)))))) + output)) + + ;;; Algorithms @@ -472,69 +539,6 @@ (1+ sub-symbol-index)))))) valid)) -;; Generally described at .p 339 -(defun parser-generator-ll--parse () - "Parse input via lex-analyzer and return parse trail." - (let ((accept) - (stack - (list - (list - (parser-generator--get-grammar-start) - parser-generator--eof-identifier))) - (output)) - (while accept - (let* ((state (car stack)) - (state-action-table - (gethash - state - parser-generator-ll--parsing-table)) - (look-ahead - (parser-generator-lex-analyzer--peek-next-look-ahead))) - - (unless look-ahead - (signal - 'error - (format - "Reached end of input without accepting!"))) - - (unless (gethash look-ahead state-action-table) - (let ((possible-look-aheads)) - (maphash - (lambda (k _v) (push k possible-look-aheads)) - state-action-table) - (setq - possible-look-aheads - (sort state-action-table)) - (signal - 'error - (format - "Invalid look-ahead '%S' in state: '%S', valid look-aheads: '%S'" - look-ahead - state - possible-look-aheads)))) - - (let* ((action (gethash look-ahead state-action-table)) - (action-type action)) - (when (listp action) - (setq action-type (car action))) - (cond - ((equal action-type 'pop) - (push - (parser-generator-lex-analyzer--pop-token) - stack)) - - ((equal action-type 'reduce) - (push - (nth 1 action) - stack) - (push - (nth 2 action) - output)) - - ((equal action-type 'accept) - (setq accept t)))))) - output)) - (provide 'parser-generator-ll) diff --git a/test/parser-generator-ll-test.el b/test/parser-generator-ll-test.el index 58829b2f18..96bda89fe0 100644 --- a/test/parser-generator-ll-test.el +++ b/test/parser-generator-ll-test.el @@ -270,6 +270,25 @@ (message "Passed tests for (parser-generator-ll--generate-parsing-table)")) +(defun parser-generator-ll-test--parse () + "Test `parser-generator-ll-parse'." + (message "Started tests for (parser-generator-ll-parse)") + + ;; TODO Test example 5.5 p. 340 + ;; TODO Test example 5.12 p. 346-347 + ;; TODO Test example 5.16 p. 352 + ;; TODO Test example 5.17 p. 355 + + (message "Passed tests for (parser-generator-ll-parse)")) + +(defun parser-generator-ll-test--generate-parser-tables () + "Test `parser-generator-ll-generate-parser-tables'." + (message "Started tests for (parser-generator-ll-generate-parser-tables)") + + ;; TODO Do testing of hash-table generation here + + (message "Passed tests for (parser-generator-ll-generate-parser-tables)")) + (defun parser-generator-ll-test--valid-grammar-p () "Test `parser-generator-ll--valid-grammar-p'." (message "Started tests for (parser-generator-ll--valid-grammar-p)") @@ -323,9 +342,14 @@ (defun parser-generator-ll-test () "Run test." + ;; Helpers (parser-generator-ll-test--generate-tables) (parser-generator-ll-test--generate-parsing-table) - (parser-generator-ll-test--valid-grammar-p)) + (parser-generator-ll-test--valid-grammar-p) + + ;; Main stuff + (parser-generator-ll-test--generate-parser-tables) + (parser-generator-ll-test--parse)) (provide 'parser-generator-ll-test)