aboutsummaryrefslogtreecommitdiff
path: root/c.l
blob: 77381fbee9d02af0f7394ffa5f72b280b4f01f6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
%{

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "type.h"
#include "y.tab.h"

#undef 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
*/