代码之家  ›  专栏  ›  技术社区  ›  Cheeso

Emacs:如何在宏中定义的代码上使用Edebug?

  •  8
  • Cheeso  · 技术社区  · 15 年前

    我甚至不知道这个lisp语法的正确术语,所以我不知道我用来问这个问题的词是否有意义。但我相信这个问题是有道理的。

    所以让我给你看看。CC模式(cc-fonts.el)有一个称为“matchers”的东西,它是一些运行的代码,用来决定如何确定代码区域的字体。这听起来很简单,但是Matcher代码的形式我不完全理解,它有反勾号和逗号a t符号,只有逗号等等,而且它嵌入到一个C-lang-defcost中,这个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语法,以了解这些东西是什么以及如何调用它们,但除此之外,我如何在阅读注释后的代码上运行edebug ;; Fontify the identifiers inside enum lists. ?

    我知道如何在defun上运行edebug-只需调用 edebug-defun 在函数的定义内,然后关闭。我是否需要做相应的事情来消除CC模式匹配器代码表单的缺陷?

    做什么? def-edebug-spec 是的,我会在这里用吗?如果是,如何?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Ivan Andrus    15 年前

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

    我想这完全取决于你想做什么。

        2
  •  4
  •   huaiyuan    15 年前

    使用 macroexpand macroexpand-all 把它变成无宏代码并像往常一样调试?

    backticks&co最好用一个例子来说明:

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

    反勾号(或反引号) ` )类似于报价单( ' )因为它可以防止评估,除非它的效果可以用逗号选择性地撤销。( , ;及 ,@ 就像 , ,但其参数必须是列表,并拼接到结果列表中。