Pyparsing:如何解析 SQL 提示

Pyparsing: How to parse SQL Hints

我正在尝试解析下面的 EBNF(在代码中有注释),我正在努力解析可选注释的 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

感谢 Paul McGuire 在 OP 的评论中提供的帮助,这是现在可以运行的代码。最初在这里设置答案时,我确实摆脱了转发功能。但是通过将结果名称附加到不同元素来检查代码,我注意到我在这里的第一个答案是将除第一个提示之外的所有提示都分类为注释。因此,我保留了前锋,但利用了 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"]