Thanks for the extensive reply! Yes, your example captures the gist of it. Unfortunately I think macro expansion during lexing would be impractical because macros are usually defined in header files that are often included by using a path that is dependent on the compile-time environment. For example, Erlang's xunit, eunit, has assertion macros that are normally included with:

The compiler then expects to find something on its path named eunit or eunit-<version> which must contain the include/eunit.hrl file.

I will have to think some more on it. As a start I'm going to use the parsing to figure out the arity of a function call and for that it's enough to be able to recognize ?foo(a)(b) as a single argument.


2013/11/2 David Engster <>
Thomas Järvstrand writes:
> Yeah, it turns out that it was the way I was using the rule that was causing
> the warning. The problem is that depending on the macro definitions that are
> present ?foo(bar) can mean either "replace this expression with the value of
> the parameterized macro foo(a)" or "replace foo with the value of the
> unparameterized macro foo and call the result as a function with the argument
> bar". I guess I'm going to have to build a pre-processor :-/

Aah, the joys of pre-processing. So if I understand you correctly, the
problem you have is equivalent to this in C/C++:

#define THEFUNC1 some_func
#define THEFUNC2(x) 5*(x)

a = THEFUNC1(3)  // --> a = some_func(3)
b = THEFUNC2(3)  // --> b = 5*(3)

Is this a correct description of your problem? If so, then Semantic can
already deal with this through lex-spp, which does preprocessing as part
of the lexing process. If you look at the definition of the C lexer,
you'll see that it includes special lexers like
`semantic-lex-cpp-define', which parses #define macro definitions, and
`semantic-lex-spp-replace-or-symbol-or-keyword', which checks whether a
symbol is actually a macro, expands it in-place and returns the correct
lexical tokens. You can try it out by putting point on the 'a' and run

((symbol 55 . 56)
 (punctuation 57 . 58)
 (symbol "some_func" 59 . 67)
 (semantic-list 67 . 70)
 (symbol 96 . 97)
 (punctuation 98 . 99)
 (number "5" 100 . 111)
 (punctuation "*" 100 . 111)
  #("(x)" 0 1
     (("x" number "3" 109 . 110))))
  100 . 111))

Handling the C/C++-preprocessor at the lexing stage is surprisingly
complex, which is why lex-spp is a large package; it might be overkill
for your use-case. But even if you don't end up using it, you might see
some hints there on how to deal with this problem.

Another possibility would be to not deal with this at the lexing stage,
but do it afterwards in the tag expansion. For instance, look at how
Semantic makes several tags out of things like

int a,b=5,c=3;

in semantic-expand-c-tag. This function could also do macro
expansion. It's really a matter of what would fit Erlang better (which I
know nothing of).