[erlang-questions] erl_scan, erl_parse, macros and records
Fri Jun 17 13:11:01 CEST 2011
I can also whole-heartedly recommend parse_trans, and in particular
the exprecs module. You can see another usage of this in
and of the API for accessing record info in
- look at the function record_to_proplist/1, which is completely
generic in the type of the record and works with recursive record
Very useful stuff!
On 17 June 2011 07:42, Ulf Wiger <> wrote:
> This sounds in part similar to what the Diameter application (part of OTP
> R14B03) does.
> The Diameter application uses a parse_transform called diameter_exprecs,
> which is essentially the same as the exprecs module in
> For one thing, this allows users to work with record definitions generated
> at compile-time, without having to deal with include files. It also allows
> the diameter_service agent to check ubiquitous attributes like
> 'Destination-Host', 'Destination-Realm' in any record, as long as that
> record is known by the encode-decode ("dictionary") module:
> get_avp_value(Dict, Name, Rec)
> when is_tuple(Rec) ->
> Dict:'#get-'(Name, Rec)
> error:_ ->
> (from diameter/src/app/diameter_service.erl)
> Another thing that might help is parse_trans_codegen.erl, which provides a
> (IMHO) more readable way to generate code.
> The idea is that you simply wrap the code you want to generate in a fun(),
> possibly using some simple expansion techniques to import values, etc. If
> records are known at generation time, they can simply be included and used
> as-is, with normal record syntax.
> also https://github.com/esl/parse_trans/blob/master/examples/ex_codegen.erl for
> some (admittedly pretty corny) examples.
> Ulf W
> On 16 Jun 2011, at 21:48, Dan Kelley wrote:
> I'm working on a router of sorts. I'd like to have a config file which
> specifies how to classify messages, what channels are available, and routing
> rules based on classifications and channels.
> When my application starts, I'd like to transform the configuration into a
> module (let's call it 'router') so I can do someting like
> 'router:route(Message)'. Message will be a record that encapsulates a bunch
> of things about the message, and the returned value will be the channel to
> which the message should be delivered. The Message record is reasonably
> complicated - the top level thing contains several layers of different
> records. I also have a large number of macros that I use to extract
> different fields/subrecords of a top-level Message.
> When I started looking at how to do this, I quickly found erl_scan,
> erl_parse, and friends. I can easily create a module on the fly with these,
> but everything falls apart when I need to get at the Message record and
> macro definitions. Despite the access provided to compiler-ish things by
> erl_scan, erl_parse and friends, it looks like the only way to get at the
> preprocessor is to use epp on files. This is a problem because the code I
> want to dynamically create needs to use the record definitions and macros
> from the Message header file.
> Trying to figure a way around this led me to aleppo, which neatly solved the
> problem of including the header file, but aleppo doesn't process records.
> For a brief and exciting moment, it looked like erl_expand_records might
> save the day, but it expects forms, and I can't get anything with records
> through erl_parse:parse_form.
> Am I missing an easier way to dynamically create code that references macros
> and records?
> erlang-questions mailing list
> Ulf Wiger, CTO, Erlang Solutions, Ltd.
> erlang-questions mailing list
More information about the erlang-questions