【问题标题】:Semantic, cedet how to force parsing of source files语义,cedet如何强制解析源文件
【发布时间】:2013-08-14 11:45:26
【问题描述】:

我一直在我的 emacs c/c++ 开发设置中试验 cedet 和语义,我对它非常满意,除了一个小细节。

我使用ede-cpp-root-project 创建一个项目,并提供我的项目的根目录以及包含文件所在的目录,如下所示:

(ede-cpp-root-project "My Project"
                :name "My Project"
                :file "/path/to/rootdir/AFILE"
                :include-path '( 
                "/include2"
                "/include1"
                               )

                )

这让我可以轻松地跳转到带有semantic-ia-fast-jump 的函数声明,但它无法让我了解这些函数的定义。所以它似乎只处理头文件而完全忽略源文件。即使我继续声明函数并触发semantic-analyze-proto-impl-toggle,它也会告诉我找不到合适的实现。

如果我手动打开函数实现所在的源文件,那么只有这样它被语义解析并且上述所有函数都起作用。

所以我的问题是,除了手动打开项目根目录下包含的所有源文件或通过:spp-files 参数手动将它们包含在ede-cpp-root-project 中之外,还有其他方法可以强制解析目录下的所有源文件?

谢谢!

【问题讨论】:

    标签: c++ c emacs cedet


    【解决方案1】:

    在长时间忽略这个问题后,我想我应该花一些时间阅读 elisp 并尝试找出解决方法。它不是最漂亮的 elisp 代码,因为我仅将 elisp 用于我的 emacs 需求,但它可以满足我的需求。

    (defvar c-files-regex ".*\\.\\(c\\|cpp\\|h\\|hpp\\)"
      "A regular expression to match any c/c++ related files under a directory")
    
    (defun my-semantic-parse-dir (root regex)
      "
       This function is an attempt of mine to force semantic to
       parse all source files under a root directory. Arguments:
       -- root: The full path to the root directory
       -- regex: A regular expression against which to match all files in the directory
      "
      (let (
            ;;make sure that root has a trailing slash and is a dir
            (root (file-name-as-directory root))
            (files (directory-files root t ))
           )
        ;; remove current dir and parent dir from list
        (setq files (delete (format "%s." root) files))
        (setq files (delete (format "%s.." root) files))
        (while files
          (setq file (pop files))
          (if (not(file-accessible-directory-p file))
              ;;if it's a file that matches the regex we seek
              (progn (when (string-match-p regex file)
                   (save-excursion
                     (semanticdb-file-table-object file))
               ))
              ;;else if it's a directory
              (my-semantic-parse-dir file regex)
          )
         )
      )
    )
    
    (defun my-semantic-parse-current-dir (regex)
      "
       Parses all files under the current directory matching regex
      "
      (my-semantic-parse-dir (file-name-directory(buffer-file-name)) regex)
    )
    
    (defun lk-parse-curdir-c ()
      "
       Parses all the c/c++ related files under the current directory
       and inputs their data into semantic
      "
      (interactive)
      (my-semantic-parse-current-dir c-files-regex)
    )
    
    (defun lk-parse-dir-c (dir)
      "Prompts the user for a directory and parses all c/c++ related files
       under the directory
      "
      (interactive (list (read-directory-name "Provide the directory to search in:")))
      (my-semantic-parse-dir (expand-file-name dir) c-files-regex)
    )
    
    (provide 'lk-file-search)
    

    要使用它,可以像这样直接调用函数:(my-semantic-parse-dir "path/to/dir/root/" ".*regex") 或从缓冲区按 M-x lk-parse-curdir-c 以递归扫描该缓冲区的访问文件名目录中的所有 c/c++ 相关文件。

    调用该函数的另一种可能更可取的方法是交互式调用lk-parse-dir-c,这反过来会提示您输入要解析的目录。

    如果任何 elisp 大师有更好的解决方案或建议来改进代码,我很乐意听到他们。

    【讨论】:

    • 嘿,我也偶然发现了你的博客,这个解决方案看起来不错,但是 emacs 不会跨会话保存标签数据库。我错过了什么吗?
    • 嘿,这很奇怪。它们应该保存在 .emacs 目录中名为 .semanticdb 的目录中
    • 我遇到了一个问题,我的文件列表太长了,以至于 emacs 可能会停止运行并且似乎没有进一步的进展。在我们进入下一个目录之前,我通过添加对 (semanticdb-save-all-db) 的调用来解决它。这样缓存会不断更新。也许这会有所帮助。通常语义只在你退出 emacs 时保存。
    • 正则表达式有问题。它让一切都被解析。快速解决方法是在搜索字符串的末尾添加$。此外,当语义解析失败时,函数也会失败。我不确定是否存在这样的实用程序,但是当它无法解析特定文件时,可能适合使用 continue-with-next-file 类型的处理。
    • 我添加了 (semanticdb-save-all-db) ,但标签不会跨会话保留。我跳到函数原型,而不是定义。怎么办?
    【解决方案2】:

    我最近为 Python 实现了这个。稍作改动即可用于 C/C++。

    (defvar python-extention-list (list "py"))
    
    (defun semanticdb-rescan-directory (pathname)
      (dolist (file (cddr (directory-files pathname t)))
        (if (file-directory-p file)
            (semanticdb-rescan-directory file)
          (when (member (file-name-extension file) python-extention-list)
            (message "Parsing %s file." file)
            (ignore-errors
                (semanticdb-file-table-object file))))))
    
    (defun semantic-python-rescan-includes ()
      (interactive)
      (dolist (includes (semantic-python-get-system-include-path))
        (message "Parsing %s" includes)
        (semanticdb-rescan-directory includes)))
    

    【讨论】:

      【解决方案3】:

      尝试运行命令“bovinate”。这可以通过组合键 Meta + X 然后键入“bovinate”,然后按“Enter”键来完成。 “Meta”键在 Windows 中称为“Alt”键。

      【讨论】:

      • 嘿,感谢您抽出时间回复,但我不知道 bovinate 对我的情况有何帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      相关资源
      最近更新 更多