diff options
| author | Stefan Monnier | 2010-11-11 20:33:28 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2010-11-11 20:33:28 -0500 |
| commit | 10b40d2ef6eb3480f36a39168440dd59efca0e97 (patch) | |
| tree | 85dfa2b966ee495b3d133c001a408125d1d4b323 | |
| parent | acef0722fc954a88eea588486b478f49b1afdc6a (diff) | |
| download | emacs-10b40d2ef6eb3480f36a39168440dd59efca0e97.tar.gz emacs-10b40d2ef6eb3480f36a39168440dd59efca0e97.zip | |
* lisp/emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints
when filling the remaining "unconstrained" values.
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/smie.el | 45 |
2 files changed, 45 insertions, 5 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index fef5fec5ce9..a20f4d57aed 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2010-11-12 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/smie.el (smie-prec2->grammar): Obey equality constraints | ||
| 4 | when filling the remaining "unconstrained" values. | ||
| 5 | |||
| 1 | 2010-11-11 Stefan Monnier <monnier@iro.umontreal.ca> | 6 | 2010-11-11 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 7 | ||
| 3 | * emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the | 8 | * emacs-lisp/bytecomp.el (byte-compile-warnings): Simplify the |
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index e944902f6e3..09095521b49 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el | |||
| @@ -74,10 +74,20 @@ | |||
| 74 | ;; IF=ELSE and ELSE=END, we could turn them into IF<ELSE and ELSE>END | 74 | ;; IF=ELSE and ELSE=END, we could turn them into IF<ELSE and ELSE>END |
| 75 | ;; and IF=END, | 75 | ;; and IF=END, |
| 76 | 76 | ||
| 77 | ;;; Code: | 77 | ;; TODO & BUGS: |
| 78 | ;; | ||
| 79 | ;; - FIXME: I think the behavior on empty lines is wrong. It shouldn't | ||
| 80 | ;; look at the next token on subsequent lines. | ||
| 81 | ;; - Using the structural information SMIE gives us, it should be possible to | ||
| 82 | ;; implement a `smie-align' command that would automatically figure out what | ||
| 83 | ;; there is to align and how to do it (something like: align the token of | ||
| 84 | ;; lowest precedence that appears the same number of times on all lines, | ||
| 85 | ;; and then do the same on each side of that token). | ||
| 86 | ;; - Maybe accept two juxtaposed non-terminals in the BNF under the condition | ||
| 87 | ;; that the first always ends with a terminal, or that the second always | ||
| 88 | ;; starts with a terminal. | ||
| 78 | 89 | ||
| 79 | ;; FIXME: I think the behavior on empty lines is wrong. It shouldn't | 90 | ;;; Code: |
| 80 | ;; look at the next token on subsequent lines. | ||
| 81 | 91 | ||
| 82 | (eval-when-compile (require 'cl)) | 92 | (eval-when-compile (require 'cl)) |
| 83 | 93 | ||
| @@ -401,6 +411,18 @@ CSTS is a list of pairs representing arcs in a graph." | |||
| 401 | (append names (list (car names))) | 411 | (append names (list (car names))) |
| 402 | " < "))) | 412 | " < "))) |
| 403 | 413 | ||
| 414 | ;; (defun smie-check-grammar (grammar prec2 &optional dummy) | ||
| 415 | ;; (maphash (lambda (k v) | ||
| 416 | ;; (when (consp k) | ||
| 417 | ;; (let ((left (nth 2 (assoc (car k) grammar))) | ||
| 418 | ;; (right (nth 1 (assoc (cdr k) grammar)))) | ||
| 419 | ;; (when (and left right) | ||
| 420 | ;; (cond | ||
| 421 | ;; ((< left right) (assert (eq v '<))) | ||
| 422 | ;; ((> left right) (assert (eq v '>))) | ||
| 423 | ;; (t (assert (eq v '=)))))))) | ||
| 424 | ;; prec2)) | ||
| 425 | |||
| 404 | (put 'smie-prec2->grammar 'pure t) | 426 | (put 'smie-prec2->grammar 'pure t) |
| 405 | (defun smie-prec2->grammar (prec2) | 427 | (defun smie-prec2->grammar (prec2) |
| 406 | "Take a 2D precedence table and turn it into an alist of precedence levels. | 428 | "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 | |||
| 469 | ;; left = right). | 491 | ;; left = right). |
| 470 | (unless (caar cst) | 492 | (unless (caar cst) |
| 471 | (setcar (car cst) i) | 493 | (setcar (car cst) i) |
| 494 | ;; (smie-check-grammar table prec2 'step1) | ||
| 472 | (incf i)) | 495 | (incf i)) |
| 473 | (setq csts (delq cst csts)))) | 496 | (setq csts (delq cst csts)))) |
| 474 | (unless progress | 497 | (unless progress |
| @@ -478,8 +501,19 @@ PREC2 is a table as returned by `smie-precs->prec2' or | |||
| 478 | (incf i 10)) | 501 | (incf i 10)) |
| 479 | ;; Propagate equalities back to their source. | 502 | ;; Propagate equalities back to their source. |
| 480 | (dolist (eq (nreverse eqs)) | 503 | (dolist (eq (nreverse eqs)) |
| 481 | (assert (or (null (caar eq)) (eq (car eq) (cdr eq)))) | 504 | (when (null (cadr eq)) |
| 482 | (setcar (car eq) (cadr eq))) | 505 | ;; There's an equality constraint, but we still haven't given |
| 506 | ;; it a value: that means it binds tighter than anything else, | ||
| 507 | ;; and it can't be an opener/closer (those don't have equality | ||
| 508 | ;; constraints). | ||
| 509 | ;; So set it here rather than below since doing it below | ||
| 510 | ;; makes it more difficult to obey the equality constraints. | ||
| 511 | (setcar (cdr eq) i) | ||
| 512 | (incf i)) | ||
| 513 | (assert (or (null (caar eq)) (eq (caar eq) (cadr eq)))) | ||
| 514 | (setcar (car eq) (cadr eq)) | ||
| 515 | ;; (smie-check-grammar table prec2 'step2) | ||
| 516 | ) | ||
| 483 | ;; Finally, fill in the remaining vars (which only appeared on the | 517 | ;; Finally, fill in the remaining vars (which only appeared on the |
| 484 | ;; right side of the < constraints). | 518 | ;; right side of the < constraints). |
| 485 | (let ((classification-table (gethash :smie-open/close-alist prec2))) | 519 | (let ((classification-table (gethash :smie-open/close-alist prec2))) |
| @@ -500,6 +534,7 @@ PREC2 is a table as returned by `smie-precs->prec2' or | |||
| 500 | (incf i))))) ;See other (incf i) above. | 534 | (incf i))))) ;See other (incf i) above. |
| 501 | (let ((ca (gethash :smie-closer-alist prec2))) | 535 | (let ((ca (gethash :smie-closer-alist prec2))) |
| 502 | (when ca (push (cons :smie-closer-alist ca) table))) | 536 | (when ca (push (cons :smie-closer-alist ca) table))) |
| 537 | ;; (smie-check-grammar table prec2 'step3) | ||
| 503 | table)) | 538 | table)) |
| 504 | 539 | ||
| 505 | ;;; Parsing using a precedence level table. | 540 | ;;; Parsing using a precedence level table. |