%option c++ %option noyywrap %option yyclass="Scanner" %x STRING %{ #include "scanner.hpp" #include "indent_helper.hpp" IndentHelper indent_helper; bool at_line_start = true; %} %% ^[ \t]* { if (!at_line_start) { REJECT; } at_line_start = false; int spaces = 0; for (int i = 0; i < yyleng; i++) spaces += (yytext[i] == '\t') ? 8 : 1; int result = indent_helper.processLine(spaces); if (result > 0) return yy::parser::token::TOK_INDENT; if (result < 0) return yy::parser::token::TOK_DEDENT; } \n { at_line_start = true; return yy::parser::token::TOK_NEWLINE; } def { return yy::parser::token::TOK_KW_DEF; } if { return yy::parser::token::TOK_KW_IF; } return { return yy::parser::token::TOK_KW_RETURN; } for { return yy::parser::token::TOK_KW_FOR; } in { return yy::parser::token::TOK_KW_IN; } \( { return yy::parser::token::TOK_L_PAREN; } \) { return yy::parser::token::TOK_R_PAREN; } \: { return yy::parser::token::TOK_COLON; } \= { return yy::parser::token::TOK_ASSIGN; } \+ { return yy::parser::token::TOK_PLUS; } \- { return yy::parser::token::TOK_MINUS; } \" { yymore(); BEGIN(STRING); } \"\" { yymore(); } \" { BEGIN(INITIAL); yylval->as() = yytext; return yy::parser::token::TOK_STRING; } . { yymore(); } [0-9]+ { yylval->as() = yytext; return yy::parser::token::TOK_NUMBER; } [A-Za-z_][A-Za-z0-9_]* { yylval->as() = yytext; return yy::parser::token::TOK_IDENTIFIER; } <> { if (indent_helper.hasPendingDedents()) { indent_helper.consumeDedent(); return yy::parser::token::TOK_DEDENT; } int d; if ((d = indent_helper.flushDedent()) != 0) return yy::parser::token::TOK_DEDENT; return yy::parser::token::TOK_EOF; } . { /* ignore other characters */ }