/ * * /のようなcスタイルのコメントを消費するようにflexでルールを作成したい
私は以下を持っています
c_comment "/*"[\n.]*"*/"
しかし、それは決して一致しません。理由は何ですか?私のコードがもっと必要な場合は、私に知らせてください。すべてを提出します。返信してくれた人に感謝します。
代わりに 開始条件 を使用することをお勧めします。
%x C_COMMENT
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>\n { }
<C_COMMENT>. { }
<condition>
とルールの間に空白があってはならないことに注意してください。
%x C_COMMENT
はC_COMMENT状態を定義し、ルール/*
はそれを開始します。開始されると、*/
は初期状態に戻り(INITIAL
は事前定義されています)、他のすべての文字は特別なアクションなしで消費されます。 2つのルールが一致する場合、Flexは最も長い一致を持つルールを取得することで明確にするため、ドットルールは*/
の一致を妨げません。 ドットは改行以外のすべてに一致する であるため、\n
ルールが必要です。
%x
定義により、C_COMMENTは排他状態になります。つまり、レクサーは、状態に入ると<C_COMMENT>
に「タグ付けされた」ルールにのみ一致します。
これが 小さな例のレクサー で、/* comments */
内のものを除くすべてを出力することでこの回答を実装します。
Zneakの答えを操作する方法について誰かが混乱している場合に備えて、次の例を示します。
(基本的に、彼の役立つリンクで説明されているように、最初のセクションに「%x C_COMMENT」を配置し、残りを2番目のセクションに配置します)
foo.l
%{
// c code..
%}
%x C_COMMENT
%%
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>. { }
%%
// c code..
それが誰かを助けることを願っています!ティフ
なぜそれが取り上げられないのかはわかりませんが、そのようなパターンが大きな語彙要素を生成する可能性があることは知っています。開始コメントマーカーだけを検出し、終了マーカーが見つかるまでビットバケット内のすべてを投げる方が効率的です。
このサイト それを行うコードがあります:
"/*" {
for (;;) {
while ((c = input()) != '*' && c != EOF)
; /* eat up text of comment */
if (c == '*') {
while ((c = input()) == '*')
;
if (c == '/')
break; /* found the end */
}
if (c == EOF) {
error ("EOF in comment");
break;
}
}
}
この解決策はもっと簡単だと思います。
"/*"((\*+[^/*])|([^*]))*\**"*/"
Flexマニュアル に実際の例があります。これは、厄介なEdgeケースを正しく取得します。
<INITIAL>"/*" BEGIN(IN_COMMENT);
<IN_COMMENT>"*/" BEGIN(INITIAL);
<IN_COMMENT>[^*\n]+ // eat comment in chunks
<IN_COMMENT>"*" // eat the lone star
<IN_COMMENT>\n yylineno++;
私は提案された解決策のいくつかを試しました、そしてここに結果があります。
paxdiabloからの回答は機能し、読みやすいという利点がありました。私はさらに次のように変更しました:
"/ *" {int c1 = 0、c2 = input(); for(;;){ if(c2 == EOF)break; if(c1 == '*' && c2 == '/') break; c1 = c2; c2 = input(); } }