On Sat, Jan 11, 2014 at 2:34 PM, <"Casper Færgemand\" <shortt...@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; }; }