मैं http://coffeescript.org/ वेबसाइट पर CoffeeScript पर शोध कर रहा हूं , और इसमें टेक्स्ट है
CoffeeScript कंपाइलर को खुद CoffeeScript में लिखा गया है
एक कंपाइलर खुद को कैसे संकलित कर सकता है, या इस कथन का क्या अर्थ है?
मैं http://coffeescript.org/ वेबसाइट पर CoffeeScript पर शोध कर रहा हूं , और इसमें टेक्स्ट है
CoffeeScript कंपाइलर को खुद CoffeeScript में लिखा गया है
एक कंपाइलर खुद को कैसे संकलित कर सकता है, या इस कथन का क्या अर्थ है?
जवाबों:
एक संकलक का पहला संस्करण एक प्रोग्रामिंग भाषा से मशीन-जनरेट नहीं किया जा सकता है जो इसके लिए विशिष्ट है; आपका भ्रम समझ में आता है। पहले संकलक द्वारा अधिक भाषा सुविधाओं (नई भाषा के पहले संस्करण में फिर से लिखे गए स्रोत) के साथ संकलक का एक बाद का संस्करण बनाया जा सकता है। वह संस्करण फिर अगले संकलक को संकलित कर सकता है, और इसी तरह। यहाँ एक उदाहरण है:
नोट: मुझे यकीन नहीं है कि कॉफ़ीस्क्रिप्ट संस्करण कैसे गिने जाते हैं, यह सिर्फ एक उदाहरण था।
इस प्रक्रिया को आमतौर पर बूटस्ट्रैपिंग कहा जाता है । बूटस्ट्रैपिंग कंपाइलर का एक और उदाहरण rustc
, रस्ट भाषा के लिए कंपाइलर है ।
ट्रस्टिंग ट्रस्ट पर पेपर रिफ्लेक्शंस में , यूनिक्स के प्रवर्तकों में से एक, केन थॉम्पसन, सी कंपाइलर खुद को कैसे संकलित करता है, इसका एक आकर्षक (और आसानी से पठनीय) अवलोकन लिखते हैं। इसी तरह की अवधारणाओं को कॉफीस्क्रिप्ट या किसी अन्य भाषा में लागू किया जा सकता है।
संकलक का विचार जो अपने स्वयं के कोड को संकलित करता है, वह बिल्कुल एक क्वीन के समान होता है : स्रोत कोड जो निष्पादित होने पर, मूल स्रोत कोड के आउटपुट के रूप में उत्पन्न होता है। यहां एक कॉफ़ीस्क्रिप्ट क्वीन का एक उदाहरण है। थॉम्पसन ने C quine का उदाहरण दिया:
char s[] = {
'\t',
'0',
'\n',
'}',
';',
'\n',
'\n',
'/',
'*',
'\n',
… 213 lines omitted …
0
};
/*
* The string s is a representation of the body
* of this program from '0'
* to the end.
*/
main()
{
int i;
printf("char\ts[] = {\n");
for(i = 0; s[i]; i++)
printf("\t%d,\n", s[i]);
printf("%s", s);
}
इसके बाद, आप आश्चर्यचकित हो सकते हैं कि कंपाइलर को कैसे सिखाया जाता है कि '\n'
ASCII कोड 10 का एक एस्केप सीक्वेंस होता है । इसका उत्तर यह है कि कहीं न कहीं C कंपाइलर में एक रुटीन होता है जो चरित्र शाब्दिकों की व्याख्या करता है, जिसमें कुछ शर्तें होती हैं जैसे बैकस्लैम सीक्वेंस को पहचानना:
…
c = next();
if (c != '\\') return c; /* A normal character */
c = next();
if (c == '\\') return '\\'; /* Two backslashes in the code means one backslash */
if (c == 'r') return '\r'; /* '\r' is a carriage return */
…
तो, हम ऊपर दिए गए कोड में एक शर्त जोड़ सकते हैं ...
if (c == 'n') return 10; /* '\n' is a newline */
... एक संकलक का उत्पादन करने के लिए जो जानता है कि '\n'
ASCII 10 का प्रतिनिधित्व करता है। दिलचस्प बात यह है कि संकलक, और इसके बाद संकलित सभी संकलक , "मैपिंग" जानते हैं, ताकि स्रोत कोड की अगली पीढ़ी में, आप उस अंतिम पंक्ति को बदल सकें।
if (c == 'n') return '\n';
... और यह सही काम करेगा! 10
संकलक से आता है, और अब स्पष्ट रूप से संकलक के स्रोत कोड में परिभाषित करने की आवश्यकता। 1
यह C भाषा सुविधा का एक उदाहरण है जिसे C कोड में लागू किया गया था। अब, हर एक भाषा सुविधा के लिए उस प्रक्रिया को दोहराएं, और आपके पास "स्वयं-होस्टिंग" संकलक है: एक सी संकलक जो कि सी में लिखा गया है।
1 कागज में वर्णित प्लॉट ट्विस्ट यह है कि चूंकि कंपाइलर को इस तरह से "सिखाया गया" तथ्यों के रूप में बताया जा सकता है, इसलिए ट्रोजन अंजामों को इस तरह से उत्पन्न करना भी गलत तरीके से सिखाया जा सकता है, जो पता लगाना मुश्किल है, और तोड़फोड़ का ऐसा कार्य जारी रह सकता है सभी संकलक दागी संकलक द्वारा उत्पादित।
आपने पहले ही बहुत अच्छा उत्तर प्राप्त कर लिया है, हालांकि मैं आपको एक अलग दृष्टिकोण प्रदान करना चाहता हूं, जो कि आपके लिए ज्ञानवर्धक होगा। आइए पहले दो तथ्यों को स्थापित करें, जिन पर हम दोनों सहमत हो सकते हैं:
मुझे यकीन है कि आप सहमत हो सकते हैं कि दोनों # 1 और # 2 सच हैं। अब, दो कथनों को देखें। क्या अब आप देखते हैं कि कॉफ़ीस्क्रिप्ट संकलक के लिए कॉफ़ीस्क्रिप्ट संकलक को संकलित करना पूरी तरह से सामान्य है?
संकलक को परवाह नहीं है कि वह क्या संकलित करता है। जब तक यह कॉफीस्क्रिप्ट में लिखा गया एक कार्यक्रम है, तब तक यह इसे संकलित कर सकता है। और CoffeeScript संकलक ही इस तरह के एक कार्यक्रम होने के लिए होता है। कॉफीस्क्रिप्ट कंपाइलर को इस बात की परवाह नहीं है कि यह कॉफीस्क्रिप्ट कंपाइलर है जो इसे संकलित कर रहा है। यह सब देखता है कुछ CoffeeScript कोड है। अवधि।
एक कंपाइलर खुद को कैसे संकलित कर सकता है, या इस कथन का क्या अर्थ है?
हां, यह वही है जो इस कथन का अर्थ है, और मुझे आशा है कि आप अब देख सकते हैं कि यह कथन सत्य कैसे है।
एक कंपाइलर खुद को कैसे संकलित कर सकता है, या इस कथन का क्या अर्थ है?
इसका मतलब बिल्कुल यही है। सबसे पहले, कुछ बातों पर विचार करें। चार वस्तुओं को देखने की जरूरत है:
अब, यह स्पष्ट होना चाहिए कि आप किसी भी मनमाने ढंग से कॉफ़ीस्क्रिप्ट प्रोग्राम को संकलित करने के लिए उत्पन्न विधानसभा - निष्पादन योग्य - कॉफ़ीस्क्रिप्ट कंपाइलर का उपयोग कर सकते हैं, और उस कार्यक्रम के लिए विधानसभा उत्पन्न कर सकते हैं।
अब, CoffeScript संकलक स्वयं एक मनमाना CoffeScript प्रोग्राम है, और इस प्रकार, इसे CoffeScript संकलक द्वारा संकलित किया जा सकता है।
ऐसा लगता है कि आपका भ्रम इस तथ्य से उपजा है कि जब आप अपनी नई भाषा बनाते हैं, तो आपके पास कोई कंपाइलर नहीं होता है फिर भी आप अपने कंपाइलर का उपयोग कर सकते हैं। यह निश्चित रूप से चिकन-अंडे की समस्या की तरह दिखता है , है ना?
बूटस्ट्रैपिंग नामक प्रक्रिया का परिचय दें ।
अब आपको नई सुविधाओं को जोड़ने की आवश्यकता है। कहें कि आपने केवल while
-लूप लागू किया है, लेकिन for
-लूप भी चाहते हैं । यह कोई समस्या नहीं है, क्योंकि आप किसी भी for
-लूप को इस तरह से फिर से लिख सकते हैं जैसे कि यह while
-लूप है। इसका मतलब है कि आप केवल while
अपने कंपाइलर के सोर्स कोड में -loops का उपयोग कर सकते हैं , क्योंकि आपके पास जो असेंबली है वह केवल उन लोगों को संकलित कर सकता है। लेकिन आप अपने कंपाइलर के अंदर फंक्शन्स बना सकते हैं, जो for
इसके साथ-पाओ और संकलन कर सकते हैं । फिर आप पहले से ही असेंबली का उपयोग करते हैं, और नए संकलक संस्करण को संकलित करते हैं। और अब आपके पास एक संकलक की एक असेंबली है जो for
पार्सल और संकलन -लूप भी कर सकता है ! अब आप अपने संकलक के स्रोत फ़ाइल पर वापस जा सकते हैं, और किसी भी while
-loops को फिर से लिख सकते हैं जिसे आप for
-loops में नहीं चाहते हैं ।
कुल्ला और दोहराएं जब तक कि वांछित सभी भाषा सुविधाएँ संकलक के साथ संकलित नहीं की जा सकती हैं।
while
और for
स्पष्ट रूप से केवल उदाहरण थे, लेकिन यह किसी भी नई भाषा सुविधा के लिए काम करता है जिसे आप चाहते हैं। और फिर आप इस स्थिति में हैं कि कॉफस्क्रिप्ट अब में है: संकलक खुद को संकलित करता है।
वहाँ बहुत साहित्य है। ट्रस्टिंग ट्रस्ट पर विचार एक क्लासिक है जो उस विषय में रुचि रखने वाले सभी को कम से कम एक बार पढ़ना चाहिए।
यहाँ संकलक शब्द इस तथ्य से अधिक चमकता है कि इसमें दो फाइलें शामिल हैं। एक निष्पादन योग्य है जो कॉफ़स्क्रिप्ट में लिखी गई इनपुट फ़ाइलों के रूप में लेता है और इसके आउटपुट फ़ाइल के रूप में एक और निष्पादन योग्य, एक लिंक करने योग्य ऑब्जेक्ट फ़ाइल, या एक साझा लाइब्रेरी का उत्पादन करता है। दूसरी एक कॉफीस्क्रिप्ट स्रोत फ़ाइल है जो सिर्फ कॉफीस्क्रिप्ट संकलन की प्रक्रिया का वर्णन करने के लिए होती है।
आप पहले फ़ाइल को दूसरे पर लागू करते हैं, एक तीसरा निर्माण करते हैं जो संकलन के समान कार्य करने में सक्षम है पहला (संभवतः अधिक, यदि दूसरी फ़ाइल पहले द्वारा लागू नहीं की गई विशेषताओं को परिभाषित करती है), और इसलिए यदि आप पहली जगह ले सकते हैं इतनी इच्छा।
चूंकि कॉफ़ीस्क्रिप्ट कंपाइलर के रूबी संस्करण पहले से ही मौजूद थे, इसलिए इसका उपयोग कॉफ़ीस्क्रिप्ट कंपाइलर के कॉफ़ीस्क्रिप्ट संस्करण को बनाने के लिए किया गया था।
इसे सेल्फ-होस्टिंग कंपाइलर के रूप में जाना जाता है ।
यह बेहद सामान्य है, और आमतौर पर एक लेखक की अपनी भाषा के विकास को बनाए रखने के लिए अपनी भाषा का उपयोग करने की इच्छा होती है।
यह यहाँ संकलक की बात नहीं है, बल्कि भाषा की अभिव्यक्ति की बात है, क्योंकि संकलक केवल किसी भाषा में लिखा गया कार्यक्रम है।
जब हम कहते हैं कि "एक भाषा लिखी / कार्यान्वित की जाती है" तो हमारा वास्तव में मतलब है कि उस भाषा के लिए एक संकलक या दुभाषिया लागू किया जाता है। प्रोग्रामिंग भाषाएं हैं जिनमें आप प्रोग्राम लागू कर सकते हैं जो भाषा को लागू करते हैं (उसी भाषा के लिए कंपाइलर / व्याख्याकार हैं)। इन भाषाओं को सार्वभौमिक भाषा कहा जाता है ।
इसे समझने में सक्षम होने के लिए, धातु के खराद के बारे में सोचें। यह एक उपकरण है जिसका उपयोग धातु को आकार देने के लिए किया जाता है। यह संभव है, उस उपकरण का उपयोग करके, उसके भागों को बनाकर, एक और समान उपकरण बनाने के लिए। इस प्रकार, वह उपकरण एक सार्वभौमिक मशीन है। बेशक, पहले एक अन्य साधनों (अन्य उपकरण) का उपयोग करके बनाया गया था, और शायद कम गुणवत्ता का था। लेकिन पहले वाले का उपयोग उच्च परिशुद्धता के साथ नए निर्माण के लिए किया गया था।
एक 3 डी प्रिंटर लगभग एक सार्वभौमिक मशीन है। आप 3D प्रिंटर का उपयोग करके पूरे 3 डी प्रिंटर को प्रिंट कर सकते हैं (आप प्लास्टिक को पिघलाने वाले टिप का निर्माण नहीं कर सकते हैं)।
संकलक का n + 1 वां संस्करण X में लिखा गया है।
इस प्रकार यह संकलक के nth संस्करण (जिसे X में भी लिखा गया है) द्वारा संकलित किया जा सकता है।
लेकिन X में लिखे गए संकलक के पहले संस्करण को X के लिए एक संकलक द्वारा संकलित किया जाना चाहिए जो X के अलावा किसी अन्य भाषा में लिखा गया है। इस चरण को संकलक को बूटस्ट्रैपिंग कहा जाता है।
कंपाइलर एक उच्च-स्तरीय विनिर्देश लेते हैं और इसे निम्न-स्तरीय कार्यान्वयन में बदल देते हैं, जैसे कि हार्डवेयर पर निष्पादित किया जा सकता है। इसलिए विनिर्देश के प्रारूप और वास्तविक निष्पादन के बीच कोई संबंध नहीं है इसके अलावा भाषा के शब्दार्थ को लक्षित किया जा रहा है।
क्रॉस-कंपाइलर एक सिस्टम से दूसरे सिस्टम में जाते हैं, क्रॉस-भाषा कंपाइलर एक भाषा विनिर्देश को दूसरे भाषा विनिर्देश में संकलित करते हैं।
मूल रूप से संकलन एक मात्र अनुवाद है, और स्तर आमतौर पर उच्च स्तर की भाषा से निचले स्तर की भाषा है, लेकिन कई संस्करण हैं।
बूटस्ट्रैपिंग कंपाइलर, सबसे भ्रामक हैं, निश्चित रूप से, क्योंकि वे उस भाषा को संकलित करते हैं जिसमें वे लिखे गए हैं। बूटस्ट्रैपिंग में प्रारंभिक चरण को मत भूलना जिसमें निष्पादन योग्य कम से कम मौजूदा संस्करण की आवश्यकता होती है। कई बूटस्ट्रैप्ड संकलक पहले एक प्रोग्रामिंग भाषा की न्यूनतम विशेषताओं पर काम करते हैं और अतिरिक्त जटिल भाषा सुविधाएँ जोड़ते हैं, जब तक कि नई सुविधा को पिछली विशेषताओं का उपयोग करके व्यक्त किया जा सकता है। अगर ऐसा नहीं होता तो इसके लिए "कंपाइलर" के उस हिस्से को पहले से किसी दूसरी भाषा में विकसित किया जाना आवश्यक होता।
self-hosting
संकलक है। प्रोग्रामर