当你没有完整的语法规范时,很难给出明确的答案,但至少让我们试着让你的例子按照你想要的方式工作,然后你应该能够在需要时纠正它。
因此,您在 Github 中包含一些打印操作的完整示例实际上说明了很多关于状态机中正在发生的事情(在使用 Ragel 时您应该定期检查的另一件事是它可以生成的状态机图你)。在其初始规范(与问题相同)中,它在运行时输出以下内容:
[this]< >,< >[is]
所以进入第三个变量有问题。这是为什么?嗯,那是因为你line
只指定了一个( ',' whitespace* var)
元素,但是如果你试图通过指定来解决这个问题( ',' whitespace* var)*
,它也不会起作用,因为现在你要求你的var
is后面紧跟一个重复的逗号,没有任何空格。让我们试试这个(有意删除的操作),将空格移动到重复组中:
line = var whitespace* ( ',' whitespace* var whitespace*)* koniec;
现在你在输出中得到这个:
[this]< >,< >[is]< >,< >[a]< >< >< >,< >[test]< >
这是一个明显的改进。那为什么现在失败了?好吧,那是因为在你koniec
的机器想要换成下一个之后line
,但为了做到这一点,它需要看到一个var
. 但是我们;
在输入之后有空格。所以我们需要改变我们对 line 的定义以在开始时启用一些空格,但这也会使空格在main
.
line = whitespace* var whitespace* ( ',' whitespace* var whitespace*)* koniec;
main:= line*;
现在我们有这个输出:
[this]< >,< >[is]< >,< >[a]< >< >< >,< >[test]< >
< >[and],< >[this]
哪个更好,但仍然不够好。现在您可以看到它在换行符上阻塞,这对我来说实际上也有点不清楚。你这么说
结束行是';' 或输入
然而你想得到
行(并且,这个,是,好的)
所以让我们假设 enter 开始一个新的line
,除非你在行尾有一个逗号。要在语法中指定它,让我们这样做:
line = whitespace* var whitespace* ( ',' (whitespace | enter)* var whitespace*)* koniec;
现在你在输出中得到这个:
[this]< >,< >[is]< >,< >[a]< >< >< >,< >[test]< >
< >[and],< >[this],[is],[ok]
为什么不走得更远?那是因为我们line
必须有,var
但我们在输入中有一个空行。这也引发了一个只有空格的行的问题,所以让我们line
用这样的只有空格的内容来工作:
line = whitespace* (var whitespace* ( ',' (whitespace | enter)* var whitespace*)*)? koniec;
砰!突然你在输出中拥有了所有你想要的词组。但是你也有一些多余的线条,实际上很容易修复,你只需要将你的pisz_enter
动作从koniec
这样的线条中移动:
vargroup = var whitespace* ( ',' %pisz_przecinek (whitespace | enter)* var whitespace*)* %pisz_enter;
line = whitespace* vargroup? koniec;
而已。我能注意到的另外两件事是: