我正在使用ANTLR(带有访问者的JavaScript目标)编写转译器(myLang-> JS)。焦点在于目标代码生成部分,来自解析树。与之类似,如何处理语言源代码的变化。
为了使问题更清楚,请考虑以下两种变化-
源#1:PRINT 'hello there'
source#2:
varGreeting = 'hey!'
PRINT varGreeting
在情况1中,我处理字符串。在第2种情况下,它是一个变量。然后,JS目标代码需要有所不同(如下)。情况1有引号,情况2无引号。
target#1(JS):
console.log("hello there"); // <-- string
target#2(JS):
var varGreeting = "hey!";
console.log(varGreeting); // <-- var
如何最好地消除歧义并生成不同的代码?我一下子想到了使用规则名称(ID
,STRLIT
)作为不同用法的载体。但是我找不到这些在RuleContext API中公开。我查看了java ones,并假设在JS运行时中也是如此。
[getText()
给出值('hello there'
,varGreeting
),没有我可以利用的元数据/属性信息。
我深入研究了tree / ctx对象,却没有以容易使用的方式找到它们。
问题:如何在不构建难看的hack的情况下做到最好?Transpiler似乎在ANTLR的用例范围内,我是否缺少某些东西?
((相关部分)语法:
print : PRINTKW (ID | STRLIT) NEWLINE;
STRLIT: '\'' .*? '\'' ;
ID : [a-zA-Z0-9_]+;
访客替代:
// sample code for generating code for case 1 (with quotes)
myVisitor.prototype.visitPrint = function(ctx) {
const Js =
`console.log("${ctx.getChild(1).getText()}");`;
// ^^ this is the part which needs different treatment for case 1 and 2
// write to file
fs.writeFile(targetFs + fileName + '.js', Js, 'utf8', function (err) {
if (err) return console.log(err);
console.log(`done`);
});
return this.visitChildren(ctx);
};
使用ANTLR 4.8
您已经有了此信息。如果找到字符串标记,则在生成的输出中将其与引号一起使用。任何其他令牌(数字文字,ID等)都可以原样编写。