9

背景:作为寒假期间的一个短期项目,我正在尝试使用 Python 和 PLY 实现一种名为 Ax 的编程语言(专为图形计算器设计)。简要说明:该语言仅允许全局变量并大量使用指针。

我正在尝试用这种语言实现 goto,但不知道该怎么做。

我的一般方法是首先使用 PLY 将代码解析为 ast,然后在执行过程中遍历它。

例如,声明

If 3
    Disp 4
    Disp 6
End

……会变成……

['PROGRAM', 
  ['BLOCK', 
    ['IF', 
      ['CONDITION', 3], 
      ['BLOCK', 
        ['DISP', 4], 
        ['DISP', 6]
      ]
    ]
  ]
]

...我将递归执行(我添加了缩进以提高可读性)。

因为ast是一棵树,我不知道如何在不同的节点之间跳转。我考虑过可能将树转换为扁平数组['IF', ['CONDITION', 3], ['DISP', 4], ['DISP', 6]],以便我可以使用扁平数组的索引转到代码中的特定行,但这似乎缺乏一定的优雅,几乎感觉像是一个步骤倒退(虽然我可能是错的)。

我看过这个,但无法理解它是如何工作的。

任何帮助或提示将不胜感激。

4

3 回答 3

9

“递归执行”不适合goto. 为了goto工作,您需要一台 PC、一个“程序计数器”,并且程序中的每条语句都必须有一个不同的地址。当它被执行时,每条语句的地址被分配给 PC。遇到goto时,将 goto 的目标地址(它的参数)放入 PC 并从那里继续执行。

使用基于堆栈的递归方法几乎不可能实现这一点。你有两个选择:

  • 将您的 AST 扁平化为一个序列,您可以在其中为每个语句分配一个不同的地址

  • 为您的解释器添加“跳过”模式。当goto遇到时,抛出一个GotoException打破所有堆栈帧并返回到根的。处理语句(跳过它们而不执行)直到到达目标地址。

我认为您可以想象这种实现goto不是很高效,并且可能难以实现。

于 2011-12-27T08:40:42.333 回答
3

我考虑过可能将树转换为扁平数组……但这似乎缺乏某种优雅,几乎感觉像是倒退了一步(尽管我可能是错的)。

你错了。机器代码总是平坦的。像 C 这样的语言被扁平化以创建机器代码。

计算器(与其他简单机器一样)是扁平的。

然而。展平 AX 语法树并不是完全必要的。

您只需将编程源标签应用于树中的每个节点。

然后“GOTO”简单地在树中搜索该标签并在该标签处恢复执行。

于 2011-12-27T17:49:18.183 回答
0

您还可以将 AST 展平为有向图(控制流图)。可以在 Python 包中找到如何执行此操作以生成networkx可由解释器遍历的图形的示例。请注意,您必须为此编写一些 AST 类。promela

于 2015-03-27T09:47:41.720 回答