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
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.