2009/08/26

Qtで言語を作る (3)

 2回目で挙げた必要なライブラリの中に、入れ忘れていたものがありました。それは、
正規表現
プログラムを書いていても触れる機会が無かったりするものです(無くても書けるから)が、知らないとかなりの時間を浪費すると思います。

 例えば、C言語の変数の仕様を正規表現で表してみる事にしましょうか。仕様自体は、

  1. A〜Z a〜z 0〜9 _(アンダースコア)で表現する。
  2. ただし、先頭の文字は、英字またはアンダースコアで始まる。

と書いてありますので、実際に表現してみるとこんな感じになります。

^[A-Za-z_]{1}[A-Za-z0-9_]*$

{1}は要らないとか、もっと簡潔に書けるよぉって言われそうですが、ここは我慢してください。この表現の詳細を見ていきましょう。各表現は次の様に対応します。

  • ^ => 文字の始めに当てはまる。
  • [ ] => 括弧内にある任意の文字に当てはまる。
  • - => (括弧内にて)文字の範囲を表す。[A-Z]は大文字のA〜Z。
  • { } => 前方に現れた正規表現の繰返しを表す。{3}は3回の繰返し。
  • * => 前方に現れた正規表現の0回以上の繰り返し。
  • $ => 文字の終わりに当てはまる。

となります。これを先の仕様に当てはめると、

  1. [A-Za-z0-9_]*
  2. ^[A-Za-z_]{1}

になりますので、それぞれを足して^[A-Za-z_]{1}[A-Za-z0-9_]*$となる訳です。では、どんなケースでの使用が想定されるのでしょうか。Qtのドキュメントには、

  • 検証
  • 検索と置換
  • 文字列の分割

とありますので、検証をしてみましょう。実際のコードはこうなります。

// QStringはunicode文字列を格納出来るクラス
QString s1 = "x_data";
QString s2 = "0_data";
bool b1,b2;

QRegExp e( "^[A-Za-z_]{1}[A-Za-z0-9_]*$" ); // さっきの正規表現
b1 = s1.contains( e ); // 正規表現にマッチするので、true
b2 = s2.contains( e ); // 正規表現にマッチしないので、false

コメントに書いた様に、b1は真でb2は偽になります。これで、その文字列がC言語仕様上の変数に値するかどうか判定出来る様になりました。

 後は、変数やら文字列定数等の条件を決め、言語を実行する前の検証に使えばOKです。これから作る言語は、単語の定義を^[A-Za-z0-9]+[A-Za-z0-9-_]*$にしようと思います。


0 コメント:

コメントを投稿

Powered By Blogger