कंपाइलर एक प्रकार की त्रुटि से कैसे ठीक होता है?


10

मैंने कई पेपर, लेख और अनुभाग 4.1.4, कंपाइलर के अध्याय 4 : सिद्धांत, तकनीक और उपकरण (2 डी संस्करण) (उर्फ "द ड्रैगन बुक") पढ़ा है, जो सभी वाक्य रचना संकलक त्रुटि सुधार के विषय पर चर्चा करते हैं। हालांकि, कई आधुनिक संकलक के साथ प्रयोग करने के बाद, मैंने देखा है कि वे सिमेंटिक त्रुटियों के साथ-साथ सिंटैक्टिक त्रुटियों से भी उबर जाते हैं।

मैं काफी अच्छी तरह से एल्गोरिदम और तकनीकों को संकलक संबंधित त्रुटियों से उबरने के पीछे समझ रहा हूं, हालांकि मैं यह बिल्कुल नहीं समझता कि एक संकलक एक त्रुटि से कैसे पुनर्प्राप्त कर सकता है।

मैं वर्तमान में अपने सार सिंटैक्स ट्री से कोड उत्पन्न करने के लिए विज़िटर पैटर्न की थोड़ी भिन्नता का उपयोग कर रहा हूं। निम्नलिखित अभिव्यक्तियों को संकलित करने वाले मेरे संकलक पर विचार करें:

1 / (2 * (3 + "4"))

कंपाइलर निम्नलिखित सार सिंटैक्स ट्री उत्पन्न करेगा:

      op(/)
        |
     -------
    /       \ 
 int(1)    op(*)
             |
          -------
         /       \
       int(2)   op(+)
                  |
               -------
              /       \
           int(3)   str(4)

कोड-जनरेशन चरण फिर विज़िटर पैटर्न का उपयोग करके सार सिंटैक्स ट्री की पुनरावृत्ति करेगा और प्रकार की जाँच करेगा। सार सिंटैक्स ट्री को तब तक ट्रेस किया जाएगा जब तक कि कंपाइलर अभिव्यक्ति के अंतरतम भाग में नहीं आ जाता; (3 + "4")। संकलक तब प्रत्येक पक्ष की जाँच करता है और देखता है कि वे शब्दार्थ के समकक्ष नहीं हैं। कंपाइलर एक प्रकार की त्रुटि उठाता है। यहीं पर समस्या है। अब कंपाइलर को क्या करना चाहिए ?

कंपाइलर को इस त्रुटि से उबरने के लिए और भावों के बाहरी हिस्सों को टाइप करते रहना है, इसे अभिव्यक्ति के अगले भाग के लिए , अभिव्यक्ति के अंतरतम भाग के मूल्यांकन से कुछ प्रकार ( intया str) वापस करना होगा । लेकिन यह बस एक प्रकार से वापस नहीं आता है । चूंकि एक प्रकार की त्रुटि हुई, कोई प्रकार नहीं घटाया गया था।

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

क्या मैं ऊपर वर्णित विधि का उपयोग करता हूं (मुझे संदेह है)। यदि हां, तो क्या यह कुशल नहीं है? यदि नहीं, तो कंपाइल शब्द त्रुटियों से उबरने के लिए वास्तव में क्या तरीके इस्तेमाल किए जाते हैं?


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

जवाबों:


8

आपका प्रस्तावित विचार अनिवार्य रूप से सही है।

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


3

एक दिलचस्प दृष्टिकोण त्रुटियों के लिए एक विशेष प्रकार है। जब ऐसी त्रुटि पहली बार सामने आती है, तो एक निदान लॉग किया जाता है, और त्रुटि प्रकार को अभिव्यक्ति के प्रकार के रूप में वापस किया जाता है। इस त्रुटि प्रकार में कुछ रोचक गुण हैं:

  • इस पर किया गया कोई भी ऑपरेशन सफल होता है (सभी एक ही मूल गलती के कारण त्रुटि संदेशों के एक झरना को रोकने के लिए)
  • किसी ऑब्जेक्ट पर त्रुटि प्रकार के साथ किए गए किसी भी ऑपरेशन का परिणाम भी त्रुटि प्रकार है
  • यदि कोड प्रकार के रूप में एक त्रुटि प्रकार प्राप्त होता है, तो कोड जनरेटर उपयोग को स्पॉट करता है और कोड उत्पन्न करता है जो विफल रहता है (जैसे एक अपवाद, गर्भपात, या जो भी आपकी भाषा के लिए उपयुक्त है) फेंकता है

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


उत्तर जूल्स के लिए धन्यवाद। काफी मजेदार है, यह सटीक विधि है जिसका मैंने उपयोग किया है। महान दिमाग एक जैसे लगते हैं, एह? ;-)
क्रिश्चियन डीन

2

यदि कोई शब्दार्थ त्रुटि है, तो एक संकलित त्रुटि संदेश जो यह दर्शाता है कि उपयोगकर्ता को जारी किया गया है।

एक बार जब यह हो जाता है, तो संकलन को समाप्त करना ठीक है क्योंकि इनपुट प्रोग्राम त्रुटि में है - यह भाषा में एक कानूनी कार्यक्रम नहीं है, इसलिए इसे बस अस्वीकार किया जा सकता है।

हालांकि, यह बहुत कठोर है, इसलिए नरम विकल्प हैं। किसी भी कोड पीढ़ी और आउटपुट फ़ाइल पीढ़ी को निरस्त करें, फिर भी अधिक त्रुटियों को देखने के लिए कुछ जारी रखें।

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


2

मान लें कि आपकी भाषा पूर्णांक जोड़ने की अनुमति देती है, और +ऑपरेटर के साथ तार के संयोजन की अनुमति देता है ।

चूंकि int + stringअनुमति नहीं है, इसलिए +वसीयत का मूल्यांकन करने में त्रुटि की सूचना दी जाएगी। कंपाइलर केवल प्रकार के रूप में वापस आ सकता हैerror । या यह अधिक चालाक हो सकता है, क्योंकि int + int -> intऔर string + string -> stringअनुमति दी जाती है, यह "त्रुटि, इंट या स्ट्रिंग हो सकता है" वापस आ सकता है।

फिर *ऑपरेटर आता है , और हम मान लेंगे कि केवल int + intअनुमति है। कंपाइलर तब तय कर सकता है कि +वास्तव में लौटने वाला था int, और किसी भी त्रुटि संदेश के बिना, *उसके बाद लौटा हुआ टाइप होगा int


मुझे लगता है कि मैं आपका अनुसरण करता हूं, @gnasher, लेकिन "" ऑपरेटर से आपका वास्तव में क्या मतलब है ? क्या वह टाइपो था?
क्रिश्चियन डीन

@ChristianDean के उद्धरणों में एक तारांकन चिह्न है जिसकी व्याख्या मार्कडाउन मार्कअप के रूप में की जा रही है।
जाकेरॉब

मैंने उत्तर के लिए एक संपादन प्रस्तुत किया है जो मेरे संपादन की समीक्षा किए जाते ही समस्या का समाधान कर देगा।
जाकेरोबब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.