Можно ли запустить подграмматику внутри грамматики 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, на самом деле построен с использованием сленгов, они не являются официальной функцией. Я уверен, что они будут когда-нибудь, но легко могут пройти годы.

А пока я думаю, что лучшее, что я могу предоставить, это:

  • Repl.it пример.

  • Ссылка на соответствующий "[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?

Другие вопросы по тегам