ccompiler-errorsbisonflex-lexerc-minus-minus

Bulding a syntax tree with bison ($ ref issue)


I'm into a project where I need to build a whole compiler for C- language. I was looking for materials on this topic but I don't found anything.

I have this code's piece of a grammar rule about function declaration:

fun_declaracao:
    tipo_especificador ID APR { 
        // Start of semantic action after parsing the return type (tipo_especificador), 
        // the function name (ID), and the opening parenthesis (APR).

        // Initialize function type as "erro" to detect issues later.
        char* tipo_fun = "erro";

        // Set the current function and scope to the function name.
        // These are likely used elsewhere to keep track of context during parsing.
        funcao_at = $2;
        escopo_at = $2;

        // Check if this function name is already declared in the global scope.
        if (busca(T, tm_tab, $2, "global") != -1) {
            // If found, report a semantic error: function already declared.
            erro_semantico("Funcao ja declarada", $2, yylineno);
        } else {
            // If not found, insert this new function into the symbol table.
            // Parameters: symbol table T, temporary table tm_tab,
            // function name $2, symbol kind "func", return type $1, line number, scope "global".
            add(&T, &tm_tab, $2, "func", $1, yylineno, "global");

            // Mark the identifier as valid for future reference.
            tipo_fun = "id"; 
        }
    } params FPR composto_declaracao {
        // This is the second semantic action, after the full function header and body have been parsed:
        // - params: the parameter list
        // - FPR: closing parenthesis
        // - composto_declaracao: the function body block

        // Build a syntax tree node representing the whole function declaration.
        // It includes 4 children: return type, function name, parameters, and body.
        $$ = novo("fun_declaracao", NULL, 4, 
                  novo($1, $1, 0),     // Return type node
                  novo($2, tipo_fun, 0), // Function name node with type info
                  $4,                 // Parameters node
                  $6);                // Function body node

        // After building the function, reset context to global (we're outside the function now).
        escopo_at = "global";
        funcao_at = NULL;
    }
;

So when I run it, I got this error:

bison -d parser.y
parser.y:124.86-87: $4 of `fun_declaracao' has no declared type
parser.y:124.90-91: $6 of `fun_declaracao' has no declared type
makefile:13: recipe for target 'parser.tab.c' failed
make: *** [parser.tab.c] Error 1

I think is a dumb issue and probaly I just didn't understand the bison syntax.

This is my %type declaration:

%union {
    char *string;
    NO *no;
    char *tipo; 
}

%token <string> ID
%token <string> NUM 

%token  INT VOID WHILE RETURN PEV VIR ERRO

%type <tipo> tipo_especificador

%type <no> expressao var simples_expressao soma_expressao termo fator 
%type <no> programa declaracao_lista declaracao var_declaracao fun_declaracao 
%type <no> params param_lista param composto_declaracao 
%type <no> local_declaracoes statement_lista statement expressao_declaracao selecao_declaracao iteracao_declaracao 
%type <no> retorno_declaracao args arg_lista relacional

Solution

  • Per the Bison manual:

    The midrule action itself counts as one of the components of the rule. This makes a difference when there is another action later in the same rule (and usually there is another at the end): you have to count the actions along with the symbols when working out which number n to use in $n.

    As a result, in the end-of-rule action presented, $4 refers to the mid-rule action, and $6 refers to FPR. These are off by one from the components I think you intend to reference.