I am unfamiliar with Yacc and trying to get an example I found here to work. When I try to compile with yacc -d calc.yacc
, I get the following errors.
calc.yacc:42.17-18: $1 of `stat' has no declared type
calc.yacc:96.22-23: $1 of `expr' has no declared type
calc.yacc:105.17-18: $1 of `number' has no declared type
calc.yacc:106.20-21: $1 of `number' has no declared type
calc.yacc:110.29-30: $2 of `number' has no declared type
I tried googling and from what I can tell, the solution has to do with %type, but I'm not sure what to add.
The code is below:
%{
#include <stdio.h>
int regs[26];
int base;
%}
%start list
%union { int a; }
%type <a> expr number
%token DIGIT LETTER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
%% /* beginning of rules section */
list: /*empty */
|
list stat '\n'
|
list error '\n'
{
yyerrok;
}
;
stat: expr
{
printf("%d\n",$1);
}
|
LETTER '=' expr
{
regs[$1] = $3;
}
;
expr: '(' expr ')'
{
$$ = $2;
}
|
expr '*' expr
{
$$ = $1 * $3;
}
|
expr '/' expr
{
$$ = $1 / $3;
}
|
expr '%' expr
{
$$ = $1 % $3;
}
|
expr '+' expr
{
$$ = $1 + $3;
}
|
expr '-' expr
{
$$ = $1 - $3;
}
|
expr '&' expr
{
$$ = $1 & $3;
}
|
expr '|' expr
{
$$ = $1 | $3;
}
|
'-' expr %prec UMINUS
{
$$ = -$2;
}
|
LETTER
{
$$ = regs[$1];
}
|
number
;
number: DIGIT
{
$$ = $1;
base = ($1==0) ? 8 : 10;
} |
number DIGIT
{
$$ = base * $1 + $2;
}
;
%%
main()
{
return(yyparse());
}
yyerror(s)
char *s;
{
fprintf(stderr, "%s\n",s);
}
yywrap()
{
return(1);
}
%union
and%type
directives. The default type for the stack isint
, and without a%union
yacc assumes all tokens and nonterminals have the same type (YYSTYPE
if I recall correctly, defaultint
anyway). Use%union
and%type
to set different types for different tokens/nonterminals. – Sharice