%%{ 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)开始:(为了强调而添加了粗体文字):
“In general Ragel cannot handle recursive structures because the grammar is interpreted as a regular language. However,depending on what needs to be parsed it is sometimes practical to implement the recursive parts using manual coding techniques. This often works in cases where the recursive structures are simple and easy to recognize,such as in the balancing of parentheses.”
“One approach to parsing recursive structures is to use actions that increment and decrement counters or otherwise recognize the entry to and exit from recursive structures and then jump to the appropriate machine defnition using fcall and fret. Alternatively,semantic conditions can be used to test counter variables.
“A more traditional approach is to call a separate parsing function (expressed in the host lan- guage) when a recursive structure is entered,then later return when the end is recognized.”
从a mailing list discussion on nested brackets开始,提到了相同的三种方法:
Specify a growable stack using prepush and postpop and then use fcall
and fret.Counting and then verify in actions or conditions.
Call a new parsing function (in the host language) when the recursive
structure is entered.
你能在Ruby中指出我的每个例子 – 最好是使用上面的例子吗?谢谢!
解决方法
balanced = [^(){}\[\]] | '(' @{ fcall balancedTokensParen; } | '[' @{ fcall balancedTokensBracket; } | '{' @{ fcall balancedTokensBrace; }; balancedTokensParen := balanced* ')' @{ fret; }; balancedTokensBracket := balanced* ']' @{ fret; }; balancedTokensBrace := balanced* '}' @{ fret; };
所以你的案子可以作为
char = [xo]; group = '(' @{ fcall group_rest; }; group_rest := (char|group)* ')' @{ fret; }; main := group;
词法分析器函数应该包含堆栈数组,你必须手动检查顶部以确保没有未闭合'(‘:
stack = [] %% write init; %% write exec; if top > 0 cs = %%{ write error; }%% end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。