aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2010-10-07 13:27:19 +0200
committerStefan Monnier2010-10-07 13:27:19 +0200
commit29c72a6e4382d33779f7706719cb784ee4c4ef88 (patch)
treef51755be02c2752be61d2b3c83947399328e9676 /lisp
parent07ff7702e086ca4eb02aadf438c97a9c87c3389d (diff)
downloademacs-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/ChangeLog14
-rw-r--r--lisp/emacs-lisp/smie.el93
-rw-r--r--lisp/progmodes/octave-mod.el5
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 @@
12010-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
12010-10-07 Miles Bader <Miles Bader <miles@gnu.org>> 112010-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
262010-10-06 Michael Albinus <michael.albinus@gmx.de> 362010-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
312010-10-06 Glenn Morris <rgm@gnu.org> 412010-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.
320Each 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