我几乎在网上搜索了所有资料。但我仍然困惑为什么lexer无法识别yylval。
以下是这种情况:
我在node.h
中定义了一堆ADT并在node.c
中实现它们,我的目的是在正确存储这些结构后生成AST。但我被困在野牛档案中。
首先,我将%union
更改为union YYSTYPE {...};
和typedef union YYSTYPE YYSTYPE;
,我不知道为什么我需要这样做,在线发布的其他一些文件似乎与{{1}一起使用}。
然后,我被%uinion
事情困扰了。我已完成yylval
项事务,并已在bison -d
中检查过(我已指定了bison输出),因此我认为parser.c
应该有效。但事实并非如此。所以我想知道是否还有另一种解决yylval未申报问题的方法。
我只使用两种类型的extern YYSTYPE yylval;
结构,YYSTYPE
和int
,我可以将AST的char *
和结构分开吗?这意味着,非终结者将没有相关类型。你们有其他想法吗?
答案 0 :(得分:5)
如果它对其他人有帮助,我发现(OpenBSD lex v2.5.4 + yacc)包括
extern YYSTYPE yylval;
我的lex源代码中的不足以防止'yylval undefined'问题,即使 y.tab.c 文件包含:
#ifndef YYSTYPE
typedef int YYSTYPE;
#endif
我通过在lex源中添加一个明确的定义来解决这个问题:
#define YYSTYPE int
extern YYSTYPE yyltype
但是,我不清楚以这种方式定义是否会传播到yacc源文件的语言环境...
答案 1 :(得分:1)
你应该使用%union。您不需要键入dede联合。
使用bison -d获取带有任何声明的头文件(例如终端,非终结符和令牌的类型)。例如:
bison -d parser.y
将产生两个文件,parser.tab.c和parser.tab.h。您可以将后一个文件包含在词法分析器文件中,这样就可以了解您的%token
定义。该文件还包括yylval及其类型的定义。
你不应该将联盟分开,因为你很可能会扩展它,并且需要它来在词法分析器和解析器之间进行通信。
答案 2 :(得分:0)
你的.y文件中是否设置了%pure-parser(或类似)?这会禁用正常的lex声明,因为它们不可重入。
https://www.gnu.org/software/bison/manual/html_node/Pure-Decl.html