【发布时间】:2018-08-16 21:14:46
【问题描述】:
我正在尝试将赋值表达式编译为字节码。我正在写我自己的语言,这部分真的让我很难过。我的语言获取源代码并将其转换为令牌,然后直接转换为字节码。例如,类似:
a + 2
变成
TOKEN_NAME
TOKEN_ADD
TOKEN_INT
这将被解析并转换为类似于
的字节码LOAD_VARIABLE (this is the a)
LOAD_CONSTANT (this is the 2)
ADD
这很简单。但是对于赋值表达式,例如:
a[0][1] = 2
会变成
TOKEN_NAME
TOKEN_L_BRACKET
TOKEN_INT
TOKEN_R_BRACKET
TOKEN_L_BRACKET
TOKEN_INT
TOKEN_R_BRACKET
TOKEN_ASSIGN
TOKEN_INT
我需要加载一个,在该对象上做一个下标(0 下标),然后将 2 存储到 1 下标中。我应该补充一点,解析器实际上是 LL(1),这使得这特别困难。
我想不出一种方法来确保左侧表达式的最后一部分(我分配给的部分)没有被加载,但其中存储了值 (2)。
如果有任何不清楚的地方,请发表评论,我很乐意澄清我的程序。 (很难为编程语言的整个解释器制作 MCVE!)
提前致谢。
【问题讨论】:
-
你不能得到assign token,然后回到名字或括号吗?
-
这是一个 LL(1) 解析器,因此我无法回溯。在实际代码中,这些表达式在下标之间可能绝对是巨大的,因此返回将非常低效。
-
您不能回溯,但您可以将令牌存储在辅助列表中。
-
这可能适用于下标,但我不确定它是否类似于
x = 2我如何能够确保我将 2 存储在 x 中,而不是先加载 x -
嗯,这听起来像是一个递归下降解析器,@DanielGee,而不是一个 LL(1)。递归下降解析器也构建了一个 AST,但它通过一系列堆栈帧体现在调用堆栈上。
标签: c parsing compiler-construction bytecode interpreter