-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AST parent pointer implementation #147
Conversation
b283e70
to
fb6face
Compare
1b8817d
to
7a626dd
Compare
Slightly unfortunate this approach means you lose the type of the parent and have to use a broad |
Yea this was one of the trade offs vs having to manipulate the existing AST and storing the parents in the AST. But I agree that the specific concrete type of the parent should be returned. Will make some changes. |
@SebastienGllmt updated to abstract the let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
let pv = ParentVisitor::new(&cddl).unwrap();
let rule = cddl.rules.first().unwrap();
assert_eq!(rule.parent(&pv).unwrap(), &cddl); Parent trait definition: pub trait Parent<'a, 'b: 'a, T> {
fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&T>;
} In situations where certain AST nodes can have different parent types based on context, you'll need to manually cast ... so for example: let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
let pv = ParentVisitor::new(&cddl).unwrap();
if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
let parent: &TypeRule = rule.name.parent(&pv).unwrap();
assert_eq!(parent, rule);
} ... the rule name's ident vs. let cddl = cddl_from_str(
r#"
terminal-color = &basecolors
basecolors = (
black: 0, red: 1, green: 2, yellow: 3,
blue: 4, magenta: 5, cyan: 6, white: 7,
)
"#,
true,
)
.unwrap();
let pv = ParentVisitor::new(&cddl).unwrap();
if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
if let t2 @ Type2::ChoiceFromGroup { ident, .. } =
&rule.value.type_choices.first().unwrap().type1.type2
{
let parent: &Type2 = ident.parent(&pv).unwrap();
assert_eq!(parent, t2);
}
} ... wherein the ident |
a2a8e77
to
6e78e23
Compare
@SebastienGllmt PR is ready for final review and merge |
d7dc14f
to
c0c7765
Compare
I think you forgot Also, CtlOp has a |
7a6259e
to
d0e2b76
Compare
@SebastienGllmt |
70a3e08
to
2c271dd
Compare
@SebastienGllmt this is ready to merge |
LGTM. Integration worked as expected so far in our codebase 👍 |
6e1dc6e
to
8a3cabd
Compare
Implements #150.
Based on the work started by @SebastienGllmt in #134. Removes
parent
fields from the AST in favor of a rudimentary "arena" implementation which negates the need for AST manipulation. Introduces aParentVisitor
which houses the arena tree and implements theVisitor
. Also introduces aCDDLType
enum which holds all of the different AST nodes.ParentVisitor
andCDDLType
can be used as follows to identify an AST node's parent:You can also walk up the parent tree by recursively calling
parent()
on the returnedCDDLType
as follows:In the example above, the
TypeRule
's parent's parent is the mainCDDL
struct itself.CDDLType::From
has also been implemented for all of the AST types.@SebastienGllmt let me know if this API works for you.