3
    %%{
  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意思?

这是代码的来源:这里

编辑:* RecordDigit 具体是如何工作的?pdigit =(*p)- '0';是什么指针?如果是这样,它指向什么?什么意思?[解决了]

4

5 回答 5

3

p指针_

pinRecordDigit是 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 位数字。

概括

第一次遇到新的数字时,设置为0。数字由-'0'currentNumber变为a ,并存入。当下一个数字到来时,计算它的数值,并与当前值相加乘以 10 等。因此,此 Ragel 示例的目的是将字符串中以空格分隔的数字转换为整数。uint8_t(*p)currentNumbercurrentNumber

参考

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

于 2012-04-02T19:50:01.383 回答
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

在此处输入图像描述

于 2012-04-04T18:01:47.793 回答
1

我不知道 ragel,但 RecordDigit 的代码与 C 非常相似,所以这就是它的作用。正如您所怀疑的, p 是一个指针;*p 查看字符数组(字符串)中的一个字符。从字符'9'中减去'0'会留下数值9。正如您所注意到的,第一次调用时乘以10没有意义,但是随着连续数字的转换,它很有意义,因为现在数字'321' 变为数字 321,每次调用 RecordDigit 后乘以 10 以将数字移动小数点。

我还没有理解“数字”。

于 2011-02-16T03:55:29.620 回答
1
number = ((digit @RecordDigit)+) >ClearNumber;

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

它一个一个地收集数字(使用“+”运算符,意思是“1..N”)并在新数字的开头输入 ClearNumber 操作。

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

对不起我的英语,不是我的母语。希望这可以帮助。

于 2011-02-17T13:24:50.277 回答
1

虽然我不知道ragel。但是看代码,它似乎将字符串转换为数字。如果你记得数字 0-9 的 ASCII 值范围从 48 到 57。因此假设输入字符串是 '123' 所以你正在获取第一个字符并将其减去 48 以获得其值 1。然后乘以 10 形成十进制数 123。

于 2011-02-16T03:57:47.753 回答