我有一个非常标准的递归下降解析器。该算法很简单:每个函数从stream
读取字符并返回FAIL
或调用后续的解析函数(由相应的语法规则指定):
function parseFoo() {
var ret = parseBar(stream);
if (ret == FAIL) {
ret = parseQuax(stream);
...
}
...
return ret;
}
我想解决一下我没有完整stream
的情况 - 我异步得到它的碎片。因此我需要的是“可中断性”的特性 - 我必须能够保存解析器的状态,然后从那时起继续。
可悲的是,这是嵌套函数调用无法做到的一件事,因为解析器的所有状态都“存储”在调用堆栈中(按函数和局部变量的顺序)。
所以我必须以不同的方式构建parse*
函数。
我使用的语言是 JavaScript 。
有人可以指出任何想法如何继续吗?
编辑:
我觉得我需要某种状态机。我无法将头围绕在发电机或延续通道式上,它在我看来,在保存状态和恢复中存在很多故障。对我来说,我能想到的最明确的途径是将嵌套调用转换为某种堆栈,将局部变量重写为存储在堆栈项中的某些散列映射,并以不同的线性方式构造解析代码,以便我可以轻松地“转到” “到某个州。
我看到的一个子问题可能是这样的:因为我没有完整的stream
我想我必须尝试多个路径并存储所有部分解析的尝试。例如,如果语法显示a = b | c
,那么b
可能会很长,以至于它不完全在stream
中。所以我不能在解析b
时“挂起”,我必须尝试两者并保存部分计算。我是对的吗?
答案 0 :(得分:1)
这取决于所使用的编程语言。
你基本上需要continuations的一些支持(你可以理解为调用堆栈的抽象)。换句话说,您可能希望使用continuation passing style(CPS)进行编码。
如果使用C编码,您可能会对CPC感兴趣。
如果使用Javascript编码,您可能需要在CPS中手动编码。另请参阅this,this,this question,this页等....