Question

I'm using Flex and Bison with my grammar for a very simple programming language. But I'm a beginner, so I'm not exactly sure about how to work with them.

Besides some basic operations (like arithmetic and logical operations, assignments, etc.) I also have a function that needs to be recognized by this language: this function is called "ftoc" and it takes one numeric argument.

In my flex .l file I have (among others) these definitions:

DIGITO [0-9]
PUNTO ["."]
CONST_REAL {DIGITO}+{PUNTO}{DIGITO}+
CONST_ENTERA {DIGITO}+
P_A ["("]
P_C [")"]

I also have this rule for the "ftoc" function:

"FtoC" { printf("%s\n", yytext);return FTOC;}

My bison .y file has this union to accept three data types:

%union {
    char *text;
    int integer;
    double real;
}

It also has these token definitions:

%token <integer> CONST_ENTERA
%token <real> CONST_REAL
%token <text> INTEGER
%token <text> REAL
%token <text> STRING
%token P_A P_C
%token FTOC

And the rules involving the "ftoc" function are these:

conversion:
    FTOC P_A constante P_C
;
constante:
    CONST_ENTERA
    | CONST_REAL
;

Now, I need to write a function that prints "ftoc" plus its argument every time the function is found. E.g., if the parser finds the function used as: FtoC(57.6) I need it to print "ftoc57.6".

My function to print this would look somewhat like this:

printFtoc(char* function, double argument){
    snprintf("%s, %f", function, argument);
}

My problem here is how exactly I should pass the parameters to this function. I tried with $n in the "conversion" rule, like this:

FTOC P_A constante P_C {printFtoC($1, $3)}

But then I get 2 errors in Bison (one for each $n), saying that "conversion" has no declared type.

I've been trying to read from Bison documentation but I don't really get what exactly I should be doing. From other questions and forums I get I might need to do something with %type or with %token, but I really don't know.

I just need to get the function name and the argument whenever they're found, but no clue on how to achieve that, since $n didn't work.

Was it helpful?

Solution

The error tells you exactly what is wrong -- you have a $3 use in a rule that corresponds to a constante, but you haven't declared a type for constante. You probably need a declaration something like:

%type<real> constante

to tell bison that a constante is in the real field of the union. You also have a problem with $1 in that action, because FTOC has no type. You could fix that by either giving FTOC a type and modifying the lex rule to yylval appropriately, or by getting rid of the $1 and using a string literal like "ftoc" instead

Any given non-terminal can only have a single type, so you'll need to add actions to your constante rules. With the above %type declaration, you would have:

constante: CONST_ENTERA  { $$ = $1; /* implicit int->double conversion */ }
         | CONST_REAL    { $$ = $1; /* simple assignment of a double */ }
;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top