//declaracionconst //se checa que se tenga una definición de constante. si está bien //el identificador se pone en la tabla de símbolos, otro caso //el programador cometió un error al construir la definición de constante void declaracionconst() { int i; if (token==ident) { i=posicion(); if (i!=0) { error(41); //error 11: No se deben redefinir objetos } obtoken(); if ( (token==igl) || (token==asignacion) ) { //mejora del tipo "adivinación" de la intención del programador if (token==asignacion) error(1); //error 1: usar '=" en vez de ":=". es la misma técnica que en C & C++ se usa para if (x=) por if (x==) obtoken(); if (token == entero || token == real) { poner(CONSTANTE); obtoken(); } else error(2) ; //error 2: debe ir seguido de un número } else error (3) ; //error 3: el identificador debe ir seguido de "=" } else error(4) ; //error 4: Const, Var y Procedure deben ir seguidos de un identificador }
//bloque //da inicio el análisis sintáctico void bloque () { int temp; if (token==consttok) { obtoken(); declaracionconst();//llamada a función que checa que la constante esté bien definida. */ //si lo está, se coloca el identificador en la tds while (token==coma) { obtoken(); declaracionconst(); } if (token==puntoycoma) obtoken(); else error(5); //error 5: falta una coma o un punto y coma } if (token==vartok) { obtoken(); declaracionvar(); //llamada a función que checa que la variable esté bien declarada. */ //si lo está, se coloca el identificador en la tds while (token==coma) { obtoken(); declaracionvar(); } if (token==puntoycoma) obtoken(); else error(5); //error 5: Falta una coma o un punto y coma } while (token==proctok) { obtoken(); if (token==ident) { poner(PROCEDIMIENTO); obtoken(); } else error(4); //error 4: Const, Var y Procedure deben ir seguidos de un identificador if (token==puntoycoma) obtoken(); else error(5); //error 5: falta una coma o un punto y coma temp=it; bloque(); it=temp; if (token==puntoycoma) obtoken(); else error(5); } instruccion(); }
//declaracionvar //se checa que se tenga una declaración de variable. si está bien //el identificador se pone en la tabla de símbolos, otro caso //el programador cometió un error al construir la declaración de variable void declaracionvar() { if (token==ident) { poner(VARIABLE); obtoken(); } else error(4) ; //error 4: Const, Var y Procedure deben ir seguidos de un identificador }
//declaracionvar //se checa que se tenga una declaración de variable. si está bien //el identificador se pone en la tabla de símbolos, otro caso //el programador cometió un error al construir la declaración de variable void declaracionvar() { int i; if (token==ident) { i=posicion(); if (i!=0) { error(41); //error 11: No se deben redefinir objetos } poner(VARIABLE); obtoken(); } else error(4) ; //error 4: Const, Var y Procedure deben ir seguidos de un identificador }
void *peon(void *p) { const char * mi_nombre = (const char *) p; int ladrillos; while(get_puestos() < TOTAL){ ladrillos = rand() % 10 + 10; cuenta_ladrillos(); printf("%s: Pongo %i ladrillos-\n", mi_nombre, ladrillos); poner(ladrillos); usleep(100000 * (rand() % 3 + 1) ); } return NULL; }
//declaracionconst //se checa que se tenga una definición de constante. si está bien //el identificador se pone en la tabla de símbolos, otro caso //el programador cometió un error al construir la definición de constante void declaracionconst() { if (token==ident) { obtoken(); if (token==igl) { obtoken(); if (token==entero || token == real) { poner(CONSTANTE); obtoken(); } else error(2) ; //error 2: debe ir seguido de un número } else error (3) ; //error 3: el identificador debe ir seguido de "=" } else error(4) ; //error 4: Const, Var y Procedure deben ir seguidos de un identificador }
//bloque //da inicio el análisis sintáctico void bloque (int toksig[]) { int temp; int setpaso[NOTOKENS]; //conjunto de paso por valor int vacio[NOTOKENS]; //conjunto vacío init_set(vacio); do { if (token==consttok) { obtoken(); //do-while:equivale a insertar una coma do { declaracionconst(); //llamada a función que checa que la constante esté bien definida. */ //si lo está, se coloca el identificador en la TDS while (token==coma) { obtoken(); declaracionconst(); } if (token==puntoycoma) obtoken(); else error(5); //error 5: falta una coma o un punto y coma } while (token==ident); } if (token==vartok) { obtoken(); //análogo al "do" de arriba do { declaracionvar(); //llamada a función que checa que la variable esté bien declarada. */ //si lo está, se coloca el identificador en la TDS while (token==coma) { obtoken(); declaracionvar(); } if (token==puntoycoma) obtoken(); else error(5); //error 5: Falta una coma o un punto y coma } while (token==ident); } while (token==proctok) { obtoken(); if (token==ident) { poner(PROCEDIMIENTO); obtoken(); } else error(4); //error 4: Const, Var y Procedure deben ir seguidos de un identificador if (token==puntoycoma) obtoken(); else error(5); //error 5: falta una coma o un punto y coma temp=it; copia_set(setpaso,toksig); setpaso[puntoycoma]=1; //setpaso=puntoycoma+toksig bloque(setpaso); //sucesor+símbolos de cajón it=temp; if (token==puntoycoma) { obtoken(); copia_set(setpaso,tokiniinst); setpaso[ident]=setpaso[proctok]=1; //setpaso=tokiniinst+ident+proctok test(setpaso,toksig,6); //¿símbolo incorrecto después de un procedimiento? } else error(5); } copia_set(setpaso,tokiniinst); setpaso[ident]=1; //setpaso=tokiniinst+ident test(setpaso,tokinidecl,7); //se espera una instrucción } while (tokinidecl[token]==1); //salir cuando el token ya no sea de declaración copia_set(setpaso,toksig); setpaso[puntoycoma]=setpaso[endtok]=1; //setpaso=puntoycoma+end+toksig instruccion(setpaso); //aquí viene el chequeo explícito de que el token que viene a continuación //está en el conjunto de sucesores correctos (los sucesores de bloque) copia_set(setpaso,toksig); test(setpaso,vacio,8); //símbolo incorrecto detrás de las instrucciones de un bloque }