वन-पास कंपाइलर: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 1: Line 1:
[[कंप्यूटर प्रोग्रामिंग]] में, वन-पास [[ संकलक |संकलक]] एक कंपाइलर होता है जो प्रत्येक [[संकलन इकाई]] के हिस्सों से केवल एक बार गुजरता है, तुरंत प्रत्येक भाग को उसके अंतिम मशीन कोड में अनुवादित करता है। यह एक [[मल्टी-पास कंपाइलर]] के विपरीत है जो प्रोग्राम को स्रोत कोड और मशीन कोड के बीच चरणों में एक या अधिक [[मध्यवर्ती भाषा]]ओं में परिवर्तित करता है, और जो प्रत्येक अनुक्रमिक पास में संपूर्ण संकलन इकाई को पुन: संसाधित करता है।
[[कंप्यूटर प्रोग्रामिंग]] में, वन-पास [[ संकलक |कंपाइलर]] एक कंपाइलर होता है जो प्रत्येक [[संकलन इकाई|कंपाइलेशन यूनिट]] के भागो से मात्र एक बार पास है, तुरंत प्रत्येक भाग को उसके फाइनल मशीन कोड में ट्रांसलेट करता है। यह एक [[मल्टी-पास कंपाइलर]] के विपरीत होता है जो प्रोग्राम को सौर्स कोड और मशीन कोड के मध्य चरणों में एक या अधिक [[मध्यवर्ती भाषा|इंटरमीडिएट रिप्रजेंटेशन]] में परिवर्तित करता है, और जो प्रत्येक अनुक्रमिक पास में एनटायर कंपाइलेशन यूनिट को पुन: प्रोसेस करता है।


यह कंपाइलर की तार्किक कार्यप्रणाली को संदर्भित करता है, न कि केवल एक बार स्रोत फ़ाइल की वास्तविक रीडिंग को। उदाहरण के लिए, स्रोत फ़ाइल को एक बार अस्थायी भंडारण में पढ़ा जा सकता है लेकिन उस प्रतिलिपि को कई बार स्कैन किया जा सकता है। [[आईबीएम 1130]] [[फोरट्रान]] कंपाइलर ने स्रोत को मेमोरी में संग्रहीत किया और कई पासों का उपयोग किया; इसके विपरीत, डिस्क भंडारण इकाई की कमी वाले सिस्टम पर असेंबलर के लिए आवश्यक है कि कार्ड के स्रोत डेक को कार्ड रीडर/पंच के सामने दो बार प्रस्तुत किया जाए।
यह कंपाइलर की लॉजिकल फंक्शन को रेफेर करता है, न कि मात्र एक बार सौर्स फ़ाइल की एक्चुअल रीडिंग को। उदाहरण के लिए, सौर्स फ़ाइल को एक बार टेम्पररी स्टोरेज में रीड किया जा सकता है परन्तु उस प्रतिलिपि को कई बार स्कैन किया जा सकता है। [[आईबीएम 1130]] [[फोरट्रान]] कंपाइलर ने सौर्स को मेमोरी में स्टोर किया और कई पासों का उपयोग किया; इसके विपरीत, डिस्क स्टोरेज यूनिट की लैक वाले सिस्टम पर असेंबलर के लिए आवश्यक है कि कार्ड के सौर्स डेक को कार्ड रीडर/पंच के सामने दो बार प्रेजेंट किया जाए।


==गुण==
==गुण==
एक-पास कंपाइलर मल्टी-पास कंपाइलर की तुलना में छोटे और तेज़ होते हैं।<ref>{{Cite web |date=2019-03-13 |title=सिंगल पास, टू पास और मल्टी पास कंपाइलर|url=https://www.geeksforgeeks.org/single-pass-two-pass-and-multi-pass-compilers/ |access-date=2023-05-15 |website=GeeksforGeeks |language=en-us}}</ref>
वन-पास कंपाइलर मल्टी-पास कंपाइलर की तुलना में स्माल और फ़ास्ट होते हैं।<ref>{{Cite web |date=2019-03-13 |title=सिंगल पास, टू पास और मल्टी पास कंपाइलर|url=https://www.geeksforgeeks.org/single-pass-two-pass-and-multi-pass-compilers/ |access-date=2023-05-15 |website=GeeksforGeeks |language=en-us}}</ref>
उपलब्ध जानकारी के सीमित दायरे के कारण वन-पास कंपाइलर मल्टी-पास कंपाइलर के समान कुशल प्रोग्राम उत्पन्न करने में असमर्थ हैं। कई प्रभावी कंपाइलर अनुकूलन के लिए मूल ब्लॉक, लूप (विशेष रूप से नेस्टेड लूप), सबरूटीन, या संपूर्ण मॉड्यूल पर एकाधिक पास की आवश्यकता होती है। कुछ को संपूर्ण कार्यक्रम के लिए पास की आवश्यकता होती है। कुछ [[प्रोग्रामिंग भाषा]]ओं को उनके डिज़ाइन के परिणामस्वरूप, एक बार में संकलित नहीं किया जा सकता है। उदाहरण के लिए पीएल/आई डेटा घोषणाओं को प्रोग्राम के भीतर कहीं भी रखने की अनुमति देता है, विशेष रूप से, अभी तक घोषित नहीं किए गए आइटम के कुछ संदर्भों के बाद, इसलिए जब तक पूरा प्रोग्राम स्कैन नहीं हो जाता तब तक कोई कोड उत्पन्न नहीं किया जा सकता है। भाषा की परिभाषा में प्री-प्रोसेसर स्टेटमेंट भी शामिल हैं जो संकलित करने के लिए स्रोत कोड उत्पन्न करते हैं: एकाधिक पास निश्चित हैं। इसके विपरीत, कई प्रोग्रामिंग भाषाओं को विशेष रूप से एक-पास कंपाइलरों के साथ संकलित करने के लिए डिज़ाइन किया गया है, और इसमें एक-पास संकलन की अनुमति देने के लिए विशेष प्रोग्रामिंग संरचनाएं शामिल हैं।
 
उपलब्ध जानकारी के लिमिटेड स्कोप के कारण वन-पास कंपाइलर मल्टी-पास कंपाइलर के समान एफ्फिसिएंट प्रोग्राम उत्पन्न करने में असमर्थ होते हैं। कई इफेक्टिव कंपाइलर ऑप्टिमाइजेशन के लिए बेसिक ब्लॉक, लूप (स्पेशल रूप से नेस्टेड लूप), सबरूटीन, या एनटायर मॉड्यूल पर मल्टीपल पास की आवश्यकता होती है। कुछ को एनटायर फंक्शन के लिए पास की आवश्यकता होती है। कुछ [[प्रोग्रामिंग भाषा|प्रोग्रामिंग रिप्रजेंटेशन]] को उनके डिज़ाइन के परिणामस्वरूप, एक बार में कंपाइल नहीं किया जा सकता है। उदाहरण के लिए पीएल/आई डेटा डिक्लेरेशन को प्रोग्राम के भीतर कहीं भी रखने की अनुमति देता है, स्पेशल रूप से, अभी तक डिक्लेअर नहीं किए गए आइटम के कुछ रिफरेन्स के पश्चात्, इसलिए जब तक पूरा प्रोग्राम स्कैन नहीं हो जाता तब तक कोई कोड उत्पन्न नहीं किया जा सकता है। डेफिनिशन की लैंग्मेंवेज  प्री-प्रोसेसर स्टेटमेंट भी सम्मिलित होता हैं जो कंपाइल करने के लिए सौर्स कोड उत्पन्न करता हैं: मल्टीपल पास निश्चित होते हैं। इसके विपरीत, कई प्रोग्रामिंग रिप्रजेंटेशनओं को स्पेशल रूप से वन-पास कंपाइलरों के साथ कंपाइल करने के लिए डिज़ाइन किया गया है, और इसमें वन-पास कंपाइलेशन की अनुमति देने के लिए स्पेशल प्रोग्रामिंग कंस्ट्रक्ट सम्मिलित होता हैं।


==कठिनाइयाँ==
==कठिनाइयाँ==
मूल समस्या आगे के सन्दर्भों की है। स्रोत फ़ाइल में किसी बिंदु पर किसी प्रतीक की सही व्याख्या स्रोत फ़ाइल में आगे अन्य प्रतीकों की उपस्थिति या अनुपस्थिति पर निर्भर हो सकती है और जब तक उनका सामना नहीं किया जाता है, तब तक वर्तमान प्रतीक के लिए सही कोड उत्पन्न नहीं किया जा सकता है। यह संदर्भ निर्भरता की समस्या है, और विस्तार आसन्न प्रतीकों से लेकर मनमाने ढंग से बड़ी मात्रा में स्रोत पाठ तक कहीं भी हो सकता है।
बेसिक समस्या फॉरवर्ड रेफेरेन्स की होती है। सौर्स फ़ाइल में किसी पॉइंट पर किसी सिंबल की करेक्ट  इंटरप्रिटेशन सौर्स फ़ाइल में आगे अन्य सिंबलों की उपस्थिति या अनुपस्थिति पर निर्भर हो सकती है और जब तक उनका एनकाउंटर नहीं किया जाता है, तब तक वर्तमान सिंबल के लिए सही कोड प्रोडूस नहीं किया जा सकता है। यह रेफेरेन्स डिपेंडेंस की समस्या है, और स्पैन एडजासेंट सिंबलों से लेकर आर्बिट्रेरी बड़ी अमाउंट में सौर्स टेक्स्ट तक कहीं भी हो सकता है।


===स्थानीय संदर्भ===
===लोकल रेफेरेन्स===
मान लीजिए कि प्रतीक < को तुलना से कम के रूप में पहचाना जाता है, उदाहरण के लिए इससे अधिक के विपरीत। कैरेक्टर कोडिंग सीमाओं के कारण, ग्लिफ़ ≤ मानक एन्कोडिंग में उपलब्ध नहीं हो सकता है, इसलिए एक मिश्रित प्रतिनिधित्व की अनुमति दी जानी चाहिए, <=। भले ही यह संदर्भ अगले प्रतीक द्वारा निर्धारित किया जाता है, यह अज्ञात है जब < का सामना होता है। इसी तरह, प्रतीक = का मतलब हमेशा = नहीं होता है, क्योंकि जब यह किसी मिश्रित प्रतीक का हिस्सा होता है। अन्य मिश्रित प्रतीकों में .lt शामिल हो सकता है। उस स्थिति के लिए जब विशेष वर्ण < अनुपलब्ध हो। फिर भी एक और संभावना जहां ग्लिफ़ ¬ (नहीं) के लिए एक वर्ण कोड अनुपलब्ध है, <> ¬= के लिए है या बराबर नहीं है - कुछ सिस्टम ~ या ! का उपयोग करते हैं। ¬ के लिए अभी भी और भिन्नता है। एक तरीका यह है कि < के बाद स्कैन को आगे बढ़ाया जाए और = का सामना करने पर, पीछे चला जाए। निःसंदेह इसका मतलब यह है कि पाठ के उस हिस्से पर दो बार गुजरना होगा, जिससे बचना होगा। उस मामले के लिए, स्रोत फ़ाइल किसी ऐसे उपकरण से आ सकती है जो कार्ड रीडर जैसे गो-बैक-एंड-रीरीड ऑपरेशन का समर्थन नहीं करता है। प्रारंभिक निर्णय लेने के बजाय, जिसे बाद में पूर्ववत करना पड़ सकता है, लेक्सिकल विश्लेषक क्वांटम सुपरपोजिशन की धारणा की तरह कई व्याख्याओं को बनाए रख सकता है, जो बाद में निर्धारण प्रतीक को देखने पर ही एक विशिष्ट विकल्प में बदल जाता है। विशेष रूप से, COBOL कंपाइलर दशमलव स्थिरांक में दिखाई देने वाले पूर्ण विराम और कथनों के अंत में दिखाई देने वाले पूर्ण विराम के बीच अंतर करने के लिए एक पास समर्पित करते हैं। ऐसी योजना एकल-पास कंपाइलर के लिए उपलब्ध नहीं है।
मान लीजिए कि सिंबल < को तुलना से कम के रूप में पहचाना जाता है, उदाहरण के लिए इससे अधिक के विपरीत। कैरेक्टर कोडिंग सीमाओं के कारण, ग्लिफ़ ≤ मानक एन्कोडिंग में उपलब्ध नहीं हो सकता है, इसलिए एक मिश्रित प्रतिनिधित्व की अनुमति दी जानी चाहिए, <=। भले ही यह रेफेरेन्स अगले सिंबल द्वारा निर्धारित किया जाता है, यह अज्ञात है जब < का एनकाउंटर होता है। इसी तरह, सिंबल = का मतलब हमेशा = नहीं होता है, क्योंकि जब यह किसी मिश्रित सिंबल का हिस्सा होता है। अन्य मिश्रित सिंबलों में .lt सम्मिलित हो सकता है। उस स्थिति के लिए जब स्पेशल वर्ण < अनुपलब्ध हो। फिर भी एक और संभावना जहां ग्लिफ़ ¬ (नहीं) के लिए एक वर्ण कोड अनुपलब्ध है, <> ¬= के लिए है या बराबर नहीं है - कुछ सिस्टम ~ या ! का उपयोग करते हैं। ¬ के लिए अभी भी और भिन्नता है। एक तरीका यह है कि < के पश्चात् स्कैन को आगे बढ़ाया जाए और = का एनकाउंटर करने पर, पीछे चला जाए। निःसंदेह इसका मतलब यह है कि टेक्स्ट के उस हिस्से पर दो बार गुजरना होगा, जिससे बचना होगा। उस मामले के लिए, सौर्स फ़ाइल किसी ऐसे उपकरण से आ सकती है जो कार्ड रीडर जैसे गो-बैक-एंड-रीरीड ऑपरेशन का समर्थन नहीं करता है। प्रारंभिक निर्णय लेने के बजाय, जिसे पश्चात् में पूर्ववत करना पड़ सकता है, लेक्सिकल विश्लेषक क्वांटम सुपरपोजिशन की धारणा की तरह कई इंटरप्रिटेशनओं को बनाए रख सकता है, जो पश्चात् में निर्धारण सिंबल को देखने पर ही एक विशिष्ट विकल्प में बदल जाता है। स्पेशल रूप से, COBOL कंपाइलर दशमलव स्थिरांक में दिखाई देने वाले पूर्ण विराम और कथनों के अंत में दिखाई देने वाले पूर्ण विराम के मध्य अंतर करने के लिए एक पास समर्पित करते हैं। ऐसी योजना एकल-पास कंपाइलर के लिए उपलब्ध नहीं है।


इसी प्रकार वस्तुओं के नाम के साथ भी। कुछ भाषाएँ स्वयं को एकल-वर्ण नामों तक ही सीमित रखती हैं, इसलिए एकल-वर्ण नाम के रूप में वर्ण x, पाठ जैसे नाम के भीतर वर्ण x से काफी भिन्न होता है - अब संदर्भ तत्काल आसन्न वर्णों से आगे बढ़ जाता है। अनुक्रमिक स्रोत धारा की वस्तुओं को भाषा के टोकन में अलग करना शाब्दिक विश्लेषक का कार्य है। सिर्फ शब्द ही नहीं, क्योंकि < और <= टोकन भी हैं। नाम आम तौर पर एक अक्षर से शुरू होते हैं और अक्षरों और अंकों के साथ जारी रहते हैं, और शायद कुछ अतिरिक्त प्रतीक जैसे _। संख्याओं को निर्दिष्ट करने के लिए अनुमत वाक्यविन्यास आश्चर्यजनक रूप से जटिल है, उदाहरण के लिए +3.14159E+0 मान्य हो सकता है। टोकन के बीच अंतरिक्ष वर्णों की एक मनमानी संख्या की अनुमति देना सामान्य है, और फोरट्रान स्पष्ट टोकन के भीतर रिक्त स्थान की अनुमति देने (और अनदेखा करने) में भी असामान्य है ताकि GO TO और GOTO समान हों जैसे कि <= और < =। हालाँकि, कुछ प्रणालियों को कुछ टोकन को सीमित करने के लिए रिक्त स्थान की आवश्यकता हो सकती है, और अन्य, जैसे कि पायथन, प्रोग्राम ब्लॉक के दायरे को इंगित करने के लिए अग्रणी रिक्त स्थान का उपयोग करते हैं जो अन्यथा प्रारंभ ... अंत या समान मार्करों द्वारा इंगित किया जा सकता है।
इसी प्रकार वस्तुओं के नाम के साथ भी। कुछ रिप्रजेंटेशनएँ स्वयं को एकल-वर्ण नामों तक ही सीमित रखती हैं, इसलिए एकल-वर्ण नाम के रूप में वर्ण x, टेक्स्ट जैसे नाम के भीतर वर्ण x से काफी भिन्न होता है - अब रेफेरेन्स तत्काल एडजासेंट वर्णों से आगे बढ़ जाता है। अनुक्रमिक सौर्स धारा की वस्तुओं को रिप्रजेंटेशन के टोकन में अलग करना शाब्दिक विश्लेषक का कार्य है। सिर्फ शब्द ही नहीं, क्योंकि < और <= टोकन भी हैं। नाम सामान्यतः एक अक्षर से प्रारम्भ होते हैं और अक्षरों और अंकों के साथ जारी रहते हैं, और शायद कुछ अतिरिक्त सिंबल जैसे _। संख्याओं को निर्दिष्ट करने के लिए अनुमत सिंटेक्स आश्चर्यजनक रूप से जटिल है, उदाहरण के लिए +3.14159E+0 मान्य हो सकता है। टोकन के मध्य अंतरिक्ष वर्णों की एक मनमानी संख्या की अनुमति देना सामान्य है, और फोरट्रान स्पष्ट टोकन के भीतर रिक्त स्थान की अनुमति देने (और अनदेखा करने) में भी असामान्य है ताकि GO TO और GOTO समान हों जैसे कि <= और < =। हालाँकि, कुछ प्रणालियों को कुछ टोकन को सीमित करने के लिए रिक्त स्थान की आवश्यकता हो सकती है, और अन्य, जैसे कि पायथन, प्रोग्राम ब्लॉक के दायरे को इंगित करने के लिए अग्रणी रिक्त स्थान का उपयोग करते हैं जो अन्यथा प्रारंभ ... अंत या समान मार्करों द्वारा इंगित किया जा सकता है।


===अभिव्यक्ति के भीतर संदर्भ===
===एक्सप्रेशंस के भीतर रेफेरेन्स===
जो भाषाएँ अंकगणितीय अभिव्यक्तियों की अनुमति देती हैं वे आम तौर पर प्राथमिकता नियमों के साथ इन्फ़िक्स नोटेशन के वाक्यविन्यास का पालन करती हैं। इसका मतलब यह है कि किसी अभिव्यक्ति के मूल्यांकन के लिए कोड का निर्माण सुचारू रूप से नहीं होता है क्योंकि अभिव्यक्ति के टोकन स्रोत पाठ से प्राप्त होते हैं। उदाहरण के लिए, अभिव्यक्ति x + y*(u - v) लोड x के समतुल्य की ओर नहीं ले जाती है, y जोड़ें, क्योंकि x को y में नहीं जोड़ा गया है। यदि अंकगणित के लिए स्टैक स्कीम का उपयोग किया जाता है, तो कोड लोड एक्स से शुरू हो सकता है, लेकिन निम्नलिखित + टोकन से संबंधित कोड का पालन नहीं होता है। इसके बजाय, (u - v) के लिए कोड तैयार किया जाता है, उसके बाद y से गुणा किया जाता है और उसके बाद ही x जोड़ा जाता है। अंकगणितीय अभिव्यक्तियों का पार्सर अपने विश्लेषण के दौरान स्रोत के साथ आगे और पीछे नहीं चलता है, यह प्राथमिकता नियमों द्वारा संचालित स्थगित संचालन के स्थानीय स्टैक को नियोजित करता है। अंकगणितीय अभिव्यक्तियों को [[रिवर्स पोलिश नोटेशन]] या इसी तरह प्रस्तुत करने की आवश्यकता से इस नृत्य से बचा जा सकता है; उपरोक्त उदाहरण के लिए u v - y * x + जैसा कुछ और जिसे सख्ती से बाएं से दाएं स्कैन किया जाएगा।
जो रिप्रजेंटेशन अर्थमेटिक एक्सप्रेशंस की अनुमति देती हैं वे सामान्यतः प्रेसड़ेंस नियमों के साथ इन्फ़िक्स नोटेशन के सिंटेक्स को फॉलो करती हैं। इसका अर्थ यह है कि किसी एक्सप्रेशन के बेसिक्यांकन के लिए कोड का निर्माण सुचारू रूप से नहीं होता है क्योंकि एक्सप्रेशन के टोकन सौर्स टेक्स्ट से प्राप्त होते हैं। उदाहरण के लिए, एक्सप्रेशन x + y*(u - v) लोड x के एक्यूइवलेंट की ओर नहीं ले जाती है, क्योंकि x को y में नहीं ऐड किया जाता है। यदि अंकगणित के लिए स्टैक स्कीम का उपयोग किया जाता है, तो कोड लोड एक्स से प्रारम्भ हो सकता है, परन्तु निम्नलिखित + टोकन से संबंधित कोड का फॉलो नहीं होता है। इसके अतिरिक्त, (u - v) के लिए कोड जनरेट किया जाता है, उसके पश्चात् y से गुणा किया जाता है और उसके पश्चात् ही x ऐड जाता है। अर्थमेटिक एक्सप्रेशंस का पार्सर अपने एनालिसिस के समय सौर्स के साथ आगे और पीछे नहीं चलता है, यह प्रेसड़ेंस नियमों द्वारा ड्रिवेन डिफर्ड ऑपरेशन के लोकल स्टैक को नियोजित करता है। अर्थमेटिक एक्सप्रेशंस को [[रिवर्स पोलिश नोटेशन]] या इसी तरह प्रेजेंट करने की आवश्यकता से इस डांस से बचा जा सकता है; उपरोक्त उदाहरण के लिए u v - y * x + जैसा कुछ और जिसे स्ट्रिक्टली से लेफ्ट से राईट स्कैन किया जाएगा।


एक अनुकूलन संकलक पुनरावृत्ति को पहचानने और हटाने या अन्य संभावित सुधार करने के लिए अंकगणितीय अभिव्यक्ति के रूप का विश्लेषण कर सकता है। विचार करना
एक ऑप्टिमाइजेशन कंपाइलर रेपिटेशन को पहचानने और हटाने या अन्य पोटेंशियल सुधार करने के लिए अर्थमेटिक एक्सप्रेशन के रूप का एनालिसिस कर सकता है। विचार करना
  a*sin(x) + b*sin(x)
  a*sin(x) + b*sin(x)
कुछ भाषाएँ, जैसे अल्गोल, अंकगणितीय अभिव्यक्ति के भीतर असाइनमेंट की अनुमति देती हैं, इसलिए प्रोग्रामर कुछ इस तरह लिख सकता था
कुछ रिप्रजेंटेशन, जैसे अल्गोल, अर्थमेटिक एक्सप्रेशन के भीतर असाइनमेंट की अनुमति देती हैं, इसलिए प्रोग्रामर कुछ इस तरह लिख सकता था
  a*(t:=sin(x)) + b*t
  a*(t:=sin(x)) + b*t
लेकिन ऐसा करने के लिए आवश्यक परिश्रम के अलावा, परिणामी कथन का रूप गड़बड़ है और अब इसे कोडित किए जा रहे गणितीय अभिव्यक्ति से आसानी से तुलना नहीं की जा सकेगी। गलतियाँ आसानी से हो जायेंगी. इसके बजाय, कंपाइलर संपूर्ण अभिव्यक्ति के रूप का प्रतिनिधित्व कर सकता है (आमतौर पर एक पेड़ संरचना का उपयोग करके), उस संरचना का विश्लेषण और संशोधन कर सकता है, और फिर बेहतर फॉर्म के लिए कोड उत्सर्जित कर सकता है। क्रमिक असाइनमेंट स्टेटमेंट के ब्लॉक में एक स्पष्ट विस्तार होगा। इसमें स्रोत पाठ के माध्यम से दोबारा गुजरना शामिल नहीं है।
परन्तु ऐसा करने के लिए आवश्यक परिश्रम के अलावा, परिणामी कथन का रूप गड़बड़ है और अब इसे कोडित किए जा रहे गणितीय एक्सप्रेशन से आसानी से तुलना नहीं की जा सकेगी। गलतियाँ आसानी से हो जायेंगी. इसके बजाय, कंपाइलर एनटायर एक्सप्रेशन के रूप का प्रतिनिधित्व कर सकता है (आमतौर पर एक पेड़ संरचना का उपयोग करके), उस संरचना का एनालिसिस और संशोधन कर सकता है, और फिर बेहतर फॉर्म के लिए कोड उत्सर्जित कर सकता है। क्रमिक असाइनमेंट स्टेटमेंट के ब्लॉक में एक स्पष्ट स्पैन होगा। इसमें सौर्स टेक्स्ट के माध्यम से दोबारा गुजरना सम्मिलित नहीं है।


===मध्यम श्रेणी संदर्भ===
===मध्यम श्रेणी रेफेरेन्स===
यद्यपि शाब्दिक विश्लेषक ने इनपुट स्ट्रीम को टोकन की एक स्ट्रीम में विभाजित कर दिया है (और किसी भी टिप्पणी को खारिज कर दिया है), भाषा के वाक्यविन्यास के अनुसार इन टोकन की व्याख्या अभी भी संदर्भ पर निर्भर हो सकती है। फोरट्रान छद्म कोड में निम्नलिखित कथनों पर विचार करें:
यद्यपि शाब्दिक विश्लेषक ने इनपुट स्ट्रीम को टोकन की एक स्ट्रीम में विभाजित कर दिया है (और किसी भी टिप्पणी को खारिज कर दिया है), रिप्रजेंटेशन के सिंटेक्स के अनुसार इन टोकन की इंटरप्रिटेशन अभी भी रेफेरेन्स पर निर्भर हो सकती है। फोरट्रान छद्म कोड में निम्नलिखित कथनों पर विचार करें:
  यदि (अभिव्यक्ति) = आदि।
  यदि (एक्सप्रेशन) = आदि।
  यदि (अभिव्यक्ति) लेबल1,लेबल2,लेबल3
  यदि (एक्सप्रेशन) लेबल1,लेबल2,लेबल3
  यदि (अभिव्यक्ति) तो
  यदि (एक्सप्रेशन) तो
पहला, if नामक एक-आयामी सरणी के एक तत्व के लिए कुछ अंकगणितीय अभिव्यक्ति (आदि) के मान का असाइनमेंट है। फोरट्रान इस मायने में असामान्य है कि इसमें कोई आरक्षित शब्द नहीं हैं, इसलिए एक सांकेतिक लेखन का मतलब यह नहीं है कि कोई लेखन-कथन प्रगति पर है। अन्य कथन वास्तव में यदि-कथन हैं - दूसरा एक अंकगणित है-यदि जो अभिव्यक्ति के परिणाम के संकेत की जांच करता है और इसके नकारात्मक, शून्य, या सकारात्मक होने के आधार पर 1, 2, या 3 लेबल पर कूदता है; तीसरा एक तार्किक-यदि है, और इसके लिए आवश्यक है कि इसकी अभिव्यक्ति का परिणाम बूलियन हो - इस प्रकार, लेक्सिकल विश्लेषक से निकलने वाले टोकन की सही व्याख्या तब तक नहीं की जा सकती जब तक कि अभिव्यक्ति को स्कैन नहीं किया जाता है और समापन ब्रैकेट के बाद वहां दिखाई नहीं देता है या तो एक बराबर चिह्न, एक अंक (लेबल 1 का पाठ होने के नाते: फोरट्रान लेबल के रूप में केवल पूर्णांक का उपयोग करता है, हालांकि यदि अक्षरों को अनुमति दी जाती है तो स्कैन को अल्पविराम खोजने पर निर्भर रहना होगा) या एक अक्षर से शुरू होने वाली कोई चीज़ (वह तब होनी चाहिए), और तो अब, संदर्भ स्रोत पाठ की एक मनमानी मात्रा तक फैला हुआ है क्योंकि अभिव्यक्ति मनमानी है। हालाँकि, तीनों मामलों में कंपाइलर स्कैन के आगे बढ़ने पर अभिव्यक्ति के मूल्यांकन के लिए कोड उत्पन्न कर सकता है। इस प्रकार, शाब्दिक विश्लेषण हमेशा स्वीकार्य वाक्यविन्यास की अनियमितताओं के कारण पहचाने गए टोकन के अर्थ को निर्धारित नहीं कर सकता है, और इसलिए यदि बैकट्रैकिंग से बचना है तो वाक्यविन्यास विश्लेषण को संभावित राज्यों का एक सुपरपोजिशन बनाए रखना होगा।
पहला, if नामक एक-आयामी सरणी के एक तत्व के लिए कुछ अर्थमेटिक एक्सप्रेशन (आदि) के मान का असाइनमेंट है। फोरट्रान इस मायने में असामान्य है कि इसमें कोई आरक्षित शब्द नहीं हैं, इसलिए एक सांकेतिक लेखन का मतलब यह नहीं है कि कोई लेखन-कथन प्रगति पर है। अन्य कथन वास्तव में यदि-कथन हैं - दूसरा एक अंकगणित है-यदि जो एक्सप्रेशन के परिणाम के संकेत की जांच करता है और इसके नकारात्मक, शून्य, या सकारात्मक होने के आधार पर 1, 2, या 3 लेबल पर कूदता है; तीसरा एक लॉजिकल-यदि है, और इसके लिए आवश्यक है कि इसकी एक्सप्रेशन का परिणाम बूलियन हो - इस प्रकार, लेक्सिकल विश्लेषक से निकलने वाले टोकन की सही इंटरप्रिटेशन तब तक नहीं की जा सकती जब तक कि एक्सप्रेशन को स्कैन नहीं किया जाता है और समापन ब्रैकेट के पश्चात् वहां दिखाई नहीं देता है या तो एक बराबर चिह्न, एक अंक (लेबल 1 का टेक्स्ट होने के नाते: फोरट्रान लेबल के रूप में मात्र पूर्णांक का उपयोग करता है, हालांकि यदि अक्षरों को अनुमति दी जाती है तो स्कैन को अल्पविराम खोजने पर निर्भर रहना होगा) या एक अक्षर से प्रारम्भ होने वाली कोई चीज़ (वह तब होनी चाहिए), और तो अब, रेफेरेन्स सौर्स टेक्स्ट की एक मनमानी मात्रा तक फैला हुआ है क्योंकि एक्सप्रेशन मनमानी है। हालाँकि, तीनों मामलों में कंपाइलर स्कैन के आगे बढ़ने पर एक्सप्रेशन के बेसिक्यांकन के लिए कोड उत्पन्न कर सकता है। इस प्रकार, शाब्दिक एनालिसिस हमेशा स्वीकार्य सिंटेक्स की अनियमितताओं के कारण पहचाने गए टोकन के अर्थ को निर्धारित नहीं कर सकता है, और इसलिए यदि बैकट्रैकिंग से बचना है तो सिंटेक्स एनालिसिस को संभावित राज्यों का एक सुपरपोजिशन बनाए रखना होगा।


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


इस समस्या को आरक्षित शब्दों के उपयोग के माध्यम से कम किया जा सकता है, उदाहरण के लिए यदि, तब, और अन्य हमेशा एक इफ-स्टेटमेंट के हिस्से होते हैं और चर के नाम नहीं हो सकते हैं, लेकिन आश्चर्यजनक रूप से बड़ी संख्या में उपयोगी शब्द अनुपलब्ध हो सकते हैं। एक और तरीका है स्ट्रॉपिंग, जिसके तहत आरक्षित शब्दों को चिह्नित किया जाता है, जैसे कि उन्हें पूर्ण विराम, या एपोस्ट्रोफ जैसे विशेष वर्णों के बीच रखकर, जैसा कि अल्गोल के कुछ संस्करणों में होता है। इस का मतलब है कि <code>'if'</code> और <code>if</code> अलग-अलग टोकन हैं, बाद वाला एक सामान्य नाम है, लेकिन उन सभी एपोस्ट्रोफ की आपूर्ति जल्द ही परेशान करने वाली हो जाती है। कई भाषाओं के लिए, रिक्ति पर्याप्त जानकारी प्रदान करती है, हालांकि यह जटिल हो सकती है। अक्सर यह केवल एक स्थान (या टैब, आदि) नहीं होता है, बल्कि एक अक्षर या अंक के अलावा एक वर्ण होता है जो संभावित टोकन के पाठ को समाप्त करता है। उपरोक्त उदाहरण में, यदि-कथन की अभिव्यक्ति कोष्ठक के भीतर होनी चाहिए ताकि (निश्चित रूप से यदि की पहचान समाप्त हो जाए और इसी तरह,) तब की पहचान को सक्षम कर सके; इसके अलावा, किसी कंपाउंड के अन्य भाग if-स्टेटमेंट को नई लाइनों पर प्रदर्शित होना चाहिए: else और End if (या Endif ) और else if । इसके विपरीत, अल्गोल और अन्य के साथ कोष्ठक की आवश्यकता नहीं होती है और इफ-स्टेटमेंट के सभी भाग एक पंक्ति में हो सकते हैं। पास्कल के साथ, 'यदि' ए 'या' बी 'तब' आदि मान्य है, लेकिन यदि ए और बी अभिव्यक्ति हैं, तो उन्हें कोष्ठक में संलग्न किया जाना चाहिए।
इस समस्या को आरक्षित शब्दों के उपयोग के माध्यम से कम किया जा सकता है, उदाहरण के लिए यदि, तब, और अन्य हमेशा एक इफ-स्टेटमेंट के हिस्से होते हैं और चर के नाम नहीं हो सकते हैं, परन्तु आश्चर्यजनक रूप से बड़ी संख्या में उपयोगी शब्द अनुपलब्ध हो सकते हैं। एक और तरीका है स्ट्रॉपिंग, जिसके तहत आरक्षित शब्दों को चिह्नित किया जाता है, जैसे कि उन्हें पूर्ण विराम, या एपोस्ट्रोफ जैसे स्पेशल वर्णों के मध्य रखकर, जैसा कि अल्गोल के कुछ संस्करणों में होता है। इस का मतलब है कि <code>'if'</code> और <code>if</code> अलग-अलग टोकन हैं, पश्चात् वाला एक सामान्य नाम है, परन्तु उन सभी एपोस्ट्रोफ की आपूर्ति जल्द ही परेशान करने वाली हो जाती है। कई रिप्रजेंटेशनओं के लिए, रिक्ति पर्याप्त जानकारी प्रदान करती है, हालांकि यह जटिल हो सकती है। अक्सर यह मात्र एक स्थान (या टैब, आदि) नहीं होता है, बल्कि एक अक्षर या अंक के अलावा एक वर्ण होता है जो संभावित टोकन के टेक्स्ट को समाप्त करता है। उपरोक्त उदाहरण में, यदि-कथन की एक्सप्रेशन कोष्ठक के भीतर होनी चाहिए ताकि (निश्चित रूप से यदि की पहचान समाप्त हो जाए और इसी तरह,) तब की पहचान को सक्षम कर सके; इसके अलावा, किसी कंपाउंड के अन्य भाग if-स्टेटमेंट को नई लाइनों पर प्रदर्शित होना चाहिए: else और End if (या Endif ) और else if । इसके विपरीत, अल्गोल और अन्य के साथ कोष्ठक की आवश्यकता नहीं होती है और इफ-स्टेटमेंट के सभी भाग एक पंक्ति में हो सकते हैं। पास्कल के साथ, 'यदि' ए 'या' बी 'तब' आदि मान्य है, परन्तु यदि ए और बी एक्सप्रेशन हैं, तो उन्हें कोष्ठक में संलग्न किया जाना चाहिए।


संकलक द्वारा निर्मित स्रोत फ़ाइल सूची को उसके द्वारा पहचाने जाने वाले आरक्षित शब्दों को <u>रेखांकित</u> या 'बोल्ड' या इटैलिक में प्रस्तुत करके पढ़ना आसान बनाया जा सकता है, लेकिन आलोचना हुई है: अल्गोल एकमात्र ऐसी भाषा है जो इटैलिक और सामान्य पूर्ण विराम के बीच अंतर करती है। दरअसल ये कोई मज़ाक की बात नहीं है. फोरट्रान में, एक डू-स्टेटमेंट की शुरुआत जैसे होती है <code>DO 12 I = 1,15</code> से अलग है <code>DO 12 I = 1.15</code> (एक वैरिएबल के लिए मान 1.15 का एक असाइनमेंट कहा जाता है <code>DO12I</code>; याद रखें कि रिक्त स्थान अप्रासंगिक हैं) केवल अल्पविराम और पूर्ण विराम के बीच के अंतर से, और एक मुद्रित सूची के ग्लिफ़ अच्छी तरह से नहीं बने हो सकते हैं।
कंपाइलर द्वारा निर्मित सौर्स फ़ाइल सूची को उसके द्वारा पहचाने जाने वाले आरक्षित शब्दों को <u>रेखांकित</u> या 'बोल्ड' या इटैलिक में प्रेजेंट करके पढ़ना आसान बनाया जा सकता है, परन्तु आलोचना हुई है: अल्गोल एकमात्र ऐसी रिप्रजेंटेशन है जो इटैलिक और सामान्य पूर्ण विराम के मध्य अंतर करती है। दरअसल ये कोई मज़ाक की बात नहीं है. फोरट्रान में, एक डू-स्टेटमेंट की शुरुआत जैसे होती है <code>DO 12 I = 1,15</code> से अलग है <code>DO 12 I = 1.15</code> (एक वैरिएबल के लिए मान 1.15 का एक असाइनमेंट कहा जाता है <code>DO12I</code>; याद रखें कि रिक्त स्थान अप्रासंगिक हैं) मात्र अल्पविराम और पूर्ण विराम के मध्य के अंतर से, और एक मुद्रित सूची के ग्लिफ़ अच्छी तरह से नहीं बने हो सकते हैं।


किसी भाषा के डिज़ाइन पर सावधानीपूर्वक ध्यान देने से एक विश्वसनीय संकलक बनाने की दृष्टि से अभिव्यक्ति की स्पष्टता और सरलता को बढ़ावा मिल सकता है जिसका व्यवहार आसानी से समझ में आता है। फिर भी ख़राब विकल्प आम हैं। उदाहरण के लिए, मैटलैब ए' के ​​रूप में एपोस्ट्रोफ का उपयोग करके मैट्रिक्स ट्रांसपोज़िशन को दर्शाता है जो कि अपवाद नहीं है और गणितीय उपयोग का बारीकी से पालन करता है। ठीक है और अच्छा है, लेकिन टेक्स्ट स्ट्रिंग के सीमांकक के लिए मैटलैब किसी भी उद्देश्य के लिए दोहरे उद्धरण चिह्न द्वारा प्रस्तुत अवसर को अनदेखा करता है और इसके लिए एपोस्ट्रोफ का भी उपयोग करता है। हालाँकि ऑक्टेव टेक्स्ट स्ट्रिंग्स के लिए दोहरे उद्धरण चिह्नों का उपयोग करता है, यह मैटलैब कथनों को भी स्वीकार करने का प्रयास करता है और इसलिए समस्या दूसरे सिस्टम तक फैल जाती है।
किसी रिप्रजेंटेशन के डिज़ाइन पर सावधानीपूर्वक ध्यान देने से एक विश्वसनीय कंपाइलर बनाने की दृष्टि से एक्सप्रेशन की स्पष्टता और सरलता को बढ़ावा मिल सकता है जिसका व्यवहार आसानी से समझ में आता है। फिर भी ख़राब विकल्प आम हैं। उदाहरण के लिए, मैटलैब ए' के ​​रूप में एपोस्ट्रोफ का उपयोग करके मैट्रिक्स ट्रांसपोज़िशन को दर्शाता है जो कि अपवाद नहीं है और गणितीय उपयोग का बारीकी से फॉलो करता है। ठीक है और अच्छा है, परन्तु टेक्स्ट स्ट्रिंग के सीमांकक के लिए मैटलैब किसी भी उद्देश्य के लिए दोहरे उद्धरण चिह्न द्वारा प्रेजेंट अवसर को अनदेखा करता है और इसके लिए एपोस्ट्रोफ का भी उपयोग करता है। हालाँकि ऑक्टेव टेक्स्ट स्ट्रिंग्स के लिए दोहरे उद्धरण चिह्नों का उपयोग करता है, यह मैटलैब कथनों को भी स्वीकार करने का प्रयास करता है और इसलिए समस्या दूसरे सिस्टम तक फैल जाती है।


===प्री-प्रोसेसर विस्तार===
===प्री-प्रोसेसर स्पैन===
यह इस स्तर पर है कि प्री-प्रोसेसर विकल्पों का प्रयोग किया जाता है, तथाकथित क्योंकि इन्हें कंपाइलर द्वारा आने वाले स्रोत को उचित रूप से संसाधित करने से पहले प्रयोग किया जाता है। वे असेंबलर सिस्टम के मैक्रो विस्तार विकल्पों को प्रतिध्वनित करते हैं, उम्मीद है कि अधिक दयालु वाक्यविन्यास के साथ। सबसे आम व्यवस्था पर एक भिन्नता है
यह इस स्तर पर है कि प्री-प्रोसेसर विकल्पों का प्रयोग किया जाता है, तथाकथित क्योंकि इन्हें कंपाइलर द्वारा आने वाले सौर्स को उचित रूप से प्रोसेस करने से पहले प्रयोग किया जाता है। वे असेंबलर सिस्टम के मैक्रो स्पैन विकल्पों को प्रतिध्वनित करते हैं, उम्मीद है कि अधिक दयालु सिंटेक्स के साथ। सबसे आम व्यवस्था पर एक भिन्नता है
  यदि ''स्थिति'' तो ''यह स्रोत'' अन्यथा ''अन्य स्रोत'' फाई
  यदि ''स्थिति'' तो ''यह सौर्स'' अन्यथा ''अन्य सौर्स'' फाई
अक्सर प्री-प्रोसेसर सोर्स स्टेटमेंट को सामान्य सोर्स स्टेटमेंट से अलग करने की कुछ व्यवस्था के साथ, जैसे कि pl/i, या # इत्यादि में % प्रतीक से शुरू होने वाला स्टेटमेंट। एक और सरल विकल्प एक भिन्नता है
अक्सर प्री-प्रोसेसर सोर्स स्टेटमेंट को सामान्य सोर्स स्टेटमेंट से अलग करने की कुछ व्यवस्था के साथ, जैसे कि pl/i, या # इत्यादि में % सिंबल से प्रारम्भ होने वाला स्टेटमेंट। एक और सरल विकल्प एक भिन्नता है
  ''यह'' = ''वह'' परिभाषित करें
  ''यह'' = ''वह'' परिभाषित करें
लेकिन सावधानी की जरूरत है, जैसे कि
परन्तु सावधानी की जरूरत है, जैसे कि
  SumXY = (x + y) को परिभाषित करें
  SumXY = (x + y) को परिभाषित करें
  योग:=3*SumXY;
  योग:=3*SumXY;
चूँकि कोष्ठक के बिना, परिणाम sum:=3*x + y; इसी तरह, प्रतिस्थापन पाठ की सीमा निर्धारित करने और परिणामी पाठ को कैसे स्कैन किया जाएगा, यह निर्धारित करने में सावधानी बरतने की आवश्यकता है। विचार करना
चूँकि कोष्ठक के बिना, परिणाम sum:=3*x + y; इसी तरह, प्रतिस्थापन टेक्स्ट की सीमा निर्धारित करने और परिणामी टेक्स्ट को कैसे स्कैन किया जाएगा, यह निर्धारित करने में सावधानी बरतने की आवश्यकता है। विचार करना
  #तीन परिभाषित करें = 3;
  #तीन परिभाषित करें = 3;
  #बिंदु परिभाषित करें = .;
  #पॉइंट परिभाषित करें = .;
  #एक को परिभाषित करें = 1;
  #एक को परिभाषित करें = 1;
  x:=तीन दशमलव एक;
  x:=तीन दशमलव एक;
यहां परिभाषित कथन को अर्धविराम द्वारा समाप्त किया जाता है, और अर्धविराम स्वयं प्रतिस्थापन का हिस्सा नहीं है। आह्वान नहीं हो सकता <code>x:=threepointone;</code> क्योंकि वह एक अलग नाम है, लेकिन <code>three point one</code> होगा <code>3 . 1</code> और बाद का स्कैन उसे एकल टोकन के रूप में मानने में सक्षम हो भी सकता है और नहीं भी।
यहां परिभाषित कथन को अर्धविराम द्वारा समाप्त किया जाता है, और अर्धविराम स्वयं प्रतिस्थापन का हिस्सा नहीं है। आह्वान नहीं हो सकता <code>x:=threepointone;</code> क्योंकि वह एक अलग नाम है, परन्तु <code>three point one</code> होगा <code>3 . 1</code> और पश्चात् का स्कैन उसे एकल टोकन के रूप में मानने में सक्षम हो भी सकता है और नहीं भी।


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


इसके अलावा, एक ही प्री-प्रोसेसर सिंटैक्स का उपयोग कई अलग-अलग भाषाओं, यहां तक ​​कि प्राकृतिक भाषाओं के लिए भी किया जा सकता है, जैसे किसी व्यक्ति के नाम, उपनाम, पालतू कुत्ते का नाम आदि का उपयोग करके कहानी टेम्पलेट से कहानी तैयार करना और प्रलोभन होगा एक प्री-प्रोसेसर प्रोग्राम तैयार करें जो स्रोत फ़ाइल को स्वीकार करेगा, प्री-प्रोसेसर क्रियाएं करेगा और अगले चरण, संकलन के लिए तैयार परिणाम को आउटपुट करेगा। लेकिन यह स्पष्ट रूप से स्रोत के माध्यम से कम से कम एक अतिरिक्त पास का गठन करता है और इसलिए ऐसा समाधान एकल-पास कंपाइलर के लिए अनुपलब्ध होगा। इस प्रकार, वास्तविक इनपुट स्रोत फ़ाइल के माध्यम से प्रगति फिट और स्टार्ट में अच्छी तरह से आगे बढ़ सकती है, लेकिन यह अभी भी यूनिडायरेक्शनल है।
इसके अलावा, एक ही प्री-प्रोसेसर सिंटैक्स का उपयोग कई अलग-अलग रिप्रजेंटेशनओं, यहां तक ​​कि प्राकृतिक रिप्रजेंटेशनओं के लिए भी किया जा सकता है, जैसे किसी व्यक्ति के नाम, उपनाम, पालतू कुत्ते का नाम आदि का उपयोग करके कहानी टेम्पलेट से कहानी जनरेट करना और प्रलोभन होगा एक प्री-प्रोसेसर प्रोग्राम जनरेट करें जो सौर्स फ़ाइल को स्वीकार करेगा, प्री-प्रोसेसर क्रियाएं करेगा और अगले चरण, कंपाइलेशन के लिए जनरेट परिणाम को आउटपुट करेगा। परन्तु यह स्पष्ट रूप से सौर्स के माध्यम से कम से कम एक अतिरिक्त पास का गठन करता है और इसलिए ऐसा समाधान एकल-पास कंपाइलर के लिए अनुपलब्ध होगा। इस प्रकार, वास्तविक इनपुट सौर्स फ़ाइल के माध्यम से प्रगति फिट और स्टार्ट में अच्छी तरह से आगे बढ़ सकती है, परन्तु यह अभी भी यूनिडायरेक्शनल है।


===लंबी दूरी का संदर्भ===
===लंबी दूरी का रेफेरेन्स===
कंपाइलर द्वारा कोड जेनरेशन (कंपाइलर) को फॉरवर्ड रेफरेंस की समस्या का भी सामना करना पड़ता है, सबसे सीधे तौर पर ''लेबल'' पर जाएं जैसे जहां गंतव्य लेबल स्रोत फ़ाइल में आगे एक अज्ञात दूरी है, और इस प्रकार जंप निर्देश उस लेबल के स्थान तक पहुंचने के लिए अभी तक उत्पन्न होने वाले कोड में एक अज्ञात दूरी शामिल है। कुछ भाषा डिज़ाइन, संभवतः Consulted_harmful| से प्रभावित हैं हानिकारक माने जाने वाले GOTO में GOTO कथन नहीं होता है, लेकिन इससे समस्या नहीं सुलझती क्योंकि एक कार्यक्रम में कई अंतर्निहित GOTO समकक्ष होते हैं। विचार करना
कंपाइलर द्वारा कोड जेनरेशन (कंपाइलर) को फॉरवर्ड रेफरेंस की समस्या का भी एनकाउंटर करना पड़ता है, सबसे सीधे तौर पर ''लेबल'' पर जाएं जैसे जहां गंतव्य लेबल सौर्स फ़ाइल में आगे एक अज्ञात दूरी है, और इस प्रकार जंप निर्देश उस लेबल के स्थान तक पहुंचने के लिए अभी तक उत्पन्न होने वाले कोड में एक अज्ञात दूरी सम्मिलित है। कुछ रिप्रजेंटेशन डिज़ाइन, संभवतः Consulted_harmful| से प्रभावित हैं हानिकारक माने जाने वाले GOTO में GOTO कथन नहीं होता है, परन्तु इससे समस्या नहीं सुलझती क्योंकि एक फंक्शन में कई अंतर्निहित GOTO समकक्ष होते हैं। विचार करना
  यदि ''स्थिति'' है तो ''कोड सही है'' अन्यथा ''कोड गलत है''
  यदि ''स्थिति'' है तो ''कोड सही है'' अन्यथा ''कोड गलत है''
जैसा कि पहले उल्लेख किया गया है, ''स्थिति'' का मूल्यांकन करने के लिए कोड तुरंत उत्पन्न किया जा सकता है। लेकिन जब तत्कालीन टोकन का सामना होता है, तो एक जम्पफाल्स ऑपरेशन कोड रखा जाना चाहिए जिसका गंतव्य पता ''कोड गलत'' कथनों के लिए कोड की शुरुआत है, और इसी तरह, जब अन्य टोकन का सामना होता है, तो उसके लिए अभी-अभी पूरा किया गया कोड ''कोड ट्रू'' स्टेटमेंट के बाद एक GOTO-स्टाइल जंप ऑपरेशन होना चाहिए जिसका गंतव्य वह कोड है जो if-स्टेटमेंट के अंत के बाद आता है, यहां फाई टोकन द्वारा चिह्नित किया गया है। इन गंतव्यों को केवल तब ही जाना जा सकता है जब अभी तक स्कैन न किए गए स्रोत के लिए मनमानी मात्रा में कोड उत्पन्न हो जाए। इसी तरह की समस्याएँ किसी भी कथन के लिए उत्पन्न होती हैं जिनके हिस्से स्रोत की मनमानी मात्रा तक फैले होते हैं, जैसे कि केस स्टेटमेंट।
जैसा कि पहले उल्लेख किया गया है, ''स्थिति'' का बेसिक्यांकन करने के लिए कोड तुरंत उत्पन्न किया जा सकता है। परन्तु जब तत्कालीन टोकन का एनकाउंटर होता है, तो एक जम्पफाल्स ऑपरेशन कोड रखा जाना चाहिए जिसका गंतव्य पता ''कोड गलत'' कथनों के लिए कोड की शुरुआत है, और इसी तरह, जब अन्य टोकन का एनकाउंटर होता है, तो उसके लिए अभी-अभी पूरा किया गया कोड ''कोड ट्रू'' स्टेटमेंट के पश्चात् एक GOTO-स्टाइल जंप ऑपरेशन होना चाहिए जिसका गंतव्य वह कोड है जो if-स्टेटमेंट के अंत के पश्चात् आता है, यहां फाई टोकन द्वारा चिह्नित किया गया है। इन गंतव्यों को मात्र तब ही जाना जा सकता है जब अभी तक स्कैन न किए गए सौर्स के लिए मनमानी मात्रा में कोड उत्पन्न हो जाए। इसी तरह की समस्याएँ किसी भी कथन के लिए उत्पन्न होती हैं जिनके हिस्से सौर्स की मनमानी मात्रा तक फैले होते हैं, जैसे कि केस स्टेटमेंट।


एक रिकर्सिव-डिसेंट कंपाइलर प्रत्येक प्रकार के स्टेटमेंट के लिए एक प्रक्रिया को सक्रिय करेगा, जैसे कि इफ-स्टेटमेंट, जिसके बदले में ''कोड ट्रू'' और ''कोड गलत'' के स्टेटमेंट के लिए कोड उत्पन्न करने के लिए उचित प्रक्रियाओं को लागू किया जाएगा। इसके कथन के कुछ हिस्सों और इसी प्रकार अन्य कथनों के लिए उनके वाक्य-विन्यास के अनुसार। अपने स्थानीय भंडारण में यह अपने अपूर्ण जंपफाल्स ऑपरेशन के पता फ़ील्ड के स्थान का ट्रैक रखेगा, और इसके तत्कालीन टोकन का सामना करने पर, अब ज्ञात पते को रखेगा, और इसी तरह 'के बाद आवश्यक जंप के लिए फाई टोकन का सामना करने पर 'कोड सत्य'' कोड। GoTo स्टेटमेंट इस मायने में भिन्न है कि जिस कोड पर जम्प किया जाना है वह उसके स्टेटमेंट फॉर्म के अंदर नहीं है, इसलिए फिक्सअप की एक सहायक तालिका में एक प्रविष्टि की आवश्यकता होती है जिसका उपयोग अंततः उसके लेबल के सामने आने पर किया जाएगा। इस धारणा को बढ़ाया जा सकता है. सभी अज्ञात-गंतव्य जंप एक जंप टेबल में एक प्रविष्टि के माध्यम से किए जा सकते हैं (जिनके पते बाद में गंतव्यों के सामने आने पर भर दिए जाते हैं), हालांकि इस तालिका का आवश्यक आकार संकलन के अंत तक अज्ञात है।
एक रिकर्सिव-डिसेंट कंपाइलर प्रत्येक प्रकार के स्टेटमेंट के लिए एक प्रक्रिया को सक्रिय करेगा, जैसे कि इफ-स्टेटमेंट, जिसके बदले में ''कोड ट्रू'' और ''कोड गलत'' के स्टेटमेंट के लिए कोड उत्पन्न करने के लिए उचित प्रक्रियाओं को लागू किया जाएगा। इसके कथन के कुछ हिस्सों और इसी प्रकार अन्य कथनों के लिए उनके वाक्य-विन्यास के अनुसार। अपने लोकल स्टोरेज में यह अपने अपूर्ण जंपफाल्स ऑपरेशन के पता फ़ील्ड के स्थान का ट्रैक रखेगा, और इसके तत्कालीन टोकन का एनकाउंटर करने पर, अब ज्ञात पते को रखेगा, और इसी तरह 'के पश्चात् आवश्यक जंप के लिए फाई टोकन का एनकाउंटर करने पर 'कोड सत्य'' कोड। GoTo स्टेटमेंट इस मायने में भिन्न है कि जिस कोड पर जम्प किया जाना है वह उसके स्टेटमेंट फॉर्म के अंदर नहीं है, इसलिए फिक्सअप की एक सहायक तालिका में एक प्रविष्टि की आवश्यकता होती है जिसका उपयोग अंततः उसके लेबल के सामने आने पर किया जाएगा। इस धारणा को बढ़ाया जा सकता है. सभी अज्ञात-गंतव्य जंप एक जंप टेबल में एक प्रविष्टि के माध्यम से किए जा सकते हैं (जिनके पते पश्चात् में गंतव्यों के सामने आने पर भर दिए जाते हैं), हालांकि इस तालिका का आवश्यक आकार कंपाइलेशन के अंत तक अज्ञात है।''


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


===दुर्भाग्यपूर्ण निर्णय===
===दुर्भाग्यपूर्ण निर्णय===
हालाँकि ऊपर दिए गए विवरण में इस धारणा को नियोजित किया गया है कि कोड को बाद में तय किए जाने के लिए छोड़े गए कुछ फ़ील्ड के साथ उत्पन्न किया जा सकता है, एक अंतर्निहित धारणा थी कि ऐसे कोड अनुक्रमों का आकार स्थिर था। यह मामला नहीं हो सकता है। कई कंप्यूटरों में अलग-अलग मात्रा में स्टोरेज लेने वाले संचालन के लिए प्रावधान होता है, विशेष रूप से सापेक्ष एड्रेसिंग, जिसके तहत यदि गंतव्य -128 या +127 एड्रेसिंग चरणों के भीतर है, तो आठ-बिट एड्रेस फ़ील्ड का उपयोग किया जा सकता है, अन्यथा पहुंचने के लिए बहुत बड़े एड्रेस फ़ील्ड की आवश्यकता होती है। . इस प्रकार यदि कोड एक आशाजनक संक्षिप्त पता फ़ील्ड के साथ उत्पन्न किया गया था, तो बाद में वापस जाना और लंबे फ़ील्ड का उपयोग करने के लिए कोड को समायोजित करना आवश्यक हो सकता है, जिसके परिणामस्वरूप परिवर्तन के बाद पहले कोड संदर्भित स्थानों को भी समायोजित करना होगा। इसी तरह, परिवर्तन के दौरान पीछे की ओर जाने वाले बाद के संदर्भों को भी ठीक करना होगा, यहां तक ​​कि वे भी जो ज्ञात पतों पर थे। और साथ ही, फिक्सअप जानकारी को स्वयं ही सही ढंग से ठीक करना होगा। दूसरी ओर, लंबे पते का उपयोग उन सभी मामलों के लिए किया जा सकता है जब निकटता निश्चित नहीं है, लेकिन परिणामी कोड अब आदर्श नहीं होगा।
हालाँकि ऊपर दिए गए विवरण में इस धारणा को नियोजित किया गया है कि कोड को पश्चात् में तय किए जाने के लिए छोड़े गए कुछ फ़ील्ड के साथ उत्पन्न किया जा सकता है, एक अंतर्निहित धारणा थी कि ऐसे कोड अनुक्रमों का आकार स्थिर था। यह मामला नहीं हो सकता है। कई कंप्यूटरों में अलग-अलग मात्रा में स्टोरेज लेने वाले ऑपरेशन के लिए प्रावधान होता है, स्पेशल रूप से सापेक्ष एड्रेसिंग, जिसके तहत यदि गंतव्य -128 या +127 एड्रेसिंग चरणों के भीतर है, तो आठ-बिट एड्रेस फ़ील्ड का उपयोग किया जा सकता है, अन्यथा पहुंचने के लिए बहुत बड़े एड्रेस फ़ील्ड की आवश्यकता होती है। . इस प्रकार यदि कोड एक आशाजनक संक्षिप्त पता फ़ील्ड के साथ उत्पन्न किया गया था, तो पश्चात् में वापस जाना और लंबे फ़ील्ड का उपयोग करने के लिए कोड को समायोजित करना आवश्यक हो सकता है, जिसके परिणामस्वरूप परिवर्तन के पश्चात् पहले कोड रेफेर स्थानों को भी समायोजित करना होगा। इसी तरह, परिवर्तन के दौरान पीछे की ओर जाने वाले पश्चात् के रिफरेन्स को भी ठीक करना होगा, यहां तक ​​कि वे भी जो ज्ञात पतों पर थे। और साथ ही, फिक्सअप जानकारी को स्वयं ही सही ढंग से ठीक करना होगा। दूसरी ओर, लंबे पते का उपयोग उन सभी मामलों के लिए किया जा सकता है जब निकटता निश्चित नहीं है, परन्तु परिणामी कोड अब आदर्श नहीं होगा।


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


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


==उपयोग से पहले घोषणा==
==उपयोग से पहले घोषणा==
विभिन्न अभिव्यक्तियों के लिए कोड बनाते समय, कंपाइलर को ऑपरेंड की प्रकृति जानने की आवश्यकता होती है। उदाहरण के लिए, एक कथन जैसे A:=B; ए और बी पूर्णांक हैं या फ़्लोटिंग-पॉइंट वैरिएबल (और कौन सा आकार: एकल, डबल या चौगुनी परिशुद्धता) या जटिल संख्या, सरणी, स्ट्रिंग, प्रोग्रामर-परिभाषित प्रकार इत्यादि के आधार पर अलग-अलग कोड उत्पन्न कर सकते हैं। इस मामले में, एक सरल दृष्टिकोण भंडारण के शब्दों की उचित संख्या को स्थानांतरित करना होगा, लेकिन, स्ट्रिंग्स के लिए यह अनुपयुक्त हो सकता है क्योंकि प्राप्तकर्ता आपूर्तिकर्ता से छोटा हो सकता है और किसी भी मामले में, स्ट्रिंग का केवल एक हिस्सा उपयोग किया जा सकता है - शायद इसमें एक हजार अक्षरों के लिए जगह है, लेकिन वर्तमान में इसमें दस शामिल हैं। फिर अधिक जटिल निर्माण भी हैं, जैसे कि COBOL और pl/i द्वारा प्रस्तावित <code>A:=B by name;</code> इस मामले में, ए और बी समुच्चय (या संरचनाएं) हैं, उदाहरण के लिए ए में कुछ हिस्से हैं <code>A.x</code>, <code>A.y</code> और <code>A.other</code> जबकि बी के हिस्से हैं <code>B.y</code>, <code>B.c</code> और <code>B.x</code>, और उसी क्रम में. नाम सुविधा का अर्थ इसके समकक्ष है <code>A.y:=B.y; A.x:=B.x;</code> लेकिन क्योंकि <code>B.c</code> ए, और में कोई समकक्ष नहीं है <code>A.other</code> बी में कोई समकक्ष नहीं है, वे शामिल नहीं हैं।
विभिन्न एक्सप्रेशंस के लिए कोड बनाते समय, कंपाइलर को ऑपरेंड की प्रकृति जानने की आवश्यकता होती है। उदाहरण के लिए, एक कथन जैसे A:=B; ए और बी पूर्णांक हैं या फ़्लोटिंग-पॉइंट वैरिएबल (और कौन सा आकार: एकल, डबल या चौगुनी परिशुद्धता) या जटिल संख्या, सरणी, स्ट्रिंग, प्रोग्रामर-परिभाषित प्रकार इत्यादि के आधार पर अलग-अलग कोड उत्पन्न कर सकते हैं। इस मामले में, एक सरल दृष्टिकोण स्टोरेज के शब्दों की उचित संख्या को स्थानांतरित करना होगा, परन्तु, स्ट्रिंग्स के लिए यह अनुपयुक्त हो सकता है क्योंकि प्राप्तकर्ता आपूर्तिकर्ता से छोटा हो सकता है और किसी भी मामले में, स्ट्रिंग का मात्र एक हिस्सा उपयोग किया जा सकता है - शायद इसमें एक हजार अक्षरों के लिए जगह है, परन्तु वर्तमान में इसमें दस सम्मिलित हैं। फिर अधिक जटिल निर्माण भी हैं, जैसे कि COBOL और pl/i द्वारा प्रस्तावित <code>A:=B by name;</code> इस मामले में, ए और बी समुच्चय (या कंस्ट्रक्ट) हैं, उदाहरण के लिए ए में कुछ हिस्से हैं <code>A.x</code>, <code>A.y</code> और <code>A.other</code> जबकि बी के हिस्से हैं <code>B.y</code>, <code>B.c</code> और <code>B.x</code>, और उसी क्रम में. नाम सुविधा का अर्थ इसके समकक्ष है <code>A.y:=B.y; A.x:=B.x;</code> परन्तु क्योंकि <code>B.c</code> ए, और में कोई समकक्ष नहीं है <code>A.other</code> बी में कोई समकक्ष नहीं है, वे सम्मिलित नहीं हैं।


यह सब इस आवश्यकता से नियंत्रित किया जा सकता है कि वस्तुओं को उपयोग से पहले घोषित किया जाए। कुछ भाषाओं में स्पष्ट घोषणाओं की आवश्यकता नहीं होती है, पहली बार किसी नए नाम का सामना करने पर एक अंतर्निहित घोषणा उत्पन्न होती है। क्या फोरट्रान कंपाइलर को पहले से अज्ञात नाम का सामना करना पड़ता है जिसका पहला अक्षर I, J,...,N में से एक है, तो चर एक पूर्णांक होगा, अन्यथा एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। इस प्रकार एक नाम <code>DO12I</code> एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। यह एक सुविधा है, लेकिन गलत टाइप किए गए नामों के साथ कुछ अनुभवों के बाद, अधिकांश प्रोग्रामर इस बात से सहमत हैं कि किसी भी अंतर्निहित कंपाइलर विकल्प का उपयोग नहीं किया जाना चाहिए।
यह सब इस आवश्यकता से नियंत्रित किया जा सकता है कि वस्तुओं को उपयोग से पहले डिक्लेअर किया जाए। कुछ रिप्रजेंटेशनओं में स्पष्ट डिक्लेरेशन की आवश्यकता नहीं होती है, पहली बार किसी नए नाम का एनकाउंटर करने पर एक अंतर्निहित घोषणा उत्पन्न होती है। क्या फोरट्रान कंपाइलर को पहले से अज्ञात नाम का एनकाउंटर करना पड़ता है जिसका पहला अक्षर I, J,...,N में से एक है, तो चर एक पूर्णांक होगा, अन्यथा एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। इस प्रकार एक नाम <code>DO12I</code> एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। यह एक सुविधा है, परन्तु गलत टाइप किए गए नामों के साथ कुछ अनुभवों के पश्चात्, अधिकांश प्रोग्रामर इस बात से सहमत हैं कि किसी भी अंतर्निहित कंपाइलर विकल्प का उपयोग नहीं किया जाना चाहिए।


अन्य प्रणालियाँ प्रकार तय करने के लिए पहली मुठभेड़ की प्रकृति का उपयोग करती हैं, जैसे कि एक स्ट्रिंग, या एक सरणी, इत्यादि। व्याख्या की गई भाषाएँ विशेष रूप से लचीली हो सकती हैं, निर्णय रन टाइम पर लिया जा सकता है, कुछ इस प्रकार
अन्य प्रणालियाँ प्रकार तय करने के लिए पहली मुठभेड़ की प्रकृति का उपयोग करती हैं, जैसे कि एक स्ट्रिंग, या एक सरणी, इत्यादि। इंटरप्रिटेशन की गई रिप्रजेंटेशनएँ स्पेशल रूप से लचीली हो सकती हैं, निर्णय रन टाइम पर लिया जा सकता है, कुछ इस प्रकार
  यदि ''स्थिति'' तो pi:= 3.14 अन्यथा pi:=3.14 fi;
  यदि ''स्थिति'' तो pi:= 3.14 अन्यथा pi:=3.14 fi;
  पाई प्रिंट करें;
  पाई प्रिंट करें;
क्या ऐसी भाषा के लिए कोई कंपाइलर होना चाहिए, उसे वेरिएबल पाई का प्रतिनिधित्व करने के लिए एक जटिल इकाई बनानी होगी, जिसमें यह संकेत होगा कि इसका वर्तमान प्रकार क्या है और ऐसे प्रकार का प्रतिनिधित्व करने के लिए संबंधित भंडारण होगा। यह निश्चित रूप से लचीला है, लेकिन गहन गणना के लिए सहायक नहीं हो सकता है जैसे कि A.x = b को हल करने में जहां A सौ क्रम का एक मैट्रिक्स है, और अचानक, इसका कोई भी तत्व एक अलग प्रकार का हो सकता है।
क्या ऐसी रिप्रजेंटेशन के लिए कोई कंपाइलर होना चाहिए, उसे वेरिएबल पाई का प्रतिनिधित्व करने के लिए एक जटिल यूनिट बनानी होगी, जिसमें यह संकेत होगा कि इसका वर्तमान प्रकार क्या है और ऐसे प्रकार का प्रतिनिधित्व करने के लिए संबंधित स्टोरेज होगा। यह निश्चित रूप से लचीला है, परन्तु गहन गणना के लिए सहायक नहीं हो सकता है जैसे कि A.x = b को हल करने में जहां A सौ क्रम का एक मैट्रिक्स है, और अचानक, इसका कोई भी तत्व एक अलग प्रकार का हो सकता है।


===प्रक्रियाएँ और कार्य===
===प्रक्रियाएँ और कार्य===
उपयोग से पहले घोषणा भी प्रक्रियाओं और कार्यों के लिए एक आसान आवश्यकता है, और यह प्रक्रियाओं के भीतर प्रक्रियाओं के घोंसले पर भी लागू होती है। ALGOL, पास्कल, PL/I और कई अन्य की तरह, MATLAB और (1995 से) फोरट्रान एक फ़ंक्शन (या प्रक्रिया) को किसी अन्य फ़ंक्शन (या प्रक्रिया) की परिभाषा को शामिल करने की अनुमति देते हैं, जो केवल युक्त फ़ंक्शन के भीतर दिखाई देता है, लेकिन इन प्रणालियों के लिए आवश्यक है कि उन्हें युक्त प्रक्रिया के अंत के बाद परिभाषित किया जाए।
उपयोग से पहले घोषणा भी प्रक्रियाओं और कार्यों के लिए एक आसान आवश्यकता है, और यह प्रक्रियाओं के भीतर प्रक्रियाओं के घोंसले पर भी लागू होती है। ALGOL, पास्कल, PL/I और कई अन्य की तरह, MATLAB और (1995 से) फोरट्रान एक फ़ंक्शन (या प्रक्रिया) को किसी अन्य फ़ंक्शन (या प्रक्रिया) की परिरिप्रजेंटेशन को सम्मिलित करने की अनुमति देते हैं, जो मात्र युक्त फ़ंक्शन के भीतर दिखाई देता है, परन्तु इन प्रणालियों के लिए आवश्यक है कि उन्हें युक्त प्रक्रिया के अंत के पश्चात् परिभाषित किया जाए।


लेकिन जब पुनरावृत्ति की अनुमति दी जाती है, तो एक समस्या उत्पन्न होती है। दो प्रक्रियाएँ, जिनमें से प्रत्येक एक दूसरे का आह्वान करती हैं, दोनों को उपयोग से पहले घोषित नहीं किया जा सकता है। स्रोत फ़ाइल में सबसे पहले होना चाहिए। इससे कोई फर्क नहीं पड़ता, जैसा कि एक अज्ञात चर के साथ मुठभेड़ पर, मुठभेड़ से पर्याप्त निष्कर्ष निकाला जा सकता है कि कंपाइलर अज्ञात प्रक्रिया के आह्वान के लिए उपयुक्त कोड उत्पन्न कर सकता है, निश्चित रूप से वापस आने और भरने के लिए फिक्सअप उपकरण के साथ जब प्रक्रिया की परिभाषा सामने आती है तो गंतव्य के लिए सही पते पर। उदाहरण के लिए, बिना किसी पैरामीटर वाली प्रक्रिया के लिए यही स्थिति होगी। किसी फ़ंक्शन मंगलाचरण से लौटाया गया परिणाम मंगलाचरण से पहचाने जाने योग्य प्रकार का हो सकता है, लेकिन यह हमेशा सही नहीं हो सकता है: एक फ़ंक्शन एक फ़्लोटिंग-पॉइंट परिणाम लौटा सकता है लेकिन इसका मान एक पूर्णांक को सौंपा जा सकता है।
परन्तु जब रेपिटेशन की अनुमति दी जाती है, तो एक समस्या उत्पन्न होती है। दो प्रक्रियाएँ, जिनमें से प्रत्येक एक दूसरे का आह्वान करती हैं, दोनों को उपयोग से पहले डिक्लेअर नहीं किया जा सकता है। सौर्स फ़ाइल में सबसे पहले होना चाहिए। इससे कोई फर्क नहीं पड़ता, जैसा कि एक अज्ञात चर के साथ मुठभेड़ पर, मुठभेड़ से पर्याप्त निष्कर्ष निकाला जा सकता है कि कंपाइलर अज्ञात प्रक्रिया के आह्वान के लिए उपयुक्त कोड उत्पन्न कर सकता है, निश्चित रूप से वापस आने और भरने के लिए फिक्सअप उपकरण के साथ जब प्रक्रिया की परिरिप्रजेंटेशन सामने आती है तो गंतव्य के लिए सही पते पर। उदाहरण के लिए, बिना किसी पैरामीटर वाली प्रक्रिया के लिए यही स्थिति होगी। किसी फ़ंक्शन मंगलाचरण से लौटाया गया परिणाम मंगलाचरण से पहचाने जाने योग्य प्रकार का हो सकता है, परन्तु यह हमेशा सही नहीं हो सकता है: एक फ़ंक्शन एक फ़्लोटिंग-पॉइंट परिणाम लौटा सकता है परन्तु इसका मान एक पूर्णांक को सौंपा जा सकता है।


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


मापदंडों के साथ एक प्रक्रिया (या फ़ंक्शन) के आह्वान के लिए, उनके प्रकार को जाना जाएगा (उन्हें उपयोग से पहले घोषित किया जाएगा) लेकिन प्रक्रिया के आह्वान में उनका उपयोग नहीं किया जा सकता है। उदाहरण के लिए, फोरट्रान सभी मापदंडों को संदर्भ द्वारा (यानी पते द्वारा) पारित करता है, इसलिए कोड उत्पन्न करने में कोई तत्काल कठिनाई नहीं होती है (हमेशा की तरह, वास्तविक पते बाद में तय किए जाएंगे), लेकिन पास्कल और अन्य भाषाएं विभिन्न तरीकों से मापदंडों को पारित करने की अनुमति देती हैं प्रोग्रामर की पसंद पर (मूल्यांकन रणनीति#संदर्भ द्वारा कॉल करें, या मूल्यांकन रणनीति#मूल्य द्वारा कॉल करें, या शायद मूल्यांकन रणनीति#नाम से कॉल करें|नाम से) और यह केवल प्रक्रिया की परिभाषा में दर्शाया गया है, जो इससे पहले अज्ञात है परिभाषा का सामना करना पड़ा है. विशेष रूप से पास्कल के लिए, मापदंडों के विनिर्देश में एक उपसर्ग वार दर्शाता है कि इसे संदर्भ द्वारा प्राप्त किया जाना चाहिए, इसकी अनुपस्थिति मूल्य से दर्शाती है। पहले मामले में कंपाइलर को कोड उत्पन्न करना होगा जो पैरामीटर के पते को पास करता है, जबकि दूसरे में उसे अलग कोड उत्पन्न करना होगा जो मान की एक प्रति को आमतौर पर स्टैक के माध्यम से पास करता है। हमेशा की तरह, इससे निपटने के लिए एक फिक्सअप तंत्र लागू किया जा सकता है, लेकिन यह बहुत गड़बड़ होगा। मल्टी-पास कंपाइलर निश्चित रूप से सभी आवश्यक जानकारी को एकत्रित कर सकते हैं क्योंकि वे आगे और पीछे शटल करते हैं, लेकिन सिंगल-पास कंपाइलर ऐसा नहीं कर सकते हैं। स्कैन के आगे बढ़ने पर कोड जनरेशन को रोका जा सकता है (और इसके परिणाम आंतरिक भंडारण में रखे जाएंगे) जब तक कि आवश्यक इकाई का सामना न हो जाए, और इसे स्रोत के माध्यम से दूसरी बार पास होने के परिणामस्वरूप नहीं माना जा सकता है क्योंकि कोड जनरेशन चरण होगा जल्द ही पकड़ लो, यह केवल थोड़ी देर के लिए रुक रहा था। लेकिन यह जटिल होगा. इसके बजाय एक विशेष निर्माण शुरू किया गया है, जिसके तहत पैरामीटर उपयोग की प्रक्रिया की परिभाषा को इसकी बाद की पूर्ण परिभाषा से पहले घोषित किया जाता है ताकि कंपाइलर इसे उपयोग से पहले जान सके, जैसा कि इसकी आवश्यकता है।
मापदंडों के साथ एक प्रक्रिया (या फ़ंक्शन) के आह्वान के लिए, उनके प्रकार को जाना जाएगा (उन्हें उपयोग से पहले डिक्लेअर किया जाएगा) परन्तु प्रक्रिया के आह्वान में उनका उपयोग नहीं किया जा सकता है। उदाहरण के लिए, फोरट्रान सभी मापदंडों को रेफेरेन्स द्वारा (यानी पते द्वारा) पारित करता है, इसलिए कोड उत्पन्न करने में कोई तत्काल कठिनाई नहीं होती है (हमेशा की तरह, वास्तविक पते पश्चात् में तय किए जाएंगे), परन्तु पास्कल और अन्य रिप्रजेंटेशनएं विभिन्न तरीकों से मापदंडों को पारित करने की अनुमति देती हैं प्रोग्रामर की पसंद पर (बेसिक्यांकन रणनीति#रेफेरेन्स द्वारा कॉल करें, या बेसिक्यांकन रणनीति#बेसिक्य द्वारा कॉल करें, या शायद बेसिक्यांकन रणनीति#नाम से कॉल करें|नाम से) और यह मात्र प्रक्रिया की परिरिप्रजेंटेशन में दर्शाया गया है, जो इससे पहले अज्ञात है परिरिप्रजेंटेशन का एनकाउंटर करना पड़ा है. स्पेशल रूप से पास्कल के लिए, मापदंडों के विनिर्देश में एक उपसर्ग वार दर्शाता है कि इसे रेफेरेन्स द्वारा प्राप्त किया जाना चाहिए, इसकी अनुपस्थिति बेसिक्य से दर्शाती है। पहले मामले में कंपाइलर को कोड उत्पन्न करना होगा जो पैरामीटर के पते को पास करता है, जबकि दूसरे में उसे अलग कोड उत्पन्न करना होगा जो मान की एक प्रति को आमतौर पर स्टैक के माध्यम से पास करता है। हमेशा की तरह, इससे निपटने के लिए एक फिक्सअप तंत्र लागू किया जा सकता है, परन्तु यह बहुत गड़बड़ होगा। मल्टी-पास कंपाइलर निश्चित रूप से सभी आवश्यक जानकारी को एकत्रित कर सकते हैं क्योंकि वे आगे और पीछे शटल करते हैं, परन्तु सिंगल-पास कंपाइलर ऐसा नहीं कर सकते हैं। स्कैन के आगे बढ़ने पर कोड जनरेशन को रोका जा सकता है (और इसके परिणाम आंतरिक स्टोरेज में रखे जाएंगे) जब तक कि आवश्यक यूनिट का एनकाउंटर न हो जाए, और इसे सौर्स के माध्यम से दूसरी बार पास होने के परिणामस्वरूप नहीं माना जा सकता है क्योंकि कोड जनरेशन चरण होगा जल्द ही पकड़ लो, यह मात्र थोड़ी देर के लिए रुक रहा था। परन्तु यह जटिल होगा. इसके बजाय एक स्पेशल निर्माण प्रारम्भ किया गया है, जिसके तहत पैरामीटर उपयोग की प्रक्रिया की परिरिप्रजेंटेशन को इसकी पश्चात् की पूर्ण परिरिप्रजेंटेशन से पहले डिक्लेअर किया जाता है ताकि कंपाइलर इसे उपयोग से पहले जान सके, जैसा कि इसकी आवश्यकता है।


फर्स्ट फोरट्रान (1957) के बाद से, एक कार्यक्रम के हिस्सों का अलग-अलग संकलन संभव हो गया है, जो प्रक्रियाओं और कार्यों के पुस्तकालयों के निर्माण का समर्थन करता है। संकलित की जा रही स्रोत फ़ाइल में एक प्रक्रिया जो ऐसे बाहरी संग्रह से एक फ़ंक्शन को आमंत्रित करती है, उसे प्रकार जानना चाहिएअज्ञात फ़ंक्शन द्वारा लौटाए गए परिणाम का, यदि केवल कोड उत्पन्न करना है जो परिणाम ढूंढने के लिए सही जगह पर दिखता है। मूल रूप से, जब केवल पूर्णांक और फ़्लोटिंग-पॉइंट चर थे, तो विकल्प को अंतर्निहित घोषणा के नियमों पर छोड़ा जा सकता था, लेकिन आकार और प्रकारों के प्रसार के साथ आह्वान प्रक्रिया को फ़ंक्शन के लिए एक प्रकार की घोषणा की आवश्यकता होगी। यह कोई विशेष बात नहीं है, इसका स्वरूप प्रक्रिया के अंदर घोषित चर के समान ही है।
फर्स्ट फोरट्रान (1957) के पश्चात् से, एक फंक्शन के हिस्सों का अलग-अलग कंपाइलेशन संभव हो गया है, जो प्रक्रियाओं और कार्यों के पुस्तकालयों के निर्माण का समर्थन करता है। कंपाइल की जा रही सौर्स फ़ाइल में एक प्रक्रिया जो ऐसे बाहरी संग्रह से एक फ़ंक्शन को आमंत्रित करती है, उसे प्रकार जानना चाहिएअज्ञात फ़ंक्शन द्वारा लौटाए गए परिणाम का, यदि मात्र कोड उत्पन्न करना है जो परिणाम ढूंढने के लिए सही जगह पर दिखता है। बेसिक रूप से, जब मात्र पूर्णांक और फ़्लोटिंग-पॉइंट चर थे, तो विकल्प को अंतर्निहित घोषणा के नियमों पर छोड़ा जा सकता था, परन्तु आकार और प्रकारों के प्रसार के साथ आह्वान प्रक्रिया को फ़ंक्शन के लिए एक प्रकार की घोषणा की आवश्यकता होगी। यह कोई स्पेशल बात नहीं है, इसका स्वरूप प्रक्रिया के अंदर डिक्लेअर चर के समान ही है।


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


किसी प्रक्रिया (या फ़ंक्शन) के सभी आह्वानों की एक-दूसरे और उनकी परिभाषाओं के साथ अनुकूलता के लिए जाँच की जाती है या नहीं, यह एक अलग मामला है। अल्गोल-जैसी प्रेरणा से उत्पन्न भाषाओं में, यह जाँच आमतौर पर कठोर होती है, लेकिन अन्य प्रणालियाँ उदासीन हो सकती हैं। उन प्रणालियों को छोड़कर जो किसी प्रक्रिया को वैकल्पिक पैरामीटर रखने की अनुमति देते हैं, पैरामीटर की संख्या और प्रकार में गलतियाँ आम तौर पर प्रोग्राम के क्रैश होने का कारण बनेंगी। सिस्टम जो पूरे कार्यक्रम के हिस्सों के अलग-अलग संकलन की अनुमति देते हैं, जिन्हें बाद में एक साथ जोड़ा जाता है, उन्हें सही प्रकार और मापदंडों की संख्या और परिणामों की भी जांच करनी चाहिए क्योंकि गलतियाँ करना और भी आसान है, लेकिन अक्सर ऐसा नहीं होता है। कुछ भाषाओं (जैसे अल्गोल) में उन्नयन या विस्तार या पदोन्नति की औपचारिक धारणा होती है, जिसके तहत एक प्रक्रिया जो यह अपेक्षा करती है कि एक डबल-सटीक पैरामीटर को एकल परिशुद्धता चर के रूप में लागू किया जा सकता है, और इस मामले में कंपाइलर कोड उत्पन्न करता है जो एकल परिशुद्धता चर को एक अस्थायी डबल-परिशुद्धता चर में संग्रहीत करता है जो वास्तविक पैरामीटर बन जाता है। हालाँकि, यह पैरामीटर पासिंग तंत्र को मूल्यांकन रणनीति#कॉपी-रिस्टोर|कॉपी-इन, कॉपी-आउट द्वारा कॉल में बदल देता है जिससे व्यवहार में सूक्ष्म अंतर हो सकता है। जब कोई प्रक्रिया एक एकल परिशुद्धता चर का पता प्राप्त करती है, जब वह दोहरे परिशुद्धता पैरामीटर, या अन्य आकार भिन्नताओं की अपेक्षा करती है, तो परिणाम बहुत कम सूक्ष्म होते हैं। जब प्रक्रिया के भीतर पैरामीटर का मान पढ़ा जाता है, तो उसके दिए गए पैरामीटर की तुलना में अधिक संग्रहण पढ़ा जाएगा और परिणामी मान में सुधार होने की संभावना नहीं है। इससे भी बदतर स्थिति तब होती है जब प्रक्रिया अपने पैरामीटर का मान बदल देती है: कुछ न कुछ क्षतिग्रस्त होना निश्चित है। इन गलतियों को खोजने और सुधारने में बहुत धैर्य खर्च किया जा सकता है।
किसी प्रक्रिया (या फ़ंक्शन) के सभी आह्वानों की एक-दूसरे और उनकी परिरिप्रजेंटेशनओं के साथ अनुकूलता के लिए जाँच की जाती है या नहीं, यह एक अलग मामला है। अल्गोल-जैसी प्रेरणा से उत्पन्न रिप्रजेंटेशनओं में, यह जाँच आमतौर पर कठोर होती है, परन्तु अन्य प्रणालियाँ उदासीन हो सकती हैं। उन प्रणालियों को छोड़कर जो किसी प्रक्रिया को वैकल्पिक पैरामीटर रखने की अनुमति देते हैं, पैरामीटर की संख्या और प्रकार में गलतियाँ सामान्यतः प्रोग्राम के क्रैश होने का कारण बनेंगी। सिस्टम जो पूरे फंक्शन के हिस्सों के अलग-अलग कंपाइलेशन की अनुमति देते हैं, जिन्हें पश्चात् में एक साथ ऐड जाता है, उन्हें सही प्रकार और मापदंडों की संख्या और परिणामों की भी जांच करनी चाहिए क्योंकि गलतियाँ करना और भी आसान है, परन्तु अक्सर ऐसा नहीं होता है। कुछ रिप्रजेंटेशनओं (जैसे अल्गोल) में उन्नयन या स्पैन या पदोन्नति की औपचारिक धारणा होती है, जिसके तहत एक प्रक्रिया जो यह अपेक्षा करती है कि एक डबल-सटीक पैरामीटर को एकल परिशुद्धता चर के रूप में लागू किया जा सकता है, और इस मामले में कंपाइलर कोड उत्पन्न करता है जो एकल परिशुद्धता चर को एक टेम्पररी डबल-परिशुद्धता चर में संग्रहीत करता है जो वास्तविक पैरामीटर बन जाता है। हालाँकि, यह पैरामीटर पासिंग तंत्र को बेसिक्यांकन रणनीति#कॉपी-रिस्टोर|कॉपी-इन, कॉपी-आउट द्वारा कॉल में बदल देता है जिससे व्यवहार में सूक्ष्म अंतर हो सकता है। जब कोई प्रक्रिया एक एकल परिशुद्धता चर का पता प्राप्त करती है, जब वह दोहरे परिशुद्धता पैरामीटर, या अन्य आकार भिन्नताओं की अपेक्षा करती है, तो परिणाम बहुत कम सूक्ष्म होते हैं। जब प्रक्रिया के भीतर पैरामीटर का मान रीड जाता है, तो उसके दिए गए पैरामीटर की तुलना में अधिक संग्रहण रीड जाएगा और परिणामी मान में सुधार होने की संभावना नहीं है। इससे भी बदतर स्थिति तब होती है जब प्रक्रिया अपने पैरामीटर का मान बदल देती है: कुछ न कुछ क्षतिग्रस्त होना निश्चित है। इन गलतियों को खोजने और सुधारने में बहुत धैर्य खर्च किया जा सकता है।


===पास्कल उदाहरण===
===पास्कल उदाहरण===
ऐसे निर्माण का एक उदाहरण [[पास्कल (प्रोग्रामिंग भाषा)]] में आगे की घोषणा है। पास्कल के लिए आवश्यक है कि उपयोग से पहले [[सबरूटीन]] को घोषित या पूर्ण रूप से परिभाषित किया जाए। यह एक-पास कंपाइलर को उसके प्रकार की जाँच करने में मदद करता है: ऐसी प्रक्रिया को कॉल करना जिसे कहीं भी घोषित नहीं किया गया है, एक स्पष्ट त्रुटि है। उपयोग से पहले घोषणा नियम के बावजूद, आगे की घोषणाएं आपसी रिकर्सन प्रक्रियाओं को एक-दूसरे को सीधे कॉल करने में मदद करती हैं:
ऐसे निर्माण का एक उदाहरण [[पास्कल (प्रोग्रामिंग भाषा)|पास्कल (प्रोग्रामिंग रिप्रजेंटेशन)]] में आगे की घोषणा है। पास्कल के लिए आवश्यक है कि उपयोग से पहले [[सबरूटीन]] को डिक्लेअर या पूर्ण रूप से परिभाषित किया जाए। यह वन-पास कंपाइलर को उसके प्रकार की जाँच करने में मदद करता है: ऐसी प्रक्रिया को कॉल करना जिसे कहीं भी डिक्लेअर नहीं किया गया है, एक स्पष्ट त्रुटि है। उपयोग से पहले घोषणा नियम के बावजूद, आगे की घोषणाएं आपसी रिकर्सन प्रक्रियाओं को एक-दूसरे को सीधे कॉल करने में मदद करती हैं:


<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
Line 124: Line 125:
end;
end;
</syntaxhighlight>
</syntaxhighlight>
फ़ंक्शन के लिए एक अग्रेषित घोषणा जोड़कर <code>even</code> समारोह से पहले <code>odd</code>, वन-पास कंपाइलर को बताया जाता है कि इसकी एक परिभाषा होगी <code>even</code> बाद में कार्यक्रम में.
फ़ंक्शन के लिए एक अग्रेषित घोषणा जोड़कर <code>even</code> समारोह से पहले <code>odd</code>, वन-पास कंपाइलर को बताया जाता है कि इसकी एक परिरिप्रजेंटेशन होगी <code>even</code> पश्चात् में फंक्शन में.


<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
Line 132: Line 133:
   { Et cetera }
   { Et cetera }
</syntaxhighlight>
</syntaxhighlight>
जब फ़ंक्शन के मुख्य भाग की वास्तविक घोषणा की जाती है, तो या तो पैरामीटर हटा दिए जाते हैं या मूल फ़ॉरवर्ड घोषणा के बिल्कुल समान होने चाहिए, या एक त्रुटि चिह्नित की जाएगी।
जब फ़ंक्शन के मुख्य भाग की वास्तविक घोषणा की जाती है, तो या तो पैरामीटर हटा दिए जाते हैं या बेसिक फ़ॉरवर्ड घोषणा के बिल्कुल समान होने चाहिए, या एक त्रुटि चिह्नित की जाएगी।


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


===अग्रेषित घोषणाएँ हानिकारक मानी जाती हैं===
===अग्रेषित घोषणाएँ हानिकारक मानी जाती हैं===
जिस किसी ने भी एक बड़े कार्यक्रम में प्रक्रियाओं की घोषणाओं और उपयोगों और दिनचर्या के पुस्तकालयों के उपयोग के बीच सुसंगतता बनाए रखने का प्रयास किया है, विशेष रूप से परिवर्तन से गुजरने वाली प्रक्रियाओं के लिए आगे या इसी तरह की अतिरिक्त घोषणाओं के उपयोग पर संघर्ष किया होगा, लेकिन परिभाषित नहीं किया गया है वर्तमान संकलन. व्यापक रूप से अलग-अलग स्थानों, विशेष रूप से विभिन्न स्रोत फ़ाइलों के बीच तालमेल बनाए रखने के लिए परिश्रम की आवश्यकता होती है। आरक्षित शब्द का उपयोग करने वाली उन घोषणाओं को ढूंढना आसान है, लेकिन यदि सहायक घोषणाओं को सामान्य घोषणाओं से अलग नहीं किया जाता है, तो कार्य परेशानी भरा हो जाता है। कथित रूप से तेज़ संकलन का लाभ तब अपर्याप्त लग सकता है जब केवल एक-पास संकलन के लक्ष्य को छोड़ने से यह अधिरोपण दूर हो जाएगा।
जिस किसी ने भी एक बड़े फंक्शन में प्रक्रियाओं की डिक्लेरेशन और उपयोगों और दिनचर्या के पुस्तकालयों के उपयोग के मध्य सुसंगतता बनाए रखने का प्रयास किया है, स्पेशल रूप से परिवर्तन से गुजरने वाली प्रक्रियाओं के लिए आगे या इसी तरह की अतिरिक्त डिक्लेरेशन के उपयोग पर संघर्ष किया होगा, परन्तु परिभाषित नहीं किया गया है वर्तमान कंपाइलेशन. व्यापक रूप से अलग-अलग स्थानों, स्पेशल रूप से विभिन्न सौर्स फ़ाइलों के मध्य तालमेल बनाए रखने के लिए परिश्रम की आवश्यकता होती है। आरक्षित शब्द का उपयोग करने वाली उन डिक्लेरेशन को ढूंढना आसान है, परन्तु यदि सहायक डिक्लेरेशन को सामान्य डिक्लेरेशन से अलग नहीं किया जाता है, तो कार्य परेशानी भरा हो जाता है। कथित रूप से तेज़ कंपाइलेशन का लाभ तब अपर्याप्त लग सकता है जब मात्र वन-पास कंपाइलेशन के लक्ष्य को छोड़ने से यह अधिरोपण दूर हो जाएगा।


==यह भी देखें==
==यह भी देखें==
Line 146: Line 147:
*[[एक्सपीएल]]
*[[एक्सपीएल]]


==संदर्भ==  
==रेफेरेन्स==  
{{reflist}}
{{reflist}}



Revision as of 22:22, 5 August 2023

कंप्यूटर प्रोग्रामिंग में, वन-पास कंपाइलर एक कंपाइलर होता है जो प्रत्येक कंपाइलेशन यूनिट के भागो से मात्र एक बार पास है, तुरंत प्रत्येक भाग को उसके फाइनल मशीन कोड में ट्रांसलेट करता है। यह एक मल्टी-पास कंपाइलर के विपरीत होता है जो प्रोग्राम को सौर्स कोड और मशीन कोड के मध्य चरणों में एक या अधिक इंटरमीडिएट रिप्रजेंटेशन में परिवर्तित करता है, और जो प्रत्येक अनुक्रमिक पास में एनटायर कंपाइलेशन यूनिट को पुन: प्रोसेस करता है।

यह कंपाइलर की लॉजिकल फंक्शन को रेफेर करता है, न कि मात्र एक बार सौर्स फ़ाइल की एक्चुअल रीडिंग को। उदाहरण के लिए, सौर्स फ़ाइल को एक बार टेम्पररी स्टोरेज में रीड किया जा सकता है परन्तु उस प्रतिलिपि को कई बार स्कैन किया जा सकता है। आईबीएम 1130 फोरट्रान कंपाइलर ने सौर्स को मेमोरी में स्टोर किया और कई पासों का उपयोग किया; इसके विपरीत, डिस्क स्टोरेज यूनिट की लैक वाले सिस्टम पर असेंबलर के लिए आवश्यक है कि कार्ड के सौर्स डेक को कार्ड रीडर/पंच के सामने दो बार प्रेजेंट किया जाए।

गुण

वन-पास कंपाइलर मल्टी-पास कंपाइलर की तुलना में स्माल और फ़ास्ट होते हैं।[1]

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

कठिनाइयाँ

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

लोकल रेफेरेन्स

मान लीजिए कि सिंबल < को तुलना से कम के रूप में पहचाना जाता है, उदाहरण के लिए इससे अधिक के विपरीत। कैरेक्टर कोडिंग सीमाओं के कारण, ग्लिफ़ ≤ मानक एन्कोडिंग में उपलब्ध नहीं हो सकता है, इसलिए एक मिश्रित प्रतिनिधित्व की अनुमति दी जानी चाहिए, <=। भले ही यह रेफेरेन्स अगले सिंबल द्वारा निर्धारित किया जाता है, यह अज्ञात है जब < का एनकाउंटर होता है। इसी तरह, सिंबल = का मतलब हमेशा = नहीं होता है, क्योंकि जब यह किसी मिश्रित सिंबल का हिस्सा होता है। अन्य मिश्रित सिंबलों में .lt सम्मिलित हो सकता है। उस स्थिति के लिए जब स्पेशल वर्ण < अनुपलब्ध हो। फिर भी एक और संभावना जहां ग्लिफ़ ¬ (नहीं) के लिए एक वर्ण कोड अनुपलब्ध है, <> ¬= के लिए है या बराबर नहीं है - कुछ सिस्टम ~ या ! का उपयोग करते हैं। ¬ के लिए अभी भी और भिन्नता है। एक तरीका यह है कि < के पश्चात् स्कैन को आगे बढ़ाया जाए और = का एनकाउंटर करने पर, पीछे चला जाए। निःसंदेह इसका मतलब यह है कि टेक्स्ट के उस हिस्से पर दो बार गुजरना होगा, जिससे बचना होगा। उस मामले के लिए, सौर्स फ़ाइल किसी ऐसे उपकरण से आ सकती है जो कार्ड रीडर जैसे गो-बैक-एंड-रीरीड ऑपरेशन का समर्थन नहीं करता है। प्रारंभिक निर्णय लेने के बजाय, जिसे पश्चात् में पूर्ववत करना पड़ सकता है, लेक्सिकल विश्लेषक क्वांटम सुपरपोजिशन की धारणा की तरह कई इंटरप्रिटेशनओं को बनाए रख सकता है, जो पश्चात् में निर्धारण सिंबल को देखने पर ही एक विशिष्ट विकल्प में बदल जाता है। स्पेशल रूप से, COBOL कंपाइलर दशमलव स्थिरांक में दिखाई देने वाले पूर्ण विराम और कथनों के अंत में दिखाई देने वाले पूर्ण विराम के मध्य अंतर करने के लिए एक पास समर्पित करते हैं। ऐसी योजना एकल-पास कंपाइलर के लिए उपलब्ध नहीं है।

इसी प्रकार वस्तुओं के नाम के साथ भी। कुछ रिप्रजेंटेशनएँ स्वयं को एकल-वर्ण नामों तक ही सीमित रखती हैं, इसलिए एकल-वर्ण नाम के रूप में वर्ण x, टेक्स्ट जैसे नाम के भीतर वर्ण x से काफी भिन्न होता है - अब रेफेरेन्स तत्काल एडजासेंट वर्णों से आगे बढ़ जाता है। अनुक्रमिक सौर्स धारा की वस्तुओं को रिप्रजेंटेशन के टोकन में अलग करना शाब्दिक विश्लेषक का कार्य है। सिर्फ शब्द ही नहीं, क्योंकि < और <= टोकन भी हैं। नाम सामान्यतः एक अक्षर से प्रारम्भ होते हैं और अक्षरों और अंकों के साथ जारी रहते हैं, और शायद कुछ अतिरिक्त सिंबल जैसे _। संख्याओं को निर्दिष्ट करने के लिए अनुमत सिंटेक्स आश्चर्यजनक रूप से जटिल है, उदाहरण के लिए +3.14159E+0 मान्य हो सकता है। टोकन के मध्य अंतरिक्ष वर्णों की एक मनमानी संख्या की अनुमति देना सामान्य है, और फोरट्रान स्पष्ट टोकन के भीतर रिक्त स्थान की अनुमति देने (और अनदेखा करने) में भी असामान्य है ताकि GO TO और GOTO समान हों जैसे कि <= और < =। हालाँकि, कुछ प्रणालियों को कुछ टोकन को सीमित करने के लिए रिक्त स्थान की आवश्यकता हो सकती है, और अन्य, जैसे कि पायथन, प्रोग्राम ब्लॉक के दायरे को इंगित करने के लिए अग्रणी रिक्त स्थान का उपयोग करते हैं जो अन्यथा प्रारंभ ... अंत या समान मार्करों द्वारा इंगित किया जा सकता है।

एक्सप्रेशंस के भीतर रेफेरेन्स

जो रिप्रजेंटेशन अर्थमेटिक एक्सप्रेशंस की अनुमति देती हैं वे सामान्यतः प्रेसड़ेंस नियमों के साथ इन्फ़िक्स नोटेशन के सिंटेक्स को फॉलो करती हैं। इसका अर्थ यह है कि किसी एक्सप्रेशन के बेसिक्यांकन के लिए कोड का निर्माण सुचारू रूप से नहीं होता है क्योंकि एक्सप्रेशन के टोकन सौर्स टेक्स्ट से प्राप्त होते हैं। उदाहरण के लिए, एक्सप्रेशन x + y*(u - v) लोड x के एक्यूइवलेंट की ओर नहीं ले जाती है, क्योंकि x को y में नहीं ऐड किया जाता है। यदि अंकगणित के लिए स्टैक स्कीम का उपयोग किया जाता है, तो कोड लोड एक्स से प्रारम्भ हो सकता है, परन्तु निम्नलिखित + टोकन से संबंधित कोड का फॉलो नहीं होता है। इसके अतिरिक्त, (u - v) के लिए कोड जनरेट किया जाता है, उसके पश्चात् y से गुणा किया जाता है और उसके पश्चात् ही x ऐड जाता है। अर्थमेटिक एक्सप्रेशंस का पार्सर अपने एनालिसिस के समय सौर्स के साथ आगे और पीछे नहीं चलता है, यह प्रेसड़ेंस नियमों द्वारा ड्रिवेन डिफर्ड ऑपरेशन के लोकल स्टैक को नियोजित करता है। अर्थमेटिक एक्सप्रेशंस को रिवर्स पोलिश नोटेशन या इसी तरह प्रेजेंट करने की आवश्यकता से इस डांस से बचा जा सकता है; उपरोक्त उदाहरण के लिए u v - y * x + जैसा कुछ और जिसे स्ट्रिक्टली से लेफ्ट से राईट स्कैन किया जाएगा।

एक ऑप्टिमाइजेशन कंपाइलर रेपिटेशन को पहचानने और हटाने या अन्य पोटेंशियल सुधार करने के लिए अर्थमेटिक एक्सप्रेशन के रूप का एनालिसिस कर सकता है। विचार करना

a*sin(x) + b*sin(x)

कुछ रिप्रजेंटेशन, जैसे अल्गोल, अर्थमेटिक एक्सप्रेशन के भीतर असाइनमेंट की अनुमति देती हैं, इसलिए प्रोग्रामर कुछ इस तरह लिख सकता था

a*(t:=sin(x)) + b*t

परन्तु ऐसा करने के लिए आवश्यक परिश्रम के अलावा, परिणामी कथन का रूप गड़बड़ है और अब इसे कोडित किए जा रहे गणितीय एक्सप्रेशन से आसानी से तुलना नहीं की जा सकेगी। गलतियाँ आसानी से हो जायेंगी. इसके बजाय, कंपाइलर एनटायर एक्सप्रेशन के रूप का प्रतिनिधित्व कर सकता है (आमतौर पर एक पेड़ संरचना का उपयोग करके), उस संरचना का एनालिसिस और संशोधन कर सकता है, और फिर बेहतर फॉर्म के लिए कोड उत्सर्जित कर सकता है। क्रमिक असाइनमेंट स्टेटमेंट के ब्लॉक में एक स्पष्ट स्पैन होगा। इसमें सौर्स टेक्स्ट के माध्यम से दोबारा गुजरना सम्मिलित नहीं है।

मध्यम श्रेणी रेफेरेन्स

यद्यपि शाब्दिक विश्लेषक ने इनपुट स्ट्रीम को टोकन की एक स्ट्रीम में विभाजित कर दिया है (और किसी भी टिप्पणी को खारिज कर दिया है), रिप्रजेंटेशन के सिंटेक्स के अनुसार इन टोकन की इंटरप्रिटेशन अभी भी रेफेरेन्स पर निर्भर हो सकती है। फोरट्रान छद्म कोड में निम्नलिखित कथनों पर विचार करें:

यदि (एक्सप्रेशन) = आदि।
यदि (एक्सप्रेशन) लेबल1,लेबल2,लेबल3
यदि (एक्सप्रेशन) तो

पहला, if नामक एक-आयामी सरणी के एक तत्व के लिए कुछ अर्थमेटिक एक्सप्रेशन (आदि) के मान का असाइनमेंट है। फोरट्रान इस मायने में असामान्य है कि इसमें कोई आरक्षित शब्द नहीं हैं, इसलिए एक सांकेतिक लेखन का मतलब यह नहीं है कि कोई लेखन-कथन प्रगति पर है। अन्य कथन वास्तव में यदि-कथन हैं - दूसरा एक अंकगणित है-यदि जो एक्सप्रेशन के परिणाम के संकेत की जांच करता है और इसके नकारात्मक, शून्य, या सकारात्मक होने के आधार पर 1, 2, या 3 लेबल पर कूदता है; तीसरा एक लॉजिकल-यदि है, और इसके लिए आवश्यक है कि इसकी एक्सप्रेशन का परिणाम बूलियन हो - इस प्रकार, लेक्सिकल विश्लेषक से निकलने वाले टोकन की सही इंटरप्रिटेशन तब तक नहीं की जा सकती जब तक कि एक्सप्रेशन को स्कैन नहीं किया जाता है और समापन ब्रैकेट के पश्चात् वहां दिखाई नहीं देता है या तो एक बराबर चिह्न, एक अंक (लेबल 1 का टेक्स्ट होने के नाते: फोरट्रान लेबल के रूप में मात्र पूर्णांक का उपयोग करता है, हालांकि यदि अक्षरों को अनुमति दी जाती है तो स्कैन को अल्पविराम खोजने पर निर्भर रहना होगा) या एक अक्षर से प्रारम्भ होने वाली कोई चीज़ (वह तब होनी चाहिए), और तो अब, रेफेरेन्स सौर्स टेक्स्ट की एक मनमानी मात्रा तक फैला हुआ है क्योंकि एक्सप्रेशन मनमानी है। हालाँकि, तीनों मामलों में कंपाइलर स्कैन के आगे बढ़ने पर एक्सप्रेशन के बेसिक्यांकन के लिए कोड उत्पन्न कर सकता है। इस प्रकार, शाब्दिक एनालिसिस हमेशा स्वीकार्य सिंटेक्स की अनियमितताओं के कारण पहचाने गए टोकन के अर्थ को निर्धारित नहीं कर सकता है, और इसलिए यदि बैकट्रैकिंग से बचना है तो सिंटेक्स एनालिसिस को संभावित राज्यों का एक सुपरपोजिशन बनाए रखना होगा।

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

इस समस्या को आरक्षित शब्दों के उपयोग के माध्यम से कम किया जा सकता है, उदाहरण के लिए यदि, तब, और अन्य हमेशा एक इफ-स्टेटमेंट के हिस्से होते हैं और चर के नाम नहीं हो सकते हैं, परन्तु आश्चर्यजनक रूप से बड़ी संख्या में उपयोगी शब्द अनुपलब्ध हो सकते हैं। एक और तरीका है स्ट्रॉपिंग, जिसके तहत आरक्षित शब्दों को चिह्नित किया जाता है, जैसे कि उन्हें पूर्ण विराम, या एपोस्ट्रोफ जैसे स्पेशल वर्णों के मध्य रखकर, जैसा कि अल्गोल के कुछ संस्करणों में होता है। इस का मतलब है कि 'if' और if अलग-अलग टोकन हैं, पश्चात् वाला एक सामान्य नाम है, परन्तु उन सभी एपोस्ट्रोफ की आपूर्ति जल्द ही परेशान करने वाली हो जाती है। कई रिप्रजेंटेशनओं के लिए, रिक्ति पर्याप्त जानकारी प्रदान करती है, हालांकि यह जटिल हो सकती है। अक्सर यह मात्र एक स्थान (या टैब, आदि) नहीं होता है, बल्कि एक अक्षर या अंक के अलावा एक वर्ण होता है जो संभावित टोकन के टेक्स्ट को समाप्त करता है। उपरोक्त उदाहरण में, यदि-कथन की एक्सप्रेशन कोष्ठक के भीतर होनी चाहिए ताकि (निश्चित रूप से यदि की पहचान समाप्त हो जाए और इसी तरह,) तब की पहचान को सक्षम कर सके; इसके अलावा, किसी कंपाउंड के अन्य भाग if-स्टेटमेंट को नई लाइनों पर प्रदर्शित होना चाहिए: else और End if (या Endif ) और else if । इसके विपरीत, अल्गोल और अन्य के साथ कोष्ठक की आवश्यकता नहीं होती है और इफ-स्टेटमेंट के सभी भाग एक पंक्ति में हो सकते हैं। पास्कल के साथ, 'यदि' ए 'या' बी 'तब' आदि मान्य है, परन्तु यदि ए और बी एक्सप्रेशन हैं, तो उन्हें कोष्ठक में संलग्न किया जाना चाहिए।

कंपाइलर द्वारा निर्मित सौर्स फ़ाइल सूची को उसके द्वारा पहचाने जाने वाले आरक्षित शब्दों को रेखांकित या 'बोल्ड' या इटैलिक में प्रेजेंट करके पढ़ना आसान बनाया जा सकता है, परन्तु आलोचना हुई है: अल्गोल एकमात्र ऐसी रिप्रजेंटेशन है जो इटैलिक और सामान्य पूर्ण विराम के मध्य अंतर करती है। दरअसल ये कोई मज़ाक की बात नहीं है. फोरट्रान में, एक डू-स्टेटमेंट की शुरुआत जैसे होती है DO 12 I = 1,15 से अलग है DO 12 I = 1.15 (एक वैरिएबल के लिए मान 1.15 का एक असाइनमेंट कहा जाता है DO12I; याद रखें कि रिक्त स्थान अप्रासंगिक हैं) मात्र अल्पविराम और पूर्ण विराम के मध्य के अंतर से, और एक मुद्रित सूची के ग्लिफ़ अच्छी तरह से नहीं बने हो सकते हैं।

किसी रिप्रजेंटेशन के डिज़ाइन पर सावधानीपूर्वक ध्यान देने से एक विश्वसनीय कंपाइलर बनाने की दृष्टि से एक्सप्रेशन की स्पष्टता और सरलता को बढ़ावा मिल सकता है जिसका व्यवहार आसानी से समझ में आता है। फिर भी ख़राब विकल्प आम हैं। उदाहरण के लिए, मैटलैब ए' के ​​रूप में एपोस्ट्रोफ का उपयोग करके मैट्रिक्स ट्रांसपोज़िशन को दर्शाता है जो कि अपवाद नहीं है और गणितीय उपयोग का बारीकी से फॉलो करता है। ठीक है और अच्छा है, परन्तु टेक्स्ट स्ट्रिंग के सीमांकक के लिए मैटलैब किसी भी उद्देश्य के लिए दोहरे उद्धरण चिह्न द्वारा प्रेजेंट अवसर को अनदेखा करता है और इसके लिए एपोस्ट्रोफ का भी उपयोग करता है। हालाँकि ऑक्टेव टेक्स्ट स्ट्रिंग्स के लिए दोहरे उद्धरण चिह्नों का उपयोग करता है, यह मैटलैब कथनों को भी स्वीकार करने का प्रयास करता है और इसलिए समस्या दूसरे सिस्टम तक फैल जाती है।

प्री-प्रोसेसर स्पैन

यह इस स्तर पर है कि प्री-प्रोसेसर विकल्पों का प्रयोग किया जाता है, तथाकथित क्योंकि इन्हें कंपाइलर द्वारा आने वाले सौर्स को उचित रूप से प्रोसेस करने से पहले प्रयोग किया जाता है। वे असेंबलर सिस्टम के मैक्रो स्पैन विकल्पों को प्रतिध्वनित करते हैं, उम्मीद है कि अधिक दयालु सिंटेक्स के साथ। सबसे आम व्यवस्था पर एक भिन्नता है

यदि स्थिति तो यह सौर्स अन्यथा अन्य सौर्स फाई

अक्सर प्री-प्रोसेसर सोर्स स्टेटमेंट को सामान्य सोर्स स्टेटमेंट से अलग करने की कुछ व्यवस्था के साथ, जैसे कि pl/i, या # इत्यादि में % सिंबल से प्रारम्भ होने वाला स्टेटमेंट। एक और सरल विकल्प एक भिन्नता है

यह = वह परिभाषित करें

परन्तु सावधानी की जरूरत है, जैसे कि

SumXY = (x + y) को परिभाषित करें
योग:=3*SumXY;

चूँकि कोष्ठक के बिना, परिणाम sum:=3*x + y; इसी तरह, प्रतिस्थापन टेक्स्ट की सीमा निर्धारित करने और परिणामी टेक्स्ट को कैसे स्कैन किया जाएगा, यह निर्धारित करने में सावधानी बरतने की आवश्यकता है। विचार करना

#तीन परिभाषित करें = 3;
#पॉइंट परिभाषित करें = .;
#एक को परिभाषित करें = 1;
x:=तीन दशमलव एक;

यहां परिभाषित कथन को अर्धविराम द्वारा समाप्त किया जाता है, और अर्धविराम स्वयं प्रतिस्थापन का हिस्सा नहीं है। आह्वान नहीं हो सकता x:=threepointone; क्योंकि वह एक अलग नाम है, परन्तु three point one होगा 3 . 1 और पश्चात् का स्कैन उसे एकल टोकन के रूप में मानने में सक्षम हो भी सकता है और नहीं भी।

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

इसके अलावा, एक ही प्री-प्रोसेसर सिंटैक्स का उपयोग कई अलग-अलग रिप्रजेंटेशनओं, यहां तक ​​कि प्राकृतिक रिप्रजेंटेशनओं के लिए भी किया जा सकता है, जैसे किसी व्यक्ति के नाम, उपनाम, पालतू कुत्ते का नाम आदि का उपयोग करके कहानी टेम्पलेट से कहानी जनरेट करना और प्रलोभन होगा एक प्री-प्रोसेसर प्रोग्राम जनरेट करें जो सौर्स फ़ाइल को स्वीकार करेगा, प्री-प्रोसेसर क्रियाएं करेगा और अगले चरण, कंपाइलेशन के लिए जनरेट परिणाम को आउटपुट करेगा। परन्तु यह स्पष्ट रूप से सौर्स के माध्यम से कम से कम एक अतिरिक्त पास का गठन करता है और इसलिए ऐसा समाधान एकल-पास कंपाइलर के लिए अनुपलब्ध होगा। इस प्रकार, वास्तविक इनपुट सौर्स फ़ाइल के माध्यम से प्रगति फिट और स्टार्ट में अच्छी तरह से आगे बढ़ सकती है, परन्तु यह अभी भी यूनिडायरेक्शनल है।

लंबी दूरी का रेफेरेन्स

कंपाइलर द्वारा कोड जेनरेशन (कंपाइलर) को फॉरवर्ड रेफरेंस की समस्या का भी एनकाउंटर करना पड़ता है, सबसे सीधे तौर पर लेबल पर जाएं जैसे जहां गंतव्य लेबल सौर्स फ़ाइल में आगे एक अज्ञात दूरी है, और इस प्रकार जंप निर्देश उस लेबल के स्थान तक पहुंचने के लिए अभी तक उत्पन्न होने वाले कोड में एक अज्ञात दूरी सम्मिलित है। कुछ रिप्रजेंटेशन डिज़ाइन, संभवतः Consulted_harmful| से प्रभावित हैं हानिकारक माने जाने वाले GOTO में GOTO कथन नहीं होता है, परन्तु इससे समस्या नहीं सुलझती क्योंकि एक फंक्शन में कई अंतर्निहित GOTO समकक्ष होते हैं। विचार करना

यदि स्थिति है तो कोड सही है अन्यथा कोड गलत है

जैसा कि पहले उल्लेख किया गया है, स्थिति का बेसिक्यांकन करने के लिए कोड तुरंत उत्पन्न किया जा सकता है। परन्तु जब तत्कालीन टोकन का एनकाउंटर होता है, तो एक जम्पफाल्स ऑपरेशन कोड रखा जाना चाहिए जिसका गंतव्य पता कोड गलत कथनों के लिए कोड की शुरुआत है, और इसी तरह, जब अन्य टोकन का एनकाउंटर होता है, तो उसके लिए अभी-अभी पूरा किया गया कोड कोड ट्रू स्टेटमेंट के पश्चात् एक GOTO-स्टाइल जंप ऑपरेशन होना चाहिए जिसका गंतव्य वह कोड है जो if-स्टेटमेंट के अंत के पश्चात् आता है, यहां फाई टोकन द्वारा चिह्नित किया गया है। इन गंतव्यों को मात्र तब ही जाना जा सकता है जब अभी तक स्कैन न किए गए सौर्स के लिए मनमानी मात्रा में कोड उत्पन्न हो जाए। इसी तरह की समस्याएँ किसी भी कथन के लिए उत्पन्न होती हैं जिनके हिस्से सौर्स की मनमानी मात्रा तक फैले होते हैं, जैसे कि केस स्टेटमेंट।

एक रिकर्सिव-डिसेंट कंपाइलर प्रत्येक प्रकार के स्टेटमेंट के लिए एक प्रक्रिया को सक्रिय करेगा, जैसे कि इफ-स्टेटमेंट, जिसके बदले में कोड ट्रू और कोड गलत के स्टेटमेंट के लिए कोड उत्पन्न करने के लिए उचित प्रक्रियाओं को लागू किया जाएगा। इसके कथन के कुछ हिस्सों और इसी प्रकार अन्य कथनों के लिए उनके वाक्य-विन्यास के अनुसार। अपने लोकल स्टोरेज में यह अपने अपूर्ण जंपफाल्स ऑपरेशन के पता फ़ील्ड के स्थान का ट्रैक रखेगा, और इसके तत्कालीन टोकन का एनकाउंटर करने पर, अब ज्ञात पते को रखेगा, और इसी तरह 'के पश्चात् आवश्यक जंप के लिए फाई टोकन का एनकाउंटर करने पर 'कोड सत्य कोड। GoTo स्टेटमेंट इस मायने में भिन्न है कि जिस कोड पर जम्प किया जाना है वह उसके स्टेटमेंट फॉर्म के अंदर नहीं है, इसलिए फिक्सअप की एक सहायक तालिका में एक प्रविष्टि की आवश्यकता होती है जिसका उपयोग अंततः उसके लेबल के सामने आने पर किया जाएगा। इस धारणा को बढ़ाया जा सकता है. सभी अज्ञात-गंतव्य जंप एक जंप टेबल में एक प्रविष्टि के माध्यम से किए जा सकते हैं (जिनके पते पश्चात् में गंतव्यों के सामने आने पर भर दिए जाते हैं), हालांकि इस तालिका का आवश्यक आकार कंपाइलेशन के अंत तक अज्ञात है।

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

दुर्भाग्यपूर्ण निर्णय

हालाँकि ऊपर दिए गए विवरण में इस धारणा को नियोजित किया गया है कि कोड को पश्चात् में तय किए जाने के लिए छोड़े गए कुछ फ़ील्ड के साथ उत्पन्न किया जा सकता है, एक अंतर्निहित धारणा थी कि ऐसे कोड अनुक्रमों का आकार स्थिर था। यह मामला नहीं हो सकता है। कई कंप्यूटरों में अलग-अलग मात्रा में स्टोरेज लेने वाले ऑपरेशन के लिए प्रावधान होता है, स्पेशल रूप से सापेक्ष एड्रेसिंग, जिसके तहत यदि गंतव्य -128 या +127 एड्रेसिंग चरणों के भीतर है, तो आठ-बिट एड्रेस फ़ील्ड का उपयोग किया जा सकता है, अन्यथा पहुंचने के लिए बहुत बड़े एड्रेस फ़ील्ड की आवश्यकता होती है। . इस प्रकार यदि कोड एक आशाजनक संक्षिप्त पता फ़ील्ड के साथ उत्पन्न किया गया था, तो पश्चात् में वापस जाना और लंबे फ़ील्ड का उपयोग करने के लिए कोड को समायोजित करना आवश्यक हो सकता है, जिसके परिणामस्वरूप परिवर्तन के पश्चात् पहले कोड रेफेर स्थानों को भी समायोजित करना होगा। इसी तरह, परिवर्तन के दौरान पीछे की ओर जाने वाले पश्चात् के रिफरेन्स को भी ठीक करना होगा, यहां तक ​​कि वे भी जो ज्ञात पतों पर थे। और साथ ही, फिक्सअप जानकारी को स्वयं ही सही ढंग से ठीक करना होगा। दूसरी ओर, लंबे पते का उपयोग उन सभी मामलों के लिए किया जा सकता है जब निकटता निश्चित नहीं है, परन्तु परिणामी कोड अब आदर्श नहीं होगा।

वन-पास अनुक्रमिक इनपुट, अनियमित अनुक्रम आउटपुट

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

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

उपयोग से पहले घोषणा

विभिन्न एक्सप्रेशंस के लिए कोड बनाते समय, कंपाइलर को ऑपरेंड की प्रकृति जानने की आवश्यकता होती है। उदाहरण के लिए, एक कथन जैसे A:=B; ए और बी पूर्णांक हैं या फ़्लोटिंग-पॉइंट वैरिएबल (और कौन सा आकार: एकल, डबल या चौगुनी परिशुद्धता) या जटिल संख्या, सरणी, स्ट्रिंग, प्रोग्रामर-परिभाषित प्रकार इत्यादि के आधार पर अलग-अलग कोड उत्पन्न कर सकते हैं। इस मामले में, एक सरल दृष्टिकोण स्टोरेज के शब्दों की उचित संख्या को स्थानांतरित करना होगा, परन्तु, स्ट्रिंग्स के लिए यह अनुपयुक्त हो सकता है क्योंकि प्राप्तकर्ता आपूर्तिकर्ता से छोटा हो सकता है और किसी भी मामले में, स्ट्रिंग का मात्र एक हिस्सा उपयोग किया जा सकता है - शायद इसमें एक हजार अक्षरों के लिए जगह है, परन्तु वर्तमान में इसमें दस सम्मिलित हैं। फिर अधिक जटिल निर्माण भी हैं, जैसे कि COBOL और pl/i द्वारा प्रस्तावित A:=B by name; इस मामले में, ए और बी समुच्चय (या कंस्ट्रक्ट) हैं, उदाहरण के लिए ए में कुछ हिस्से हैं A.x, A.y और A.other जबकि बी के हिस्से हैं B.y, B.c और B.x, और उसी क्रम में. नाम सुविधा का अर्थ इसके समकक्ष है A.y:=B.y; A.x:=B.x; परन्तु क्योंकि B.c ए, और में कोई समकक्ष नहीं है A.other बी में कोई समकक्ष नहीं है, वे सम्मिलित नहीं हैं।

यह सब इस आवश्यकता से नियंत्रित किया जा सकता है कि वस्तुओं को उपयोग से पहले डिक्लेअर किया जाए। कुछ रिप्रजेंटेशनओं में स्पष्ट डिक्लेरेशन की आवश्यकता नहीं होती है, पहली बार किसी नए नाम का एनकाउंटर करने पर एक अंतर्निहित घोषणा उत्पन्न होती है। क्या फोरट्रान कंपाइलर को पहले से अज्ञात नाम का एनकाउंटर करना पड़ता है जिसका पहला अक्षर I, J,...,N में से एक है, तो चर एक पूर्णांक होगा, अन्यथा एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। इस प्रकार एक नाम DO12I एक फ़्लोटिंग-पॉइंट वैरिएबल होगा। यह एक सुविधा है, परन्तु गलत टाइप किए गए नामों के साथ कुछ अनुभवों के पश्चात्, अधिकांश प्रोग्रामर इस बात से सहमत हैं कि किसी भी अंतर्निहित कंपाइलर विकल्प का उपयोग नहीं किया जाना चाहिए।

अन्य प्रणालियाँ प्रकार तय करने के लिए पहली मुठभेड़ की प्रकृति का उपयोग करती हैं, जैसे कि एक स्ट्रिंग, या एक सरणी, इत्यादि। इंटरप्रिटेशन की गई रिप्रजेंटेशनएँ स्पेशल रूप से लचीली हो सकती हैं, निर्णय रन टाइम पर लिया जा सकता है, कुछ इस प्रकार

यदि स्थिति तो pi:= 3.14 अन्यथा pi:=3.14 fi;
पाई प्रिंट करें;

क्या ऐसी रिप्रजेंटेशन के लिए कोई कंपाइलर होना चाहिए, उसे वेरिएबल पाई का प्रतिनिधित्व करने के लिए एक जटिल यूनिट बनानी होगी, जिसमें यह संकेत होगा कि इसका वर्तमान प्रकार क्या है और ऐसे प्रकार का प्रतिनिधित्व करने के लिए संबंधित स्टोरेज होगा। यह निश्चित रूप से लचीला है, परन्तु गहन गणना के लिए सहायक नहीं हो सकता है जैसे कि A.x = b को हल करने में जहां A सौ क्रम का एक मैट्रिक्स है, और अचानक, इसका कोई भी तत्व एक अलग प्रकार का हो सकता है।

प्रक्रियाएँ और कार्य

उपयोग से पहले घोषणा भी प्रक्रियाओं और कार्यों के लिए एक आसान आवश्यकता है, और यह प्रक्रियाओं के भीतर प्रक्रियाओं के घोंसले पर भी लागू होती है। ALGOL, पास्कल, PL/I और कई अन्य की तरह, MATLAB और (1995 से) फोरट्रान एक फ़ंक्शन (या प्रक्रिया) को किसी अन्य फ़ंक्शन (या प्रक्रिया) की परिरिप्रजेंटेशन को सम्मिलित करने की अनुमति देते हैं, जो मात्र युक्त फ़ंक्शन के भीतर दिखाई देता है, परन्तु इन प्रणालियों के लिए आवश्यक है कि उन्हें युक्त प्रक्रिया के अंत के पश्चात् परिभाषित किया जाए।

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

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

मापदंडों के साथ एक प्रक्रिया (या फ़ंक्शन) के आह्वान के लिए, उनके प्रकार को जाना जाएगा (उन्हें उपयोग से पहले डिक्लेअर किया जाएगा) परन्तु प्रक्रिया के आह्वान में उनका उपयोग नहीं किया जा सकता है। उदाहरण के लिए, फोरट्रान सभी मापदंडों को रेफेरेन्स द्वारा (यानी पते द्वारा) पारित करता है, इसलिए कोड उत्पन्न करने में कोई तत्काल कठिनाई नहीं होती है (हमेशा की तरह, वास्तविक पते पश्चात् में तय किए जाएंगे), परन्तु पास्कल और अन्य रिप्रजेंटेशनएं विभिन्न तरीकों से मापदंडों को पारित करने की अनुमति देती हैं प्रोग्रामर की पसंद पर (बेसिक्यांकन रणनीति#रेफेरेन्स द्वारा कॉल करें, या बेसिक्यांकन रणनीति#बेसिक्य द्वारा कॉल करें, या शायद बेसिक्यांकन रणनीति#नाम से कॉल करें|नाम से) और यह मात्र प्रक्रिया की परिरिप्रजेंटेशन में दर्शाया गया है, जो इससे पहले अज्ञात है परिरिप्रजेंटेशन का एनकाउंटर करना पड़ा है. स्पेशल रूप से पास्कल के लिए, मापदंडों के विनिर्देश में एक उपसर्ग वार दर्शाता है कि इसे रेफेरेन्स द्वारा प्राप्त किया जाना चाहिए, इसकी अनुपस्थिति बेसिक्य से दर्शाती है। पहले मामले में कंपाइलर को कोड उत्पन्न करना होगा जो पैरामीटर के पते को पास करता है, जबकि दूसरे में उसे अलग कोड उत्पन्न करना होगा जो मान की एक प्रति को आमतौर पर स्टैक के माध्यम से पास करता है। हमेशा की तरह, इससे निपटने के लिए एक फिक्सअप तंत्र लागू किया जा सकता है, परन्तु यह बहुत गड़बड़ होगा। मल्टी-पास कंपाइलर निश्चित रूप से सभी आवश्यक जानकारी को एकत्रित कर सकते हैं क्योंकि वे आगे और पीछे शटल करते हैं, परन्तु सिंगल-पास कंपाइलर ऐसा नहीं कर सकते हैं। स्कैन के आगे बढ़ने पर कोड जनरेशन को रोका जा सकता है (और इसके परिणाम आंतरिक स्टोरेज में रखे जाएंगे) जब तक कि आवश्यक यूनिट का एनकाउंटर न हो जाए, और इसे सौर्स के माध्यम से दूसरी बार पास होने के परिणामस्वरूप नहीं माना जा सकता है क्योंकि कोड जनरेशन चरण होगा जल्द ही पकड़ लो, यह मात्र थोड़ी देर के लिए रुक रहा था। परन्तु यह जटिल होगा. इसके बजाय एक स्पेशल निर्माण प्रारम्भ किया गया है, जिसके तहत पैरामीटर उपयोग की प्रक्रिया की परिरिप्रजेंटेशन को इसकी पश्चात् की पूर्ण परिरिप्रजेंटेशन से पहले डिक्लेअर किया जाता है ताकि कंपाइलर इसे उपयोग से पहले जान सके, जैसा कि इसकी आवश्यकता है।

फर्स्ट फोरट्रान (1957) के पश्चात् से, एक फंक्शन के हिस्सों का अलग-अलग कंपाइलेशन संभव हो गया है, जो प्रक्रियाओं और कार्यों के पुस्तकालयों के निर्माण का समर्थन करता है। कंपाइल की जा रही सौर्स फ़ाइल में एक प्रक्रिया जो ऐसे बाहरी संग्रह से एक फ़ंक्शन को आमंत्रित करती है, उसे प्रकार जानना चाहिएअज्ञात फ़ंक्शन द्वारा लौटाए गए परिणाम का, यदि मात्र कोड उत्पन्न करना है जो परिणाम ढूंढने के लिए सही जगह पर दिखता है। बेसिक रूप से, जब मात्र पूर्णांक और फ़्लोटिंग-पॉइंट चर थे, तो विकल्प को अंतर्निहित घोषणा के नियमों पर छोड़ा जा सकता था, परन्तु आकार और प्रकारों के प्रसार के साथ आह्वान प्रक्रिया को फ़ंक्शन के लिए एक प्रकार की घोषणा की आवश्यकता होगी। यह कोई स्पेशल बात नहीं है, इसका स्वरूप प्रक्रिया के अंदर डिक्लेअर चर के समान ही है।

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

किसी प्रक्रिया (या फ़ंक्शन) के सभी आह्वानों की एक-दूसरे और उनकी परिरिप्रजेंटेशनओं के साथ अनुकूलता के लिए जाँच की जाती है या नहीं, यह एक अलग मामला है। अल्गोल-जैसी प्रेरणा से उत्पन्न रिप्रजेंटेशनओं में, यह जाँच आमतौर पर कठोर होती है, परन्तु अन्य प्रणालियाँ उदासीन हो सकती हैं। उन प्रणालियों को छोड़कर जो किसी प्रक्रिया को वैकल्पिक पैरामीटर रखने की अनुमति देते हैं, पैरामीटर की संख्या और प्रकार में गलतियाँ सामान्यतः प्रोग्राम के क्रैश होने का कारण बनेंगी। सिस्टम जो पूरे फंक्शन के हिस्सों के अलग-अलग कंपाइलेशन की अनुमति देते हैं, जिन्हें पश्चात् में एक साथ ऐड जाता है, उन्हें सही प्रकार और मापदंडों की संख्या और परिणामों की भी जांच करनी चाहिए क्योंकि गलतियाँ करना और भी आसान है, परन्तु अक्सर ऐसा नहीं होता है। कुछ रिप्रजेंटेशनओं (जैसे अल्गोल) में उन्नयन या स्पैन या पदोन्नति की औपचारिक धारणा होती है, जिसके तहत एक प्रक्रिया जो यह अपेक्षा करती है कि एक डबल-सटीक पैरामीटर को एकल परिशुद्धता चर के रूप में लागू किया जा सकता है, और इस मामले में कंपाइलर कोड उत्पन्न करता है जो एकल परिशुद्धता चर को एक टेम्पररी डबल-परिशुद्धता चर में संग्रहीत करता है जो वास्तविक पैरामीटर बन जाता है। हालाँकि, यह पैरामीटर पासिंग तंत्र को बेसिक्यांकन रणनीति#कॉपी-रिस्टोर|कॉपी-इन, कॉपी-आउट द्वारा कॉल में बदल देता है जिससे व्यवहार में सूक्ष्म अंतर हो सकता है। जब कोई प्रक्रिया एक एकल परिशुद्धता चर का पता प्राप्त करती है, जब वह दोहरे परिशुद्धता पैरामीटर, या अन्य आकार भिन्नताओं की अपेक्षा करती है, तो परिणाम बहुत कम सूक्ष्म होते हैं। जब प्रक्रिया के भीतर पैरामीटर का मान रीड जाता है, तो उसके दिए गए पैरामीटर की तुलना में अधिक संग्रहण रीड जाएगा और परिणामी मान में सुधार होने की संभावना नहीं है। इससे भी बदतर स्थिति तब होती है जब प्रक्रिया अपने पैरामीटर का मान बदल देती है: कुछ न कुछ क्षतिग्रस्त होना निश्चित है। इन गलतियों को खोजने और सुधारने में बहुत धैर्य खर्च किया जा सकता है।

पास्कल उदाहरण

ऐसे निर्माण का एक उदाहरण पास्कल (प्रोग्रामिंग रिप्रजेंटेशन) में आगे की घोषणा है। पास्कल के लिए आवश्यक है कि उपयोग से पहले सबरूटीन को डिक्लेअर या पूर्ण रूप से परिभाषित किया जाए। यह वन-पास कंपाइलर को उसके प्रकार की जाँच करने में मदद करता है: ऐसी प्रक्रिया को कॉल करना जिसे कहीं भी डिक्लेअर नहीं किया गया है, एक स्पष्ट त्रुटि है। उपयोग से पहले घोषणा नियम के बावजूद, आगे की घोषणाएं आपसी रिकर्सन प्रक्रियाओं को एक-दूसरे को सीधे कॉल करने में मदद करती हैं:

function odd(n : integer) : boolean;
begin
    if n = 0 then
        odd := false
    else if n < 0 then
        odd := even(n + 1) { Compiler error: 'even' is not defined }
    else
        odd := even(n - 1)
end;

function even(n : integer) : boolean;
begin
    if n = 0 then
        even := true
    else if n < 0 then
        even := odd(n + 1)
    else
        even := odd(n - 1)
end;

फ़ंक्शन के लिए एक अग्रेषित घोषणा जोड़कर even समारोह से पहले odd, वन-पास कंपाइलर को बताया जाता है कि इसकी एक परिरिप्रजेंटेशन होगी even पश्चात् में फंक्शन में.

function even(n : integer) : boolean; forward;

function odd(n : integer) : boolean;
  { Et cetera }

जब फ़ंक्शन के मुख्य भाग की वास्तविक घोषणा की जाती है, तो या तो पैरामीटर हटा दिए जाते हैं या बेसिक फ़ॉरवर्ड घोषणा के बिल्कुल समान होने चाहिए, या एक त्रुटि चिह्नित की जाएगी।

प्री-प्रोसेसर रिकर्सन

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

अग्रेषित घोषणाएँ हानिकारक मानी जाती हैं

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

यह भी देखें

रेफेरेन्स

  1. "सिंगल पास, टू पास और मल्टी पास कंपाइलर". GeeksforGeeks (in English). 2019-03-13. Retrieved 2023-05-15.