1

假设我希望我的 Lex 和 Yacc 程序解析命令行参数,例如:

./a.out show memory

我想让 lex 解析字符串“显示内存”。我该如何做到这一点?

4

4 回答 4

2
int main(int argc, char **argv) {
    if(argc > 1) {
    if(argv[1])
        yy_scan_string(argv[1]);
    }
    yyparse();
    return 0;
} 
于 2011-10-24T23:35:58.277 回答
2

您需要通过在它们之间插入空格来将所有参数连接成一个大字符串。然后将剩余的文本缓冲区提供给 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;
}
于 2009-12-15T11:23:20.727 回答
0

用老式的方式做有什么问题?:

if(argc > 1 && !strcmp(argv[1],"show"))
{
    if(argc > 2)
    {
        if(!strcmp(argv[2],"memory"))
            ...
        else if(!strcmp(argv[2],"cpu"))
            ...
        else ...
    }
}

再说,getopt()和朋友在一起更合适。

于 2009-12-15T14:59:21.117 回答
0

我的博客文章Parsing command line parameters with Yacc & Flex用一个工作示例解释了这一点。无需连接参数字符串。原因在文章中给出。

简介是:

每隔一段时间就会有人过来询问如何使用 Yacc 和 Flex 解析命令行参数。这是相当直截了当的,但需要对生成的代码有一些了解才能正确。

在这里,我们提供了一个执行此操作的源模板。用户只需编辑语法和扫描规则。假定您对 C、Yacc 和 Flex 有一定的了解。

该代码已获得 WTFPL 许可

该模板是为 Berkeley Yacc 和 Flex 的反射变体编写的。它可以与 GNU Bison 和 SourceForge Flex 一起使用,可能需要进行一些更改。

你得到的是一个模板,你可以在其中插入你的词汇和语法规范。

请询问有关使用和调整模板本身以适应博客评论的问题。

于 2012-06-05T22:22:40.393 回答