Skip to content
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

Visitor generation #51

Closed
woutersl opened this issue Apr 10, 2018 · 8 comments

Comments

@woutersl
Copy link
Member

commented Apr 10, 2018

Original report by Goomba (Bitbucket: 5a6bdc01c10afd5fcdd933bf, GitHub: raizam).


Hello! I needed to walk the AST tree using a generated IVisitor interface, so I added in the SDK a method to do so, here is the code (if interested) to be added somewhere in the generated namespace. It adds an IVisitor interface and an extension method Visit(IVisitor v) to ParseResult.

#!c#

        private void GenerateVisitor(StreamWriter stream)
        {
            stream.WriteLine("\t\t/// <summary>");
            stream.WriteLine("\t\t/// Visitor interface");
            stream.WriteLine("\t\t/// </summary>");
            stream.WriteLine("\t\tpublic interface IVisitor");
            stream.WriteLine("\t\t{");
            foreach (Variable var in variables)
            {
                if (var.Name.StartsWith(Grammar.PREFIX_GENERATED_VARIABLE))
                    continue;

                stream.WriteLine("\t\t\tvoid On{0}(ASTNode node);", Helper.ToUpperCamelCase(var.Name));
            }
            foreach (Virtual var in virtuals)
            {
                stream.WriteLine("\t\t\tvoid OnVirtual{0}(ASTNode node);", Helper.ToUpperCamelCase(var.Name));
            }
            stream.WriteLine("\t\t}");

            stream.WriteLine("\tpublic static class ParserHelper{");

            stream.WriteLine("\t\t/// <summary>");
            stream.WriteLine("\t\t/// Walk the AST using a visitor");
            stream.WriteLine("\t\t/// </summary>");
            stream.WriteLine("\t\tpublic static void Visit(this ParseResult result, IVisitor visitor)");
            stream.WriteLine("\t\t{");
            stream.WriteLine("\t\t\tVisitASTNode(result.Root, visitor);");
            stream.WriteLine("\t\t}");


            stream.WriteLine("\t\t/// <summary>");
            stream.WriteLine("\t\t/// Walk the AST using a visitor");
            stream.WriteLine("\t\t/// </summary>");
            stream.WriteLine("\t\tpublic static void VisitASTNode(ASTNode node, IVisitor visitor)");
            stream.WriteLine("\t\t{");

            stream.WriteLine("\t\t\tfor (int i = 0; i < node.Children.Count; i++)");
            stream.WriteLine("\t\t\t\tVisitASTNode(node.Children[i], visitor);");

            stream.WriteLine("\t\t\tswitch(node.Symbol.ID)");
            stream.WriteLine("\t\t\t{");
            foreach (Variable var in variables)
            {
                if (var.Name.StartsWith(Grammar.PREFIX_GENERATED_VARIABLE))
                    continue;

                   stream.WriteLine("\t\t\t\tcase 0x{1}: visitor.On{0}(node); break;", Helper.ToUpperCamelCase(var.Name), var.ID.ToString("X4"));
            }
            foreach (Virtual var in virtuals)
            {
                stream.WriteLine("\t\t\t\tcase 0x{1}: visitor.OnVirtual{0}(node); break;", Helper.ToUpperCamelCase(var.Name), var.ID.ToString("X4"));
            }
            stream.WriteLine("\t\t\t}");
           
            stream.WriteLine("\t\t}");

            stream.WriteLine("\t}");
        }

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Apr 10, 2018

Original comment by Goomba (Bitbucket: 5a6bdc01c10afd5fcdd933bf, GitHub: raizam).


I'm currently looking at the runtime library, feeling a little stuck.

I want to apply a Drop action to a terminal ASTNode "LABEL", while assigning to its parent its Value/TextPosition/Span.

OR apply a Promote action to the terminal ASTNode, and rename its symbol with the name of the parent its replacing

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Apr 12, 2018

Original comment by Laurent Wouters (Bitbucket: 557058:675792b6-d731-4823-9f7d-c6dfcb2df2b5, ).


Hello,

Thank you for your input. I will take it in consideration.

As to your question, if I understand correctly, you would like to replace a parent node with one of its children, except you want to retain the symbol (identifier and name) of the parent node, for example:

A (X Y="y" Z)

would yield

A="x" (X Z)

If my understanding is correct, there unfortunately cannot be achieved for two reasons. First, the promote action promotes the complete data of the node (the symbol, the text value, etc.). The reason is works likes this is due to the second reason : In the above case, a variable symbol is attached to the parent node and there is no way to attach a text value to a AST node with a variable. The way data is attached to an AST is a single value encoding the type of data, which can be either a variable, a virtual or a token. In the case of a token, the symbol the user can retrieved on the node corresponds to the terminal of the token and the textual value to that of the token. From this, it is impossible to represent a node with a variable symbol and a textual value, which would be the result of the case above.

I hope this explanation is clear !

I don't know what is your intended use case, but have you considered introducing virtual symbols? They can be useful as AST markers when you need to convey more information to the program that will walk through the AST.

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Apr 12, 2018

Original comment by Goomba (Bitbucket: 5a6bdc01c10afd5fcdd933bf, GitHub: raizam).


I did realize it's not possible while looking deeply into the code, but it's okay, this will just make my parser a little more verbose.

For the visitor I have removed the iteration part, which is from chids to parents, this order is very application specific, and I ended up parsing parents to childs.

I'd like to thank you for this library, this is very well done, the code is hard to understand but is very performant.

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

Original comment by Alexey Smirnov (Bitbucket: 5b4cb1f71fd8f72ca71b68ba, GitHub: RamyAlexis).


Any news with this?
I am interested too.

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

Original comment by Goomba (Bitbucket: 5a6bdc01c10afd5fcdd933bf, GitHub: raizam).


The code is right above if needed

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Aug 9, 2018

Original comment by Laurent Wouters (Bitbucket: 557058:675792b6-d731-4823-9f7d-c6dfcb2df2b5, ).


Sorry for the late reply, this feature is going to be integrated within the SDK, with some adaptations and a port for the Java and Rust code generator.
This should be available in the next release.

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Aug 9, 2018

Original comment by Laurent Wouters (Bitbucket: 557058:675792b6-d731-4823-9f7d-c6dfcb2df2b5, ).


Work is ongoing.

@woutersl

This comment has been minimized.

Copy link
Member Author

commented Aug 9, 2018

Original comment by Laurent Wouters (Bitbucket: 557058:675792b6-d731-4823-9f7d-c6dfcb2df2b5, ).


[fix] Fixed issue #51 Visitor generation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.