0

如何让yyparse函数从 C 字符串中读取其输入?

尝试过yy_scan_buffer(使用“fp”前缀而不是“yy”):

extern YY_BUFFER_STATE fs_scan_string ( const char *str );

struct fs *parse(char *s)
{
fp_scan_buffer(s);
int r = fpparse();
return r == 0 ? AST : NULL;

}

但:

h1.cpp:27: error: ‘YY_BUFFER_STATE’ does not name a type
h1.cpp: In function ‘fs* parse(char*)’:
h1.cpp:32: error: ‘fp_scan_buffer’ was not declared in this scope

尝试使用yy_delete_buffer,结果相同:未在此范围内声明。

fp.y

%{
#include "ft.h"
#include <map>
#include <iostream>

int fplex(); 
int fperror(char *p);
int fperror(char *p) { }

using namespace std;

struct fs *AST;
bool fpworking = true;
%}

%union {
    struct fs *f;
    struct ts *t;
    std::list<struct ts *> *tl;
    std::string *s;
}

%token END_OF_FILE
MORE TOKEN HERE...

%%

s : formula '\n'    { AST = $1; fpworking = true; YYACCEPT; }
MORE RULE HERE...

fp.l

%{
#include <iostream>
#include <list>
using namespace std;
#include "fp.tab.h"
%}

%option noyywrap

%%
[a-z][a-zA-Z0-9]*       { fplval.s = new std::string(fptext); return (TERM_ID); }
MORE PATTERN HERE...

h1.cpp

#include <iostream>
#include <list>
#include <string>
#include <map>
#include <stdlib.h>
#include <fstream>
#include "ft.h"

int fpparse();
int signparse();

extern bool fpworking;
extern struct fs *AST;

int main(int argc, char **argv)
{
    MORE CODE HERE...
}
4

2 回答 2

2

生成的解析器bison不进行 I/O。读取(或以其他方式获取)输入的责任由扫描仪负责,通常由(f)lex. 您提到的缓冲区管理功能是flex框架的一部分。它们不会在任何头文件中导出,因此您需要在插入flex输入文件的代码中使用它们,或者将它们显式添加到您自己的头文件中。

flexbison(或者,一般来说,lex和的派生词)的传统使用yacc严重依赖于全局状态变量,因此很难将多个解析器和/或扫描器集成到单个可执行文件中。修改yy前缀并不能真正解决这个问题,但确实允许多个单例。更新版本的代码生成器允许生成pure解析器和扫描器,它们将包含状态的结构作为附加参数。可以将您自己的状态添加到这些结构中,甚至可以将它们组合成一个结构。这可以产生更优雅的界面,但这些工具对 API 设计的帮助不大。无论如何,使用纯解析器和扫描器,外部可用的状态访问更少。

简而言之,您可能应该将自己的缓冲区管理 API 添加到您的flex文件中,将其接口导出到您自己的头文件中,然后将该文件导入您的扫描仪、解析器和它们的使用者中。

于 2013-10-05T14:45:23.550 回答
1

为了使用各种 flex 定义的符号(例如YY_BUFFER_STATEand yy_scan_buffer),这样做的代码必须放在 .l 文件的第三部分。

问题是这些符号仅在 lex.yy.c 文件中定义,而不是在您可以#include在其他地方的任何头文件中定义。

因此,您需要做的就是将parse代码(上面的第一个块)放在 .l 文件的末尾(第二%%行之后)并从中调用它main,它应该可以正常工作。

于 2013-10-05T16:35:26.770 回答