gpt4 book ai didi

python - pyparsing:忽略注释时,parseAll=True 不会抛出 ParseException

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:04 25 4
gpt4 key购买 nike

我注意到 pyparsing 中有一个奇怪的副作用:

在解析器的超集上使用 .ignore() 时,parseString(..., parseAll = True) 会停止检查注释符号处的整个字符串。用下面的代码更好地解释。

如何在不使用 stringEnd 的情况下解决这个问题?

例子:

def test():        
import pyparsing as p
unquoted_exclude = "\\\"" + "':/|<>,;#"
unquoted_chars = ''.join(set(p.printables) - set(unquoted_exclude))
unquotedkey = p.Word(unquoted_chars)

more = p.OneOrMore(unquotedkey)
more.ignore("#" + p.restOfLine)
# ^^ "more" should ignore comments, but not "unquotedkey" !!

def parse(parser, input_, parseAll=True):
try:
print input_
print parser.parseString(input_, parseAll).asList()
except Exception as err:
print err


parse(unquotedkey, "abc#d")
parse(unquotedkey, "abc|d")

withstringend = unquotedkey + p.stringEnd
parse(withstringend, "abc#d", False)
parse(withstringend, "abc|d", False)

输出:

abc#d     
['abc'] <--- should throw an exception but does not
abc|d
Expected end of text (at char 3), (line:1, col:4)
abc#d
Expected stringEnd (at char 3), (line:1, col:4)
abc|d
Expected stringEnd (at char 3), (line:1, col:4)

最佳答案

为了比较苹果与苹果,你还应该在定义 withstringend 之后添加这一行:

withstringend.ignore('#' + p.restOfLine)

我想您会发现它与您使用 unquotedKey 进行解析的测试具有相同的行为。

ignore 的目的是在解析的输入文本中任何地方 忽略构造,而不仅仅是在最顶层。例如,在 C 程序中,您不只是忽略语句之间的注释:

/* add one to x */
x ++;

您还必须忽略可能出现在任何地方的评论:

x /* this is a post-increment 
so it really won't add 1 to x until after the
statement executes */ ++
/* and this is the trailing semicolon
for the previous statement -> */;

或者也许不那么做作:

for (x = ptr; /* start at ptr */
*x; /* keep going as long as we point to non-zero */
x++ /* add one to x */ )

因此,为了支持这一点,ignore() 被实现为递归遍历整个定义的解析器,并更新整个解析器中每个子解析器上的可忽略表达式列表,以便在整个解析器的每个级别。另一种方法是在整个解析器定义中散布对 ignore 的调用,并不断尝试找出那些被意外跳过的调用。

所以在你的第一个案例中,当你这样做的时候:

more = p.OneOrMore(unquotedKey)
more.ignore('#' + p.restOfline)

您还更新了 unquotedKey 的可忽略项。如果你想隔离 unquotedKey 以便它不会产生这种副作用,那么定义 more 使用:

more = p.OneOrMore(unquotedKey.copy())

还有一点 - 您通过将键定义为“可打印文件中除这些特殊字符之外的所有内容”来定义不带引号的键。您使用的技术在版本 1.5.6 之前一直很好,当时 excludeChars 参数被添加到 Word 类。现在您不必费力地构建仅包含允许字符的列表,您可以让 Word 来完成这项工作。尝试:

unquotedKey = p.Word(p.printables,
excludeChars = r'\"' + "':/|<>,;#")

关于python - pyparsing:忽略注释时,parseAll=True 不会抛出 ParseException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24944975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com