%option noyywrap nounput noinput yylineno %{ #include "lexer.h" #include "ast.h" #include "parser.h" #include #include static bool failed = false; static char unescape(char escaped) { switch (escaped) { case 'n': return '\n'; case 't': return '\t'; case '0': return '\0'; default: return escaped; } } static int fail(const char* message) { (void)fprintf(stderr, "line %d: %s\n", yylineno, message); failed = true; return 0; } %} %% "::" return TOK_COLONCOLON; "emit" return TOK_EMIT; "commit" return TOK_COMMIT; "void" return TOK_VOID; "int32_t" return TOK_INT32; "byte" return TOK_BYTE; "size_t" return TOK_SIZE_T; "remove_cv_t" return TOK_REMOVE_CV; "decltype" return TOK_DECLTYPE; "difference" return TOK_DIFFERENCE; "sum" return TOK_SUM; "product" return TOK_PRODUCT; "quotient" return TOK_QUOTIENT; [<>(),;] return yytext[0]; '\\.' yylval.character = unescape(yytext[2]); return TOK_CHAR; '.' yylval.character = yytext[1]; return TOK_CHAR; "//"[^\n]* /* a comment */ [ \t\r\n]+ /* blanks */ [0-9]+ return fail("numeric literals are for the weak, subtract two characters"); [A-Za-z_][A-Za-z0-9_]* return fail("that is not a notion this language recognises"); . return fail("what is this character even"); %% bool lexer_failed(void) { return failed; }