0

I'm struggling with teaching SMIE how to handle if-elseif-else constructs correctly. In the following test file 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

This 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)))
1
  • I suspect you'll get more traction asking this on emacs-devel@gnu.org, I don't think Stefan Monnier follows StackExchange. – rpluim Sep 30 '20 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.