diff options
| author | hachem <im@hachem.wtf> | 2026-09-19 10:49:33 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-19 10:49:33 +0200 |
| commit | 05bf718e37efdc5201ad281e85da7850af31bd59 (patch) | |
| tree | c862c8fca6d5deb1422d81ee538f214050c2d81a /sfinae.l | |
| parent | 0393d0b61b44a2b4df77a36bc63d64c5842971f9 (diff) | |
feat: basic lexer with flex
Diffstat (limited to 'sfinae.l')
| -rw-r--r-- | sfinae.l | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/sfinae.l b/sfinae.l new file mode 100644 index 0000000..8453699 --- /dev/null +++ b/sfinae.l @@ -0,0 +1,58 @@ +%option noyywrap nounput noinput yylineno + +%{ +#include "lexer.h" + +#include <stdbool.h> +#include <stdio.h> + +static bool failed = false; +static char character = '\0'; + +static char unescape(char escaped) +{ + switch (escaped) + { + case 'n': return '\n'; + case 't': return '\t'; + case '0': return '\0'; + default: return escaped; + } +} + +// complains, remembers, and hands back TOK_END so the scan stops where it went wrong +static int fail(const char* message) +{ + (void)fprintf(stderr, "line %d: %s\n", yylineno, message); + failed = true; + return TOK_END; +} +%} + +%% + +"::" return TOK_COLONCOLON; +"emit" return TOK_EMIT; +"commit" return TOK_COMMIT; +"decltype" return TOK_DECLTYPE; +"difference" return TOK_DIFFERENCE; +[<>(),;] return yytext[0]; +'\\.' character = unescape(yytext[2]); return TOK_CHAR; +'.' 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; +} + +char lexer_character(void) +{ + return character; +} |
