这段 Ragel 代码有什么作用?

发布于 2024-10-17 17:52:40 字数 895 浏览 5 评论 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)*;
}%% 

编辑:让我理解这个“>”的含义操作员。我在 @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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦中的蝴蝶 2024-10-24 17:52:40

RecordDigit中的p指针

p是Ragel需要的变量。它是一个“指向要处理的字符数据”的指针。 (在 Java 和 Ruby 中,它是字节数组 data 的偏移量)。因此,表达式 (*p) - '0' 获取当前字符的字符代码(例如 '7' 的 ASCII 代码为 55),减去'0' 的字符代码(ASCII 中的 48)来获取该字符代表的实际数值:55 - 48 = 7

>@ 运算符

> 运算符用于在从计算机进入计算机时执行操作。启动状态。 @ 运算符用于在将机器移至最终状态时执行操作。

这意味着:

((digit @RecordDigit)+) >ClearNumber

输入时首先调用 ClearNumber,每次匹配 digit 时调用 RecordDigit。这可以通过更改操作来轻松验证,如下所示:

  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 (*p) - '0',并存储到 currentNumber 中。当下一个数字到来时,计算其数值,并将其与 currentNumber 的当前值乘以 10 相加,依此类推。因此,此 Ragel 示例的目的是转换字符串中以空格分隔的数字化为整数。

参考

Ragel 用户指南包含所有有关上述元素的信息,并且非常容易阅读。我自己是 Ragel 的初学者,编写自己的示例没有任何问题。

The p pointer

p in RecordDigit 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 @ operators

The > 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:

((digit @RecordDigit)+) >ClearNumber

calls first ClearNumber on entering, and calls RecordDigit every time digit is matched. This can be easily verified by altering the actions as follows:

  action ClearNumber {
    printf("ClearNumber\n");
    currentNumber = 0;
  }

  action RecordDigit {
    printf("RecordDigit\n");
    uint8_t digit = (*p) - '0';
    currentNumber = (currentNumber * 10) + digit;
  }

prints out:

ClearNumber
RecordDigit
RecordDigit
RecordDigit

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 a uint8_t by (*p) - '0', and stored into currentNumber. When the next digit comes, its numeric value is computed, and added to the current value of currentNumber 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.

说谎友 2024-10-24 17:52:40

我不知道 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".

少女的英雄梦 2024-10-24 17:52:40

虽然我不知道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.

时光与爱终年不遇 2024-10-24 17:52:40
number = ((digit @RecordDigit)+) >ClearNumber;

'digit' 是一个内置机器: [0-9]

它逐一收集数字(使用 '+' 运算符,意思是 '1..N'),并在新数字开始时输入 ClearNumber 操作。

@RecordDigit 操作用于在解析期间计算数字。

抱歉我的英语不是我的母语。
希望这有帮助。

number = ((digit @RecordDigit)+) >ClearNumber;

'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.

深海蓝天 2024-10-24 17:52:40

要真正理解 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

“在此输入图像描述”

To really understand ragel you must generate the diagram.
Install graphviz and run ragel like this:

ragel -V -p microscript.rl | dot -Tpng -o microscript.png

Usually I just use Makefile

%.png: %.rl
        ragel -V -p $*.rl | dot -Tpng -o $@

So I could just run make microscript.png

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文