%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; "decltype" return TOK_DECLTYPE; "difference" return TOK_DIFFERENCE; [<>(),;] 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; }