【发布时间】: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 << (all_hints | comment_in_hint) + ZeroOrMore(grammar)。你也可以更简单地写成grammar = ZeroOrMore(all_hints | comment_in_hint)- 不需要递归定义。
标签: sql comments pyparsing recursive-datastructures hints