簡體   English   中英

解析C文件而不預處理它

[英]Parsing C files without preprocessing it

我想對C文件運行簡單的分析(例如,如果你用INT_TYPE作為參數調用foo宏,然后將響應轉換為int* ),我不想預處理文件,我只是想解析它(這樣,例如,我將有正確的行號)。

即,我想得到

#include <a.h>

#define FOO(f)

int f() {FOO(1);}

一個令牌列表

<include_directive value="a.h"/>
<macro name="FOO"><param name="f"/><result/></macro>
<function name="f">
    <return>int</return>
    <body>
        <macro_call name="FOO"><param>1</param></macro_call>
    </body>
</function>

無需設置包含路徑等

有沒有預先存在的解析器呢? 我知道的所有解析器都假設C是經過預處理的。 我想訪問宏和實際包含指令。

我們的C前端可以解析包含preprocesser元素的代碼,可以在相當程度上做到這一點,並且仍然構建一個可用的AST。 (是的,解析樹具有精確的文件/行/列號信息)。

有許多限制,允許它處理大多數代碼。 在少數情況下,它無法處理,通常是對源文件的一個小的,簡單的更改,給出等效的代碼解決了問題。

這是一套粗略的規則和限制:

  • #includes和#defines可以出現在聲明或語句可以發生的任何地方,但不能出現在語句的中間。 這些很少引起問題。
  • 宏調用可以發生在表達式中發生函數調用的地方,或者可以不用分號代替語句。 跨越非格式良好的塊的宏調用處理不好(任何人都感到驚訝?)。 后者偶爾發生但很少發生,需要手動修改。 OP的“j(v,oid)*”的例子是有問題的,但這在代碼中很少見。
  • #if ... #endif必須包含主要語言概念(非終結符) (常量,表達式,語句,聲明,函數)或此類實體的序列,或圍繞某些非格式良好但常見的慣用語,例如if (exp){ 條件的每個臂必須包含與其他臂相同類型的句法結構。 #if纏繞隨機文本作為壞評論是有問題的,但通過做出真正的評論很容易在源中修復。 如果不滿足這些條件,則需要修改原始源代碼,通常是移動#if #elsif #else #end幾個標記。

根據我們的經驗,人們可以在幾個小時內修改50,000行的代碼庫來解決這些問題。 雖然這看起來很煩人(而且確實如此),但替代方案是根本無法解析源代碼,這比煩人的要糟糕得多。

您還需要的不僅僅是解析器。 請參閱解析后的生活 ,了解成功獲取解析樹后會發生什么。 我們在構建符號表方面做了一些額外的工作,其中聲明是使用嵌入它們的預處理器上下文記錄的,從而使類型檢查能夠包含預處理器條件。

你可以看看這個ANTLR語法 但是,您必須為預處理程序令牌添加規則。

您可以通過編寫自己的解析並忽略宏擴展來處理您的具體示例。

因為FOO(1)本身可以解釋為函數調用。

但是,當考慮更多情況時,解析器要困難得多。 您可以參考PDF鏈接以查找更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM