这是我的程序的开始。我一直收到错误boolExpr.y:13:2:错误:未知类型名“bool”bool boolean;但是当我检查野牛生成的文件时,我可以看到stdbool. h被包含在程序执行的开始处。我不明白为什么一个库很重要,但是bool却没有被识别出来。我想我遗漏了一些简单的东西,或者我需要重新安装bison或lex。如果需要的话,我可以包含程序的其余部分。
我试图将其转换为int布尔值;而不是bool布尔值;这就解决了编译问题,但它仍然让我感到困惑。有没有什么方法可以将指向结构体的指针扩展到%union中而不会出现编译错误?我尝试将structName * 布尔值;以替换bool boolean,但它也会作为未定义的wimplicit错误返回。
%{
#include "semantics.h"
#include <stdbool.h>
#include "IOMngr.h"
#include <string.h>
extern int yylex(); /* The next token function. */
extern char *yytext; /* The matched token text. */
extern int yyerror(char *s);
extern SymTab *table;
extern SymEntry *entry;
%}
%union{
bool boolean;(this is the line # of error)
char * string;
}
%type <string> Id
%type <boolean> Expr
%type <boolean> Term
%type <boolean> Factor
%token Ident
%token TRUE
%token FALSE
%token OR
%token AND
%%
Prog : StmtSeq {printSymTab();};
StmtSeq : Stmt StmtSeq { };
StmtSeq : { };
Stmt : Id '=' Expr ';' {storeVar($1, $3);};
Expr : Expr OR Term {$$ = doOR($1, $3);};
Expr : Term {$$ = $1;};
Term : Term AND Factor {$$ = doAND($1, $3);};
Term : Factor {$$ = $1;};
Factor : '!' Factor {$$ = doNOT($2);};
Factor : '(' Expr ')' {$$ = $2;};
Factor : Id {$$ = getVal($1);};
Factor : TRUE {$$ = true;};
Factor : FALSE {$$ = false;};
Id : Ident {$$ = strdup(yytext);};
%%
int yyerror(char *s) {
WriteIndicator(getCurrentColumnNum());
WriteMessage("Illegal Character in YACC");
return 1;
}
2条答案
按热度按时间cnwbcb6i1#
好吧,愚蠢的错误毕竟-在我的莱克斯文件,我有
但应该是
没意识到顺序重要!
2fjabf4q2#
当使用
%union
声明时,野牛创建一个名为YYSTYPE
的union
类型,它在生成的头文件中声明该类型;该类型用于yylval
的声明中,它也在生成的头文件中。将声明放在生成的头文件中意味着除了#include
在bison生成的头文件中之外,您不需要做任何事情来使yylval
及其类型YYSTYPE
在词法分析器中可用。如果在
%union
声明中引用的所有类型都是标准C类型,这是很好的。但是,如果你想使用一个需要#include
d头文件的类型,或者你自己定义的类型,那就有问题了。假设你把必要的行放在野牛代码序言中(%{...}%
),编译解析器不会有问题,但是词法分析器会遇到问题。当您对头文件进行#include
时,您将有效地插入“union YYSTYPE”声明,并且除非所有引用的类型都已定义,否则该操作将失败。当然,您可以通过将所有必需的
#include
和/或定义从.y
文件复制到.l
文件来解决这个问题,请确保将union+
声明所需的代码放在头文件的#include
* 之前 *,并将需要定义YYSTYPE
的代码放在#include
* 之后 *。但这违背了优秀软件设计的原则;这意味着每次在.y
文件中更改#include
或声明时,都需要考虑是否需要在.l
文件中进行类似的更改以及在何处进行类似的更改。理想的做法是将所有需要插入的内容都安排到生成的头文件中,然后您可以在词法分析器中只插入
#include "h4.tab.h"
,确信您不需要做任何其他事情来确保所需的#include
存在并且顺序正确。为此,野牛提供了
%{...}%
指令的更灵活的替代方案:where
有几个可能的值,这些值在野牛文档中有说明。其中两个值用于维护生成的头文件:%code requires { ... }
在头文件和源文件中插入代码块,在这两种情况下都在union
声明之前。这是您应该用于语义和位置类型依赖项的代码块类型。%code provides { ... }
也会将代码块插入到头文件和源文件中,但这次是在union
声明之后。如果你有一些引用YYSTYPE
的接口,你可以使用这种块类型。您仍然可以使用
%{...}%
将代码直接插入到输出源代码中。与
%{...}%
类似,它只将代码插入源文件中。与%{...}%
不同,它将代码插入源文件中定义的位置,在YYSTYPE
和其他声明之后。这避免了%{...}%
块的模糊问题,这些代码有时插入得早,有时插入得晚,因此,如果更改明显不相关的野牛的顺序,可能会突然编译失败指令中。