如何处理解析器中的反向引用?

How to handle back references in a parser?

我正在开发 XAML 解析器。我想尽可能context-free。

你知道 XAML 类似于普通的 XML,但考虑到属性和可扩展性(值转换、模板、标记扩展、元素之间的命名引用...)

目前,我遇到了一个大问题:XAML规范允许节点被命名并且通常有属性可以依赖那些名字.

考虑这个 XAML:

<Parent x:Name="MyParent">
   <Setter Target="MyParent.Background" Value="Red" />
</Parent>

在此代码段中,您可以看到 Target 属性 必须 "wait" 直到创建 Parent 才能传递值。等待的概念对我来说听起来像是一个任务(一个承诺),可能会在以后解决,但它看起来很复杂,而且可能有点矫枉过正。

为了理解这个问题,重要的是要注意,作为一个设计决定,我让我的解析器在 parent 之前 膨胀 children 元素元素。

例如:

<Parent>
   <Child1/>
   <Child2/>
</Parent>

Child1Child2 实例在创建 Parent 实例之前完全初始化。

既然我已经解释了它是如何工作的,那么我该如何处理节点之间的那些引用呢?来自 parent => child 的引用将起作用,但不是相反,因为 parent 是在它们的所有 children 之后创建的。

与任何编译器相同:当您看到对尚未定义的任何给定标识符 Foo 的引用时,将对象粘贴到字典中。该对象在字典中位于 "Foo" 下,并具有对引用 Foo 的位置的引用列表。

定义完所有内容后,返回该词典并填写所有参考资料。如果缺少任何内容,请发出错误。如果任何标识符在此过程中以相同的名称 space 被定义两次,则发出错误。如果 Foo 只定义了一次,但其类型不适合引用它,则发出错误。

一旦你在你使用的任何中间结构中得到了所有的东西,将中间结构交给代码来完成最后的传递并生成你的UI、字节码、二进制或任何。

如果您可以拥有多个示波器(如果您不是在编写玩具,您就会拥有),这会变得更加复杂。您需要每个作用域有一个标识符字典,并将它们挂在解析树之外,以便代码生成器在进行时获取。