How to handle backlinks in a parser?
I am working on a XAML parser. I would like to make it as context free as possible.
You know, XAML is like regular XML, but with properties and extensibility in the form (value mapping, templates, markup extension, named links between elements ...)
Currently, I have a big problem: the XAML spec allows nodes to be named and, as a rule, there are properties that can depend on those names .
Consider this XAML:
<Parent x:Name="MyParent">
<Setter Target="MyParent.Background" Value="Red" />
</Parent>
In this snippet, you can see that the property has Target
to "wait" until the parent is created to deliver the value. The concept of waiting sounds to me like a task (promise) that can be solved at a later time, but it seems complicated and might be overkill.
To understand the problem, it is important to note that as a design decision, I forced my parser to inflate the children to the parent elements.
For example:
<Parent>
<Child1/>
<Child2/>
</Parent>
Instances Child1
and are Child2
fully initialized before the parent is instantiated.
Now that I've explained how it works, how can I handle these links between nodes? Links from parent => child will work, but not the other way around, because the parents are created after all of their children.
source to share
The same as any compiler. When you see a link to any given identifier Foo
that is not yet defined, insert the object into the dictionary. The object is under "Foo" in the dictionary and has a list of point references to which it refers Foo
.
Once you've defined everything, go back through this dictionary and fill in all the links. If something is missing, please follow the error. If any identifiers are defined twice in the same namespace, submit an error. If Foo
defined only once, but is of the wrong type to reference it, throw an error.
Once you've got all of these things together in whatever staging structure you use, arm the staging structure to the code that makes the final pass and forms your UI, bytecode, Binary, or whatever.
If you can have multiple areas (and you will, if you don't write a toy), it gets more complicated. You will need to have one dictionary identifier for each scope and hang them out of the parse tree for the code generator to grab onto.
source to share