-
Notifications
You must be signed in to change notification settings - Fork 0
/
blang.l
137 lines (135 loc) · 2.57 KB
/
blang.l
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
%option noyywrap
%option noinput
%option nounput
%top {
#include "parse.tab.h"
static void validate_chars(void);
static int length(void);
static void format(char);
}
DIGIT [[:digit:]]
ID [[:alpha:]_][[:alnum:]_]{0,255}
%%
\/\/.*\n? |
\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ |
[ \t\r\n]* ;
int return TOKEN_INT;
boolean return TOKEN_BOOLEAN;
char return TOKEN_CHAR;
string return TOKEN_STRING;
void return TOKEN_VOID;
var return TOKEN_VAR;
if return TOKEN_IF;
else return TOKEN_ELSE;
print return TOKEN_PRINT;
return return TOKEN_RETURN;
while return TOKEN_WHILE;
; return TOKEN_SEMI;
, return TOKEN_COMMA;
"{" return TOKEN_LBRACE;
"}" return TOKEN_RBRACE;
"(" return TOKEN_LPAREN;
")" return TOKEN_RPAREN;
"++" return TOKEN_INCR;
"--" return TOKEN_DECR;
"^" return TOKEN_POW;
"+" return TOKEN_ADD;
"-" return TOKEN_SUB;
"*" return TOKEN_MUL;
"/" return TOKEN_DIV;
"%" return TOKEN_MOD;
"==" return TOKEN_EQ;
"!=" return TOKEN_NE;
">=" return TOKEN_GE;
"<=" return TOKEN_LE;
">" return TOKEN_GT;
"<" return TOKEN_LT;
"&&" return TOKEN_AND;
"||" return TOKEN_OR;
"!" return TOKEN_NOT;
"=" return TOKEN_ASSIGN;
true return TOKEN_TRUE;
false return TOKEN_FALSE;
\"(\\.|[^\"])*\" {
validate_chars();
if (length() > 256) {
fprintf(stderr, "scan: string exceeds max length: %s\n", yytext);
exit(1);
}
format('\"');
return TOKEN_STRING_LITERAL; }
\'[^\'\\]\' |
\'\\.\' {
validate_chars();
format('\'');
return TOKEN_CHAR_LITERAL; }
{DIGIT}+ {
long value;
errno = 0;
value = strtol(yytext, NULL, 10);
if (errno == ERANGE || value > 2147483647) {
fprintf(stderr, "scan: int exceeds size limits: %s\n", yytext);
exit(1);
}
return TOKEN_INT_LITERAL; }
{ID} return TOKEN_ID;
. {
fprintf(stderr, "scan: unrecognized token: %s\n", yytext);
exit(1); }
%%
void validate_chars(void)
{
int i;
for (i = 0; i < yyleng; ++i) {
int c = yytext[i];
if ((c < 0x20) || (c > 0x7e)) {
fprintf(stderr, "scan: invalid char in string or char literal: %d\n", c);
exit(1);
}
}
}
int length(void)
{
int len = 0;
int i = 1;
while (yytext[i] != '"') {
if (yytext[i] == '\\') {
++i;
}
++i;
++len;
}
return len;
}
void format(char t)
{
int i = 1, j = 1;
char c;
while (yytext[j] != t) {
c = yytext[j++];
if (c == '\\') {
c = yytext[j++];
switch (c) {
case 'n':
yytext[i++] = '\\';
yytext[i++] = 'n';
break;
case '\\':
yytext[i++] = '\\';
yytext[i++] = '\\';
break;
case '0':
yytext[i++] = '\\';
yytext[i++] = '0';
break;
default:
yytext[i++] = c;
break;
}
} else {
yytext[i++] = c;
}
}
yytext[i++] = t;
yytext[i] = '\0';
}