1

我正在尝试解析下面的 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
4

1 回答 1

0

由于 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"]
于 2016-05-12T09:56:48.553 回答