(F)lexは、可能な限り最長のトークンと常に一致します。 .*
は、改行文字が含まれていないシーケンスと一致するので、うれしく12sdaesre34
と一致します。 (lexでは、.
は改行以外の文字と一致します)。したがって34
はマッチすることができなくなりました。
修正するには、content
と一致するものを明確にする必要があります。たとえば、次のように数字が含まれていないものにマッチします:
[^[:digit:]]+ { printf("content\n"); }
あなたが一致しないために文字のリストに改行を追加したい場合があります:
[^\n[:digit:]]+ { printf("content\n"); }
それとも、あなたがしたいです34
を含まない最長配列と一致する。それはトリッキーだが、それを行うことができます。
([^3]|3+[^34])+ { printf("content\n"); }
、問題を解決するには十分ではありませんので、しかし、それはまだ、初期12
と一致します。
入力が常に12...34
の文字列で構成されていて、他のコンテンツが散在している場合は、12...34
シーケンス全体を一致させて3つのトークンに分割できます。最初と最後のマーカーは既知の長さであるため、間違いなく最も簡単な解決策です。次のパターンの最初は、12
を開始しない文字列と、最初のインスタンス12
の直前で終わる文字列に一致し、2番目の文字は12
で始まり、最初のインスタンス34
(一致する)で終わる文字列と一致します。いずれのパターンも、一致しない12
を含む入力と一致しません。その場合に合致するように第3のルールが追加されます。 2番目のルールのように見えますが、末尾に34
の一致は含まれません。 (f)lexは常に最長のトークンと一致するため、3番目のルールは2番目のルールが失敗した場合にのみ成功します。
([^1]|1+[^12])* { puts("content"); }
12([^3]|3+[^34])*34 { puts("head content tail"); }
12([^3]|3+[^34])* { puts("error"); }
通常、あなたが実際に呼び出し元のプログラムに渡すためにcontent
の値をキャプチャしたいと思います。最初のルールでは、それはちょうどyytext
ですが、2番目のルールでは、コンテンツはyytext+2
で始まるyyleng-4
文字からなります(先頭と末尾の区切り文字を削除するため)。
yytext
がレキシカルスキャナで使用されている内部データ構造を指し、ポインタが次のパターンマッチで無効になるため、ほとんどの場合、一致したトークンを保持する必要がある場合はコピーする必要があります。最初のルールの場合は、あなたはstrcpy
を使用して文字列のコピーを作成することもできますが、2番目のルールのため、あなたはコピーを自分で作りたいと思います:
([^1]|1+[^12])* { yylval = strcpy(yytext); ... }
12([^3]|3+[^34])*34 { yylval = malloc(yyleng-3);
memcpy(yylval, yytext, yyleng-4);
yylval[yyleng-4] = '\0';
...
}
者はyylval
がグローバル変数であると仮定しますタイプchar*
であり、コード内のどこかにある規則free()
の文字列です。彼らはまた、省略コード(...
)でyylval
を使って何かをやっているとか、頭と尾が遭遇したかどうかの表示で呼び出し元に戻ったと仮定します。
ありがとうございますが、答えはそれほど正確ではありません。 ([^ 3] | 3 + [^ 34])+ {printf( "content \ n"); } は今、結果はまだないが、私はwated: \t $が12dsfadsf34をエコー| \tコンテンツ \t尾 \tコンテンツ –
@HindForsum a.out形式:はい、あなたは全く正しいです。どのように進めるかについていくつかの提案を加えましたが、実際にはあなたの要件を知らないので、明らかに概要に過ぎません。私は一般的にあなたがCで文字列処理に精通していると仮定しています。 – rici