如何在Rascal语法定义中添加换行符?
在Rascal语法定义中添加换行符的正确方式
你之前的写法不生效,核心原因是Rascal的语法定义里空白符(包括换行)默认会被忽略,直接把“\n”写在语法规则里没用,得根据你的需求选下面两种方案:
需求1:解析时强制Field之间必须用换行分隔
如果要求输入的代码里每个Field必须单独占一行,得通过自定义layout来控制分隔规则:
// 定义允许的空白类型(空格、制表符、换行等) layout EntityLayout = [\t-\n\r\ ]*; // 强制Field之间必须是「换行+任意空白」 layout FieldSeparator = "\n" EntityLayout; syntax Entity = @Foldable entity: "entity" Id name "{" {Field FieldSeparator}+ fields "}" ; syntax Field = field: Id name ":" Type t ;
这样解析器就只会接受Field之间用换行分隔的输入了。
需求2:格式化输出时给Field添加换行
如果只是想在生成代码/打印AST的时候让每个Field换行,语法定义里不用改,而是写一个**漂亮打印机(Pretty Printer)**来控制输出格式:
import IO; import ParseTree; // 定义Entity的打印规则 str pp(Entity e) = "entity <e.name> {\n" + join("\n", [pp(f) | f <- e.fields]) + "\n}"; // 定义Field的打印规则(加缩进更美观) str pp(Field f) = " <f.name>: <f.t>"; // 测试示例 void main() { Entity userEntity = entity(name=id("User"), fields=[ field(name=id("username"), t=type("String")), field(name=id("age"), t=type("Int")) ]); println(pp(userEntity)); }
运行后会输出:
entity User { username: String age: Int }
简单说:Rascal的语法定义管的是「识别输入结构」,输出格式是另外用漂亮打印机来控制的,别把这俩混在一起。
内容的提问来源于stack exchange,提问作者Benni Katchy
相关产品推荐
相关产品推荐

