नोट: जब मैंने शीर्षक में "जटिल" का उपयोग किया था, तो मेरा मतलब है कि अभिव्यक्ति में कई ऑपरेटर और ऑपरेंड हैं। ऐसा नहीं है कि अभिव्यक्ति ही जटिल है।
मैं हाल ही में x86-64 विधानसभा के लिए एक साधारण संकलक पर काम कर रहा हूँ। मैंने संकलक के मुख्य सामने के छोर - लेसर और पार्सर को समाप्त कर दिया है - और अब मैं अपने प्रोग्राम का एक सार सिंटैक्स ट्री प्रतिनिधित्व उत्पन्न करने में सक्षम हूं। और जब से मेरी भाषा सांख्यिकीय रूप से टाइप की जाएगी, मैं अब अगला चरण कर रहा हूं: स्रोत कोड की जांच कर रहा हूं। हालांकि, मैं एक समस्या पर आया हूं और इसे स्वयं हल करने में सक्षम नहीं हो पाया हूं।
निम्नलिखित उदाहरण पर विचार करें:
मेरे संकलक के पार्सर ने कोड की यह पंक्ति पढ़ी है:
int a = 1 + 2 - 3 * 4 - 5
और इसे निम्नलिखित एएसटी में बदल दिया:
=
/ \
a(int) \
-
/ \
- 5
/ \
+ *
/ \ / \
1 2 3 4
अब इसे एएसटी की जांच करना होगा। यह पहले प्रकार से =
ऑपरेटर की जाँच करके शुरू होता है । यह पहले ऑपरेटर के बाएँ हाथ की जाँच करता है। यह देखता है कि चर a
को पूर्णांक के रूप में घोषित किया गया है। इसलिए अब यह सत्यापित करना चाहिए कि दाहिने हाथ की अभिव्यक्ति पूर्णांक का मूल्यांकन करती है।
मुझे समझ में आया कि अगर अभिव्यक्ति सिर्फ एक मूल्य थी, जैसे कि 1
या यह कैसे किया जा सकता है 'a'
? लेकिन यह कई मूल्यों और ऑपरेंड्स के साथ अभिव्यक्ति के लिए कैसे किया जाएगा - एक जटिल अभिव्यक्ति - जैसे कि ऊपर वाला? अभिव्यक्ति के मूल्य को सही ढंग से निर्धारित करने के लिए, ऐसा लगता है कि प्रकार चेकर को वास्तविक रूप से अभिव्यक्ति को निष्पादित करना होगा और परिणाम रिकॉर्ड करना होगा। लेकिन यह स्पष्ट रूप से संकलन और निष्पादन चरणों को अलग करने के उद्देश्य को हराने के लिए लगता है।
एकमात्र ऐसा तरीका है जिसकी मैं कल्पना करता हूं कि यह किया जा सकता है कि एएसटी में प्रत्येक सबप्रेप्रेशन की पत्ती की पुनरावृत्ति की जाँच करें और पत्ती के सभी प्रकारों को सत्यापित ऑपरेटर प्रकार से सत्यापित करें। तो =
ऑपरेटर के साथ शुरू , टाइप चेकर फिर बाएं हाथ की एएसटी के सभी स्कैन करेगा और सत्यापित करेगा कि लीफ़ सभी पूर्णांक हैं। यह तब उपप्रकार में प्रत्येक ऑपरेटर के लिए इसे दोहराएगा।
मैंने "द ड्रैगन बुक" की अपनी प्रति में विषय पर शोध करने की कोशिश की है , लेकिन यह बहुत विस्तार से नहीं लगता है, और बस वही दोहराता है जो मैं पहले से जानता हूं।
जब एक कंपाइलर कई ऑपरेटर और ऑपरेंड के साथ अभिव्यक्ति की जाँच कर रहा होता है, तो सामान्य विधि का क्या उपयोग किया जाता है? क्या मैं ऊपर बताए गए किसी भी तरीके का इस्तेमाल कर रहा हूं? यदि नहीं, तो क्या तरीके हैं और वे वास्तव में कैसे काम करेंगे?
double a = 7/2
दाईं ओर के हिस्से को दोहरे के रूप में व्याख्या करने की कोशिश करेगा, इसलिए अंश और हर को दो के रूप में व्याख्या करने की कोशिश करेगा और यदि आवश्यक हो तो उन्हें परिवर्तित कर सकता है; परिणामस्वरूप a = 3.5
। बॉटम-अप पूर्णांक विभाजन का प्रदर्शन करेगा और केवल अंतिम चरण (असाइनमेंट) पर परिवर्तित होगा a = 3.0
।
int a = 1 + 2 - 3 * 4 - 5
लेकिनint a = 5 - ((4*3) - (1+2))