Hi I’m getting $$ has no return type when I run the following Bison:
%{
#include <stdio.h>
#include <string.h>
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
%}
%start query
%token AND OR GREATER LESS COLON TO
%union
{
int number;
char *string;
}
%token <number> VALUE
%token <string> WORD
%%
query: /* empty */
| query expression { }
;
expression:
term
|expression AND term {$$=$1}
|expression OR term {}
;
term:
WORD { printf("Term:%s\t",$1);}
| VALUE
;
Following is my flex:
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
%}
%%
":" return COLON;
"and"|"&"|"&&" return AND;
"or"|"|"|"||" return OR;
".." return TO;
">" return GREATER;
"<" return LESS;
\n /* ignore end of line */;
\t /* ignore end of line */;
%%
What does this error mean? How can I fix this?
Its because you’re missing the declaration
%type <...> expressionin the first part of your grammar, where...is some type declared in your%unionstatement. Without this, you can’t access$$in anyexpressionaction. Also, if you set$$in ANY action for a non-terminal, you need to set it in all actions for that non-terminal.In general, you need to decide for all non-terminals whether they produce a value that can be used in rules that use that non-terminal or not. If they do produce such a value, they need a
%typedeclaration and every action needs to set$$to something. If they do not, then no action can use$1(or whatever) to access the non-existent value.You need the same for all terminals, except for terminals, you use
%tokeninstead of%type, and you need to setyylvalin your lexer, as that’s the equivalent of$$.In your particular example, you’ve dealt with the terminals but ignored the non-terminals. Depending on exactly what you’re trying to do, you probably want a
%typefor bothexpressionandterm, but may not want one forquery. This means that everytermandexpressionrule needs an action that sets$$