You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rascal插值字符串美化器空格保留问题及语法优化求助

问题诊断

  1. 词法匹配逻辑错误:原IntStringCharacter规则会将${中的$识别为字符串常量的一部分,导致${foobar}被整体纳入InterpolatedStringConstant,无法触发InterpolatedPart的语法匹配。
  2. 美化器代码问题:存在重复的toString(interpolatedPart)方法,且interpolatedString方法参数与语法定义的Interpolation结构不匹配,直接导致空格丢失。

修正方案

1. 调整词法规则,优先识别插值标记${

修改词法规则,确保$仅在后续不是{时才被纳入字符串常量,让${能被语法分析器识别为插值起始标记:

lexical InterpolatedStringConstant 
  = @category="Constant" IntStringCharacter*  // 仅匹配插值前后的纯字符串内容(不含s"和结尾")
  ; 
lexical IntStringCharacter 
  = "\\" [" \\ b f n r t]  // 处理转义序列
  | UnicodeEscape           // Unicode转义
  | ![" \\ $]               // 匹配非 "、\、$ 的普通字符
  | "$" !>> "{"             // 匹配独立$,后续是{则不纳入字符串
  ;

lexical Id 
    = ([a-zA-Z] [a-zA-Z0-9_]* !>> [a-zA-Z0-9]) | `[^`]*`  // 简化并修正标识符规则
    ;

syntax InterpolatedPart = "${" Id variable "}";

// 明确插值字符串的整体结构:s" + 前缀 + 插值 + 后缀 + "
syntax Interpolation = "s\"" InterpolatedStringConstant? InterpolatedPart InterpolatedStringConstant? "\"";

syntax Expr = Interpolation;
  • 将s"和结尾"从InterpolatedStringConstant中拆分到Interpolation规则,确保空格能被完整保留在前后字符串部分。
  • 修正了原Id规则中的语法错误,简化为标准的标识符匹配逻辑。

2. 修复美化器代码

删除重复方法,调整参数与语法结构对应,确保空格被正确拼接:

public str toString(interpolatedPart(str variable)){
    return "${<variable>}";
}

public str toString(interpolation(str prefix, InterpolatedPart intpart, str suffix)){
    // 处理前缀/后缀为空的情况(比如插值在字符串首尾)
    str pre = prefix != null ? prefix : "";
    str suf = suffix != null ? suffix : "";
    return "s\"<pre><toString(intpart)><suf>\"";
}

验证效果

输入:let x = s" ${foobar} "
解析后结构:

  • 前缀:" "
  • 插值部分:${foobar}
  • 后缀:" "
    输出:let x = s" ${foobar} ",与预期完全一致。

扩展说明

如果需要支持多插值场景(如s"a${x}b${y}c"),可将Interpolation规则修改为:

syntax Interpolation = "s\"" (InterpolatedStringConstant | InterpolatedPart)+ "\"";

同时对应的美化器方法需要遍历处理所有字符串和插值部分。

内容的提问来源于stack exchange,提问作者Onyedika Ekwe CHRISxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:09:58