branch: externals/parser-generator commit 85d1b4916c6855d7a65dab81eff4ecb646b3f064 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Infix calculator translation passing some tests --- parser-generator-lr.el | 86 +++++++++++++++++++++++++++------------- parser-generator.el | 2 +- test/parser-generator-lr-test.el | 11 ++++- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/parser-generator-lr.el b/parser-generator-lr.el index 67343e1..8934b3f 100644 --- a/parser-generator-lr.el +++ b/parser-generator-lr.el @@ -1803,33 +1803,47 @@ (dolist (popped-item popped-items-contents) (parser-generator--debug (message - "popped-item: %s" + "popped-item: %s (for translation)" popped-item)) (if (and (listp popped-item) (cdr popped-item)) + ;; If item is a terminal, use it's literal value (push (parser-generator-lex-analyzer--get-function popped-item) popped-items-meta-contents) + + ;; If item is a non-terminal (let ((temp-hash-key (format "%S" popped-item))) + + ;; If we have a translation for symbol, pop one + ;; otherwise push nil on translation argument stack (if (gethash temp-hash-key translation-symbol-table) - (push - (gethash - temp-hash-key - translation-symbol-table) - popped-items-meta-contents) + (let ((symbol-translations + (gethash + temp-hash-key + translation-symbol-table))) + (let ((symbol-translation + (pop symbol-translations))) + (push + symbol-translation + popped-items-meta-contents) + (puthash + temp-hash-key + symbol-translations + translation-symbol-table))) (push nil popped-items-meta-contents))))) - ;; If we just have one argument, pass it as a scalar + ;; If we just have one argument, pass it as a instead of a list (if (= (length popped-items-meta-contents) 1) (setq popped-items-meta-contents @@ -1859,17 +1873,26 @@ "translation-symbol-table: %s = %s" production-lhs partial-translation)) - (puthash - (format - "%S" - production-lhs) - partial-translation - translation-symbol-table) - (setq - translation - partial-translation)) - - ;; When no translation is specified just use partial-translation as translation + (let ((symbol-translations + (gethash + (format + "%S" + production-lhs) + translation-symbol-table))) + (push + partial-translation + symbol-translations) + (puthash + (format + "%S" + production-lhs) + (reverse symbol-translations) + translation-symbol-table) + (setq + translation + partial-translation))) + + ;; When no translation is specified just use popped contents as translation (let ((partial-translation popped-items-meta-contents)) (parser-generator--debug @@ -1877,15 +1900,24 @@ "translation-symbol-table: %s = %s (generic)" production-lhs partial-translation)) - (puthash - (format - "%S" - production-lhs) - partial-translation - translation-symbol-table) - (setq - translation - partial-translation)))) + (let ((symbol-translations + (gethash + (format + "%S" + production-lhs) + translation-symbol-table))) + (push + partial-translation + symbol-translations) + (puthash + (format + "%S" + production-lhs) + (reverse symbol-translations) + translation-symbol-table) + (setq + translation + partial-translation))))) (let ((new-table-index (car pushdown-list))) (let ((goto-table-distinct-index diff --git a/parser-generator.el b/parser-generator.el index 72a44da..b3520c8 100644 --- a/parser-generator.el +++ b/parser-generator.el @@ -17,7 +17,7 @@ (defvar parser-generator--debug - t + nil "Whether to print debug messages or not.") (defvar diff --git a/test/parser-generator-lr-test.el b/test/parser-generator-lr-test.el index 7da377a..57f7381 100644 --- a/test/parser-generator-lr-test.el +++ b/test/parser-generator-lr-test.el @@ -684,12 +684,21 @@ (switch-to-buffer buffer) (kill-region (point-min) (point-max)) (insert "7-3\n") - (message "7-3=%S" (parser-generator-lr-translate)) (should (equal 4 (parser-generator-lr-translate))) (message "7-3=4\n") + + (switch-to-buffer buffer) + (kill-region (point-min) (point-max)) + (insert "3+4+5-6\n") + (should + (equal + 6 + (parser-generator-lr-translate))) + (message "3+4+5-6=6\n") + (kill-buffer)) (message "Passed tests for (parser-generator-lr--parse)"))