我在pyparsing中定义了一种简单的语言。解析工作正常,但问题在于错误消息。他们显示的行号不对。我在这里展示代码的主要部分
communications = Group( Suppress(CaselessLiteral("communications")) + op + ZeroOrMore(communicationList) + cl + semicolon)
language = Suppress(CaselessLiteral("language")) + (CaselessLiteral("cpp")|CaselessLiteral("python")) + semicolon
componentContents = communications.setResultsName('communications') & language.setResultsName('language') & gui.setResultsName('gui') & options.setResultsName('options')
component = Suppress(CaselessLiteral("component")) + identifier.setResultsName("name") + op + componentContents.setResultsName("properties") + cl + semicolon
CDSL = idslImports.setResultsName("imports") + component.setResultsName("component")
它只在component
之前报告正确的行号,但是对于component
(即在componentContents中)中的任何错误,它只说组件开始的行号。例如,这是要解析的文本的示例
import "/robocomp/interfaces/IDSLs/Test.idsl";
Component publish
{
Communications
{
requires test;
implements test;
};
language python;
};
如果我错过了python;
或test之后的分号。它会说(line:4, col:1)
即在{
。你知道吗
这种行为是pyparsing的特征,而不是bug,需要特别小心处理(或解决)。你知道吗
当pyparsing无法匹配复杂表达式中的某个地方时,它会将其解析堆栈放回最后一个完全完整的表达式。您知道在匹配了“component”之后,后面的任何内容都应该是组件定义中的错误,但是pyparsing没有。因此,当在opening关键字之后发生故障时,pyparsing将备份并报告关键字表达式(包括关键字)无法匹配。你知道吗
当您有这样的命令语法时,关键字通常是明确的。例如,在匹配“component”之后,任何不是标识符,后跟括号中的参数列表的内容都将是一个错误。通过将“+”运算符替换为“-”运算符,可以指示pyparsing应该而不是备份过去的“component”。你知道吗
看看你的语法,我会备份并写一个简短的BNF(总是好的做法):
当语法中有关键字时,我总是建议使用
Keyword
或CaselessKeyword
,而不是Literal
或CaselessLiteral
。Literal
类不强制单词边界,因此如果我使用Literal("no")
作为语法的一部分,它可以匹配“not”或“none”或“nothing”等的前导“no”下面是我将如何处理这个BNF。(我将使用
setResultsName
的快捷版本,我发现这样可以使语法本身更清晰):分析示例组件时使用:
提供:
(顺便说一句,我喜欢使用“&;运算符对不同内容与pyparsing的
Each
类进行无序匹配—我认为这会使解析器更友好、更健壮。结果是Each
与“-”运算符有一点冲突,我必须在下一个版本中解决这个问题。)相关问题 更多 >
编程相关推荐