Мошенник: Содержит Импортированные Символы - PullRequest
1 голос
/ 11 февраля 2020

Я работаю с несколькими грамматиками в репл. Грамматики используют одни и те же имена для некоторых из своих правил.

В одном из рецептов документации упоминается полная квалификация , чтобы устранить неоднозначность аннотаций типов при сопоставлении с образцом функции (это примечание load функция, но не в коде этой страницы - .jar это правильно). Но это может стать утомительным, так что, возможно, есть псевдонимы для импорта (как в Python import regex as r) ?! И использование полной квалификации в первом аргументе функции parse, похоже, не помогает устранить неоднозначность всех правил синтаксического анализа, которые вызываются рекурсивно, parse(#lang::java::\syntax::Java18::CompilationUnit, src). По крайней мере, это приводит к странным ошибкам, если я также импортирую lang :: java :: \ syntax :: Java15.

В целом, как безопасно обрабатывать символы из разных модулей с одинаковыми именами?

В качестве альтернативы, есть ли способ "выгрузить" модуль в repl?

1 Ответ

1 голос
/ 12 февраля 2020

Некоторая справочная информация:

  1. Модули Rascal открыты по причинам расширяемости, в частности определения data, syntax и перегруженные функции могут быть расширены путем импорта другого модуль; Таким образом, вы можете расширить язык и его функции обработки, импортировав другой модуль и добавив правила и альтернативы функций на досуге.
  2. Существует небольшая разница c между import ing и extend использованием модуль. В частности, import не является транзитивным и объединяет использование имени внутри импортирующего модуля, в то время как extend является транзитивным, а также объединяет рекурсивное использование имени в расширенном модуле. Поэтому для расширения языка вы по умолчанию используете extend, а для использования библиотеки функций вы будете использовать import.
  3. Мы планируем удалить поведение fusing из import полностью в одном из выпусков 2020 года. После этого все противоречиво импортированные нетерминальные имена должны быть устранены путем префикса с именем модуля, и префикс не будет иметь побочного эффекта от слияния рекурсивно используемых нетерминалов из разных модулей. Это не так для extend, который все еще объединяет нетерминал и функционирует полностью.
  4. Все определения в экземпляре REPL имитируют семантику членов одного анонимного модуля.

Итак, чтобы ответить на ваши вопросы:

  • это не особенно безопасно обрабатывать символы из разных импортированных модулей с одинаковыми именами, пока мы не исправим семантику import то есть.
  • трюк с префиксом модуля работает только на «верхнем уровне», ниже этого типа типы в любом случае слиты, потому что код, который использует нетерминал как грамматику, не распространяет префикс. Он не знает, как.
  • Отмена импорта модуля:

    rascal>import IO;
    ok
    rascal>println("x");
    x
    ok
    rascal>:un
    undeclare   unimport    
    rascal>:unimport IO
    ok
    rascal>println("x");
    |prompt:///|(0,7,<1,0>,<1,7>): Undeclared variable: println
    
    • , вероятно, одна из наименее используемых функций в среде; caveat emptor!

Чтобы обойти эти проблемы, можно написать функции внутри отдельного модуля для каждой отдельной языковой / языковой версии и создать модуль верхнего уровня, который импортирует эти если вы хотите объединить функциональность в единый интерфейс. Таким образом, поскольку import не является транзитивным, пространства имен остаются отдельными и чистыми. Конечно, это не решает проблему REPL; Единственное, что я могу предложить, это запустить fre sh REPL для каждой языковой версии, с которой вы играете.

...