1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Uso de cadenas con bison y flex

Discussion in 'Programming/Internet' started by Luis, Oct 8, 2018.

  1. Luis

    Luis Guest

    Tengo un problema al momento de recuperar cadenas que he guardado usando flex en bison, soy nuevo con estas herramientas y sólo estoy haciendo pruebas para crear un lenguaje, pero según entiendo cuando utilizas el operador $n te da el valor del elemnto n de la regla(ya sea que es un token o falte calcularse), pero cuando utilizo este operador con un token el cual debería ser muy básico me da toda la cadena que ingresé. Mi lenguaje hace que al inicio se tenga que poner la palabra "init" y al final la palabra "end" por motivos de pruebas hice que cuando flex detectara init y end guardara en el token las palabras init y end. Pero cuando en la regla que tiene el uso de init le pido que imprima el valor del token init me devuelve toda la cadena ingresada y yo sólo quiero el valor del token.

    Aquí está mi código de flex

    %option noyywrap

    %{

    #include <stdio.h>
    #define YY_DECL int yylex()
    #include "prueba.tab.h"

    %}

    DIGIT[0-9]
    LETRA[a-zA-Z]
    ALFANUM[a-zA-Z0-9]
    ASIGNACION[=]
    IGUALDAD{ASIGNACION}{ASIGNACION}
    TAB[ \t]
    COMILLAS["]
    ID{LETRA}+{ALFANUM}*
    CADENA{COMILLAS}{ID}{COMILLAS}

    %%
    {TAB} ;
    "init" {printf("INIT es %s \n",yytext);yylval.idval = yytext;return INIT;}
    "end" {printf("END es %s \n",yytext);yylval.idval = yytext;return END;}
    "if" {printf("%s \n",yytext); yylval.idval = yytext;return T_IF;}
    "else" {printf("%s \n",yytext); yylval.idval = yytext;return T_ELSE;}
    "print" {printf("%s \n",yytext); yylval.idval = yytext; return T_PRINT;}
    "define" {printf("%s \n",yytext); yylval.idval = yytext;return T_DEFINE;}
    "false" {printf("BOOL %s \n",yytext); yylval.idval = yytext;return T_BOOL;}
    "true" {printf("BOOL %s \n",yytext); yylval.idval = yytext;return T_BOOL;}
    "exit" {return T_QUIT;}
    "quit" {return T_QUIT;}
    {IGUALDAD} {printf("%s \n",yytext); yylval.idval = yytext;return T_IG;}
    {ASIGNACION} {printf("ASIG es %s \n",yytext); yylval.idval = yytext; return T_AS;}
    {DIGIT}+\.{DIGIT}+ {printf("FLOAT es %s \n",yytext); yylval.idval = yytext; return T_FLOAT;}
    {DIGIT}+ {printf("INT es %s \n",yytext); yylval.idval = yytext; return T_INT;}
    \n {return T_NEWLINE;}
    ";" {printf("PYC es %s \n",yytext); yylval.idval = yytext; return T_PYC;}
    "+" {yylval.idval = yytext; return T_PLUS;}
    "-" {yylval.idval = yytext; return T_MINUS;}
    "*" {yylval.idval = yytext; return T_MULTIPLY;}
    "/" {yylval.idval = yytext; return T_DIVIDE;}
    "(" {printf("%s \n",yytext); yylval.idval = yytext; return T_LEFT;}
    ")" {printf("%s \n",yytext); yylval.idval = yytext; return T_RIGHT;}
    {ID} {printf("ID es %s \n",yytext); yylval.idval = yytext; return T_ID;}
    {CADENA} {printf("CADENA es %s \n",yytext); yylval.idval = yytext; return T_CADENA;}
    %%


    Y mi código de bison

    %{

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    extern int yylex();
    extern int yyparse();
    extern FILE* yyin;

    void yyerror(const char* s);
    %}

    %union {
    char *idval;
    }

    %token<idval> T_ID
    %token<idval> T_INT
    %token<idval> T_FLOAT
    %token<idval> T_CADENA
    %token<idval> T_PLUS
    %token<idval> T_MINUS
    %token<idval> T_MULTIPLY
    %token<idval> T_DIVIDE
    %token<idval> T_RIGHT
    %token<idval> T_LEFT
    %token<idval> T_IF
    %token<idval> T_ELSE
    %token<idval> T_BOOL
    %token<idval> T_PRINT
    %token<idval> T_DEFINE
    %token<idval> T_IG
    %token<idval> T_AS
    %token<idval> T_PYC
    %token<idval> INIT
    %token<idval> END
    %token T_NEWLINE T_QUIT
    %left T_PLUS T_MINUS
    %left T_MULTIPLY T_DIVIDE


    %type<idval> expr
    %type<idval> asi
    %type<idval> valor
    %type<idval> expri
    %type<idval> ti
    %type<idval> f
    %type<idval> t
    %type<idval> p
    %type<idval> ifelse
    %type<idval> cond
    %type<idval> print
    %type<idval> def_met
    %type<idval> param
    %type<idval> llam_met




    %start s

    %%

    s: calculation
    ;

    calculation: inicio T_NEWLINE
    | T_QUIT T_NEWLINE { printf("bye!\n"); exit(0); }
    ;

    inicio: INIT p END {printf("$1 %s \n",$1);}
    ;

    p: {$$="";}
    | asi
    | ifelse
    | print
    | def_met
    | llam_met
    ;

    pi: asi
    | ifelse
    | print
    | llam_met
    ;

    llam_met: T_ID T_LEFT param T_RIGHT T_PYC p
    ;

    def_met: T_DEFINE T_ID T_LEFT param T_RIGHT T_LEFT pi T_RIGHT p
    ;

    param: T_ID
    | T_ID param
    ;

    print: T_PRINT T_INT T_PYC p
    | T_PRINT T_CADENA T_PYC p
    | T_PRINT T_ID T_PYC p
    ;

    ifelse: T_LEFT T_IF cond pi T_ELSE pi T_RIGHT p
    ;


    cond: T_ID T_IG T_ID
    | T_BOOL T_IG T_BOOL
    | T_BOOL T_IG T_ID
    | T_ID T_IG T_BOOL
    | T_BOOL
    ;

    asi: T_ID T_AS valor T_PYC p
    ;

    valor: T_CADENA
    | expr
    | T_BOOL
    ;

    expr: t expri
    ;

    expri: {$$ = "";}
    | T_PLUS t expri
    | T_MINUS t expri
    ;

    t: f ti
    ;

    ti: {$$ = "";}
    | T_MULTIPLY f ti
    | T_DIVIDE f ti
    ;

    f: T_LEFT expr T_RIGHT
    | T_INT /*{printf("INT, %s\n", $1);}{$$ = strcat("INT, ",$1);}*/
    ;
    %%

    int main() {
    yyin = stdin;

    do {
    yyparse();
    } while(!feof(yyin));

    return 0;
    }

    void yyerror(const char* s) {
    fprintf(stderr, "Parse error: %s\n", s);
    exit(1);
    }


    La ejecución más básica que me muestra el error [​IMG]

    Login To add answer/comment
     

Share This Page