www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Understanding the AST...

reply joe <something example.com> writes:
Hello everybody!

Last week end I found this post ( 
https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/
) on the Blog and thought to myself awesome.

So I built the library and everything went smooth. Thanks for the 
effort of all the involved people who made that possible!

I've had a look at the 2 examples, too, the avg. function lines ( 
https://github.com/dlang/dmd/blob/master/src/examples/avg.d ) and 
the import ( 
https://github.com/dlang/dmd/blob/master/src/examples/impvisitor.d ) ones and
for a start I decided to make a program that prints the outline of a module.

Turns out I don't really understand how to access the data in the 
AST.
For everything there's a visitor method and overriding a few of 
them to print return statements and some such works as advertised.

However, I have no idea where I am in the tree when any of those 
methods are called.
Like for example in 
FunctionLengthVisitor(AST).visitFuncBody(AST.FuncDeclaration fd).
I have a function declaration object which tells me everything 
about what's inside the function, but how do I know what or where 
this function belongs to, where can I get that information ? I 
don't see anything about UDAs either, nor the doc comment.

I understand when visitor.getAvgLen is called with the parsed 
module, the accept function calls a visitor overload for each 
member.
But this sounds to me like I'd have to do a lot of book keeping 
in my visitor to keep track of things which are already present 
in the AST.

Any insight to this would be much appreciated :)
Feb 06
parent RazvanN <razvan.nitu1305 gmail.com> writes:
Hi Joe,

I suggest you watch this video which explains how the parse time 
visitors work: https://www.youtube.com/watch?v=tK072jcoWv4 .

On Tuesday, 6 February 2018 at 12:03:06 UTC, joe wrote:
 Hello everybody!

 Last week end I found this post ( 
 https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/
) on the Blog and thought to myself awesome.

 So I built the library and everything went smooth. Thanks for 
 the effort of all the involved people who made that possible!

 I've had a look at the 2 examples, too, the avg. function lines 
 ( https://github.com/dlang/dmd/blob/master/src/examples/avg.d ) 
 and the import ( 
 https://github.com/dlang/dmd/blob/master/src/examples/impvisitor.d ) ones and
for a start I decided to make a program that prints the outline of a module.

 Turns out I don't really understand how to access the data in 
 the AST.
 For everything there's a visitor method and overriding a few of 
 them to print return statements and some such works as 
 advertised.

 However, I have no idea where I am in the tree when any of 
 those methods are called.
 Like for example in 
 FunctionLengthVisitor(AST).visitFuncBody(AST.FuncDeclaration 
 fd).
 I have a function declaration object which tells me everything 
 about what's inside the function, but how do I know what or 
 where this function belongs to, where can I get that 
 information ? I don't see anything about UDAs either, nor the 
 doc comment.
The FuncDeclaration node contains all the information for that. For example, you can access fd.parent to see if the function is declared at top-level (in which case, the parent is going to be a module declaration ) or if it is a nested function (in a class, in a struct, in a function). Every AST node contains information about the position in the AST, all you have to do is find how to get that information: which field to access or which member function to call.
 I understand when visitor.getAvgLen is called with the parsed 
 module, the accept function calls a visitor overload for each 
 member.
 But this sounds to me like I'd have to do a lot of book keeping 
 in my visitor to keep track of things which are already present 
 in the AST.
The function average length visitor inherits a transitive visitor which means that the AST traversal logic is already implemented for you. All you have to do is override the visiting methods of interest and do whatever suits you : print stuff, alter the ast, stop the visitation or continue the visitation (by calling super.visit(ASTnode)).
 Any insight to this would be much appreciated :)
I know that my explanations might not be very explicit, but if you have an example please post it and we can work on it. Cheers, RazvanN
Feb 12