背景: 作为寒假期间的一个简短项目,我正在尝试使用Python和PLY实现一种名为Axe(为绘制计算器而设计)的编程语言。简要说明:该语言只允许全局变量,并且大量使用指针。在
我试图用这种语言实现goto,但不知道如何实现。
我的一般方法是首先使用PLY将代码解析为ast,然后在执行时遍历它。在
例如,语句
If 3
Disp 4
Disp 6
End
…会变成。。。在
^{pr2}$…我将递归执行(为了可读性,我添加了缩进)。在
因为ast是一棵树,我不知道如何在不同的节点之间跳转。我曾经考虑过将树转换成一个平坦的数组['IF', ['CONDITION', 3], ['DISP', 4], ['DISP', 6]]
,这样我就可以使用flat-ish数组的索引来查找代码中的特定行,但这似乎缺乏某种优雅,几乎感觉像是在倒退(虽然我可能错了)。在
我看过this,但无法理解它是如何工作的。在
任何帮助或提示将不胜感激。在
还可以将AST展平为有向图(控制流图)。可以找到一个例子,说明如何这样做来生成一个
networkx
图,该图可以被解释器遍历here。请注意,您必须为此编写一些AST类。在你错了。机器代码总是平坦的。像C这样的语言被扁平化以创建机器代码。在
计算器(像其他简单的机器一样)是平面的。在
然而。扁平化您的AXE语法树并不是完全需要的。在
您只需将编程源标签应用于树中的每个节点。在
然后“GOTO”只需在树中搜索该标签并继续在该标签处执行。在
“递归执行”不适合
goto
。要使goto
工作,您需要一台PC、“程序计数器”,并且程序中的每个语句都必须有一个不同的地址。当它被执行时,每个语句的地址被分配给PC。当遇到goto
时,goto的目标地址(它的参数)被放入PC,然后从那里继续执行。在使用基于堆栈的递归方法几乎不可能实现这一点。您有两种选择:
将AST展平到一个序列中,在该序列中可以为每个语句分配不同的地址
给你的翻译添加一个“跳过”模式。当遇到
goto
时,抛出一个GotoException
,它从所有堆栈帧中分离出来并返回根。进程语句(跳过它们而不执行)直到到达目标地址。我想您可以想象,
goto
的这个实现性能不高,而且可能很难实现。在相关问题 更多 >
编程相关推荐