2016-12-06 43 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

相关问题