-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlexer.l
More file actions
132 lines (109 loc) · 5.92 KB
/
Copy pathlexer.l
File metadata and controls
132 lines (109 loc) · 5.92 KB
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
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* getenv */
#include "parser.tab.h" /* Cabecera generada por Bison: define tokens y YYLTYPE */
extern YYLTYPE yylloc;
extern int g_lex_errors;
/* Activa/desactiva impresión de tokens leídos (depuración) */
#define DEBUG_LEXER 0
/* YY_USER_ACTION se ejecuta antes de **cada** acción de regla del lexer.
Aquí propagamos la línea del token a Bison (yylloc.first/last_line). */
#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno;
/* Helpers de depuración (imprimen token y/o “atributo” simbólico) */
static void print_tok(const char* lexeme, const char* tok_name) {
if (!DEBUG_LEXER) return;
if (lexeme && *lexeme && tok_name && *tok_name) {
printf("[ %s ] :: %s\n", lexeme, tok_name);
}
}
static void print_tok_attr(const char* lexeme, const char* tok_name, int attr_number) {
if (!DEBUG_LEXER) return;
if (lexeme && *lexeme && tok_name && *tok_name) {
if (attr_number == -1)
printf("[ %s ] :: %s :: atrib = ( %s )\n", lexeme, tok_name, lexeme);
else
printf("[ %s ] :: %s :: atrib = %d ( %s )\n", lexeme, tok_name, attr_number, lexeme);
}
}
%}
/* ---- Opciones de Flex ----
noyywrap: evita que Flex pida más ficheros al acabar (yywrap()→0 implícito)
yylineno: hace que Flex mantenga y actualice la variable global yylineno
noinput/nounput: no generes funciones input()/unput() (reduce binario y “features” no usadas)
*/
%option noyywrap
%option yylineno
%option noinput
%option nounput
/* Estado léxico adicional para comentarios multi-línea (start conditions) */
%x CMT
/* ----- Macros (expresiones regulares reutilizables) ----- */
WS [ \t\r\f\v]+
IDENT_RE [A-Za-z_][A-Za-z0-9_]*
DIGITS [0-9]+
REALCOMA {DIGITS},{DIGITS} /* reales con coma (p.e. 1,5) */
DQSTR \"[^\"\n]*\"
CMT_LINE \/\/[^\n]*
%%
{WS} ;
\n+ ;
{CMT_LINE} ;
"/*" { BEGIN(CMT); }
<CMT>[^*\n]+ ;
<CMT>\n+ ;
<CMT>"*"+[^*/\n] ;
<CMT>"*"+"/" { BEGIN(INITIAL); }
<CMT><<EOF>> { g_lex_errors++; fprintf(stderr, "Error léxico (línea %d): comentario sin cerrar\n", yylineno); yyterminate(); }
"if" { print_tok(yytext, "IF"); return IF; }
"then" { print_tok(yytext, "THEN"); return THEN; }
"else" { print_tok(yytext, "ELSE"); return ELSE; }
"while" { print_tok(yytext, "WHILE"); return WHILE; }
"do" { print_tok(yytext, "DO"); return DO; }
"until" { print_tok(yytext, "UNTIL"); return UNTIL; }
"read" { print_tok(yytext, "NOM_ENTRADA"); return NOM_ENTRADA; }
"write" { print_tok(yytext, "NOM_SALIDA"); return NOM_SALIDA; }
"proc" { print_tok(yytext, "PROC"); return PROC; }
"int" { yylval.atrib = 0; print_tok_attr(yytext, "TIPO", 0); return TIPO; }
"real" { yylval.atrib = 1; print_tok_attr(yytext, "TIPO", 1); return TIPO; }
"char" { yylval.atrib = 2; print_tok_attr(yytext, "TIPO", 2); return TIPO; }
"bool" { yylval.atrib = 3; print_tok_attr(yytext, "TIPO", 3); return TIPO; }
"false" { yylval.atrib = 0; yylval.tipo = booleano;
print_tok_attr(yytext, "BOOLEAN",0); return BOOLEAN; }
"true" { yylval.atrib = 1; yylval.tipo = booleano;
print_tok_attr(yytext, "BOOLEAN",1); return BOOLEAN; }
"**" { yylval.atrib = 2; print_tok_attr(yytext, "OP_MUL", 0); return OP_MUL; }
"*" { yylval.atrib = 0; print_tok_attr(yytext, "OP_MUL", 0); return OP_MUL; }
"/" { yylval.atrib = 1; print_tok_attr(yytext, "OP_MUL", 1); return OP_MUL; }
"==" { yylval.atrib = 0; print_tok_attr(yytext, "OP_EQ", 0); return OP_EQ; }
"!=" { yylval.atrib = 1; print_tok_attr(yytext, "OP_EQ", 1); return OP_EQ; }
"<=" { yylval.atrib = 0; print_tok_attr(yytext, "OP_REL", 0); return OP_REL; }
">=" { yylval.atrib = 1; print_tok_attr(yytext, "OP_REL", 1); return OP_REL; }
"<" { yylval.atrib = 2; print_tok_attr(yytext, "OP_REL", 2); return OP_REL; }
">" { yylval.atrib = 3; print_tok_attr(yytext, "OP_REL", 3); return OP_REL; }
"and" { print_tok(yytext, "AND"); return AND; }
"or" { print_tok(yytext, "OR"); return OR; }
"xor" { print_tok(yytext, "XOR"); return XOR; }
"+" { yylval.atrib = 0; print_tok_attr(yytext, "OP_ADD", 0); return OP_ADD; }
"-" { yylval.atrib = 1; print_tok_attr(yytext, "OP_ADD", 1); return OP_ADD; }
"~" { print_tok(yytext, "NOT"); return NOT; }
"$" { print_tok(yytext, "DOLLAR"); return DOLLAR; }
"=" { print_tok(yytext, "ASSIGN"); return ASSIGN; }
"(" { print_tok(yytext, "PIZQ"); return PIZQ; }
")" { print_tok(yytext, "PDER"); return PDER; }
"[" { print_tok(yytext, "CORIZQ"); return CORIZQ; }
"]" { print_tok(yytext, "CORDER"); return CORDER; }
"{" { print_tok(yytext, "IBLOQ"); return IBLOQ; }
"}" { print_tok(yytext, "FBLOQ"); return FBLOQ; }
"," { print_tok(yytext, "COM"); return COM; }
";" { print_tok(yytext, "PYC"); return PYC; }
{REALCOMA} { yylval.atrib = atof(yytext);
print_tok(yytext, "REAL"); return REAL; }
{DIGITS} { yylval.atrib = atoi(yytext);
print_tok(yytext, "ENTERO"); return ENTERO; }
{DQSTR} {
print_tok(yytext, "CADENA"); return CADENA; }
{IDENT_RE} { yylval.lexema = strdup(yytext);
print_tok_attr(yytext, "IDENT", -1); return IDENT; }
. { g_lex_errors++; fprintf(stderr, "Error léxico (línea %d): carácter no reconocido '%s'\n", yylineno, yytext); }
%%