Flex2でソースコードをブログに貼り付けるツールを作る(1) - ブログに美しいソースコードを貼り付けよう
- ブログに美しいソースコードを貼り付けよう
- ソースコードをブログに貼り付けるツールを拡張しよう
ソースコードの解析について
当たり前のことですが、ソースコードの構文に色をつけるためには、ある程度、ソースコードの構文を調べる必要があります。かと言って、インタプリタを作るのでは、ありませんので、完全に解析する必要はありません。『「/*」からはじまって「*/」で終わるのが、コメントである』と、この程度の解析ができれば十分でしょう。
そこで、ソースコードの構文解析を行うために、大々的に正規表現を利用することにしました。手軽に、トークン(語句の意味のあるまとまり・文節)分割ができるようなクラスも作りました。
コラム~Flexの開発スタイル
※Flexに詳しくない人のために、少し補足をすると、Flexのプログラミングスタイルは、「HTML + JavaScript」と似ています。HTML + JavaScriptの組み合わせでは、レイアウトをHTMLを作り、そこに動的な要素を加えるために、JavaScript でプログラムを作ります。Flex の場合は、XMLベースのマークアップ言語「MXML」で、レイアウトを作り、「ActionScript3」でプログラムを作っていきます。ActionScript3では、クラスベースのオブジェクト指向を利用することができるのが魅力です。
例えば、JavaScript の強調構文を定義したテーブルは、次のように指定しています。
// 構文定義 table = [ // number ——(*1) new SParserTableItem(/^(\d+\.\d+|\d+)/, STYLE_NUMBER, null), // comment —–(*2) new SParserTableItem(/^\/\*.*?\*\//s, STYLE_REM, null), new SParserTableItem(/^\/\/[^\r\n]*/, STYLE_REM, null), // string ——(*3) new SParserTableItem(/^\”/, STYLE_STRING, readStringDQ), new SParserTableItem(/^\’/, STYLE_STRING, readStringSQ), // word ——–(*4) new SParserTableItem(/^[\w\_][\w\d\_]*/, “”, checkReserveWord), new SParserTableItem(/^[\w\_][\w\d\_]*/, "", checkReserveWord), ]; // 強調語句 reserve_word = [ "var","new","function","null", "break","case","catch","continue","default", "do","else","false","finally","for","function", "if","on","prototype","return","super","switch", // 以下省略..
はじめに、数値の判定を行う指定を詳しく見ていきます。(プログラム中 *1 の部分です。)
JavaScriptで扱う数値は、主に整数と実数です。整数を正規表現で表すと「\d+」となり、実数は「\d+\.\d+」です。これのどちらかにマッチするようにするためには、「(\d+\.\d+|\d+)」となります。
解析処理では、文字列をこの table にあるパターンで1つずつパターンマッチさせていきます。そして、もし、数値のパターンにマッチすれば、そのマッチした部分を切り取って、数値というスタイルを与える(STYLE_NUMBERをセットする)ようにしています。(こうして切り取った文字列を、テキストとスタイルのフィールドを持つクラスで管理しています。)
同様にして、コメント (プログラム中の *2)でも、「/*」から「*/」までにマッチすれば、注釈(STYLE_REM)であるという情報を与えて覚えておきます。
ただし、文字列の解析(プログラム中の *3)は特別扱いしています。文字列のパターンは、「”」から「”」までが基本なのですが、しかし、文字列の中で「”」が使いたい場合には、「\”」と書く決まりがあるのです。そのため、正規表現を使って複雑なパターンを記述するよりは、「”」というパターンが見つかったら、関数「readStringDQ()」を呼び出して、1文字ずつ調べて文字列の範囲を切り取るという処理を行っています。
最後に、一般的な語句を解析しているのが、プログラム中の(*4)です。ここでは、正規表現を使って変数名や予約語などの一般的な語句を切り出していますが、その後に「checkReserveWord()」関数を呼び出すように指定してします。「checkReserveWord()」関数では、切り出した語句が予約語かどうか調べて、予約語ならば、STYLE_KEYWORDを与えるようにしています。
パーサーの切り替え
構文を解析することを「パース(Parse)する」と言いますが、構文を解析するプログラムのことを「パーサー(Parser)」と呼びます。今回は、4種類のパーサークラスを作りました。Flexのパーサー「SParserFlex」、XML/HTMLのパーサー「SParserXML」、JavaScript/ActionScriptのパーサー「SParserJS」です。これらのクラスは、すべて「SParser」を継承して作られています。将来的に、PHPのパーサーを作ろうと思ったら「SParserPHP」などのクラスを作ることになるでしょう。
実際にパーサーの切り替えを行っている部分が以下になります。コンボボックス(type_cmb)の選択肢にパーサークラスの型を設定していますので、「type_cmb.selecteditem.parser」を参照することで、クラスの型を得ることができます。ActionScript3では、型情報からインスタンスを生成することができるのです。
// 解析用クラスを生成 var klass:Class = type_cmb.selectedItem.parser; var instance:* = new klass( source ); var parser:SParser = SParser(instance); var html:String = parser.makeToken().getHtml();
ちなみに、コンボボックスは、以下のように定義しています。
<!– コンボボックスの作成 –> <mx:ComboBox id="type_cmb" dataProvider="{script_type}"/> <!– 選択肢のデータ –> <mx:Array id="script_type"> <mx:Object label="Flex" parser="{SParserFlex}"/> <mx:Object label="JS/AS2/AS3" parser="{SParserJS}"/> <mx:Object label="XML/HTML" parser="{SParserXML}"/> <mx:Object label="CSS" parser="{SParserCSS}"/> </mx:Array>
まとめと今後の抱負
ソースコードをHTMLに変換するツールを作ってみました。将来的な拡張を考慮して、複数の言語に対応できるように、構文規則を正規表現で手軽に指定できることと、カスタム関数を指定できるようにすることで、ある程度、複雑な構文も解析できるように工夫してみました。
JavaScript の強調構文を定義した、SParserJS.as を見ると、関数が2つしかなく、その1つが、初期化関数で、もう1つが正規表現で構文を定義したテーブルと予約語テーブルだけなので、これを参考にして、別の言語に対応するのも難しくないと思います。ですので、対応言語を増やしたり、これを叩き台にして、もっと素晴らしい変換ツールを作ってみるのも良いでしょう。
個人的には、せっかく作ったツールなので、対応言語を増やしたり、より美しいソースが貼り付けられるように改良を加えていこうと考えています。
1 2
このサイトについて
TrackBack URL :

[…] 八角研究所 : Flex2でソースコードをブログに貼り付けるツールを作る(1) … 八角研究所 : Flex2でソースコードをブログに貼り付けるツールを作る(2) - ソースコードをブログに貼り付けるツールを拡張しよう […]
Posted by [Flex][Ruby]Ruby唐辛子 : blog Boreal Kiss | 2008年08月14日 23:16