在emacs中生成标签完成表时堆栈溢出

我在Windows上使用GNU Emacs 23.3。 我在一个非常大的代码库中工作,为此我生成一个TAGS文件(使用Emacs提供的etags二进制文件)。 标签文件相当大(通常徘徊在100MB左右)。 我很少需要使用find-tag之外的任何功能,但有时候我希望能够完成TAGS表格。

调用complete-tag会导致Emacs自动创建一个完成表。 这个过程需要一段时间,但我的问题不在于花费的时间,而是在最后(大约100%完成)的事实,我得到了堆栈溢出(对于不可打印的字符感到抱歉) ):

Debugger entered--Lisp error: (error "Stack overflow in regexp matcher")
  re-search-forward("^(([^]+[^-a-zA-Z0-9_+*$:]+)?([-a-zA-Z0-9_+*$?:]+)[^-a-zA-Z0-9_+*$?:]*)(([^n]+))?([0-9]+)?,([0-9]+)?n" nil t)
  etags-tags-completion-table()
  byte-code(...)
  tags-completion-table()

有没有其他人遇到过这个问题? 知道解决它的方法吗?

编辑:打开debug-on-error后,堆栈输出

编辑:删除堆栈,因为我现在知道失败的条目是什么样子:

^L
c:pathtosomeheader.h,0
^L
c:pathtosomeotherheader.h,0

我的标签文件包含这种格式的不少条目。 看看所涉及的头文件,很明显,它们不能被etags正确解析。 这很好,但我很惊讶tags-completion-table在它的正则表达式中没有考虑这种格式。 作为参考,这里是一个真实的条目:

^L
c:pathtosomevalidheader.h,115
class CSomeClass ^?12,345
bool SomeMethod(^?CSomeClass::SomeMethod^A67,890

有问题的正则表达式用于匹配TAGS文件内的TAGS条目。 我猜如果文件格式不正确(例如,使用非本地行结束符),或者如果一个条目真的非常大,就会发生错误。 (一个条目通常是一两行,这对正则表达式匹配器来说不应该是个问题。)

跟踪问题的一种方法是转到TAGS缓冲区,并在发生错误后查看点(光标)的位置。 一旦你知道它是哪个功能,并且你可以在没有标签的情况下生存,你可以避免为它生成TAGS条目。

如果问题是由于输入太复杂,我建议您应该向Emacs团队发送错误报告。


如果加载标签表(使用Emacs打开TAGS表,然后bury-buffer ),请尝试Mx dabbrev-expand (绑定到M-/ )。 如果现在的前缀很常见,那么在达到所需的前缀之前,最终可能会遇到很多可能的完成。

我不使用Windows,但在我使用的Mac和Linux机器上,我没有遇到这个问题。


这看起来像Emacs中的一个错误,请参阅:

  • https://groups.google.com/d/msg/gnu.emacs.help/Ew0sTxk0C-g/YsTPVEKTBAAJ
  • https://debbugs.gnu.org/db/20/20703.html
  • 我已将建议的修补程序应用于etags-tags-completion-table (为了您的方便,将其完整地复制到下方)并捕获错误案例。

    我用非常长的一行代码(46,000个字符!)触发错误! 我假定有人以编程方式生成该行并将其粘贴到源代码中。 解决方法可能是在ctag构建或加载阶段简单地过滤这些行,只是删除“长”行,无论这可能意味着什么。 可能有500个字符够长!

    我也可以考虑在ctags中为我的正则表达式添加最大尺寸,但这并不是一个通用的解决方案,因为许多ctags模式没有这种限制。

    (defun etags-tags-completion-table () ; Doc string? 
      (let ((table (make-vector 511 0)) 
            (progress-reporter 
             (make-progress-reporter 
              (format "Making tags completion table for %s..." buffer-file-name) 
              (point-min) (point-max)))) 
        (save-excursion 
          (goto-char (point-min)) 
          ;; This monster regexp matches an etags tag line. 
          ;;   1 is the string to match; 
          ;;   2 is not interesting; 
          ;;   3 is the guessed tag name; XXX guess should be better eg DEFUN 
          ;;   4 is not interesting; 
          ;;   5 is the explicitly-specified tag name. 
          ;;   6 is the line to start searching at; 
          ;;   7 is the char to start searching at. 
          (condition-case err 
              (while (re-search-forward 
                      "^(([^177]+[^-a-zA-Z0-9_+*$:177]+)? 
    ([-a-zA-Z0-9_+*$?:]+)[^-a-zA-Z0-9_+*$?:177]*)177 
    (([^n01]+)01)?([0-9]+)?,([0-9]+)?n" 
                      nil t) 
                (intern        (prog1 (if (match-beginning 5) 
                                   ;; There is an explicit tag name. 
                                   (buffer-substring (match-beginning 5) (match-end 5)) 
                                 ;; No explicit tag name.  Best guess. 
                                 (buffer-substring (match-beginning 3) (match-end 3))) 
                          (progress-reporter-update progress-reporter (point))) 
                        table)) 
              (error 
               (message "error happened near %d" (point)) 
               (error (error-message-string err))))) 
          table)) 
    
    链接地址: http://www.djcxy.com/p/51639.html

    上一篇: Stack overflow while generating tags completion table in emacs

    下一篇: Displaying values in FPDF