%{ #include #include "tbsp.tab.h" int code_nesting = 0; int code_caller; sds buffer; %} identifier [a-zA-z][-a-zA-z0-9_]* %x IN_DEFINITION_SECTION IN_RULE_SECTION IN_CODE_SECTION %x IN_COMMENT IN_MULTILINE_COMMENT %x IN_CODE %option nodefault %option noyywrap %option nounput noinput %% . { yyless(0); BEGIN IN_DEFINITION_SECTION; } { \%top[[:space:]]*\{ { code_caller = IN_DEFINITION_SECTION; BEGIN IN_CODE; return TOP; } \%language[[:space:]] { return LANGUAGE; } {identifier} { yylval.strval = strdup(yytext); return IDENTIFIER; } [[:space:]] { ; } \%\% { BEGIN IN_RULE_SECTION; return SEPARATOR; } . { yyerror("unknown expression in rule section"); } } { \{ { code_caller = IN_RULE_SECTION; BEGIN IN_CODE; } \} { ; } ([[:space:]]|\n)* { ; } enter[[:space:]] { return ENTER; } leave[[:space:]] { return LEAVE; } {identifier} { yylval.strval = strdup(yytext); return IDENTIFIER; } \/\/ { BEGIN IN_COMMENT; } \/\* { BEGIN IN_MULTILINE_COMMENT; } \%\% { BEGIN IN_CODE_SECTION; return SEPARATOR; } } { . { ; } \n { BEGIN IN_RULE_SECTION; } } { .|\n { ; } \*\/ { BEGIN IN_RULE_SECTION; } } { \{ { buffer = sdscat(buffer, yytext); ++code_nesting; } \} { if (!code_nesting) { yylval.strval = strdup(buffer); sdsclear(buffer); BEGIN code_caller; return CODE_BLOB; } buffer = sdscat(buffer, yytext); --code_nesting; } .|\n { buffer = sdscat(buffer, yytext); } } { (.|\n)* { yylval.strval = strdup(yytext); BEGIN IN_DEFINITION_SECTION; return CODE_BLOB; } } %% int tbsp_yy_init(void) { buffer = sdsnew(""); return 0; } int tbsp_yy_deinit(void) { yy_delete_buffer(YY_CURRENT_BUFFER); sdsfree(buffer); return 0; }