調(diào)試一個(gè)編譯器不是件容易的事情。PLY 提供了一些高級(jí)的調(diào)試能力,這是通過(guò) Python 的l ogging 模塊實(shí)現(xiàn)的,下面兩節(jié)介紹這一主題:
lex() 和 yacc() 命令都有調(diào)試模式,可以通過(guò) debug 標(biāo)識(shí)實(shí)現(xiàn):
lex.lex(debug=True)
yacc.yacc(debug=True)
正常情況下,調(diào)試不僅輸出標(biāo)準(zhǔn)錯(cuò)誤,對(duì)于 yacc(),還會(huì)給出 parser.out 文件。這些輸出可以通過(guò)提供 logging 對(duì)象來(lái)精細(xì)的控制。下面這個(gè)例子增加了對(duì)調(diào)試信息來(lái)源的輸出:
# Set up a logging object
import logging
logging.basicConfig(
level = logging.DEBUG,
filename = "parselog.txt",
filemode = "w",
format = "%(filename)10s:%(lineno)4d:%(message)s"
)
log = logging.getLogger()
lex.lex(debug=True,debuglog=log)
yacc.yacc(debug=True,debuglog=log)
如果你提供一個(gè)自定義的 logger,大量的調(diào)試信息可以通過(guò)分級(jí)來(lái)控制。典型的是將調(diào)試信息分為 DEBUG,INFO,或者 WARNING 三個(gè)級(jí)別。
PLY 的錯(cuò)誤和警告信息通過(guò)日志接口提供,可以從 errorlog 參數(shù)中傳入日志對(duì)象
lex.lex(errorlog=log)
yacc.yacc(errorlog=log)
如果想完全過(guò)濾掉警告信息,你除了可以使用帶級(jí)別過(guò)濾功能的日志對(duì)象,也可以使用 lex 和 yacc 模塊都內(nèi)建的 Nulllogger 對(duì)象。例如:
yacc.yacc(errorlog=yacc.NullLogger())
為分析器指定 debug 選項(xiàng),可以激活語(yǔ)法分析器的運(yùn)行時(shí)調(diào)試功能。這個(gè)選項(xiàng)可以是整數(shù)(表示對(duì)調(diào)試功能是開(kāi)還是關(guān)),也可以是 logger 對(duì)象。例如:
log = logging.getLogger()
parser.parse(input,debug=log)
如果傳入日志對(duì)象的話,你可以使用其級(jí)別過(guò)濾功能來(lái)控制內(nèi)容的輸出。INFO 級(jí)別用來(lái)產(chǎn)生歸約信息;DEBUG 級(jí)別會(huì)顯示分析棧的信息、移進(jìn)的標(biāo)記和其他詳細(xì)信息。ERROR 級(jí)別顯示分析過(guò)程中的錯(cuò)誤相關(guān)信息。
對(duì)于每個(gè)復(fù)雜的問(wèn)題,你應(yīng)該用日志對(duì)象,以便輸出重定向到文件中,進(jìn)而方便在執(zhí)行結(jié)束后檢查。