yylex errors for simple parser generator

橙三吉。 提交于 2021-01-07 01:29:21

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!