【问题标题】:Can a petitparser parser be reused safely?petitparser 解析器可以安全地重用吗?
【发布时间】:2020-02-28 21:18:19
【问题描述】:

在 Dart 中使用petitparser,可以复用解析器吗?

例如,假设我们要解析像 192.168.1.21 这样的 IPv4 样式地址。

最初,我写道:

final ipv4Part = digit().repeat(1, 3).flatten();
final ipv4Address = (ipv4Part &
        char('.') &
        ipv4Part &
        char('.') &
        ipv4Part &
        char('.') &
        ipv4Part)
    .flatten();
ipv4Address.parse('192.168.1.21');

我注意到我的序列解析器有 7 个孩子,正如预期的那样,但是数字解析器都是相同的(至少都具有相同的 hashCode),而点解析器却完全不同。尽管如此,解析器似乎可以工作。

我尝试过:

Parser ipv4Part() => digit().repeat(1, 3).flatten();
final ipv4Address = (ipv4Part() &
        char('.') &
        ipv4Part() &
        char('.') &
        ipv4Part() &
        char('.') &
        ipv4Part())
    .flatten();

在这个简单的情况下同样有效,但代价是增加了一些额外的 ()s 和一些内存中的对象。

有任何理由偏爱一种风格而不是另一种风格吗?有没有更好的写法?

我的第一次尝试成功是不是很幸运?如果我将所有finals 更改为返回Parser 的函数,那么我似乎采用了GrammarDefinition 的风格。我是否必须/应该在整个过程中使用ref(parser) 语法?

我的整体解析器是针对非递归语法的,目前我没有使用GrammarDefinition。到目前为止,当我认为我的语法中没有任何递归时,将我所做的重新修改为语法定义有什么好处?

【问题讨论】:

  • 我确信这不是重点,对于这种解析 IPv4 地址的特殊情况,我可能建议在自定义语法解析器上使用正则表达式。在我看来,除了教育目的之外,对于 IP 地址来说,这似乎有点过头了。
  • 如果你需要在 dart 中解析一个 ip 地址,你可以使用 InternetAddress 并捕获 ArgumentException

标签: dart petitparser


【解决方案1】:

是的,解析器可以(并且应该)被重用。解析器对象可以被视为知道如何解析特定语法的可配置函数。您可以调用(解析一些输入)并重用解析器,如 Dart 函数。

上面的任何一个例子都可以工作并且做同样的事情,第一个例子只是产生了一个更小的解析器图。使用GrammarDefinition 时,您应该使用ref,它适用于递归语法并自动重用解析器对象。在您的情况下,我将使用最初的示例,这似乎是最简洁的解决方案。

【讨论】:

    猜你喜欢
    • 2018-09-30
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多