5

如果我有不正确的术语,请原谅我;也许仅仅用“正确”的词来描述我想要的就足以让我自己找到答案。

我正在开发 ODL(对象描述语言)的解析器,据我所知,这是一种神秘的语言,现在只有 NASA PDS(行星数据系统;这是 NASA 向公众提供其数据的方式)使用。幸运的是,PDS 终于转向 XML,但我仍然必须为在截止日期前落下的任务编写软件。

ODL 以类似以下方式定义对象:

OBJECT              = TABLE
  ROWS              = 128
  ROW_BYTES         = 512 
END_OBJECT          = TABLE

我正在尝试使用 编写解析器pyparsing,并且在进行上述构造之前我做得很好。

我必须创建一些规则,以确保 OBJECT 行的右侧值与 END_OBJECT 的 RHV 相同。但我似乎无法将其纳入pyparsing规则。我可以确保两者都是语法上有效的值,但我不能采取额外的步骤来确保值相同。

  1. 我的直觉是否正确,这是一种上下文相关的语法?这是我应该用来描述这个问题的短语吗?
  2. 无论是理论上的哪种语法,都pyparsing能够处理这种结构吗?
  3. 如果pyparsing无法处理它,是否有另一个 Python 工具能够这样做?怎么样( /ply的 Python 实现)?lexyacc
4

2 回答 2

6

它实际上是一种上下文敏感语言的语法,经典地抽象为wcww 在 (a|b)* 中的位置(请注意wcw''表示反转的,是上下文无关的)。

解析表达式语法能够通过使用语义谓词来解析 wcw 类型的语言。PyParsing 为此目的提供了matchPreviousExpr()matchPreviousLiteral()辅助方法,例如

w = Word("ab")
s = w + "c" + matchPreviousExpr(w)

所以在你的情况下,你可能会做类似的事情

table_name = Word(alphas, alphanums)
object = Literal("OBJECT") + "=" + table_name + ... +
  Literal("END_OBJECT") + "=" +matchPreviousExpr(table_name)
于 2013-02-27T04:23:25.257 回答
3

作为一般规则,解析器被构建为上下文无关的解析引擎。如果存在上下文敏感性,则在解析后(或至少在相关解析步骤完成后)进行嫁接。

在您的情况下,您想编写上下文无关的语法规则:

  head = 'OBJECT' '=' IDENTIFIER ;
  tail = 'END_OBJECT'  '=' IDENTIFIER ;
  element = IDENTIFIER '=' value ;
  element_list = element ;
  element_list = element_list element ;
  block = head element_list tail ;

检查头部和尾部构造是否具有匹配的标识符在技术上不是由解析器完成的。

然而,许多解析器允许在识别句法元素时发生语义动作,通常是为了构建树节点。在您的情况下,您希望使用它来启用额外的检查。对于element,您要确保IDENTIFIER不是块中已有内容的副本;这意味着对于遇到的每个元素,您都需要捕获相应的IDENTIFIER并制作一个特定于块的列表以启用重复检查。对于块,您要捕获头部*IDENTIFIER*,并检查它是否与尾部*IDENTIFIER* 匹配。

如果您在进行过程中构建表示解析的树,并将各种上下文相关值挂在树上的各个位置(例如,将实际IDENTIFIER值附加到head子句的树节点),这是最简单的。在为尾部构造构建树节点时,应该很简单地沿着树向上走,找到树,然后比较标识符。

如果您想象首先构建整个树,然后对树进行后处理传递来进行此检查,那么这更容易考虑。懒惰的人实际上是这样做的:-} 我们所做的只是将可以在后处理步骤中完成的工作推入附加到语义动作的树构建步骤中。

这些概念都不是特定于 python 的,PyParsing 的细节会有所不同。

于 2013-02-27T03:47:58.563 回答