unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* SMIE: if-elseif-else constructs
@ 2020-10-03 15:16 Andreas Matthias
  2020-10-03 16:24 ` Stefan Monnier
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas Matthias @ 2020-10-03 15:16 UTC (permalink / raw)
  To: help-gnu-emacs

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)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-10-06 14:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-03 15:16 SMIE: if-elseif-else constructs Andreas Matthias
2020-10-03 16:24 ` Stefan Monnier
2020-10-06 13:29   ` Andreas Matthias
2020-10-06 14:04     ` Stefan Monnier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).