/* MODULO AUXILIAR PARA EL ROBOT KAREL */ /* ==================================================*/ /* === Programa: karel.yac ===*/ /* === TEcnica: Dirigida por la sintAxis ===*/ /* === Programador: J. Rafael R. ochoa ===*/ /* ==================================================*/ %{ struct codif // almacena el codigo objeto (*.ok) { int linea; // numero de linea char *comando; // nombre de comando struct codif *sig; // apuntador al siguiente nodo struct codif *ant; // apuntador al nodo anterior }; char e1[50], e2[50], b1[50], b2[50]; // variables de etiqueta(2) y brincos(2) int etiqueta = 1; int lineno = 1; %} %union { char str[80]; struct codif *robot; } /* =============PROGRAMA=======================*/ %token INICIO_DE_AMBIENTE FIN_DE_AMBIENTE %token INICIO_DE_EJECUCION FIN_DE_EJECUCION %token INICIO_DE_PROGRAMA FIN_DE_PROGRAMA /* =============AMBIENTE=======================*/ %token KAREL_ESTA_EN_CALLE AVENIDA VIENDO_AL CON MONEDAS_EN_SU_BOLSA %token NORTE SUR ESTE OESTE %token PARED_JUNTO_A_AVENIDA PARED_JUNTO_A_CALLE DE_CALLE %token DE_AVENIDA A HAY MONEDAS_EN_CALLE /* ============BLOQUE==========================*/ %token INICIO FIN /* ============CONDICION=======================*/ %token SI ENTONCES SINO /* ============REPETICION======================*/ %token REPITE VECES MIENTRAS HAZ /* =============PRIMITIVAS=====================*/ %token AVANZA GIRA_A_LA_IZQUIERDA RECOGE_MONEDA COLOCA_MONEDA %token APAGATE /* ============FUNCIONES=======================*/ %token DEFINE_NUEVA_INSTRUCCION COMO /* ============PRUEBAS=========================*/ %token FRENTE_DESPEJADO FRENTE_BLOQUEADO %token IZQUIERDA_DESPEJADA IZQUIERDA_BLOQUEADA %token DERECHA_DESPEJADA DERECHA_BLOQUEADA %token JUNTO_A_MONEDA NO_JUNTO_A_MONEDA %token HACIA_EL_NORTE NO_HACIA_EL_NORTE %token HACIA_EL_SUR NO_HACIA_EL_SUR %token HACIA_EL_ESTE NO_HACIA_EL_ESTE %token HACIA_EL_OESTE NO_HACIA_EL_OESTE %token CON_MONEDAS_EN_SU_BOLSA SIN_MONEDAS_EN_SU_BOLSA /* ============TOKENS QUE REGRESAN VALOR===========*/ %token <str> NUM FUNCION %type <robot> karel ambiente describe_amb instr_karel instr_amb %type <robot> pared moneda programa funciones funcion %type <robot> ejecucion instrucciones instruccion instr_primitiva %type <robot> call_to_func condicion direccion sino %% /* producciones de la gramatica */ karel : ambiente programa {archiva($1, $2);} ; ambiente : INICIO_DE_AMBIENTE describe_amb FIN_DE_AMBIENTE { $$ = lista($2, nodo("jc kini")); } ; describe_amb : instr_karel instr_amb {$$ = lista($1, $2);} ; instr_karel : KAREL_ESTA_EN_CALLE NUM AVENIDA NUM VIENDO_AL direccion CON NUM MONEDAS_EN_SU_BOLSA ';' { $$ = lista(nodo("k"), lista(nodo($2), lista(nodo($4), lista($6, nodo($8)))) ); } ; direccion : NORTE { $$ = nodo("NORTE"); } | SUR { $$ = nodo("SUR"); } | ESTE { $$ = nodo("ESTE"); } | OESTE { $$ = nodo("OESTE"); } ; instr_amb : pared instr_amb {$$ = lista($1, $2);} | moneda instr_amb {$$ = lista($1, $2);} | {$$ = NULL;} ; pared : PARED_JUNTO_A_CALLE NUM DE_AVENIDA NUM A NUM ';' {$$ = lista(nodo("pc"), lista(nodo($2), lista(nodo($4), nodo($6)))); } | PARED_JUNTO_A_AVENIDA NUM DE_CALLE NUM A NUM ';' {$$ = lista(nodo("pa"), lista(nodo($2), lista(nodo($4), nodo($6)))); } ; moneda : HAY NUM MONEDAS_EN_CALLE NUM AVENIDA NUM ';' {$$ = lista(nodo("m"), lista(nodo($2), lista(nodo($4), nodo($6)))); } ; programa : INICIO_DE_PROGRAMA funciones ejecucion FIN_DE_PROGRAMA {$$ = lista($2, $3);} ; funciones : {$$ = NULL;} | funcion funciones {$$ = lista($1, $2);} ; funcion : DEFINE_NUEVA_INSTRUCCION FUNCION COMO instruccion {$$ = lista(nodo($2), lista($4, nodo("rs"))); } ; ejecucion : INICIO_DE_EJECUCION instrucciones FIN_DE_EJECUCION {$$ = lista(nodo("kini"), $2);} ; instrucciones : instruccion instrucciones {$$ = lista($1, $2);} | {$$ = NULL;} ; instruccion : instr_primitiva {$$ = $1;} | INICIO instrucciones FIN {$$ = $2;} | SI condicion ENTONCES instruccion sino { sprintf(e1, "%s", genera_etiqueta()); sprintf(e2, "%s", genera_etiqueta()); sprintf(b1, "jc %s", e1); sprintf(b2, "jc %s", e2); $$ = lista($2, lista(nodo(b1), lista($4, lista(nodo(b2), lista(nodo(e1), lista($5, nodo(e2)))))) ); } | REPITE NUM VECES instruccion { $$ = repite($4, atoi($2));} | MIENTRAS condicion HAZ instruccion { sprintf(e1, "%s", genera_etiqueta()); sprintf(e2, "%s", genera_etiqueta()); sprintf(b1, "jc %s", e1); sprintf(b2, "jc %s", e2); $$ = lista(nodo(e1), lista($2, lista(nodo(b2), lista($4, lista(nodo(b1), nodo(e2))))) ); } | call_to_func {$$ = $1;} ; sino : {$$ = NULL;} | SINO instruccion {$$ = $2; } ; instr_primitiva : GIRA_A_LA_IZQUIERDA ';' {$$ = nodo("gi");} | AVANZA ';' {$$ = nodo("av");} | APAGATE ';' {$$ = nodo("ap");} | COLOCA_MONEDA ';' {$$ = nodo("cm");} | RECOGE_MONEDA ';' {$$ = nodo("rm");} ; call_to_func : FUNCION ';' { sprintf(b1, "js %s", $1); $$ = nodo(b1); } ; condicion : FRENTE_DESPEJADO {$$ = nodo("fd") ;} | FRENTE_BLOQUEADO {$$ = nodo("fb") ;} | IZQUIERDA_DESPEJADA {$$ = nodo("id") ;} | IZQUIERDA_BLOQUEADA {$$ = nodo("ib") ;} | DERECHA_DESPEJADA {$$ = nodo("dd") ;} | DERECHA_BLOQUEADA {$$ = nodo("db") ;} | JUNTO_A_MONEDA {$$ = nodo("jm") ;} | NO_JUNTO_A_MONEDA {$$ = nodo("njm");} | HACIA_EL_NORTE {$$ = nodo("hn") ;} | NO_HACIA_EL_NORTE {$$ = nodo("nhn");} | HACIA_EL_SUR {$$ = nodo("hs") ;} | NO_HACIA_EL_SUR {$$ = nodo("nhs");} | HACIA_EL_ESTE {$$ = nodo("he") ;} | NO_HACIA_EL_ESTE {$$ = nodo("nhe");} | HACIA_EL_OESTE {$$ = nodo("ho") ;} | NO_HACIA_EL_OESTE {$$ = nodo("nho");} | CON_MONEDAS_EN_SU_BOLSA {$$ = nodo("din");} | SIN_MONEDAS_EN_SU_BOLSA {$$ = nodo("smb");} ; %% /* funciones auxiliares */ #include <stdio.h> #include <stdlib.h> #include <string.h> extern int yylex(); /* Liga con la funcion yylex generada por LEX */ extern int yynerrs; extern FILE *yyin; int yyparse(); int main(int argc, char *argv[]) { if (argc != 2) {printf ("\nOlvido el archivo karel\n"); return 0; } yyin = fopen(argv[1],"r"); if (yyin == NULL) { printf ("error al abrir el archivo"); return 0; } /*Llama al analizador sintactico */ yyparse(); fclose(yyin); return 0; } yyerror() /* llamado por yyparse() cuando ocurra */ { /* un error */ printf("\n [error en linea %d] \n", lineno); return 1; } struct codif *nodo(char *cad) { struct codif *nodo_nuevo = NULL; nodo_nuevo = (struct codif *)malloc(sizeof(struct codif)); nodo_nuevo->comando = strdup(cad); nodo_nuevo->linea = lineno; nodo_nuevo->sig = NULL; nodo_nuevo->ant = NULL; return nodo_nuevo; } struct codif *lista(struct codif *lista1, struct codif *lista2) { struct codif *lista_total = lista1; struct codif *anterior; if (!lista1 && !lista2) return NULL; if (lista2 == NULL ) return lista1; if (lista1 == NULL ) return lista2; while(lista1) { anterior = lista1; lista1 = lista1->sig; } anterior->sig = lista2; lista2->ant = anterior; return lista_total; } char *genera_etiqueta(void) { char etiq[10]; sprintf(etiq, "etiq_%d", etiqueta); etiqueta++; return strdup(etiq); } void archiva(struct codif *amb, struct codif *prog) { FILE *out; printf("hola mundo ..."); if ((out = fopen("karel.ok", "wt")) == NULL) // archivo de salida { printf("No se puede crear el archivo karel.ok\n"); return; } printf("\nAlmacenando el archivo karel.ok\n"); while(amb) { fprintf(out, "%d %s\n", amb->linea, amb->comando); amb = amb->sig; } while(prog) { fprintf(out, "%d %s\n", prog->linea, prog->comando); prog = prog->sig; } fprintf(out, "ok\n"); fclose(out); } struct codif *copia(struct codif *lista) { struct codif *salida = NULL; struct codif *nuevo = NULL; struct codif *temp = NULL; while(lista) { nuevo = nodo(lista->comando); nuevo->linea = lista->linea; if(!salida) {salida = nuevo; temp = nuevo;} else {temp->sig = nuevo; temp = nuevo;} lista = lista->sig; } return salida; } struct codif *repite(struct codif *instr, int n) { struct codif *salida = NULL; struct codif *temp; while(n) { printf("\nN= %d y comando= %s",n,instr->comando); temp = NULL; temp = copia(instr); salida = lista(salida, temp); n--; } return salida; }