第1段階では、Cの字下げ機構は、字下げしようとしているまえの行を調べて、
その行を構成する構文上の構成要素を決定します。
つまり、構文シンボルとバッファ内の相対位置を要素とする
構文構成要素のリストを組み立てます。
構文シンボルには、statement(文)や
substatement(部分文)のように
文法要素を記述するものと、
class-open(クラス開始)や
knr-argdecl(K&R版引数宣言)のように文法要素のあいだの位置を
記述するものがあります。
概念的には、Cのコード行は、バッファ中でそれよりまえに あるいずれかの行に対して必ず相対的に字下げされます。 これは構文構成要素リストの中にあるバッファ内位置として表現されます。
以下に例を示します。 つぎのコードが、C++モードのバッファに入っているとしましょう (実際にバッファに行番号が表示されるわけではない)。
1: void swap (int& a, int& b)
2: {
3: int tmp = a;
4: a = b;
5: b = tmp;
6: }
4行目で(c-show-syntactic-informationを実行する)
C-c C-sを打つと、
その行に対する字下げ機構の結果が表示されます。
((statement . 32))
これは、その行が文であり、
バッファ内位置32に対して相対的に字下げされていることを示します。
バッファ内位置32は、3行目のintの`i'にあたります。
カーソルを3行目に動かしてC-c C-sと打つと、
今度はつぎのように表示されます。
((defun-block-intro . 28))
この結果は、int行がブロックの最初の文であり、
バッファ内位置28に対して相対的に字下げされていることを示しています。
バッファ内位置28は、関数ヘッダの直後の中括弧にあたります。
別の例を見てみましょう。
1: int add (int val, int incr, int doit)
2: {
3: if (doit)
4: {
5: return (val + incr);
6: }
7: return (val);
8: }
4行目でC-c C-sと打つと、つぎのように表示されます。
((substatement-open . 43))
これは、中括弧が部分文のブロックを始めていることを示しています。
ところで、部分文とは、if、else、while、
do、switch、for、try、catch、
finally、synchronizedのあとの行を表します。
Cの字下げコマンドにおいては、
字下げのために行を構文解析し終えると、
変数c-syntactic-contextには解析結果を表すリストが入ります。
このリストの各要素は構文構成要素であり、
構文シンボルと(省かれるかもしれない)対応するバッファ内位置の
コンスセルです。
構文構成要素リストには、複数の要素が含まれることもあります。
また、典型的には、バッファ内位置を持つ要素は1つだけです。