aboutsummaryrefslogtreecommitdiff
path: root/c.l
diff options
context:
space:
mode:
Diffstat (limited to 'c.l')
-rw-r--r--c.l119
1 files changed, 119 insertions, 0 deletions
diff --git a/c.l b/c.l
new file mode 100644
index 0000000..376ed4c
--- /dev/null
+++ b/c.l
@@ -0,0 +1,119 @@
+%{
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "type.h"
+#include "y.tab.h"
+
+#define DEBUG
+
+int yylex(void);
+
+int lineno=1;
+
+static enum state {
+ SOP,
+ STERM,
+ SPTR
+} state = STERM;
+
+__attribute__((format (printf, 1, 2)))
+void pdebug(const char *format, ...);
+
+#define RETS(val_) {pdebug(#val_ ": %s\n", yytext); yylval.id = strdup(yytext); return val_;}
+#define RET_TYPE(val_, ty_) {pdebug(#val_ ": %s (" #ty_ ")\n", yytext); yylval.type = ty_; return val_;}
+#define RET(val_) {pdebug(#val_ "\n"); return val_;}
+
+%}
+
+%option noinput nounput
+
+LETTER [a-zA-Z]
+DIGIT [0-9]
+ID {LETTER}({LETTER}|{DIGIT}|_)*
+DIGITS {DIGIT}{DIGIT}*
+
+NUM -?{DIGITS}
+
+%x C_COMMENT
+
+
+%%
+
+{NUM} { state = SOP; RETS(NUM); }
+
+int { state = SPTR; RET_TYPE(INT, type_int(16)); }
+void { state = SPTR; RET_TYPE(VOID, type_void()); }
+if { RET(IF); }
+else { RET(ELSE); }
+while { RET(WHILE); }
+for { RET(FOR); }
+return { state = STERM; RET(RETURN); }
+
+{ID} { state = SOP; RETS(ID); }
+
+"//"[^\n]* {}
+
+"/*" { pdebug("C_COMMENT... "); fflush(stdout); BEGIN(C_COMMENT); }
+<C_COMMENT>"*/" { pdebug("done\n"); BEGIN(INITIAL); }
+<C_COMMENT>. {}
+<C_COMMENT>\n { lineno++; }
+
+\n { lineno++; }
+[ \t]+ {}
+
+"+" { state = STERM; RETS(ADDOP); }
+[/%] { state = STERM; RETS(MULOP); }
+"<"=?|">"=?|==|!= { state = STERM; RETS(RELOP); }
+&&|"||" { state = STERM; RETS(BOOLOP); }
+= { state = STERM; RET(ASSIGN); }
+"!" { state = STERM; RET(NOT); }
+
+"-" {
+ switch (state) {
+ case SOP: state = STERM; RETS(ADDOP);
+ case STERM: state = STERM; RETS(NEGATE);
+ default: fprintf(stderr, "Unexpected '-'\n"); exit(1);
+ }
+ }
+
+"*" {
+ switch (state) {
+ case SOP: state = STERM; RETS(MULOP);
+ case STERM: state = STERM; RET(DEREF);
+ case SPTR: state = SPTR; RET(PTR);
+ default: fprintf(stderr, "Unexpected '*'\n"); exit(1);
+ }
+ }
+
+"&" {
+ switch (state) {
+ case SOP: fprintf(stderr, "Bit-and not implemented\n"); exit(1);
+ case STERM: state = STERM; RET(ADDROF);
+ default: fprintf(stderr, "Unexpected '&'\n"); exit(1);
+ }
+ }
+
+")" { state = SOP; pdebug("')'\n"); return ')'; }
+
+. { pdebug(".: %c\n", yytext[0]); return yytext[0]; }
+
+
+%%
+
+
+void pdebug(const char *format, ...) {
+ (void)format;
+#ifdef DEBUG
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+#endif
+}
+
+
+/* vim:et:ts=4:sw=4
+*/