[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SMIE: if-elseif-else constructs
From: |
Andreas Matthias |
Subject: |
SMIE: if-elseif-else constructs |
Date: |
Sat, 3 Oct 2020 17:16:32 +0200 |
I'm trying to teach SMIE to handle if-elseif-else constructs correctly.
In the following example the indentation of the last line, i.e. "xoxox;",
is wrong. I suppose something's wrong with my definition of elseif
in the grammar. But what is it? How can I fix it?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if a > 5 then
foo;
bar;
else
foo;
bar;
end;
xoxox; // correct indentation
if a > 5 then
foo;
bar;
elseif a > 5 then
foo;
bar;
else
foo;
bar;
end;
xoxox; // wrong indentation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Here is the code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'smie)
(setq foobar-grammar
(smie-prec2->grammar
(smie-bnf->prec2
`((insts (insts ";" insts)
(inst))
(inst (if))
(exp)
(if ("if" exp "then" else "end"))
(else (insts)
(insts "else" insts)
(insts "elseif" exp "then" else)))
'((assoc ";")
(assoc "then" "end")
))))
(defun foobar-rules (kind token)
(message "rule: (%s . %s) at point %d" kind token (point))
(pcase (cons kind token)
(`(:before . "then") (smie-rule-parent 0))
(`(:before . "else") (smie-rule-parent 0))
(`(:after . "else") (smie-rule-parent 4))
(`(:before . "elseif") (smie-rule-parent 0))
(`(:after . "elseif") (smie-rule-parent 4))
(`(:before . "end") (smie-rule-parent 0))
))
(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)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- SMIE: if-elseif-else constructs,
Andreas Matthias <=