--- /dev/null
+package org.simantics.parser.grammar.input2;
+
+import org.simantics.parser.grammar.input2.Token;
+
+%%
+
+%public
+%char
+%unicode
+%class GrammarLexer
+%function nextToken
+%type Token
+%yylexthrow RuntimeException
+%scanerror RuntimeException
+%eofval{
+ return sym(GrammarTerminals.EOF);
+%eofval}
+
+%{
+ private Token sym(int id) {
+ return new Token(id, yychar, yychar+yylength(), yytext());
+ }
+%}
+
+
+idChar = [a-zA-Z0-9_]
+nonterminal = [a-z]{idChar}*
+terminal = [A-Z]{idChar}*
+
+whitespace = [ \n\r\t]+
+c_comment = "//" [^\n\r]*
+cpp_comment = "/*" ~"*/"
+
+%%
+
+<YYINITIAL> {
+ {c_comment} { }
+ {cpp_comment} { }
+ "=" { return sym(GrammarTerminals.EQUALS); }
+ "|" { return sym(GrammarTerminals.BAR); }
+ ";" { return sym(GrammarTerminals.SEMICOLON); }
+ "#" { return sym(GrammarTerminals.HASH); }
+ "," { return sym(GrammarTerminals.COMMA); }
+ "(" { return sym(GrammarTerminals.LPAREN); }
+ ")" { return sym(GrammarTerminals.RPAREN); }
+ "*" { return sym(GrammarTerminals.STAR); }
+ "+" { return sym(GrammarTerminals.PLUS); }
+ "?" { return sym(GrammarTerminals.OPTIONAL); }
+ initial { return sym(GrammarTerminals.INITIAL); }
+ shift { return sym(GrammarTerminals.SHIFT); }
+ reduce { return sym(GrammarTerminals.REDUCE); }
+ {terminal} { return sym(GrammarTerminals.TERMINAL); }
+ {nonterminal} { return sym(GrammarTerminals.NONTERMINAL); }
+ {whitespace} { }
+ . { throw new RuntimeException("Illegal character '" + yytext() + "'."); }
+}