branch: externals/parser-generator
commit 9e8b89bac986a0cd539fdf5d2352cacc70a3231d
Author: Christian Johansson <christ...@cvj.se>
Commit: Christian Johansson <christ...@cvj.se>

    More work on exporting LR-parser
---
 parser-generator-lr-export.el           | 349 +++++++++++++++++++++-----------
 test/parser-generator-lr-export-test.el |  13 +-
 2 files changed, 237 insertions(+), 125 deletions(-)

diff --git a/parser-generator-lr-export.el b/parser-generator-lr-export.el
index a90a392..2862221 100644
--- a/parser-generator-lr-export.el
+++ b/parser-generator-lr-export.el
@@ -52,73 +52,73 @@
        (format
         ";;; %s.el --- Exported Emacs Parser Generator -*- lexical-binding: t 
-*-\n\n\n"
         namespace))
-      (insert ";;; Commentary:\n\n\n;;; Code:\n\n\n")
+      (insert ";;; Commentary:\n\n\n;;; Code:\n\n")
 
-      (insert ";;; Constants:\n\n\n")
+      (insert "\n;;; Constants:\n\n\n")
 
       ;; Action-tables
       (insert
        (format
-        "(defconst\n  %s--action-tables\n  %S\n  \"Generated 
action-tables.\")\n\n"
+        "(defconst\n  %s--action-tables\n  %S\n  \"The generated 
action-tables.\")\n\n"
         namespace
         parser-generator-lr--action-tables))
       (insert
        (format
-        "(defconst\n  %s--distinct-action-tables\n  %S\n  \"Generated distinct 
action-tables.\")\n\n"
+        "(defconst\n  %s--distinct-action-tables\n  %S\n  \"The generated 
distinct action-tables.\")\n\n"
         namespace
         parser-generator-lr--distinct-action-tables))
 
       ;; Goto-tables
       (insert
        (format
-        "(defconst\n  %s--goto-tables\n  %S\n  \"Generated goto-tables.\")\n\n"
+        "(defconst\n  %s--goto-tables\n  %S\n  \"The generated 
goto-tables.\")\n\n"
         namespace
         parser-generator-lr--goto-tables))
       (insert
        (format
-        "(defconst\n  %s--distinct-goto-tables\n  %S\n  \"Generated distinct 
goto-tables.\")\n\n"
+        "(defconst\n  %s--distinct-goto-tables\n  %S\n  \"The generated 
distinct goto-tables.\")\n\n"
         namespace
         parser-generator-lr--distinct-goto-tables))
 
       ;; Table production-number
       (insert
        (format
-        "(defconst\n  %s--table-productions-number-reverse\n  %S\n  
\"Hash-table indexed by production-number and value is production.\")\n\n"
+        "(defconst\n  %s--table-productions-number-reverse\n  %S\n  \"The 
hash-table indexed by production-number and value is production.\")\n\n"
         namespace
         parser-generator--table-productions-number-reverse))
 
       ;; Table look-aheads
       (insert
        (format
-        "(defconst\n  %s--table-look-aheads\n  %S\n  \"Hash-table of valid 
look-aheads.\")\n\n"
+        "(defconst\n  %s--table-look-aheads\n  %S\n  \"The hash-table of valid 
look-aheads.\")\n\n"
         namespace
         parser-generator--table-look-aheads-p))
 
       ;; Table terminals
       (insert
        (format
-        "(defconst\n  %s--table-terminal-p\n  %S\n  \"Hash-table of valid 
terminals.\")\n\n"
+        "(defconst\n  %s--table-terminal-p\n  %S\n  \"The hash-table of valid 
terminals.\")\n\n"
         namespace
         parser-generator--table-terminal-p))
 
       ;; Table non-terminals
       (insert
        (format
-        "(defconst\n  %s--table-non-terminal-p\n  %S\n  \"Hash-table of valid 
non-terminals.\")\n\n"
+        "(defconst\n  %s--table-non-terminal-p\n  %S\n  \"The hash-table of 
valid non-terminals.\")\n\n"
         namespace
         parser-generator--table-non-terminal-p))
 
       ;; Table translations
       (insert
        (format
-        "(defconst\n  %s--table-translations\n  %S\n  \"Hash-table of 
translations.\")\n\n"
+        "(defconst\n  %s--table-translations\n  %S\n  \"The hash-table of 
translations.\")\n\n"
         namespace
         parser-generator--table-translations))
 
       ;; Lex-Analyzer Get Function
       (insert
        (format
-        "(defconst\n  %s-lex-analyzer--get-function\n  (lambda %S %S)\n  
\"Lex-Analyzer Get Function.\")\n\n"
+        "(defconst\n  %s-lex-analyzer--get-function\n  (lambda %S %S)\n  \"The 
lex-analyzer get function.\")\n\n"
         namespace
         (nth 2 parser-generator-lex-analyzer--get-function)
         (nth 3 parser-generator-lex-analyzer--get-function)))
@@ -126,7 +126,7 @@
       ;; Lex-Analyzer Function
       (insert
        (format
-        "(defconst\n  %s-lex-analyzer--function\n  (lambda %S %S)\n  
\"Lex-Analyzer Function.\")\n\n"
+        "(defconst\n  %s-lex-analyzer--function\n  (lambda %S %S)\n  \"The 
lex-analyzer function.\")\n\n"
         namespace
         (nth 2 parser-generator-lex-analyzer--function)
         (nth 3 parser-generator-lex-analyzer--function)))
@@ -143,40 +143,40 @@
             (nth 2 parser-generator-lex-analyzer--reset-function)
             (nth 3 parser-generator-lex-analyzer--reset-function)))
         (insert "nil\n"))
-      (insert "  \"Lex-Analyzer Reset Function.\")\n\n")
+      (insert "  \"The lex-analyzer reset function.\")\n\n")
 
       ;; E-identifier
       (insert
        (format
-        "(defconst\n  %s--e-identifier\n  '%S\n  \"e-identifier\")\n\n"
+        "(defconst\n  %s--e-identifier\n  '%S\n  \"The e-identifier.\")\n\n"
         namespace
         parser-generator--e-identifier))
 
       ;; EOF-identifier
       (insert
        (format
-        "(defconst\n  %s--eof-identifier\n  '%S\n  \"EOF-identifier.\")\n\n"
+        "(defconst\n  %s--eof-identifier\n  '%S\n  \"The 
end-of-file-identifier.\")\n\n"
         namespace
         parser-generator--eof-identifier))
 
       ;; Look-ahead number
       (insert
        (format
-        "(defconst\n  %s--look-ahead-number\n  %S\n  \"Look-ahead 
number.\")\n\n"
+        "(defconst\n  %s--look-ahead-number\n  %S\n  \"The look-ahead 
number.\")\n\n"
         namespace
         parser-generator--look-ahead-number))
 
-      (insert "\n;;; Variables:\n\n\n")
+      (insert "\n;;; Variables:\n\n")
 
       ;; Lex-analyzer index
       (insert
        (format
-        "(defvar-local\n  %s-lex-analyzer--index\n  0\n  \"Current index of 
lex-analyzer.\")\n\n"
+        "(defvar-local\n  %s-lex-analyzer--index\n  0\n  \"The current index 
of the lex-analyzer.\")\n\n"
         namespace))
 
-      (insert "\n;;; Functions:\n\n\n")
+      (insert "\n;;; Functions:\n\n")
 
-      (insert ";;; Lex-Analyzer:\n\n\n")
+      (insert "\n;;; Lex-Analyzer:\n\n")
 
       ;; Lex-Analyzer Get Function
       (insert
@@ -196,10 +196,10 @@
         namespace
         namespace))
       (insert "
-      (error
+      (error (error
         \"Lex-analyze failed to get token meta-data of %s, error: %s\"
         token
-        (car (cdr error))))
+        (car (cdr error)))))
     (unless meta-information
       (error \"Could not find any token meta-information for: %s\" token))
     meta-information))\n")
@@ -309,7 +309,7 @@
     (nreverse tokens)))\n"
                       namespace))
 
-      (insert "\n;;; Syntax-Analyzer / Parser:\n\n\n");
+      (insert "\n\n;;; Syntax-Analyzer / Parser:\n\n");
 
       ;; Get grammar production by number
       (insert
@@ -443,6 +443,16 @@
          input-tape-index)
       (%s-lex-analyzer--reset))
 
+    ;; Make sure tables exists
+    (unless %s--action-tables
+      (error \"Missing action-tables for grammar!\"))
+    (unless %s--distinct-action-tables
+      (error \"Missing distinct GOTO-tables for grammar!\"))
+    (unless %s--goto-tables
+      (error \"Missing GOTO-tables for grammar!\"))
+    (unless %s--distinct-goto-tables
+      (error \"Missing distinct GOTO-tables for grammar!\"))
+
     (let ((accept)
           (pre-index 0))
       (while (not accept)
@@ -506,7 +516,14 @@
                namespace
                namespace
                namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
                namespace))
+
       (insert "
               (unless action-table
                 (error
@@ -626,7 +643,6 @@
                            %s-lex-analyzer--index
                            possible-look-aheads))
 
-                        ;; Maybe push both tokens here?
                         (push (car a-full) pushdown-list)
                         (push next-index pushdown-list)
                         (%s-lex-analyzer--pop-token))))))
@@ -667,8 +683,10 @@
                               (setq popped-items (1+ popped-items)))))
                         (push production-number output)
 
-                        (let ((popped-items-meta-contents)
-                              (all-expanded t))
+                        (let ((popped-items-meta-contents))
+                          (setq
+                           popped-items-contents
+                           (reverse popped-items-contents))
                           ;; Collect arguments for translation
                           (dolist (popped-item popped-items-contents)
                             (if (and
@@ -678,55 +696,145 @@
                                 (push
                                  (%s-lex-analyzer--get-function
                                   popped-item)
-                                 popped-items-meta-contents)
+                                 popped-items-meta-contents)"
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace))
+
+      (insert "
+
+                              ;; If item is a non-terminal
+                              (let ((temp-hash-key
+                                     (format
+                                      \"%S\"
+                                       popped-item)))
+")
+
+      (insert (format "
+                                  ;; If we have a translation for symbol, pop 
one
+                                  ;; otherwise push nil on translation 
argument stack
                               (if (gethash
-                                   popped-item
+                                   temp-hash-key
                                    translation-symbol-table)
-                                  (push
-                                   (gethash
-                                    popped-item
-                                    translation-symbol-table)
-                                   popped-items-meta-contents)
-                                (setq
-                                 all-expanded
-                                 nil)
-                                (push
-                                 nil
-                                 popped-items-meta-contents))))
-                          (setq
-                           popped-items-meta-contents
-                           (nreverse popped-items-meta-contents))
+                                  (let ((symbol-translations
+                                         (gethash
+                                          temp-hash-key
+                                          translation-symbol-table)))
+                                    (push
+                                     partial-translation
+                                     symbol-translations)
+                                    (puthash
+                                     temp-hash-key
+                                     symbol-translations
+                                     translation-symbol-table)
+                                    (setq
+                                     translation
+                                     partial-translation))))))
+
+                          ;; If we have a translation for symbol, pop one
+                                  ;; otherwise push nil on translation 
argument stack
+                                  (if (gethash
+                                       temp-hash-key
+                                       translation-symbol-table)
+                                      (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 
instead of a list
+                            (when (= (length popped-items-meta-contents) 1)
+                              (setq
+                               popped-items-meta-contents
+                               (car popped-items-meta-contents)))
+
+                            ;; Perform translation at reduction if specified
+                            (if
+                                
(parser-generator--get-grammar-translation-by-number
+                                 production-number)
+                                (let ((partial-translation
+                                       (funcall
+                                        
(parser-generator--get-grammar-translation-by-number
+                                         production-number)
+                                        popped-items-meta-contents)))"
+                      namespace
+                      namespace
+                      namespace
+                      namespace
+                      namespace
+                      namespace))
 
-                          ;; Perform translation at reduction if specified
-                          (if
-                              (%s--get-grammar-translation-by-number
-                               production-number)
-                              (let ((partial-translation
-                                     (funcall
-                                      (%s--get-grammar-translation-by-number
-                                       production-number)
-                                      popped-items-meta-contents)))
-                                (puthash
-                                 production-lhs
-                                 partial-translation
-                                 translation-symbol-table)
-                                (setq
-                                 translation
-                                 partial-translation))
-
-                            ;; When no translation is specified just use 
arguments as translation
-                            (when all-expanded
+      (insert "
+                                  (let ((temp-hash-key
+                                         (format
+                                          \"%S\"
+                                          production-lhs)))")
+
+      (insert (format "
+                                    (let ((symbol-translations
+                                           (gethash
+                                            temp-hash-key
+                                            translation-symbol-table)))
+                                      (push
+                                       partial-translation
+                                       symbol-translations)
+                                      (puthash
+                                       temp-hash-key
+                                       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))
-                                (puthash
-                                 production-lhs
-                                 partial-translation
-                                 translation-symbol-table)
-                                (setq
-                                 translation
-                                 partial-translation)))))
-
-                        (let ((new-table-index (car pushdown-list)))
+                                     popped-items-meta-contents))"
+                                          namespace
+                                          namespace
+                                          namespace
+                                          namespace
+                                          namespace
+                                          namespace
+                                          namespace))
+               (insert "
+                                (let ((temp-hash-key
+                                       (format
+                                        \"%S\"
+                                        production-lhs)))")
+
+               (insert (format "
+                                  (let ((symbol-translations
+                                         (gethash
+                                          temp-hash-key
+                                          translation-symbol-table)))
+                                    (push
+                                     partial-translation
+                                     symbol-translations)
+                                    (puthash
+                                     temp-hash-key
+                                     symbol-translations
+                                     translation-symbol-table)
+                                    (setq
+                                     translation
+                                     partial-translation))))))
+
+                          (let ((new-table-index (car pushdown-list)))
                             (let ((goto-table-distinct-index
                                    (gethash
                                     new-table-index
@@ -735,52 +843,41 @@
                                      (gethash
                                       goto-table-distinct-index
                                       %s--distinct-goto-tables)))
-                            (let ((goto-table-length
-                                   (length goto-table))
-                                  (goto-index 0)
-                                  (searching-match t)
-                                  (next-index))
-
-                              (while (and
-                                      searching-match
-                                      (< goto-index goto-table-length))
-                                (let ((goto-item (nth goto-index goto-table)))
-                                  (let ((goto-item-symbol (list (car 
goto-item)))
-                                        (goto-item-next-index (car (cdr 
goto-item))))
-
-                                    (when (equal
-                                           goto-item-symbol
-                                           production-lhs)
-                                      (setq next-index goto-item-next-index)
-                                      (setq searching-match nil))))
-
-                                (setq goto-index (1+ goto-index)))
-
-                              (when next-index
-                                (push production-lhs pushdown-list)
-                                (push next-index pushdown-list))))))))))
-
-                 ((equal action-match '(accept))
-                  ;;    (d) If f(u) = accept, we halt and declare the string
-                  ;;    in the output buffer to be the right parse of the 
original
-                  ;;    input string.
-
-                  (setq accept t))"
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace
-               namespace))
-
-      (insert "
-                 (t (error
-                     \"Invalid action-match: %s!\"
-                     action-match)))))))))
+                                (let ((goto-table-length
+                                       (length goto-table))
+                                      (goto-index 0)
+                                      (searching-match t)
+                                      (next-index))
+
+                                  (while (and
+                                          searching-match
+                                          (< goto-index goto-table-length))
+                                    (let ((goto-item (nth goto-index 
goto-table)))
+                                      (let ((goto-item-symbol (list (car 
goto-item)))
+                                            (goto-item-next-index (car (cdr 
goto-item))))
+
+                                        (when (equal
+                                               goto-item-symbol
+                                               production-lhs)
+                                          (setq next-index 
goto-item-next-index)
+                                          (setq searching-match nil))))
+
+                                    (setq goto-index (1+ goto-index)))
+
+                                  (when next-index
+                                    (push production-lhs pushdown-list)
+                                    (push next-index pushdown-list))))))))))
+
+                   ((equal action-match '(accept))
+                    ;;    (d) If f(u) = accept, we halt and declare the string
+                    ;;    in the output buffer to be the right parse of the 
original
+                    ;;    input string.
+
+                    (setq accept t))
+
+                   (t (error
+                       \"Invalid action-match: %s!\"
+                       action-match)))))))))
       (unless accept
         (error
          \"Parsed entire string without getting accepting! Output: %s\"
@@ -801,7 +898,19 @@
          output
          translation
          translation-symbol-table-list
-         history)))))\n")
+         history)))))"
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               namespace
+               ))
 
       ;; Parse
       (insert
@@ -823,6 +932,8 @@
           history)))
     (nth 0 result)))\n"
                namespace
+               namespace
+               namespace
                namespace))
 
       ;; Translate
diff --git a/test/parser-generator-lr-export-test.el 
b/test/parser-generator-lr-export-test.el
index 0d8b30a..b9a7558 100644
--- a/test/parser-generator-lr-export-test.el
+++ b/test/parser-generator-lr-export-test.el
@@ -176,22 +176,22 @@
   (message "Passed parse before export")
 
   ;; Export parser
-  (let ((export (parser-generator-lr-export-to-elisp "e--")))
+  (let ((export (parser-generator-lr-export-to-elisp "e")))
+
+    (message "export:\n%S\n" export)
 
-    (parser-generator--debug
-     (message "export:\n%s\n" export))
     (with-temp-buffer
       (insert export)
       (eval-buffer)
       (should
        (equal
         t
-        (fboundp 'e---parse)))
-      (when (fboundp 'e---parse)
+        (fboundp 'e-parse)))
+      (when (fboundp 'e-parse)
         (should
          (equal
           '(2 2 2 1 1)
-          (e---parse))))
+          (e-parse))))
       (message "Passed parse for exported parser")))
 
   (let ((buffer (generate-new-buffer "*a*")))
@@ -232,6 +232,7 @@
     ;; Export parser
     (let ((export (parser-generator-lr-export-to-elisp "fa")))
       (with-temp-buffer
+        (message "Export:\n%S" export)
         (insert export)
         (eval-buffer)
         (should

Reply via email to