0

我一直在为Brain(Brainfuck-like语言)开发一位口译员,并对break语句的设计有一些疑虑。在解释器上执行break语句的最佳方式是什么?

考虑下面的代码JS:

var Stmt = (function() { 
    var Stmt = function() {}; 
    Stmt.prototype = { 
     update_expression: function(update) { return false; }, 
     value: function() { return this; }, 
     exec: function(delegate) { }, 
     zerofy: function (tapeObj) { 
     if (tapeObj.data[tapeObj.d_ptr] === undefined) { 
      tapeObj.data[tapeObj.d_ptr] = 0; 
     } 
    } 
    }; 

    return Stmt; 
})(); 

var BreakStmt = (function() { 
    var BreakStmt = function(){ }; 
    BreakStmt.prototype = Object.create(Stmt.prototype); 
    return BreakStmt; 
})(); 

var LoopStmt = (function() { 
    var LoopStmt = function(stmts, type) { 
    this.type = 'undefined'; 
    this.stmts = null; 

    if (tokens[type] === 'TT_BEGIN_WHILE' 
     || tokens[type] === 'TT_BEGIN_FOR') { 
     this.type = type; 
     this.stmts = stmts; 
    } 
    }; 

    LoopStmt.prototype = Object.create(Stmt.prototype); 
    return LoopStmt; 
})(); 

var IfStmt = (function() { 
    var IfStmt = function(stmts_then) { 
    this.stmts_then = stmts_then; 
    this.stmts_else = null; 
    }; 

    IfStmt.prototype = Object.create(Stmt.prototype); 
    IfStmt.prototype.set_else = function(stmts_else) { 
     this.stmts_else = stmts_else; 
    }; 

    return IfStmt; 
})(); 

解析器将通过递归语句,然后返回一个AST。现在想象一下具有以下陈述的AST:

LoopStmt 
    IfStmt 
    IfStmt 
     BreakStmt 
... 

函数也递归地递归。尽管有很多关于这个实现的想法,但经过大量研究后,我仍然无法找到如何在发现最接近的LoopStmt之前递归地阻止这种递归(如果有意义的话)的最佳方式。

什么是最好的设计? 任何帮助将是伟大的,谢谢!

回答

0

经过大量的研究,我相信我找到了答案。

实施tree accumulation的方法将是我设计的最佳创意之一。事实上,为此,我们将只使用向上累积的方法,其中每个节点(在这种情况下,我的stmts)具有关于其后代的信息。

在这种情况下,对于所提到的AST:

1. LoopStmt 
2. IfStmt 
3. IfStmt 
4.  BreakStmt 
    ... 

一切我们需要做的是#4 Stmt的信息#3的信息存储(或累加)到#3 Stmt,进入#2 ,最后#2分成#1。然后,我们会递归地将语句的执行分解到最近的循环。

我希望我会帮助任何人!

相关问题