繁体   English   中英

TypeError:无法读取未定义 javascript 错误的属性“”[重复]

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM