代码之家  ›  专栏  ›  技术社区  ›  Henrik Paul

为什么在线解析器似乎停在regexps上?

  •  6
  • Henrik Paul  · 技术社区  · 16 年前

    我一直在想为什么没有任何解析器,比如, BNF ,其行为类似于各种库中的regexp。

    当然,有这样的事情 ANTLR , Yacc 还有很多其他的 生成代码 反过来,它可以分析 CFG 但似乎没有一个图书馆可以做到这一点而不需要中间步骤。

    我有兴趣写一篇 Packrat parser ,以引导所有与regexps相关的嵌套括号怪癖(也许更重要的是,对于它的运动),但不知何故,我有这样的感觉,我只是进入另一个暂停的问题-像沼泽类。

    这些解析器是否有技术/理论上的限制,或者我只是缺少一些东西?

    8 回复  |  直到 16 年前
        1
  •  4
  •   Dave    16 年前

    我觉得这更像是一种文化。上下文无关语法的使用主要局限于编译器,编译器通常具有与每个生产规则相关联的代码。在某些语言中,输出代码比模拟回调更容易。在另一些中,您将看到解析器库:例如,Haskell中的解析器组合器。另一方面,正则表达式在grep等工具中得到了广泛的使用,在这些工具中,每次用户提供新的正则表达式时都不方便运行C编译器。

        2
  •  2
  •   jheriko    16 年前

    Boost.Spirit 看起来像你在找什么。

    如果你想自己做,我就用 BNFC 对于我最新的编译器项目,它提供 the grammar used in its own implementation . 这可能是一个很好的起点…

        3
  •  2
  •   rndmcnlly    16 年前

    没有和技术/理论上的限制潜伏在阴影中。我不能说为什么它们不那么流行,但我知道至少有一个库提供了您所寻找的这种“在线”解析。

    SimpleParse 是一个python库,它允许您简单地将毛茸茸的ebnf语法粘贴到程序中,并立即使用它来解析内容,而不是执行ITerMediate步骤。我已经在几个项目中使用了它,在这些项目中我需要一种定制的输入语言,但实际上并不想提交到任何正式的构建过程中。

    下面是一个小小的例子:

    decl = r"""
        root := expr
        expr := term, ("|", term)*
        term := factor+
        factor := ("(" expr ")") / [a-z]
    """
    parser = Parser(decl) 
    success, trees, next = parser.parse("(a(b|def)|c)def")
    

    haskell和scala的解析器组合器库还允许您在使用它的同一块代码中表示解析器的语法。然而,你不能,比方说,让用户在运行时输入语法(这可能只对制作帮助人们理解语法的软件的人感兴趣)。

        4
  •  1
  •   PaulMcG    16 年前

    Pyparsing http://pyparsing.wikispaces.com )内置了对packrat解析的支持,它是纯Python,因此您可以看到实际的实现。

        5
  •  0
  •   Chris Lutz    16 年前

    因为全面的上下文无关语法已经足够令人困惑了,因为它们没有一些神秘的密集和不可理解的语法,使它们更加令人困惑?

    很难知道你在问什么。你是否试图创建一个类似正则表达式的东西,但是为了上下文无关的语法?比如,使用 $var =~ /expr = expr + expr/ (在Perl中)并进行匹配 "1 + 1" "1 + 1 + 1" "1 + 1 + 1 + 1 + 1 + ..." ?我认为这其中的一个限制是语法:超过三个规则将使你的“语法表达式”比任何现代的正则表达式更难以阅读。

        6
  •  0
  •   BCS    16 年前

    副作用是我看到的唯一能带给你的东西。大多数解析器生成器都包含用于处理的嵌入式代码,您将需要一个eval来实现这一点。

    解决这一问题的一种方法是命名操作,然后生成一个“action”函数,该函数使用要执行的操作的名称和要使用的参数。

        7
  •  0
  •   Zifre    16 年前

    理论上你可以用 Boost Spirit 在C++中,但它主要是针对静态语法编写的。我认为这种情况不常见的原因是CFG不像regex那样常用。除了编译器构造之外,我从未使用过语法,但我使用过很多次regex。cfg通常比regexs复杂得多,因此使用yacc或antlr之类的工具静态生成代码是有意义的。

        8
  •  0
  •   SingleNegationElimination    16 年前

    tcllib 有那样的东西,如果你能忍受的话 Parse Expression Grammars 还有TCL。如果Perl是你的东西,CPAN有 Parse::Earley . Here 这是一个纯粹的Perl变体,看起来很有前途。 PLY 对于python来说似乎是一个合理的解决方案

    推荐文章