
[英]Uncaught TypeError: Cannot read property '0' of undefined javascript error and with highcharts
[英]TypeError: Cannot read property '' of undefined javascript error [duplicate]
所以我做了一个解析器,当我尝试在我的解析器 class 中调用我的 binOp function 时,它会给我这个错误。
已编辑以显示我的完整解析器代码:我的代码:
//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 只是有一个错误和节点属性,当调用 register 时,它会查看 res 是否有错误,当调用成功时,它会将节点设置为 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)
Examining the class code, the class method binOp(func, ops)
's param func
is possibly class method through other class methods term()
and 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.