2016-12-06 40 views
1

使用pyparsing我嘗試分析一些文本與複合式像pyparsing可以吐出導致ParseException的文本嗎?

a = pp.Word(pp.alphas).setResultsName('A') 
b = pp.Word(pp.nums).setResultsName('B') 
c = pp.Word(pp.alphas).setResultsName('C') 
expr = a + b + c 

parseString失敗,出現異常

ParseException: Expected W:(0123...) (at char 7), (line:1, col:8) 

到目前爲止好。但是,爲了更好地理解發生了什麼,是否可以詢問pyparsing/parseString直接告訴我什麼字符來自輸入字符串不匹配? (當然,我可以從例外文本中的信息中自行計算)

此外,有可能看到哪個子表達式(a,b或c)引發了異常?

回答

1

Pyparsing例外包括方法,markInputline()將打印輸入字符串的最後一行,並在異常發生標記:

import pyparsing as pp 
a = pp.Word(pp.alphas).setResultsName('A') 
b = pp.Word(pp.nums).setResultsName('B') 
c = pp.Word(pp.alphas).setResultsName('C') 
expr = a + b + c 
try: 
    expr.parseString("lskdjf lskdjf sdlkfj") 
except ParseException as pe: 
    print(pe.markInputline()) 

lskdjf >!<lskdjf sdlkfj 

(可以指定不同的標記,如果你不喜歡。「!> <」)

下面是我用另一種方法,它利用了山坳和ParseException的線屬性:

alphaword = pp.Word(pp.alphas).setName('alphaword') 
numword = pp.Word(pp.nums).setName('numword') 
expr = alphaword('A') + numword('B') + alphaword('C') 
try: 
    expr.parseString('sldkj slkdj sldkj') 
except ParseException as pe: 
    print(pe.line) 
    print(' '*(pe.col-1) + '^') 
    print(pe) 

sldkj slkdj sldkj 
    ^
Expected numword (at char 6), (line:1, col:7) 

幾個其他點:

  • 我用的setName()得到表達自己的名字,這樣的異常信息是有點更具可讀性。請注意setName和setResultsName之間的區別。

  • 我已經使用調用語法來定義結果名稱。在實踐中(或僅僅是懶惰),我發現'.setResultsName'方法調用實際上會損害代碼的語法定義部分。所以代替expr.setResultsName('xyz'),你可以寫expr('xyz')

+0

謝謝!像魅力一樣工作。 - 使用'setName'也不錯,但是編寫'.a.setname('A')','.b.setname('B')'和'.c.setname('C' )'......如果ParserElement'對象可以檢查它所引用的變量名 - 這很好,但是在Python中這不太可能...... – halloleo

+0

記住,爲表達式保留setName(在這個例子中,只是字母和numword),每次使用時都不需要調用它。但是,是的,我研究了自動調用表達式的各種選項,包括回想調用堆棧和檢查包含賦值的行,但它們都相當危險,在版本或Python實現中不可靠。祝你好運! – PaulMcG

相關問題