Scala 动态创建parboiled2规则

Scala 动态创建parboiled2规则,scala,parboiled2,Scala,Parboiled2,我可以在parboiled2解析器中动态生成规则吗?用例是,我已经定义了一堆规则,但希望添加更多,而不是每次添加规则时都进行编译 如果您想在运行时生成规则(就像您在Parboiled1中所做的那样),这是不可能的。Parboach 2正在使用marco表达式,因此无法在运行时生成规则。所有的事情都发生在编译阶段 如果您有许多已定义的规则,并且希望以任意顺序组合它们,即使其中一些规则缺失。这是可能的。我做到了 有两个已知的选项,您可以如何实现这一点: 第一个选项(我还没有尝试过)称为Dynamic

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

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

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

有两个已知的选项,您可以如何实现这一点:

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

第二个选项是手动生成分派(正如我所做的那样)

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

    def RuleWithSideEffect=规则{ 捕获(EmailAddress)~run{address:String=> saveItSomewhere(地址) }~EOI

  • 您需要在解析器内创建某种可变状态。保存解析结果的保存位置。可以是hashmap。此hashmap应存储所有可能的规则及其值。您不能使用值堆栈,因为您没有确定的匹配规则数。 在维护可变状态时要小心。每次调用后都必须清理它

  • 您需要规则对齐的格式来对齐规则。 例如:

    类解析器(输入:ParserInput,格式:String)扩展了解析器

  • 然后需要解析格式字符串并获取格式标记。 使用模式匹配将相应格式标记的列表分派给 下面的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来解析Generator访问日志。因此,您需要某种数据模型来验证规则。

    我认为它们大量使用宏,因此我假设您无法在运行时动态创建宏。
    添加更多,而不是每次添加规则时都进行编译。
    为什么重新编译会让您担心?