Speed is a good reason to let the paren-matching be performed by syntax-tables where possible. In your case, the "parens" are not multi-char, so you can definitely use syntax-tables for them. In order to avoid treating -> as a paren closer, you can setup a syntax-propertize-function which modifies the syntax of those > which appear in ->. ...
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.
Besides the SMIE package (which can indeed use a BNF grammar, but will usually not work well with a BNF grammar that was designed for the usual LALR-style parser), there's the wisi package available from GNU ELPA (http://elpa.gnu.org/packages/wisi.html):
The wisi package provides utilities for using generalized LALR parsers
to do indentation, ...
If you replace AttributeBegin and AttributeEnd with open and close parens, you code is basically of the form:
The reason for this indentation is that there is no ; between the three parenthesized elements. Basically, SMIE parses the above as a ; operator with test on the left and (...) (...) (...) on the right. And SMIE ...
Your problem lies within the indentation rules.
You must align the text after "AttributeEnd" to the parent token of "AttributeEnd", i.e., its opener "AttributeBegin".
You can do that with case
('(:after "AttributeEnd") (smie-rule-parent))
in function smie-sample-rules.
There follows a complete minimal working example.
First the Elisp code:
Check the code that uses sh-indent-after-continuation since that's the config variable that decides how continued lines should be indented. You'll probably want to look at the following change I installed recently:
Author: Stefan Monnier <firstname.lastname@example.org>
Date: Tue Sep 29 21:43:07 2015 -0400
I need to add an associativity level for in, making it weaker/looser than the other binary operators. E.g., changing the last line to
'((assoc "in") (assoc ";") (assoc "+") (assoc "*")))))
This is because the parser needs to be able to see that
let e1 in e2 + e3
should be parsed as
let e1 in (e2 + e3)
(let e1 in e2) + e3
It's a known bug (aka limitation) of SMIE's support for (backward-)up-list. To fix it right we need to make changes to (backward-)up-list, or otherwise redirect those commands to SMIE versions of them.
IIRC, you can partly avoid the problem by replacing things like
("Theorem" id ":" quotedmaterial "Proof" tactic "QED")
with something ...
Not sure why it highlights type as unmatched in the first case. Seems like a bug.
If you don't want your = to match type then you're expected to set smie-blink-matching-inners to nil in your ~/.emacs. This said, I'm not completely sure if paren-mode obeys it. If not, that'd be a bug.
Finally, you can also change your grammar to:
(statement ("type" ...
You can also parse the empty string behind AttributeEnd as ;. Point behind AttributeEnd is the corresponding parser state. The only tricky detail is that you must flee from that position when you have parsed ; in forward direction and you may only parse the arrival at AttributeEnd as ; when you are parsing in backward direction.
Minimal working example:
As suggested by Stefan in his comment, it seems like the best thing to do here
is to modify the lexer(s) to return a virtual separator after "AttributeEnd"
(defun smie-sample-forward-token ()
"Go forwards to the next SMIE token."
(let ((start-pos (point)))
((and (> (point) start-pos) ...
The Att..Begin...Att..End is just a (parenthesized) "expression", like test, c, and d because it's not separated from them with any keyword (which is why the same problem doesn't show up when you add a semi-colon between them). So SMIE considers the above as 4 ...