5

I'm trying SMIE to describe the Nix language. Unfortunately when I use it, I have the following problems:

  1. There are 4 messages saying: Warning (smie): token } is both closer and neither. Which I do not understand.
  2. A message asks you for a comment syntax : but the syntax table has a comment character. So again, I don't understand
  3. If you enter # as comment character, you will see that indentation is 28 instead of the expected 2.

I put all my code on Github | nix-mode. You can reproduce by cloning the repository, running cask and then running cask exec ecukes.

Here is the SMIE grammar for Nix:

(defvar nix+-smie-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id)
      (expr (exprfunction))
      (exprfunction ("{" formals "}" ":" exprfunction)
                    (exprassert))
      (exprassert ("assert" expr ";" exprassert)
                  (exprif))
      (exprif ("if" expr "then" expr "else" expr)
              (exprop))
      (exprop ("!" exprop)
              (exprop "==" exprop)
              (exprop "!=" exprop)
              (exprop "&&" exprop)
              (exprop "||" exprop)
              (exprop "->" exprop)
              (exprop "//" exprop)
              (exprop "~" exprop)
              (exprop "?" id)
              (exprapp))
      (exprapp (exprapp "." exprselect)
               (exprselect))
      (exprselect (exprsimple))
      (exprsimple (id)
                  ("true")
                  ("false")
                  ("null")
                  ("(" expr ")")
                  ("{" binds "}")
                  ("let" "{" binds "}")
                  ("rec" "{" binds "}")
                  ("[" exprselects "]"))
      (binds (binds ";" binds)
             (bind))
      (exprselects (expreselect))
      (bind (id "=" expr)
            ("inherit" exprp))
      (exprp ("(" expr ")"))
      (formals (formals "," formals)
               (formal))
      (formal (id)
              (id "?" expr)))
    '((assoc ";"))
    '((assoc ","))
    '((assoc "==")
      (assoc "!=")
      (assoc "&&")
      (assoc "||")
      (assoc "->")
      (assoc "//")
      (assoc "~")
      (assoc "?")
      (assoc "!")))))

1 Answer 1

6

Regarding 2, the problem is simple: your major-mode function needs to set comment-start. This part has nothing to do with SMIE.

Regarding 3, I'm not sure exactly what it is you're doing (where is point? what does the buffer contain? what command have you run?). But I suggest to first concentrate on indentation of the non-comment parts of the code.

As for 1 the issue is that you have rules like ("{" binds "}") and ("let" "{" binds "}") and ("{" formals "}" ":" exprfunction). SMIE likes to distinguish tokens that only appear at the beginning or only at the end or rules (these are treated like open/close parens) from those that only appear within rules (so called "neither").

This is useful for example when parsing forward from a {: once we find the matching } should we just keep on parsing, looking for the : that should follow (assuming we've jump seen the beginning of an exprfunction) or should we stop and say we've jumped over one AST node?

So to solve these issues for your grammar, replace rules like ("let" "{" binds "}") by a rule like ("let" brace-binds-brace) where brace-binds-brace is defined with a single rule ("{" binds "}").

[ BTW, if at the end of this ordeal you could suggest improvements to the Texinfo docs, or even better provide a patch for it, that would be greatly appreciated. ]

1
  • Thanks for your answers to 2 and 1. Regarding 3, I will read the documentation and ask another question if necessary. Commented Nov 3, 2014 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.