C++ में DSL: वास्तविक समस्याओं के लिए अपनी खुद की प्रोग्रामिंग भाषा कैसे बनाएं

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

जब C++ सिर्फ एक भाषा नहीं, बल्कि भाषाओं का निर्माता है

\n\n

कल्पना करें कि आप एक जटिल रोबोटिक आर्म नियंत्रण प्रणाली लिख रहे हैं। हर दिन आप एक जैसे कमांड टाइप करते हैं: "सर्वो को 30 डिग्री घुमाएँ", "भाग को पकड़ें", "बिंदु X:100 Y:200 पर ले जाएँ"। शुद्ध C++ में कोड फ़ंक्शन कॉल और लूप की एक अंतहीन शीट में बदल जाता है। क्या होगा अगर आप मानव भाषा की तरह एक कमांड लिख सकें: move arm to (100, 200) at speed 50? और यह वास्तविक, संकलित C++ कोड हो?

\n\n

यह कल्पना नहीं है। यह है — DSL (Domain-Specific Language), या डोमेन-विशिष्ट भाषा। C++ पर आप अपनी खुद की मिनी-भाषा बना सकते हैं जो आपके डोमेन के कार्यों का पूरी तरह से वर्णन करेगी। इस लेख में हम सिर्फ सिद्धांत के बारे में बात नहीं करेंगे — हम शुरू से एक वास्तविक C++ DSL लिखेंगे, दो दृष्टिकोणों (आंतरिक और बाहरी) का विश्लेषण करेंगे और दिखाएंगे कि यह विकास को 5-10 गुना कैसे तेज़ करता है।

\n\n

उस दुनिया में आपका स्वागत है जहाँ प्रोग्रामर एक भाषाविद् बन जाता है, और कंपाइलर आपका अनुवादक बन जाता है।

\n\n

DSL क्या है और आपको इसकी आवश्यकता क्यों है?

\n\n

डोमेन-विशिष्ट भाषा (DSL) एक प्रोग्रामिंग भाषा है जो एक विशिष्ट क्षेत्र की समस्याओं को हल करने के लिए बनाई गई है। सामान्य प्रयोजन की भाषा (C++, Python, Java) के विपरीत, DSL बहुत संकीर्ण रूप से विशिष्ट है। उदाहरण जो आप शायद जानते हैं: SQL (डेटाबेस के लिए), Regex (पैटर्न खोजने के लिए), HTML (वेब पेज मार्कअप के लिए)।

\n\n

लेकिन C++ पर अपना खुद का DSL क्यों लिखें? तीन मुख्य कारण:

\n
    \n
  • कोड पठनीयता। आपका कोड तकनीकी विनिर्देश जैसा दिखता है। इसे न केवल एक प्रोग्रामर, बल्कि एक इंजीनियर, गणितज्ञ, डिज़ाइनर भी पढ़ और बदल सकता है।
  • \n
  • विकास की गति। 20 पंक्तियों के बॉयलरप्लेट कोड के बजाय — DSL पर एक पंक्ति।
  • \n
  • सुरक्षा। DSL आपको अपने सिस्टम के लिए वाक्यात्मक रूप से गलत कमांड लिखने नहीं देगा। त्रुटियाँ संकलन चरण में पकड़ी जाती हैं।
  • \n
\n\n

C++ टेम्पलेट्स (template metaprogramming), ऑपरेटर ओवरलोडिंग और मैक्रोज़ की शक्तिशाली प्रणाली के कारण DSL बनाने के लिए आदर्श है। आप एक DSL बना सकते हैं जो सामान्य C++ कोड जितनी तेज़ी से चलेगा, क्योंकि यह सीधे कंपाइलर में बनाया गया है।

\n\n

दो दुनियाएँ: Internal DSL बनाम External DSL

\n\n

कोड लिखने से पहले, आइए एक दृष्टिकोण चुनें। C++ के लिए दो प्रकार के DSL हैं:

\n\n

Internal DSL (एम्बेडेड DSL)

\n

आप कोई नया पार्सर नहीं लिखते। आप C++ सिंटैक्स — ऑपरेटर ओवरलोडिंग, मेथड चेनिंग, लैम्ब्डा — का उपयोग करके "भाषा के अंदर भाषा" बनाते हैं। यह C++ में सबसे लोकप्रिय दृष्टिकोण है। उदाहरण: Boost.Spirit लाइब्रेरी या रैखिक बीजगणित के लिए Eigen, जहाँ आप v = (3.0 * m1 + m2) * m3; लिखते हैं — यह गणितीय DSL जैसा दिखता है, लेकिन यह शुद्ध C++ है।

\n\n

External DSL (बाहरी DSL)

\n

आप शुरू से अपना खुद का सिंटैक्स बनाते हैं, एक पार्सर लिखते हैं (या ANTLR, Flex/Bison जैसे पार्सर जनरेटर का उपयोग करते हैं), और फिर इसे C++ कोड में अनुवाद करते हैं। यह अधिक कठिन है, लेकिन पूर्ण स्वतंत्रता देता है। उदाहरण के लिए, आप अपनी भाषा में एक स्क्रिप्ट लिख सकते हैं, और C++ प्रोग्राम इसे निष्पादित करेगा।

\n\n

इस लेख में हम दोनों विकल्प बनाएंगे। चलिए सरल से शुरू करते हैं — आंतरिक DSL।

\n\n

अभ्यास 1: रोबोट कॉन्फ़िगरेशन के लिए Internal DSL बनाना

\n\n

मान लीजिए कि हम रोबोट नियंत्रण के लिए एक लाइब्रेरी लिख रहे हैं। हमें क्रियाओं का एक क्रम निर्दिष्ट करना होगा। सामान्य कोड इस तरह दिखेगा:

\n\n
Robot robot;\nrobot.connect("COM3");\nrobot.setSpeed(50);\nrobot.moveTo(100, 200);\nrobot.grip(true);\nrobot.moveTo(300, 400);\nrobot.grip(false);\n
\n\n

यह काम करता है, लेकिन उबाऊ है। आइए इसे मेथड चेनिंग और ऑपरेटर ओवरलोडिंग का उपयोग करके DSL में बदलें। हम इस तरह लिखना चाहते हैं:

\n\n
Robot robot;\nrobot << connect("COM3") << speed(50)\n      << move(100, 200) << grip(on)\n      << move(300, 400) << grip(off);\n
\n\n

इसे कैसे लागू करें? "Builder" पैटर्न और <<

ब्लॉग

पुस्तक अनुशंसाएँ