gpt4 book ai didi

scala - 动态创建 parboiled2 规则

转载 作者:行者123 更新时间:2023-12-01 09:42:53 28 4
gpt4 key购买 nike

我可以在 parboiled2 解析器中动态生成规则吗?用例是我已经定义了一堆规则,但想添加更多而不是每次添加规则时都编译。

最佳答案

如果您想在运行时生成规则(就像您在 Parboiled1 中所做的那样),这是不可能的。 Parboiled 2 使用宏表达式,因此您无法在运行时生成规则。所有的事情都发生在编译阶段。

如果您有许多已定义的规则,并希望以任意顺序组合它们,即使其中一些缺失。这是可能的。我做到了。

有两个已知选项,如何实现:

第一个选项(我还没有尝试过)称为 DynamicRuleDispatch,您可以在 documentation 中找到它看看它的测试 here .

第二种选择是手动执行调度(就像我所做的那样)。

  1. 您应该创建一组可以动态组合的规则。这些规则必须具有 Rule0 类型。它们不应该影响值(value)堆栈。在规则评估之后,向这些规则添加副作用。副作用操作必须将捕获的数据保存在解析器状态内的某个位置。你应该使用 capture + ~ + run bundle 来实现这个,看下面的示例:

    def RuleWithSideEffect = 规则 { 捕获(电子邮件地址)〜运行{地址:字符串=> saveItSomewhere(地址) } ~ 意向书

  2. 您需要在解析器中创建某种可变状态。一个可以保存解析结果的保存位置。它可以是 HashMap 。此 Hashmap 应存储所有可能的规则及其值。您不能使用值堆栈,因为您无法确定匹配规则的数量。维护可变状态时要小心。每次通话后必须清洁它。

  3. 您需要一种规则对齐格式来对齐规则。例如:

    class Parser(input: ParserInput, format: String) extends Parser....

然后您需要解析格式字符串并获取格式标记。使用模式匹配将相应格式标记的列表分派(dispatch)给下面的 Rule0 字段 dispatchRule 方法。然后将字符串标记列表映射到规则。

当您有规则列表时,您需要执行以下操作:

// concatenates two rules. Must be inside rule block
def concatRules(f: Rule0, s: Rule0): Rule0 = rule {
f ~ s
}

val rootRule =
stringTokens map dispatchRule reduce concatRules

def RootRule: Rule0 = rule { mainRule ~ EOI }

def dispatchRule(token: String): Rule0 = match token {
case "DATE" => DateParser.DateRule
....
}

您可以通过在解析器构造函数中使用 logformat 来解析生成器访问日志。因此,您需要某种数据模型来匹配规则。

关于scala - 动态创建 parboiled2 规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32615256/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com