-
Notifications
You must be signed in to change notification settings - Fork 0
/
scanner.l
175 lines (152 loc) · 4.49 KB
/
scanner.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
%{
#include "aux/types.h"
#include "aux/ast.h"
#include "parser.tab.h"
int line_number = 1;
int column = 1, next_column = 1;
#define YY_USER_ACTION column = next_column; next_column += yyleng;
void init_valor_lexico(int type);
%}
/* Definicao de algumas expressoes */
DIGIT [0-9]
ALPHA [A-Za-z_]
SIGN [+-]
DELIMITER [ \n[:punct:]]
/* Por conta da segunda etapa possuir '+-', os inteiros aqui serão naturais */
INT {DIGIT}+
CHAR \'[^']\'
STRING \"[^"\n]*\"
BOOL_ET_LITERAL_TRUE "TRUE"|"true"
BOOL_ET_LITERAL_FALSE "FALSE"|"false"
SPECIAL [\,\;\:\(\)\[\]\{\}\+\-\|\*\/\<\>\=\!\&\%\#\^\.\$\?]
%x MULTILINE_COMMENT
%%
/* Guarda o numero de linhas */
\n {line_number++; next_column=1;}
/* Caracteres que devem ser ignorados */
" " {}
" " {}
\r {}
/* Ignora comentarios simples */
\/\/.* {}
/* Ignora comentarios multi-linha */
\/\* {BEGIN(MULTILINE_COMMENT);} /* Entra no estado MULTILINE_COMMENT */
<MULTILINE_COMMENT>[^*\n]* {} /* Ignora qualquer CHAR que nao for * ou \n */
<MULTILINE_COMMENT>\*[^*/\n]* {} /* Ignora "*" nao seguido de "/" */
<MULTILINE_COMMENT>\n {line_number++;} /* Conta quebra de linhas em comentarios */
<MULTILINE_COMMENT>\*\/ {BEGIN(INITIAL);} /* Fim do comentario, retorna ao estado INITIAL */
/* Identifica os literais da linguagem */
{INT}/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_INT;
yylval.valor_lexico.value.i = atoi(yytext);
return TK_LIT_INT;
}
{INT}\.{INT}([Ee]{SIGN}?{INT})?/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_FLOAT;
yylval.valor_lexico.value.f = atof(yytext);
return TK_LIT_FLOAT;
}
{CHAR}/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_CHAR;
yylval.valor_lexico.value.c = yytext[1];
return TK_LIT_CHAR;
}
{STRING}/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_STRING;
yylval.valor_lexico.value.s = strndup(yytext+1, strlen(yytext)-2);
return TK_LIT_STRING;
}
{BOOL_ET_LITERAL_TRUE}/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_BOOL;
yylval.valor_lexico.value.b = 1;
return TK_LIT_TRUE;
}
{BOOL_ET_LITERAL_FALSE}/{DELIMITER} {
init_valor_lexico(TOKEN_TYPE_LIT);
yylval.valor_lexico.data_type = DT_BOOL;
yylval.valor_lexico.value.b = 0;
return TK_LIT_FALSE;
}
/* Identifica as palavras reservadas da linguagem */
"int" {return TK_PR_INT;}
"float" {return TK_PR_FLOAT;}
"bool" {return TK_PR_BOOL;}
"char" {return TK_PR_CHAR;}
"string" {return TK_PR_STRING;}
"if" {return TK_PR_IF;}
"else" {return TK_PR_ELSE;}
"while" {return TK_PR_WHILE;}
"do" {return TK_PR_DO;}
"input" {return TK_PR_INPUT;}
"output" {return TK_PR_OUTPUT;}
"return" {return TK_PR_RETURN;}
"const" {return TK_PR_CONST;}
"static" {return TK_PR_STATIC;}
"for" {return TK_PR_FOR;}
"break" {return TK_PR_BREAK;}
"continue" {return TK_PR_CONTINUE;}
/* Identifica os operadores compostos da linguagem */
"<=" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_LE;
}
">=" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_GE;
}
"==" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_EQ;
}
"!=" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_NE;
}
"&&" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_AND;
}
"||" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_OR;
}
">>" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_SR;
}
"<<" {
init_valor_lexico(TOKEN_TYPE_COMPOUND_OP);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_OC_SL;
}
/* Identifica os caracteres especiais da linguagem */
{SPECIAL} {
return yytext[0];
}
/* Identifica os identificadores da linguagem */
{ALPHA}({ALPHA}|{DIGIT})* {
init_valor_lexico(TOKEN_TYPE_ID);
yylval.valor_lexico.value.s = strdup(yytext);
return TK_IDENTIFICADOR;
}
/* Para qualquer outro padrão, retorna o token de erro */
. {return TOKEN_ERRO;}
%%
void init_valor_lexico(int type) {
yylval.valor_lexico.line_number = line_number;
yylval.valor_lexico.col_number = column;
yylval.valor_lexico.token_type = type;
yylval.valor_lexico.data_type = -1;
}