トップページ > ドキュメント > Xcodeでの構文色付け定義
構文が入れ子になったり、IncludeRulesやTokenizerが出て来て話が複雑になってきました。ここで一度、構文解析の流れについて整理して見たいと思います。
(
// トップレベルの構文定義
{
Identifier = "my.lang.sample";
Name = "Sample";
Description = "Sample Language Coloring";
BasedOn = "xcode.lang.simpleColoring";
IncludeInMenu = YES;
Syntax = {
Tokenizer = "my.lang.sample.lexer";
IncludeRules = ( "my.lang.sample.block" );
Type = "xcode.syntax.plain";
};
},
// トークンの定義
{
Identifier = "my.lang.sample.lexer";
Syntax = {
IncludeRules = ( "my.lang.sample.keyword" );
};
},
// キーワードの構文定義
{
Identifier = "my.lang.sample.keyword";
Syntax = {
StartChars = "abcdefghijklmnopqrstuvwxyz";
Chars = "abcdefghijklmnopqrstuvwxyz";
Words = ( "function", "print" );
Type = "xcode.syntax.keyword";
AltType = "xcode.syntax.identifier";
};
},
// ブロックの構文定義
{
Identifier = "my.lang.sample.block";
Syntax = {
Tokenizer = "my.lang.sample.lexer";
Start = "{";
End = "}";
Foldable = YES;
Recursive = YES;
};
}
)
function hoge() {
print HELLO!
}
"my.lang.sample"から始まります。"f"を読み込んで、それをバッファに格納します。TokenizerとIncludeRulesしかないので、Tokenizer→IncludeRulesの順番で構文のチェックが行われます。具体的には、"my.lang.sample.keyword"→"my.lang.sample.block"の順になります。"my.lang.sample.keyword"で、バッファの"f"がチェックされた結果、StartCharsに"f"があり、かつAltTypeが設定されているので、この構文にマッチします。この構文定義に関しては、Wordsがメインの定義でStartCharsやCharsは補助的な定義となります。補助的な定義はAltTypeが設定されていないと、たとえ文字がマッチしても構文としてマッチしたことになりません。Typeが適用されます。今回はAltTypeの"xcode.syntax.identifier"が適用されます。"my.lang.sample.keyword"に移行します。しかし、"my.lang.sample.keyword"にはこれ以上構文定義がないため、何もせずにトップレベルに戻ります。もしも、TokenizerやIncludeRulesがあれば、マッチした構文に対して、さらに構文解析が行われます。"u"が先読みされます。"u"はCharsに含まれる文字なので、単語を構成する文字列がこの後も続くと判断されます。"u"が読まれて、バッファの内容は"fu"になります。同じようにステップ2〜7が繰り返されて、最終的にバッファの内容は"function"になります。"my.lang.sample.keyword"のWordsの"function"にマッチします。"xcode.syntax.keyword"が適用されます。" "が先読みされますが、" "(スペース)はCharsに含まれない文字なので、ここで単語境界が検出され、バッファはクリアされます。"hoge"は、構文定義"my.lang.sample.keyword"にマッチして、構文タイプが"xcode.syntax.identifier"になります。"()"は、どの構文定義にもマッチしないので、トップレベルの"xcode.syntax.plain"が構文タイプになります。"{"が読まれて、バッファに格納されます。"my.lang.sample.block"のStartがマッチします。このStartはちょっと特殊で、これにマッチすると、Endにマッチしなくても、この構文にマッチしたと判断されます。"my.lang.sample.block"には、Typeがないので、"{"の構文タイプは、トップレベルを継承して"xcode.syntax.plain"になります。"my.lang.sample.block"に移行します。"my.lang.sample.block"には、Tokenizerが定義されているので、Endにマッチするまでの間、"my.lang.sample.block"がTokenizerを使って構文解析を行います。