antlr4:访问者中的条件代码生成处理

问题描述 投票:0回答:1

我使用ANTLR(使用访问者的JavaScript目标)编写(自己的lang-> JS)转译器。重点放在目标代码生成中的变体

[更早的SO post,描述了一种更简单情况的解决方案。这一点不同,主要是由于涉及到递归。

语法:

grammar Alang;
...

variableDeclaration : DECL (varDecBl1 | varDecBl2) EOS;
varDecBl1 : ID AS TYP;
varDecBl2 : CMP ID US (SGST varDecBl1+ SGFN);
...


DECL  : 'var-declare' ;
EOS   : ';' ;
SGST  : 'segment-start:' ;
SGFN  : 'segment-finish' ;
AS    : 'as';
CMP   : 'cmp';
US    : 'using';
TYP
: 'str'
| 'int'
| 'bool'
;
ID    : [a-zA-Z0-9_]+ ;

需要对两种不同的源代码案例进行不同的处理。

源代码1:

var-declare fooString as str;

其目标需要显示为:var fooString;

源代码2:

var-declare cmp barComplex using 
segment-start:
 barF1 as int
 barF2 as bool
 barF3 as str 
segment-finish;

此目标必须是:var barComplex = new Map();(因为简单的var声明无法处理值类型)

代码生成使用:

  visitVarDecBl1 = function(ctx) {    
    this.targetCode += `var ${ctx.getChild(0).getText()};`;
    return this.visitChildren(ctx);
  };

....

  visitVarDecBl2 = function(ctx) {
    this.targetCode += `var ${ctx.getChild(1).getText()} = new Map();`;
    return this.visitChildren(ctx);
  };

([targetCode合并目标代码)

以上适用于案例1。对于情况2,由于递归使用规则var barComplex = new Map()而最终超出varDecBl1,该规则再次调用visitVarDecBl1代码生成实现。错误的结果:

var barComplex = new Map();
var barF1;   // <---- wrong one coming from visitVarDecBl1
var barF2;   // <---- wrong
var barF3;   // <---- wrong

为了解决这个问题,我想尝试的一种方法是将visitVarDecBl1设置为父ctx的条件。如果parent = variableDeclaration,则目标代码= var ${ctx.getChild(0).getText()};。如果parent = varDecBl2,请跳过代码生成。

但是我无法在ctx有效负载中找到调用规则,因此无法进行字符串比较。使用ctx.parentCtx之类的东西给我[378 371 204 196 178 168](哈希?)。

欢迎输入。 (包括建议采用更好的方法)

antlr antlr4 visitor
1个回答
0
投票

[如果有人手头有类似的情况,我会自己发布答案。我自己提取父规则来处理它。

util = require("util");

...

//  parentCtx object -> string
const parentCtxStr = util.inspect(ctx.parentCtx);   

// snip out parent rule from payload, e.g.: 'varDecBl2 {…, ruleIndex: 16, …}'
const snip = parentCtxStr.slice(0,parentCtxStr.indexOf("{")-1); // extracts varDecBl2 for you
}

现在使用snip的值如上所述进行处理。

当然,这种方式建立了有效负载结构的耦合方式。如果这种情况发生改变,将来可能会有突破的危险。我希望通过API使用相同的东西,尽管找不到。

© www.soinside.com 2019 - 2024. All rights reserved.