%x mu emu

%%

[^\x00]*?/("<%")                 {
                                   if(yytext.slice(-1) !== "\\") this.begin("mu");
                                   if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1), this.begin("emu");
                                   if(yytext) return 'CONTENT';
                                 }

[^\x00]+                         { return 'CONTENT'; }

<emu>[^\x00]{2,}?/("{{"|<<EOF>>) {
                                   if(yytext.slice(-1) !== "\\") this.popState();
                                   if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1);
                                   return 'CONTENT';
                                 }

<mu>"{{>"                        { return 'OPEN_PARTIAL'; }
<mu>"<%="                        { return 'OPEN_BLOCK'; }
<mu>"<%/"                        { return 'OPEN_ENDBLOCK'; }
<mu>"{{^"                        { return 'OPEN_INVERSE'; }
<mu>"<%"\s*"else"                { return 'OPEN_INVERSE'; }
<mu>"{<%%"                        { return 'OPEN_UNESCAPED'; }
<mu>"{{&"                        { return 'OPEN_UNESCAPED'; }
<mu>"<%!"[\s\S]*?"%>"            { yytext = yytext.substr(3,yyleng-5); this.popState(); return 'COMMENT'; }
<mu>"<%"                         { return 'OPEN'; }

<mu>"="                          { return 'EQUALS'; }
<mu>"."/[%} ]                     { return 'ID'; }
<mu>".."                         { return 'ID'; }
<mu>[\/.]                        { return 'SEP'; }
<mu>\s+                          { /*ignore whitespace*/ }
<mu>"%%>"                        { this.popState(); return 'CLOSE'; }
<mu>"%>"                         { this.popState(); return 'CLOSE'; }
<mu>'"'("\\"["]|[^"])*'"'        { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
<mu>"'"("\\"[']|[^'])*"'"        { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
<mu>"@"[a-zA-Z]+                 { yytext = yytext.substr(1); return 'DATA'; }
<mu>"true"/[%}\s]                 { return 'BOOLEAN'; }
<mu>"false"/[%}\s]                { return 'BOOLEAN'; }
<mu>[0-9]+/[%}\s]                 { return 'INTEGER'; }
<mu>[a-zA-Z0-9_$-]+/[=%}\s\/.]    { return 'ID'; }
<mu>'['[^\]]*']'                 { yytext = yytext.substr(1, yyleng-2); return 'ID'; }
<mu>.                            { return 'INVALID'; }

<INITIAL,mu><<EOF>>              { return 'EOF'; }