diff options
| author | Stefan Monnier | 2010-10-07 13:27:19 +0200 |
|---|---|---|
| committer | Stefan Monnier | 2010-10-07 13:27:19 +0200 |
| commit | 29c72a6e4382d33779f7706719cb784ee4c4ef88 (patch) | |
| tree | f51755be02c2752be61d2b3c83947399328e9676 /lisp | |
| parent | 07ff7702e086ca4eb02aadf438c97a9c87c3389d (diff) | |
| download | emacs-29c72a6e4382d33779f7706719cb784ee4c4ef88.tar.gz emacs-29c72a6e4382d33779f7706719cb784ee4c4ef88.zip | |
SMIE: Reliably distinguish openers/closers in smie-prec2-levels
* lisp/emacs-lisp/smie.el (smie-bnf-classify): New function.
(smie-bnf-precedence-table): Use it to remember the closers/openers.
(smie-merge-prec2s): Handle those new entries.
(smie-prec2-levels): Only set precedence to nil for actual
openers/closers.
* lisp/progmodes/octave-mod.el (octave-smie-op-levels): Remove dummy entry
that is now unnecessary.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/emacs-lisp/smie.el | 93 | ||||
| -rw-r--r-- | lisp/progmodes/octave-mod.el | 5 |
3 files changed, 78 insertions, 34 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index dc851b93f4e..a1ed3bdfe1b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2010-10-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/smie.el (smie-bnf-classify): New function. | ||
| 4 | (smie-bnf-precedence-table): Use it to remember the closers/openers. | ||
| 5 | (smie-merge-prec2s): Handle those new entries. | ||
| 6 | (smie-prec2-levels): Only set precedence to nil for actual | ||
| 7 | openers/closers. | ||
| 8 | * progmodes/octave-mod.el (octave-smie-op-levels): Remove dummy entry | ||
| 9 | that is now unnecessary. | ||
| 10 | |||
| 1 | 2010-10-07 Miles Bader <Miles Bader <miles@gnu.org>> | 11 | 2010-10-07 Miles Bader <Miles Bader <miles@gnu.org>> |
| 2 | 12 | ||
| 3 | * emacs-lisp/regexp-opt.el (regexp-opt): Add `symbols' mode. | 13 | * emacs-lisp/regexp-opt.el (regexp-opt): Add `symbols' mode. |
| @@ -25,8 +35,8 @@ | |||
| 25 | 35 | ||
| 26 | 2010-10-06 Michael Albinus <michael.albinus@gmx.de> | 36 | 2010-10-06 Michael Albinus <michael.albinus@gmx.de> |
| 27 | 37 | ||
| 28 | * net/tramp-sh.el (tramp-sh-file-name-handler-alist): Use | 38 | * net/tramp-sh.el (tramp-sh-file-name-handler-alist): |
| 29 | `tramp-handle-find-backup-file-name'. | 39 | Use `tramp-handle-find-backup-file-name'. |
| 30 | 40 | ||
| 31 | 2010-10-06 Glenn Morris <rgm@gnu.org> | 41 | 2010-10-06 Glenn Morris <rgm@gnu.org> |
| 32 | 42 | ||
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index 55516d276da..4f5b2046150 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el | |||
| @@ -138,7 +138,12 @@ one of those elements share the same precedence level and associativity." | |||
| 138 | (let ((prec2 (make-hash-table :test 'equal))) | 138 | (let ((prec2 (make-hash-table :test 'equal))) |
| 139 | (dolist (table tables) | 139 | (dolist (table tables) |
| 140 | (maphash (lambda (k v) | 140 | (maphash (lambda (k v) |
| 141 | (smie-set-prec2tab prec2 (car k) (cdr k) v)) | 141 | (if (consp k) |
| 142 | (smie-set-prec2tab prec2 (car k) (cdr k) v) | ||
| 143 | (if (and (gethash k prec2) | ||
| 144 | (not (equal (gethash k prec2) v))) | ||
| 145 | (error "Conflicting values for %s property" k) | ||
| 146 | (puthash k v prec2)))) | ||
| 142 | table)) | 147 | table)) |
| 143 | prec2))) | 148 | prec2))) |
| 144 | 149 | ||
| @@ -225,6 +230,9 @@ one of those elements share the same precedence level and associativity." | |||
| 225 | '= override))) | 230 | '= override))) |
| 226 | (t (smie-set-prec2tab prec2 (car rhs) (cadr rhs) '= override))) | 231 | (t (smie-set-prec2tab prec2 (car rhs) (cadr rhs) '= override))) |
| 227 | (setq rhs (cdr rhs))))) | 232 | (setq rhs (cdr rhs))))) |
| 233 | ;; Keep track of which tokens are openers/closer, so they can get a nil | ||
| 234 | ;; precedence in smie-prec2-levels. | ||
| 235 | (puthash :smie-open/close-alist (smie-bnf-classify bnf) prec2) | ||
| 228 | prec2)) | 236 | prec2)) |
| 229 | 237 | ||
| 230 | ;; (defun smie-prec2-closer-alist (prec2 include-inners) | 238 | ;; (defun smie-prec2-closer-alist (prec2 include-inners) |
| @@ -307,6 +315,33 @@ from the table, e.g. the table will not include things like (\"if\" . \"else\"). | |||
| 307 | (pushnew (cons (car rhs) term) alist :test #'equal))))))) | 315 | (pushnew (cons (car rhs) term) alist :test #'equal))))))) |
| 308 | (nreverse alist))) | 316 | (nreverse alist))) |
| 309 | 317 | ||
| 318 | (defun smie-bnf-classify (bnf) | ||
| 319 | "Return a table classifying terminals. | ||
| 320 | Each terminal can either be an `opener', a `closer', or neither." | ||
| 321 | (let ((table (make-hash-table :test #'equal)) | ||
| 322 | (alist '())) | ||
| 323 | (dolist (category bnf) | ||
| 324 | (puthash (car category) 'neither table) ;Remove non-terminals. | ||
| 325 | (dolist (rhs (cdr category)) | ||
| 326 | (if (null (cdr rhs)) | ||
| 327 | (puthash (pop rhs) 'neither table) | ||
| 328 | (let ((first (pop rhs))) | ||
| 329 | (puthash first | ||
| 330 | (if (memq (gethash first table) '(nil opener)) | ||
| 331 | 'opener 'neither) | ||
| 332 | table)) | ||
| 333 | (while (cdr rhs) | ||
| 334 | (puthash (pop rhs) 'neither table)) ;Remove internals. | ||
| 335 | (let ((last (pop rhs))) | ||
| 336 | (puthash last | ||
| 337 | (if (memq (gethash last table) '(nil closer)) | ||
| 338 | 'closer 'neither) | ||
| 339 | table))))) | ||
| 340 | (maphash (lambda (tok v) | ||
| 341 | (when (memq v '(closer opener)) | ||
| 342 | (push (cons tok v) alist))) | ||
| 343 | table) | ||
| 344 | alist)) | ||
| 310 | 345 | ||
| 311 | (defun smie-debug--prec2-cycle (csts) | 346 | (defun smie-debug--prec2-cycle (csts) |
| 312 | "Return a cycle in CSTS, assuming there's one. | 347 | "Return a cycle in CSTS, assuming there's one. |
| @@ -345,11 +380,6 @@ CSTS is a list of pairs representing arcs in a graph." | |||
| 345 | (defun smie-prec2-levels (prec2) | 380 | (defun smie-prec2-levels (prec2) |
| 346 | ;; FIXME: Rather than only return an alist of precedence levels, we should | 381 | ;; FIXME: Rather than only return an alist of precedence levels, we should |
| 347 | ;; also extract other useful data from it: | 382 | ;; also extract other useful data from it: |
| 348 | ;; - matching sets of block openers&closers (which can otherwise become | ||
| 349 | ;; collapsed into a single equivalence class in smie-op-levels) for | ||
| 350 | ;; smie-close-block as well as to detect mismatches in smie-next-sexp | ||
| 351 | ;; or in blink-paren (as well as to do the blink-paren for inner | ||
| 352 | ;; keywords like the "in" of "let..in..end"). | ||
| 353 | ;; - better default indentation rules (i.e. non-zero indentation after inner | 383 | ;; - better default indentation rules (i.e. non-zero indentation after inner |
| 354 | ;; keywords like the "in" of "let..in..end") for smie-indent-after-keyword. | 384 | ;; keywords like the "in" of "let..in..end") for smie-indent-after-keyword. |
| 355 | ;; Of course, maybe those things would be even better handled in the | 385 | ;; Of course, maybe those things would be even better handled in the |
| @@ -369,18 +399,19 @@ PREC2 is a table as returned by `smie-precs-precedence-table' or | |||
| 369 | ;; variables (aka "precedence levels"). These can be either | 399 | ;; variables (aka "precedence levels"). These can be either |
| 370 | ;; equality constraints (in `eqs') or `<' constraints (in `csts'). | 400 | ;; equality constraints (in `eqs') or `<' constraints (in `csts'). |
| 371 | (maphash (lambda (k v) | 401 | (maphash (lambda (k v) |
| 372 | (if (setq tmp (assoc (car k) table)) | 402 | (when (consp k) |
| 373 | (setq x (cddr tmp)) | 403 | (if (setq tmp (assoc (car k) table)) |
| 374 | (setq x (cons nil nil)) | 404 | (setq x (cddr tmp)) |
| 375 | (push (cons (car k) (cons nil x)) table)) | 405 | (setq x (cons nil nil)) |
| 376 | (if (setq tmp (assoc (cdr k) table)) | 406 | (push (cons (car k) (cons nil x)) table)) |
| 377 | (setq y (cdr tmp)) | 407 | (if (setq tmp (assoc (cdr k) table)) |
| 378 | (setq y (cons nil (cons nil nil))) | 408 | (setq y (cdr tmp)) |
| 379 | (push (cons (cdr k) y) table)) | 409 | (setq y (cons nil (cons nil nil))) |
| 380 | (ecase v | 410 | (push (cons (cdr k) y) table)) |
| 381 | (= (push (cons x y) eqs)) | 411 | (ecase v |
| 382 | (< (push (cons x y) csts)) | 412 | (= (push (cons x y) eqs)) |
| 383 | (> (push (cons y x) csts)))) | 413 | (< (push (cons x y) csts)) |
| 414 | (> (push (cons y x) csts))))) | ||
| 384 | prec2) | 415 | prec2) |
| 385 | ;; First process the equality constraints. | 416 | ;; First process the equality constraints. |
| 386 | (let ((eqs eqs)) | 417 | (let ((eqs eqs)) |
| @@ -432,16 +463,22 @@ PREC2 is a table as returned by `smie-precs-precedence-table' or | |||
| 432 | (setcar (car eq) (cadr eq))) | 463 | (setcar (car eq) (cadr eq))) |
| 433 | ;; Finally, fill in the remaining vars (which only appeared on the | 464 | ;; Finally, fill in the remaining vars (which only appeared on the |
| 434 | ;; right side of the < constraints). | 465 | ;; right side of the < constraints). |
| 435 | (dolist (x table) | 466 | (let ((classification-table (gethash :smie-open/close-alist prec2))) |
| 436 | ;; When both sides are nil, it means this operator binds very | 467 | (dolist (x table) |
| 437 | ;; very tight, but it's still just an operator, so we give it | 468 | ;; When both sides are nil, it means this operator binds very |
| 438 | ;; the highest precedence. | 469 | ;; very tight, but it's still just an operator, so we give it |
| 439 | ;; OTOH if only one side is nil, it usually means it's like an | 470 | ;; the highest precedence. |
| 440 | ;; open-paren, which is very important for indentation purposes, | 471 | ;; OTOH if only one side is nil, it usually means it's like an |
| 441 | ;; so we keep it nil, to make it easier to recognize. | 472 | ;; open-paren, which is very important for indentation purposes, |
| 442 | (unless (or (nth 1 x) (nth 2 x)) | 473 | ;; so we keep it nil if so, to make it easier to recognize. |
| 443 | (setf (nth 1 x) i) | 474 | (unless (or (nth 1 x) |
| 444 | (setf (nth 2 x) i)))) | 475 | (eq 'opener (cdr (assoc (car x) classification-table)))) |
| 476 | (setf (nth 1 x) i) | ||
| 477 | (incf i)) ;See other (incf i) above. | ||
| 478 | (unless (or (nth 2 x) | ||
| 479 | (eq 'closer (cdr (assoc (car x) classification-table)))) | ||
| 480 | (setf (nth 2 x) i) | ||
| 481 | (incf i))))) ;See other (incf i) above. | ||
| 445 | table)) | 482 | table)) |
| 446 | 483 | ||
| 447 | ;;; Parsing using a precedence level table. | 484 | ;;; Parsing using a precedence level table. |
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el index bbefdaa2ccf..56de9b869db 100644 --- a/lisp/progmodes/octave-mod.el +++ b/lisp/progmodes/octave-mod.el | |||
| @@ -456,10 +456,7 @@ Non-nil means always go to the next Octave code line after sending." | |||
| 456 | octave-smie-bnf-table | 456 | octave-smie-bnf-table |
| 457 | '((assoc "\n" ";"))) | 457 | '((assoc "\n" ";"))) |
| 458 | 458 | ||
| 459 | (smie-precs-precedence-table | 459 | (smie-precs-precedence-table octave-operator-table)))) |
| 460 | (append octave-operator-table | ||
| 461 | '((nonassoc " -dummy- "))) ;Bogus anchor at the end. | ||
| 462 | )))) | ||
| 463 | 460 | ||
| 464 | ;; Tokenizing needs to be refined so that ";;" is treated as two | 461 | ;; Tokenizing needs to be refined so that ";;" is treated as two |
| 465 | ;; tokens and also so as to recognize the \n separator (and | 462 | ;; tokens and also so as to recognize the \n separator (and |