I'm learning flex/bison. I wrote the following program but getting errors.
%{
#include <stdio.h>
typedef struct node
{
struct node *left;
struct node *right;
char *token;
}node;
node *mknode( node *left, node *right, char *token);
void printtree(node *tree);
#define YYSTYPE struct node *
%}
%union
{
char* str;
int num;
}
%start lines
%token <str> WORD
%token <str> PLUS MINUS TIMES DIVIDE POWER
%token <str> LEFT_PARENTHESIS RIGHT_PARENTHESIS
%token <str> END
%left PLUS MINUS
%left TIMES DIVIDE
%right POWER
%type <str> exp term factor line lines
%%
lines: /* empty */
| lines line;
line: exp END { printtree($1); printf("\n");}
;
exp: term {$$=$1; }
| exp PLUS term { $$=mknode($1,$3,"+"); }
| exp MINUS term { $$=mknode($1,$3,"-"); }
;
term: factor { $$=$1; }
|term TIMES factor { $$=mknode($1,$3,"*"); }
;
factor: WORD { $$=mknode(0,0, (char*)yylval); }
|LEFT_PARENTHESIS exp RIGHT_PARENTHESIS
{ $$=$2; }
;
%%
int main(void)
{
return yyparse();
}
node *mknode(node *left, node *right, char *token)
{
/* malloc the node */
node *newnode = (node *)malloc(sizeof(node));
char *newstr = (char *)malloc(strlen(token)+1);
strcpy(newstr, token);
newnode->left = left;
newnode->right = right;
newnode->token = newstr;
return(newnode);
}
void printtree(node *tree)
{
int i;
if (tree->left || tree->right)
printf("(");
printf(" %s ", tree->token);
if (tree->left)
printtree(tree->left);
if (tree->right)
printtree(tree->right);
if (tree->left || tree->right)
printf(")");
}
int yyerror(char *s )
{
fprintf (stderr, "%s\n", s);
}
flex:
%{
#include <stdlib.h>
#include "y.tab.h"
%}
%%
[a-zA-Z0-9]+ { yylval.str = strdup( yytext ); return WORD; }
/* cast pointer to int for compiler warning */
[ \t] ;
"+" return(PLUS);
"-" return(MINUS);
"*" return(TIMES);
"/" return(DIVIDE);
"^" return(POWER);
"(" return(LEFT_PARENTHESIS);
")" return(RIGHT_PARENTHESIS);
\n return(END);
%%
int yywrap (void) {return 1;}
The error I'm getting:
C:\flexbison>recomp example2
example2.y:40.6: warning: empty rule for typed nonterminal, and no action
conflicts: 5 reduce/reduce
example2.y:43: error: request for member `str' in something not a structure or union
example2.y:46: error: request for member `str' in something not a structure or union
example2.y:46: error: request for member `str' in something not a structure or union
example2.y:47: error: request for member `str' in something not a structure or union
example2.y:47: error: request for member `str' in something not a structure or union
example2.y:47: error: request for member `str' in something not a structure or union
example2.y:48: error: request for member `str' in something not a structure or union
example2.y:48: error: request for member `str' in something not a structure or union
example2.y:48: error: request for member `str' in something not a structure or union
example2.y:51: error: request for member `str' in something not a structure or union
example2.y:51: error: request for member `str' in something not a structure or union
example2.y:52: error: request for member `str' in something not a structure or union
example2.y:52: error: request for member `str' in something not a structure or union
example2.y:52: error: request for member `str' in something not a structure or union
example2.y:55: error: request for member `str' in something not a structure or union
example2.y:56: error: request for member `str' in something not a structure or union
example2.y:58: error: request for member `str' in something not a structure or union
example2.y:58: error: request for member `str' in something not a structure or union
Any idea why I'm getting this error?
The first glaring problem is that you should not be defining YYSTYPE
if you are using yacc. Yacc defines YYSTYPE
from your %union
. You need to define YYSTYPE
if you're using lex
, but not using yacc
.
Your %union
parse stack item type only contains int
and str
members. Example: you have defined the exp
grammar symbol as having type str
, and then you have this production:
exp: term {$$=$1; }
| exp PLUS term { $$=mknode($1,$3,"+"); }
| exp MINUS term { $$=mknode($1,$3,"-"); }
;
The mknode
function returns node *
, but the type of the $$
symbol is char *
because it stands for the exp
on the left hand side, which you typed as a str
, and the str
member of the %union
is char *
.
The arguments to mknode
must also be node *
. But $1
and $3
do not have that type.
来源:https://stackoverflow.com/questions/10273523/flex-bison-errorrequest-for-member-str-in-something-not-a-structure-or-union