If I have Grammar a
and define a Grammar b
that have a block '{ ... }' that has syntax of Grammar a
, is it possible to somehow link these grammars together? I.e. Grammar a
is Tcl and Grammar b
is embedded C. How does Rakudo do this when switching from Perl6 grammar to Regex grammar?
use Liz's-Answer;
answer Mine { ... }
say ?Mine if prompt 'Does that answer your question?' eq 'n' ;
answer Mine is B does Or-Perhaps-This does Or-Perhaps-That { }
role Or-Perhaps-This {
token baz { <Liz's-Answer::B::foo> }
}
role Or-Perhaps-That {
https://repl.it/@RalphMellor/Simple-slang
}
Liz's-Answer
Liz's initial answer wisely started at the beginning: declaring that a Raku grammar/role has one or more of its rules textually declared in another Raku grammar/role.
But then you edited your question to add:
I.e. Grammar
a
is Tcl and Grammarb
is embedded C.
It's pretty unlikely that it would make sense for grammars for c and tcl to textually share any rules. :)
Or-Perhaps-This
Another possibly relevant solution is to have a method within a grammar call another one in some other class. This can include a rule in one grammar calling a rule in another grammar.
This could be what you want for a tcl grammar/parser calling a c grammar/parser, or vice-versa, or both:
grammar c { ... }
grammar tcl {
rule TOP { ... }
...
rule block { 'c {' <c::TOP> '}' }
...
}
grammar c {
rule TOP { ... }
...
rule block { 'tcl {' <tcl::TOP> '}' }
...
}
Or-Perhaps-That
How does Rakudo do this when switching from Perl6 grammar to Regex grammar?
The above Or-Perhaps-This
example kept things simple. It hard coded the call from tcl to c, and vice-versa, and did not add any "userland" code that tracked that a switch had occurred.
What if one wanted to:
Have an arbitrary collection of languages calling into each other using the above Or-Perhaps-This
technique;
Be able to replace or tweak any grammar in the collection;
Be able to add a new one (in conjunction with replacing/modifying an existing one to call the new one);
Dynamically track precisely which grammar one is "in", in a dynamic/innermost sense, at any given time?
Also, what about that being the approach adopted for Raku itself, using its own grammar construct to define itself as a braid of languages?
This is indeed the approach adopted for Raku, and, in turn, nqp, via a feature called "slangs", short for "sub-languages".
While the Raku implemented in Rakudo is actually constructed using slangs, they are not an official feature. I'm sure they will be one day but it could easily be years.
In the meantime, I think the best I can provide is:
The repl.it example.
A link to SO's matching "[raku] slang".
Friendly advice: liberally apply the compiler optimization flag -Ofun
as you spelunk the compiler's code and maybe use Comma on Rakudo to figure out what's going on...
Grammars are really classes. So you can inherit from them. Or you can create a role and does
that in both Grammars.
role A {
token foo { bar }
}
grammar B does A {
... # other stuff
}
Does that answer your question?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With