【问题标题】:How can I parse a C string (char *) with flex/bison?如何使用 flex/bison 解析 C 字符串 (char *)?
【发布时间】:2011-05-15 20:19:15
【问题描述】:

在我的编程项目中,我想使用 flex/bison 解析命令行属性。我的程序是这样调用的:

./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename

是否可以使用 flex/bison 解析这个字符串而不将其写入文件并解析该文件?

【问题讨论】:

  • 我认为编写一个简单的状态机比使用 Flex 或 Bison 更容易和更干净。
  • 如果你认为你需要 flex 和 bison,这个语法到底有多复杂?而且我必须同意 James 的观点:仅解析带有可选空格和括号的以逗号分隔的整数列表,C 是最好的。
  • 到目前为止,我只同时使用了 flex 和 bison。仔细观察,只使用 flex 更有意义。

标签: c bison flex-lexer


【解决方案1】:

看到这个问题String input to flex lexer

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
  • 或者也许只是将问题作为重复项关闭?
【解决方案2】:

我认为您可以通过使用fmemopenchar* 创建一个流然后将其替换为标准输入来实现类似的目标(我做了类似的事情)

类似的东西(不确定它是否功能齐全,因为我实际上是在尝试记住可用的系统调用,但它会与此类似)

char* args = "(1,2,3)(4,5)(6,7,8)"
FILE *newstdin = fmemopen (args, strlen (args), "r");
FILE *oldstdin = fdup(stdin);

stdin = newstdin;

// do parsing

stdin = oldstdin;

【讨论】:

    【解决方案3】:

    这是一个完整的 flex 示例。

    %%
    
    <<EOF>> return 0;
    
    .   return 1;
    
    %%
    
    int yywrap()
    {
        return (1);
    }
    
    int main(int argc, const char* const argv[])
    {
        YY_BUFFER_STATE bufferState = yy_scan_string("abcdef");
    
        // This is a flex source. For yacc/bison use yyparse() here ...    
        int token;
        do {
            token = yylex();
        } while (token != 0);
    
        // Do not forget to tell flex to clean up after itself. Lest
        // ye leak memory.
        yy_delete_buffer(bufferState);
    
        return (EXIT_SUCCESS);
    }
    

    【讨论】:

      【解决方案4】:

      另一个例子。这个重新定义了 YY_INPUT 宏:

      %{
      int myinput (char *buf, int buflen);
      char *string;
      int offset;
      #define YY_INPUT(buf, result, buflen) (result = myinput(buf, buflen));
      %}
      %%
      
      [0-9]+             {printf("a number! %s\n", yytext);}
      
      .                  ;
      %%
      
      int main () {
          string = "(1, 2, 3)(4, 5)(6, 7, 8)";
          yylex();
      }
      
      int myinput (char *buf, int buflen) {
          int i;
          for (i = 0; i < buflen; i++) {
              buf[i] = string[offset + i];
              if (!buf[i]) {
                  break;
              }
          }
          offset += i;
          return i;
      }
      

      【讨论】:

        【解决方案5】:

        答案是“是”。请参阅由 Doug Brown、John Levine、Tony Mason 撰写的名为“lex & yacc”的 O'Reilly 出版物第 2 版。请参阅第 6 章,“从字符串输入”部分。

        我还刚刚注意到,John Levine 的“flex 和 bison”第 5 章的“字符串输入”部分有一些很好的说明。注意例程 yy_scan_bytes(char *bytes, int len)、yy_scan_string("string") 和 yy_scan_buffer(char *base, yy_size_t size)。我自己还没有从字符串中扫描,但很快就会尝试。

        【讨论】:

        • “去买书”不是答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多