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

时间:2017-03-27 14:03:48

标签: c# xaml parsing compiler-construction

我正在使用XAML解析器。我想尽可能无上下文。

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

目前,我遇到了一个大问题:XAML规范允许将节点命名为,并且通常有一些属性可以依赖于这些名称

考虑一下这个XAML:

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

在此代码段中,您可以看到Target属性必须等待&#34;等待&#34;直到创建Parent才能传递值。等待的概念听起来像一个可以在以后解决的任务(一个承诺),但它似乎很复杂,可能是一种矫枉过正。

要理解这个问题,重要的是要注意,作为一个设计决策,我让我的解析器在父元素之前强化儿童元素

例如:

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

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

现在我已经解释了它是如何工作的,我怎么能处理节点之间的那些引用呢?来自parent =&gt;的引用孩子会工作,但不是相反,因为父母是在他们所有的孩子都被创造之后创造的。

1 个答案:

答案 0 :(得分:4)

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

一旦定义了所有内容,请返回该字典并填写所有引用。如果有任何遗漏,请发出错误。如果在此过程中在同一名称空间中定义了两次标识符,则发出错误。如果Foo仅定义一次,但对于引用它是不合适的类型,则发出错误。

一旦你将所有这些东西放在你正在使用的任何中间结构中,就把中间结构交给最后一遍传递的代码,然后生成你的UI,字节码,二进制等等。

如果你可以拥有多个范围(如果你不是在写玩具,你会这样做),这会变得更加复杂。你需要为每个作用域都有一个标识符字典,并将它们从解析树中挂起,以便代码生成器随着它一起抓取。