のような文字列を解析する必要がありますfunc1(arg1, arg2); func2(arg3, arg4);
。これはそれほど複雑な構文解析の問題ではないので、flex/bisonまたは同様のユーティリティに頼るのは避けたいと思います。
私の最初のアプローチは、POSIXCregcomp/regexec
またはC++のBoost実装を使用することでしたstd::regex
。次の正規表現を作成しましたが、機能しません(理由については後で説明します)。
"^"
"[ ;\t\n]*"
"(" // (1) identifier
"[a-zA-Z_][a-zA-Z0-9_]*"
")"
"[ \t\n]*"
"(" // (2) non-marking
"\["
"(" // (3) non-marking
"[ \t]*"
"(" // (4..n-1) argument
"[a-zA-Z0-9_]+"
")"
"[ \t\n]*"
","
")*"
"[ \t\n]*"
"(" // (n) last argument
"[a-zA-Z0-9_]+"
")"
"]"
")?"
"[ \t\n]*"
";"
1
グループは識別子をキャプチャし、グループ4..n-1
はグループによってキャプチャされる最後の引数を除いて引数をキャプチャすることを目的としていることに注意してくださいn
。
この正規表現をに適用するとfunc(arg1, arg2, arg3)
、得られる結果は配列であると言い{func, arg2, arg3}
ます。入っていないのでこれは間違ってarg1
います!
問題は、標準の正規表現ライブラリでは、サブマーキングは最後の一致のみをキャプチャすることです。つまり、たとえば正規表現を"((a*|b*))*"
適用した場合"babb"
、内部一致の結果は次のようにbb
なり、以前のすべてのキャプチャは忘れられます。
ここで私を悩ませているもう1つの点は、エラーが発生した場合、入力が拒否されたときのパーサーの状態に関する情報がほとんど提供されないため、どの文字が認識されなかったかを知る方法がないことです。
だから私はここで何かが欠けているかどうかわかりません...この場合sscanf
、代わりにまたは同様のものを使用する必要がありますか?
私はC/C ++標準ライブラリを使用することを好むことに注意してください(そしておそらくブースト)。