| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
構文テーブル(syntax table)は、 各文字の構文的なテキスト上の機能を指定します。 この情報は、構文解析関数や複雑な移動を行うコマンドなどが 単語やシンボルなどの構文要素がどこで始まりどこで終るかを調べるために使います。 現在の構文テーブルが、本章の関数に加えて、 単語単位の移動関数(see 節 29.2.2 単語単位の移動)、 リスト単位の移動関数(see 節 29.2.6 式単位の移動)の意味を制御します。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
構文テーブル(syntax table)は、 バッファ内の各文字の構文上の用途に関する情報をEmacsに与えます。 この情報は、構文解析関数や複雑な移動を行うコマンドなどが 単語やシンボルなどの構文要素がどこで始まりどこで終るかを調べるために使います。 現在の構文テーブルが、本章の関数に加えて、 単語単位の移動関数(see 節 29.2.2 単語単位の移動)、 リスト単位の移動関数(see 節 29.2.6 式単位の移動)の意味を制御します。
構文テーブルは文字テーブル(see 節 6.6 文字テーブル)です。 cで添字付けられる要素は、コードがcである文字について記述します。 要素の値は、当該文字の構文上の機能を符号化したリストです。
構文テーブルは、テキスト内を動き回るためにのみ使われ、 EmacsのLispリーダはこれを使いません。 Emacs LispがLisp式を読むときには、組み込みの構文規則を使います。 (入力構文を再定義する方法を与えるLispシステムもあるが、 単純であるようにEacs Lispではこの機能を省くことにした。)
各バッファには独自のメジャーモードがあり、 各メジャーモードはさまざまな文字の構文クラスを独自に扱います。 たとえば、lispモードでは文字`;'はコメントを始めますが、 Cモードでは文を終らせます。 このような多様性を扱うために、 Emacsは各バッファごとにローカルな構文テーブルを選びます。 典型的には、各メジャーモードに独自の構文テーブルがあり、 そのモードを使っているバッファに当該構文テーブルをインストールします。 この構文テーブルを変更すると、 同じモードのバッファだけでなく将来そのモードになったバッファでも 構文を変更してしまいます。 類似したモードでは1つの構文テーブルを共有することがあります。 構文テーブルの設定方法の例については、See 節 22.1.2 メジャーモードの例。
構文テーブルでは、標準の構文テーブルから文字のデータを継承し、 一方でその他の文字に独自の指定を行えます。 構文クラスの『継承』とは、 『標準の構文テーブルから当該文字の構文を引き継ぐ』ことです。 ある文字に対して標準の構文を変更すると、 それを継承するすべての構文テーブルに影響します。
tを返す。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、文字の構文を指定する構文クラスと構文フラグ、 それらを構文記述子(syntax descriptor)としてどのように 表現するかについて述べます。 構文記述子はLisp文字列であり、 望みの構文を指定するためにmodify-syntax-entryに渡します。
構文テーブルは、各文字の構文クラスを指定します。 ある構文テーブルでの文字のクラスと 他の構文テーブルでの当該文字のクラスとのあいだにはなんの関係も必要ありません。
各クラスはニーモニック文字(指定子)で区別します。 ニーモニック文字は、 クラスを指定する必要があるときにクラス名として働きます。 通常、指定子の文字は当該クラスによく現れるものです。 しかしながら、指定子としての意味は不変で、その文字の現在の構文とは独立です。
構文記述子は、構文クラス、(括弧のクラスの場合にのみ使われる) 釣り合う文字、フラグを指定するLisp文字列です。 最初の文字は、構文クラスを指定する文字(指定子)です。 2番目の文字はその文字に釣り合う文字ですが、使用しない場合には空白です。 そのあとに望みのフラグが続きます。 釣り合う文字やフラグが必要なければ、文字1つだけで十分です。
たとえば、Cモードにおける文字`*'の構文記述子は `. 23'(句読点、釣り合う文字なし、 コメント開始の2番目の文字、コメント終了の最初の文字)であり、 `/'は`. 14'(句読点、釣り合う文字なし、 コメント開始の最初の文字、コメント終了の2番目の文字)です。
34.2.1 構文クラス一覧 Table of syntax classes. 34.2.2 構文フラグ Additional flags each character can have.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
以下の一覧は、構文クラス、そのクラスを表す文字(指定子)、 そのクラスの意味、その使用例です。
開き括弧文字クラスは`('で指定し、 閉じ括弧文字クラスは`)'で指定する。
英文向けのテキスト(text)モードとCモードでは、 括弧の対は、`()'、`[]'、`{}'である。 Emacs Lispでは、リストとベクトルの区切り(`()'と`[]')は、 括弧文字としてクラス分けされる。
Emacsの構文解析機能では、文字列を1つの字句とみなす。 文字列内の文字の普通の構文的な意味は抑制される。
lisp向けのモードには文字列クォート文字が2つ、 ダブルクォート(`"')と縦棒(`|')がある。 `|'はEmacs Lispでは使わないがCommon Lispで使う。 Cにも2つの文字列クォート文字、 文字列用のダブルクォートと文字定数用のシングルクォート(`'')がある。
英文はプログラム言語ではないので、英文には文字列クォート文字はない。 英文でも引用符は用いるが、その内側の文字の普通の構文的な属性を 抑制したくないのである。
words-include-escapesがnil以外であると、 このクラスの文字は単語の一部分と解釈される。 see 節 29.2.2 単語単位の移動。
words-include-escapesがnil以外であると、 このクラスの文字は単語の一部分と解釈される。 see 節 29.2.2 単語単位の移動。
このクラスは、TeXモードのバックスラッシュに使われる。
英文にはコメント文字はない。 Lispでは、セミコロン(`;')でコメントが始まり、 改行かページ送りで終る。
この構文クラスは、主にテキスト属性syntax-table (see 節 34.4 構文属性)で使うことを意図したものである。 任意の範囲の文字がコメントを形成すると印を付けるには、 その範囲の先頭と末尾の文字にそれらが汎用コメント区切りであることを 識別する属性syntax-tableを与える。
この構文クラスは、主にテキスト属性syntax-table (see 節 34.4 構文属性)で使うことを意図したものである。 任意の範囲の文字が文字列定数を形成すると印を付けるには、 その範囲の先頭と末尾の文字にそれらが汎用文字列区切りであることを 識別する属性syntax-tableを与える。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
構文テーブルの各文字には、構文クラスに加えて、フラグも指定できます。 文字`1'、`2'、`3'、`4'、`b'、`p'で 表現される6つの可能なフラグがあります。
`p'を除くすべてのフラグは、複数の文字から成るコメント区切りの記述に 使います。 数字フラグは、当該文字のクラスで表される構文上の属性に加えて、 コメント列の一部分でもあることを示します。 フラグはクラスや他のフラグとは独立であり、 Cモードの`*'のような文字のためにあります。 Cモードの`*'は、句読点文字であるとともに、 コメント開始列の2番目の文字`/*'でもあり、 コメント終了列の最初の文字`*/'でもあります。
文字cに対して可能なフラグとそれらの意味を以下に示します。
Emacsでは、任意の1つの構文テーブルで2つの形式のコメントを同時に扱える。 これはC++のためである。 コメント構文の各形式には、独自の開始列と独自の終了列がある。 各コメントはどちらか1つの形式である必要がある。 したがって、『b』形式のコメント開始列で始まるものは、 『b』形式のコメント終了列で終る必要がある。
2つのコメント開始列は同じ文字で始まる必要があり、2文字目のみが異なる。 『b』形式のコメント開始列の2番目の文字にフラグ`b'を付ける。
(1文字か2文字の)コメント終了列は、 その最初の文字にフラグ`b'が付いていると『b』形式に適用する。 さもなければ『a』形式に適用する。
C++向けの適切なコメント構文の設定はつぎのとおりである。
これは4つのコメント区切り列を定義する。
関数backward-prefix-charsは後方へ向けて移動するときには、 構文クラスが式前置子(`'')である文字に加えて これらの文字も飛び越す。 see 節 34.5 移動と構文。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、構文テーブルを作成/参照/変更するための関数について述べます。
ほとんどのメジャーモードの構文テーブルはこのように作成する。
nil)、 現在の構文テーブルのコピーを返す。 tableが構文テーブルでないとエラーを通知する。この関数はつねにnilを返す。 当該構文テーブルにおけるこの文字に対する古い構文情報は破棄される。
構文記述子の最初の文字が12個の構文クラス指定子の1つでないとエラーを通知する。 charが文字でなくてもエラーを通知する。
【例】
;; 空白文字をクラス白文字にする
(modify-syntax-entry ?\ " ")
=> nil
;; `$'を開き括弧文字にする
;; 対応する閉じる文字は`^'である
(modify-syntax-entry ?$ "(^")
=> nil
;; `^'を閉じ括弧文字にする
;; 対応する開く文字は{$である}
(modify-syntax-entry ?^ ")$")
=> nil
;; `/'を句読点文字にする
;; コメント開始列の最初の文字、および、
;; コメント終了列の2番目の文字にもする
;; これはCモードで用いられる
(modify-syntax-entry ?/ ". 14")
=> nil
|
charが文字でないとエラーを通知する。
つぎの例はCモードにあてはまる。 最初の例は、空白の構文クラスが(空白で表現される)白文字であることを示す。 2番目の例は、`/'の構文が句読点であることを示す。 これは、この文字がコメント開始/終了の一部分でもあることは示さない。 3番目の例は、開き括弧は開き括弧クラスであることを示す。 これは、この文字に釣り合う文字が`)'であることは示さない。
(string (char-syntax ?\ ))
=> " "
(string (char-syntax ?/))
=> "."
(string (char-syntax ?\())
=> "("
|
ここでは、char-syntaxが返す文字を 見やすくするためにstringを用いた。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
言語の構文を指定するに十分なほど構文テーブルに柔軟性がないときには、 バッファ内の特定の文字の出現に対して構文テーブルに優先する テキスト属性syntax-tableを指定できます。 See 節 31.19 テキスト属性。
テキスト属性syntax-tableの正しい値はつぎのとおりです。
(syntax-code . matching-char)nilnilであると、通常どおり、 現在の構文テーブルから文字の構文を判定する。nil以外であると、 構文を解析する関数は、テキスト属性による構文指定に注意を払う。 さもなければ、現在の構文テーブルのみを用いる。| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、特定の構文クラスを持つ文字を越えて移動するための 関数について述べます。
戻り値は移動距離である。 それはゼロか負の整数である。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ここでは、括弧が対になっているS式(sexp)とも呼ばれる 釣り合った式を解析したり走査する関数について述べます。 構文テーブルで文字の解釈を制御することで、 LispモードではLispの式に対して、CモードではCの式に対して これらの関数を用いることができます。 釣り合った式を飛び越えて移動するための便利な上位レベルの関数については、 See 節 29.2.6 式単位の移動。
stateがnilであると、 位置startは、関数定義の先頭のような 括弧の構造のトップレベルであると仮定する。 あるいは、構造の途中から解析を再開したい場合もある。 それには、解析の初期状態を引数stateに指定する必要がある。
3番目の引数target-depthがnil以外であると、 括弧の深さがtarget-depthに等しくなると解析を停止する。 深さは0、あるいは、stateで指定された値から始まる。
4番目の引数stop-beforeがnil以外であると、 S式を始める文字に出会うと解析を停止する。 stop-commentがnil以外であると、 コメントの始まりに出会うと解析を停止する。 stop-commentがシンボルsyntax-tableであると、 コメントや文字列の始まり、コメントや文字列の終りのいずれかに 出会ったあとで解析を停止する。
5番目の引数stateは9要素のリストであり、 以下に述べるようにこの関数の値と同じ形である。 (9番目の最後の要素は省いてもよい。) parse-partial-sexpの呼び出しの戻り値を、 別のparse-partial-sexpの呼び出しの解析状態の初期値に使ってよい。
結果は、解析の最終状態を記述した9要素のリストである。
nil。
nil。
nil以外である。 より正確には、これは文字列を終える文字である。 あるいは、汎用文字列区切り文字で終えるときにはtである。
tである。
tである。
nil、 『b』形式であるとt、 汎用コメント区切り文字で終るコメントの場合にはsyntax-tableである。
nilである。引数stateでは、要素0、3、4、5、7は重要である。
depthが0以外であると、括弧の深さをその値から数え始める。 停止箇所の候補位置は、括弧の深さが0になる箇所である。 scan-listsは、そのような箇所をcount回数えてから停止する。 したがって、depthに正の値を指定すると、 括弧のレベルをdepthレベルだけ抜けることを意味する。
parse-sexp-ignore-commentsがnil以外であると、 コメントを無視して走査する。
走査がバッファ(あるいはその参照可能部分)の先頭や末尾に達し、 深さが0でないと、エラーを通知する。 深さは0であるが指定個数だけ数えてない場合には、nilを返す。
parse-sexp-ignore-commentsがnil以外であると、 コメントを無視して走査する。
走査が括弧によるグループの途中で バッファ(あるいはその参照可能部分)の先頭や末尾に達すると、 エラーを通知する。 指定個数だけ数えるまえに括弧によるグループのあいだで 先頭や末尾に達した場合はnilを返す。
nil以外であると、 本節の関数やforward-sexpは、コメントを白文字として扱う。
Emacsの古い版では、コメントの終了が`*/'のような形であり、かつ、 コメントの終了と思える場合にのみ、この機能は動作した。 改行でコメントを終える言語では、改行すべてがコメントの終りではないために、 この変数をnilにする必要があった。 このような制限事項はすでにない。
forward-commentを使うと、 1つのコメントや複数のコメントを飛び越えて前後に移動できます。
ポイントに続くすべてのコメントと白文字を飛び越えるには、 (forward-comment (buffer-size))を使います。 バッファ内のコメントの個数は(buffer-size)を越えるはずがないので、 引数に使うには(buffer-size)はよいものです。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsのほとんどのメジャーモードにはそれ独自の構文テーブルがあります。 それらのいくつかをつぎに示します。
readにはなんの効果もない。)| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Lispプログラムでは普通は構文テーブルの要素を直接には操作しません。 Lispレベルの構文テーブル関数は、 普通は構文記述子(see 節 34.2 構文記述子)を操作します。 ですが、内部形式を明文化しておきます。
構文テーブルの各要素は、(syntax-code . matching-char)の 形のコンスセルです。 CARのsyntax-codeは、構文クラスと構文フラグを符号化する整数です。 釣り合う文字を指定してあると、 CDRのmatching-charはnil以外です。
つぎの表は、各構文クラスに対応するsyntax-codeの値です。
| 整数 クラス | 整数 クラス | 整数 クラス | |
| 0 whitespace | 5 close parenthesis | 10 character quote | |
| 白文字 | 閉じ括弧 | 文字クォート | |
| 1 punctuation | 6 expression prefix | 11 comment-start | |
| 句読点 | 式前置子 | コメント開始 | |
| 2 word | 7 string quote | 12 comment-end | |
| 単語 | 文字列クォート | コメント終了 | |
| 3 symbol | 8 paired delimiter | 13 inherit | |
| シンボル | 対になった区切り | 継承 | |
| 4 open parenthesis | 9 escape | 14 comment-fence | |
| 開き括弧 | エスケープ | コメント区切り | |
| 15 string-fence | |||
| 文字列区切り |
たとえば、`('の普通の構文値は、(4 . 41)です。 (41は`)'の文字コード。)
フラグは、最下位ビットから16番目のビットから始まる上位ビットに符号化します。 つぎの表は、各構文フラグとそれに対応する2の巾です。
| フラグ 2の巾 | フラグ 2の巾 | フラグ 2の巾 | |
`1' (lsh 1 16)
|
`3' (lsh 1 18)
|
`p' (lsh 1 20)
|
|
`2' (lsh 1 17)
|
`4' (lsh 1 19)
|
`b' (lsh 1 21)
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
カテゴリ(category)は、文字を構文的に分類する別の方法です。 必要に応じて複数のカテゴリを定義できて、 そうすると各文字に1つか複数のカテゴリを独立に設定できます。 構文クラスと異なり、カテゴリは互いに排他的ではありません。 1つの文字が複数のカテゴリに属することは普通にあります。
各バッファにはカテゴリテーブル(category table)があり、 どのカテゴリが定義済みでどの文字がどのカテゴリに属するかを記録しています。 各カテゴリテーブルはそれ独自のカテゴリ群を定義しますが、 それらは標準のカテゴリテーブルをコピーして普通は初期化されます。 そのため、すべてのモードで標準のカテゴリを使えます。
各カテゴリには名前があり、それは` 'から`~'までの 範囲のASCII印字文字です。 define-categoryでカテゴリを定義するときにその名前を指定します。
カテゴリテーブルは実際には文字テーブル(see 節 6.6 文字テーブル)です。 カテゴリテーブルの添字cの要素は、 カテゴリ集合(category set)です。 これはブールベクトルであり、文字cが属するカテゴリ群を表します。 このカテゴリ集合において、添字catの要素がtであると、 catは集合の要素であることを意味し、 当該文字cはカテゴリcatに属することを意味します。
新たなカテゴリは、カテゴリテーブルtableに対して定義される。 tableのデフォルトは、カレントバッファのカテゴリテーブルである。
(category-docstring ?a)
=> "ASCII"
(category-docstring ?l)
=> "Latin"
|
nilを返す。tを返し、 さもなければnilを返す。nil)と、 現在のカテゴリテーブルのコピーを返す。 tableがカテゴリテーブルでないとエラーを通知する。tを それ以外のカテゴリに対してはnilを設定する。
(make-category-set "al")
=> #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
|
char-category-setは、カテゴリテーブルに 存在する同じブールベクトルを返すため、新たな領域を割り付けない。
(char-category-set ?a)
=> #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
|
(category-set-mnemonics (char-category-set ?a))
=> "al"
|
普通、カテゴリ集合にcategoryを追加して変更する。 しかし、resetがnil以外であるとcategoryを削除する。
| [ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |