Q:

Calculator with flex and bison

I'm doing a simple calculator with flex and bison and when I compile it says me "$1 of ... has no declared type"
I have to print the type of the expression and it's result.
the type of a expression can be a float an integer or a string.
this is my bison code:
%{    
    #include <stdio.h>    
    #include <stdlib.h>    
    #include <math.h>    
    #include <symtab.h>    
    extern int yylex(void);    
    extern char *yytext;    
    extern int nlines;    
    extern FILE *yyin;    
    void yyerror(char *s);    
%}    

%union {    
    char *str;    
}    
%union{    
    struct{    
        char *lexema;    
        int lenght;    
        int line;    
    }ident;    
}    
%union{    
    struct{    
        int integer;    
        float real;    
        char *string;    
        int type;    
        }num    
}    
%token <num> IDENT    
%token <num> LIT_INT    
%token <num> LIT_FLOAT    
%token <num> CADENA    
%token PARENTESIS1    
%token PARENTESIS2    
%token OP_SUM    
%token OP_REST    
%token OP_MULT    
%token OP_DIV    
%token OP_MOD    
%token OP_POW    
%token ASSIGN    

%type <num> expr    
%type <num> term    
%type <num> factor    
%type <num> primary    
%type <num> linea    

%%    
linea   :   IDENT ASSIGN expr '\n'  {sym_enter($1,$3);}    
        |   OP_SUM expr '\n'    {if($1.type==0) {    
                            printf("El valor es %d. \n", $1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", $1.real);    
                        }}    
        |   OP_REST expr '\n'   {if($1.type==0) {    
                            printf("El valor es %d. \n", -$1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", -$1.real);    
                        }}    
        |   expr '\n'   {if($1.type==0) {    
                            printf("El valor es %d. \n", $1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", $1.real);    
                        }}    
        ;    
expr    :   expr OP_SUM term    {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1+$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1+$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1+$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1+$3;    
                                    }}    
        |   expr OP_REST term   {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1-$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1-$3;    
                                    } else if($1.type==0 $$ $3.type==1 {   
                                        $$.type=1;    
                                        $$.real=$1-$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1-$3;    
                                    }}    
        |   OP_SUM term         {$$=$2;}    
        |   OP_REST term        {$$=-$2;}    
        |   term                {$$=$1;}    
        ;    
term    :   term OP_MULT factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1*$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1*$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1*$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1*$3;    
                                    }}    
        |   term OP_DIV factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1/$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1/$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1/$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;   
                                        $$.real=$1/$3;    
                                    }}    
        |   term OP_MOD factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1%$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1%$3;    
                                    }}    
        |   factor              {$$=$1;}    
        ;    
factor  :   primary             {$$=$1;}    
        |   primary OP_POW factor   {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=Math.pow($1,$3);    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=Math.pow($1,$3)    
                                    }}    
        ;    
primary :   PARENTESIS1 expr PARENTESIS2    {$$=$2;}    
        |   PARENTESIS1 OP_REST expr PARENTESIS2    {$$=-$3;}    
        |   PARENTESIS1 OP_SUM expr PARENTESIS2 {$$=$3;}    
        |   LIT_INT {$$=inicializarEntero($1);}    
        |   LIT_FLOAT   {$$=inicializarReal($1);}    
        |   CADENA  {$$=$1;}    
        |   IDENT   {sym_lookup($1,$$);}    
        ;    

%%    

num* inicializarReal(float real) {    
    num *n;    
    n=(num *)malloc(sizeof(int)+sizeof(float));    
    *n.real=real;    
    *n.type=1;    
    return n;    
}    
num* inicializarEntero(int entero) {    
    num *n;    
    n=(num *)malloc(2*sizeof(int));    
    *n.integer=entero;    
    *n.type=0;    
    return n;    
}    

void yyerror(char *s)    
{    
    printf("Error %s",s);    
}    
int main(int argc,char **argv)    
{
    if (argc>1)    
        yyin=fopen(argv[1],"rt");    
    else    
        yyin=stdin;    
    yyparse();    
    printf("FIN del Analisis. Entrada CORRECTA\n");    
    printf("Numero lineas analizadas: %d\n", nlines);    
    return 0;    
}

A:

It is always helpful when seeking the explanation for an error message to quote the complete error message, and indicate which line it applies to.
So here is just one of the lines which will trigger an error similar to the one in the question. Undoubtedly there are more.
OP_SUM expr '\n'    {if($1.type==0) ...

Here, $1 refers to the semantic value of the first symbol (OP SUM); $2 would refer to the second symbol (expr). OP_SUM has no declared type, which is unsurprising, since it does not represent a symbol with a value.
Obviously, the intention was to use the semantic value of expr, which would be $2

