簡體   English   中英

如何知道IntegerLiteral是否來自Clang的十進制或八進制表示?

[英]How to know if an IntegerLiteral comes from a decimal or octal representation with Clang?

您可能知道, Clang庫中的整數值由IntegerLiteral類處理。

但是,作為行動的問題,這兩項任務似乎沒有區別:

int i,j;
// i is assigned 42 with octal representation (052)
i = 052; 
//j is assigned 42 with decimal representation (42)
j = 42;

AST-dump產生相同的樹:

|-DeclStmt 0x1cbc5b0 <line:2:2, col:9>
| |-VarDecl 0x1cbc4d0 <col:2, col:6> i 'int'
| `-VarDecl 0x1cbc540 <col:2, col:8> j 'int'
|-BinaryOperator 0x1cbc610 <line:4:2, col:6> 'int' lvalue '='
| |-DeclRefExpr 0x1cbc5c8 <col:2> 'int' lvalue Var 0x1cbc4d0 'i' 'int'
| `-IntegerLiteral 0x1cbc5f0 <col:6> 'int' 42
|-BinaryOperator 0x1cbc680 <line:5:2, col:6> 'int' lvalue '='
| |-DeclRefExpr 0x1cbc638 <col:2> 'int' lvalue Var 0x1cbc540 'j' 'int'
| `-IntegerLiteral 0x1cbc660 <col:6> 'int' 42

我想提出一些警告,因為使用八進制表示會被危險地誤解。 我可以區分Clang解析這兩種表示的方式嗎?

呼叫clang::Lexer::getSpelling ,它傳遞SourceLocation您的IntegerLiteral 然后,您可以對八進制或您感興趣的任何其他拼寫屬性進行手動測試(例如,查找前導'0'后跟數字)。 手動執行此檢查還可以讓您正確地獲得一些特殊情況 - 例如, 0在技​​術上是八進制文字 ,但您可能不希望以這種方式對待它。

在無法實現理查德史密斯給出的答案后,我發現了一種非常討厭的方法(並且它不適用於MACROS),但萬一,這是我的(不完整但功能性)解決方案:

bool VisitIntegerLiteral(IntegerLiteral * intLiteral){
    // Source Location of current int literal
    SourceLocation loc = intLiteral->getLocation();
    // Source manager associated
    SourceManager &SM = _carrier->getSourceManager();
    // Get first char and second char of the integer literal (getCharacterData returns the whole code from the SourceLocation until the end of code)
    char first_char = SM.getCharacterData(loc,nullptr)[0];
    char second_char= SM.getCharacterData(loc,nullptr)[1];
    // If first character is 0
    if(first_char == '0'){
        // If second character is also a number
        if(second_char == '1' || second_char == '2' || second_char == '3' || second_char == '4' || second_char == '5' || second_char == '6' || second_char == '7' || second_char == '8' || second_char == '9'){
            cout << "This is an octal value" << endl;
        }
    }
    return true;
}

如果整數常量以八進制或十進制方式給出,那么它只是一個句法事實。 編譯后,整數文字將轉換為相同的二進制數。 在正數的情況下,表示由標准精確地表示,是存儲的整數值的精確二進制表示。

因此,在任何情況下,源程序中的基數信息(八進制,十進制,十六進制)都不會存儲在任何地方,因此在執行環境中無法了解它的任何信息。

我同意Deduplicator的評論:你需要預處理源代碼本身以“看到”這些信息。

另一種替代方法可能是您不在第一種方法中使用int值,而是使用字符串。

  char *s_val1 = "052";  
  char *s_val2 = "42";  
  if (radix(s_val1) == 8)   // You can write some function radix() to recognize the radix
      printf("%s is octal", s_val1);

  int val1 = octalstr_to_int(s_val1);  // You can write some string-to-integer convertion functions

暫無
暫無

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

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