假设我希望我的 Lex 和 Yacc 程序解析命令行参数,例如:
./a.out show memory
我想让 lex 解析字符串“显示内存”。我该如何做到这一点?
假设我希望我的 Lex 和 Yacc 程序解析命令行参数,例如:
./a.out show memory
我想让 lex 解析字符串“显示内存”。我该如何做到这一点?
int main(int argc, char **argv) {
if(argc > 1) {
if(argv[1])
yy_scan_string(argv[1]);
}
yyparse();
return 0;
}
您需要通过在它们之间插入空格来将所有参数连接成一个大字符串。然后将剩余的文本缓冲区提供给 Lex/Yacc,方法是重新定义YY_INPUT
宏,以便它从您的文本缓冲区读取输入。
开始可能是这样的:
#include <stdio.h>
#include <string.h>
char *argbuf;
size_t arglen;
int main(int argc, char *argv[])
{
int i;
// Compute total length of all arguments, with a single space between.
arglen = 0;
for(i = 1; argv[i] != NULL; i++)
arglen += 1 + strlen(argv[i]);
// Allocate buffer space.
argbuf = malloc(arglen);
if(argbuf == NULL)
{
fprintf(stderr, "No memory for argument buffer, aborting");
exit(1);
}
// Concatenate all arguments. This is inefficient, but simple.
argbuf[0] = 0;
for(i = 1; argv[i] != NULL; i++)
{
if(i > 1)
strcat(argbuf, " ");
strcat(argbuf, argv);
}
// Here we should be ready to call yyparse(), if we had implemented YY_INPUT().
return 0;
}
用老式的方式做有什么问题?:
if(argc > 1 && !strcmp(argv[1],"show"))
{
if(argc > 2)
{
if(!strcmp(argv[2],"memory"))
...
else if(!strcmp(argv[2],"cpu"))
...
else ...
}
}
再说,getopt()
和朋友在一起更合适。
我的博客文章Parsing command line parameters with Yacc & Flex用一个工作示例解释了这一点。无需连接参数字符串。原因在文章中给出。
简介是:
每隔一段时间就会有人过来询问如何使用 Yacc 和 Flex 解析命令行参数。这是相当直截了当的,但需要对生成的代码有一些了解才能正确。
在这里,我们提供了一个执行此操作的源模板。用户只需编辑语法和扫描规则。假定您对 C、Yacc 和 Flex 有一定的了解。
该代码已获得 WTFPL 许可
该模板是为 Berkeley Yacc 和 Flex 的反射变体编写的。它可以与 GNU Bison 和 SourceForge Flex 一起使用,可能需要进行一些更改。
你得到的是一个模板,你可以在其中插入你的词汇和语法规范。
请询问有关使用和调整模板本身以适应博客评论的问题。