Newer
Older
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
%option prefix="mcc_parser_"
%option batch
%option bison-bridge
%option bison-locations
%option noinput
%option nounput
%option noyywrap
%option reentrant
%option yylineno
%{
#include "parser.tab.h"
#define YYSTYPE MCC_PARSER_STYPE
#define YYLTYPE MCC_PARSER_LTYPE
/* Update line and column count *
* Reference: https://stackoverflow.com/a/22125500 */
#define YY_USER_ACTION \
yylloc->first_column = yylloc->last_column; \
yylloc->last_column += yyleng; \
for(int i = 0; yytext[i] != '\0'; i++) { \
if(yytext[i] == '\n') { \
yylloc->last_line++; \
yylloc->last_column = 0; \
} \
else { \
yylloc->last_column++; \
} \
}
int mcc_line_num = 1;
int mcc_comment_caller;
%}
int_literal [0-9]+
float_literal [0-9]+\.[0-9]+
bool_literal true|false
string_literal \"(\\.|[^"\\])*\"
identifier [a-zA-Z_][a-zA-Z0-9_]*
%x comment foo
/* Scanning comments based on documentation *
* Documentation: ftp://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_mono/flex.html */
%%
"/*" {
mcc_comment_caller = INITIAL;
BEGIN(comment);
}
<foo>"/*" {
mcc_comment_caller = foo;
BEGIN(comment);
}
<comment>[^*\n]* /* eat anything that's not a '*' */
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
<comment>\n ++mcc_line_num;
<comment>"*"+"/" BEGIN(mcc_comment_caller);
"+" { return TK_PLUS; }
"-" { return TK_MINUS; }
"*" { return TK_ASTER; }
"/" { return TK_SLASH; }
"(" { return TK_LPARENTH; }
")" { return TK_RPARENTH; }
"{" { return TK_LBRACE; }
"}" { return TK_RBRACE; }
"[" { return TK_LBRACKET; }
"]" { return TK_RBRACKET; }
"<" { return TK_LESS; }
">" { return TK_GREATER; }
"<=" { return TK_LESS_EQ; }
">=" { return TK_GREATER_EQ; }
"==" { return TK_EQUALS; }
"!=" { return TK_NOT_EQUALS; }
"=" { return TK_ASSIGNMENT; }
";" { return TK_SEMICOLON; }
"," { return TK_COMMA; }
"!" { return TK_NOT; }
"&&" { return TK_AND; }
"||" { return TK_OR; }
"bool" { return TK_BOOL_TYPE; }
"int" { return TK_INT_TYPE; }
"float" { return TK_FLOAT_TYPE; }
"string" { return TK_STRING_TYPE; }
"void" { return TK_VOID; }
"if" { return TK_IF; }
"else" { return TK_ELSE; }
"while" { return TK_WHILE; }
"return" { return TK_RETURN; }
"for" { return TK_FOR; }
[ \t\r\n]+ { /* ignore */ }
{bool_literal} { yylval->TK_BOOL_LITERAL = strcmp(yytext, "true") == 0; return TK_BOOL_LITERAL; }
{identifier} {
yylval->TK_IDENTIFIER = strdup(yytext);
return TK_IDENTIFIER;
}
{int_literal} { yylval->TK_INT_LITERAL = atol(yytext); return TK_INT_LITERAL; }
{float_literal} { yylval->TK_FLOAT_LITERAL = atof(yytext); return TK_FLOAT_LITERAL; }
{string_literal} { /* https://stackoverflow.com/questions/14185172/lex-how-to-eliminate-double-quotes-from-a-string-literal */
strcpy(str, "\\");
strncpy(str+1, yytext, yyleng-1);
strcpy(str+yyleng, "\\\"");
str[yyleng+2] = '\0';
yylval->TK_STRING_LITERAL = str;
return TK_STRING_LITERAL; }