Is it possible to run a sub-grammar inside a grammar nqp?
Asked Answered
M

2

7

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?

Mercurous answered 11/5, 2020 at 9:54 Comment(1)
What's nqp got to do with this question? Are you talking about grammars in general?Hans
Q
6
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 Grammar b 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".

Slangs

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:

Queenie answered 11/5, 2020 at 12:23 Comment(2)
The %*LANG seem to be involved somehow. I'm digging around in In rakudos src/Perl6/Grammar.nqp and Perl6::Grammar::TOP adds self.define_slang(). But I cannot really follow how thethis works. Is there some NQP description somewhere? (ps also: how do you create a raku file at repl.it? )Mercurous
"how do you create a raku file at repl.it?" Try https://repl.it/languages/raku. Hopefully that'll work for you.Queenie
K
5

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?

Kenon answered 11/5, 2020 at 12:4 Comment(1)
Not exactly. What I meant is i.e. Grammar a is tcl and Grammar b is a embedded C block. Will update the textMercurous

© 2022 - 2024 — McMap. All rights reserved.