2012-05-08 16 views
11

के लिए ऑटो-जनरेट स्ट्रीम ऑपरेटर क्या कोई स्ट्रक्चर या क्लास के लिए ostream < < ऑपरेटर को स्वतः उत्पन्न करने का कोई टूल है?स्ट्रक्चर/क्लास

इनपुट (One Debug-Print function to rule them all से लिया गया):

typedef struct ReqCntrlT /* Request control record */ 
{ 
    int    connectionID; 
    int    dbApplID; 
    char   appDescr[MAX_APPDSCR]; 
    int    reqID; 
    int   resubmitFlag; 
    unsigned int resubmitNo; 
    char   VCIver[MAX_VCIVER]; 
    int    loginID; 
} ReqCntrlT; 

आउटपुट:

std::ostream& operator <<(std::ostream& os, const ReqCntrlT& r) 
{ 
    os << "reqControl { " 
     << "\n\tconnectionID: " << r.connectionID 
     << "\n\tdbApplID: " << r.dbApplID 
     << "\n\tappDescr: " << r.appDescr 
     << "\n\treqID: " << r.reqID 
     << "\n\tresubmitFlag: " << r.resubmitFlag 
     << "\n\tresubmitNo: " << r.resubmitNo 
     << "\n\tVCIver: " << r.VCIver 
     << "\n\tloginID: " << r.loginID 
     << "\n}"; 
    return os; 
} 

किसी भी उपकरण ठीक होगा, पायथन/रूबी लिपियों को प्राथमिकता दी जाएगी।

+0

कोई स्वचालित श्रेणी क्रमिकरण उपकरण का प्रयास कर सकता है, मेरा मानना ​​है कि बूस्ट में एक है। क्या इससे कोई फर्क पड़ता है ऑपरेटर के आउटपुट का प्रारूप << आपके लिए है? – johnathon

+0

जेएसओएन, एक्सएमएल, जो कुछ भी मनुष्य पढ़ सकता है वह मेरे साथ ठीक है। –

+0

आप * शायद इसे बढ़ावा देने के साथ पीपी और एमपीएल – David

उत्तर

0

मैं आपके प्रश्न को दो तरीकों से समझ गया था।

यदि आप अपने कार्यक्रम की स्वचालित स्थिति रिपोर्ट जेनरेट करना चाहते हैं तो मैं आपको बूस्ट की जांच करने का सुझाव देता हूं। क्रमबद्धता। हालांकि यह पहले चरण या प्रेरणा के लिए संकलन-समय पर कोड उत्पन्न नहीं करेगा। नीचे दिया गया कोड आपको XML या txt फ़ाइलों को उत्पन्न करने में मदद करेगा जो आप बाद में पढ़ सकते हैं।

typedef struct ReqCntrlT /* Request control record */ 
{ 
    int    connectionID; 
    int    dbApplID; 
    char   appDescr[MAX_APPDSCR]; 
    int    reqID; 
    int   resubmitFlag; 
    unsigned int resubmitNo; 
    char   VCIver[MAX_VCIVER]; 
    int    loginID; 

    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) 
    { 
     ar & connectionID; 
     ar & reqID; 
     ... 
    } 
} ReqCntrlT; 

और अधिक विस्तार के लिए ट्यूटोरियल देखें: http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html

आप केवल अभी पैरामीटर नाम देकर कोड "लिखने" करने की कोशिश कर रहे हैं। उदाहरण के लिए आपको पाइथन या पर्ल में नियमित अभिव्यक्तियों को देखना चाहिए। इस समाधान का मुख्य डिफ़ॉल्ट यह है कि आप अपनी संरचना के "ऑफ़लाइन" हैं यानी हर बार जब आप कुछ बदलते हैं तो उसे चलाने के लिए होता है।

बेनोइट।

+0

मुख्य समस्या यह है कि मैं खुद को धारावाहिक विधि लिखना नहीं चाहता, क्योंकि यह उबाऊ और कठिन काम है। चूंकि मैं सभी structs को आउटपुट करना चाहता हूं, इसलिए मैं serialize() या ऑपरेटर <<() कोड को स्वत: उत्पन्न करना चाहता हूं। –

1

यह प्राप्त करने के लिए, एकमात्र तरीका बाहरी स्रोत का उपयोग करना है जिसे आप अपनी स्रोत फ़ाइलों पर चलाते हैं।

सबसे पहले, आप c/c++ analysing tool का उपयोग कर सकते हैं, और इसका उपयोग स्रोत कोड से पार्स पेड़ को पुनर्प्राप्त करने के लिए कर सकते हैं। फिर, एक बार जब आप पार्स पेड़ प्राप्त कर लेंगे, तो आपको केवल संरचनाओं को खोजना होगा। प्रत्येक संरचना के लिए, अब आप operator<< अधिभार उत्पन्न कर सकते हैं जो संरचना के क्षेत्र को क्रमबद्ध करता है। आप डी deserialize ऑपरेटर भी उत्पन्न कर सकते हैं।

लेकिन यह इस बात पर निर्भर करता है कि आपके पास कितनी संरचनाएं हैं: एक दर्जन बेहतर ऑपरेटरों को मैन्युअल रूप से लिखना बेहतर है, लेकिन यदि आपके पास कई सैकड़ों संरचनाएं हैं तो आप (डी) ऑपरेटर जेनरेटर को क्रमबद्ध करना चाहते हैं।

3

इसके लिए क्या आवश्यक है एक ऐसा उपकरण है जो सी ++ को सटीक रूप से पार्स कर सकता है, विभिन्न कक्षाओं/structs का आकलन कर सकता है, प्रति वर्ग/संरचना आधार पर अपने "क्रमिकरण" को निर्धारित और उत्पन्न कर सकता है, और फिर जेनरेट कोड को " सही जगह "(संभवतः वही दायरा जिसमें संरचना मिली थी)। असली कोड में निर्देशों के विस्तार को संभालने के लिए इसे एक पूर्ण प्रीप्रोसेसर की आवश्यकता है।

हमारे DMS Software Reengineering Toolkit इसके C++11 front end के साथ ऐसा कर सकता है। डीएमएस जेनेरिक पार्सिंग/एएसटी बिल्डिंग, प्रतीक तालिका निर्माण, प्रवाह और कस्टम विश्लेषण, परिवर्तन और स्रोत कोड पुनर्जनन क्षमता प्रदान करके कस्टम टूल्स के निर्माण को सक्षम बनाता है। सी ++ फ्रंट डीएमएस को सी ++ को पार्स करने और सटीक प्रतीक टेबल बनाने के साथ-साथ सुंदर प्रिंट संशोधित या नए एएसटी को संकलित स्रोत फ़ॉर्म पर वापस करने में सक्षम बनाता है। डीएमएस और उसके सी ++ फ्रंट एंड का उपयोग सी ++ कोड पर बड़े पैमाने पर परिवर्तन करने के लिए किया गया है।

आपको डीएमएस को समझा देना है कि आप क्या करना चाहते हैं; प्रतीक टेबल प्रविष्टियों की गणना करने के लिए सीधा लगता है, पूछें कि संरचना/वर्ग प्रकार की घोषणाएं, घोषणा के दायरे को निर्धारित करें (प्रतीक तालिका प्रविष्टि में दर्ज की गई), सतह सिंटैक्स पैटर्न लिखकर एएसटी का निर्माण करें, और उसके बाद निर्मित एएसटी डालने के लिए एक परिवर्तन लागू करें।

pattern ostream_on_slot(i:IDENTIFIER):expression = 
    " << "\n\t" << \tostring\(\i\) << r.\i "; -- tostring is a function that generates "<name>" 

pattern ostream_on_struct(i:IDENTIFIER,ostream_on_slots:expression): declaration = 
    " std::ostream& operator <<(std::ostream& os, const \i& r) 
    { os << \tostring\(\i\) << " { " << \ostream_on_slots << "\n}"; 
     return os; 
    } 

एक ostream_on_slot के लिए व्यक्तिगत पेड़ की रचना करने के होते हैं::

pattern compound_ostream(e1:expression, e2:expression): expression 
    = " \e1 << \e2 "; 

इन पैटर्न के साथ यह स्पष्ट है

कोर सतह वाक्य रचना की जरूरत पैटर्न स्लॉट के लिए और समारोह शरीर के लिए होते हैं संरचना के स्लॉट को गिनने के लिए, शरीर के लिए ओस्ट्रीम का निर्माण करें, और एक संरचना के लिए समग्र कार्य में डालें।

2

ऐसा करने के दो मुख्य तरीके हैं: (बजना बाइंडिंग पर झुका इस तरह के एक अजगर स्क्रिप्ट के रूप में)

  • एक बाहरी पार्स उपकरण का उपयोग कर
  • metaprogramming टेकनीक का उपयोग कर

.. और निश्चित रूप से वे मिश्रित किया जा सकता है।

मेरे पास क्लैंग पायथन बाइंडिंग के बारे में पर्याप्त जानकारी नहीं है, इसलिए मैं मेटाप्रोग्रामिंग पर ध्यान केंद्रित करूंगा।


असल में, जो आप पूछ रहे हैं आत्मनिरीक्षण की आवश्यकता है। सी ++ पूर्ण आत्मनिरीक्षण का समर्थन नहीं करता है, हालांकि मेटाप्रोग्रामिंग चाल (और टेम्पलेट मिलान) का उपयोग करके यह संकलन समय पर आत्मनिरीक्षण तकनीकों के सीमित सबसेट का समर्थन कर सकता है, जो हमारे उद्देश्य के लिए पर्याप्त है।

आसानी से मेटाप्रोग्रामिंग और रनटाइम ऑपरेशन को मिश्रित करने के लिए, पुस्तकालय को खेलना आसान है: Boost.Fusion

यदि आप अपनी संरचना को ट्विक करते हैं जैसे कि इसके गुण बूस्ट.फ्यूजन अनुक्रम के संदर्भ में अवरुद्ध होते हैं, तो आप अनुक्रम पर स्वचालित रूप से बहुत सारे एल्गोरिदम लागू कर सकते हैं। यहां, associate sequence सर्वोत्तम है।

क्योंकि हम metaprogramming बात कर रहे हैं, the map एक टाइप किया मूल्य करने के लिए एक प्रकार एकत्रित करती है।

फिर आप उस अनुक्रम पर for_each का उपयोग कर फिर से शुरू कर सकते हैं।


मैं विवरण पर चमक जाएगा, क्योंकि यह एक समय हो गया है और मुझे याद नहीं वाक्य रचना शामिल है, लेकिन मूल रूप से विचार करने के लिए है:

// Can be created using Boost.Preprocessor, but makes array types a tad difficult 
DECL_ATTRIBUTES((connectionId, int) 
       (dbApplId, int) 
       (appDescr, AppDescrType) 
       ... 
       ); 

जो वाक्यात्मक है चीनी की घोषणा किए जाने की फ्यूजन मानचित्र और इससे संबंधित टैग:

struct connectionIdTag {}; 
struct dbApplIdTag {}; 

typedef boost::fusion::map< 
    std::pair<connectionIdTag, int>, 
    std::pair<dbApplIdTag, int>, 
    ... 
    > AttributesType; 
AttributesType _attributes; 

फिर, किसी भी आपरेशन उस के साथ बस बनाया जा सकता है विशेषताओं पर लागू किया जा जरूरत:

+०१२३५१६४१०६
// 1. A predicate: 
struct Predicate { 
    template <typename T, typename U> 
    void operator()(std::pair<T, U> const&) const { ... } 
}; 

// 2. The for_each function 
for_each(_attributes, Predicate()); 
+0

@MatthieM: Di एक बाहरी समाधान पसंद करेगा, जिसमें मैं संरचना पेस्ट करता हूं और उत्पन्न करता हूं और फिर उत्पन्न ऑपरेटर कोड को कॉपी करता हूं। अधिकांश structs जिन्हें मैं आउटपुट करना चाहता हूं बाहरी पुस्तकालयों में हैं। –

+0

@ क्रिस्टोफर ओज़बेक: मुझे इसके लिए किसी भी "एकीकृत" उपकरण के बारे में पता नहीं है (मुझे लगता है कि बहुत विशिष्ट), लेकिन यदि आप डीएमएस (ईरा के उत्तर) के लिए भुगतान नहीं करना चाहते हैं, तो मेरा सुझाव है कि आपको क्लैंग प्रोजेक्ट में रुचि हो। Libclang के साथ आप सी ++ फ़ाइलों को पार्स कर सकते हैं और फिर एएसटी पर काम कर सकते हैं। आप क्लैंग देव मेल सूची पर विशिष्ट प्रश्न पूछ सकते हैं। –

+0

@MaththieM: धन्यवाद! बूस्ट :: फ्यूजन मेरी दूसरी परियोजना के लिए दिलचस्पी दिखता है! –