सी

2010-07-21 2 views
7

के सबसेट के लिए एक स्टैक आधारित आभासी मशीन को कार्यान्वित करना हैलो हर कोई मैं वर्तमान में सीखने के अनुभव के लिए एक सरल प्रोग्रामिंग भाषा लागू कर रहा हूं लेकिन मुझे कुछ सलाह की आवश्यकता है। वर्तमान में मैं अपने इंटरप्रेटर को डिजाइन कर रहा हूं और मैं एक समस्या में आया हूं।सी

मेरी भाषा सी का सबसेट है और मुझे स्टैक दुभाषिया कार्यान्वयन के बारे में कोई समस्या है। भाषा में निम्नलिखित संकलन होगा:

somefunc() 
{ 
    1 + 2; 
} 

main() 
{ 
    somefunc(); 
} 

अब यह ठीक है, लेकिन जब "1 + 2" की जाती है परिणाम एक ढेर पर धकेल दिया जाता है और फिर समारोह रिटर्न लेकिन अभी भी ढेर पर एक नंबर है, और वहाँ नहीं होना चाहिए। मैं इस समस्या के आसपास कैसे हो सकता हूं?

मैंने फ़ंक्शन कॉल से पहले स्टैक के "राज्य" को सहेजने और फ़ंक्शन कॉल के बाद "स्थिति" को पुनर्स्थापित करने के बारे में सोचा है। उदाहरण के लिए स्टैक पर तत्वों की संख्या को सहेजना, फिर फ़ंक्शन कोड निष्पादित करें, वापसी करें, और उसके बाद स्टैक से पॉप करें जब तक कि हमारे पास पहले की तरह तत्वों की संख्या न हो (या यदि फ़ंक्शन कुछ लौटाया गया हो तो +1 हो सकता है)।

कोई विचार? किसी भी सुझाव के लिए धन्यवाद!

उत्तर

8

शानदार सवाल! मेरे शौक में से एक खिलौना भाषाओं के लिए कंपाइलर्स लिख रहा है, इसलिए आपके उत्कृष्ट प्रोग्रामिंग स्वाद के लिए कुडोस।

एक अभिव्यक्ति कथन वह जगह है जहां कथन में कोड बस एक अभिव्यक्ति है। इसका अर्थ है <expression> ; फॉर्म में से कुछ, जिसमें असाइनमेंट और फ़ंक्शन कॉल जैसी चीजें शामिल हैं, लेकिन if एस, while एस, या return एस नहीं है। किसी भी अभिव्यक्ति कथन के अंत में स्टैक पर एक मूल्य से अधिक मूल्य होगा, जिसे आपको त्यागना चाहिए।

1 + 2 एक अभिव्यक्ति बयान है, लेकिन इतना ये हैं:

  • x = 5;
    काम अभिव्यक्ति एक काम का परिणाम के बाद से स्टैक पर मूल्य 5 पत्ते बाईं का मूल्य है हाथ ऑपरेंड बाद बयान समाप्त हो गया है आप अप्रयुक्त मूल्य 5.

  • printf("hello world!\n");
    printf() वर्ण उत्पादन की संख्या रिटर्न बंद पॉप। आपके पास स्टैक पर यह मान शेष होगा, इसलिए कथन समाप्त होने पर इसे पॉप करें।

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

+0

इसका मजाकिया आप नाम है क्योंकि मेरे एएसटी प्रतिनिधित्व में मेरे पास सिर्फ "ASTStmtExpr" नामक एक नोड है! मुझे लगता है कि मुझे समझना शुरू हो रहा है, इस प्रकार ... यहां मैं क्या अनिश्चित हूं: इन टिप्पणी उत्तरों की सीमाओं के कारण मेरे पास है एक snipplet पेस्ट करने के लिए: \t शून्य संकलक :: यात्रा (स्थिरांक ASTStmtExpr और expr_stmt, std :: shared_ptr समारोह) \t \t { \t \t \t expr_stmt.expr() -> स्वीकार (* इस, समारोह); \t \t} आप कह रहे हैं कि मुझे इसके बाद एक OP_POP जोड़ना चाहिए, और असाइनमेंट जैसी चीजों के लिए मैं एक डमी "नील" ऑब्जेक्ट दबा दूंगा ताकि फिर पॉप हो जाए? –

+0

क्षमा करें मुझे नहीं पता था कि टिप्पणियां प्रारूपित नहीं हैं –

+1

असाइनमेंट के लिए, आप डमी मान को धक्का नहीं देते हैं, क्योंकि आपके पास पहले से ही स्टैक पर असाइनमेंट का परिणाम होगा। एक असाइनमेंट '= 'ऑपरेटर का उपयोग करके सिर्फ एक अभिव्यक्ति है, जो' + 'या' -' से अलग नहीं है, इसके अलावा' = 'को एक चर को असाइन करने का दुष्प्रभाव होता है। अन्यथा यह अन्य सभी ऑपरेटरों की तरह व्यवहार करता है। –

2

आपको एक बेहतर पार्सर की आवश्यकता होगी। जब आप एक अभिव्यक्ति देखते हैं जिसका मूल्य उपयोग नहीं किया जा रहा है तो आपको एक पीओपी उत्सर्जित करने की आवश्यकता है।

+0

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

0

यह अनुकूलन सीखने पर एक महत्वपूर्ण अवसर है। आपके पास एक ऐसा फ़ंक्शन है जो संख्या पूर्णांक गणित करता है, int गणित का परिणाम किसी भी रूप, आकार या फ़ॉर्म में भी उपयोग नहीं किया जाता है।

आपके कंपाइलर को फ़ंक्शन को अनुकूलित करने के बाद बाइटकोड उत्पन्न होने और कुछ भी नहीं के लिए निष्पादित किया जाएगा!