c - 解析:库函数、FSM、explode() 或 lex/yacc?

标签 c parsing lex explode scanf

当我必须解析文本(例如配置文件或其他相当简单/描述性的语言)时,我想到了几种解决方案:

  • 使用库函数,例如strtok() , sscanf()
  • 一次处理一个字符的有限状态机,标记和解析
  • 使用 explode()我曾经因为无聊而写的函数
  • 使用 lex/yacc (阅读: flex/bison )生成合适的解析器

  • 我不喜欢“库函数”方法。感觉很笨拙和尴尬。 explode() ,虽然它不需要太多的新代码,但感觉更炸了。和 flex/bison往往看起来太过分了。

    我通常会实现 FSM,但同时我已经为这个可怜的家伙感到抱歉,他可能不得不在以后维护我的代码。

    因此我的问题是:

    解析相对简单的文本文件的最佳方法是什么?
    这有关系吗?
    是否有普遍认可的方法?

    最佳答案

    我将打破规则并乱序回答您的问题。

  • 是否有普遍认可的方法?

  • 绝对不。恕我直言,您选择的解决方案应该取决于(仅举几例)您的文本、您的时间框架、您的经验,甚至您的个性。如果文字足够简单,可以制作flexbison矫枉过正,也许 C 本身就是矫枉过正。快速还是稳健更重要?它是否需要维护,还是可以快速而肮脏地启动?您是热情的 C 用户,还是会被正确的语言功能所吸引? &c., &c.
  • 这有关系吗?

  • 同样,这是只有您才能回答的问题。如果您与具有特定技能和能力的团队密切合作,并且解析器很重要并且需要维护,那么它确实很重要!如果你写一些“纯粹是无聊”的东西,我会建议它根本不重要,不。 :-)
  • 解析相对简单的文本文件的最佳方法是什么?

  • 好吧,我不知道你会喜欢我的回答。也许首先在这里阅读其他一些很好的答案。

    不,真的,继续。我会等待。

    啊,你回来了,放松了。让我们放松一下,好吗?

    Never write it in 'C' if you can do it in 'awk';
    Never do it in 'awk' if 'sed' can handle it;
    Never use 'sed' when 'tr' can do the job;
    Never invoke 'tr' when 'cat' is sufficient;
    Avoid using 'cat' whenever possible.
    -- Taylor's Laws of Programming



    如果您用 C 编写它,但 C 感觉像是错误的工具……它真的可能是错误的工具。 awkperl可能会在没有所有恶化的情况下做你想做的事情。您甚至可以使用 cut 来做到这一点。或类似的东西。

    另一方面,如果你用 C 编写它,你可能有一个很好的理由用 C 编写它。也许你的解析器是一个更大系统的一小部分,为了论证,它是嵌入的,在冰箱里,在月球上。或者你可能喜欢 C。你甚至可能讨厌 awkperl ,天诛地灭。

    如果你不讨厌awkperl ,您可能希望将它们嵌入到您的 C 程序中。原则上这是可行的——我自己从来没有做过。对于 awk , 试试 libmawk .对于 perl ,大概有几种方法(TMTOWTDI)。您可以运行 perl单独使用 popen启动它,或者您实际上可以将 Perl 解释器嵌入到您的 C 程序中——参见 man perlembed .

    无论如何,正如我所说,“解析的最佳方式”完全取决于您和您的团队、问题空间以及您解决问题的方法。我能提供的是我的意见。

    我将假设在您的纯 C 解决方案(库函数和 FSM(考虑您的 explode 本质上是一个库函数))中,您已经尽最大努力隔离相关代码、设计代码和文件嗯,等等。

    即便如此,我还是要推荐lexyacc .

    库函数感觉“笨拙而别扭”。状态机似乎无法维护。但是你说lexyacc觉得矫枉过正。

    我认为你应该以不同的方式处理你的投诉。你真正在做的是指定一个 FSM。但是,您还聘请了某人为您编写和维护它,从而解决了大部分可维护性问题。矫枉过正?我有没有提到他们会免费工作?

    我怀疑但不知道原因 lexyacc最初感觉有点矫枉过正,因为您的配置/简单文件也感觉太简单了。如果我是对的(如果我是对的),您可能可以在词法分析器中完成大部分工作。 (甚至可以想象,您可以在词法分析器中完成所有工作,但我对您的输入一无所知。)如果您的输入不仅简单而且广泛,您也许能够找到免费提供的词法分析器/解析器组合,用于什么你需要。

    简而言之:如果您不能在 C 中做到这一点,请尝试其他方法。如果你想要 C,请使用 lexyacc --它们有一点开销,但它们是一个非常好的解决方案。

    关于c - 解析:库函数、FSM、explode() 或 lex/yacc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5696769/

    相关文章:

    python - 使用 lxml.html 解析 HTML 时等价于 InnerHTML

    java - 使用斯坦福解析器给出的解析分数检查句子的语法

    c++ - memset() 导致数据中止

    c++ - 为什么在 C 中减去 '0' 会得到 char 代表的数字?

    directory - 如何使用 qsort 根据字节对包含路径名/文件的字符进行排序?

    java - 识别 JFlex 1.4.3 中的小数

    c - lex/yacc 项目编译时出现问题

    c - 错误编译内核模块 linux/module.h : No such file or directory found

    c# - 当前 JsonReader 项不是对象

    regex - Flex 中的非贪婪正则表达式匹配