萩谷先生のレジュメ lex の2ページの内容です。

* 字句解析の実際(Emacs Lispの場合)

        ;;; キーワードの連想リスト:
        ;;;   ((キーワード文字列 . トークン) ... )
        (defvar *keyword-alist*
          '(("if" . if) ("then" . then) ("else" . else)
            ("while" . while) ("do" . do)))

        ;;; トークンの連想リスト
        ;;;   ((トークン文字列 . トークン) ... )
        (defvar *token-alist*
          '(("(" . lpar) (")" . rpar)
            ("+" . +) ("-" . -) ("*" . *) ("/" . /)
            ("=" . =) ("<" . <) (">" . >) ("<=" . <=) (">=" . >=)
            (":=" . :=)
            ("$" . $)))

        ;;; カーソルの次のトークンを読んで、トークン値を返す。
        ;;; カーソルはトークンの次に進む。
        (defun next-token ()
          ;; 空白文字(スペース,タブ,改行)を読み飛ばす。
          (skip-chars-forward " \t\n")
          ;; 次の文字を調べる。
          (let ((p (point)) (c (following-char)))
            (cond ((or (and (<= ?a c) (<= c ?z))
                       (and (<= ?A c) (<= c ?Z)))
                   ;; 次の文字が英字ならば、英数字を読み飛ばす。
                   (skip-chars-forward "A-Za-z0-9")
                   ;; 文字列を抜き出して、キーワードの連想リストを調べる。
                   (let* ((id (buffer-substring p (point)))
                          (a (assoc id *keyword-alist*)))
                     (if a
                         ;; 連想リストにあれば、
                         ;; キーワードに対応するトークンを返す。
                         (cons (cdr a) nil)
                         ;; 連想リストになければ、
                         ;; (id . 文字列) というトークン値を返す。
                         (cons 'id id))))
                  ((= c ?0)
                   ;; 次の文字が0ならば、(num . 0) というトークン値を返す。
                   (forward-char)
                   (cons 'num 0))
                  ((and (<= ?1 c) (<= c ?9))
                   ;; 次の文字が1から9ならば、数字を読み飛ばす。
                   (skip-chars-forward "0-9")
                   ;; 文字列を抜き出して、数に変換し、
                   ;; (num . 数) というトークン値を返す。
                   (cons 'num (string-to-int (buffer-substring p (point)))))
                  (t ;; 特殊記号を読み飛ばす。
                     (skip-chars-forward "---()+*/=<>:$")
                     ;; 文字列を抜き出して、トークンの連想リストを調べる。
                     (let* ((token (buffer-substring p (point)))
                            (a (assoc token *token-alist*)))
                       (if a
                           ;; 連想リストにあれば、トークン値を返す。
                           (cons (cdr a) nil)
                           ;; 連想リストになければ、エラー。
                           (error "%s: unrecognized token" token)))))))

〔仮想講義の2ページ目へ〕 〔トップページへ〕 〔言語処理系論の仮想講義のindexページへ〕
<vu@is.s.u-tokyo.ac.jp>

Last updated on 28 May, 1999