在 M3 `loc` 方案和常规 `loc` 类型之间转换?

Converting between M3 `loc` scheme and regular `loc` type?

M3 核心模块 returns Rascal 中的一种简化 loc 表示。例如,文件 MapParser 中的方法可能具有 loc|java+method:///MapParser/a()|

然而,这显然不同于我倾向于看到的其他 loc 方案,后者看起来或多或少像:|project://main-scheme/src/tests/MapParser.java|

这不是问题,除了某些函数只接受一种或另一种方案。例如,函数 appendToFile(loc file, value V...) 不接受 M3 使用的这个方案,并将拒绝它并返回类似 IO("Unsupported scheme java+method") 的错误。

那么,我怎样才能轻松地在两种方案之间转换?我想保留所有信息,例如突出显示的部分。

干杯。

这里有两个区别。

物理位置与逻辑位置

java+method是逻辑位置,project是物理位置。我认为描述它们区别的最佳方式是物理位置描述了实际文件或实际文件的子集的位置。逻辑位置描述了某个实体在更大模型的上下文中的位置。例如,java class/project 中的 java 方法。通常逻辑位置可以映射到物理位置,但这并不总是正确的。

例如,对于 m3,您可以使用 IO 中的 resolveLocation 来获取逻辑位置指向的文件中的实际偏移量。

只读与可写位置

并非所有位置都是可写的,我认为任何逻辑位置都不是。但也有一些物理位置是只读的。从这个意义上说,您得到的错误是通用的。

Rascal 确实支持在文本文件中间写入,很可能您不想使用 appendToFile,因为它也会附加在您指向的位置之后。您很可能想用您的新部分替换文本的一部分,因此常规 writeFile 应该可以。

一些笔记

请注意,您必须在每次写入后重新计算文件中的所有偏移量。因此,为逻辑位置解析的物理位置将过时,因为自从构建 m3 模型及其逻辑位置和物理位置之间的相应映射以来文件已经更改。

所以对于这个用例,你可能想想一个更好的方法。最好的解决方案是使用语法,重写文件的解析树,重写后覆盖旧文件。请注意,Rascal 随附的最新 Java 语法是针对 Java 5 的,因此这可能比您希望的要多一些。也许将您的目标设定为 new Stack Overflow 问题,我们将看看还有哪些其他选项可能适用。