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