Flex 词法分析器的字符串输入
我想使用 flex/bison 解析器创建一个读取-评估-打印循环。 问题是,flex 生成的词法分析器需要 FILE* 类型的输入,而我希望它是 char*。 有办法做到这一点吗?
一个建议是创建一个管道,向其提供字符串并打开文件描述符并发送到词法分析器。 这相当简单,但感觉很复杂,而且不太独立于平台。 有没有更好的办法?
I want to create a read-eval-print loop using flex/bison parser. Trouble is, the flex generated lexer wants input of type FILE* and i would like it to be char*. Is there anyway to do this?
One suggestion has been to create a pipe, feed it the string and open the file descriptor and send to the lexer. This is fairly simple but it feels convoluted and not very platform independent. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
以下例程可用于设置输入缓冲区以扫描内存中字符串而不是文件(如 yy_create_buffer 所做的那样):
YY_BUFFER_STATE yy_scan_string(const char *str)
:扫描以 NUL 结尾的字符串`YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len)
:从位置字节开始扫描 len 个字节(可能包括 NUL)请注意,这两个函数都会创建、返回相应的 YY_BUFFER_STATE 句柄(您必须使用 yy_delete_buffer( 删除该句柄) )完成后),因此 yylex() 扫描字符串或字节的副本。 这种行为可能是理想的,因为 yylex() 修改了它正在扫描的缓冲区的内容)。
如果您想避免复制(和 yy_delete_buffer),请使用:
YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size)
示例 main:
The following routines are available for setting up input buffers for scanning in-memory strings instead of files (as yy_create_buffer does):
YY_BUFFER_STATE yy_scan_string(const char *str)
: scans a NUL-terminated string`YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len)
: scans len bytes (including possibly NULs) starting at location bytesNote that both of these functions create, return a corresponding YY_BUFFER_STATE handle (which you must delete with yy_delete_buffer() when done with it) so yylex() scan a copy of the string or bytes. This behavior may be desirable since yylex() modifies the contents of the buffer it is scanning).
If you want avoid the copy (and yy_delete_buffer) using:
YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size)
sample main:
有关信息,请参阅 Flex 手册的本节关于如何扫描内存缓冲区,例如字符串。
See this section of Flex's manual for information on how to scan in-memory buffers, such as strings.
flex 可以使用以下三个函数之一解析
char *
:yy_scan_string()
,yy_scan_buffer()
和yy_scan_bytes()
(请参阅 文档)。 这是第一个示例:yy_scan_buffer() 的等效语句(需要双空终止字符串):
我的回答重申了 @dfa 和 @jlholland 提供的一些信息,但两者都没有他们的答案代码似乎对我有用。
flex can parse
char *
using any one of three functions:yy_scan_string()
,yy_scan_buffer()
, andyy_scan_bytes()
(see the documentation). Here's an example of the first:The equivalent statements for
yy_scan_buffer()
(which requires a doubly null-terminated string):My answer reiterates some of the information provided by @dfa and @jlholland, but neither of their answers' code seemed to be working for me.
这就是我需要做的:
你不能 extern typedef,当你考虑它时这是有道理的。
Here is what I needed to do :
you cannot extern the typedef, which make sense when you think about it.
接受的答案是不正确的。 会导致内存泄漏。
在内部,yy_scan_string 调用 yy_scan_bytes,后者又调用 yy_scan_buffer。
yy_scan_bytes 为输入缓冲区的副本分配内存。
yy_scan_buffer 直接作用于提供的缓冲区。
对于所有三种形式,您必须调用 yy_delete_buffer 来释放 Flex 缓冲区状态信息 (YY_BUFFER_STATE)。
但是,使用 yy_scan_buffer,您可以避免内部缓冲区的内部分配/复制/释放。
yy_scan_buffer 的原型不采用 const char* 并且您不能期望内容保持不变。
如果您分配了内存来保存字符串,则您有责任在调用 yy_delete_buffer 之后释放它。
另外,当您仅解析此字符串时,不要忘记让 yywrap 返回 1(非零)。
下面是一个完整的例子。
The accepted answer is incorrect. It will cause memory leaks.
Internally, yy_scan_string calls yy_scan_bytes which, in turn, calls yy_scan_buffer.
yy_scan_bytes allocates memory for a COPY of the input buffer.
yy_scan_buffer works directly upon the supplied buffer.
With all three forms, you MUST call yy_delete_buffer to free the flex buffer-state information (YY_BUFFER_STATE).
However, with yy_scan_buffer, you avoid the internal allocation/copy/free of the internal buffer.
The prototype for yy_scan_buffer does NOT take a const char* and you MUST NOT expect the contents to remain unchanged.
If you allocated memory to hold your string, you are responsible for freeing it AFTER you call yy_delete_buffer.
Also, don't forget to have yywrap return 1 (non-zero) when you're parsing JUST this string.
Below is a COMPLETE example.
或者,您可以在 lex 文件中重新定义函数 YY_INPUT,然后将字符串设置为 LEX 的输入。 如下:
在你的main.c中,在扫描之前,你需要先设置lex的缓冲区:
Other-way, you can redefine function YY_INPUT in lex file, and then set your string to LEX's input. As below:
In your main.c, before scanning, you need to set lex's buffer first:
这是一个在 cpp 代码中使用 bison / flex 作为解析器的小示例,用于解析字符串并根据它更改字符串值
(代码的一小部分被删除,因此可能存在不相关的部分。)
解析器.y:
here is a small example for using bison / flex as a parser inside your cpp code for parsing string and changing a string value according to it
(few parts of the code were removed so there might be irrelevant parts there.)
parser.y :
libmatheval 中有这段有趣的代码:
There's this funny code in libmatheval: