这段 Ragel 代码有什么作用?
%%{
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 指南中的描述,
我理解 ClearNumber 操作是在 RecordDigit 之前调用的,如果是这样,currentNumber 被初始化为零,将其乘以 10 有什么用。
最后,数字的定义。 number=((digit @RecordDigit)+) >ClearNumber
是什么意思?
这是代码源: 这里
编辑: *RecordDigit具体是如何工作的? p是什么?指针?如果是的话,它指向什么? digit =(*p)- '0';
是什么意思? [已解决]
%%{
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)*;
}%%
EDIT: Make me understand the meaning of this ">" operator. I have quoted its description from the ragel guide in a comment to @jcomeu
I understand ClearNumber action is called before RecordDigit, if so, currentNumber is initialised to zero, what is the use of multiplying it by 10.
And lastly, the definition of number. What does number=((digit @RecordDigit)+) >ClearNumber
mean?
This is the source of code: here
EDIT :
*Specifically how does RecordDigit work? What is p? A Pointer? if so, what is it pointing to? What is digit =(*p)- '0';
mean? [solved]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
RecordDigit中的
p
指针p
是Ragel需要的变量。它是一个“指向要处理的字符数据”的指针。 (在 Java 和 Ruby 中,它是字节数组data
的偏移量)。因此,表达式(*p) - '0'
获取当前字符的字符代码(例如'7'
的 ASCII 代码为 55),减去'0'
的字符代码(ASCII 中的 48)来获取该字符代表的实际数值:55 - 48 = 7
。>
和@
运算符>
运算符用于在从计算机进入计算机时执行操作。启动状态。@
运算符用于在将机器移至最终状态时执行操作。这意味着:
输入时首先调用
ClearNumber
,每次匹配digit
时调用RecordDigit
。这可以通过更改操作来轻松验证,如下所示:打印输出:
对于 3 位数字。
摘要
当第一次遇到新数字时,
currentNumber
被设置为 0。该数字被更改为
- '0',并存储到uint8_t
(*p)currentNumber
中。当下一个数字到来时,计算其数值,并将其与currentNumber
的当前值乘以 10 相加,依此类推。因此,此 Ragel 示例的目的是转换字符串中以空格分隔的数字化为整数。参考
Ragel 用户指南包含所有有关上述元素的信息,并且非常容易阅读。我自己是 Ragel 的初学者,编写自己的示例没有任何问题。
The
p
pointerp
inRecordDigit
is a variable required by Ragel. It is a pointer “to the character data to process.” (In Java and Ruby it is an offset to a byte array,data
). The expression(*p) - '0'
therefore takes the character code of the current character (for example'7'
’s code is 55 in ASCII), subtracts the character code of'0'
(48 in ASCII) to get the actual numeric value represented by the character:55 - 48 = 7
.The
>
and@
operatorsThe
>
operator is used to execute an action when entering a machine from the start state. The@
operator is used to execute an action when moving the machine into a final state.This means that:
calls first
ClearNumber
on entering, and callsRecordDigit
every timedigit
is matched. This can be easily verified by altering the actions as follows:prints out:
for a 3-digit number.
Summary
When meeting a new digit for the first time, the
currentNumber
is set to 0. The digit is changed into auint8_t
by(*p)
- '0', and stored intocurrentNumber
. When the next digit comes, its numeric value is computed, and added to the current value ofcurrentNumber
multiplied by 10, etc. So the aim of this Ragel sample is to convert space-separated numbers in a string into integers.Reference
The Ragel user guide contains all the information on the elements above, and is pretty easy to read. I am myself a beginner with Ragel, and had no problem writing my own samples.
我不知道 ragel,但 RecordDigit 的代码与 C 非常相似,所以这就是它的作用。正如您所怀疑的, p 是一个指针; *p 查看字符数组(字符串)中的一个字符。从字符“9”中减去“0”留下数值 9。正如您所注意到的,第一次调用时乘以 10 没有任何意义,但是随着连续的数字被翻译,它就很有意义了,因为现在的数字'321' 变为数字 321,在每次调用 RecordDigit 后乘以 10,将数字移动一位小数点。
我还没有摸索出“数字”。
I don't know ragel, but the code of RecordDigit is very similar to C, so here's what it does. as you suspected, p is a pointer; *p looks at a character of a character array (string). subtracting '0' from the character '9' leaves the numeric value 9. as you noticed, multiplying by 10 makes no sense the first time this is called, but as successive digits are translated it makes a lot of sense, as now the digits '321' become the number 321, multiplying by 10 after each invocation of RecordDigit to shift the number over by a decimal point.
I don't yet grok "number".
虽然我不知道ragel。但是看代码似乎它将字符串转换为数字。如果你还记得数字0-9范围的ASCII值48到57。因此假设输入字符串是
'123' 因此您获取第一个字符并将其减去 48 以获得其值 1。然后乘以 10 形成十进制数 123。
Although I do not know the ragel.But looking at the code it seems that it converts a string into a number.If you remember ASCII value of numbers 0-9 range from 48 to 57.Thus suppose input string is
'123' so you are obtaining first character and subtracting it by 48 to obtain its value that is 1.And then multiplying by 10 form the decimal number 123.
'digit' 是一个内置机器: [0-9]
它逐一收集数字(使用 '+' 运算符,意思是 '1..N'),并在新数字开始时输入 ClearNumber 操作。
@RecordDigit 操作用于在解析期间计算数字。
抱歉我的英语不是我的母语。
希望这有帮助。
'digit' is a built-in machine for : [0-9]
It collects digits one by one (using the '+' operator, meaning '1..N') and enters ClearNumber action at the start of a new number.
@RecordDigit action is used to compute the number during parsing.
Sorry for my English, not my native language.
Hope this helps.
要真正理解 ragel,您必须生成图表。
安装 graphviz 并像这样运行 ragel:
通常我只使用 Makefile
所以我可以运行
make microscript.png
To really understand ragel you must generate the diagram.
Install graphviz and run ragel like this:
Usually I just use Makefile
So I could just run
make microscript.png