我的 Flex 代码必须单独无效才能对 Bison 有效吗?

Must my Flex code be invalid alone to be valid with Bison?

每个教程都仅从 Flex 词法分析器开始。然后他们介绍了野牛。我可以 运行 Flex 和 运行 Bison 并编译得很好 - 我已经为自己编写了一个 shell 脚本 - 但我不应该只从 Flex 生成和编译为出色地?还是我必须放弃?

遗漏了我的 Bison 导致了很多错误。一些来源包括:

<tab>{FLA}  {yylval.midi = midi(yytext[1],yytext[0],1) ; return FLA;}

错误“对 `yylval' 的未定义引用。并且:

#include "y.tab.h"

找不到 .h 文件。我已经开始在我的编译脚本中包含 sed regex 以生成一个 kinder .l 文件,省略这些有问题的东西,然后我可以将其转换为 C 代码并单独编译,以便跟踪我在解析器旁边开发的词法分析器对于我的符号。

这是人们做的事吗?是否有不同的方法来保持 Flex 代码本身有效?还是人们就此放弃了?

是的,您可以 运行 flex 代码 stand-alone,出于某些目的,flex 生成的那种 finite-state 机器是完成这项工作的完美工具,仅此而已(例如需要上下文无关文法解析器)。我给学生的一个例子是,处理一些简单的通信包可能只需要一个有限状态机,而不是手工编码*,只需要使用flex.[=14这样的工具=]

但是,当同时使用 flex 和 bison 时,我认为对与 bison 组件分开的 flex 组件执行单元测试是很好的软件工程实践。当您首先动摇词法分析器时,它可以节省数小时的调试时间。我在这里教我的学生的技术是使用 C 宏和条件编译来分离依赖于 bison 的代码。其他人可能有他们喜欢的其他机制。

让我们举个例子。假设您有一种带有整数常量和标识符的简单语言,如您的问题所示,这些常量和标识符由 yylval 传递回解析器。我是这样做的:

%{
#ifdef PRINT
#define TOKEN(token) printf("Token: " #token ": %s\n", yytext)
#else
#define TOKEN(token) yylval=SymbolTable(yytext); return(token)
#endif
%}

identifier       [a-zA-Z][0-9a-zA-Z]*
number           [0-9]+

%%

{identifier}     TOKEN(ID);
{number}         TOKEN(NUMBER);

然后我可以这样构建我的 stand-alone 版本:

flex sample.l
gcc -o lexer.exe lex.yy.c -lfl -DPRINT

* 我假设您知道有限状态机只是循环中的一个开关...

while (not <<EOF>>) do {
  switch (state) {

   state1:   ... break;

 }
}