hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/sfinae.l
diff options
context:
space:
mode:
Diffstat (limited to 'sfinae.l')
-rw-r--r--sfinae.l58
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;
+}