我甚至不知道这个lisp语法的正确术语,所以我不知道我用来提问的话是否有意义。但这个问题很有道理,我敢肯定。
所以,让我告诉你。 cc-mode(cc-fonts.el)有一些称为“匹配器”的东西,它们是用来决定如何形成代码区域的代码。这听起来很简单,但匹配器代码的形式我并不完全理解,带有反引号和逗号,只有逗号等等,而且它嵌入在c-lang-defcost中,它本身就是一个宏。我不知道该怎么称呼它,但我想在该代码上运行edebug。
看:
(c-lang-defconst c-basic-matchers-after
"Font lock matchers for various things that should be fontified after
generic casts and declarations are fontified. Used on level 2 and
higher."
t `(;; Fontify the identifiers inside enum lists. (The enum type
;; name is handled by `c-simple-decl-matchers' or
;; `c-complex-decl-matchers' below.
,@(when (c-lang-const c-brace-id-list-kwds)
`((,(c-make-font-lock-search-function
(concat
"\\<\\("
(c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
"\\)\\>"
;; Disallow various common punctuation chars that can't come
;; before the '{' of the enum list, to avoid searching too far.
"[^\]\[{}();,/#=]*"
"{")
'((c-font-lock-declarators limit t nil)
(save-match-data
(goto-char (match-end 0))
(c-put-char-property (1- (point)) 'c-type
'c-decl-id-start)
(c-forward-syntactic-ws))
(goto-char (match-end 0)))))))
我正在阅读lisp语法以了解这些内容以及调用它们的内容,但除此之外,如何在注释;; Fontify the identifiers inside enum lists.
之后的代码上运行edebug?
我知道如何在defun上运行edebug - 只需在函数定义中调用edebug-defun
,然后关闭。我需要做些相应的事情才能对cc模式匹配器代码表进行edebug吗?
def-edebug-spec
做了什么,我会在这里使用它吗?如果是这样,怎么样?
答案 0 :(得分:4)
使用macroexpand
或macroexpand-all
将其转换为无宏代码并照常调试?
Backticks&amp; co可以通过一个例子得到最好的说明:
(let ((a 1)
(b (list 2 3)))
`(a ,a ,b ,@b))
-> (a 1 (2 3) 2 3)
反引号(或反引号`
)类似于引号('
),因为它会阻止评估,但其效果可以使用逗号选择性地撤消(,
); ,@
和,
类似{{1}},除了它的参数必须是一个列表,它被拼接到结果列表中。
答案 1 :(得分:4)
根据(elisp)Top > Debugging > Edebug > Edebug and Macros
,您必须告诉Edebug如何通过使用debug
语句或使用def-edebug-spec
来定义宏来调试宏。这告诉它应该评估哪些参数,哪些参数不应该评估。所以它可以完成。事实上,c-lang-defconst
似乎已经适合edebug
。以下是您感兴趣的定义:
(def-edebug-spec c-lang-defconst
(&define name [&optional stringp] [&rest sexp def-form]))
但是,如果您只想查看正文评估的内容,那么执行此操作的方法是使用下面的macro-expand-last-sexp
之类的内容来查看结果。将光标放在要展开的性别之后(就像C-x C-e
那样)并运行M-x macro-expand-last-sexp RET
。这将向您展示它扩展到什么。如果您尝试扩展,(....)
之类的内容,可能会遇到麻烦,因此您可能需要将该性别复制到其他地方并删除,
或,@
。
(defun macro-expand-last-sexp (p)
"Macro expand the previous sexp. With a prefix argument
insert the result into the current buffer and pretty print it."
(interactive "P")
(let*
((sexp (preceding-sexp))
(expanded (macroexpand sexp)))
(cond ((eq sexp expanded)
(message "No changes were found when macro expanding"))
(p
(insert (format "%S" expanded))
(save-excursion
(backward-sexp)
(indent-pp-sexp 1)
(indent-pp-sexp)))
(t
(message "%S" expanded)))))
我想这取决于你想要做什么。