[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
構文テーブル(syntax table)は, 各文字の構文的なテキスト上の機能を指定します. この情報は, 構文解析関数や複雑な移動を行うコマンドなどが 単語やシンボルなどの構文要素がどこで始まりどこで終るかを調べるために使います. 現在の構文テーブルが, 本章の関数に加えて, 単語単位の移動関数(see section 単語単位の移動), リスト単位の移動関数(see section 式単位の移動)の意味を制御します.
34.1 構文テーブルの概念 | Basic concepts of syntax tables. | |
34.2 構文記述子 | How characters are classified. | |
34.3 構文テーブル向け関数 | How to create, examine and alter syntax tables. | |
34.4 構文属性 | Overriding syntax with text properties. | |
34.5 移動と構文 | Moving over characters with certain syntaxes. | |
34.6 釣り合った式の解析 | Parsing balanced expressions using the syntax table. | |
34.7 標準的な構文テーブル | Syntax tables used by various major modes. | |
34.8 構文テーブルの内部 | How syntax table information is stored. | |
34.9 カテゴリ | Another way of classifying character syntax. |
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
構文テーブルは文字テーブル(see section 文字テーブル)です. cで添字付けられる要素は, コードがcである文字について記述します. 要素の値は, 当該文字の構文上の機能を符号化したリストです.
構文テーブルは, テキスト内を動き回るためにのみ使われ, EmacsのLispリーダはこれを使いません. Emacs LispがLisp式を読むときには, 組み込みの構文規則を使います. (入力構文を再定義する方法を与えるLispシステムもあるが, 単純であるようにEacs Lispではこの機能を省くことにした. )
各バッファには独自のメジャーモードがあり, 各メジャーモードはさまざまな文字の構文クラスを独自に扱います. たとえば, lispモードでは文字‘;’はコメントを始めますが, Cモードでは文を終らせます. このような多様性を扱うために, Emacsは各バッファごとにローカルな構文テーブルを選びます. 典型的には, 各メジャーモードに独自の構文テーブルがあり, そのモードを使っているバッファに当該構文テーブルをインストールします. この構文テーブルを変更すると, 同じモードのバッファだけでなく将来そのモードになったバッファでも 構文を変更してしまいます. 類似したモードでは1つの構文テーブルを共有することがあります. 構文テーブルの設定方法の例については, See section メジャーモードの例.
構文テーブルでは, 標準の構文テーブルから文字のデータを継承し, 一方でその他の文字に独自の指定を行えます. 構文クラスの『継承』とは, 『標準の構文テーブルから当該文字の構文を引き継ぐ』ことです. ある文字に対して標準の構文を変更すると, それを継承するすべての構文テーブルに影響します.
この関数は, objectが構文テーブルならばt
を返す.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
本節では, 文字の構文を指定する構文クラスと構文フラグ,
それらを構文記述子(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. |
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
以下の一覧は, 構文クラス, そのクラスを表す文字(指定子), そのクラスの意味, その使用例です.
白文字(‘ ’か‘-’で指定)は, シンボルや単語を互いに区切る. 典型的には, 白文字には他の構文上の意味はなく, 複数個の白文字は1つの白文字と構文的には等価である. ほとんどすべてのメジャーモードでは, 空白, タブ, 改行, ページ送りは白文字である.
単語構成文字(‘w’で指定)は普通の英単語の一部分であり, 典型的には, プログラムの変数やコマンド名に使われる. すべての大英文字, 小英文字, 数字文字は, 典型的には単語構成文字である.
シンボル構成文字(‘_’で指定)は, 単語構成文字に加えて, 変数やコマンド名に使われる追加の文字である. たとえば, 英単語の一部分ではないがシンボル名に使える特定の文字を指定 するために, Lispモードではシンボル構成文字クラスを使う. このような文字は‘$&*+-_<>’である. 標準のCでは, 単語構成文字でなくてシンボルに使える唯一の文字は 下線(‘_’)である.
句読点文字(‘.’で指定)は, 英文の句読点として使われたり, プログラム言語でシンボルを区切るために使われる文字である. emacs-lispモードを含むほとんどのプログラム言語向けモードでは, シンボル構成文字でも単語構成文字でもない少数の文字には別の用途があるため, このクラスの文字はない.
開き/閉じ括弧文字は, 文や式を囲む相異なる対として使われる文字である. そのようなグループ化は, 開き括弧文字で始まり閉じ括弧文字で終る. 各開き括弧文字は特定の閉じ括弧文字に対応し, その逆もいえる. Emacsは, 通常, 閉じ括弧文字を挿入すると 対応する開き括弧文字を短時間指し示す. see section 括弧を点滅する.
開き括弧文字クラスは‘(’で指定し, 閉じ括弧文字クラスは‘)’で指定する.
英文向けのテキスト(text)モードとCモードでは, 括弧の対は, ‘()’, ‘[]’, ‘{}’である. Emacs Lispでは, リストとベクトルの区切り(‘()’と‘[]’)は, 括弧文字としてクラス分けされる.
文字列クォート文字(‘"’で指定)は, LispやCを含む多くの言語で文字列定数を区切るために使われる. 同じ文字列クォート文字が文字列の最初と最後に現れる.
Emacsの構文解析機能では, 文字列を1つの字句とみなす. 文字列内の文字の普通の構文的な意味は抑制される.
lisp向けのモードには文字列クォート文字が2つ, ダブルクォート(‘"’)と縦棒(‘|’)がある. ‘|’はEmacs Lispでは使わないがCommon Lispで使う. Cにも2つの文字列クォート文字, 文字列用のダブルクォートと文字定数用のシングルクォート(‘'’)がある.
英文はプログラム言語ではないので, 英文には文字列クォート文字はない. 英文でも引用符は用いるが, その内側の文字の普通の構文的な属性を 抑制したくないのである.
エスケープ文字(‘\’で指定)は, Cの文字列や文字定数で使われるようなエスケープシーケンスを開始する. CとLispでは, 文字‘\’はこのクラスに属する. (Cではこの文字は文字列の内側だけで使われるが, Cモードでつねにこのように扱っても問題ないことがわかった. )
words-include-escapes
がnil
以外であると,
このクラスの文字は単語の一部分と解釈される.
see section 単語単位の移動.
文字クォート文字(‘/’で指定)は, 後続の1文字をクォートし, 通常の構文上の意味を抑制する. 直後の1文字のみに影響するという点で, エスケープ文字と異なる.
words-include-escapes
がnil
以外であると,
このクラスの文字は単語の一部分と解釈される.
see section 単語単位の移動.
このクラスは, TeXモードのバックスラッシュに使われる.
対になった区切り文字(‘$’)は文字列クォート文字と同様であるが, 区切り文字のあいだにある文字の構文上の属性を抑制しない点が異なる. 現在, 対になった区切りはTeXモードのみで使い, 数学モードに出入りする‘$’である.
式前置演算子(‘'’)は, 式のまえに現れると 式の一部であるとみなされる構文上の演算子に使われる. lisp向けのモードでは, (クォートする)アポストロフ‘'’, (マクロで使う)コンマ‘,’, (ある種のデータの入力構文に使われる)‘#’の文字がそうである.
コメント開始文字とコメント終了文字は, さまざまな言語でコメントを区切るために用いられる. これらのクラスは, それぞれ, ‘<’と‘>’で指定する.
英文にはコメント文字はない. Lispでは, セミコロン(‘;’)でコメントが始まり, 改行かページ送りで終る.
この構文クラスは特定の構文を指定しない. 標準の構文テーブルで当該文字の構文を探す指定である. この構文クラスは‘@’で指定する.
汎用コメント区切り文字は, 特別な種類のコメントを 始めて終える文字である. 任意の汎用コメント区切り文字は 任意の汎用コメント区切り文字に対応するが, 普通のコメント開始文字/コメント終了文字には対応しない. 汎用コメント区切り文字同士のみで対応する.
この構文クラスは, 主にテキスト属性syntax-table
(see section 構文属性)で使うことを意図したものである.
任意の範囲の文字がコメントを形成すると印を付けるには,
その範囲の先頭と末尾の文字にそれらが汎用コメント区切りであることを
識別する属性syntax-table
を与える.
汎用文字列区切り文字は, 文字列を始めて終える. このクラスは文字列クォートクラスと異なり, 汎用文字列区切りは他の汎用文字列区切りに対応し, 普通の文字列クォート文字には対応しない.
この構文クラスは, 主にテキスト属性syntax-table
(see section 構文属性)で使うことを意図したものである.
任意の範囲の文字が文字列定数を形成すると印を付けるには,
その範囲の先頭と末尾の文字にそれらが汎用文字列区切りであることを
識別する属性syntax-table
を与える.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
構文テーブルの各文字には, 構文クラスに加えて, フラグも指定できます. 文字‘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++向けの適切なコメント構文の設定はつぎのとおりである.
‘124b’
‘23’
‘>b’
これは4つのコメント区切り列を定義する.
2文字目の‘*’にはフラグ‘b’がないので, これは『a』形式のコメント開始列である.
2文字目の‘/’にはフラグ‘b’があるので, これは『b』形式のコメント開始列である.
2文字目の‘*’にはフラグ‘b’がないので, これは『a』形式のコメント終了列である.
改行にはフラグ‘b’があるので, これは『b』形式のコメント終了列である.
関数backward-prefix-chars
は後方へ向けて移動するときには,
構文クラスが式前置子(‘'’)である文字に加えて
これらの文字も飛び越す.
see section 移動と構文.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
本節では, 構文テーブルを作成/参照/変更するための関数について述べます.
この関数は, 新たな構文テーブルを作成する. 英文字やコントロール文字の構文は標準の構文テーブルから継承する. 他の文字の構文は標準の構文テーブルからコピーする.
ほとんどのメジャーモードの構文テーブルはこのように作成する.
この関数は, 構文テーブルtableのコピーを作成しそれを返す.
tableを指定しないと(あるいはnil
),
現在の構文テーブルのコピーを返す.
tableが構文テーブルでないとエラーを通知する.
この関数は, 文字charの構文指定を 構文記述子syntax-descriptorとする. 構文テーブルtableにおいてのみ構文を変更し, 他の構文テーブルは変更しない. tableのデフォルトはカレントバッファの構文テーブルである. syntax-descriptorで望みの構文を指定する. これは, クラス指定子で始まり, 必要に応じて釣り合う文字とフラグを含む文字列である. see section 構文記述子.
この関数はつねにnil
を返す.
当該構文テーブルにおけるこの文字に対する古い構文情報は破棄される.
構文記述子の最初の文字が12個の構文クラス指定子の1つでないとエラーを通知する. charが文字でなくてもエラーを通知する.
【例】 ;; 空白文字をクラス白文字にする (modify-syntax-entry ?\ " ") ⇒ nil ;; ‘$’を開き括弧文字にする ;; 対応する閉じる文字は‘^’である (modify-syntax-entry ?$ "(^") ⇒ nil ;; ‘^’を閉じ括弧文字にする ;; 対応する開く文字は‘$’である (modify-syntax-entry ?^ ")$") ⇒ nil ;; ‘/’を句読点文字にする ;; コメント開始列の最初の文字, および, ;; コメント終了列の2番目の文字にもする ;; これはCモードで用いられる (modify-syntax-entry ?/ ". 14") ⇒ nil |
この関数は, 文字characterの構文クラスを指定子で表したもので返す. これは構文クラスのみを返し, 釣り合う文字や構文フラグは返さない.
charが文字でないとエラーを通知する.
つぎの例はCモードにあてはまる. 最初の例は, 空白の構文クラスが(空白で表現される)白文字であることを示す. 2番目の例は, ‘/’の構文が句読点であることを示す. これは, この文字がコメント開始/終了の一部分でもあることは示さない. 3番目の例は, 開き括弧は開き括弧クラスであることを示す. これは, この文字に釣り合う文字が‘)’であることは示さない.
(string (char-syntax ?\ )) ⇒ " " (string (char-syntax ?/)) ⇒ "." (string (char-syntax ?\()) ⇒ "(" |
ここでは, char-syntax
が返す文字を
見やすくするためにstring
を用いた.
この関数は, tableをカレントバッファの構文テーブルにする. tableを返す.
この関数は, 現在の構文テーブル, つまり, カレントバッファの構文テーブルを返す.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
言語の構文を指定するに十分なほど構文テーブルに柔軟性がないときには,
バッファ内の特定の文字の出現に対して構文テーブルに優先する
テキスト属性syntax-table
を指定できます.
See section テキスト属性.
テキスト属性syntax-table
の正しい値はつぎのとおりです.
属性値が構文テーブルであると, 文字のこの出現に対する構文を判定するために カレントバッファの構文テーブルのかわりにこのテーブルを用いる.
(syntax-code . matching-char)
この形のコンスセルは, 文字のこの出現の構文を指定する.
nil
属性がnil
であると, 通常どおり,
現在の構文テーブルから文字の構文を判定する.
これがnil
以外であると,
構文を解析する関数は, テキスト属性による構文指定に注意を払う.
さもなければ, 現在の構文テーブルのみを用いる.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
本節では, 特定の構文クラスを持つ文字を越えて移動するための 関数について述べます.
この関数は, syntaxesで指定される構文クラスを持つ文字を越えて ポイントを前方へ向けて移動する. バッファの末尾, (指定されていれば)limitの位置, 飛び越さない文字のいずれかに出会うと停止する. 戻り値は移動距離であり非負整数である.
この関数は, syntaxesで指定される構文クラスである文字を越えて ポイントを後方へ向けて移動する. バッファの先頭, (指定されていれば)limitの位置, 飛び越さない文字のいずれかに出会うと停止する.
戻り値は移動距離である. それはゼロか負の整数である.
この関数は, 式前置子構文の文字を飛び越えてポイントを後方へ向けて移動する. 式前置子クラスやフラグ‘p’を持つ文字を飛び越す.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
ここでは, 括弧が対になっているS式(sexp)とも呼ばれる 釣り合った式を解析したり走査する関数について述べます. 構文テーブルで文字の解釈を制御することで, LispモードではLispの式に対して, CモードではCの式に対して これらの関数を用いることができます. 釣り合った式を飛び越えて移動するための便利な上位レベルの関数については, See section 式単位の移動.
この関数は, カレントバッファのstartから始まるS式を解析するが, limitを越えては走査しない. 位置limitで止まるか, 以下に述べる条件が満たされると解析を停止し, 当該箇所にポイントを置く. ポイントを置いた箇所での解析状況を表す値を返す.
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は重要である.
この関数は, 入れ子にあった括弧を持つ言語向けに 字下げを計算するためにしばしば用いられる.
この関数は, 位置fromから前方へ向けてcount個の 釣り合った括弧のグループを走査する. 走査を停止した位置を返す. countが負であると, 後方へ向けて走査する.
depthが0以外であると, 括弧の深さをその値から数え始める.
停止箇所の候補位置は, 括弧の深さが0になる箇所である.
scan-lists
は, そのような箇所をcount回数えてから停止する.
したがって, depthに正の値を指定すると,
括弧のレベルをdepthレベルだけ抜けることを意味する.
parse-sexp-ignore-comments
がnil
以外であると,
コメントを無視して走査する.
走査がバッファ(あるいはその参照可能部分)の先頭や末尾に達し,
深さが0でないと, エラーを通知する.
深さは0であるが指定個数だけ数えてない場合には, nil
を返す.
この関数は, 位置fromから前方へ向けてcount個のS式を走査する. 走査を終えた位置を返す. countが負であると, 後方へ向けて移動する.
parse-sexp-ignore-comments
がnil
以外であると,
コメントを無視して走査する.
走査が括弧によるグループの途中で
バッファ(あるいはその参照可能部分)の先頭や末尾に達すると,
エラーを通知する.
指定個数だけ数えるまえに括弧によるグループのあいだで
先頭や末尾に達した場合はnil
を返す.
値がnil
以外であると,
本節の関数やforward-sexp
は, コメントを白文字として扱う.
Emacsの古い版では, コメントの終了が‘*/’のような形であり, かつ,
コメントの終了と思える場合にのみ, この機能は動作した.
改行でコメントを終える言語では, 改行すべてがコメントの終りではないために,
この変数をnil
にする必要があった.
このような制限事項はすでにない.
forward-comment
を使うと,
1つのコメントや複数のコメントを飛び越えて前後に移動できます.
この関数は, ポイントを前方へ向けて(countが負ならば後方へ向けて) count個のコメントを飛び越えて移動する. コメントか白文字以外のものに出会うと停止し, 当該箇所にポイントを置く. count個だけ数えたあとにももちろん停止する.
ポイントに続くすべてのコメントと白文字を飛び越えるには,
(forward-comment (buffer-size))
を使います.
バッファ内のコメントの個数は(buffer-size)
を越えるはずがないので,
引数に使うには(buffer-size)
はよいものです.
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
Emacsのほとんどのメジャーモードにはそれ独自の構文テーブルがあります. それらのいくつかをつぎに示します.
この関数は, 基本(fundamental)モードで使用する構文テーブルである 標準の構文テーブルを返す.
この変数の値は, テキスト(text)モードで使用する構文テーブルである.
この変数の値は, Cモードのバッファ向けの構文テーブルである.
この変数の値は, 編集コマンドがemacs-lispモードで使用する構文テーブルである.
(これはLispの関数read
にはなんの効果もない. )
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
Lispプログラムでは普通は構文テーブルの要素を直接には操作しません. Lispレベルの構文テーブル関数は, 普通は構文記述子(see section 構文記述子)を操作します. ですが, 内部形式を明文化しておきます.
構文テーブルの各要素は, (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) |
[ << ] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
この文書は新堂 安孝によって2009年9月22日にtexi2html 1.82を用いて生成されました。