2012-12-14 14 views
9

मैंने हाल ही में सी फाइलों को पार्स करने के लिए libclang का उपयोग करना शुरू कर दिया है। मेरी समस्या यह है कि स्पष्ट रूप से, libclang एएसटी उत्पन्न करने से पहले प्रीप्रोसेसर शुरू करता है। मैं चलने से पूर्वप्रक्रमक प्रतिबंधित करने के लिए, और बदले में जानकारी दी कि पूर्वप्रक्रमक निर्देशों फ़ाइल में हैं हो सकता है ...प्री-प्रोसेसर निर्देशों के बारे में जानकारी प्राप्त करें

मैं निम्नलिखित अजगर स्क्रिप्ट (cindex.py और libclang)

import codecs 
from clang.cindex import * 

class SourceFile(object): 
    def __init__(self, path): 
     with codecs.open(path, 'r', 'utf-8') as file: 
      self.file_content = file.read() 

     index = Index.create() 
     root_node = index.parse(path) 

     for included in root_node.get_includes(): 
      print included.include 

     self.print_declerations(root_node.cursor) 

    def print_declerations(self, root, recurse=True): 
     print root.kind.name, root.spelling 
     if root.kind.is_declaration(): 
      node_def = root.get_definition() 
      if node_def is not None: 
       start_offset = node_def.extent.start.offset 
       end_offset = node_def.extent.end.offset + 1 
       print self.file_content[start_offset:end_offset], '\n' 

     if recurse: 
      for child in root.get_children(): 
       self.print_declerations(child, False) 

if __name__ == '__main__': 
    path = 'Sample.cpp' 
    print 'Translation unit:', path 
    source = SourceFile(path) 

का उपयोग करना चाहते हैं कौन सा आउटपुट

Translation unit: Sample.cpp 
/mingw/include\stdio.h 
/mingw/include\_mingw.h 
/mingw/include\sys/types.h 
TRANSLATION_UNIT None 
TYPEDEF_DECL __builtin_va_list 

STRUCT_DECL _iobuf 

TYPEDEF_DECL FILE 

VAR_DECL _iob 
UNEXPOSED_DECL 

FUNCTION_DECL main 
int main() 
{ 
    printf(HELLO_WORLD); 
    return 0; 
} 

निम्नलिखित सी-कोड के लिए:

#include <stdio.h> 
#define HELLO_WORLD "HELLO!" 

int main() 
{ 
    printf(HELLO_WORLD); 
    return 0; 
} 

मैं चाहता हूं कि कोड में मेरे # परिभाषा के लिए DEFINE_DECL HELLO_WORLD प्राप्त करें (वर्तमान में मुझे कुछ भी नहीं मिलता है)। और निश्चित रूप से मेरे # शामिल के लिए समान बयान भी प्राप्त करें। क्या यह संभव है?

संपादित करें: असल में, मैं प्रीप्रोसेसर निर्देशों के बिना फ़ाइल को पार्स करना चाहता हूं।

+0

आप के अलावा कुछ विचार करने के लिए तैयार हैं, तो Clang, मेरे पास एक वैकल्पिक समाधान है। –

उत्तर

4

कुछ दिन पहले मैंने #llvm freenode irc चैनल पर एक ही प्रश्न पूछा है। जवाब था "मैक्रोज़ एएसटी का हिस्सा नहीं है, इसलिए आप नहीं कर सकते", लेकिन शायद सबसे अधिक "-fsyntax-only" विकल्प और libclang के बजाय क्लैंग प्लगइन आपकी मदद कर सकता है।

संपादित: ऐसा लगता है कि अब यह वास्तव में संभव है, bradtgmurray

+0

क्या आप अपना खुद का क्लैंग प्लगइन लिखना चाहते हैं? या वास्तव में एक प्लगइन वास्तव में क्लैंग प्लगइन कहा जाता है? Google पर उपयोग करने के लिए सबसे आसान वाक्यांश नहीं है। –

+1

चेकआउट 'क्लैंग' और 'उदाहरण' फ़ोल्डर में देखें। शुरू करने के लिए "प्रिंटफंक्शन नाम" और "विश्लेषक-प्लगइन" हो सकता है। –

19

आप index.parse करने के लिए अपने कॉल करने के लिए एक विकल्प() आप पूर्वप्रक्रमक नोड्स एक्सेस कर सकते हैं के रूप में PARSE_DETAILED_PROCESSING_RECORD जोड़ देते हैं तो द्वारा उत्तर देखें।

index = clang.cindex.Index.create()                   
tu = index.parse(filename, options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) 

यह विकल्प निम्नलिखित libclang सी API विकल्प मान के लिए मानचित्र है। वहां एक टिप्पणी है जिसमें कुछ और संदर्भ शामिल हैं।

/**                   
* \brief Used to indicate that the parser should construct a "detailed"  
* preprocessing record, including all macro definitions and instantiations. 
*                   
* Constructing a detailed preprocessing record requires more memory   
* and time to parse, since the information contained in the record   
* is usually not retained. However, it can be useful for     
* applications that require more detailed information about the    
* behavior of the preprocessor.            
*/                   
CXTranslationUnit_DetailedPreprocessingRecord = 0x01, 
+0

आज भी यह मिला। नया उत्तर जोड़ने के लिए यहां वापस जाएं, लेकिन यहां यह है। कुछ भी जोड़ने के लिए नहीं है। –

+0

ध्यान दें कि दस्तावेज गलत है। इसमें सभी मैक्रो इंस्टॉलेशन नहीं होते हैं, लेकिन केवल वे जो मैक्रो इंस्टेंटेशन के भीतर नहीं होते हैं (इसलिए, मैक्रो विस्तार का केवल एक स्तर ट्रैक किया जाता है)। आप इसे बदलने के लिए 'PreprocessingRecord :: addMacroExpansion' की शुरुआत में' if' को टिप्पणी कर सकते हैं। – Cameron

1

आप एक तरह से libclang आह्वान करने के लिए के रूप में आदेश पंक्ति तर्क का उपयोग कर रहे हैं, तो यहाँ libclang सी API कार्यान्वयन से प्रासंगिक कोड है:

// Do we need the detailed preprocessing record? 
if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 
    Args->push_back("-Xclang"); 
    Args->push_back("-detailed-preprocessing-record"); 
} 
संबंधित मुद्दे

 संबंधित मुद्दे