Python 解析异常中的行号错误

Python 解析异常中的行号错误,python,Python,我在pyparsing中定义了一种简单的语言。解析工作正常,但问题在于错误消息。他们显示了错误的线路号码。我在这里展示代码的主要部分 communications = Group( Suppress(CaselessLiteral("communications")) + op + ZeroOrMore(communicationList) + cl + semicolon) language = Suppress(CaselessLiteral("language")) + (Caseles

我在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")
它只在
组件
之前报告正确的行号,但是对于
组件
内部的任何错误(即在组件内容中),它只是说组件开始的行号。例如,这是要解析的文本示例

import "/robocomp/interfaces/IDSLs/Test.idsl";

Component publish
{
    Communications
    {
        requires test;
        implements test;
    };
    language python;
};

在这里,如果我错过了
python之后的分号或测试后。它会说
(第4行,第1列)
{

这种行为是pyparsing的特征,而不是一个bug,需要特别小心处理(或解决)

当pyparsing无法匹配复杂表达式中的某个位置时,它会将其解析堆栈放回最后一个完全完整的表达式替代项这之后的任何内容都应该是组件定义中的错误,但pyparsing不会。因此,当在打开关键字之后发生故障时,pyparsing将备份并报告关键字表达式(包括关键字)无法匹配

当您有这样的命令语法时,关键字通常是明确的。例如,在匹配“component”之后,任何不是标识符并后跟括号中的参数列表的内容都将是错误的。您可以通过将“+”运算符替换为“-”运算符来指示pyparsing不应备份“component”之前的内容

看看你的语法,我会备份并写一篇简短的BNF(总是很好的练习):

当语法中有关键字时,我总是建议使用
关键字
CaselessKeyword
,而不是
Literal
CaselessLiteral
Literal
类不强制单词边界,因此如果我使用
Literal(“否”)
作为语法的一部分,它可以匹配“not”或“none”或“nothing”等的前导“no”

下面是我如何处理这个BNF的。(我将使用
setResultsName
的快捷版本,我发现它使语法本身更加清晰。):

使用以下命令分析示例组件:

sample = """\
Component publish
{
    Communications
    {
        requires test;
        implements test;
    };
    language python;
};
"""

component.runTests([sample])
给出:

[['COMPONENT', 'publish', [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]]]
[0]:
  ['COMPONENT', 'publish', [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]]
  - name: 'publish'
  - properties: [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]
    - communications: [['REQUIRES', 'test'], ['IMPLEMENTS', 'test']]
      [0]:
        ['REQUIRES', 'test']
      [1]:
        ['IMPLEMENTS', 'test']
    - language: ['PYTHON']

(顺便说一句,我喜欢您使用“&”操作符将不同内容与pyparsing的
每个
类进行无序匹配-我认为这是一个更友好、更健壮的解析器。事实证明,
每个
都与“-”操作符有轻微冲突,我必须在下一版本中解决这个问题。)

谢谢,我以前尝试过
-
,但由于与
-
的冲突,它无法工作。一旦我删除
&
sample = """\
Component publish
{
    Communications
    {
        requires test;
        implements test;
    };
    language python;
};
"""

component.runTests([sample])
[['COMPONENT', 'publish', [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]]]
[0]:
  ['COMPONENT', 'publish', [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]]
  - name: 'publish'
  - properties: [[['REQUIRES', 'test'], ['IMPLEMENTS', 'test']], ['PYTHON']]
    - communications: [['REQUIRES', 'test'], ['IMPLEMENTS', 'test']]
      [0]:
        ['REQUIRES', 'test']
      [1]:
        ['IMPLEMENTS', 'test']
    - language: ['PYTHON']