]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Nov 2010 01:33:28 +0000 (20:33 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Nov 2010 01:33:28 +0000 (20:33 -0500)
when filling the remaining "unconstrained" values.

lisp/ChangeLog
lisp/emacs-lisp/smie.el

index fef5fec5ce9604c8a8ed70a1f1e054dce29161ee..a20f4d57aed21db8c93423942b505ce6f07e567f 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-12  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints
+       when filling the remaining "unconstrained" values.
+
 2010-11-11  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the
index e944902f6e31707588b7d44e1aeab63de9c0ea79..09095521b491806f41e084bf2ac788574aabfc6d 100644 (file)
 ;;   IF=ELSE and ELSE=END, we could turn them into IF<ELSE and ELSE>END
 ;;   and IF=END,
 
-;;; Code:
+;; TODO & BUGS:
+;;
+;; - FIXME: I think the behavior on empty lines is wrong.  It shouldn't
+;;   look at the next token on subsequent lines.
+;; - Using the structural information SMIE gives us, it should be possible to
+;;   implement a `smie-align' command that would automatically figure out what
+;;   there is to align and how to do it (something like: align the token of
+;;   lowest precedence that appears the same number of times on all lines,
+;;   and then do the same on each side of that token).
+;; - Maybe accept two juxtaposed non-terminals in the BNF under the condition
+;;   that the first always ends with a terminal, or that the second always
+;;   starts with a terminal.
 
-;; FIXME: I think the behavior on empty lines is wrong.  It shouldn't
-;; look at the next token on subsequent lines.
+;;; Code:
 
 (eval-when-compile (require 'cl))
 
@@ -401,6 +411,18 @@ CSTS is a list of pairs representing arcs in a graph."
      (append names (list (car names)))
      " < ")))
 
+;; (defun smie-check-grammar (grammar prec2 &optional dummy)
+;;   (maphash (lambda (k v)
+;;              (when (consp k)
+;;                (let ((left (nth 2 (assoc (car k) grammar)))
+;;                      (right (nth 1 (assoc (cdr k) grammar))))
+;;                  (when (and left right)
+;;                    (cond
+;;                     ((< left right) (assert (eq v '<)))
+;;                     ((> left right) (assert (eq v '>)))
+;;                     (t (assert (eq v '=))))))))
+;;            prec2))
+
 (put 'smie-prec2->grammar 'pure t)
 (defun smie-prec2->grammar (prec2)
   "Take a 2D precedence table and turn it into an alist of precedence levels.
@@ -469,6 +491,7 @@ PREC2 is a table as returned by `smie-precs->prec2' or
               ;; left = right).
               (unless (caar cst)
                 (setcar (car cst) i)
+                ;; (smie-check-grammar table prec2 'step1)
                 (incf i))
               (setq csts (delq cst csts))))
           (unless progress
@@ -478,8 +501,19 @@ PREC2 is a table as returned by `smie-precs->prec2' or
         (incf i 10))
       ;; Propagate equalities back to their source.
       (dolist (eq (nreverse eqs))
-        (assert (or (null (caar eq)) (eq (car eq) (cdr eq))))
-        (setcar (car eq) (cadr eq)))
+        (when (null (cadr eq))
+          ;; There's an equality constraint, but we still haven't given
+          ;; it a value: that means it binds tighter than anything else,
+          ;; and it can't be an opener/closer (those don't have equality
+          ;; constraints).
+          ;; So set it here rather than below since doing it below
+          ;; makes it more difficult to obey the equality constraints.
+          (setcar (cdr eq) i)
+          (incf i))
+        (assert (or (null (caar eq)) (eq (caar eq) (cadr eq))))
+        (setcar (car eq) (cadr eq))
+        ;; (smie-check-grammar table prec2 'step2)
+        )
       ;; Finally, fill in the remaining vars (which only appeared on the
       ;; right side of the < constraints).
       (let ((classification-table (gethash :smie-open/close-alist prec2)))
@@ -500,6 +534,7 @@ PREC2 is a table as returned by `smie-precs->prec2' or
             (incf i)))))                ;See other (incf i) above.
     (let ((ca (gethash :smie-closer-alist prec2)))
       (when ca (push (cons :smie-closer-alist ca) table)))
+    ;; (smie-check-grammar table prec2 'step3)
     table))
 
 ;;; Parsing using a precedence level table.