首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeError:无法读取未定义javascript错误的属性'‘

TypeError:无法读取未定义javascript错误的属性'‘
EN

Stack Overflow用户
提问于 2021-04-10 17:13:40
回答 1查看 58关注 0票数 0

所以我创建了一个解析器,当我试图在解析器类中调用我的binOp函数时,它会给我这个错误。

我编辑过以显示完整的解析器代码:我的代码:

代码语言:javascript
复制
//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的节点。当调用失败时,它会检查错误,然后设置错误

完整错误消息:

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

发布于 2021-04-10 18:15:25

检查类代码,类方法binOp(func, ops)的参数func可能是通过其他类方法term()expr()的类方法。为了在正确的实例上下文中运行func(),请按如下方式更新binOp(func, ops)方法:

代码语言:javascript
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67032646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档