这部Ragel代码有什么作用?

时间:2011-02-16 03:46:54

标签: c linux 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指南中的描述

我理解在RecordDigit之前调用ClearNumber动作,如果是这样,currentNumber初始化为零,将它乘以10的用途是什么。

最后,数字的定义。 number=((digit @RecordDigit)+) >ClearNumber是什么意思?

这是代码的来源:here

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

5 个答案:

答案 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

enter image description here