[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: SMIE: if-elseif-else constructs
From: |
Andreas Matthias |
Subject: |
Re: SMIE: if-elseif-else constructs |
Date: |
Tue, 6 Oct 2020 15:29:55 +0200 |
Stefan Monnier wrote:
>
> > (assoc "then" "end")
>
> This says that
>
> a then b then c then d
>
> is acceptable and that `a`, `b`, and `c` should be considered as
> siblings (i.e. at the same depth level). Same for `end`.
I see. Using assoc seemed to be the easy way but was not reasonable.
I think I've found a better way. I revised the grammar and adjusted
the indentation rules.
The following seems to work.
(require 'smie)
(setq foobar-grammar
(smie-prec2->grammar
(smie-bnf->prec2
`((insts (insts ";" insts)
(inst))
(inst (if))
(exp)
(if ("if" if-body1 "end"))
(if-body1 (exp "then" if-body2))
(if-body2 (insts "elseif" if-body1)
(insts "else" insts)
(insts)))
'((assoc ";")
))))
(defun foobar-rules (kind token)
(message "rule: (%s . %s) at point %d" kind token (point))
(pcase (cons kind token)
(`(:elem . basic) foobar-indent-basic)
(`(:before . "then") 0)
(`(:after . "then") foobar-indent-basic)
(`(:before . "else") 0)
(`(:after . "else") foobar-indent-basic)
(`(:before . "elseif") 0)
(`(:after . "elseif") foobar-indent-basic)
))
(setq foobar-indent-basic 4)
(define-derived-mode foobar-mode prog-mode "foobar"
:syntax-table nil
(modify-syntax-entry ?/ ". 124")
(modify-syntax-entry ?* ". 23b")
(modify-syntax-entry ?\n ">")
(setq comment-start "//")
(smie-setup foobar-grammar #'foobar-rules)
(font-lock-add-keywords
nil
`((,(regexp-opt '("if" "then" "elseif" "else" "end")) .
font-lock-keyword-face)))
(font-lock-mode)
(font-lock-ensure (point-min) (point-max)))