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