1

背景を説明するだけです。私たちには、C で独自のコンパイラーを作成する必要がある学校のプロジェクトがあります。私の仕事は、字句解析を作成することです。ここまでは順調ですが、エスケープ シーケンスに問題があります。

エスケープ シーケンスを見つけ、そのエスケープ シーケンスが正しい場合、この\xAFのような文字列に保存します。それ以外の場合は字句エラーです。

私の問題は、エスケープ シーケンスのみを含む文字列を 1 つの文字に変換する方法です。したがって、残りの文字列を含む「バッファ」に追加できます。

エスケープ シーケンスのみを含む大規模なテーブルを作成し、それを 1 つずつ比較するというアイデアがありましたが、エレガントに見えません。

4

3 に答える 3

3

このソリューションは、8 進数、16 進数など、すべての長さとタイプの数値エスケープ シーケンスに使用できます。

a が表示されたときに行うことは'\'、次の文字を確認することです。'x'(または)の場合'X'は 1 文字を読み取り、16 進数の数字 ( isxdigit) の場合は別の文字を読み取ります。最後の数字が 16 進数でない場合は、それをストリームに戻し (「取得」操作)、読み取った最初の数字のみを使用します。

読み取った各数字を文字列に入れると、egstrtolを使用してその文字列を数値に変換できます。その数値をトークン値に直接入れます。

8 進シーケンスの場合は、代わりに最大 3 文字までです。


同様の方法の例については、私が何年も前に作成したこの古いレクサーを参照してください。関数を検索し lex_getescapeます。strtoulこの方法は、エスケープコードを数値に変換する代わりに直接演算を使用しますが、標準isxdigitなどの機能も使用しません。

于 2012-11-18T14:44:43.417 に答える
2

次のコードを使用できます。文字列で xString2char を呼び出します。

char x2char(const char c)
{
    if (c >= '0' && c <= '9')
        return c - '0';
    if (c >= 'a' && c <= 'f')
        return c - 'a';
    if (c >= 'A' && c <= 'F')
        return c - 'A';
    //if we got here it's an error - handle it as you like...
}

char xString2char(const char* buf)
{
    char ans;
    ans = x2char(buf[2]);
    ans <<= 4;
    ans += x2char(buf[3]);
    return ans;
}

これは機能するはずです。エラー チェックと処理を追加するだけです (コードでまだ検証していない場合)。

于 2012-11-18T14:45:47.140 に答える
-1

フレックスにはstart条件があります。これにより、コンテキスト分析が可能になります。たとえば、flex マニュアルに C コメント分析 (/*との間) の例があります。*/

<INITIAL>"/*"   BEGIN(IN_COMMENT);
<IN_COMMENT>{
"*/"            BEGIN(INITIAL);
[^*\n]+         /* eat comment in chunks */
"*"             /* eat the lone star */
\n              yylineno++;
}

開始条件により、文字列リテラルの分析も可能になります。開始条件の項目に開始条件を使用して C スタイルの引用符で囲まれた文字列を一致させる方法の例があり"How do I expand backslash-escape sequences in C-style quoted strings?"、flex マニュアルにタイトルの付いた FAQ 項目もあります。おそらくこれはあなたの質問に答えるでしょう。

于 2012-11-18T14:44:14.157 に答える