branch: externals/parser-generator
commit f5f7b2c82b5f997a64e783229f27c9e0c0f94804
Author: Christian Johansson <[email protected]>
Commit: Christian Johansson <[email protected]>
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)