%%{
machine microscript;
action ClearNumber {
currentNumber = 0;
}
action RecordDigit {
uint8_t digit = (*p) - '0';
currentNumber = (currentNumber * 10) + digit;
}
number = ((digit @RecordDigit)+) >ClearNumber;
whitespace = space+;
main := number (whitespace number)*;
}%%
编辑:让我理解这个“>”的含义运营商。我在对@jcomeu
的评论中引用了ragel指南中的描述我理解在RecordDigit之前调用ClearNumber动作,如果是这样,currentNumber初始化为零,将它乘以10的用途是什么。
最后,数字的定义。 number=((digit @RecordDigit)+) >ClearNumber
是什么意思?
这是代码的来源:here
编辑 :
*具体来说RecordDigit如何工作?什么是 p?一个指针?如果是这样,它指向什么?什么是digit =(*p)- '0';
是什么意思? [已解决]
答案 0 :(得分:3)
p
指针
p
中的 RecordDigit
是Ragel所需的变量。它是一个“指向要处理的字符数据的指针。”(在Java和Ruby中,它是字节数组的偏移量,data
)。因此,表达式(*p) - '0'
采用当前字符的字符代码(例如'7'
的代码在ASCII中为55),减去'0'
的字符代码(ASCII中为48)以获取字符所代表的实际数值:55 - 48 = 7
。
>
和@
运营商
>
运算符用于在从开始状态进入机器时执行操作。 @
运算符用于在将机器移动到最终状态时执行操作。
这意味着:
((digit @RecordDigit)+) >ClearNumber
在输入时先拨打ClearNumber
,并在每次RecordDigit
匹配时拨打digit
。通过如下更改操作可以轻松验证这一点:
action ClearNumber {
printf("ClearNumber\n");
currentNumber = 0;
}
action RecordDigit {
printf("RecordDigit\n");
uint8_t digit = (*p) - '0';
currentNumber = (currentNumber * 10) + digit;
}
打印出来:
ClearNumber
RecordDigit
RecordDigit
RecordDigit
为3位数字。
<强>摘要强>
第一次见到新数字时,currentNumber
设置为0.数字由uint8_t
- '0'更改为(*p)
,并存储到{ {1}}。当下一个数字到来时,计算其数值,并将其添加到当前值currentNumber
乘以10等。因此,此Ragel示例的目的是将字符串中以空格分隔的数字转换为整数。
<强>参考强>
Ragel user guide包含上述元素的所有信息,并且非常易于阅读。我自己是Ragel的初学者,编写我自己的样本没有问题。
答案 1 :(得分:1)
我不知道ragel,但RecordDigit的代码与C非常相似,所以这就是它的作用。如你所料,p是一个指针; * p查看字符数组(字符串)的字符。从字符'9'中减去'0'会留下数值9.正如您所注意到的,乘以10在第一次调用时没有任何意义,但是当连续数字被翻译时,它很有意义,就像现在的数字一样'321'成为数字321,在每次调用RecordDigit后乘以10,将数字移过小数点。
我还没说“数字”。
答案 2 :(得分:1)
虽然我不知道 ragel 。但是看看代码似乎它将字符串转换为数字。如果你记得数字0的ASCII值 - 9范围从48到57.因此假设输入字符串是 '123'所以你获得第一个字符并减去它48以获得它的值1.然后乘以10形成十进制数123.
答案 3 :(得分:1)
number = ((digit @RecordDigit)+) >ClearNumber;
'digit'是一个内置机器:[0-9]
它逐个收集数字(使用'+'运算符,表示'1..N')并在新数字的开头输入ClearNumber操作。
@RecordDigit操作用于计算解析期间的数字。
抱歉我的英语,而不是我的母语。 希望这会有所帮助。
答案 4 :(得分:1)
要真正理解ragel,你必须生成图表。 安装graphviz并像这样运行ragel:
ragel -V -p microscript.rl | dot -Tpng -o microscript.png
通常我只使用Makefile
%.png: %.rl
ragel -V -p $*.rl | dot -Tpng -o $@
所以我可以运行make microscript.png