| INSTITUTO POLITÉCNICO NACIONAL ESCUELA SUPERIOR DE CÓMPUTO |

Introducción | Contenido | Bibliografía

Introducción
Contenido
UNIDAD I
UNIDAD II
UNIDAD III
UNIDAD IV
UNIDAD V
UNIDAD VI
UNIDAD VII
UNIDAD VIII
UNIDAD IX
PROBLEMARIO Problema Unidad 8.4 Problemas 1-10 Problemas 11-20 Problemas 21-30

Problemas 31-40

Problemas 41-50

Bibliografía

PROBLEMARIO

Problema Unidad 8.4

> Se presenta la solución por medio de LEX de una calculadora, que sirve como auxiliar para un proyecto implementado de esta calculadora. Este problema es un apoyo para el tema de la Unidad 8.4 de este polilibro. El problema tiene como objetivo, reconocer las palabras reservadas, los identificadores y los números, así como ignorar comentarios y llevar la cuenta del número de línea por el que avanza el análisis léxico. Los comentarios se extienden en líneas completas y comienzan por un asterisco:

> 1 %{
> 2 int linea_actual = 1;
> 3 %}
> 4 %START COMENT
> 5 %%
> 6 ^[b¯& \t]*"*" { BEGIN COMENT; }
> 7 <COMENT>.+ { ; }
> 8 <COMENT>\n { BEGIN 0; linea_actual ++; }
> 9
> 10 ":=" { return ASIG; }
> 11 ">=" { return MAI; }
> 12 "<=" { return MEI; }
> 13 "!=" { return DIF; }
> 14 CASE { return CASE; }
> 15 OF { return OF; }
> 16 CASO { return CASO; }
> 17 OTHERWISE { return OTHERWISE; }
> 18 REPEAT { return REPEAT; }
> 19 UNTIL { return UNTIL; }
> 20 IF { return IF; }
> 21 THEN { return THEN; }
> 22 ELSE { return ELSE; }
> 23 WHILE { return WHILE; }
> 24 DO { return DO; }
> 25 AND { return AND; }
> 26 OR { return OR; }
> 27 NOT { return NOT; }
> 28 FIN { return FIN; }
> 29
> 30 [0-9]+ {
> 31 strcpy(yylval.numero, yytext);
> 32 return NUMERO;
> 33 }
> 34 [A-Za-z_][A-Za-z0-9_]* {
> 35 strcpy(yylval.variable_aux, yytext);
> 36 return ID;
> 37 }
> 38 [b¯& \t]+ { ; }
> 39 \n { linea_actual++; }
> 40 . { return yytext[0]; }

> En cuanto al código Yacc, es el siguiente:
> 1 /* Declaraciones de apoyo */
> 2 %{
> 3 typedef struct _doble_cond {
> 4 char etq_verdad[21],
> 5 etq_falso[21];
> 6 } doble_cond;
> 7 typedef struct _datos_case {
> 8 char etq_final[21];
> 9 char variable_expr[21];
> 10 } datos_case;
> 11 %}
> 12 /* Declaracion de atributos */
> 13 %union {
> 14 char numero[21];
> 15 char variable_aux[21];
> 16 char etiqueta_aux[21];
> 17 char etiqueta_siguiente[21];
> 18 doble_cond bloque_cond;
> 19 datos_case bloque_case;
> 20 }
> 21 /* Declaracion de tokens y sus atributos */
> 22 %token <numero> NUMERO
> 23 %token <variable_aux> ID
> 24 %token <etiqueta_aux> IF WHILE REPEAT
> 25 %token <etiqueta_siguiente> CASO
> 26 %token ASIG THEN ELSE FIN DO UNTIL CASE OF OTHERWISE
> 27 %token MAI MEI DIF
> 28 /* Declaración de no terminales y sus atributos */
> 29 %type <variable_aux> expr
> 30 %type <bloque_cond> cond
> 31 %type <bloque_case> inicio_case
> 32 /* Precedencia y asociatividad de operadores */
> 33 %left OR
> 34 %left AND
> 35 %left NOT
> 36 %left '+' '-'
> 37 %left '*' '/'
> 38 %left MENOS_UNARIO
> 39
> 40 %%
> 41 prog : prog sent ';'
> 42 | prog error ';' { yyerrok; }
> 43 |
> 44 ;
> 45 sent : ID ASIG expr {
> 46 printf("\t%s = %s\n", $1, $3);
> 47 }
> 48 | IF cond {
> 49 printf("label %s\n", $2.etq_verdad);
> 50 }
> 51 THEN sent ';' {
> 52 nuevaEtq($1);
> 53 printf("\tgoto %s\n", $1);
> 54 printf("label %s\n", $2.etq_falso);
> 55 }
> 56 opcional
> 57 FIN IF {
> 58 printf("label %s\n", $1);
> 59 }
> 60 | '{' lista_sent '}' { ; }
> 61 | WHILE {
> 62 nuevaEtq($1);
> 63 printf("label %s\n", $1);
> 64 }
> 65 cond {
> 66 printf("label %s\n", $3.etq_verdad);
> 67 }
> 68 DO sent ';'
> 69 FIN WHILE {
> 70 printf("\tgoto %s\n", $1);
> 71 printf("label %s\n", $3.etq_falso);
> 72 }
> 73 | REPEAT {
> 74 nuevaEtq($1);
> 75 printf("label %s\n", $1);
> 76 }
> 77 sent ';'
> 78 UNTIL cond {
> 79 printf("label %s\n", $6.etq_falso);
> 80 printf("\tgoto %s\n", $1);
> 81 printf("label %s\n", $6.etq_verdad);
> 82 }
> 83 | sent_case
> 84 ;
> 85 opcional : ELSE sent ';'
> 86 | /* Epsilon */
> 87 ;
> 88 lista_sent : /* Epsilon */
> 89 | lista_sent sent ';'
> 90 | lista_sent error ';' { yyerrok; }
> 91 ;
> 92 sent_case : inicio_case
> 93 OTHERWISE sent ';'
> 94 FIN CASE {
> 95 printf("label %s\n", $1.etq_final);
> 96 }
> 97 | inicio_case
> 98 FIN CASE {
> 99 printf("label %s\n", $1.etq_final);
> 100 }
> 101 ;
> 102 inicio_case : CASE expr OF {
> 103 strcpy($$.variable_expr, $2);
> 104 nuevaEtq($$.etq_final);
> 105 }
> 106 | inicio_case
> 107 CASO expr ':' {
> 108 nuevaEtq($2);
> 109 printf("\tif %s != %s goto %s\n",
> 110 $1.variable_expr, $3, $2);
> 111 }
> 112 sent ';' {
> 113 printf("\tgoto %s\n", $1.etq_final);
> 114 printf("label %s\n", $2);
> 115 strcpy($$.variable_expr, $1.variable_expr);
> 116 strcpy($$.etq_final, $1.etq_final);
> 117 }
> 118 ;
> 119 expr : NUMERO { generarTerceto("\t%s = %s\n", $$, $1, NULL); }
> 120 | ID { strcpy($$, $1); }
> 121 | expr '+' expr { generarTerceto("\t%s = %s + %s\n", $$, $1, $3); }
> 122 | expr '-' expr { generarTerceto("\t%s = %s - %s\n", $$, $1, $3); }
> 123 | expr '*' expr { generarTerceto("\t%s = %s * %s\n", $$, $1, $3); }
> 124 | expr '/' expr { generarTerceto("\t%s = %s / %s\n", $$, $1, $3); }
> 125 | '-' expr %prec MENOS_UNARIO
> 126 { generarTerceto("\t%s = - %s\n", $$, $2, NULL); }
> 127 | '(' expr ')' { strcpy($$, $2); }
> 128 ;
> 129 cond : expr '>' expr { generarCondicion($1, ">", $3, &($$)); }
> 130 | expr '<' expr { generarCondicion($1, "<", $3, &($$)); }
> 131 | expr MAI expr { generarCondicion($1, ">=", $3, &($$)); }
> 132 | expr MEI expr { generarCondicion($1, "<=", $3, &($$)); }
> 133 | expr '=' expr { generarCondicion($1, "=", $3, &($$)); }
> 134 | expr DIF expr { generarCondicion($1, "!=", $3, &($$)); }
> 135 | NOT cond { strcpy($$.etq_verdad, $2.etq_falso);
> 136 strcpy($$.etq_falso, $2.etq_verdad);
> 137 }
> 138 | cond AND {
> 139 printf("label %s\n", $1.etq_verdad);
> 140 }
> 141 cond {
> 142 printf("label %s\n", $1.etq_falso);
> 143 printf("\tgoto %s\n", $4.etq_falso);
> 144 strcpy($$.etq_verdad, $4.etq_verdad);
> 145 strcpy($$.etq_falso, $4.etq_falso);
> 146 }
> 147 | cond OR {
> 148 printf("label %s\n", $1.etq_falso);
> 149 }
> 150 cond {
> 151 printf("label %s\n", $1.etq_verdad);
> 152 printf("\tgoto %s\n", $4.etq_verdad);
> 153 strcpy($$.etq_verdad, $4.etq_verdad);
> 154 strcpy($$.etq_falso, $4.etq_falso);
> 155 }
> 156 | '(' cond ')' {
> 157 strcpy($$.etq_verdad, $2.etq_verdad);
> 158 strcpy($$.etq_falso, $2.etq_falso);
> 159 }
> 160 ;
> 161
> 162 %%
> 163 #include "ejem6l.c"
> 164 void main() {
> 165 yyparse();
> 166 }
> 167 void yyerror(char * s) {
> 168 fprintf(stderr, "Error de sintaxis en la linea %d\n", linea_actual);
> 169 }
> 170 void nuevaTmp(char * s) {
> 171 static actual=0;
> 172 sprintf(s, "tmp%d", ++actual);
> 173 }
> 174 void nuevaEtq(char * s) {
> 175 static actual=0;
> 176 sprintf(s, "etq%d", ++actual);
> 177 }
> 178 void generarTerceto( char * terceto,
> 179 char * Lvalor,
> 180 char * Rvalor1,
> 181 char * Rvalor2){
> 182 nuevaTmp(Lvalor);
> 183 printf(terceto, Lvalor, Rvalor1, Rvalor2);
> 184 }
> 185 void generarCondicion( char * Rvalor1,
> 186 char * condicion,
> 187 char * Rvalor2,
> 188 doble_cond * etqs){
> 189 nuevaEtq((*etqs).etq_verdad);
> 190 nuevaEtq((*etqs).etq_falso);
> 191 printf("\tif %s %s %s goto %s\n", Rvalor1, condicion, Rvalor2, (*etqs).etq_verdad);
> 192 printf("\tgoto %s\n", (*etqs).etq_falso);
> 193 }

> Atrás Siguiente

##### Introducción / Contenido / Unidad I / Unidad II / Unidad III / Unidad IV / Unidad V / Unidad VI / Unidad VII / Unidad VIII / Unidad IX / Problemario / Bibliografía

##### Inicio

##### Créditos

José Sánchez Juárez, Andrés Ortigoza Campos, Fabiola Ocampo Botello