unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Andreas Matthias <andreas.matthias@gmail.com>
To: help-gnu-emacs@gnu.org
Subject: Re: SMIE: if-elseif-else constructs
Date: Tue, 6 Oct 2020 15:29:55 +0200	[thread overview]
Message-ID: <CAHp59H2D41tK_DV=NRzDNCM9vp1J1jOtnZmxjGB58ZA2FnSBQw@mail.gmail.com> (raw)
In-Reply-To: <jwvsgavffd0.fsf-monnier+emacs@gnu.org>

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



  reply	other threads:[~2020-10-06 13:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2020-10-06 14:04     ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHp59H2D41tK_DV=NRzDNCM9vp1J1jOtnZmxjGB58ZA2FnSBQw@mail.gmail.com' \
    --to=andreas.matthias@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).