科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件Python解析器程序库:DParser for Python简介

Python解析器程序库:DParser for Python简介

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文介绍Python 解析器DParser

作者:IBM.COM 来源:IBM.COM 2007年9月15日

关键字: 软件

  • 评论
  • 分享微博
  • 分享邮件
调试简介

DParser 可以显示调试信息的选项,这是我所喜欢的它的一个方面。观察这些信息并不是直观地创建正确语法所必需的,但是至少可以通过它洞察当处理特定的短语时解析器所采取的动作。例如:

清单 8. 展示对不确定结果的追踪

#------- Showing a trace of speculative productions

$ echo -n "alex alice benny carl dave" | ./abc2.py --debug

  d_words ???:

  d_A ???: alex

d_word ???: alex

  d_words ???:

 d_phrase ???: alex

  d_words ???: alex

  d_A ???: alice

d_word ???: alice

  d_words ???:

  d_words ???: alice

 d_phrase ???: alex alice

 d_phrase ???: alex alice

  d_words ???: alex alice

d_word ???: benny

 d_AB ???: alice benny

  d_words ???: benny

  d_words ???: alice benny

  d_words ???:

 d_phrase ???: alex alice benny

 d_phrase ???: alex alice benny

 d_phrase ???: alex alice benny

  d_words ???: alex alice benny

d_word: alex

  d_words: alex

  d_A: alice

 d_AB: alice benny

d_ABC ???: alice benny carl

  d_words ???:

 d_phrase ???: alex alice benny carl

d_ABC: alice benny carl

d_word ???: dave

  d_words ???: dave

 d_phrase ???: alex alice benny carl dave

d_word: dave

  d_words: dave

 d_phrase: alex alice benny carl dave

Head: alex

ABC: alice benny carl

Tail: dave

后面跟有问号的结果是推测性的尝试;那些后面其实没有最终的结果。与此相关, DParser 让您有能力当结果成为推测的或者是最终解析时采取不同的动作。默认情况下,函数体中的动作只作用于最终解析。不过,您可以向结果指定两个额外参数中的一个来处理推测性解析。(还有很多本文中没有讨论的选项参数。)

清单 9. 推测性解析过程中的动作

def d_prod1(t, spec_only):

'prod1 : this that+ other?'

print "Speculative parse of prod1"

def d_prod2(t, spec):

'prod2: spam* eggs toast'

if spec:

print "Speculative parse of prod2"

else:

print "Final parse of prod2"

当然,通过指定 dparser.Parser.parse() 的 print_debug_info 参数,我的推测性解析所显示的所有信息也都显示出来(以稍微不同的格式)。不过您也可以决定采取其他动作 —— 比如触发外部事件。

深入探讨优先级

我承认,前面 ABC 结果所使用的指定优先级有些不太正统。但是假如是简单含糊短语,则微调结束优先级是一个非常好的工具。让我来给出另一个关于简单含糊短语的语法:

清单 10. 逐项的二义性语法,ibm.py

def d_phrase(t, s):

'phrase : word ( vowel | caps | threeletter ) word'

print "Head:", ''.join(s[0])

print t[1][0]+":", ''.join(s[1])

print "Tail:", ''.join(s[2])

def d_word(t): 'word : "[A-Za-z]+" '

def d_vowel(t):

'vowel : "[AEIOUaeiou][A-Za-z]*"'

return 'VOWEL'

def d_caps(t):

'caps : "[A-Z]+"'

return 'CAPS'

def d_threeletter(t):

'threeletter : "[A-Za-z][A-Za-z][A-Za-z]"'

return '3LETT'

#-- Parse STDIN

from dparser import Parser

from sys import stdin

Parser().parse(stdin.read())

vowel、caps 和 threeletter 的结果不需要是确切的;它们全部都可以获取彼此有重叠的单词集合。例如:

清单 11. 当 DParser 得体地检测到含糊短语

$ echo -n "Read IBM developerWorks" | ./ibm.py

Traceback (most recent call last): [...]

dparser.AmbiguityException: [...]

当然,您可能幸运地使用了特定的短语:

清单 12. 幸运地避免了含糊短语的解析

$ echo -n "Read GNOSIS website" | ./ibm.py

Head: Read

CAPS: GNOSIS

Tail: website

不要满足于祈祷好运,让我们来显式地指定结果之间的优先级:

清单 13. 判定含糊的条件,ibm2.py

def d_vowel(t):

'vowel : "[AEIOUaeiou][A-Za-z]*" $term 3'

return 'VOWEL'

def d_caps(t):

'caps : "[A-Z]+" $term 2'

return 'CAPS'

def d_threeletter(t):

'threeletter : "[A-Za-z][A-Za-z][A-Za-z]" $term 1'

return '3LETT'

现在,每一个短语都将以特定的顺序识别出中间单词的类型(当然只是可能的那些):

清单 14. 无歧义的解析结果

$ echo -n "Read IBM developerWorks" | ./ibm2.py

Head: Read

VOWEL: IBM

Tail: developerWorks

$ echo -n "Read XYZ journal" | ./ibm2.py

Head: Read

CAPS: XYZ

Tail: journal

做出决定

尽管得到了一些读者的建议,我还是不太看重 DParser。它有很多可以作用于结果的强大的开关和选项,我还没有讨论到 —— 比如指定关联性。大体上,DParser 语言非常健壮,我非常怀疑用于 Python 的 DParser 是否会比纯粹的 Python 解析器运行速度快得非常多。

无论如何,我仍然不能对函数文档字符串风格的解析器具有太多热情。显然,关于这一点,很多优秀的 Python 程序员不会赞同我。此外我还发现一些解析结果有些令人不解:为什么调试模式下可以成功,而标准模式下却不能成功?含糊问题确切是什么时候发生的?使用任何解析工具开发语法都会有类似的意外,但是我发现 DParser 不知何故尤其出乎意料;例如 SimpleParse,就不会让我那么感到惊讶。可能,如果我了解了底层算法的更多复杂细节,它将会更具意义;不过,就我相对浅薄的学识而言,我可能与 95% 以上的读者差不多。有人比我更加熟悉解析;但是实际上大部分程序员懂得更少。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章