2
votes

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?

1
The bottom bit looks like lex. Bison is just an alternative to Yacc as far as I know, so I don't think you would use them together.Max Spencer
To elaborate. Lex is the "lexical analyser", it reads the characters from the input and returns tokens (so in your example it returns an AND token when it reads the string "and". Yacc/Bison is the grammar parser. It analyses the token stream and parses it i.e. ensures the series of tokens are a valid sentence in the grammar.Max Spencer
yes you are right, it was a typo. Flex does lexical analysis and bison does syntax analysis..so yes they are used together.sap
Edited my examples. Can you pls tell me how to fix this error or why I"m getting this? Thankssap
I might be able to, I have been using Flex/Byacc recently and I had the exact same error at one stage. Can you post the Yacc/Bison grammar if you have written that. The problem in my case was that I needed to specify the type of some of the productions in the grammar. Note: Byacc is just another thing like Yacc and Bison.Max Spencer

1 Answers

7
votes

Its because you're missing the declaration %type <...> expression in the first part of your grammar, where ... is some type declared in your %union statement. Without this, you can't access $$ in any expression action. 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 %type declaration 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 %token instead of %type, and you need to set yylval in 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 %type for both expression and term, but may not want one for query. This means that every term and expression rule needs an action that sets $$