Pyparsing:快速参考解析器定义正确吗?

Pyparsing: Quick Reference parser definition correct?

我的工作方式:

Pyparsing Quick Reference, Chapter 3: Small Example -

示例解析器应该匹配有效的 Python 标识符,因此

'a_#'

应该是无效的,像作者评论的那样吧?但是,在页面底部:

---Test for 'a_#'
  Matches: ['a', '_']

解析器如下:

first = pp.Word(pp.alphas+"_", exact=1)
rest = pp.Word(pp.alphanums+"_")
identifier = first+pp.Optional(rest)

我不确定,所以在联系作者之前我想要一些反馈。

此外,我试图通过构建一个只接受整个字符串中定义的字符范围的解析器来纠正它,因此它不会匹配它的前缀。无法正确处理 - 有什么建议吗?

哎呀!使用两个 Word 建立一个标识符是浪费的、低效的,而且是糟糕的 pyparsing 实践。我认为作者这样做是为了展示如何在此处使用 Combine,但后记,他应该仅使用一个 Word 表达式来展示更好的替代方案。

Word 有一个双参数格式(清楚地描述 in the online docs)只是为了这种情况:

valid_ident_leading_chars = alphas + '_'
valid_ident_body_chars = alphanums + '_'
identifier = Word(valid_ident_leading_chars, valid_ident_body_chars)

(顺便说一句,这相当于:

identifier = Regex('['+valid_ident_leading_chars+']['+valid_ident_body_chars+']*')

如果您查看 pyparsing 代码,您会发现 Word 通过构建非常正则表达式来实现其匹配。)

这仍然会解析 'a_#' 的前导部分,与正则表达式一样。如果您希望您的测试因为未解析完整字符串而失败,请使用:

identifier.parseString('a_#', parseAll=True)

为了简化编写测试,您还可以使用“==”——当将 pyparsing 表达式与字符串进行比较时,表达式将 运行 expr.parseString(comparison_string, parseAll=True),并且 return True/False 取决于是否引发了 ParseException。

assert 'a_' == identifier    # <-- will pass
assert 'a_#' == identifier   # <-- will fail