首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的Ragel例子,平衡父母?

简单的Ragel例子,平衡父母?
EN

Stack Overflow用户
提问于 2012-08-18 03:50:53
回答 3查看 2.4K关注 0票数 7

这里是语法的起点:

代码语言:javascript
复制
%%{
  machine xo;

  char = "x" | "o";
  group = "(" char* ")";
  main := group;
}%%

例如,它处理(xxxx(oo)()xx)。如何将其扩展为允许嵌套组;例如,(xxxx(o(x)o)()xx

我知道递归通常不是由一个Ragel机器支持的。所以这是行不通的

代码语言:javascript
复制
group = "(" ( char | group )* ")";

来自Ragel状态机编译器用户指南(PDF):(为强调添加的粗体文本):

“一般来说,Ragel不能处理递归结构,因为语法被解释为一种常规语言。然而,根据需要解析的内容,使用手动编码技术实现递归部件有时是可行的。在递归结构简单且易于识别的情况下,例如在括号的平衡方面,这通常是可行的。” “解析递归结构的一种方法是使用增量和递减计数器的操作,或以其他方式识别递归结构的输入和退出,然后使用fcall和fret跳转到适当的计算机缺陷。或者,语义条件可以用来测试计数器变量。 “更传统的方法是在输入递归结构时调用单独的解析函数(用主机lan表示),然后在识别结束时返回。”

关于嵌套括号的邮件列表讨论中,提到了同样的三种方法:

  1. 使用use和postpop指定一个可增长的堆栈,然后使用fcall。
  2. 计数,然后在操作或条件中进行验证。
  3. 在输入递归结构时调用一个新的解析函数(在宿主语言中)。

你能给我举一个例子吗-最好用上面的例子--在Ruby里?谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-11 09:00:24

使用fcall/fret的一般模式如下:

代码语言:javascript
复制
balanced = [^(){}\[\]] |
               '(' @{ fcall balancedTokensParen; } |
               '[' @{ fcall balancedTokensBracket; } |
               '{' @{ fcall balancedTokensBrace; };
balancedTokensParen   := balanced* ')' @{ fret; };
balancedTokensBracket := balanced* ']' @{ fret; };
balancedTokensBrace   := balanced* '}' @{ fret; };

所以你的案子可以作为

代码语言:javascript
复制
  char = [xo];
  group = '(' @{ fcall group_rest; };
  group_rest := (char|group)* ')' @{ fret; };

  main := group;

lexer函数应该包含stack数组,您必须手动检查top,以确保没有未关闭的'(':

代码语言:javascript
复制
stack = []
%% write init;
%% write exec;
if top > 0 
    cs = %%{ write error; }%%
end
票数 10
EN

Stack Overflow用户

发布于 2012-08-19 12:13:29

我也一直在寻找关于拉格尔问题的几天!

对于传递递归嵌套括号等需求,Ragel没有得到很好的记录。

经过5天的Google搜索,我找到的唯一示例代码是:

https://bitbucket.org/mitsuhiko/arana-main/src/289ad1a6f083/arana/lexnparse.rl

考虑到Ragel堆栈需求和fgoto()或fcall()、fret()和其他代码管理所需的Ragel代码,我(和其他许多人一样)认为Ragel不是满足这些需求的简单工具。否则,就会有一个以上的工作示例可用。

票数 1
EN

Stack Overflow用户

发布于 2012-10-10 19:29:57

粗略地说,如果您试图匹配父母,解决方案将涉及以下内容:

代码语言:javascript
复制
open_paren = '(' @{ @paren_count += 1}
close_paren = (')' when @paren_count > 0) @{ @parent_count -= 1}

请查看“用户指南”中关于语义条件的部分。

顺便说一句: Ragel是一个非常强大的工具,你必须了解它的基础才能真正利用它。使用Ragel的第一步是阅读“用户指南”并理解它--尽管仍有一些部分您不确定,但Ragel的使用将非常令人沮丧。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12015684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档