【问题标题】:Pyparsing: How to parse SQL HintsPyparsing:如何解析 SQL 提示
【发布时间】:2016-05-11 19:49:41
【问题描述】:

我正在尝试解析下面的 EBNF(在代码中注释)并且我正在努力解决可选 cmets 的 STRING 部分..(作为我的测试字符串中的额外注释编写)

 from pyparsing import *

# SQL HINT EBNF 
'''
{ /*+ hint [ string ]
      [ hint [ string ] ]... */
| --+ hint [ string ]
      [ hint [ string ]...
}
'''

test_string = "/*+ALL_ROWS extra comment FIRST_ROWS CACHE*/"

LCOMMENT = Literal("/*+")
RCOMMENT = Literal("*/")

grammar = Forward()

hint_all_rows = Literal("ALL_ROWS")
hint_first_rows = Literal("FIRST_ROWS")
hint_cache = Literal("CACHE")

comment_in_hint = Word(printables)

all_hints = (hint_all_rows | hint_first_rows | hint_cache)+ ZeroOrMore(comment_in_hint)

grammar <<  all_hints  + ZeroOrMore(grammar)

all_grammar = LCOMMENT + grammar + RCOMMENT

p = all_grammar.parseString(test_string)

print p

【问题讨论】:

  • "extra" 和 "comment" 不会出现在您的解析器中的任何位置,也没有任何像 Word(printables) 这样可以接受任何非空白字符组的包罗万象的类型元素。跨度>
  • 保罗,反应很快。现在我觉得没有把我的工作包括在内有点愚蠢! (如您所见,我不是经验丰富的 SO 用户..).. 我将使用 编辑我的 OP,正如您已经推测的那样,一个包罗万象的内容。但是,这会导致尾随的两个提示 FIRST_ROWS 和 CACHE 被捕获。
  • 我试图在编辑中输入测试但它没有显示(我想!)我在代码中添加了一个全部(comment_in_hint),但它很贪婪并且吃掉了结束注释括号(RCOMMENT )..
  • 要让事情正常进行,请更改为 comment_in_hint = Word(printables, excludeChars='*')。在某些时候,当您的评论包含嵌入的“*”字符时,这会失败,但这应该有助于您目前取得一些进展。
  • 我不会将comment_in_hint 合并为all_hints 的一部分。相反,让all_hints 只是定义的提示列表,但将grammar 更改为grammar &lt;&lt; (all_hints | comment_in_hint) + ZeroOrMore(grammar)。你也可以更简单地写成grammar = ZeroOrMore(all_hints | comment_in_hint) - 不需要递归定义。

标签: sql comments pyparsing recursive-datastructures hints


【解决方案1】:

感谢 Paul McGuire 在 OP 上的 cmets 中的帮助,现在运行的代码。最初在这里设置答案时,我确实摆脱了转发功能。但是通过将结果名称附加到不同的元素来检查代码,我注意到我在这里的第一个答案是将除第一个提示之外的所有内容分类为 cmets。因此,我保留了前锋,但利用了 Pauls 的一些其他建议。

from pyparsing import *

# SQL HINT EBNF
'''
{ /*+ hint [ string ]
      [ hint [ string ] ]... */
| --+ hint [ string ]
      [ hint [ string ]...
}
'''

LCOMMENT = Literal("/*+")
RCOMMENT = Literal("*/")

grammar = Forward()

hint_all_rows = Keyword("ALL_ROWS")
hint_first_rows = Keyword("FIRST_ROWS")
hint_cache = Keyword("CACHE")

comment_in_hint = Word(printables, excludeChars='*')

grammar = Forward()

all_hints = (hint_all_rows | hint_first_rows | hint_cache).setResultsName("Hints", listAllMatches=True) + Optional(comment_in_hint)("Comments*")

grammar << all_hints + ZeroOrMore(grammar)

all_grammar = LCOMMENT + grammar + RCOMMENT

p = all_grammar.parseString("/*+ ALL_ROWS aaaaaaa FIRST_ROWS bbbbb */")

print p["Hints"]

print p["Comments"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 2013-10-19
    相关资源
    最近更新 更多