2010-04-24 62 views
8

我甚至不知道这个lisp语法的正确术语,所以我不知道我用来提问的词语是否合理。但我相信这个问题是有道理的。emacs:如何在宏中定义的代码上使用edebug?

所以让我给你看看。 cc-mode(cc-fonts.el)有一些名为“匹配器”的东西,它们是代码的一部分,用于决定如何实现代码区域。这听起来很简单,但matcher代码是一种我不完全了解的形式,使用反引号和逗号,逗号和逗号等等,此外它嵌入在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))))))) 

我就口齿不清语法阅读了找出那些东西是什么,从调用它们,但除此之外,我怎么能在后面的注释中的代码运行edebug那读取;; Fontify the identifiers inside enum lists.

我知道如何在defun上运行edebug - 只需在函数的定义中调用edebug-defun,然后关闭。有没有相应的事情我需要做的edebug cc模式匹配代码形式?

def-edebug-spec做什么,我会在这里使用它?如果是这样,怎么样?

回答

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看到的结果。将光标定位在要扩展的sexp之后(如您对C-x C-e),并运行M-x macro-expand-last-sexp RET。这会告诉你它扩展到了什么地方。如果您尝试扩展,(....)之类的内容,则可能会遇到麻烦,因此您可能必须在其他位置复制该sexp并删除,,@

(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))))) 

我想这取决于你正在尝试做什么。

+0

这已经有一段时间了,但我相信edebug会处理反向宏(')及其适当内联(,和@)的特殊构造。没有办法在定义中的子表达式上使用edebug。相反,你必须对整个defun或顶级表达进行整理。 – dlaliberte 2011-07-28 13:54:57

4

使用macroexpandmacroexpand-all将它变成无宏代码并像往常一样进行调试?

反引号& CO可以用一个例子来最佳地示出:

(let ((a 1) 
     (b (list 2 3))) 
    `(a ,a ,b ,@b)) 
-> (a 1 (2 3) 2 3) 

甲反引号(或反引号`)类似于报价(')中,它可以防止评价,除了其效果可被选择性地复原用逗号(,);和,@就像,,除了它的参数必须是一个列表,它被拼接到结果列表中。