所以我创建了一个解析器,当我试图在解析器类中调用我的binOp函数时,它会给我这个错误。
我编辑过以显示完整的解析器代码:我的代码:
//index.js
const fs = require('fs');
const Lexer = require('./lexer/Lexer');
const Parser = require('./Parser');
class Program {
constructor(args) {
this.args = args
this.args.shift();
this.args.shift();
}
readFile(path) {
var fileValue = fs.readFileSync(path, { encoding: 'utf-8' });
return fileValue;
}
renderCommands() {
switch(this.args[0]) {
case 'compile':
this.launch(this.args[0], this.readFile(this.args[1]));
break;
}
}
launch(file, data) {
var lexer = new Lexer(file, data);
var tokens = lexer.makeTokens();
if(!(tokens == null)) {
// Say tokens is ['INT:10', 'PLUS', 'INT:22']
var parser = new Parser(tokens);
var ast = parser.parse();
console.log(ast.node)
}
}
}
var program = new Program(process.argv);
program.renderCommands()
//Parser.js
class Parser {
constructor(tokens) {
this.tokens = tokens
this.tokIdx = -1
this.advance()
}
advance() {
this.tokIdx++;
if(this.tokIdx < this.tokens.length) {
this.currentTok = this.tokens[this.tokIdx];
}
return this.currentTok;
}
parse() {
var res = this.expr()
if(!res.error && this.currentTok.type != TokenTypes.EOF) {
return res.failure(new InvalidSyntaxError(
this.currentTok.posStart, this.currentTok.posEnd,
"Expected '+', '-', '*' or '/'"
))
}
return res;
}
binOp(func, ops) {
var res = new ParseResult();
var left = res.register(func())
if(res.error) return res
while(ops.includes(this.currentTok.type)) {
var opTok = this.currentTok;
res.register(this.advance())
var res = res.register(func());
if(res.error) return res;
left = new BinOpNode(left, opTok, right);
}
return res.success(left);
}
factor() {
var res = new ParseResult();
var tok = this.currentTok;
if([TokenTypes.PLUS, TokenTypes.MINUS].includes(tok.type)) {
res.register(this.advance())
var factor = res.register(this.factor())
if(res.error) return res
return res.success(new UnaryOpNode(tok, factor));
} else if([TokenTypes.INT, TokenTypes.FLOAT].includes(tok.type)) {
res.register(this.advance())
return res.success(new NumberNode(tok));
} else if(tok.type == TokenTypes.LPAREN) {
res.register(this.advance())
var expr = res.register(this.expr())
if(res.error) return res;
if(this.currentTok.type == TokenTypes.RPAREN) {
res.register(this.advance())
return res.success(expr);
} else {
return res.failure(new InvalidSyntaxError(
this.currentTok.posStart, this.currentTok.posEnd,
"Expected '('"
));
}
}
return res.failure(new InvalidSyntaxError(
tok.posStart, tok.posEnd,
"Expected int or float"
));
}
term() {
return this.binOp(this.factor, [TokenTypes.MUL, TokenTypes.DIV]);
}
expr() {
return this.binOp(this.term, [TokenTypes.PLUS, TokenTypes.MINUS]);
}
}ParseResult只有一个error和node属性,当调用register时,它会查看res是否有错误,当调用success时,它会将节点设置为ParseResult的节点。当调用失败时,它会检查错误,然后设置错误
完整错误消息:
C:\Users\adnit\Desktop\Amethyst\src\parser\Parser.js:66
return this.binOp(this.factor, [TokenTypes.MUL, TokenTypes.DIV]);
^
TypeError: Cannot read property 'binOp' of undefined
at term (C:\Users\MiccDev\Desktop\Amethyst\src\parser\Parser.js:66:21)
at Parser.binOp (C:\Users\MiccDev\Desktop\Amethyst\src\parser\Parser.js:81:33)
at Parser.expr (C:\Users\MiccDev\Desktop\Amethyst\src\parser\Parser.js:70:21)
at Parser.parse (C:\Users\MiccDev\Desktop\Amethyst\src\parser\Parser.js:22:24)
at Program.launch (C:\Users\MiccDev\Desktop\Amethyst\src\index.js:31:30) at Program.renderCommands (C:\Users\MiccDev\Desktop\Amethyst\src\index.js:20:22)
at Object.<anonymous> (C:\Users\MiccDev\Desktop\Amethyst\src\index.js:39:9)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)发布于 2021-04-10 18:15:25
检查类代码,类方法binOp(func, ops)的参数func可能是通过其他类方法term()和expr()的类方法。为了在正确的实例上下文中运行func(),请按如下方式更新binOp(func, ops)方法:
binOp(func, ops) {
var res = new ParseResult();
// var left = res.register(func());
var left = res.register(func.apply(this));
if (res.error) return res
while (ops.includes(this.currentTok.type)) {
var opTok = this.currentTok;
res.register(this.advance())
// var res = res.register(func());
var res = res.register(func.apply(this));
if (res.error) return res;
left = new BinOpNode(left, opTok, right);
}
return res.success(left);
}https://stackoverflow.com/questions/67032646
复制相似问题