SMIEには、構文テーブルを次のように利用する事前定義済みの字句解析器が搭載されています。単語または記号の構文を持つ任意の文字列はトークンとみなされ、句読点の構文を持つ任意の文字列も同様にトークンとみなされます。このデフォルトの字句解析器は出発点としては有用であることが多いものの、特定の言語において実際に正しいことは稀です。例えば、"2,+3" は "2"、",+"、"3"
という3つのトークンで構成されているとみなされます。
SMIEに言語の字句解析ルールを説明するには、次のトークンを取得する関数と、直前のトークンを取得する関数の2つが必要です。これらの関数は通常、まず空白やコメントをスキップし、次に次のテキストチャンクを確認して、それが特殊トークンであるかどうかを判定します。特殊トークンである場合は、そのトークンをスキップして、このトークンの説明を返す必要があります。通常、これは単にバッファから抽出された文字列になりますが、任意の内容にすることも可能です。例えば:
(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))))))
これらのレクサーが、括弧の前にある場合に空文字列を返す点に注目してください。これは、SMIEが構文テーブルで定義された括弧を自動的に処理するためです。より具体的には、レクサーが
nil または空文字列を返した場合、SMIEは構文テーブルに従って、対応するテキストを sexp
として処理しようとします。