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 アクションが呼び出されることを理解しています。

最後に数の定義です。とはnumber=((digit @RecordDigit)+) >ClearNumberどういう意味ですか?

これはコードのソースです: here

EDIT : *具体的には、RecordDigit はどのように機能しますか? pdigit =(*p)- '0';とはポインター?もしそうなら、それは何を指していますか?とはどういう意味ですか? 【解決済み】

4

5 に答える 5

3

pポインター_

pinRecordDigitは Ragel が必要とする変数です。「処理する文字データへの」ポインタです。(Java と Ruby では、バイト配列へのオフセットですdata)。したがって、式(*p) - '0'は現在の文字の文字コード (たとえば、'7'のコードは ASCII では 55) を取り、(ASCII では 48) の文字コードを減算して、文字で'0'表される実際の数値を取得します: 55 - 48 = 7.

>and@演算子_

オペレーターは、>開始状態からマシンに入るときにアクションを実行するために使用されます。オペレーターは、@マシンを最終状態に移動するときにアクションを実行するために使用されます。

この意味は:

((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 に設定されます。その数字は -'0 'uint8_tによってに変更され、 に格納されます。次の数字が来ると、その数値が計算され、現在の値に10 を掛けた値に追加されます。したがって、この Ragel サンプルの目的は、文字列内のスペースで区切られた数値を整数に変換することです。(*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
number = ((digit @RecordDigit)+) >ClearNumber;

'digit' は : [0-9] のビルトイン マシンです。

数字を 1 つずつ収集し (「+」演算子を使用して、「1..N」を意味します)、新しい番号の先頭で ClearNumber アクションに入ります。

@RecordDigit アクションは、解析中に数値を計算するために使用されます。

私の母国語ではなく、私の英語で申し訳ありません。お役に立てれば。

于 2011-02-17T13:24:50.277 に答える
1

Ragel はわかりませんが、RecordDigit のコードは C に非常に似ているため、次のようにします。ご想像のとおり、p はポインターです。*p は、文字配列 (文字列) の文字を調べます。文字 '9' から '0' を引くと、数値 9 が残ります。お気づきのように、10 を掛けても、これが最初に呼び出されたときは意味がありませんが、連続する数字が変換されると、非常に意味があります。 '321' は数値 321 になり、RecordDigit を呼び出すたびに 10 を掛けて数値を小数点以下にシフトします。

私はまだ「数」を理解していません。

于 2011-02-16T03:55:29.620 に答える
1

Ragel はわかりませんが、コードを見ると、文字列を数値に変換しているようです。数値 0 ~ 9 の ASCII 値は 48 ~ 57 の範囲であることを覚えていれば、入力文字列が '123' であると仮定すると、最初の文字を取得し、それを 48 で減算して 1 の値を取得します。次に、10 を掛けて 10 進数の 123 を生成します。

于 2011-02-16T03:57:47.753 に答える