Rascal:包含进口符号

Rascal: Containing Imported Symbols

我在 repl 中使用多个语法。这些语法的某些规则使用相同的名称。

其中一个文档秘诀 mentions full qualification,用于消除函数模式匹配中类型注释的歧义(它在 load 函数的注释中,但不在本页的代码中 - .jar是否正确)。但这可能会变得乏味,所以也许导入有别名(比如 Python import regex as r)?!在 parse 函数的第一个参数中使用完全限定似乎无助于消除递归调用的所有解析规则的歧义,parse(#lang::java::\syntax::Java18::CompilationUnit, src)。如果我还导入 lang::java::\syntax::Java15.

至少它会产生奇怪的错误

一般来说,处理来自具有相同名称的不同模块的符号的安全方法是什么?

或者,有没有办法在 repl 中 "unload" 一个模块?

一些背景信息:

  1. Rascal 模块是 open 出于可扩展性的原因,特别是 datasyntax 定义和重载函数可以通过导入另一个模块来扩展;通过这种方式,您可以通过导入另一个模块并随意添加规则和函数替代来扩展语言及其处理功能。
  2. importing 和 extending 模块之间存在语义差异。特别是 import 不是可传递的并且仅融合导入模块中名称的使用,而 extend 可传递的并且还融合了名称的递归使用扩展的模块。因此,对于扩展语言,您默认使用 extend,而对于使用函数库,您将使用 import.
  3. 我们计划在 2020 年的其中一个版本中完全删除 import 中的 fusing 行为。之后,必须通过在模块名称前加上前缀来消除所有冲突导入的非终端名称的歧义, 并且前缀将不再具有融合来自不同模块的递归使用的非终端的副作用。 extend 并非如此,它仍然会融合非终结符并一直发挥作用。
  4. REPL 实例中的所有定义都模拟单个匿名模块成员的语义。

所以回答你的问题:

  • 在我们修复 import 的语义之前,不是 处理来自具有相同名称的不同导入模块的符号特别安全。
  • 模块前缀技巧只有效 "top-level",在此之下类型无论如何都会被融合,因为将非终结符具体化为语法的代码不会传播前缀。它不会知道如何。
  • 取消导入模块:

    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
    
    • 可能是环境中使用最少的功能之一;买者自负!

要解决这些问题,一种方法是在每个单独的 language/language 版本的不同模块中编写函数,如果您想将这些功能捆绑在一个界面中,则创建一个导入这些函数的顶级模块.这样,因为 import 不是可传递的,命名空间保持独立和干净。当然这并不能解决 REPL 问题;我唯一能提供的就是为你正在玩的每种语言版本启动一个新的 REPL。