2008-08-17 36 views
87

की आवश्यकता है, मैंने भाषा को बूटस्ट्रैप करने के विचार के बारे में सुना है, यानी भाषा के लिए एक कंपाइलर/दुभाषिया लिखना। मैं सोच रहा था कि यह कैसे पूरा किया जा सकता है और थोड़ा सा देखा, और किसी ने देखा कि यह केवलबूटस्ट्रैपिंग को अभी भी बाहरी समर्थन

  • एक अलग भाषा में प्रारंभिक कंपाइलर लिख सकता है। विधानसभा में एक प्रारंभिक संकलक, जो पहले

मेरे लिए का एक विशेष मामला की तरह लगता है

  • हाथ-कोडिंग, इनमें से कोई भी वास्तव में बूटस्ट्रैपिंग अर्थों में एक भाषा है कि वे दोनों बाहर की आवश्यकता होने लगते हैं समर्थन। क्या वास्तव में अपनी खुद की भाषा में एक कंपाइलर लिखने का कोई तरीका है?

  • +1

    जानकारी के लिए धन्यवाद, हर कोई। प्रारंभिक रूप से एक सीमित कंपाइलर लिखने के विचार के साथ समझाया गया, उसके बाद ऊपर की ओर बढ़ रहा है, तो बूटस्ट्रैपिंग का विचार अधिक समझ में आता है। मैं इस सेमेस्टर में एक कंपाइलर्स क्लास ले रहा हूं, एक निर्णय काफी हद तक प्रभावित होता है [स्टीव येगेज के पोस्ट पर कंपाइलर्स में कक्षा कितनी महत्वपूर्ण है] (http://steve-yegge.blogspot.com/2007/06/rich-programmer-food।एचटीएमएल) है, और मैंने अभी अमेज़ॅन लिंक से ड्रैगन पुस्तक की एक प्रति खरीदी है जो पहले एसओ पर इतनी कम हो गई थी। – pbh101

    +1

    इसी तरह के प्रश्न भी देखें: [अपने आप में एक कंपाइलर लागू करना] (http://stackoverflow.com/questions/193560/implementing-a-compiler-in-itself) –

    उत्तर

    98

    क्या वास्तव में अपनी भाषा में एक कंपाइलर लिखने का कोई तरीका है?

    आप में अपने नए संकलक लिखने के कुछ मौजूदा भाषा के लिए की है। आप एक नया, कहते हैं, सी ++ संकलक लिख रहे थे, तो आप सिर्फ C++ इसे लिखने और एक मौजूदा संकलक के साथ यह संकलन पहले होगा। दूसरी तरफ, यदि आप एक नई भाषा के लिए एक कंपाइलर बना रहे थे, तो इसे Yazzleof कहते हैं, आपको पहले किसी अन्य भाषा में नया कंपाइलर लिखना होगा। आम तौर पर, यह एक और प्रोग्रामिंग भाषा होगी, लेकिन यह होना जरूरी नहीं है। यह असेंबली हो सकती है, या यदि आवश्यक हो, तो मशीन कोड।

    यदि आप Yazzleof के लिए एक कंपाइलर बूटस्ट्रैप करने जा रहे थे, तो आप आमतौर पर पूरी भाषा के लिए एक कंपाइलर नहीं लिखेंगे। इसके बजाय आप Yazzle-lite के लिए एक कंपाइलर लिखेंगे, जो Yazzleof का सबसे छोटा संभव सबसेट (अच्छी तरह से, कम से कम सबसेट कम से कम)। फिर याज़ले-लाइट में, आप पूरी भाषा के लिए एक कंपाइलर लिखेंगे। (जाहिर है यह एक कूद में इसके बजाय क्रमशः हो सकता है।) क्योंकि याज़ले-लाइट याज़लेफ का एक उचित सबसेट है, अब आपके पास एक कंपाइलर है जो स्वयं संकलित कर सकता है।

    एक वास्तव में न्यूनतम संभव स्तर (जो एक आधुनिक मशीन पर मूल रूप से एक हेक्स संपादक है) से एक संकलक bootstrapping के बारे में अच्छा writeup नहीं है, कुछ भी नहीं से एक सरल संकलक बूटस्ट्रेपिंग शीर्षक । यह https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html पर पाया जा सकता है।

    +0

    github पर bcompiler का दर्पण है: https://github.com/certik/bcompiler – navigaid

    -1

    मुझे ऐसी चीजों के साथ बहुत अनुभवी नहीं है, लेकिन मुझे लगता है कि प्रारंभिक कंपाइलर को दूसरी भाषा में लिखा जाना होगा। मैं निश्चित रूप से निश्चित हूं कि कंपाइलर्स के संदर्भ में "बूटस्ट्रैपिंग", बस संकलक को उस भाषा में भाषा के लिए लिखने के लिए संदर्भित करता है, जिसकी भाषा संकलित करने के लिए है, लिखने वाली भाषा में भाषा के लिए पहले कंपाइलर नहीं लिखना संकलन।

    5

    जिस तरह से मैंने सुना है, वह दूसरी भाषा में एक बेहद सीमित कंपाइलर लिखना है, फिर नई भाषा में लिखे गए एक और जटिल संस्करण को संकलित करने के लिए इसका उपयोग करें। इस दूसरे संस्करण का उपयोग स्वयं संकलित करने के लिए और अगले संस्करण को संकलित करने के लिए किया जा सकता है। प्रत्येक बार जब इसे संकलित किया जाता है तो अंतिम संस्करण का उपयोग किया जाता है।

    यह bootstrapping:

    एक और अधिक जटिल प्रणाली है कि एक ही उद्देश्य में कार्य करता को सक्रिय करने के लिए एक सरल प्रणाली की प्रक्रिया की परिभाषा है।

    संपादित करें: Wikipedia article on compiler bootstrapping मेरे से बेहतर अवधारणा को शामिल करता है।

    19

    आपके द्वारा पढ़ा गया स्पष्टीकरण सही है। वहाँ में Compilers: Principles, Techniques, and Tools (ड्रैगन पुस्तक) इस की चर्चा है:

    • भाषा में भाषा एक्स के लिए एक संकलक सी 1 Y
    • उपयोग संकलक सी 1 लिखें भाषा एक्स में भाषा एक्स के लिए संकलक सी 2 लिखने के लिए
    • अब सी 2 पूरी तरह से स्वयं होस्टिंग वातावरण है। के बाद वहाँ एक काम संकलक था
    2

    एक भाषा मैं (C, PyPy) के बारे में सोच सकते हैं bootstrapping का हर उदाहरण किया गया था। आपको कहीं से शुरू करना है, और खुद को एक भाषा को फिर से लागू करने के लिए पहले किसी अन्य भाषा में एक कंपाइलर लिखना होगा।

    यह और कैसे काम करेगा? मुझे नहीं लगता कि यह अन्यथा करने के लिए भी अवधारणात्मक रूप से संभव है।

    +4

    कम से कम पहले लिस्प कंपाइलर को मौजूदा का उपयोग करके बूटस्ट्रैप किया गया था लिस्प * दुभाषिया *। तो अर्थात् एक और भाषा नहीं, लेकिन एक और भाषा कार्यान्वयन। – Ken

    2

    यह चिकन-एंड-अंडे विरोधाभास का कंप्यूटर विज्ञान संस्करण है। मैं असेंबलर या किसी अन्य भाषा में प्रारंभिक कंपाइलर नहीं लिखने का एक तरीका नहीं सोच सकता। अगर यह किया जा सकता था, तो मुझे लिस्प इसे कर सकता था।

    वास्तव में, मुझे लगता है कि लिस्प लगभग योग्यता प्राप्त करता है। its Wikipedia entry देखें। लेख के मुताबिक, लिस्प eval फ़ंक्शन को IBM 704 पर मशीन कोड में लागू किया जा सकता है, जिसमें एक पूर्ण कंपाइलर (लिस्प में लिखा गया है) 1 9 62 में MIT पर आ रहा था।

    7

    एक सुपर रोचक discussion of this यूनिक्स सह-निर्माता Ken Thompson के Turing Award व्याख्यान में है।

    क्या मैं के बारे में वर्णन करने के लिए कर रहा हूँ कई "चिकन और अंडे" समस्या पैदा जब compilers उनकी अपनी भाषा में लिखे गए हैं में से एक है:

    उन्होंने साथ शुरू होता है। इस आसानी से, मैं सी संकलक से एक विशिष्ट उदाहरण का उपयोग करूंगा।

    और आय दिखाने के लिए कि कैसे वह यूनिक्स सी संकलक कि हमेशा उसे एक पासवर्ड के बिना में लॉग इन करने की अनुमति होगी के एक संस्करण में लिखा है, क्योंकि सी संकलक लॉगिन कार्यक्रम समझते हैं और विशेष कोड में जोड़ना होगा।

    दूसरा पैटर्न सी संकलक के उद्देश्य से है। प्रतिस्थापन कोड एक चरण I स्वयं-पुनरुत्पादन प्रोग्राम है जो ट्रोजन हॉर्स दोनों को कंपाइलर में सम्मिलित करता है। स्टेज II उदाहरण में इसे सीखने के चरण की आवश्यकता होती है। सबसे पहले हम संशोधित स्रोत को सामान्य सी कंपाइलर के साथ एक बग़ाइन बाइनरी बनाने के लिए संकलित करते हैं। हम इस बाइनरी को आधिकारिक सी के रूप में स्थापित करते हैं। अब हम कंपाइलर के स्रोत से बग को हटा सकते हैं और जब भी इसे संकलित किया जाता है तो नई बाइनरी बग को फिर से जोड़ देगा। बेशक, लॉगिन कमांड कहीं भी स्रोत में कोई निशान के साथ बग़े रहेंगे।

    +7

    यह ऑफ-विषय है .. दिलचस्प, लेकिन भ्रमित, और सवाल का जवाब नहीं। – blueshift

    2

    एक और विकल्प आपकी भाषा के लिए बाइटकोड मशीन बनाना है (या मौजूदा सुविधाओं का उपयोग करना बहुत ही असामान्य नहीं है) और बाइटकोड में या तो एक अन्य इंटरमीडिएट का उपयोग करके बाइटकोड में एक कंपाइलर लिखें - जैसे एक पार्सर टूलकिट जो एएसटी को एक्सएमएल के रूप में आउटपुट करता है, फिर एक्सएसएलटी (या अन्य पैटर्न मिलान करने वाली भाषा और पेड़-आधारित प्रतिनिधित्व) का उपयोग करके एक्सएमएल को बाइटकोड में संकलित करें। यह निर्भरता को किसी अन्य भाषा पर नहीं हटाता है, लेकिन इसका मतलब यह हो सकता है कि बूटस्ट्रैपिंग कार्य का अधिकतर अंतिम सिस्टम में समाप्त होता है।

    4

    पॉडकास्ट Software Engineering Radio episode 61 (2007-07-06) देखें जो जीसीसी कंपाइलर आंतरिक, साथ ही जीसीसी बूटस्ट्रैपिंग प्रक्रिया पर चर्चा करता है।

    3

    जैसा कि मैं इसे समझता हूं, पहले Lisp दुभाषिया को कन्स्ट्रक्टर फ़ंक्शंस और टोकन रीडर को हाथ से संकलित करके बूटस्ट्रैप किया गया था। शेष दुभाषिया को तब स्रोत से पढ़ा गया था।

    आप मूल मैककार्थी पेपर, Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I पढ़कर स्वयं को देख सकते हैं।

    +0

    जो भी भाग 2 और 3 के साथ हुआ? ... मैंने यह नहीं देखा कि @Wing ने मुझसे 3 साल पहले एक ही चीज़ पोस्ट की थी? मैं एक डंसी हूँ। कम से कम मैंने पेपर को जोड़ा (सहायता के साथ)। –

    4

    Donald E. Knuth वास्तव में इसमें संकलक लिखकर WEB बनाया गया, और उसके बाद इसे असेंबली या मशीन कोड में संकलित किया गया।

    0

    कुछ बूटस्ट्रैप compilers या सिस्टम दोनों स्रोत प्रपत्र और उनके भंडार में वस्तु प्रपत्र रखें:

    • ocaml जो दोनों एक बाईटकोड दुभाषिया (यानी OCaml बाईटकोड करने के लिए एक संकलक) और एक देशी है एक भाषा है कंपाइलर (x86-64 या एआरएम, आदि ... असेंबलर)। इसके svn भंडार में दोनों स्रोत कोड (फाइल */*.{ml,mli}) और बाइटकोड (फ़ाइल boot/ocamlc) कंपाइलर के रूप दोनों शामिल हैं। तो जब आप इसे बनाते हैं तो पहले इसे संकलित करने के लिए अपने बाइटकोड (कंपाइलर के पिछले संस्करण के) का उपयोग कर रहा है। बाद में ताजा संकलित बाइटकोड मूल कंपाइलर संकलित करने में सक्षम है। तो Ocaml svn भंडार में *.ml[i] स्रोत फ़ाइलों और boot/ocamlc बाइटकोड फ़ाइल दोनों शामिल हैं।

    • rust संकलक डाउनलोड (wget का उपयोग कर, तो आप एक कार्यशील इंटरनेट कनेक्शन की जरूरत है) ने अपने द्विआधारी के पिछले संस्करण में ही संकलित करने के लिए।

    • MELTGCC को अनुकूलित और विस्तारित करने के लिए एक लिस्प जैसी भाषा है। इसे बूटस्ट्रैप किए गए अनुवादक द्वारा सी ++ कोड में अनुवादित किया जाता है। अनुवादक के जेनरेट किए गए सी ++ कोड को वितरित किया जाता है, इसलिए svn रिपॉजिटरी में *.melt स्रोत फ़ाइलों और melt/generated/*.cc अनुवादक की "ऑब्जेक्ट" फ़ाइलें दोनों होती हैं।

    • जे। पित्रत की CAIA कृत्रिम बुद्धि प्रणाली पूरी तरह आत्मनिर्भर है। यह हजारों _[0-9]* डेटा फ़ाइलों के संग्रह के साथ हजारों [A-Z]*.c जेनरेट की गई फ़ाइलों (जेनरेट की गई dx.h शीर्षलेख फ़ाइल के साथ) के संग्रह के रूप में उपलब्ध है।

    • कई योजना संकलक भी बूटस्ट्रैप किए गए हैं। योजना 48, चिकन योजना, ...