问题
I'm just doing a homework assignment where i have to make a simple polynomial parser generator. So it has to accept assignment like: a= 2x2+2 and also evaluation like a[2] will print 10. If a is entered alone it should print 2x2+2. It should work for any polynomial. There is a typedef struct defined in another file which I'm supposed to use:
typedef struct Polyn {
int sign;
int coeff;
int exp;
struct Polyn *next;
} Polyn;
lex file:
%option noyywrap
%{
#include <stdio.h>
#include <string.h>
#define YY_DECL int yylex()
#include "calc.tab.h"
%}
%%
[0-9]+ {yylval = atoi(yytext); return T_INT;}
[a-wy-z]+ {yylval.string=strdup(yytext); return T_IDENT;}
. {return 1;}
<<EOF>> {return 0;}
%%
bison file:
%{
#include <stdio.h>
#include <stdlib.h>
#include "polyn.h"
#include "symbtab.h"
extern int yylex();
extern int yyparse();
void yyerror(const char* s);
%}
%token T_INT
%token T_EQUAL
%token T_IDENT T_POLYN
%start input
%%
input:
%empty
| input line
;
line:
T_NEWLINE
| expression T_NEWLINE { printf("\tResult: %i\n", $1); }
| assign T_NEWLINE ;
| T_QUIT T_NEWLINE { exit(0); }
;
expression:
T_INT { $$ = $1; }
| expression T_PLUS expression { $$ = $1 + $3; }
| expression T_MINUS expression { $$ = $1 - $3; }
| expression T_MULTIPLY expression { $$ = $1 * $3; }
| expression T_DIVIDE expression { $$ = $1 / $3; }
| T_LROUND expression T_RROUND { $$ = $2; }
;
%%
int main() {
while (yyparse());
return 0;
}
void yyerror(const char* s) {
fprintf(stderr, "Parse error: %s\n", s);
}
When i run it right now to test I'm getting an error
./m
calc.y:54.5-11: warning: type clash on default action: <p> != <> [-Wother]
T_POLYN
^^^^^^^
calc.l: In function ‘yylex’:
calc.l:15:9: error: incompatible types when assigning to type ‘YYSTYPE {aka union YYSTYPE}’ from type ‘int’
[0-9]+ {yylval = atoi(yytext); return T_INT;}
^
calc.l:26:8: error: ‘YYSTYPE {aka union YYSTYPE}’ has no member named ‘string’
[a-wy-z]+ {yylval.string=strdup(yytext); return T_IDENT;}
回答1:
YYSTYPE
is the (union) type defined by your %union
directive in the the .y file:
%union {
int intval;
char *chstr;
struct Polyn *p;
}
so it is a union with 3 fields: intval
, chstr
, and p
. Now look at your errors:
calc.l:15:9: error: incompatible types when assigning to type ‘YYSTYPE {aka union YYSTYPE}’ from type ‘int’
[0-9]+ {yylval = atoi(yytext); return T_INT;}
you're trying to assign the return value from atoi
(an int) to a union. Not the same type, so you get a type error from the C compiler. You need yylval.intval = atoi(
...
calc.l:26:8: error: ‘YYSTYPE {aka union YYSTYPE}’ has no member named ‘string’
[a-wy-z]+ {yylval.string=strdup(yytext); return T_IDENT;}
you're trying to assign to the string
field of your union, which does not exist. You need yylval.chstr=
...
These errors are simple C errors, and the fact that you're using flex and bison is incidental.
来源:https://stackoverflow.com/questions/65033105/yylex-errors-for-simple-parser-generator