jueves, 14 de enero de 2010

miércoles, 13 de enero de 2010

Hola

Hola a todos.. estos son mis dos programas que me hicieron sufrir un rato... pero es algo normal, ya deberia estar acostumbrada porque ya tengo mucho tiempo conociendo a Lemus...jejeje...pero bueno....buena suerte a todos y que todos este año tengamos mucha salud y prosperidad, yo pues a lo que respecta empece un poco mal, por lo de mi brazo, pero se soluciono, tratare de cuidarme mas compañeros.. cuidense mucho, y aver que pasa si Lemus nos seguira dando clases.

Nota: Lemus.. muchas gracias por ser paciemte conmigo....
que no te tiemble la mano para ponernos buenas calificaciones a todos...jajaja
bueno suerte para todos.

SalidaPHP...codigo 2

#Archivo de la

class WordClass {
public:
/// variables globales
///\var text guarda una cadena de caracteres
///
void text;

/// funcion constructor
///\param number numero de clase
///
void __construct(void number) {
echo "Empezo la clase: ".number."";
}

/// funcion para cambiar la palabra
///\param nuevotexto texto que reemplazara a la actual palabra
///
void cambiarWord(void nuevotexto) {
echo "El texto ".this->text." ha sido remplazado por: ";
this->text = nuevotexto;
echo this->text;
echo "
";
}
}

codigo2

#Archivo de la clase

class WordClass {
/* variables globales
\var text guarda una cadena de caracteres
*/
var $text;

/* funcion constructor
\param number numero de clase
*/
function __construct(var $number) {
echo "Empezo la clase: ".$number."";
}

/* funcion para cambiar la palabra
\param nuevotexto texto que reemplazara a la actual palabra
*/
function cambiarWord(var $nuevotexto) {
echo "El texto ".$this->text." ha sido remplazado por: ";
$this->text = $nuevotexto;
echo $this->text;
echo "
";
}
}
?>

mainphp.c

#include
#include

using namespace std;

char *reservadas[] = {"global","function","echo","static","return","array"};

int convertir( char* archivo );

int main(int argc,char** argv)
{
char nombArchivo[ 260 ];

if(argc>=2)
{
strcpy(nombArchivo,argv[1]);
}
else
{
cout<<"Nombre de archivo de entrada: ";
cin.sync();
cin.getline(nombArchivo,260);
}

if(convertir(nombArchivo)!=0)
{
if(argc==1)
{ cout<<"No se puede abrir el archivo"< }

if(argc==1) system("pause");

return 0;
}

int convertir( char* archivo )
{
fstream entrada, salida;
char buffer[512], pal[51]="";
int i,j,fPhp=0,k,tam,fVar=0,fFunc=0,fcoment=0,fesp=0,fPhpIni=0;

entrada.open(archivo,ios::in);
if(entrada.fail()) return 1;

salida.open("salidaPHP.txt",ios::out);
if(salida.fail()) return 1;

while(entrada.eof()!=1)
{
entrada.getline(buffer,512);
tam = strlen(buffer);

i=0;

if(buffer[i]=='<' && buffer[i+1]=='?' && fPhpIni==0) // busca inicio de php
{
for( ; i < tam; i++ ) ;
fPhpIni=1;
continue;
}

for( i=0,j=0; i <= tam && fPhpIni==1; i++)
{
if((buffer[i]=='/' && buffer[i+1]=='*') || fcoment==1) // comentarios
{
fcoment=1;

for(;buffer[i]==' '&&i {
cout< salida< }

if(buffer[i]=='/'&&buffer[i+1]=='*') i+=2;

cout<<"///";
salida<<"///";

for(;i < tam; i++)
{
if(buffer[i]=='*'&&buffer[i+1]=='/') // hasta el final de comentario
{ fcoment = 0; i++; break; }

cout< salida< }
}

else if(buffer[i]=='?'&&buffer[i+1]=='>') // fin de php
{
i++;
/*
cout<<"};";
salida<<"};";*/
fPhp = 1;
break;
}

else if(isalnum(buffer[i]) || buffer[i]=='_'|| buffer[i]=='$')
{
pal[j++] = buffer[i];
pal[j]='\0';
}

else
{
if(strcmp(pal,"var")==0) // si es declaracion de variable
{ cout<<"void";
salida<<"void";
}

else if(strcmp(pal,"function")==0) // si es funcion
{
cout<<"void";
salida<<"void";
}

else if(strcmp(pal,"class")==0)
{
cout< salida<
for(;i {
cout< salida< }

cout<<"\n\tpublic:";
salida<<"\n\tpublic:";
}

else if(pal[0]=='$') // si es variable
{
cout<<&pal[1];
salida<<&pal[1];
}

else
{
if(buffer[i]!='\0')
{ cout< salida< }
}

if(isalnum(buffer[i])==0 && buffer[i]!='_' && buffer[i]!='$'&&buffer[i]!='\0')
{
cout< salida< }

j=0;
pal[j]='\0';
}
}

cout< salida<
if(fPhp==1)break;
}

entrada.close();
salida.close();

return 0;
}

Doxygen....PHP

/* \var nombre guarda una cadena de caracteres
\var numero guarda un dato numerico
*/
var $nombre;
var $numero;

/* funcion que suma a y b
\param a valor para primer operando
\param b valor para segundo operando
\return la suma de a y b
*/
function valor( var $a,var $b )
{
return $a+$b;
}

/* funcion que hace el producto de ab y da
\param ab primer operando
\param da segundo operando
\return el producto de ab * da
*/
function operacion( var $ab, var $da )
{
return $ab * $da;
}

/* imprime la cadena hola mundo */
function Hola()
{
echo "Hola mundo!";
}

/* pone un texto en la variable "nombre"
\param cadena recibe una cadena de caracteres
*/
function ponerTexto( var $cadena )
{
$nombre = cadena;
}
?>

Lexico...

#include "main.h"

extern TOKEN tablaSimb[SIMBOLOS];
extern TOKEN sintBuf[SINTAXIS];
extern char buffer[BUFFER];
extern int Bufpos, sinCont, Sinpos, buftam, linea, idSimb, simCont;

int InsertarSimbolo(char* token, int id, int tipo);

/* php 4 */
char *reservadas[RESERVADAS] = { "and","or","xor","__FILE__","exception","php_user_filter"
"__LINE__","array","as","break","case","cfunction","class",
"const","continue","declare","default","die","do","echo","else",
"elseif","empty","enddeclare","endfor","endforeach","endif",
"endswitch","endwhile","eval","exit","extends","for","foreach",
"function","global","if","include","include_once","isset","list",
"new","old_function","print","require","require_once","return",
"static","switch","unset","use","var","while","__FUNCTION__",
"__CLASS__","__METHOD__" };

char *Operadores[OPERADORES] = { "+","-","*","/","%","++","--","=","+=","-=","*=","/=","%=",".=",
"!","and","or","xor","&&","||","==",">","<","!=","<=",">=",
"&","|","{","}","(",")","[","]",".",",",";" };

int Tabla[7][7] = { { 1, 2, 3, 1, 1, 6, 6 },
{ 1, 1, 1, 1, 1, 6, 0 },
{ 6, 3, 3, 6, 5, 6, 6 },
{ 6, 3, 3, 6, 6, 6, 4 },
{ 6, 4, 4, 6, 6, 6, 6 },
{ 6, 5, 5, 5, 6, 6, 6 },
{ 6, 6, 6, 6, 6, 6, 6 } };

int AnaLex(char* token)
{
int i = Bufpos, rt=0, estado=0, j=0, res_id;
int flgHex=0, flgID = 0;
char ttok[61], tmpc;
TOKEN tmp_sim;

for( ; i <= buftam; i++ )
{
if(isalpha(buffer[i]) || buffer[i]=='_' || buffer[i]=='$')
{
tmpc = toupper(buffer[i]);

switch(estado)
{ // para ID
case 0: case 1: estado = Tabla[estado][0]; break;

case 2: // puede ser numero oct o hex
{
if(tmpc == 'X') // si es hex
estado = Tabla[estado][4];
else
estado = Tabla[estado][1]; // error en hex
} break;

case 5:
{
if(tmpc >= 'A' && tmpc <= 'F') // es numero hex
estado = Tabla[estado][3];
else
estado = Tabla[estado][1]; // error en hex
} break;

default: estado = Tabla[estado][1]; // error
}

ttok[j++] = buffer[i];
ttok[j] = '\0';
}

else if(isdigit(buffer[i])) // si es digito
{
switch(estado)
{
case 0:
{
if( buffer[Bufpos] == '0' ) // puede ser octal o hexa
estado = Tabla[ estado][1];
else
estado = Tabla[estado][2];
} break;

case 1: estado = Tabla[estado][1]; break;

case 2: case 3: case 4: estado = Tabla[estado][1]; break;

case 5: estado = Tabla[estado][2]; break; // numero hex
}

ttok[j++] = buffer[i];
ttok[j] = '\0';
}
// cualquier otro caracter perteneciente al lenguaje
else if(OperadorArit(buffer[i]) || OperadorRel(buffer[i]) || OperadorLog(buffer[i])
|| OperadorOtro(buffer[i]) || OperadorGrupo(buffer[i]) || buffer[i]=='\0'
|| buffer[i]==' ')
{
short flg=0;

for(;buffer[i] == ' ';i++) flg=1; // salta espacios

if(flg==1) Bufpos = --i;

if(buffer[i] == '.' && estado == 3)
{
estado = Tabla[ estado ][ 6 ];

ttok[ j++ ] = buffer[ i ];
ttok[ j ] = '\0';
}

else
{
if(estado==6 || buffer[i] == '.'||(ttok[0]=='$'&&isdigit(ttok[1]))) // si hay error
{
cout<<"\nError! ["< rt = TOKEN_INVALIDO;
}

else if(estado == 1) // identificador o constante
{
strcpy(tmp_sim.token,ttok);
tmp_sim.tipo = VARIABLE;

if( ttok[0]=='$') // es variable
{
tmp_sim.id = ID_SIMBOLOS + idSimb;
rt = IDENTIFICADOR;

if(BuscarSimbolo(ttok)==TOKEN_NO_ENCONTRADO )
{
InsertarSimbolo(ttok,tmp_sim.id,VARIABLE);
idSimb++;
}
}
else
{
rt=IDReserv(ttok);

if(rt != TOKEN_NO_ENCONTRADO)
{
tmp_sim.id = rt;
rt = RESERVADA;
}
else
{
tmp_sim.id = ID_SIMBOLOS + idSimb;
rt = CONST_SIMB;
}

if(BuscarSimbolo(ttok)==TOKEN_NO_ENCONTRADO )
{
InsertarSimbolo(ttok,tmp_sim.id,VARIABLE);
idSimb++;
}
}
}

else if( estado==2 || estado==3 || estado==5) rt=CONSTANTE;

else if( estado==4 ) rt=REAL;

strcpy(token,ttok);

break;
}
}

else // caracter raro
{
ttok[ j++ ] = buffer[ i ];
ttok[ j ] = '\0';
estado = 6;
}
}

Bufpos = i-1;

return rt;
}

int BuscarSimbolo(char* token) // regresa el id del simbolo si lo encuentra
{
int i;

for(i=0;i<=simCont;i++)
if( strcmp(tablaSimb[i].token,token)==0) return tablaSimb[i].id;

return TOKEN_NO_ENCONTRADO;
}

int IDReserv(char* token)
{
int i = 0;

for(;i
return TOKEN_NO_ENCONTRADO;
}

int IDOperador( char* token )// regresa el id del operador encaso de encontrarlo
{
int i = 0;

for(;i if(strcmp(Operadores[ i ],token)==0) return i + ID_OPERADORES;

return TOKEN_NO_ENCONTRADO;
}

int InsertarSimbolo(char* token, int id, int tipo)
{
simCont++;

strcpy(tablaSimb[simCont].token,token);
tablaSimb[simCont].id = id;
tablaSimb[simCont].tipo = tipo;

return 0;
}

int ModificaTipo(char* token, int tipo)
{
int i = 0;

for(i=0;i<=simCont;i++)
{
if( strcmp(tablaSimb[i].token,token)==0)
{
tablaSimb[i].tipo = tipo;
return tablaSimb[i].id;
}
}

return TOKEN_NO_ENCONTRADO;
}

int ObtieneTipo(char* token)
{
int i = 0;

for(;i<=simCont;i++)
if( strcmp(tablaSimb[i].token,token)==0) return tablaSimb[i].tipo;

return TOKEN_NO_ENCONTRADO;
}

main.h

#include
#include
using namespace std;

#define RESERVADAS 55
#define OPERADORES 37

#define SIMBOLOS 100
#define SINTAXIS 100
#define BUFFER 512

#ifndef MAX_PATH //si no esta definido max_path
#define MAX_PATH 260
#endif

#define VARIABLE 0
#define CADENA 1
#define CONSTANTE 2
#define REAL 3
#define IDENTIFICADOR 4
#define RESERVADA 6
#define CONST_SIMB 5

#define ID_OPERADORES 60
#define ID_RESERVADAS 7
#define ID_SIMBOLOS 100

#define SUMA ID_OPERADORES
#define RESTA ID_OPERADORES+1
#define MULT ID_OPERADORES+2
#define DIVI ID_OPERADORES+3
#define MODU ID_OPERADORES+4
#define INC ID_OPERADORES+5
#define DEC ID_OPERADORES+6
#define IGUAL ID_OPERADORES+7
#define SUMA_A ID_OPERADORES+8
#define RESTA_A ID_OPERADORES+9
#define MULT_A ID_OPERADORES+10
#define DIVI_A ID_OPERADORES+11
#define MODU_A ID_OPERADORES+12
#define PUNTO_A ID_OPERADORES+13
#define NOT ID_OPERADORES+14
#define AND ID_OPERADORES+15
#define OR ID_OPERADORES+16
#define XOR ID_OPERADORES+17
#define O_AND_AND ID_OPERADORES+18
#define O_OR_OR ID_OPERADORES+19
#define IGUAL_IGUAL ID_OPERADORES+20
#define MAYOR_Q ID_OPERADORES+21
#define MENOR_Q ID_OPERADORES+22
#define DIST ID_OPERADORES+23
#define MENOR_IGUAL ID_OPERADORES+24
#define MAYOR_IGUAL ID_OPERADORES+25
#define O_AND ID_OPERADORES+26
#define O_OR ID_OPERADORES+27
#define LLAVE_A ID_OPERADORES+28
#define LLAVE_C ID_OPERADORES+29
#define PAREN_A ID_OPERADORES+30
#define PAREN_C ID_OPERADORES+31
#define CORCH_A ID_OPERADORES+32
#define CORCH_C ID_OPERADORES+33
#define PUNTO ID_OPERADORES+34
#define COMA ID_OPERADORES+35
#define PUNTO_COMA ID_OPERADORES+36

#define R_AND ID_RESERVADAS
#define R_OR ID_RESERVADAS+1
#define R_XOR ID_RESERVADAS+2

#define TOKEN_NO_ENCONTRADO -2
#define TOKEN_INVALIDO -3

typedef struct _TOKEN {
char token[61];
int id;
int tipo;
}TOKEN;

int OperadorArit(char c);
int OperadorRel(char c);
int OperadorLog(char c);
int OperadorOtro(char c);
int OperadorGrupo(char c);

int abrirArchivo(char* nombre);
int AnaSint();
int AnaSem();
int AnaLex(char* token);
int IDOperador(char* token);
int IDReserv(char* token);
int BuscarSimbolo(char* token);
int ModificaTipo(char* token, int tipo);
int ObtieneTipo(char* token);

Main.c

#include "main.h"
TOKEN tablaSimb[SIMBOLOS];
TOKEN sintBuf[SINTAXIS];
char buffer[BUFFER];
int Bufpos=0, sinCont=-1, Sinpos=-1, buftam, linea=1, idSimb=0, simCont=-1;
int lCon=0;
int main()
{
char archivo[MAX_PATH];
int ret;
cout<<"Nombre de archivo fuente:"<0)cout<<"\nError de sintaxis ["<=ID_SIMBOLOS)
{
cout<<"token: "< case CADENA: cout<<"string"; break;
case CONSTANTE: cout<<"Entero"; break;
case REAL: cout<<"Flotante"; break;
case CONST_SIMB: cout<<"constante"; break;
}
cout< }
}
return 0;
}

continua lexico

["< rt = TOKEN_INVALIDO;
}

else if(estado == 1) // identificador o constante
{
strcpy(tmp_sim.token,ttok);
tmp_sim.tipo = VARIABLE;

if( ttok[0]=='$') // es variable
{
tmp_sim.id = ID_SIMBOLOS + idSimb;
rt = IDENTIFICADOR;

if(BuscarSimbolo(ttok)==TOKEN_NO_ENCONTRADO )
{
InsertarSimbolo(ttok,tmp_sim.id,VARIABLE);
idSimb++;
}
}
else
{
rt=IDReserv(ttok);

if(rt != TOKEN_NO_ENCONTRADO)
{
tmp_sim.id = rt;
rt = RESERVADA;
}
else
{
tmp_sim.id = ID_SIMBOLOS + idSimb;
rt = CONST_SIMB;
}

if(BuscarSimbolo(ttok)==TOKEN_NO_ENCONTRADO )
{
InsertarSimbolo(ttok,tmp_sim.id,VARIABLE);
idSimb++;
}
}
}

else if( estado==2 || estado==3 || estado==5) rt=CONSTANTE;

else if( estado==4 ) rt=REAL;

strcpy(token,ttok);

break;
}
}

else // caracter raro
{
ttok[ j++ ] = buffer[ i ];
ttok[ j ] = '\0';
estado = 6;
}
}

Bufpos = i-1;

return rt;
}

int BuscarSimbolo(char* token) // regresa el id del simbolo si lo encuentra
{
int i;

for(i=0;i<=simCont;i++)
if( strcmp(tablaSimb[i].token,token)==0) return tablaSimb[i].id;

return TOKEN_NO_ENCONTRADO;
}

int IDReserv(char* token)
{
int i = 0;

for(;i
return TOKEN_NO_ENCONTRADO;
}

int IDOperador( char* token )// regresa el id del operador encaso de encontrarlo
{
int i = 0;

for(;i if(strcmp(Operadores[ i ],token)==0) return i + ID_OPERADORES;

return TOKEN_NO_ENCONTRADO;
}

int InsertarSimbolo(char* token, int id, int tipo)
{
simCont++;

strcpy(tablaSimb[simCont].token,token);
tablaSimb[simCont].id = id;
tablaSimb[simCont].tipo = tipo;

return 0;
}

int ModificaTipo(char* token, int tipo)
{
int i = 0;

for(i=0;i<=simCont;i++)
{
if( strcmp(tablaSimb[i].token,token)==0)
{
tablaSimb[i].tipo = tipo;
return tablaSimb[i].id;
}
}

return TOKEN_NO_ENCONTRADO;
}

int ObtieneTipo(char* token)
{
int i = 0;

for(;i<=simCont;i++)
if( strcmp(tablaSimb[i].token,token)==0) return tablaSimb[i].tipo;

return TOKEN_NO_ENCONTRADO;
}
#include "main.h"

extern TOKEN tablaSimb[SIMBOLOS];
extern TOKEN sintBuf[SINTAXIS];
extern char buffer[BUFFER];
extern int Bufpos, sinCont, Sinpos, buftam, linea, idSimb, simCont;

int InsertarSimbolo(char* token, int id, int tipo);

/* php 4 */
char *reservadas[RESERVADAS] = { "and","or","xor","__FILE__","exception","php_user_filter"
"__LINE__","array","as","break","case","cfunction","class",
"const","continue","declare","default","die","do","echo","else",
"elseif","empty","enddeclare","endfor","endforeach","endif",
"endswitch","endwhile","eval","exit","extends","for","foreach",
"function","global","if","include","include_once","isset","list",
"new","old_function","print","require","require_once","return",
"static","switch","unset","use","var","while","__FUNCTION__",
"__CLASS__","__METHOD__" };

char *Operadores[OPERADORES] = { "+","-","*","/","%","++","--","=","+=","-=","*=","/=","%=",".=",
"!","and","or","xor","&&","","==",">","<","!=","<=",">=",
"&","","{","}","(",")","[","]",".",",",";" };

int Tabla[7][7] = { { 1, 2, 3, 1, 1, 6, 6 },
{ 1, 1, 1, 1, 1, 6, 0 },
{ 6, 3, 3, 6, 5, 6, 6 },
{ 6, 3, 3, 6, 6, 6, 4 },
{ 6, 4, 4, 6, 6, 6, 6 },
{ 6, 5, 5, 5, 6, 6, 6 },
{ 6, 6, 6, 6, 6, 6, 6 } };

int AnaLex(char* token)
{
int i = Bufpos, rt=0, estado=0, j=0, res_id;
int flgHex=0, flgID = 0;
char ttok[61], tmpc;
TOKEN tmp_sim;

for( ; i <= buftam; i++ ) { if(isalpha(buffer[i]) buffer[i]=='_' buffer[i]=='$') { tmpc = toupper(buffer[i]); switch(estado) { // para ID case 0: case 1: estado = Tabla[estado][0]; break; case 2: // puede ser numero oct o hex { if(tmpc == 'X') // si es hex estado = Tabla[estado][4]; else estado = Tabla[estado][1]; // error en hex } break; case 5: { if(tmpc >= 'A' && tmpc <= 'F') // es numero hex
estado = Tabla[estado][3];
else
estado = Tabla[estado][1]; // error en hex
} break;

default: estado = Tabla[estado][1]; // error
}

ttok[j++] = buffer[i];
ttok[j] = '\0';
}

else if(isdigit(buffer[i])) // si es digito
{
switch(estado)
{
case 0:
{
if( buffer[Bufpos] == '0' ) // puede ser octal o hexa
estado = Tabla[ estado][1];
else
estado = Tabla[estado][2];
} break;

case 1: estado = Tabla[estado][1]; break;

case 2: case 3: case 4: estado = Tabla[estado][1]; break;

case 5: estado = Tabla[estado][2]; break; // numero hex
}

ttok[j++] = buffer[i];
ttok[j] = '\0';
}
// cualquier otro caracter perteneciente al lenguaje
else if(OperadorArit(buffer[i]) OperadorRel(buffer[i]) OperadorLog(buffer[i])
OperadorOtro(buffer[i]) OperadorGrupo(buffer[i]) buffer[i]=='\0'
buffer[i]==' ')
{
short flg=0;

for(;buffer[i] == ' ';i++) flg=1; // salta espacios

if(flg==1) Bufpos = --i;

if(buffer[i] == '.' && estado == 3)
{
estado = Tabla[ estado ][ 6 ];

ttok[ j++ ] = buffer[ i ];
ttok[ j ] = '\0';
}

else
{
if(estado==6 buffer[i] == '.'(ttok[0]=='$'&&isdigit(ttok[1]))) // si hay error
{
cout<<"\nError! ["<

Compilador...Gabby....Si se pudo

/*Hola Mundo*/
$as = 34,
$v1 = "Hola";
$cad = $as + $v1;
$variable;

if(!$as)
{
}

while($as == $v1)¨
{
$as++;
}

for($as ==0; $as<100; $as++)
{

}
}

sábado, 10 de octubre de 2009

Pseudocodigo

1. Inicio
2. Declara Matriz.
int matriz [7][5]={
{0,1,2,3,4,},
{1,2,2,6,6,},
{2,3,3,6,6,},
{3,4,4,6,6,},
{4,5,6,6,6,},
{5,5,5,6,5,},
{6,6,6,6,6,}};
3. Declara Cadena
char cadena [50];
4. Declara C para saber el estado int c=0;
5. Declara Estado
int estado=1
6.Muestra mensaje cout <<"Introduce Cadena";
7. Introduce Cadena
cin >> cadena;
8. Analizar Cadena
for (int n= strlen (cadena)-1;n>=0; n--)
{ for(int n=0 ;n<=0 ;n++)
9. Verifica que carácter que cae a la matriz [7] [5]
switch (cadena [n] )
{ case 'a' ; c=1 ; break;
case 'b' : c=2 ; break;
defaul: c=3; break; }
10. Asignar la posicion en la matriz a estado
estado=matriz [estado][c] ; }
11. Verifica Estado
if (estado ==5 )
12. Muestra el siguiente
mesaje cout <<"Cadena Aceptado"
13. Si no
14. Muestra el siguiente mensaje
cout<<"Cadena Rechazada";
15. Fin del programa.

Compiladores

INTRODUCCIÓN

En 1946 se desarrolló el primer ordenador digital. En un principio, estas máquinas ejecutaban instrucciones consistentes en códigos numéricos que señalan a los circuitos de la máquina los estados correspondientes a cada operación. Esta expresión mediante códigos numéricos se llamó Lenguaje Máquina, interpretado por un secuenciador cableado o por un microprograma. Pero los códigos numéricos de las máquinas son engorrosos. Pronto los primeros usuarios de estos ordenadores descubrieron la ventaja de escribir sus programas mediante claves más fáciles de recordar que esos códigos numéricos; al final, todas esas claves juntas se traducían manualmente a Lenguaje Máquina. Estas claves constituyen los llamados lenguajes ensambladores, que se generalizaron en cuanto se dio el paso decisivo de hacer que las propias máquinas realizaran el proceso mecánico de la traducción. A este trabajo se le llama ensamblar el programa.

Clasificación

Los compiladores son programas de traducción insertados en la memoria por el sistema operativo para convertir programas de cómputo en pulsaciones electrónicas ejecutables (lenguaje de máquina). Los compiladores pueden ser de:

Øuna sola pasada: examina el código fuente una vez, generando el código o programa objeto.
Øpasadas múltiples: requieren pasos intermedios para producir un código en otro lenguaje, y una pasada final para producir y optimizar el código producido durante los pasos anteriores.
ØOptimación: lee un código fuente, lo analiza y descubre errores potenciales sin ejecutar el programa.

Compiladores incrementales: generan un código objeto instrucción por instrucción (en vez de hacerlo para todo el programa) cuando el usuario teclea cada orden individual.

El otro tipo de compiladores requiere que todos los enunciados o instrucciones se compilen conjuntamente.

Ensamblador: el lenguaje fuente es lenguaje ensamblador y posee una estructura sencilla.

Compilador cruzado: se genera código en lenguaje objeto para una máquina diferente de la que se está utilizando para compilar. Es perfectamente normal construir un compilador de Pascal que genere código para MS-DOS y que el compilador funcione en Linux y se haya escrito en C++.

Compilador con montador: compilador que compila distintos módulos de forma independiente y después es capaz de enlazarlos.

Autocompilador: compilador que está escrito en el mismo lenguaje que va a compilar. Evidentemente, no se puede ejecutar la primera vez. Sirve para hacer ampliaciones al lenguaje, mejorar el código generado, etc.

Metacompilador: es sinónimo de compilador de compiladores y se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida el compilador para ese lenguaje.

El desarrollo de los metacompiladores se encuentra con la dificultad de unir la generación de código con la parte de análisis. Lo que sí se han desarrollado son generadores de analizadores léxicos y sintácticos. Por ejemplo, los conocidos:


LEX: generador de analizadores léxicos.


YACC: generador de analizadores sintácticos desarrollados para UNIX. Los inconvenientes que tienen son que los analizadores que generan no son muy eficientes.

Descompilador: es un programa que acepta como entrada código máquina y lo traduce a un lenguaje de alto nivel, realizando el proceso inverso a la compilación.


Conceptualmente un compilador opera en fases. Cada una de las cuales transforma el programa fuente de una representación en otra.

Diagrama Earley

Es un algoritmo no determinístico de análisis sintáctico para las gramáticas libres de contexto descrito originalmente por Jay Earley. Se ordena, a los lados de los algoritmos CYK y GLR, entre los algoritmos que usan la noción de reparto (de cálculos y de estructuras) y que construyen todos los análisis posibles de una frase (y no sólo uno de estos análisis). Es uno de los algoritmos no determinísticos que usan ideas de la programación dinámica.

En caso de que la gramática fuese ambigüa (algo habitual en gramáticas del lenguaje natural), el tiempo de reconocimiento será proporcional al cubo de la longitud de la cadena de entrada, aunque para ciertas gramáticas el tiempo medio se puede reducir a cuadrático e incluso lineal.

El algoritmo de Earley se basa en tres operaciones o acciones que se realizan iterativamente a lo largo del análisis de la cadena de entrada:

ØPredecir. Si tenemos un estado {A --> ... ·B ..., i} es que necesitamos desarrollar B, y por tanto, debemos recorrer las reglas del tipo B --> ... para predecir lo que buscamos.
ØCompletar. Si hemos llegado a un estado completo {A --> ...·, i}, algún estado previo debe haber predicho A y necesitará que le avancemos el puntero · quedando {B --> ...A·..., i}.

ØAvanzar. Una vez realizadas todas las posibles predicciones de símbolos terminales, debemos comprobar que la cadena de entrada posee alguno de ellos y avanzar el puntero correspondiente del elemento {A --> ...a·..., i).

Earley en su forma básica

[Inicialización]
Para cada regla
S --> ...
Nuevos =
Añadir Elemento({S --> ·...,0}, Agenda[0])

Realizar
Nuevos = 0
Para cada elemento {
A --> ...·B...,0} de Agenda[0]
Para cada regla
B --> ...
Nuevos =
Añadir Elemento({B --> ·...,0}, Agenda[0])
Para cada elemento {
A --> ...·,0} de Agenda[0]
Para cada elemento {
B --> ...·A...,0} de Agenda[0]
Nuevos =
Añadir Elemento({B --> ...A·...,0}, Agenda[0])

mientras Nuevos = 1

[Iteración]
Para
Nuevos = 0
Para cada elemento {
A --> ...·a...,i} de Agenda[j-1]
Si
a pertenece a Entrada[j]
Nuevos =
Añadir Elemento({A --> ...a·...,i}, Agenda[j])

Si Nuevos = 0
Devolver ERROR

Realizar
Nuevos = 0
Para cada elemento {
A --> ...·B...,i} de Agenda[j]
Para cada regla
B --> ...
Nuevos =
Añadir Elemento({B --> ·...,j}, Agenda[j])
Para cada elemento {
A --> ...·,i} de Agenda[j]
Para cada elemento {
B --> ...·A...,k} de Agenda[i]
Nuevos =
Añadir Elemento({B --> ...A·...,k}, Agenda[j])

mientras Nuevos = 1

Si existe algún elemento {S --> ...·,0} en Agenda[N]
Devolver BIEN
si no existe Ç

Devolver ERROR

Ejemplo


P → S # La regla de principio

S → S + M

| M

M → M * T

| T

T → número


La cadena vacía requiere un tratamiento especial, será un símbolo no terminal que no necesita de la operación completar para el avance de su puntero. Cada vez que añadamos un elemento a Agenda[i] del tipo {A --> ...· ..., j} donde el puntero · queda a la izquierda de una cadena vacía, añadiremos también el elemento {A --> ... · ..., j}. Al reconstruir la estructura de la cadena de entrada, en el bucle que recorre los símbolos de la parte derecha de una regla B --> B1 ... Bm debemos distinguir no sólo los terminales y no terminales sino también la cadena vacía, y al llegar al símbolo nulo del elemento {A --> ... ..., j} reduciremos sólo k y proseguiremos.

Algoritmo de reconstrucción del árbol sintáctico del algoritmo de Earley en ausencia de ambigüedades


Reconstruye({A --> B1 B2 ... Bm ·,i}, j)
Añade a Lista De
Reglas el elemento (A --> B1 B2 B3 ... Bm)

k = m
l = j

Realizar
Si B
k es terminal
k = k-1
l = l-1
si no
Si existe en Agenda[l] un {B
k --> ·, r} tal que en
Agenda[r] esté {A --> B
1 B2 ...·Bk, i}
Reconstruye({B --> ·, r}, l)
k = k-1
l = r

mientras k>0