【问题标题】:Instaparse ambiguity in ClojureClojure 中的 Instaparse 歧义
【发布时间】:2016-02-22 08:46:29
【问题描述】:

我在 insta 中遇到了一个模棱两可的解析问题。语法如下:

(def yip-shape
  (insta/parser
   (str/join "\n"
             ["S = ( list-item | heading | text-block )*"

              ;; lists and that
              "list-item = list-level <ws> anything"
              "list-level = #' {0,3}\\*'"

              ;; headings
              "heading = heading-level <ws> ( heading-keyword <ws> )? ( heading-date <ws> )? anything <eol?>"
              "heading-level = #'#{1,6}'"
              "heading-date = <'<'> #'[\\d-:]+' <'>'>"
              "heading-keyword = 'TODO' | 'DONE'"

              "text-block = anything*"

              "anything = #'.+'"
              "<eol> = '\\r'? '\\n'"
              "<ws> = #'\\s+'"])))

问题在于像## TODO Done 这样的标题 - 我可以理解为什么存在歧义,但我不确定解决它的最佳方法。 E.G

(insta/parses yip-shape "## TODO Done.")

生产:

([:S [:text-block [:anything "## TODO Done."]]] 
 [:S [:heading [:heading-level "##"] [:anything "TODO Done."]]] 
 [:S [:heading [:heading-level "##"] [:heading-keyword "TODO"] [:anything "Done."]]])

最后一个是我正在寻找的结果。如何最好地消除歧义并将结果缩小到该列表中的最后一个?

【问题讨论】:

    标签: parsing clojure ebnf instaparse


    【解决方案1】:

    语法用于解析结构化数据。如果您采用其他合理的语法并将“任何旧垃圾”规则放入其中,您将得到很多涉及任何旧垃圾的解析。解决歧义的方法是对“任何”规则中符合条件的内容更加严格,或者最好将其完全删除,而是实际解析那里的内容。

    【讨论】:

      【解决方案2】:

      一种选择是调整“anything”的正则表达式以允许任何字符except #。这样它只会吃掉文本直到下一个 # 字符。

      另一种选择是调整“anything”的正则表达式,以不允许将 # 作为第一个字符,并且不允许将换行符作为任何字符。也可能希望将文本块更改为 (anything | eol)*。所以在这种情况下,“任何东西”都会一直吃到换行符,基本上允许 textblock 一次处理一行文本。当您点击以 # 开头的行时,它不会被“任何东西”拾取,而是会被其他规则拾取。

      这实际上取决于您想要的行为,但这些是使您对“任何事物”的描述更准确的一些策略。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-29
        • 1970-01-01
        相关资源
        最近更新 更多