unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Using smie for Relax NG compact syntax
@ 2015-02-09 15:49 Nikolai Weibull
  2015-02-09 16:56 ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Nikolai Weibull @ 2015-02-09 15:49 UTC (permalink / raw)
  To: Emacs Users

Hi!

I’m trying to set up a grammar for Relax NG’s compact syntax and am
trying to get something as simple as

element a {
  empty
}

to work, but I’m not succeeding:

(unless rnc-mode-syntax-table
  (setq rnc-mode-syntax-table (make-syntax-table))
  (modify-syntax-entry ?\{ "(}" rnc-mode-syntax-table)
  (modify-syntax-entry ?\} "){" rnc-mode-syntax-table))

(defconst rnc-mode-smie-grammar
  (smie-prec2->grammar
    (smie-bnf->prec2
      '((id)
       (pattern ("element" id "{" pattern "}") ("empty"))))))

and

(defun rnc-mode-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:elem .basic) rnc-indent-level)))

rnc-mode-smie-forward-token and rnc-mode-smie-backward-token are
basically smie-default-forward-token and smie-default-backward-token.

The indentation after a { at the end of a line doesn’t agree with the
rules at all and I can’t understand why.  The keyword “element” is
being highlighted as show-paren-mismatch, which I also don’t
understand, as there’s a whole pattern in

element a {
  empty
}

Any obvious issues here?



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

* Re: Using smie for Relax NG compact syntax
  2015-02-09 15:49 Using smie for Relax NG compact syntax Nikolai Weibull
@ 2015-02-09 16:56 ` Stefan Monnier
  2015-02-10  7:17   ` Nikolai Weibull
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2015-02-09 16:56 UTC (permalink / raw)
  To: help-gnu-emacs

>        (pattern ("element" id "{" pattern "}") ("empty"))))))

Better make this

        (pattern ("element" id) ("empty"))))))

Since you want "{" to be an "opener" (i.e. something similar to an open
parenthesis) whereas if it's in the middle of a production rule it won't
be treated as an opener.


        Stefan




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

* Re: Using smie for Relax NG compact syntax
  2015-02-09 16:56 ` Stefan Monnier
@ 2015-02-10  7:17   ` Nikolai Weibull
  2015-02-10 20:13     ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Nikolai Weibull @ 2015-02-10  7:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Users

On Mon, Feb 9, 2015 at 5:56 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>>        (pattern ("element" id "{" pattern "}") ("empty"))))))
>
> Better make this
>
>         (pattern ("element" id) ("empty"))))))
>
> Since you want "{" to be an "opener" (i.e. something similar to an open
> parenthesis) whereas if it's in the middle of a production rule it won't
> be treated as an opener.

OK.  This results in an assertion failing in smie-prec2->grammar:

(cl-assert (numberp (car cons)))

that I can’t seem to resolve.



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

* Re: Using smie for Relax NG compact syntax
  2015-02-10  7:17   ` Nikolai Weibull
@ 2015-02-10 20:13     ` Stefan Monnier
  2015-02-11  7:55       ` Nikolai Weibull
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2015-02-10 20:13 UTC (permalink / raw)
  To: help-gnu-emacs

> OK.  This results in an assertion failing in smie-prec2->grammar:
> (cl-assert (numberp (car cons)))

I'd need more info to figure out what's going on.  E.g. a backtrace,
and maybe the chunk of code where it signals the error.


        Stefan





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

* Re: Using smie for Relax NG compact syntax
  2015-02-10 20:13     ` Stefan Monnier
@ 2015-02-11  7:55       ` Nikolai Weibull
  2015-02-11 15:54         ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Nikolai Weibull @ 2015-02-11  7:55 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Users

[-- Attachment #1: Type: text/plain, Size: 1113 bytes --]

On Tue, Feb 10, 2015 at 9:13 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>> OK.  This results in an assertion failing in smie-prec2->grammar:
>> (cl-assert (numberp (car cons)))
>
> I'd need more info to figure out what's going on.  E.g. a backtrace,
> and maybe the chunk of code where it signals the error.

Yeah, sorry.  Here’s the whole rnc-mode.el.  The backtrace doesn’t
seem to tell us much (parts of the backtrace that only involve
invoking eval-buffer have been elided):

Debugger entered--Lisp error: (cl-assertion-failed (numberp (car cons)))
  signal(cl-assertion-failed ((numberp (car cons))))
  smie-prec2->grammar(#s(hash-table size 65 test equal rehash-size 1.5
rehash-threshold 0.8 data (:smie-open/close-alist (("element" .
opener)) :smie-closer-alist nil ...)))
  (defconst rnc-mode-smie-grammar (smie-prec2->grammar
(smie-bnf->prec2 (quote ((id) (pattern ("element" id) ("empty")))))))
  eval-buffer()  ; Reading at buffer position 2901
  #<subr call-interactively>(eval-buffer record nil)
  funcall(#<subr call-interactively> eval-buffer record nil)
  …

[-- Attachment #2: rnc-mode.el --]
[-- Type: application/octet-stream, Size: 4102 bytes --]

(require 'smie)

(defgroup rnc nil
  "Major mode for editing Relax NG Compact code."
  :prefix "rnc-"
  :group 'languages)

(defcustom rnc-indent-level 2
  "Indentation of Relax NG Compact statements."
  :type 'integer
  :group 'rnc)

(defconst rnc-font-lock-keywords
  (list
   '("\\b\\(?:attribute\\|element\\)\\s-*\\(\\\\?\\sw\\(?:\\sw\\|\\s_\\)*\\)\\b"
     1 font-lock-variable-name-face)
   '("^\\s-*\\(default\\(?:\\s-+namespace\\)?\\|namespace\\|datatypes\\)\\b"
     1 font-lock-preprocessor-face)
   '("^\\s-*\\(\\\\?\\sw\\(?:\\sw\\|\\s_\\)*\\)\\s-*="
     1 font-lock-variable-name-face)
   (list (concat
          "\\b"
          (regexp-opt
           '("empty"
             "list"
             "mixed"
             "string"
             "text"
             "token"))
          "\\b")
         0 'font-lock-type-face)
   (list (concat
          "\\b"
          (regexp-opt
           '("attribute"
             "div"
             "element"
             "external"
             "grammar"
             "include"
             "inherit"
             "notAllowed"
             "parent"
             "start"))
          "\\b")
         0 'font-lock-keyword-face))
  "Keywords to higlight in rnc-mode.")

(defvar rnc-mode-abbrev-table nil
  "Abbreviation table used in rnc-mode.")

(define-abbrev-table 'rnc-mode-abbrev-table ())

(defvar rnc-mode-map nil
  "Keymap used in rnc-mode.")

(unless rnc-mode-map
  (setq rnc-mode-map (make-sparse-keymap)))

(defvar rnc-mode-syntax-table nil
  "Syntax table in use for rnc-mode buffers.")

(unless rnc-mode-syntax-table
  (setq rnc-mode-syntax-table (make-syntax-table))
  (modify-syntax-entry ?' "\"" rnc-mode-syntax-table)
  (modify-syntax-entry ?\" "\"" rnc-mode-syntax-table)
  (modify-syntax-entry ?# "<" rnc-mode-syntax-table)
  (modify-syntax-entry ?\n ">" rnc-mode-syntax-table)
  (modify-syntax-entry ?\\ "\\" rnc-mode-syntax-table)
  (modify-syntax-entry ?. "_" rnc-mode-syntax-table)
  (modify-syntax-entry ?- "_" rnc-mode-syntax-table)
  (modify-syntax-entry ?_ "_" rnc-mode-syntax-table)
  (modify-syntax-entry ?+ "." rnc-mode-syntax-table)
  (modify-syntax-entry ?* "." rnc-mode-syntax-table)
  (modify-syntax-entry ?? "." rnc-mode-syntax-table)
  (modify-syntax-entry ?& "." rnc-mode-syntax-table)
  (modify-syntax-entry ?| "." rnc-mode-syntax-table)
  (modify-syntax-entry ?= "." rnc-mode-syntax-table)
  (modify-syntax-entry ?~ "." rnc-mode-syntax-table)
  (modify-syntax-entry ?\( "()" rnc-mode-syntax-table)
  (modify-syntax-entry ?\) ")(" rnc-mode-syntax-table)
  (modify-syntax-entry ?\{ "(}" rnc-mode-syntax-table)
  (modify-syntax-entry ?\} "){" rnc-mode-syntax-table)
  (modify-syntax-entry ?\[ "(]" rnc-mode-syntax-table)
  (modify-syntax-entry ?\] ")[" rnc-mode-syntax-table))

(defconst rnc-mode-smie-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id)
      (pattern ("element" id)
               ("empty"))))))

(defun rnc-mode-smie-forward-token ()
  (smie-default-forward-token))

(defun rnc-mode-smie-backward-token ()
  (smie-default-backward-token))

(defun rnc-mode-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:elem . basic) rnc-indent-level)))

;;;###autoload
(defun rnc-mode ()
  "Major mode for editing RELAX NG Compact Syntax schemas.
\\{rnc-mode-map}"
  (interactive)
  (kill-all-local-variables)
  (use-local-map rnc-mode-map)
  (set-syntax-table rnc-mode-syntax-table)
  (setq local-abbrev-table rnc-mode-abbrev-table)
  (set (make-local-variable 'font-lock-defaults)
       '((rnc-font-lock-keywords) nil nil ((?. . "w") (?- . "w") (?_ . "w"))))
  (set (make-local-variable 'comment-start) "#")
  (set (make-local-variable 'comment-end) "")
  (set (make-local-variable 'comment-start-skip) "\\([ \t]*\\)##?[ \t]*")
  (smie-setup rnc-mode-smie-grammar #'rnc-mode-smie-rules
              :forward-token #'rnc-mode-smie-forward-token
              :backward-token #'rnc-mode-smie-backward-token)
  (setq mode-name "RNC"
	major-mode 'rnc-mode)
  (run-mode-hooks 'rnc-mode-hook))

;;;###autoload
(add-to-list 'auto-mode-alist (cons (purecopy "\\.rnc\\'") 'rnc-mode))

(provide 'rnc-mode)

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

* Re: Using smie for Relax NG compact syntax
  2015-02-11  7:55       ` Nikolai Weibull
@ 2015-02-11 15:54         ` Stefan Monnier
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2015-02-11 15:54 UTC (permalink / raw)
  To: Nikolai Weibull; +Cc: Emacs Users

> Yeah, sorry.  Here’s the whole rnc-mode.el.  The backtrace doesn’t
> seem to tell us much (parts of the backtrace that only involve
> invoking eval-buffer have been elided):

Looks like a bug in smie.el, which should disappear when you grow your
grammar.  You can remove the (cl-assert (numberp (car cons))) in smie.el
to work around the problem, or more simply add some dummy thing in `id',
such as:

(defconst rnc-mode-smie-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id ("(" id ")"))
      (pattern ("element" id)
               ("empty"))))))


-- Stefan



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

end of thread, other threads:[~2015-02-11 15:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-09 15:49 Using smie for Relax NG compact syntax Nikolai Weibull
2015-02-09 16:56 ` Stefan Monnier
2015-02-10  7:17   ` Nikolai Weibull
2015-02-10 20:13     ` Stefan Monnier
2015-02-11  7:55       ` Nikolai Weibull
2015-02-11 15:54         ` 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).