Create mixins from a list of strings

Philippe Sigaud philippe.sigaud at gmail.com
Sat Jan 11 08:07:20 PST 2014


On Sat, Jan 11, 2014 at 2:34 PM,  <"Casper Færgemand\"
<shorttail at hotmail.com>"@puremagic.com> wrote:
> On Saturday, 11 January 2014 at 09:17:34 UTC, Philippe Sigaud wrote:
>>
>>         case "Gramm.Expr":
>>             return foo(t);
>>         case "Gramm.FunctionCall":
>>             return foo(t);
>>         case "Gramm.Declaration":
>>             return foo(t);
>>         default:
>>             throw new Exception("...");
>
>
> I can't do this since there will be multiple rules with the same name that
> require different treatment. The reason I want to use semantic actions is
> that I don't want to push an already heavy grammar into double or triple
> size just to name specific rules in a certain way. Semantic actions take up
> very little space and fit nicely into the syntax.

OK, fair enough.

I'm a bit leery of putting D call syntax into semantic actions,
because it'll also explode the Pegged grammar size (I'm fairly sure
I'd have to pull in a big part of D if I want to get function calls
right). That's one feature I wanted at one time, but I'm not sure it's
a good idea.

OTOH, you can define a templated semantic action:

template foo(string s, int i)
{
    T foo(T)(T t)
    {
        writeln("Calling foo");
        t.name ~= s ~ to!string(i);
        return t;
    }
}


And then invoke it with a parameter:

mixin(grammar(`
Test:
    A <- B { foo!("abc",1) } C { foo!("def",2) }
    B <- 'b'
    C <- 'c'
`));

I did not test it thoroughly, so I'm not sure every template parameter
combination is OK. It's probably better not to have curly braces
inside the arg list.


Pegged also authorize anonymous functions as semantic actions:

https://github.com/PhilippeSigaud/Pegged/wiki/Semantic-Actions#anonymous-functions-as-actions

Maybe that could be another solution. Something like B { p => foo(arg1, p) }

Note that closures are not (yet) supported in CTFE, because else
another solution would be a function-returning function:

auto bar(string s, int i)
{
    return
        (ParseTree p) {
            p.name ~= s ~ to!string(i);
            return p;
        };
}



More information about the Digitalmars-d-learn mailing list