为了账号安全,请及时绑定邮箱和手机立即绑定

如何检测来源/调试Lexer的空值

如何检测来源/调试Lexer的空值

HUX布斯 2021-05-13 14:05:11
我已经实现了ANTLR4的基本语法,以使用简单Javascript风格的语言构建JavaScript解释器。当我运行脚本以转换代码(解析/生成/转译)时,我得到 TypeError: ctx.INT is not a function了来自转译器文件的代码。这是我要编译的脚本var fs = require('fs');var antlr4 = require('antlr4');var buildAst = require('./build-ast');var mylangTranspiler = require('./mylang-transpiler');function runScript(inputText) {    var ast = buildAst(inputText);    var transpiler = new mylangTranspiler();    antlr4.tree.ParseTreeWalker.DEFAULT.walk(transpiler, ast);    // eval(transpiler.output);    fs.writeFile("./main.js", transpiler.output, function(err) {        if(err) {            return console.log(err);        }        console.log("The file was saved!");    });}var contents = fs.readFileSync('./tests/test.mylang', 'utf8');console.log(contents);runScript(contents);module.exports = runScript;这是捕获错误的地方mylangTranspiler.prototype.resolveExpr = function(ctx) {    console.log(ctx);    if (ctx.INT() != null) {        return ctx.INT().getText();    } else if (ctx.ID() != null) {        return ctx.ID().getText();    } else if (ctx.STRING() != null) {        return ctx.STRING().getText().replace(/\$\{([^\}]+)\}/g, '" + $1 + "');    } else return "undefined";}这是我的语法文件grammar mylang;compilationUnit: stmt*;stmt    : assignStmt    | invocationStmt    ;assignStmt: SET ID TO expr;invocationStmt: ID ((expr COMMA)* expr)?;expr: expr (MUL | DIV) expr  # MulDiv    | expr (ADD | SUB) expr  # AddSub    | LPAREN expr RPAREN     # Parens    | ID                     # ID    | INT                    # Int    | STRING                 # String    ;INT: [0-9]+;STRING : '"' .*? '"' ;ID: [a-zA-Z_] [a-zA-Z0-9_]*;COMMA: ',';SAY: 'show';SET: 'set';TO: 'to';MUL: 'times';DIV: 'by';ADD: 'add';SUB: 'sub';LPAREN: '(';RPAREN: ')';WS : [ \t\r\n]+ -> skip;我试图实现的是基本的计算器操作,变量分配和向控制台的打印,但是具有不同的语法,这些语法将转换为JavaScript。
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

当您定义带有标记替代项的解析器规则时,每个替代项将获得自己的子类,并且只有该子类才会具有与该替代项的子规则相对应的getter方法。因此,鉴于您的语法,您具有以下子类ExprContext

  • MulDivContext

  • AddSubContext

  • ParensContext

  • IDContext

  • IntContext

  • StringContext

其中只有IntContext一种INT()方法。因此INT()ExprContext除非您首先确保它实际上是一个,否则不应调用an IntContext

ANTLR生成的侦听器和访问者将为每个标记的替代品使用enterexitvisit方法,因此确保与aIntContext进行处理的方法是定义visitIntContext(ctx)visitStringContext(ctx)而不是诸如此类visitExprContext(ctx),然后您将知道ctx只能曾经拥有与该替代方案相对应的类型。


查看完整回答
反对 回复 2021-05-27
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信