编辑:我做了第一个版本,Eike帮助我在其上进行了一些改进。我现在坚持一个更具体的问题,我将描述下面的内容。您可以在history用pyparsing改善错误信息
我使用pyparsing解析用于从数据库中请求特定数据的小语一看原来的问题。它具有许多关键字,运算符和数据类型以及布尔逻辑。
我试图改进发送给用户的错误消息,因为当前语法错误并不是非常有用。我设计了一个小例子,类似于我的语言,但上述小得多做:
#!/usr/bin/env python
from pyparsing import *
def validate_number(s, loc, tokens):
if int(tokens[0]) != 0:
raise ParseFatalException(s, loc, "number musth be 0")
def fail(s, loc, tokens):
raise ParseFatalException(s, loc, "Unknown token %s" % tokens[0])
def fail_value(s, loc, expr, err):
raise ParseFatalException(s, loc, "Wrong value")
number = Word(nums).setParseAction(validate_number).setFailAction(fail_value)
operator = Literal("=")
error = Word(alphas).setParseAction(fail)
rules = MatchFirst([
Literal('x') + operator + number,
])
rules = operatorPrecedence(rules | error , [
(Literal("and"), 2, opAssoc.RIGHT),
])
def try_parse(expression):
try:
rules.parseString(expression, parseAll=True)
except Exception as e:
msg = str(e)
print("%s: %s" % (msg, expression))
print(" " * (len("%s: " % msg) + (e.loc)) + "^^^")
所以基本上,唯一的东西,我们可以用这种语言做的,是写系列x = 0
,结合在一起与and
和括号。
现在,有些情况下,当使用and
和括号时,错误报告不太好。请看下面的例子:
>>> try_parse("x = a and x = 0") # This one is actually good!
Wrong value (at char 4), (line:1, col:5): x = a and x = 0
^^^
>>> try_parse("x = 0 and x = a")
Expected end of text (at char 6), (line:1, col:1): x = 0 and x = a
^^^
>>> try_parse("x = 0 and (x = 0 and (x = 0 and (x = a)))")
Expected end of text (at char 6), (line:1, col:1): x = 0 and (x = 0 and (x = 0 and (x = a)))
^^^
>>> try_parse("x = 0 and (x = 0 and (x = 0 and (x = 0)))")
Expected end of text (at char 6), (line:1, col:1): x = 0 and (x = 0 and (x = 0 and (xxxxxxxx = 0)))
^^^
事实上,看来,如果分析器无法解析(和解析这里是重要的)一个and
后的东西,它不会再产生良好的错误信息: (
我的意思是解析,因为如果它可以解析5,但“验证”的解析动作失败了,但它仍然产生了良好的错误消息。但是,如果它不能解析一个有效的数字(如a
)或有效的关键字(如xxxxxx
),它会停止生产清除正确的错误信息。
有什么想法?
有变量名也有验证的解析动作。或者像“Word(alphas)”那样捕获所有变量名称,并对其进行解析操作,这总是会引发异常。 – Eike 2013-04-09 12:38:39
另外,你可以做一级验证。有一个解析器'Word(alphas) - “==” - Word(nums)'并且在其上放置一个更复杂的解析操作,它查找合法的变量名称,并确保数字的正确性。 – Eike 2013-04-09 14:02:37
目前,这将是最后的解决方案:) – 2013-04-09 14:09:43