Cスタイルの/ ** /コメントの正規表現の導出


8

私はCスタイル言語のパーサーに取り組んでおり、そのパーサーにはCスタイルの/ ** /コメントに一致する正規表現が必要です。今、私はこの表現をウェブ上で見つけました:

/\*([^\*]*\*+[^\*/])*([^\*]*\*+|[^\*]*\*/

しかし、ご覧のとおり、これはやや乱雑な表現であり、実際に一致させたいかどうかが正確に一致するかどうかはわかりません。

それらが本当に正しいことを手動で簡単に確認でき、その後上記の正規表現に変換可能(「コンパイル可能」)な正規表現を(厳密に)定義する別の方法はありますか?


2
この方法では、コメントのネストを防ぐことができます。とにかく本格的なパーサーを構築する場合は、ブロックコメントを「適切に」解析することを検討してください。明確になるだけでなく、必要に応じてコメントから構造化メタデータを読み取ることもできます。
ラファエル

断片は(!\*)意図したものでしたか?より一般的な表記を意味します[^*]か?そして、何(!*|!/)ですか?
Gilles「SO-邪悪なことをやめよう」

@ギレス:式を更新しました。(!* |!/)は、*でも/でもないことを意図しています。
Alex ten Brink

@ Raphael、Cのコメントはネストされません
フォンブランド2013年

@vonbrand:「Cスタイル」はあまり具体的ではないため、「自然な拡張」が不可能であることを言及することは有効なポイントです。
frafl 2013年

回答:


6

私は4つの方法を考えることができます:

  1. 興味のある言語のオートマトンを定義します。正規表現をオートマトンに変換します(Brzozowskiの導関数を使用)。両方のオートマトンが同じ言語を受け入れることを確認します(バイシミュレーション引数を決定して最小化するか使用します)。

  2. 大量のテストケースを記述し、正規表現をそれらに適用します。

  3. 標準の手法を使用して、ポイント1で定義されたオートマトンを正規表現に変換します。

  4. 上記の組み合わせ。


5

Cのコメントを解析していることを確認したい場合は、モデルをC仕様に直面させる必要があります。C99は、次のように§6.4.9コメントの構文を定義しています。

1.文字定数、文字列リテラル、またはコメント内を除き、文字/* はコメントを示します。このようなコメントの内容は、マルチバイト文字を識別し、*/それを終了させる文字を見つけるためにのみ検査されます。

2.文字定数、文字列リテラル、またはコメント内を除いて、文字//は次の改行文字までのすべてのマルチバイト文字を含むコメントを導入します。このようなコメントの内容は、マルチバイト文字を識別し、終了する改行文字を見つけるためにのみ検査されます。

これは英語の散文であり、正式な定義ではありませんが、コメントを消費する非決定的有限オートマトン(NFA)に関してかなり明確な解釈があります。

  • 初期状態から/続いて*、マルチコメント内の状態に入り、/続いて/シングルコメント内の状態に入ります。
  • 複数行コメント内の状態から*続き、コメント後状態に/入ります。
  • 単一行コメント状態から、改行はコメント後状態になります。
  • 他の文字は状態を変更しません。

初期状態が適用されるかどうかを知るには、文字列リテラルと文字リテラルを検出するためにもう少し分析を行う必要があることに注意してください。

NFAを取得したら、標準的な手法を使用して正規表現を作成できます(Wikipediaの記事には記載されていませんが、教科書で説明する必要があります)。

すでに正規表現があり、それをテストしたい場合は、生成された言語を、言語仕様から推定されたNFAの言語と比較できます。正規言語の同等性は決定可能です。等しいかどうかを判断する1つの方法は、それぞれに対して最小の決定論的オートマトンを構築することです。言語が同等の場合、最小DFAは同型になります。


:Googleブックスの検索では、クリーネのアルゴリズムについては、この参照できますbooks.google.co.uk/...
rgrig

0

パーサーを作成している場合、この種のものは字句解析プログラムによって処理されます。そして、これを正規表現で表現するか、または(flex私が見た例のように)単に「基礎となる言語にエスケープ」して、そこで仕事を終えることができます。つまり、/*見つかるまで先にスキップするだけです*/(このためのDFAは簡単に構築でき、そこからCフラグメントを記述するのは簡単です)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.