コンテキスト正規表現カラー表示
Context Regular Expression Coloring (CREC)

2003/11/17 Peggy Version 4.12 (CREC 1.3.1)

株式会社エスコア
兵庫県明石市魚住町中尾337
TEL: 078-946-5609
FAX: 078-946-5552
anchor@anchorsystems.jp
http://www.anchorsystems.jp/


目次

    1. テストバージョンのお礼
    2. はじめに
    3. キーワード定義ファイル
    4. キーワード定義ファイルの記述方法
      4.1 ヘッダ部
      4.2 キーワード部
            キーワードの指定
            文法色の指定
            オプションの指定
      4.3 補完候補部
      4.4 コンテキスト
      4.5 コンテキストとサブ言語
      4.6 デフォルト文法色
    5. 正規表現
      5.1 メタ文字
      5.2 バックトラックと効率
    6. サンプル
    7. 変更履歴

1. テストバージョンのお礼

コンテキスト正規表現カラー表示(CREC)のテストバージョンでは、 数々の貴重なご意見を頂きありがとうございました。 それらを元に、CRECをより便利で有益なものにできたことに感謝しています。

各テスト版からこのバージョン4.06までの変更箇所は、変更履歴にまとめてあります。 今後もご意見をお待ちしております。



2. はじめに

コンテキスト正規表現によるカラー表示(CREC: Context Regular Expression Coloring)の使い方を解説します。 従来から正規表現を使った色づけ表示をサポートしているエディタは幾つかありました。 正規表現は非常に柔軟で強力なツールですが、 それだけでいろいろな言語の文法をサポートするには無理があります。

コンテキスト正規表現とは、コンテキストの状態と正規表現を組み合わせることにより、 テキストファイルのより高度で正確な色分け表示を可能にするまったく新しい技術です。 何行にも続くコメントや文字列も、これだけで自由に定義可能になります。

もちろん、より単純な言語はコンテキストを使わず、 キーワードを書き並べるだけなので、とても簡単に追加できます。

このコンテキスト正規表現は、 従来のPeggyシリーズの色分け表示機能の延長としてインプリメントしました。 従来の言語サポートDLLとまったく同じインターフェイスを介して エディタの描画処理から呼び出されます。 ただし、非常に汎用性の高い機能なので、 DLLとして分離することはせず、 Peggyにビルトインしました。 もちろん従来からあるDLLは、そのまま利用できます。



3. キーワード定義ファイル

コンテキスト正規表現を使って新しい言語の色分け表示を追加するには、 キーワード定義ファイルを作成し、shareフォルダに置きます。 キーワードファイルの名前は、ac_XXXXX.kwdです。 XXXXXの部分は、何のためのキーワード定義ファイルかを想像できる文字列にしておきます。

【例】 ac_make.kwd

1言語に付き1つの.kwdファイルを作成します。 Peggyは起動時にshareフォルダを調べ、 新しいキーワード定義ファイルやDLLがないかどうかをチェックします。

しかし実際の読み込みは、その言語のファイルを開くまで行われません。 いったん定義ファイルを読み込むと、その言語のファイルをすべて閉じてもメモリ上に残ります。

キーワードファイルをPeggy自身で編集して保存した場合は、 自動的に再ロードするので、すぐに結果を確認することができます。 自動再ロードは、[オプション設定]ダイアログボックスの[編集]ページ、 [編集オプション]の[キーワードファイルを自動的に再ロードする]の チェックを外すことで抑止することもできます。

【注意】ただし自動ロードでは、 言語識別名、デフォルト拡張子、デフォルトタブ間隔の変更は反映されません。 これらを変更した場合は、Peggyを再起動してください。

自動再ロードにより読み込む再には、 記述エラー、文法エラーをタグジャンプ可能な形式でアウトプットウインドウに出力します。 エラーがあれば、F4キーを押してジャンプし、修正してから保存しなおしてください。



4. キーワード定義ファイルの記述方法

キーワード定義ファイルは、大きく2つの部分に分かれます。 ヘッダ部とキーワード部です。 なおコメントや空行は、どこに書いてもかまいません。 コメントの形式は、C++言語などと同じで2種類あります。


【例】  // から行末まではコメントです。

        /*
         * ブロックコメントは複数行に渡って記述できます。
         * ...
         */

4.1 ヘッダ部

Peggyが必要とする言語の情報を記述する部分です。 色分け表示以外の情報も含まれますが、 これによって、より便利な編集機能が働くようになります。 以下の項目を1行1項目形式で記述します。 すべてを記述する必要はありません。 不要な項目は省略できます。 項目の名前は大文字小文字を区別しません。

名称意味省略(デフォルト値)
Id: 言語の識別名を指定します。

言語の識別子は、Peggyがその言語を一意に区別するための文字列です。 半角英数(または記号)の1〜10文字を目安に識別名を付けてください。 他の言語と重複しない名前を付けてください。 同じ名前の言語が複数あると、Peggyが混乱してしまいます。 識別名は、一重または二重引用符で囲みます。

【例】Id: "ANSI-C"

以下に現在までに定義した言語の識別名をリストアップしました。 これらの名前は避けるようにしてください。より詳しくは、langlist.pdfを参照してください。

【Peggyビルトイン言語】
TEXT, MAIL, C, C++

【DLL内の言語】
VB, VC++, HTML40, ASP(VBS), ASP(JS), ASP(PHP), JSP, PHP, JavaScript, VBScript Perl5, RC, Ruby, SQL/92, PL/SQL, Pro*C, Pro*C++, Pro*COBOL, Java, LaTeX2e, LaTeX2eNS, Batch, BCC++, COBOL, Delphi, HSP, C/ITRON3, C/ITRON4, Verilog-HDL, Verilog-AMS, VHDL, AS308, AS308S, NC308, MR308, AS30, AS30S, NC30, MR30, AS79, AS79S, NC79, MR79, RASM77, PRE77, NC77, MR77, SRA74, AASM740, ASM45, ASM72, ASM38, ASM96, CC78K0, ST78K0, RA78K0, CC78K0S, RA78K0S, CC900, ASM900, ASM870, APP870, CL870, CC870, ASM870X, APP870X, CL870X, ASM870C, APP870C, 8086, V25, PIC16, PIC17, Z80, SASMZ80, 68000, 68HC11, 6809, SA6809, Gen-ASM

【注意】インクルードファイル中のId:は無視されます。

省略時は、ファイル名のXXXXXの部分を大文字に変換したものが言語識別名となります。
Title: ダイアログボックスなどに表示するための名称を指定します。

言語識別名よりも長い(おおよそ40文字ぐらいまで)、 人が見て正確に内容が理解できる文字列を指定してください。

【例】Title: "ANSI準拠C"

【注意】インクルードファイル中のTitle:は無視されます。

省略すると、言語の識別名と同じになります。
Extensions: ファイルのデフォルト拡張子を指定します。

ファイルの拡張子を指定します。 スペースで区切ることにより複数指定することも可能です。 拡張子の前のドット(.)は記述しないでください。 最初にこのキーワード定義ファイルを読み込んだとき、 または[拡張子マップ]の[デフォルト]ボタンをクリックしたとき、 この情報を使って拡張子マップを初期化します。

【例】Extensions: "c h"

【注意】インクルードファイル中のExtensions:は無視されます。

デフォルト値はありません。
TabStop: デフォルトのタブ間隔を指定します。

最初にこのキーワード定義ファイルを読み込んだとき、 または[拡張子マップ]の[デフォルト]ボタンをクリックしたとき、 この情報を使って初期拡張子マップを作成します。 指定できるタブ間隔の範囲は、2〜32です。

【例】TabStop: 4

【注意】インクルードファイル中のTabStop:は無視されます。

省略すると、8と見なします。
BgColoring: 背景色分け表示を行うかどうかを指定します。

背景色分け表示をONにすると、 コンテキストに従ってある範囲の背景色を変えることができます。 ちょうど、HTMLファイル内のJavaScript部分だけ背景を薄いブルーで表示するような感じです。

【例】BgColoring: on

off
BaseLanguage: 文法的にベースとなっている言語を指定します。

世の中には、祖先は同じだけれど拡張などにより少しずつ異なった「派生」言語が多数存在します。 BaseLanguageには、定義しようとしている言語の祖先となった言語を指定します。 例えば、Delphiのベースとなっている言語は、Pascalです。 色々な組み込みCPU用のC言語はCの方言と考えられるので、ベース言語をCとします。 特に厳密な決まりがあるわけではありませんが、 JSP、ASPなど、HTMLの中に埋め込まれるような言語では、 ここにHTMLを指定することで、 HTML関連のコマンドが有効になります。 ASMとすると、前後のラベルジャンプが有効になります。

【例】BaseLanguage: "C"

現在までのDLLで定義しているベース言語は、以下の通りです。

TEXTテキスト、自然言語
CC言語とその方言
C++C++言語とその方言
JavaJava、J2SE
HTMLHTML、ASP、JSP、PHP、PSP、ASP.NET、ColdFusion
JavaScriptJavaScript
VBScriptVBScript
BasicBasicの派生言語(Visual Basicを含む)
PascalDelphiを含むPascalの派生言語
CSSCascade Style Sheet
PerlPerl
RubyRuby
SQLSQLの仲間
PL/SQLPL/SQL
COBOLCOBOL
BatchDOSバッチファイル
HSPHot Suop Processor
RCWindowsリソースファイル
ASMアセンブリ言語すべて
HDLHDL
VHDLVHDL
XMLXML

TEXT
LineComment: 行コメントの始まりを表す文字列を指定します。

定義しようとしている言語で、行末までをコメントとする文字列を指定します。 ここで指定した文字列は、コメントコマンドを使ってのコメント挿入や削除で使われます。

【例】LineComment: "//"

なし
BlockComment: 複数行に記述できるブロックコメントの開始と終了を表す文字列を指定します。

ここで指定した文字列は、コメントコマンドを使ってのコメント挿入や削除で使われます。 必ず開始と終了の2つの文字列をペアで指定してください。

【例】BlockComment: "/*", "*/"

なし
IdCharacters: 単語上をダブルクリックしたとき、英数字以外に単語の一部と見なす文字を指定します。

言語によって単語を構成する文字セットは微妙に変わります。 ここで英数字以外の文字列を指定すると、 それらも単語の一部として扱うようになります。

【例】IdCharacters: "_#"

なし
IfdefPattern: 条件コンパイル文を認識するための正規表現パターンを指定します。

ここで指定したパターンは、前後条件コンパイル文へジャンプするコマンドで使用されます。 コンマで区切って4つのパターンが必要です。 それぞれ、if、elif、else、endif を探すために使われます。

正規表現を省略することはできません。 もしも該当するものがない場合は、不正な正規表現、 例えば/?/のようなものを指定してください。

【例】IfdefPattern: /^\s*#\s*if/, /^\s*#\s*elif/, /^\s*#\s*else/, /^\s*#\s*endif/

【注意】空の正規表現//は、行コメントの始まりとして解釈されてしまいます。 同じく、/*/ も不正な正規表現ではなく、ブロックコメント/* ... */の始まりと解釈されます。

なし
IncludePattern: インクルードファイルを見つけるための正規表現パターンを指定します。

[インクルードファイルを開く]コマンドは、ここで指定したパターンを 使って、インクルード文を探します。 正規表現パターンには、インクルード文中のファイル名を取り出せるよう、 ファイル名の部分を必ず括弧()で囲んでおきます。 正規表現には複数の括弧を使うことができますが、 ファイル名は最初の括弧で囲むようにしてください。

【例】IncludePattern: /^\s*#\s*include\s+[<"]([^"<>]+)[">]/

なし
HeadingPattern: 関数/ブロックジャンプで前後の見出しとなる位置を見つける正規表現パターンを指定します。

Ctrl+,、Ctrl+. は前後の関数/ブロック/見出しらしい行へジャンプするコマンドですが、 このコマンドのためのパターンを指定します。 このパターンを設定することで、テキストファイルでも見出し(らしい)行へのジャンプが 可能になります。

【例】HeadingPattern: /^\i.*\i\s*\(.*\)\s*$/

見出しパターンは、テキストの見出しアウトライン解析にも使われます。 HeaddingPattern を複数個定義すると、 アウトライン解析のときそれぞれのパターンにヒットした行を階層表示させることが可能です。 最初の HeaddingPattern が大見出し、 次の HeaddingPattern が中見出し、 次が小見出し... とすることで文章の構造と一致した見出しアウトライン解析ができます。 何レベルまで解析するかの深さの制限はありません。

【例】HeadingPattern: /^第\d+部/
HeadingPattern: /^第\d+章/
HeadingPattern: /^第\d+節/

なし
Const 定数を宣言します。 数値、文字列("..." または '...')、正規表現(/.../)に名前を付けて定数として宣言できます。 数値定数を宣言するときは、+、-、*、/ を用いた式により値を指定できます。

定数名には、英数字と下線文字(_)が使えます。ただし名前の先頭に数字を使うことはできません。 定数名の大文字小文字は区別しません。MY_SUBLANG も My_Sublang も同じ定数と見なします。

【例】Const MY_SUBLANG = 5
Const MY_CONTEXT = 128 * MY_SUBLANG
Const ENTER_PATTERN = /<%=?/
Const LEAVE_PATTERN = /%>/

宣言した定数は、宣言行以降の数値や文字列、正規表現が使える所ならどこでも使えます。

なし
Include ファイルをインクルードします。 絶対パスで指定してあるときはそのファイルを、 相対パスで指定してあるときは、現在のファイルから相対とみなします。 ファイルのインクルードは、最大4レベルまで可能です。

【例】Include "HTMLBASE.kwd"

【注意】インクルードするファイル名は、<ac_XXXX.kwd>としないでください。 この形式以外の名前を使うことにより、単独で言語定義ファイルとならないようにできます。 また、インクルードファイルの中にId:Title:Extensions:TabStop:を記述しても無視されます。 これはら必ずインクルードする側のファイルで定義してください。

なし

4.2 キーワード部

キーワード部には、キーワードを表す文字列または正規表現と、 どの文法色で表示するかの指定、 それに幾つかのオプションを1行1キーワード形式で記述します。

各行に記述する順番は、(1)キーワード、(2)文法色、(3)オプションです。 (3)オプションは省略できます。 各項目は、必ずコンマ(,)で区切ってください。 オプションが複数ある場合も、間をコンマ(,)で区切ります。


【例】"class", FgKeyword, "クラスを定義する"

キーワードはファイルの先頭から順番にテストされ、 一致したものがあれば、その部分を指定した文法色で表示します。 つまり、先に定義しているものが優先します。

キーワードの指定

(1)キーワードには、以下の4通りの記述方法があります。

種類表記法意味
二重引用符 " ... " 二重引用符の中で指定された文字列を単語として扱います。 すなわち、指定された文字列が長い単語の一部に現れるような場合を除外します。 二重引用符内の文字は、そのままその文字にマッチします。 例外として円記号(\)はエスケープ文字と解釈され、 コントロールコードや二重引用符自身を含めるのに使うことができます。
一重引用符 ' ... ' 一重引用は、二重引用符とほぼ同じですが、 単語のどの一部でもマッチする点が唯一異なります。
正規表現 / ... / / から / で指定された正規表現パターンにマッチする部分を その色で表示します。 / と / の間には、任意の正規表現を記述できますが、 その結果0文字マッチしてしまった場合は、無視されます。 正規表現の一部にスラッシュ(/)を含める必要がある場合は、 円記号(\)を直前においてください(例: /\/\//)。

【注意】 複数行にまたがるパターンを指定することはできません。 改行(\n、\r、\r\012、\012)を含むパターンも指定できません。 行を超える部分を色づけするには、コンテキストを使います。

【注意】 文字に色を付けるための正規表現パターンなので、 結果として0文字にマッチしてしまった場合は無視されます。 ただし、行末を指定するパターン/$/は例外として処理します。

行末 /$/ 正規表現の一種で、行末(改行の直前)の0文字にマッチします。 0文字なので色を指定しても表示する文字はありません。 その代わり、コンテキストと背景カラーを行っているとき、 行末でコンテキストを切り替えるタイミングを捕まえるために使います。

【注意】 行頭を表す/^/は、0文字にマッチするため無視されます。 GoTo、PostGoTo 指定も無視されてしまうので、 コンテキスト切り替えとしても使えません。 前行の行末(/$/)でコンテキストを切り替えるようにしてください。

以上どの表記法の場合でも、直後にi(ignore case のi)を付けると英大文字小文字を区別しません。


【例】  "True"i,      FgKeyword  // True、TRUE、true などにマッチ
        'False'i,     FgKeyword  // False、FALSE、false などにマッチ
        /Null/i,      FgKeyword  // Null、NULL、null などにマッチ

文法色の指定

文法色は、文法の要素を表す整数値です。 予め定義されている名前を使って、より分かりやすく指定するとこもできます。 各文法色の実際の色設定は、[オプション設定]ダイアログボックスの[表示色]ページで行います。

以下は、文法色と予め定義されている名前の一覧です。 文法色の名前は、表示色を保存したファイル(.COLファイル)内で使われている名前と同じです。 キーワード定義ファイル編集中は、文法色の名前をキーワード補完(Ctrl+/)により簡単に入力できます。

文法色番号文法色名称表示色
0FgText文法 - 一般の文字
1FgComment文法 - コメント
2FgString文法 - 文字列
3FgCharacter文法 - 文字
4FgHTMLTag文法 - HTML タグ内テキスト
6FgNumber文法 - 数値定数
7FgIdentifier文法 - 識別子/変数/関数/ラベル
8FgKeyword文法 - キーワード
9FgInstruction文法 - CPUインストラクション
10FgRegister文法 - CPUレジスタ
11FgPreprocessor文法 - プリプロセッサ命令
12FgUserKeyword1文法 - ユーザ定義キーワード1
13FgUserKeyword2文法 - ユーザ定義キーワード2
16FgHTMLElementName文法 - HTML エレメント名
17FgHTMLAttributeName文法 - HTML アトリビュート名
18FgHTMLDelimiter文法 - HTML タグデリミタ
19FgHTMLURL文法 - HTML URL
20FgHTMLEntity文法 - HTML エンティティ
21FgSystemCall文法 - システムコール
22FgSystemType文法 - システムデータ型
23FgSystemSymbol文法 - システムシンボル
24FgBuiltinFunction文法 - 組み込み関数
25FgPredefinedSymbol文法 - 定義済み変数
26FgRegularExpression文法 - 正規表現
27FgSequenceNumber文法 - シーケンス番号
28FgHTMLIllegalCharacter文法 - HTML 不正テキスト文字
30FgAux1文法 - 予備1
31FgAux2文法 - 予備2
32FgAux3文法 - 予備3
33FgAux4文法 - 予備4
34FgAux5文法 - 予備5
35FgAux6文法 - 予備6
36FgAux7文法 - 予備7
37FgAux8文法 - 予備8
38FgAux9文法 - 予備9
39FgAux10文法 - 予備10
40FgAux11文法 - 予備11
41FgAux12文法 - 予備12
42FgAux13文法 - 予備13
43FgAux14文法 - 予備14
44FgAux15文法 - 予備15
45FgAux16文法 - 予備16
46FgAux17文法 - 予備17
47FgAux18文法 - 予備18
48FgAux19文法 - 予備19
49FgAux20文法 - 予備20
50FgAuxComment1文法 - 予備コメント1
51FgAuxComment2文法 - 予備コメント2
52FgAuxComment3文法 - 予備コメント3
53FgAuxComment4文法 - 予備コメント4
54FgAuxComment5文法 - 予備コメント5
55FgAuxString1文法 - 予備文字列1
56FgAuxString2文法 - 予備文字列2
57FgAuxString3文法 - 予備文字列3
58FgAuxString4文法 - 予備文字列4
59FgAuxString5文法 - 予備文字列5

オプションの指定

各キーワードに関連する3つのオプションがあります。 間をコンマで区切れば、任意の順番で指定できます。

種類記述方法動作
キーワードチップ " ... " または
' ... '
キーワードチップとして表示する文字列を指定します。 編集中にキーワードチップを指定してあるキーワード上にマウスカーソルを移動させると、 ここで指定した文字列を一定時間チップ表示します。 キーワードチップは、1つのキーワードの1つだけ指定できます。
補完候補 @" ... " または
@' ... '
アット記号(@)に文字列が続いていると、このキーワードの補完候補であると解釈し、 キーワード補完(Ctrl+/)で使われます。

この指定を省略すると、キーワード自身が補完候補として使われます。 逆に、このキーワードの補完候補を表示したくない場合は、@off と指定してください。

キーワードだけでなく、それに続く部分も一気に補完したい場合に便利です。 補完候補は、1つのキーワードに1つだけ指定できます。 複数の補完候補を設定する場合には、「補完候補部」を参照してください。

【例】@"if (\c) {"

補完候補の文字列中では、補完後のカーソル位置を指定する特別なエスケープ文字(\c)が使えます。 もしも\cが複数あると、補完後には最初の\cと最後の\cの間の文字を選択します。

もう1つ特殊なインデントすることを指示する特殊なエスケープ文字(\i)があります。 \iは、補完を開始した行と同じ量のインデントをする空白文字に置き換えられます。 \iを使うことで、複数行の補完候補を編集中のテキストに合わせて挿入することが可能です。

【例】@"if (\c)\n\i{\n\i}\n"

【注意】 カーソル位置とインデント表す\c、\iは、 それぞれアスキーコードの127、1に変換されます。 従ってこれらの文字を補完で入力することはできません。

コンテキスト切り替え GoTo <コンテキスト番号または式>

または

PostGoTo <コンテキスト番号または式>
このキーワードや正規表現パターンにマッチすると、 コンテキストを<コンテキスト番号または式>(1〜1023の数値)で指定したものへ切り替えます。 GoToとPostGoToの違いは、 コンテキストがマッチした部分の直前で切り替わる(GoTo)か、 直後で切り替わる(PostGoTo)だけです。 例えば、前者はC言語のブロックコメントの開始パターン(/*)で コンテキストを/*の直前から切り替え、 後者は終了パターン(*/)の直後で切り替える場合に使用します。

コンテキスト切り替え指定のあるキーワードが見つかると、 以降のコンテキストが<コンテキスト番号>に遷移し、 そのコンテキスト用として定義されたキーワードだけを検索するようになります。

行末指定/$/と組み合わせて使う場合、 GoToは改行の直前から、PostGoToは改行の後でコンテキストが切り替わります。 これらを使い分けることで、背景色を改行の直前までとするか、 ウインドウの右端までとするかを選ぶことができます。

GoTo、PostGoTo による切り替え先コンテキストの指定には、 定数、+、-、*、/、%(剰余)演算子を使った任意の式を使うことができます。 *、/、%演算子は、+、-に優先して評価されます。

【例】GoTo MY_CONTEXT + 5

相対コンテキスト切り替え GoTo [+|-]<コンテキスト番号の増分または式>

または

PostGoTo [+|-]<コンテキスト番号の増分または式>
コンテキストを<コンテキスト番号の増分または式>だけプラス、またはマイナスします。 相対的にコンテキストを増減させたいときに使います。

GoTo、PostGoTo による相対コンテキストの指定には、 定数、+、-、*、/、%(剰余)演算子を使った任意の式を使うことができます。 *、/、%演算子は、+、-に優先して評価されます。

【注意】 GoTo、PostGoTo の直後にプラス(+)、またはマイナス(-)記号があるときは、 これらの記号は相対切り替えの印と見なされ、以下のように評価されます。 特にマイナス記号は、通常の単項マイナス演算子と結果が異なってしまいますので、 注意してください。

【例】GoTo + MY_CONTEXT + 1GoTo +(MY_CONTEXT + 1)
GoTo - MY_CONTEXT + 1GoTo -(MY_CONTEXT + 1)

4.3 補完候補部

キーワード補完の候補は、各キーワードのオプションとして指定できますが、 同じキーワードに複数の補完候補を用意したい場合があります。 そのときは、@" ... "、または @' ... ' を独立して1行に記述します。


【例】@"#include <\c>"
      @'#include "\c"'

これら独立した補完候補も、直後にi(Ignore Case)オプションをつけることで、 大文字小文字の区別をなくすことができます。


【例】@"<font \c>"i  // <font、<FONT、<Fontにもヒットする

さらに、Context { ... } の中で定義してある補完候補は、 そのコンテキストでキーワード補完コマンド(Ctrl+/)を実行したときだけ ピックアップされます。 すべてのコンテキストで有効な補完候補を定義するには、 Context { ... } の外で定義してください。

4.4 コンテキスト

あるキーワード、またはキーワードのグループを 特定のコンテキストのときだけ有効であることを指定する機能です。 キーワードのGoTo、PostGoToオプションと組み合わせて、 複雑な言語の色分け表示をする場合に威力を発揮します。

コンテキストは、1〜1023の数値で表します。 ファイル先頭でのコンテキストは、常に1です。 2〜1023のコンテキストは、 キーワード定義ファイルを作成する人が自由に使うことができます。

以下の記法によりキーワードのコンテキストを指定します。


    Context 10:
    {
        // コンテキスト10で有効となるキーワードの定義
        "Extended", FgKeyword
        "End", FgKeyword, PostGoTo 1
    }

上記の例では、{ と } の間で定義されているキーワードがコンテキスト10専用となり、 他のコンテキストのときは無視されます。 さらに、コンテキスト10のときにキーワードEndに遭遇すると、 Endをキーワード色として表示し、 その直後にコンテキスト1へ遷移することを指定しています。

Context文には、複数のコンテキストや...を使って コンテキストの範囲をまとめて指定するとができます。 各コンテキストや範囲は、コンマで区切ります。 定数名や式を使ってコンテキストを指定することも可能です。


    Context 10, 15, 20..31:
    {
        // コンテキスト10, 15, 20〜31の時に有効となるキーワードの定義
        ...
    }

    Context MY_LANG .. MY_LANG + 10, YOUR_LANG .. YOUR_LANG + 10:
    {
        // コンテキストMY_LANG .. MY_LANG + 10, YOUR_LANG .. YOUR_LANG + 10
        // の時に有効となるキーワードの定義
        ...
    }

さて、Context { ... } の外で定義されているキーワードはどうなるのでしょう。 これらのキーワードは、コンテキストによらず常にテストされます。 つまり、Context 1..1023: { ... } の内部に記述されているのと同じです。

【メモ】 コンテキストを入れ子にすることはできません。
【注意】 バージョン3.30からコンテキストの範囲が、 それまでの1〜255から1〜1023に拡大しました。

4.5 コンテキストとサブ言語

HTMLファイル内のJavaScript言語などのように同じファイル中に 複数の異なった言語が埋め込まれている場合など、 その部分の背景色を変化させると非常に見やすくなります。 DLLでサポートしている「WWW HTML4.0 (W3C)」などがその例です。 コンテキストを使えば、このような色分け表示も定義できます。

Peggyでは、7種類のサブ言語の背景色を変えて表示できる機能が備わっています。 ヘッダ部のBgColoring: を on にすることで、この機能が有効になります。

サブ言語1〜7の背景色は、予め特定のコンテキストの範囲と結びついています。 以下のその範囲を示します。

サブ言語コンテキストの範囲定義済み定数定義済み定数の値
基本言語1 〜 127
1128 〜 255SubLang1128
2256 〜 383SubLang2256
3384 〜 511SubLang3384
4512 〜 639SubLang4512
5640 〜 767SubLang5640
6768 〜 895SubLang6768
7896 〜 1023SubLang7896

つまり、各サブ言語に付き128のコンテキストの範囲があり、 その範囲にコンテキストがあるときは、 背景がそのサブ言語の色で表示されるわけです。 逆に言えば、サブ言語の背景色を変えたいときは、 それぞれのサブ言語の範囲を意識しながら コンテキスト番号を割り当てる必要があります。

コンテキスト1〜127は基本言語と解釈され、普通の背景色、 または編集禁止テキストの背景色で表示されます。

ヘッダ部のBgColoring: が off (デフォルト)のときは、 背景カラーリング機能が働きません。 この場合、すべてのコンテキスト(1〜1023)を 背景色を考えることなく自由に割り当てることができます。

4.6 デフォルト文法色

コンテキスト指定 Context { ... } の中には、 そのコンテキストでどのパターンにも一致しなかった場合の文法色を指定することができます。

現在のコンテキストに対応しているすべての正規表現がテストされ、 それでも一致するものがなければ、 defaultで指定した文法色と判定します。 つまり、キーワードファイルのどこに記述されているかにかかわらず、 正規表現パターンによる色指定が優先します。 同じコンテキスト番号に対して複数のdefault指定がある場合、 default指定同士の優先順位は、キーワードファイル内での定義順です。

default文法色指定を、コンテキスト指定 Context { ... } の外に置くことはできません。 同じ Context { ... } に複数のdefault指定があった場合は、 最初のものが有効となります。 また、行末を表す/$/は0文字にマッチするので、 文法色による色付けの対象となる文字はありません。 そのため、/$/, GoTo 10 のように文法色指定を省略してもかまいません。

以下の例では、コンテキスト5のときに一致するパターンがなければ、 その文字をコメント色で表示することを指定しています。 デフォルト文法色を使わない参考例と比較して、 ブロックコメントの途中と終りの指定がわかり易く効率的に記述できています。


【例】Context 5: // デフォルト文法色を使った指定
      {
          '*/',     FgComment, PostGoTo 1
          default, FgComment  /* ブロックコメント内のデフォルト文法色 */
      }

【参考例】
      Context 5: // 正規表現だけで指定した場合
      {
          /.*?\*\//,  FgComment, PostGoTo 1  /* ブロックコメントの終り */
          /.*/,       FgComment              /* ブロックコメントの途中 */
      }




5. 正規表現

コンテキスト正規表現をサポートするにあたり、 Peggy自身の正規表現をかなり拡張しました。

5.1 メタ文字

以下にメタ文字をまとめておきます。

メタ文字意味
繰り返し * 0回以上の繰り返し(最長マッチ)
*? 0回以上の繰り返し(最短マッチ)
+ 1回以上の繰り返し(最長マッチ)
+? 1回以上の繰り返し(最短マッチ)
{m} ちょうどm回の繰り返し
{m,n} m回以上n回以下の繰り返し(最長マッチ) m、またはnを省略したときは、それぞれ0、無制限とみなす。
{m,n}? m回以上n回以下の繰り返し(最短マッチ) m、またはnを省略したときは、それぞれ0、無制限とみなす。
グルーピングと選択 (...) グルーピング
| 選択 (OR検索)
文字クラス
(メモ1参照)
. 改行以外の任意の文字
[ ] 文字クラス
[^ ] 補文字クラス
[:alnum:] POSIX名前による文字クラス※注意1 - アルファベットと数字
[:alpha:] POSIX名前による文字クラス※注意1 - アルファベット
[:ascii:] POSIX名前による文字クラス※注意1 - UASCII文字セット
[:blank:] POSIX名前による文字クラス※注意1 - 空白、タブ
[:cntrl:] POSIX名前による文字クラス※注意1 - 制御文字
[:digit:] POSIX名前による文字クラス※注意1 - 数字
[:graph:] POSIX名前による文字クラス※注意1 - 空白、タブ、制御文字以外
[:lower:] POSIX名前による文字クラス※注意1 - 小文字
[:print:] POSIX名前による文字クラス※注意1 - 印刷可能文字
[:punct:] POSIX名前による文字クラス※注意1 - 区切り文字、句読点
[:space:] POSIX名前による文字クラス※注意1 - 空白、改行、リターン文字
[:upper:] POSIX名前による文字クラス※注意1 - 大文字
[:xdigit:] POSIX名前による文字クラス※注意1 - 16進文字
[:zenkaku:] POSIX風名前による日本語文字クラス※注意1 - 全角文字
[:kanji:] POSIX風名前による日本語文字クラス※注意1 - 全角漢字
[:hirakana:] POSIX風名前による日本語文字クラス※注意1 - 全角ひらかな
[:katakana:] POSIX風名前による日本語文字クラス※注意1 - 全角カタカナ
[名前による:hankakukana:] POSIX風日本語文字クラス※注意1 - 半角カタカナ
[:^alnum:] POSIX風名前による補文字クラス※注意1 - アルファベットと数字以外
[:^alpha:] POSIX風名前による補文字クラス※注意1 - アルファベット以外
[:^ascii:] POSIX風名前による補文字クラス※注意1 - UASCII文字セット以外
[:^blank:] POSIX風名前による補文字クラス※注意1 - 空白、タブ以外
[:^cntrl:] POSIX風名前による補文字クラス※注意1 - 制御文字以外
[:^digit:] POSIX風名前による補文字クラス※注意1 - 数字以外
[:^graph:] POSIX風名前による補文字クラス※注意1 - 空白、タブ、制御文字
[:^lower:] POSIX風名前による補文字クラス※注意1 - 小文字以外
[:^print:] POSIX風名前による補文字クラス※注意1 - 印刷できない文字
[:^punct:] POSIX風名前による補文字クラス※注意1 - 区切り文字、句読点以外
[:^space:] POSIX風名前による補文字クラス※注意1 - 空白、改行、リターン文字以外
[:^upper:] POSIX風名前による補文字クラス※注意1 - 大文字以外
[:^xdigit:] POSIX風名前による補文字クラス※注意1 - 16進文字以外
[:^zenkaku:] POSIX風名前による日本語補文字クラス※注意1 - 全角文字以外
[:^kanji:] POSIX風名前による日本語補文字クラス※注意1 - 全角漢字以外
[:^hirakana:] POSIX風名前による日本語補文字クラス※注意1 - 全角ひらかな以外
[:^katakana:] POSIX風名前による日本語補文字クラス※注意1 - 全角カタカナ以外
[:^hankakukana:] POSIX風名前による日本語補文字クラス※注意1 - 半角カタカナ以外
\w 単語の文字 [A-Za-z0-9_]と同等
\W 単語の文字以外 [^A-Za-z0-9_]と同等
\s 空白文字 [\t-\r  ]と同等 (全角スペースも含む)
\S 空白文字以外 [^\t-\r  ]と同等
\d 数字 [0-9]と同等
\D 数字以外 [^0-9]と同等
\z 全角文字
\Z 全角以外の文字
\k 漢字
\K 漢字以外の文字
\h 全角ひらがな
\H 全角ひらがな以外の文字
\j 全角カタカナ
\J 全角カタカナ以外の文字
\y 半角カタカナ
\Y 半角カタカナ以外の文字
アンカー ^ 行頭にマッチ
$ 行末にマッチ (文字列の最後か、CRまたはLFの直前)
\b 単語境界にマッチ (\w と \Wの間)
\B 単語境界以外にマッチ (\w、または\Wが連続している途中)
\< 単語の先頭にマッチ
\> 単語の末尾にマッチ
エスケープ文字 \a BEL (0x07)
[\b] (メモ2参照) BS (0x08)
\t HT (0x09)
\n LF (0x0A)
\v VT (0x0B)
\f FF (0x0C)
\r CR (0x0D)
\e ESC (0x1B)
\OOO 3桁の8進数で文字コードを指定
\xHH 3桁の16進数で文字コードを指定
\.、\*、\+、\(、\)、\{、\}、\|、\[、\]、\^、\$, \\ それぞれのメタ文字の意味を取り消し、 文字そのものを指定
定義済みパターン \i C言語風のシンボルにマッチ
[A-Za-z_][A-Za-z0-9_]* と同等
\l アセンブラなどのラベルにマッチ
[A-Za-z_][A-Za-z0-9_]*[ \t]*: と同等
\q 二重引用符で囲まれた文字列にマッチ
".*" と同等
【メモ1】\w、\d、\kなどの定義済み文字クラスも文字クラス[...]の中で使えます。
【メモ2】\bは単語境界と解釈されるため、バックスペースを指定するには、[\b]としてください。
【注意1】POSIX名前による文字クラス、 名前による日本語文字クラス、およびそれらの捕文字クラスは、 文字クラス[]と補文字クラス[^]の中でだけ使用することができます。 名前による文字クラスは、システムのロケールによってヒットする文字集合が変わることがあります。

5.2 バックトラックと効率

Peggyの正規表現は、バックトラック法を採用しています。 バックトラック法はマッチした部分を後から取り出したりと、 柔軟な応用が可能ですが、特定パターンでのマッチングスピードが 極端に遅くなるという問題点もあります。 特にグループの内と外に繰り返し指定がある場合は、 指数関数的に計算量が増えるので要注意です。

例えば、/(.+)*X/ という正規表現パターンをaが100文字続く文字列に マッチさせようとすると、 (結局は失敗するのですが)おそらく今世紀中には終わりません。 このようなパターンが必要になる場合は、特に注意してください。

その良い(悪い?)例として、文字列の中に\"で引用符自身を含めることができるC言語の文字列があります。 このような文字列パターンを正規表現で率直に表すと、


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

でうまく行きそうです。 確かに両端に引用符"がある場合は、これでもそこそこのスピードで処理できます。

しかし終わりの"がない場合は、 文字列の長さに従って指数関数的にバックトラック回数が増加し、 画面の更新はおろか、Peggy全体が固まってしまいます(数秒から数百年すると再び動き出すかもしれません)。 テキストエディタは編集する道具なので、 終わりの"がない状態も瞬時に扱えなくてはなりません。 それには少々の工夫が必要です。

まず、バックトラック法の正規表現では、 これを次の様に書き換えます。


    /"[^"\\]*(\\.[^"\\]*)*"/

この書き換えによりバックトラックの回数が指数関数的に増えることを避けられるので、 画面の更新が止まることがなくなります。

さらに、閉じ引用符を入力するまでは行末までを文字列として 処理させるために、閉じ引用符に?を付けておきます。


    /"[^"\\]*(\\.[^"\\]*)*"?/

これにより、閉じ引用符がない場合は行末まで一致し、 バックトラックがほとんど発生しなくなります。 また文字列を閉じ忘れた場合でも、 行末までが文字列色で表示されるため、 より直感に近い色づけとすることができます。

バックトラック量の見極め方や避ける方法は、 O'REILLY社から出版されているJeffrey E. F. Friedl著「詳説・正規表現」が参考になります。 または、サポート会議室で議題にしてください。



6. サンプル

以下のサンプルを添付しました。 必要に応じてshareフォルダにコピーしてください。

言語 ファイル名 説明
ASP.NET(C#) ac_ASPCS.kwd
HTMLBASE.kwd
ASP.NET(C#)の定義ファイルです。
HTML、VBScript、JavaScript、CSSの混在言語色分け表示の基本部分を定義してある<HTMLBASE.kwd>をインクルードし、 それに<% ... %>に囲まれたC#の色分け表示を追加する高度なサンプルです。
Constによる定数の宣言や式によるコンテキスト値の指定など、 CREC 1.3から追加された機能を多用しています。 ac_ASPCS.kwdを参考にすれば、HTMLBASE.kwdを共有してASP.NET(VB)やASP.NET(C++)も簡単に作成できます。
Keyword ac_kwd.kwd キーワード定義ファイル自身の色分け表示定義です。
キーワードチップや補完候補も定義されているので、 キーワードファイルを作成するときに役立つはずです。
各キーワードの終わりにはiが指定してあるため、 大文字小文字の区別がないことがわかります。
"..."文字列や正規表現/.../にマッチさせる 正規表現は、エスケープ文字(\)を考慮したものになっているので、 他の言語を作成するにもこの方法が応用できるでしょう。
C# ac_cs.kwd C#のキーワード定義ファイルです。
ブロックコメントや複数行にわたる文字列(@"...")が参考になるかもしれません。
XML ac_xml.kwd XML、XSLのキーワード定義ファイルです。
コンテキストを多用して、HTML形式のコメント、タグの内外、 タグ中の文字列("..."、'...')、エンティティ、 あまり好ましくない文字などを色分け表示します。 背景カラーリングとコンテキスト切り替えの参考になります。 PeggyのHTML関連コマンド、コメント操作コマンドも機能します。
Item ac_item.kwd テキストの見出しと思われる行の背景色を変えて表示します。 メールを引用していると思われる行は、別の背景色とテキストの色を変えます。 その他に、URLやEメールアドレスと思われる部分を別の色で表示します。 行末でのコンテキスト切り替え(/$/)や、コンテキストのデフォルト色指定の参考になります。
KYOIKU ac_kyoiku.kwd 小学校1〜6年で学習する漢字、常用漢字、それ以外の漢字の色を指定して表示します。 編集しながらリアルタイムに何年生で学習する漢字か知ることが可能です。 各漢字の色は、[予備1](1年生)〜[予備6](6年生)、[予備7](常用漢字)、[予備8](その他漢字)で指定します。
GAWK ac_gawk.kwd GAWKのサンプルです。コンテキスト使い、 割り算記号としての/と、正規表現の始まりとしての/を区別しています。
ANSI-C ac_ANSIC.kwd ANSI-Cのサンプルです。 相対コンテキスト切り替えを使って、ブロックコメントを処理しています。 これをベースに好みのC/C++言語色分け表示に発展させることも可能です。
JavaDoc ac_javadoc.kwd Javaの埋め込みドキュメント/** ... */内部も色分け表示します。
行コメント(//)、複数行にわたるブロックコメント(/* ... */)、 内部にHTML形式のドキュメントを埋め込んだ特殊なブロックコメント(/** ... */)を区別し、 さらに /** ... */ 内部のドキュメントのためのキーワードを色分け表示する、 少し高度なサンプルです。
J2SE ac_J2RE.kwd JavaDocに加え、J2SEのクラス名を追加しました
2000近くのキーワードを登録した場合の描画速度などの参考になります。 このくらいであれば、まずまずのスピードで処理できているようです。
Fortran90 ac_f90.kwd 完全ではありませんが、一応Fortran 90のソースを色分け表示できています。
整数や浮動小数点数にマッチさせる正規表現などが参考になるかもしれません。
MAKE ac_make.kwd Makefileのキーワード定義ファイルです。
【メモ】従来Peggy本体に組み込まれていたMakefileの色づけですが、 それほど重要ではないため、定義ファイルとして外部に出しました。




7. 変更履歴

Peggy 4.12、CREC 1.3.1 (2003/11/17)の変更点
1. 正規表現にPOSIX文字クラスを追加しました。
Peggy 4.06、CREC 1.3.0 (2002/11/15)の変更点
1. Include文を追加し、他のファイルをインクルードできるようになりました。
2. Const文を追加し、定数を宣言できるようになりました。 数値、文字列("..."、'...)、正規表現(/.../)を定数として宣言できます。
3. コンテキストの指定など数値を指定するところで任意の式が記述できるようになりました。
4. サブ言語の開始コンテキスト番号を表す定義済み定数(SubLang1〜SubLang7)を追加しました。
Peggy 4.00、CREC 1.2.0 (2002/3/15)の変更点
1. コメント、文字列部分の色分けを強化するFgAuxComment1〜5、FgAuxString1〜5を追加しました。 内部を色分けされたコメントでも、全体をコメントして編集処理をすることができようになりました。
Peggy 3.30、CREC 1.1.0 (2001/10/18)の変更点
1. CRECに独自のバージョン番号を付けることにしました。 Peggy 3.30に搭載しているCRECのバージョンは、1.1.0です。 Peggyのバージョンが変わってもCRECのバージョンが変わらなければ、 外からみたCRECの仕様に変化がないことを意味しています。 仕様上の変更がなくてもバグフィックスなどにより見えない修正があった場合は、 末尾の番号を+1します。
2. 有効なコンテキストの範囲を、1〜1023に拡大しました。 それと同時に基本言語、サブ言語のコンテキスト範囲を32から128へ拡大しました。
3. 大文字小文字を区別しないときの正規表現検索で、 [A-Z]のような文字クラスが正しく検索できない問題点をフィックスしました。
4. FgAux11〜20が[予備1〜10]にマップされていた問題点をフィックスしました。
Peggy 3.24 正式リリース版、CREC 1.0.0 (2001/7/30)の変更点
1. キーワードファイルを保存すると同時に再ロードする、 「自動再ロード」機能を追加しました。
2. 自動再ロードで見つけたエラーをアウトプットウインドウへ タグジャンプ可能な形式で出力するようにしました。 ただし、エラーメッセージは再ロードのときだけで、 その言語のファイルを開いたためにキーワードファイルがロードされるときは出力されません。
3. 括弧を多用した複雑な正規表現で、 正しくマッチしないことがある問題点をフィックスしました。
4. キーワードファイルのヘッダに HeadingPattern を追加し、 関数/ブロックジャンプで見出し位置を見つけるための正規表現パターンを記述できるようにしました。
5. 相対コンテキスト切り替え(GoTo +/-<増減分>)で、 正しいコンテキストへ切り替えられないことがある問題点をフィックスしました。
6. ANSI-Cのサンプルを改良し、 文字/文字列リテラルを改行直前の円記号(\)で 次行へ続けられるという文法に対応させました。
7. Context { ... } 内で定義した補完候補(@"...")が、 コンテキストに関係なくピックアップされていた問題点をフィックスしました。
8. 補完候補の記述でインデントをサポートしました。 補完候補の中に\iを記述することにより、 補完を始めた部分と同じ量のインデントを\iの位置に挿入します。
9. [表示色]ページのサブ言語にも独自のラベルを付けることができるようにしました。 背景色を何に使っているのかをメモできます。
テストバージョン4 (2001/7/17)の変更点
1. 予備色の名前をFgReservedからFgAuxに変更し、数も20へ増やしました(FgAux1〜FgAux20)。 旧名称であるFgReservedも受付ますが、今後はFgAuxを使うようにしてください。 これにあわせて、色保存のファイル(.COLファイル)の予備色も、FgReservedからFgAuxに変更しました。 こちらも旧名称で保存してあるファイルも読み込めます。

【注意】 予約色の数を増やしたことにより、レジストリ中のデータ形式が一部変更になりました。 正式版3.23からCREC TEST-4版への上位互換性はありますが、 CREC TEST-4から3.23へ戻すと設定していた色がリセットされてしまいます。 CREC TEST-4を実効する前に、現在の色設定を保存しておいてください。

2. カラーだけでは表現力に限界が出てきたので、二重打ちによる強調表示をサポートしました。 オプション設定ダイアログボックスの[表示色]ページから選択できます。
3. [オプション設定]ダイアログボックス[表示色]ページの予備色1〜20に、 独自のラベルを設定できるようにしました。 予備色が何を意味するのかが一目でわかるようになります。 ラベルを設定するには、予備色が選択されている状態で、 [文法 - 予備1]の後をクリックしてください。 または、選択してからF2キーでも編集できます。
4. 小学校一年〜六年で学習する教育漢字を、 それぞれ[予備1]〜[予備6]の色で表示するサンプルac_kyoiku.kwdを追加しました。 それ以外の常用漢字を[予備7]、 どれにも含まれない漢字を[予備8]で色分け表示します。
5. コンテキストを相対的に変更する、GoTo +1、PostGoTo -32 のような相対指定方法を追加しました。 入り口と出口は異なるが、その中でのキーワードやそれらのコンテキスト切り替えは同じという場合、 それらの正規表現をまとめることができます。
6. 行末でのコンテキスト切り替えで、文法色指定を指定しなくてよいように変更しました。 行末は0文字にマッチするので、文法色を指定してもその色で表示する文字がないため無意味でした。
7. コンテキスト切り替えの例として、GAWKで割り算の/と正規表現の/.../を区別するサンプルを追加しました。
8. 相対コンテキスト切り替えの例として、ANSI-Cを追加しました。
テストバージョン3 (2001/7/12)の変更点
1. 正規表現の最後が単独の\で終わっていた場合にクラッシュする問題点をフィックスしました。
2. 背景カラーONでサブ言語中のコメントを削除/解除しようとしたときにクラッシュする問題点をフィックスしました。
3. Javaのクラス名まで含んだサンプル定義ファイルac_J2SE.kwdを追加しました。
4. C#、JavaDocのサンプルで、定義順の問題から0xで始まる16進数を正しく認識できなかった問題点をフィックスしました。
テストバージョン2 (2001/7/10)の変更点
1. 正規表現でグループの最短一致繰り返しをサポートしました。
2. 正規表現で単語の先頭、末尾にマッチする\<、\>を追加しました。
3. 正規表現をチューニングし、メモリ節約、検索スピードがアップしました。
4. 正規表現ではない通常の文字列検索もスピードアップしました。
5. 行末を意味する /$/ でのコンテキスト切り替えをサポートしました。
6. コンテキストのデフォルト文法色を指定するdefaultを追加しました。
7. 行の折り返しにより背景カラーリングが消えてしまうことがある問題点をフィックスしました。
8. MAIL、TEXT以外の識別子を持った言語でも、Ctrl+,、Ctrl+.による見出し行へのジャンプができるようにしました。
テストバージョン1 (2001/7/3)