【问题标题】:Stack overflow while generating tags completion table in emacs在emacs中生成标签完成表时堆栈溢出
【发布时间】:2011-03-27 18:35:46
【问题描述】:

我在 Windows 上使用 GNU Emacs 23.3。我在一个非常大的代码库中工作,为此我生成一个 TAGS 文件(使用 Emacs 提供的 etags 二进制文件)。 TAGS 文件非常大(通常徘徊在 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:\path\to\some\header.h,0
^L
c:\path\to\some\otherheader.h,0

我的标签文件包含很多这种格式的条目。查看所涉及的标头,很明显它们无法被 etags 正确解析。这很好,但我很惊讶tags-completion-table 没有在其正则表达式中考虑这种格式。作为参考,下面是真实条目的样子:

^L
c:\path\to\some\validheader.h,115
class CSomeClass ^?12,345
bool SomeMethod(^?CSomeClass::SomeMethod^A67,890

【问题讨论】:

  • 我现在知道如何在事后修复我的 TAGS 文件,以便标签完成生成成功。随时发布有关如何防止首先生成虚假条目的建议...
  • 我使用 matlab 文件,因此我将 etags 与一堆自定义正则表达式一起使用,但我发现当我要求 etags 解析脚本时,TAGS 表中出现“错误条目”它没有找到任何有趣的标签。它会创建您指定的这种“空”条目,它只返回path,0。不知道如何抑制这种行为。幸运的是,这些似乎总是在 TAGS 文件的底部,所以为它写一个清理器应该很容易。

标签: emacs tags


【解决方案1】:

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

跟踪问题的一种方法是转到 TAGS 缓冲区并查看发生错误后的点(光标)在哪里。一旦你知道它是哪个函数,并且你可以不用为它添加标签,你就可以简单地避免为它生成 TAGS 条目。

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

【讨论】:

  • @paulcam:你能把触发问题的TAGS文件中的条目贴出来吗?
  • 结合您的建议和@vpit3833 的建议,我想我设法弄明白了。
【解决方案2】:

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

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

【讨论】:

  • 我现在确实经常使用 M-/,这就是为什么让标签完成工作并不重要的部分原因。但是,我仍然愿意尝试使用标签完成,因为我怀疑它仍然可以作为 dabbrev 的补充(或替代)有用。不过谢谢你的建议:)
  • 好的。如果将 (add-hook 'after-init-hook (lambda () (setq debug-on-error t))) 添加到 ~/.emacs 中,您能否发布完整的回溯?那应该点显示填充堆栈跟踪。
  • 完成了——不过看起来对我没有太大帮助:)
  • 有点明白了:)
【解决方案3】:

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

我已将建议的补丁应用到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\ 
\\(\\([^\n\001]+\\)\001\\)?\\([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)) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-28
    • 2011-07-26
    • 2011-05-29
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多