emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/parser-generator 8013f69 384/434: Unit tests for testin


From: ELPA Syncer
Subject: [elpa] externals/parser-generator 8013f69 384/434: Unit tests for testing precedence table generation now passes
Date: Mon, 29 Nov 2021 16:00:21 -0500 (EST)

branch: externals/parser-generator
commit 8013f693cb1c97c81186b1734d6b979e5c735281
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>

    Unit tests for testing precedence table generation now passes
---
 parser-generator-lr.el           |  88 ++++++++-
 test/parser-generator-lr-test.el | 389 ++-------------------------------------
 2 files changed, 93 insertions(+), 384 deletions(-)

diff --git a/parser-generator-lr.el b/parser-generator-lr.el
index be88680..1cd0534 100644
--- a/parser-generator-lr.el
+++ b/parser-generator-lr.el
@@ -161,12 +161,88 @@
            line-index
            (1+ line-index))))
 
-      ;; TODO Go through production-numbers
-      ;; TODO Look for attributes
-      ;; TODO Look for precedence-attributes
-      ;; TODO If none was found, iterate symbols
-      ;; TODO If found a last terminal, use it's precedence type and value
-      ;; TODO for the rule
+      ;; Go through production-numbers
+      (let ((productions (parser-generator--get-grammar-productions))
+            (production-number 0))
+        (dolist (production productions)
+          (let ((production-precedence-value)
+                (production-precedence-type))
+
+            ;; 1. Look for attributes
+            ;; 2. Look for precedence-attribute
+            ;; 3. Look for value and type of precedence-attribute
+            (when parser-generator-lr--context-sensitive-precedence-attribute
+              (let ((production-attributes
+                     
(parser-generator--get-grammar-context-sensitive-attributes-by-production-number
+                      production-number)))
+                (when production-attributes
+                  (let ((production-precedence-attribute
+                         (plist-get
+                          production-attributes
+                          
parser-generator-lr--context-sensitive-precedence-attribute)))
+                    (when production-precedence-attribute
+                      (let ((production-precedence-attribute-value
+                             (parser-generator-lr--get-symbol-precedence-value
+                              production-precedence-attribute))
+                            (production-precedence-attribute-type
+                             (parser-generator-lr--get-symbol-precedence-type
+                              production-precedence-attribute)))
+                        (when (and
+                               production-precedence-attribute-value
+                               production-precedence-attribute-type)
+                          (setq
+                           production-precedence-value
+                           production-precedence-attribute-value
+                           )
+                          (setq
+                           production-precedence-type
+                           production-precedence-attribute-type))))))))
+
+            ;; 1. If none was found
+            ;; 2. Iterate symbols of production RHS
+            ;; 3. If found a last terminal of RHS
+            ;; 4. Look for a precedence value and type of it
+            (unless production-precedence-value
+              (let ((rhs (car (cdr production)))
+                    (rhs-last-terminal))
+                (dolist (rhs-element rhs)
+                  (when (parser-generator--valid-terminal-p
+                         rhs-element)
+                    (setq
+                     rhs-last-terminal
+                     rhs-element)))
+
+                (when rhs-last-terminal
+                  (let ((terminal-precedence-value
+                         (parser-generator-lr--get-symbol-precedence-value
+                          rhs-last-terminal))
+                        (terminal-precedence-type
+                         (parser-generator-lr--get-symbol-precedence-type
+                          rhs-last-terminal)))
+                    (when (and
+                           terminal-precedence-value
+                           terminal-precedence-type)
+                      (setq
+                       production-precedence-value
+                       terminal-precedence-value)
+                      (setq
+                       production-precedence-type
+                       terminal-precedence-type))))))
+
+            (when (and
+                   production-precedence-type
+                   production-precedence-value)
+              (puthash
+               production-number
+               production-precedence-value
+               parser-generator-lr--production-number-precedence-value)
+              (puthash
+               production-number
+               production-precedence-type
+               parser-generator-lr--production-number-precedence-type))
+            (setq
+             production-number
+             (1+ production-number)))))
 
       )))
 
diff --git a/test/parser-generator-lr-test.el b/test/parser-generator-lr-test.el
index d3a7162..50a9e22 100644
--- a/test/parser-generator-lr-test.el
+++ b/test/parser-generator-lr-test.el
@@ -57,7 +57,7 @@
   "Test `parser-generator-lr--generate-precedence-tables'."
   (message "Starting tests for 
(parser-generator-lr--generate-precedence-tables)")
 
-  ;; TODO Test getting token precedence value and type
+  ;; Test getting token precedence value and type
   (setq
    parser-generator--global-attributes
    '(%left %precedence %right))
@@ -68,6 +68,9 @@
    parser-generator--context-sensitive-attributes
    '(%prec))
   (setq
+   parser-generator-lr--context-sensitive-precedence-attribute
+   '%prec)
+  (setq
    parser-generator--global-declaration
    '((%left a)
      (%right b)
@@ -80,7 +83,7 @@
      (
       (Sp S)
       (S (A c) B)
-      (A (a b))
+      (A (a b %prec a))
       (B (a b c %prec FIRST))
       )
      Sp))
@@ -142,14 +145,14 @@
     nil
     (parser-generator-lr--get-production-number-precedence-value 2)))
 
-  ;; A -> a b
+  ;; A -> a b %prec a
   (should
    (equal
-    '%right
+    '%left
     (parser-generator-lr--get-production-number-precedence-type 3)))
   (should
    (equal
-    1
+    0
     (parser-generator-lr--get-production-number-precedence-value 3)))
 
   ;; B -> a b c %prec FIRST
@@ -159,8 +162,9 @@
     (parser-generator-lr--get-production-number-precedence-type 4)))
   (should
    (equal
-    4
+    3
     (parser-generator-lr--get-production-number-precedence-value 4)))
+  (message "Passed generation of precedence value and type of productions.")
 
   ;; Grammar with conflicts that can be resolved
   ;; using context-sensitive precedence attributes
@@ -905,376 +909,6 @@
 
   (message "Passed tests for (parser-generator-lr--parse)"))
 
-(defun parser-generator-lr-test-infix-calculator ()
-  "Test infix calculator example."
-
-  ;; https://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html
-  ;; Lex-analyzer
-  (setq
-   parser-generator-lex-analyzer--function
-   (lambda (index)
-     (with-current-buffer "*buffer*"
-       (let ((token))
-         (when
-             (<
-              index
-              (point-max))
-           (goto-char
-            index)
-
-           ;; Skip white-space(s)
-           (when (looking-at-p "[\t ]+")
-             (when
-                 (search-forward-regexp "[^\t ]" nil t)
-               (forward-char -1)))
-
-           (cond
-            ((looking-at "\\([0-9]+\\.[0-9]+\\|[0-9]+\\)")
-             (setq
-              token
-              `(NUM ,(match-beginning 0) . ,(match-end 0))))
-            ((looking-at "\\(\\+\\|-\\|*\\|/\\|\\^\\|)\\|(\\|\n\\)")
-             (let ((symbol
-                    (buffer-substring-no-properties
-                     (match-beginning 0)
-                     (match-end 0))))
-               (setq
-                token
-                `(,symbol ,(match-beginning 0) . ,(match-end 0)))))
-            (t (error "Unexpected input at %d!" index))))
-         token))))
-  (setq
-   parser-generator-lex-analyzer--get-function
-   (lambda (token)
-     (with-current-buffer "*buffer*"
-       (let ((start (car (cdr token)))
-             (end (cdr (cdr token))))
-         (when (<= end (point-max))
-           (let ((symbol
-                  (buffer-substring-no-properties start end)))
-             (when
-                 (string-match-p "^\\([0-9]+\\.[0-9]+\\|[0-9]+\\)$" symbol)
-               (setq
-                symbol
-                (string-to-number symbol)))
-             symbol))))))
-  (setq
-   parser-generator--global-attributes
-   '(%left %precedence %right))
-  (setq
-   parser-generator-lr--global-precedence-attributes
-   '(%left %precedence %right))
-  (setq
-   parser-generator--global-declaration
-   '(
-     (%left "-" "+")
-     (%left "*" "/")
-     (%precedence NEG)
-     (%right "^")))
-  (setq
-   parser-generator--context-sensitive-attributes
-   '(%prec))
-  (setq
-   parser-generator-lr--precedence-comparison-function
-   (lambda(a b)
-     (if (and
-          (not a)
-          (not b))
-         nil
-       (let ((a-precedence)
-             (b-precedence))
-         (when a
-           (setq
-            a-precedence
-            (plist-get
-             a
-             '%precedence)))
-         (when b
-           (setq
-            b-precedence
-            (plist-get
-             b
-             '%precedence)))
-         (cond
-          ((and
-            a-precedence
-            (not b-precedence))
-           t)
-          ((and
-            b-precedence
-            (not a-precedence))
-           nil)
-          ((and
-            a-precedence
-            b-precedence
-            (>
-             a-precedence
-             b-precedence))
-           t)
-          ((and
-            a-precedence
-            b-precedence
-            (<
-             a-precedence
-             b-precedence))
-           nil)
-          ((and
-            a-precedence
-            b-precedence
-            (=
-             a-precedence
-             b-precedence))
-           ;; TODO Fix this
-           ;; TODO if a-precedence-value > b-precedence-value then reduce (t)
-           ;; TODO if a-precedence-value < b-precedence-value then shift (nil)
-           ;; TODO if a-precedence-value equal be-precedence-value then let 
operator decide
-           (cond
-            ((equal a-precedence))
-            )))))))
-  (parser-generator-set-grammar
-   '(
-     (start input line exp)
-     ("+" "-" "*" "/" "^" "(" ")" "\n" NUM)
-     (
-      (start input)
-      (input
-       %empty
-       (input line (lambda(args) (nth 1 args))))
-      (line
-       "\n"
-       (exp "\n" (lambda(args) (nth 0 args))))
-      (exp
-       NUM
-       (exp "+" exp (lambda(args) (+ (nth 0 args) (nth 2 args))))
-       (exp "-" exp (lambda(args) (- (nth 0 args) (nth 2 args))))
-       (exp "*" exp (lambda(args) (* (nth 0 args) (nth 2 args))))
-       (exp "/" exp (lambda(args) (/ (nth 0 args) (nth 2 args))))
-       ("-" exp %prec NEG (lambda(args) (- (nth 1 args))))
-       (exp "^" exp (lambda(args) (expt (nth 0 args) (nth 2 args))))
-       ("(" exp ")" (lambda(args) (nth 1 args)))))
-     start))
-
-  (setq
-   parser-generator--e-identifier
-   '%empty)
-  (parser-generator-set-look-ahead-number
-   1)
-
-  ;; Add global symbol precedence and also
-  ;; context-sensitive precedence and grammar should now pass without conflicts
-  (setq
-   parser-generator--context-sensitive-attributes
-   '(%prec))
-  (setq
-   parser-generator--global-attributes
-   '(%left %precedence %right))
-  (setq
-   parser-generator-lr--global-precedence-attributes
-   '(%left %precedence %right))
-  (setq
-   parser-generator-lr--context-sensitive-precedence-attribute
-   '%prec)
-  ;; https://www.gnu.org/software/bison/manual/html_node/How-Precedence.html
-  (setq
-   parser-generator-lr--precedence-comparison-function
-   (lambda(a b)
-     (let ((a-max-op)
-           (a-max-value)
-           (b-max-op)
-           (b-max-value))
-       (when a
-         (let ((a-left (plist-get a '%left))
-               (a-precedence (plist-get a '%precedence))
-               (a-right (plist-get a '%right)))
-           (when (and
-                  a-left
-                  (or
-                   (not a-max-value)
-                   (> a-left a-max-value)))
-             (setq a-max-op '%left)
-             (setq a-max-value a-left))
-           (when (and
-                  a-precedence
-                  (or
-                   (not a-max-value)
-                   (> a-precedence a-max-value)))
-             (setq a-max-op '%precedence)
-             (setq a-max-value a-precedence))
-           (when (and
-                  a-right
-                  (or
-                   (not a-max-value)
-                   (> a-right a-max-value)))
-             (setq a-max-op '%right)
-             (setq a-max-value a-right))))
-       (when b
-         (let ((b-left (plist-get b '%left))
-               (b-precedence (plist-get b '%precedence))
-               (b-right (plist-get b '%right)))
-           (when (and
-                  b-left
-                  (or
-                   (not b-max-value)
-                   (> b-left b-max-value)))
-             (setq b-max-op '%left)
-             (setq b-max-value b-left))
-           (when (and
-                  b-precedence
-                  (or
-                   (not b-max-value)
-                   (> b-precedence b-max-value)))
-             (setq b-max-op '%precedence)
-             (setq b-max-value b-precedence))
-           (when (and
-                  b-right
-                  (or
-                   (not b-max-value)
-                   (> b-right b-max-value)))
-             (setq b-max-op '%right)
-             (setq b-max-value b-right))))
-       (cond
-        ((and
-          a-max-value
-          (or
-           (not b-max-value)
-           (> a-max-value b-max-value)))
-         t)
-        ((and
-          b-max-value
-          (or
-           (not a-max-value)
-           (> b-max-value a-max-value)))
-         nil)
-        ((and
-          a-max-value
-          b-max-value
-          (= a-max-value b-max-value))
-         (cond
-          ((or
-            (equal a-max-op '%left)
-            (equal a-max-op '%precedence))
-           t)
-          (t nil)))))))
-  (setq
-   parser-generator--global-declaration
-   '(
-     (%left "-" "+")
-     (%left "*" "/")
-     (%precedence NEG)
-     (%right "^")
-     ))
-  (parser-generator-set-grammar
-   '(
-     (start input line exp)
-     ("+" "-" "*" "/" "^" "(" ")" "\n" NUM)
-     (
-      (start input)
-      (input
-       %empty
-       (input line (lambda(args) (nth 1 args))))
-      (line
-       "\n"
-       (exp "\n" (lambda(args) (nth 0 args))))
-      (exp
-       NUM
-       (exp "+" exp (lambda(args) (+ (nth 0 args) (nth 2 args))))
-       (exp "-" exp (lambda(args) (- (nth 0 args) (nth 2 args))))
-       (exp "*" exp (lambda(args) (* (nth 0 args) (nth 2 args))))
-       (exp "/" exp (lambda(args) (/ (nth 0 args) (nth 2 args))))
-       ("-" exp %prec NEG (lambda(args) (- (nth 1 args))))
-       (exp "^" exp (lambda(args) (expt (nth 0 args) (nth 2 args))))
-       ("(" exp ")" (lambda(args) (nth 1 args)))))
-     start))
-  (parser-generator-process-grammar)
-
-  (parser-generator-lr-generate-parser-tables)
-  (let ((buffer (generate-new-buffer "*buffer*")))
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "4* 5 + 3\n")
-    (should
-     (equal
-      23
-      (parser-generator-lr-translate)))
-    (message "Passed 4* 5 + 3 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "10/1+1\n")
-    (should
-     (equal
-      11
-      (parser-generator-lr-translate)))
-    (message "Passed 10/1+1 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "10^2+3\n")
-    (should
-     (equal
-      103
-      (parser-generator-lr-translate)))
-    (message "Passed 10^2+3 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "-33+5\n")
-    (should
-     (equal
-      -28
-      (parser-generator-lr-translate)))
-    (message "Passed -33+5 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "- 33 - 3\n")
-    (should
-     (equal
-      -36
-      (parser-generator-lr-translate)))
-    (message "Passed - 33 - 3 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "3 ^ 2\n")
-    (should
-     (equal
-      9
-      (parser-generator-lr-translate)))
-    (message "Passed 3 ^ 2 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "-56 + 2\n")
-    (should
-     (equal
-      -54
-      (parser-generator-lr-translate)))
-    (message "Passed -56 + 2 with correct result")
-
-    ;; TODO This should work
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "4 + 5  *3\n")
-    (should
-     (equal
-      19
-      (parser-generator-lr-translate)))
-    (message "Passed 4 + 5  *3 with correct result")
-
-    (switch-to-buffer buffer)
-    (kill-region (point-min) (point-max))
-    (insert "4 + 4.5 - (34/(8*3+-3))\n")
-    (should
-     (equal
-      6.880952381
-      (parser-generator-lr-translate)))
-    (message "Passed 4 + 4.5 - (34/(8*3+-3)) with correct result")
-
-    (kill-buffer))
-  )
-
 (defun parser-generator-lr-test-parse-k-2 ()
   "Test `parser-generator-lr-parse' with k = 2."
   (message "Started tests for (parser-generator-lr-parse) k = 2")
@@ -2047,8 +1681,7 @@
   (parser-generator-lr-test-parse)
   (parser-generator-lr-test-translate)
   (parser-generator-lr-test-parse-k-2)
-  (parser-generator-lr-test-parse-k-0)
-  (parser-generator-lr-test-infix-calculator))
+  (parser-generator-lr-test-parse-k-0))
 
 
 (provide 'parser-generator-lr-test)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]