24.8.1.4 定义标记

SMIE 内置一个预定义的词法分析器,它按如下方式使用语法表: 任意具有单词或符号语法的字符序列会被视为一个标记, 任意具有标点符号语法的字符序列同样如此。 这个默认词法分析器通常是不错的起点, 但对任意特定语言而言很少能完全适用。 例如,它会将 "2,+3" 拆分为 3 个标记:"2"",+""3"

若要向 SMIE 描述你所用语言的词法规则,需要两个函数: 一个用于获取下一个标记,另一个用于获取上一个标记。 这些函数通常会先跳过空白符与注释, 再查看下一段文本是否为特殊标记。 若是,则应跳过该标记并返回其描述。 通常直接返回从缓冲区提取的字符串即可, 但也可返回任意自定义内容。示例如下:

(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 会依据语法表将对应文本当作 S 表达式处理。

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike