Next: 非力なパーサーと歩む, Previous: 言語の文法の定義, Up: SMIE: 無邪気なインデントエンジン [Contents][Index]
SMIEには事前定義された字句解析プログラムが付属しており、それは次の方法で構文テーブルを使用します:
文字の任意のシーケンスはトークンとみなせる単語構文(word syntax)かシンボル構文(symbol
syntax)をもち、区切り文字構文(punctuation
syntax)をもつ任意の文字シーケンスもトークンとみなされます。このデフォルトのlexerは開始ポイントとして適している場合が多々ありますが、任意の与えられた言語にたいして実際に正しいことは稀です。たとえばこれは"2,+3"
が3つのトークン"2"
、",+"
、"3"
から構成されていると判断するでしょう。
あなたの言語のlexerルールをSMIEにたいして説明するためには、次のトークンをfetchする関数と前のトークンをfetchする関数という2つの関数が必要になります。これらの関数は通常は最初に空白文字とコメントをスキップして、その後に次のテキストchunk(塊)を調べてそれが特別なトークンか確認します。これは通常は単にバッファーから抽出された文字列ですが、あなたが望む他の何かでも構いません。たとえば:
(defvar sample-keywords-regexp (regexp-opt '("+" "*" "," ";" ">" ">=" "<" "<=" ":=" "=")))
(defun sample-smie-forward-token () (forward-comment (point-max)) (cond ((looking-at sample-keywords-regexp) (goto-char (match-end 0)) (match-string-no-properties 0)) (t (buffer-substring-no-properties (point) (progn (skip-syntax-forward "w_") (point))))))
(defun sample-smie-backward-token () (forward-comment (- (point))) (cond ((looking-back sample-keywords-regexp (- (point) 2) t) (goto-char (match-beginning 0)) (match-string-no-properties 0)) (t (buffer-substring-no-properties (point) (progn (skip-syntax-backward "w_") (point))))))
これらのlexerがカッコの前にあるとき空文字列をリターンする方法に注目してください。これはSMIEが構文テーブル内で定義されているカッコにたいして自動的に配慮するからです。より厳密にはlexerがnil
、または空文字列をリターンしたら、SMIEは構文テーブルにしたがって対応するテキストをsexpとして処理します。