这是语法的起点:
%%{
machine xo;
char = "x" | "o";
group = "(" char* ")";
main := group;
}%%
(xxxx(oo)()xx)
例如,它处理。如何扩展它以允许嵌套组;例如(xxxx(o(x)o)()xx
?
我知道递归通常不受一台 Ragel 机器的支持。所以这行不通:
group = "(" ( char | group )* ")";
来自Ragel State Machine Compiler User Guide (PDF):(为强调而添加了粗体文本):
“一般来说,Ragel 无法处理递归结构,因为语法被解释为常规语言。但是,根据需要解析的内容,有时使用手动编码技术实现递归部分是可行的。这通常适用于递归结构的情况简单且易于识别,例如在括号的平衡中。”
“解析递归结构的一种方法是使用递增和递减计数器的操作,或者以其他方式识别递归结构的入口和出口,然后使用 fcall 和 fret 跳转到适当的机器定义。或者,可以使用语义条件来测试计数器变量。
“一种更传统的方法是在输入递归结构时调用单独的解析函数(以宿主语言表示),然后在识别到结尾时返回。”
从关于嵌套括号的邮件列表讨论中,提到了相同的三种方法:
使用 prepush 和 postpop 指定一个可增长的堆栈,然后使用 fcall 和 fret。
计数,然后在动作或条件中验证。
输入递归结构时调用新的解析函数(以宿主语言)。
你能给我举一个例子吗——最好使用我上面的例子——在 Ruby 中?谢谢!