首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态创建parboiled2规则

动态创建parboiled2规则
EN

Stack Overflow用户
提问于 2015-09-17 01:41:47
回答 1查看 248关注 0票数 3

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

EN

回答 1

Stack Overflow用户

发布于 2016-01-08 18:47:48

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

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

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

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

第二个选项是手动执行分派(就像我做的那样)。

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

def RuleWithSideEffect = rule { capture(EmailAddress) ~ run { address: String => saveItSomewhere(address) }~EOI

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

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

类解析器(input: ParserInput,format: String)扩展了解析器....

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

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

代码语言:javascript
复制
// 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来解析生成器访问日志。因此,你需要一种数据模型来提升规则。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32615256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档