0

私の字句解析器は、数字 (5,555,543667)、小数 (44.65,4.1)、およびピリオド (.) を認識します。

数字、小数、ピリオドは問題なく数えることができますが、数字とピリオドが隣り合っていると、小数としてカウントされます。

555 2.3 55.23 44 5 を含むテキスト ファイルを考えてみましょう。

私の出力は

1型1:555
2型3:2.3
3型3:55.23
4型1:44
5型3:5。

タイプ 3 は、10 進数の識別子です。

5 番目と 6 番目のトークンを数字として、次にピリオドとしてカウントしたいと思います。

これが私のswitchステートメントの処理方法です。

  switch(*b) {

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    digits:
        t.length++;
        switch(*(b + t.length)) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                goto digits;
            case '.': 
                goto decimal;                   
                break;
            default:
                break;
        }

         t.type = TOKEN_DIGITS;
        t.string = (char *)calloc(t.length + 1, sizeof(char));
        strncpy(t.string, b, t.length);
        break;



    decimal:
        t.length++;
        switch(*(b + t.length)) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                goto decimal;
                break;
            }   
            t.type = TOKEN_DECIMAL;
            t.string = (char *)calloc(t.length+1,sizeof(char));
            strncpy(t.string,b,t.length);           
       break;

複数のことを試しましたが、公式には立ち往生しています。

4

3 に答える 3

1

この種の演習では、長い switch ステートメントの代わりに文字分類関数を使用する必要があります。コードははるかに単純になり、gotoまったく使用する必要がなくなります。

たとえば、数値は次の正規表現で記述できます (さまざまなブロックを分割するために空白を追加します)。

[-+]? [0-9]* \.? [0-9]+

これは、可能な状態遷移をすでに示しています。

  • 番号は (オプションで) +orで始めることができます (-署名付き番号をサポートしている場合)
  • 0..n 桁の場合があります
  • 次の文字が小数点記号でない場合は、区切り記号である必要があります。それ以外の場合は、無効な記号です。区切り記号の場合、番号は終了しています。
  • 小数点以下は 1..n 桁でなければなりません
  • 入力の終わりに到達するか、セパレーターに遭遇すると、番号は終了します

これはすべて、ほんの数行のコードで実行できます。現在の入力文字を指すポインターを用意し、1 つずつ前に進み、各文字を調べ、文字クラスに基づいて、何をすべきかを決定します。

さて、この特定のアプローチは、科学表記法などを使用して浮動小数点数を処理しませんが、基本が完了すると、これらのエクストラを追加するのは非常に簡単です。

于 2013-10-12T01:50:10.653 に答える
0

変数 likedigit_follow_peroidを使用して状態を保持します。ピロイドに遭遇するたびに、変数を false に設定し、10 進スイッチ ブロックで数字に遭遇したら、それを true に設定します。変数の値をチェックして t.lengthbefore を決定しますstrncpy。一緒に動作する他の変数も必要かもしれません。最良の方法は状態遷移行列を定義することです。これは goto よりもはるかに優れています。

于 2013-10-12T01:51:08.897 に答える