Documente Academic
Documente Profesional
Documente Cultură
COMPILADORES
Descripcin
Bison
COCO/R
C/C++
Flex
Lex
SDGLL1
exe
TS 2006
C/C++
TS
TS-OO
C++
exe
VASt
C++
YACC
VASt
Flex y Bison
Flex es un una herramienta que permite generar analizadores lxicos. A partir de un conjunto
de expresiones regulares, Flex busca concordancias en un fichero de entrada y ejecuta acciones
asociadas a estas expresiones. Es compatible casi al 100% con Lex, una herramienta clsica de
Unix para la generacin de analizadores lxicos, pero es un desarrollo diferente realizado por
GNU bajo licencia GPL.
GNU bison es un programa generador de analizadores sintcticos de propsito general
perteneciente al proyecto GNU disponible para prcticamente todos los sistemas operativos, se
usa normalmente acompaado de flex aunque los analizadores lxicos se pueden tambin
obtener de otras formas.
En la ventana de variables de entorno, ubicarse en la seccin Variables del sistema luego haz
clic en PATH y luego en el botn Modificar (si no est hacer clic en Nueva y agregar PATH)
/*****************
Definiciones
Se colocan las cabeceras, variables y expresiones regulares
********************
%{
#include <stdio.h>
#include <stdlib.h>
#include "sintactico.tab.h"
int linea=0;
%}
/*
Creamos todas las expresiones regulares
Creamos la definicin llamada DIGITO, podemos acceder esta definicin
usando {DIGITO}*/
DIGITO [0-9]
NUMERO {DIGITO}+("."{DIGITO}+)?
%%
/***************
Reglas
*****************/
/* Creamos las reglas que reconocern las cadenas que acepte
Nuestro scanner y retornaremos el token a bison con la
funcion return. */
{NUMERO} {yylval.real=atof(yytext); return(NUMERO);}
"="
{return(IGUAL);}
"+"
{return(MAS);}
"-"
{return(MENOS);}
";"
{return(PTOCOMA);}
"*"
{return(POR);}
"/"
{return(DIV);}
"("
{return(PAA);}
")"
{return(PAC);}
"\n"
{linea++;}
[\t\r\f] {}
""
{}
%%
/*
Cdigo de Usuario
Aqu podemos realizar otras funciones, como por ejemplo ingresar
smbolos a nuestra tabal de smbolos o cualquier otra accione
del usuario.
Todo lo que el usuario coloque en esta seccin se copiara al
archvi lex.yy.c tal y como esta.
*/
Guardamos el archivo como lexico.l. Luego creamos un nuevo archivo y colocamos el
siguiente cdigo.
%{
/********************
Declaraciones en C
**********************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
extern int yylex(void);
extern char *yytext;
extern int linea;
extern FILE *yyin;
void yyerror(char *s);
%}
/************************
Declaraciones de Bison
*************************/
/* Especifica la coleccion completa de tipos de datos para poder usar
Exp_l Calc
|Calc
;
Calc
NUMERO {$$=$1;}
|Exp MAS Exp {$$=$1+$3;}
|Exp MENOS Exp {$$=$1-$3;}
|Exp POR Exp {$$=$1*$3;}
|Exp DIV Exp {$$=$1/$3;}
|PAA Exp PAC {$$=$2;}
;
%%
/********************
Codigo C Adicional
**********************/
void yyerror(char *s)
{
printf("Error sintactico %s",s);
}
int main(int argc,char **argv)
{
if (argc>1)
yyin=fopen(argv[1],"rt");
else
yyin=stdin;
yyparse();
return 0;
}
Segundo ejemplo
Fichero lxico_solo.l
%{
/* Ejemplo para una pequea calculadora que permite
trabajar con numeros enteros y reales con las operaciones
bsicas de suma, resta, producto, division y trigonometricas como el seno y el coseno */
#include <stdio.h>
#include <stdlib.h>
int nlines=0;
%}
DIGITO [0-9]
ID [a-zA-Z][a-zA-Z0-9_]*
%%
{DIGITO}+ {printf("Encontrado TKN_NUM_ENTERO: %d",atoi(yytext));}
{DIGITO}+"."{DIGITO}+ {printf("Encontrado TKN_NUM_REAL: %f",atof(yytext));}
"=" {printf("Encontrado TKN_ASIGN: %s",yytext);}
";" {printf("Encontrado TKN_PTOCOMA: %s",yytext);}
"*" {printf("Encontrado TKN_MULT: %s",yytext);}
"/" {printf("Encontrado TKN_DIV: %s",yytext);}
"+" {printf("Encontrado TKN_MAS: %s",yytext);}
"-" {printf("Encontrado TKN_MENOS: %s",yytext);}
DIGITO [0-9]
ID [a-zA-Z][a-zA-Z0-9_]*
%%
{DIGITO}+("."{DIGITO}+)? {//printf("Encontrado TKN_NUM: %f\n",atof(yytext));
yylval.real=atof(yytext);
return(TKN_NUM);}
"=" {//printf("Encontrado TKN_ASIGN: %s\n",yytext);
return(TKN_ASIGN);}
";" {//printf("Encontrado TKN_PTOCOMA: %s\n",yytext);
return(TKN_PTOCOMA);}
"*" {//printf("Encontrado TKN_MULT: %s\n",yytext);
return(TKN_MULT);}
"/" {//printf("Encontrado TKN_DIV: %s\n",yytext);
return(TKN_DIV);}
"+" {//printf("Encontrado TKN_MAS: %s\n",yytext);
return(TKN_MAS);}
"-" {//printf("Encontrado TKN_MENOS: %s\n",yytext);
return(TKN_MENOS);}
"(" {//printf("Encontrado TKN_PAA: %s\n",yytext);
return(TKN_PAA);}
")" {//printf("Encontrado TKN_PAC: %s\n",yytext);
return(TKN_PAC);}
"cos" {//printf("Encontrado TKN_COS: %s\n",yytext);
return(TKN_COS);}
"sen" {//printf("Encontrado TKN_SEN: %s\n",yytext);
return(TKN_SEN);}
{ID} {//printf("Encontrado TKN_ID: %s\n",yytext);
return(TKN_ID);}
"\n" {nlines++;}
.
%%
/********
Para el lexico solo
void main(int argc,char **argv)
{
if (argc>1)
yyin=fopen(argv[1],"rt");
else
yyin=stdin;
yylex();
printf("\nNumero lineas analizadas: %d\n", nlines);
}
*******/
/* para compilar
flex lexico.l
cc lex.yy.c -o milex -lfl -lm
*/
Fichero sintactico.y (Bison)
%{
/* Ejemplo para una pequea calculadora que permite trabajar
con numeros enteros y reales con las operaciones bsicas de
suma, resta, producto, division y trigonometricas como el seno y el coseno */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
extern int yylex(void);
extern char *yytext;
extern int nlines;
extern FILE *yyin;
void yyerror(char *s);
%}
%union
{
float real;
}
%start Calculadora
%token <real> TKN_NUM
%token TKN_ASIGN
%token TKN_PTOCOMA
%token TKN_MULT
%token TKN_DIV
%token TKN_MAS
%token TKN_MENOS
%token TKN_PAA
%token TKN_PAC
%token TKN_COS
%token TKN_SEN
%token <real> TKN_ID
%type Calculadora
%type <real> Expresion
%left TKN_MAS TKN_MENOS
%left TKN_MULT TKN_DIV
%%
Calculadora : TKN_ID { printf("El valor de %s es: ", yytext);}
TKN_ASIGN Expresion TKN_PTOCOMA { printf("%5.2f\n", $4); } ;
Expresion : TKN_NUM {$$=$1;}|
Expresion TKN_MAS Expresion {$$=$1+$3;}|
Expresion TKN_MENOS Expresion {$$=$1-$3;}|
Expresion TKN_MULT Expresion {$$=$1*$3;}|
Expresion TKN_DIV Expresion {$$=$1/$3;} |