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

    More work on supporting LR-grammar with precedence attributes
---
 parser-generator-lr.el           | 52 ++++++++++++++++++++++++++++++----------
 test/parser-generator-lr-test.el | 29 +++++++++++++---------
 2 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/parser-generator-lr.el b/parser-generator-lr.el
index 59b2994..5da6882 100644
--- a/parser-generator-lr.el
+++ b/parser-generator-lr.el
@@ -34,6 +34,16 @@
   nil
   "Goto-tables for grammar.")
 
+(defvar
+  parser-generator-lr--precedence-attribute
+  nil
+  "Attribute used for precedence.")
+
+(defvar
+  parser-generator-lr--precedence-comparison-function
+  nil
+  "Function used for resolving precedence.")
+
 
 ;; Main Algorithms
 
@@ -766,18 +776,36 @@
                 (when (equal
                        a-follow
                        b-suffix-follow-eff-item)
-                  (when
-                      signal-on-false
-                    (error
-                     "Inconsistent grammar! %S (index: %d) with look-ahead %S 
conflicts with %S (index: %d) with look-ahead %S in sets: %S"
-                     a
-                     a-index
-                     a-follow-full
-                     b
-                     b-index
-                     b-suffix-follow-eff-item-full
-                     lr-item-sets))
-                  (setq valid-p nil))))
+
+                  ;; If it's the same symbol but we have a precedence
+                  ;; attribute on any of them, or both, pass anyway
+                  (unless
+                      (and
+                       parser-generator-lr--precedence-attribute
+                       parser-generator-lr--precedence-comparison-function
+                       (or
+                        (and
+                         (listp (car a-follow-full))
+                         (plist-get
+                          (car (cdr (car a-follow-full)))
+                          parser-generator-lr--precedence-attribute))
+                        (and
+                         (listp (car b-suffix-follow-eff-item-full))
+                         (plist-get
+                          (car (cdr (car b-suffix-follow-eff-item-full)))
+                          parser-generator-lr--precedence-attribute))))
+                    (when
+                        signal-on-false
+                      (error
+                       "Inconsistent grammar! %S (index: %d) with look-ahead 
%S conflicts with %S (index: %d) with look-ahead %S in sets: %S"
+                       a
+                       a-index
+                       a-follow-full
+                       b
+                       b-index
+                       b-suffix-follow-eff-item-full
+                       lr-item-sets))
+                    (setq valid-p nil)))))
             (setq b-index (1+ b-index))))
         (setq a-index (1+ a-index)))
       (setq set-index (1+ set-index)))
diff --git a/test/parser-generator-lr-test.el b/test/parser-generator-lr-test.el
index 2834844..fd38794 100644
--- a/test/parser-generator-lr-test.el
+++ b/test/parser-generator-lr-test.el
@@ -134,24 +134,31 @@
      Sp))
   (parser-generator-set-look-ahead-number 1)
   (parser-generator-process-grammar)
-
-  (let ((table-lr-items
-         (parser-generator-lr--generate-goto-tables)))
-    (message "conflict-lr-items: %S" table-lr-items)
-    (message "conflict-goto-tables: %S" 
(parser-generator-lr--get-expanded-goto-tables)))
-
   (should-error
    (parser-generator-lr-generate-parser-tables))
+  (message "Conflicted grammar caused expected exception 2")
+
+  (setq
+   parser-generator-lr--precedence-attribute
+   '%prec)
+  (setq
+   parser-generator-lr--precedence-comparison-function
+   #'<)
+  (parser-generator-lr-generate-parser-tables)
+  (message "Grammar not conflicting anymore")
 
   (let ((table-lr-items
          (parser-generator-lr--generate-goto-tables)))
-    (message "conflicted lr-items: %s" table-lr-items)
+    (message
+     "conflict-lr-items: %S"
+     table-lr-items)
+    (message
+     "conflict-goto-tables: %S"
+     (parser-generator-lr--get-expanded-goto-tables))
     (parser-generator-lr--generate-action-tables
      table-lr-items)
-    (message "conflicted goto-tables: %s" 
(parser-generator-lr--get-expanded-goto-tables))
-    (message "conflicted action-tables: %s" 
(parser-generator-lr--get-expanded-action-tables))
-    )
-  (message "Passed conflicted grammar")
+    (message
+     "conflicted action-tables: %s" 
(parser-generator-lr--get-expanded-action-tables)))
 
   (message "Passed tests for (parser-generator-lr--generate-action-tables)"))
 

Reply via email to