1

我是这个 flex 和 bison 的新手,我有一个小问题。一旦我得到了我的 lex.yy.c 文件和我的 tab.c 文件,当我编译 lex.yy.c 文件时,我得到了错误:

stojk_2.l: In function ‘int yylex()’:
stojk_2.l:3: error: ‘PLUS’ was not declared in this scope
stojk_2.l:4: error: ‘MINUS’ was not declared in this scope
stojk_2.l:5: error: ‘MULT’ was not declared in this scope
stojk_2.l:6: error: ‘DIVIDE’ was not declared in this scope
stojk_2.l:8: error: ‘LPAREN’ was not declared in this scope
stojk_2.l:9: error: ‘RPAREN’ was not declared in this scope
stojk_2.l:12: error: ‘yylval’ was not declared in this scope
stojk_2.l:13: error: ‘UNSIGNEDINTEGER’ was not declared in this scope

当我编译 tab.c 文件时,我得到了这些错误:

stojk_3.y: In function ‘void yyerror(char*)’:
stojk_3.y:12: error: ‘print’ was not declared in this scope
stojk_3.tab.c: At global scope:
stojk_3.tab.c:1056: error: redefinition of ‘double yylval’
stojk_3.y:8: error: ‘double yylval’ previously declared here
stojk_3.tab.c: In function ‘int yyparse()’:
stojk_3.tab.c:1253: error: ‘yylex’ was not declared in this scope
stojk_3.tab.c:1401: warning: deprecated conversion from string constant to ‘char*’
stojk_3.tab.c:1547: warning: deprecated conversion from string constant to ‘char*’

似乎他们看不到对方,但我把它们放在同一个文件夹中,所以我不知道我应该做什么......任何帮助将不胜感激......

感谢大家的帮助,但仍然试图弄清楚,但这是我的代码:

stojk_2.l

%%

"+"            {return PLUS;}
"-"            {return MINUS;}
"*"            {return MULT;}
"/"            {return DIVIDE;}

"("            {return LPAREN;}
")"            {return RPAREN;}

[0-9]+     {
            sscanf(yytext,  "%lf", &yylval);
        return UNSIGNEDINTEGER;
            }

[ \t]      {  }
[\n]       {return yytext[0];}

.          {return yytext[0];}

%%

int yywrap()
{
        return 0;
}

stojk_3.y

%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define YYSTYPE double

YYSTYPE yylval;

void yyerror(char *s)
{
        print("yyerror: %s\n", s);
}

%}

%token PLUS
%token MINUS
%token MULT
%token DIVIDE

%token LPAREN
%token RPAREN

%token UNSIGNEDINTEGER

%left PLUS MINUS
%left MULT DIVIDE

%%

lines     :         lines expr   '\n'         {printf("%g\n", $2);}
          |         lines '\n'
          |         /*empty*/
          ;

expr      :          expr PLUS  expr           {$$  =  $1  +  $3;}  
          |          expr MINUS  expr           {$$  =  $1  -  $3;} 
          |          expr MULT  expr           {$$  =  $1  *  $3;} 
          |          expr DIVIDE  expr           {$$  =  $1  /  $3;} 
          |          LPAREN  expr  RPAREN        {$$ =  $2;}
          |          UNSIGNEDINTEGER
          ;

%%

#include  "lex.yy.c"

int yylex();
int yyparse(void);

int main()
{
return yyparse();
}
4

2 回答 2

2

第一组错误看起来像您#include在 .l 文件中的 .tab.h 文件失败。第二组错误看起来像是您的 .y 文件有问题,但如果不查看 .y 文件就很难准确判断是什么。

于 2012-11-16T02:42:44.413 回答
0

您需要从中生成bison定义常量的标头。您需要在词法分析器中包含该标题。

bison -d stojk_3.y    # generates stojk_3.tab.c and stojk_3.tab.h

因此,您需要将其包含stojk_3.tab.h在 Flex 代码中。

print()函数可能是printf();的拼写错误。它当然不是标准功能。

的多重定义yylval很可能是因为您定义了它但不需要(Bison 为您这样做)。您可能需要extern int yylex(void);在代码中声明或等效。转换投诉意味着您将文字字符串传递给采用 a 的函数char *(但字符串在形式上是不可修改的,因此应声明并定义该函数以采用 aconst char *代替)。

如果没有看到更多代码,很难更具体。


使用提供的代码

正如预测的那样,问题print()是 的错字。printf()应该有一个强有力的论据fprintf(stderr, ...);错误应该去stderr而不是stdout

你不需要定义yylval; 注释掉那一行。

int yylex(void);在语法文件的顶部(在该%{ ... %}部分中)声明了。

我做yyerror()了一个静态函数。我得到了两个警告:

gcc -O3 -g -std=c99 -Wall -Wextra -Wstrict-prototypes stojk_3.tab.c -o stojk_3.tab
In file included from stojk_3.y:50:0:
lex.yy.c:1112:17: warning: ‘yyunput’ defined but not used [-Wunused-function]
lex.yy.c:1153:16: warning: ‘input’ defined but not used [-Wunused-function]

固定代码

%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define YYSTYPE double

int yylex(void);

static
void yyerror(char *s)
{
        printf("yyerror: %s\n", s);
}

%}

%token PLUS
%token MINUS
%token MULT
%token DIVIDE

%token LPAREN
%token RPAREN

%token UNSIGNEDINTEGER

%left PLUS MINUS
%left MULT DIVIDE

%%

lines     :         lines expr   '\n'         {printf("%g\n", $2);}
          |         lines '\n'
          |         /*empty*/
          ;

expr      :          expr PLUS  expr           {$$  =  $1  +  $3;}  
          |          expr MINUS  expr           {$$  =  $1  -  $3;} 
          |          expr MULT  expr           {$$  =  $1  *  $3;} 
          |          expr DIVIDE  expr           {$$  =  $1  /  $3;} 
          |          LPAREN  expr  RPAREN        {$$ =  $2;}
          |          UNSIGNEDINTEGER
          ;

%%

#include  "lex.yy.c"

int yylex(void);
int yyparse(void);

int main(void)
{
    return yyparse();
}

我没有收到关于非常量字符指针的警告;我不确定那里有什么问题。

于 2012-11-16T02:42:36.210 回答