【问题标题】:How to use PEGjs for validation, instead of parsing?如何使用 PEGjs 进行验证,而不是解析?
【发布时间】:2014-12-30 04:35:20
【问题描述】:

我有以下 PEGjs 作品:

NameStartChar = ":" / [A-Z] / "_" / [a-z] / [\u00C0-\u00D6] / [\u00D8-\u00F6] / [\u00F8-\u02FF] / [\u0370-\u037D] /
                [\u037F-\u1FFF] / [\u200C-\u200D] / [\u2070-\u218F] / [\u2C00-\u2FEF] / [\u3001-\uD7FF] /
                [\uF900-\uFDCF] / [\uFDF0-\uFFFD] / [\uD800-\uDB7F][\uDC00-\uDFFF]

NameChar = NameStartChar / "-" / "." / [0-9] / "\u00B7" / [\u0300-\u036F] / [\u203F-\u2040]

Name = NameStartChar NameChar*

如果我的输入字符串匹配Name,我想以某种方式获得true,否则获得false。我也不关心解析出组件部分。

但是,如果匹配失败,PEGjs 确实想抛出异常。

我当然可以将它包装在 try/catch 中,但我更愿意避免这种情况。而且我也想避免收集解析的组件(即,匹配"abcd"时我不需要["a", ["b", "c", "d"]],我只需要true)。

是否有一些隐藏的 PEGjs 功能可以使这项工作发挥作用?也许是一个聪明的动作,或者是对组合器的创新使用?

或者我应该使用完全不同的工具,而不是解析器生成器?如果是这样,有人知道我应该使用什么吗?

【问题讨论】:

    标签: pegjs


    【解决方案1】:

    我们可以使用Name { return true } / { return false } 来获得一个表达式,如果规则匹配则返回true。然后,我们可以添加!. 来检查我们是否在true 情况下的输入末尾,并且.* 在错误情况下跳到末尾。所以我们得到:

    ValidateName = Name !. { return true } / .* { return false }
    

    【讨论】:

      【解决方案2】:

      您定义的名称语言对我来说似乎是常规的,因此您可以使用正则表达式来实现。 根据您使用的语言,您可以调用函数 match 或 find 来测试您的输入。

      请记住放置开始和行尾锚点,以便它匹配整个输入,例如

      ^(:|[A-Z]|_|etc)(:|[A-Z]|_|etc|-|\.|[0-9]|etc)*$
      

      【讨论】:

      • 是的,确实如此,但我想在规范中重用现有的 BNF,而不是将它们转换为正则表达式语法。
      • @Domenic 也许这行得通(免责声明,因为我几乎没有使用 PEG 的经验):添加规则 TestName = Name / .* 在 / 的任一侧具有适当的语义操作。仅当不是名称时,右侧才应匹配任何内容。
      【解决方案3】:
      ValidateName = Name { return true } / { return false }
      

      如果您想在不使用子表达式推进解析器位置的情况下验证输入,您可以使用&Name

      【讨论】:

      • 这在 a! 上失败,它应该返回 false 但会引发错误。
      猜你喜欢
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2016-04-02
      相关资源
      最近更新 更多