parse transform

Richard Carlsson richardc@REDACTED
Thu Aug 30 17:06:20 CEST 2001


On 30 Aug 2001, Luke Gorrie wrote:

> I want to write a parse transform to munge the arguments of calls to
> certain functions. To find all those functions, I'll need to recurse
> down all the expressions I find and so forth.
> 
> Is the best approach to cut-and-paste all of erl_id_trans and then
> insert my new clause, or is there some more elegant but similarly easy
> way?
>
> Something nice would be what's called a "visitor" in the object
> oriented world: something generic that would traverse the parse tree
> and call my module to see what I want to do with each node. For most
> nodes I'd just say "keep the structure and recursively process the
> children", but for calls I'd do something special.
> 
> Has anyone done something like that? If so, can I have a copy? :-)

If you check out the syntax_tools package at
http://www.erlang.org/user.html, the module 'erl_syntax' contains
functions to decompose any node in the syntax tree (subtrees/1), and
reconstruct it (make_tree/2) after visiting the subnodes.

Example (from the documentation in the source code):

	postorder(F, Tree) ->
	    F(case subtrees(Tree) of
		[] ->
		    Tree;
		List ->
		    copy_attrs(Tree,
		               make_tree(type(Tree),
			                 [[postorder(F, Subtree)
				           || Subtree <- Group]
			                  || Group <- List]))
	      end).

    maps the function `F' on `Tree' and all its subtrees, doing a
    post-order traversal of the syntax tree.

If you want to return the resulting tree to the compiler, you also need
to call revert/1 on it, since the standard library modules do not
understand the extended syntax tree format created by the erl_syntax
functions. (But you can feed "old-style" syntax trees directly to these
functions without prior conversion.)

If speed is of the absolute essence, you might want to modify
erl_id_trans instead, but the syntax_tools package makes it a lot
simpler to write this sort of thing:

-module(my_parse_transform).

-export([parse_transform/2]).

parse_transform(Forms, Options) ->
	Tree = do_stuff(Forms, Options),
	erl_syntax:revert_forms(Tree).

...etc.


	/Richard Carlsson


Richard Carlsson (richardc@REDACTED)   (This space intentionally left blank.)
E-mail: Richard.Carlsson@REDACTED	WWW: http://www.csd.uu.se/~richardc/




More information about the erlang-questions mailing list