Можно ли запустить подграмматику внутри грамматики nqp?
Если у меня есть Grammar a
и определим Grammar b
которые имеют блок '{ ... }' с синтаксисом Grammar a
, можно ли как-то связать эти грамматики вместе? Т.е.Grammar a
это Tcl и Grammar b
встроен C. Как Rakudo делает это при переключении с грамматики Perl6 на грамматику Regex?
2 ответа
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
Первоначальный ответ Лиз разумно начался с самого начала: объявление, что грамматика / роль Раку имеет одно или несколько правил, текстуально объявленных в другой грамматике / роли Раку.
Но затем вы отредактировали свой вопрос, добавив:
Т.е. грамматика
a
это Tcl и грамматикаb
встроен C.
Маловероятно, что грамматикам для c и tcl будет иметь смысл текстуально разделять какие-либо правила.:)
Or-Perhaps-This
Другое возможное подходящее решение - иметь метод внутри грамматики, вызывающий другой метод в каком-то другом классе. Это может включать правило одной грамматики, вызывающее правило другой грамматики.
Это может быть то, что вы хотите для tcl-грамматики / парсера, вызывающего ac-грамматику / парсер, или наоборот, или и то, и другое:
grammar c { ... }
grammar tcl {
rule TOP { ... }
...
rule block { 'c {' <c::TOP> '}' }
...
}
grammar c {
rule TOP { ... }
...
rule block { 'tcl {' <tcl::TOP> '}' }
...
}
Or-Perhaps-That
Как Rakudo делает это при переключении с грамматики Perl6 на грамматику Regex?
Над Or-Perhaps-This
пример упростил задачу. Он жестко закодировал вызов с tcl на c и наоборот, и не добавлял никакого "пользовательского" кода, который отслеживал бы, что произошло переключение.
Что, если бы кто-то хотел:
Создайте произвольный набор языков, обращающихся друг к другу, используя указанное выше
Or-Perhaps-This
техника;Уметь заменять или настраивать любую грамматику в коллекции;
Иметь возможность добавить новый (в сочетании с заменой / изменением существующего для вызова нового);
Динамически отслеживать, в какой грамматике находится человек в динамическом / сокровенном смысле в любой момент времени?
Кроме того, что насчет подхода, принятого для самого Raku, с использованием собственной грамматической конструкции для определения себя как языковой косы?
Это действительно подход, принятый для Raku и, в свою очередь, nqp с помощью функции, называемой "сленг", сокращенно от "подъязыков".
Сленги
Хотя Raku, реализованный в Rakudo, на самом деле построен с использованием сленгов, они не являются официальной функцией. Я уверен, что они будут когда-нибудь, но легко могут пройти годы.
А пока я думаю, что лучшее, что я могу предоставить, это:
Ссылка на соответствующий "[raku] сленг" SO.
Дружественный совет: обильно применяйте флаг оптимизации компилятора
-Ofun
когда вы напишете код компилятора и, возможно, используете запятую в Rakudo, чтобы выяснить, что происходит...
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?