Clojure中的Instaparse歧义

时间:2016-02-22 08:46:29

标签: parsing clojure ebnf instaparse

我在insta中有一个模糊的解析问题。这是语法:

## TODO Done

问题在于(insta/parses yip-shape "## TODO Done.") 这样的标题 - 我能理解为什么存在模糊性,我只是不确定解决问题的最佳方法。 E.G

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

产地:

SELECT Number_of_Sent_emails, count(*)AS Number_of_Client_IDs
FROM (SELECT mel.CRM_CODE as client_ID, COUNT(mel.EMAIL) as Number_of_Sent_emails
      FROM dw.f_CRM_campaign_header mel 
          -- where    mel.TEMPLATE_NAME = 'cabin__et'
          --  and mel.SEND_DATE_FROM > '2016.02.17' 

        GROUP BY mel.CRM_CODE
     ) a
GROUP BY Number_of_Sent_emails
ORDER BY Number_of_Sent_emails;

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

2 个答案:

答案 0 :(得分:2)

语法用于解析结构化数据。如果你采用一种其他合理的语法并扔掉任何旧的垃圾"在它的规则中,你会得到很多涉及任何旧垃圾的解析。解决模糊性的方法是更严格地确定你的“任何事物”中的资格。规则,或者更好的是完全删除它,而是实际解析那里的东西。

答案 1 :(得分:0)

一个选项是调整正则表达式"任何"允许任何字符#。这样它只会占用文本直到下一个#字符。

另一个选择是调整正则表达式"任何"不允许#作为第一个字符,并且不允许换行作为任何字符。也可能想要将文本块更改为(任何| eol)*。所以在这种情况下"任何事情"将一直吃到换行符,基本上允许textblock一次处理一行文本。当你以#开头的一行时,它不会被#34;任何东西"但是会被其他规则所取代。

这实际上取决于你想要的行为,但这些是一些策略,用于描述"任何事情"更准确。