[erlang-questions] Reading comments/annotations inside parse_transforms
Richard Carlsson
carlsson.richard@REDACTED
Tue Jul 10 21:20:13 CEST 2012
On 07/05/2012 11:10 AM, Tim Watson wrote:
> There doesn't appear to be any way of doing this currently. There is
> support in erl_syntax for working with these and there is also an
> erl_comment_scan module in the syntax-tools application which parses
> and returns comments from a file (or whatever). What there doesn't
> appear to be, is a means to get erl_parse to return comments as
> attributes (?) in the AST that the compiler passes to a
> parse_transform.
>
> My question then, is this: what is the best (only!?) way to process
> comments at the same time as source code in a parse_transform? So far,
> given that this seems unlikely to work OOTB, I'm assuming I'll have to
> do something like:
>
> 1. once you hit the 'file' attribute, parse the comments and stash
> these away in a useful place
> 2. process the forms as usual, comparing each line number for each
> form, against the line numbers stored for the comments
> 3. when you get an interleaving of code and comments, you know where
> the comments reside in the source file in relation to the form you're
> currently working with
>
> I *can* do this of course, but it seems like an awful lot of hard
> work. Why can't comments be preserved in the AST passed to a parse
> transform, and then just dropped later on!? Is there an easier way of
> doing this that I'm currently missing?
The compiler toolchain just isn't targeted at preserving comments; they
are treated as whitespace and are discarded already at the tokenization
stage (erl_scan), even before the preprocessing stage (epp). After that,
there's the parsing stage, and then the parse transforms are called. So,
as you said, you'll need to use the -file("...") hints to locate the
source files and read them again to extract the comments.
It would certainly be possible to make a compiler that preserves
comments for later passes, but the way it's currently done is the
"traditional" way of writing a compiler, and changing it afterwards can
be difficult, since all the code that expects the current behaviour has
to be updated.
The good news is that the work of digging out comments and connecting
them to the abstract syntax trees has already been done, in the
syntax_tools library - EDoc uses exactly this (although not as a parse
transform). You can call erl_comment_scan:file/1 to get the comment
lines, and then use erl_recomment:recomment_forms/2 to attach the
comments to the abstract syntax trees that the parse transform got. The
result is a extended abstract syntax tree as defined by the erl_syntax
module. You can use the erl_syntax functions to manipulate the tree, and
when you're done, you need to call erl_syntax:revert/1 to revert the
representation to the form that the compiler understands (this loses the
comments again). For a detailed usage example, see edoc_extract:source/3
and friends.
/Richard
More information about the erlang-questions
mailing list