-
Notifications
You must be signed in to change notification settings - Fork 1
/
scan.l
144 lines (119 loc) · 3.19 KB
/
scan.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
138
139
140
141
142
/*
* FILE: scan.l
* AUTHORS: Yondon Fu and Matt McFarland - Delights (CS57 - 16W)
*
* PURPOSE: Flex file for scanner
*
* ATTRIBUTIONS: SWS for inspiration and kwloopup function model (cscan.l)
*
*/
%option yylineno
%{
#include <string.h>
#include "parser.tab.h"
// #include "toktypes.h"
int kwLookup(char *);
#define MAXTOKENLENGTH 201
char savedIdText[MAXTOKENLENGTH];
char savedLiteralText[MAXTOKENLENGTH];
%}
white [ \t\n]+
space [ \t]
letter [A-Za-z]
digit [0-9]
id ({letter}|_)({letter}|{digit}|_)*
integer {digit}+
bad_id ({digit})({digit}|{letter}|_)*
%x string MULTICOMMENT SINGLECOMMENT
%%
{white}
{id} {
strncpy(savedIdText, yytext, MAXTOKENLENGTH-1);
return kwLookup(yytext);
}
{integer} {
strncpy(savedLiteralText, yytext, MAXTOKENLENGTH-1);
return INT_T;
}
{bad_id} return OTHER_T;
\" { BEGIN(string); } /* Transition to string state */
<string>\n {
BEGIN(INITIAL);
yytext[--yyleng] = '\0'; /* Remove trailing double-quote */
return OTHER_T;
}
<string>\\\" { yymore(); }
<string>\" {
BEGIN(INITIAL); /* Return to initial normal state */
yytext[--yyleng] = '\0'; /* Remove trailing double-quote. Switching states takes care of leading double quote */
return STRING_T;
}
<string>. { yymore(); }
"/*" { BEGIN(MULTICOMMENT); }
<MULTICOMMENT>[^*\n]+ /* Gobble comment */
<MULTICOMMENT>"*" /* Gobble star */
<MULTICOMMENT>\n /* Gobble new line */
<MULTICOMMENT>"*/" {
BEGIN(INITIAL);
}
"//" { BEGIN(SINGLECOMMENT); }
<SINGLECOMMENT>[^\n] /* Gobble comment */
<SINGLECOMMENT>\n { BEGIN(INITIAL); }
"<=" return LTE_T;
">=" return GTE_T;
"==" return EQ_T;
"!=" return NE_T;
"++" return INCR_T;
"--" return DECR_T;
"&&" return AND_T;
"||" return OR_T;
"+" return '+';
"-" return '-';
"*" return '*';
"/" return '/';
"<" return '<';
">" return '>';
";" return ';';
"," return ',';
"(" return '(';
")" return ')';
"[" return '[';
"]" return ']';
"{" return '{';
"}" return '}';
"%" return '%';
"=" return '=';
"!" return '!';
<<EOF>> return 0;
. return OTHER_T;
%%
int kwLookup(char *s) {
// Define struct that encapsulates keyword string and int token values
struct kw_token {
char *keyword;
int token;
};
typedef struct kw_token kw_token;
static kw_token keywords[] = {
{"if", IF_T},
{"else", ELSE_T},
{"do", DO_T},
{"while", WHILE_T},
{"return", RETURN_T},
{"break", BREAK_T},
{"continue", CONTINUE_T},
{"for", FOR_T},
{"void", VOID_T},
{"read", READ_T},
{"print", PRINT_T},
{"int", TYPEINT_T},
{"sizeof", SIZEOF_T},
{NULL, ID_T}
};
kw_token *kw;
// Set end of keywords array (ID_T) to the string
keywords[sizeof(keywords) / sizeof(keywords[0]) - 1].keyword = s;
// If the end of the array is reached without matching a keyword, string defaults to an ID_T token
for (kw = keywords; strcmp(kw->keyword, s) != 0; kw++);
return kw->token;
}