繁体   English   中英

这部Ragel代码有什么作用?

[英]What does this piece of Ragel Code do?

    %%{
  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工作? 什么是p? 一个指针? 如果是这样,它指向什么? 什么是digit =(*p)- '0'; 意思? [解决了]

p指针

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

参考

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

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

在此输入图像描述

我不知道ragel,但是RecordDigit的代码与C非常相似,所以这就是它的作用。 如你所料,p是一个指针; * p查看字符数组(字符串)的字符。 从字符'9'中减去'0'会留下数值9.正如您所注意到的,乘以10在第一次调用时没有任何意义,但是当连续数字被翻译时,它很有意义,就像现在的数字一样'321'成为数字321,在每次调用RecordDigit后乘以10,将数字移过小数点。

我还没有弄“数字”。

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

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

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

它逐个收集数字(使用'+'运算符,表示'1..N')并在新数字的开头输入ClearNumber操作。

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

抱歉我的英语,而不是我的母语。 希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM