Rascal 中的具体语法匹配

Concrete Syntax Matching in Rascal

如果我有:

import demo::lang::Exp::Concrete::WithLayout::Syntax;
if ((Exp)`<IntegerLiteral e> + <IntegerLiteral e>` := (Exp)`5 + 6`) { 
    println(e);
}

这会打印 6。这是一个可能的错误还是设计决定,例如出于性能考虑?它当然不应该打印任何东西,因为 e 不能同时匹配 56。然而,这与与 ADT 的匹配形成对比,后者 捕获,即:

data ExpNum = numb(int n) | add(ExpNum e1, ExpNum e2);
if (add(numb(x), numb(x)) := add(numb(5), numb(6))) { println(x); }

不会打印数字,而在使用 numb(5) 而不是 numb(6) 时会打印数字。

Ps。我 运行 来自 Rascal 源代码的示例使用 Eclipse 插件开发(使用与最新版本的 Rascal 合并的分叉版本),以及使用官方 Eclipse 插件的两台机器。但是,该插件在两台机器上都返回了以下内容:

|stdin:///|(4,46,<1,4>,<1,50>): Java compilation failed due to with classpath [/home/wouter/eclipse//plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar]: package org.eclipse.imp.pdb.facts.type does not exist

我问的原因是,有点类似,ConcreteListVariablePattern 自动抛出一个 RedeclaredVariable 异常,而不检查匹配结果的值是否等于环境中的变量,相反例如QualifiedNamePattern 检查结果是否等同于环境中的值(如果是已声明的变量)。

谢谢!

这绝对是一个错误:变量 e 被声明了两次(没有警告),匹配成功并打印到第二个 e 的绑定。 预期的行为是抛出 RedeclaredVariable 异常。

解决方法如下:

if ((Exp)`<IntegerLiteral e1> + <IntegerLiteral e2>` := (Exp)`5 + 6` && e1 == e2) { 
    println(e1);
}