2012-11-20 14 views
7

मुझे स्टैक-आधारित प्रोग्रामिंग भाषा को लागू करके कंप्यूटर प्रोग्रामिंग के बारे में अपना ज्ञान विस्तार करने में दिलचस्पी है। मैं कहां से शुरू करना चाहता हूं, इस बारे में सलाह ले रहा हूं, क्योंकि मेरा इरादा "pushint 1" जैसे कार्यों के लिए है, जो "L01: jump L01:" जैसे लेबल के माध्यम से स्टैक और फ्लो-कंट्रोल के शीर्ष पर मान 1 के साथ एक पूर्णांक को धक्का देगा।मैं एक साधारण स्टैक-आधारित प्रोग्रामिंग भाषा को कार्यान्वित करने के बारे में कैसे जाउंगा

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

आखिरकार मैं सरणी और कार्यों को भी लागू करना चाहता हूं। इसके अलावा, मुझे लगता है कि मुझे बेहतर लेक्सर होना चाहिए और मैं सोच रहा हूं कि एक पार्सिंग-पेड़ ऐसी सरल भाषा के लिए एक अच्छा विचार होगा।

कोई सलाह/आलोचना का स्वागत है, और कृपया ध्यान दें कि मैं प्रोग्रामिंग के लिए अभी भी काफी नया हूं (मैंने अभी हाल ही में एपी कंपस्सी 1 पूरा किया है)। इसके अलावा, ओपन-सोर्स स्टैक-आधारित भाषाओं के लिंक का स्वागत है।

यहाँ एक बुनियादी कार्यक्रम है कि मैं कोशिश करते हैं और व्याख्या करने के लिए/संकलन चाहते हैं (जहां [this is a comment]):

[Hello World!] 
pushchar '\n' 
pushstring "Hello World!" 
print 
[Count to 5 and then count down!] 
pushint  1 
setlocal 0 
L01: 
pushchar '\n' 
getlocal 0 
print   [print x + '\n'] 
getlocal 0 
increment 
setlocal 0 [x = x + 1] 
pushint  5 
getlocal 0 
lessthan  [x < 5] 
iftrue  L01 
L02: 
pushchar '\n' 
getlocal 0 
print   [print x + '\n'] 
getlocal 0 
decrement 
setlocal 0 [x = x - 1] 
pushint  0 
getlocal 0 
greaterthan  [x > 0] 
iftrue  L02 

उम्मीद उत्पादन होगा:

Hello World! 
1 
2 
3 
4 
5 
4 
3 
2 
1 
+0

संयोग से, आपकी नई प्रोग्रामिंग भाषा का वाक्यविन्यास बहुत ही समान है [टैग: REBOL] प्रोग्रामिंग भाषा का वाक्यविन्यास। –

+0

@AndersonGreen यह वाक्यविन्यास वास्तव में एडोब एक्शनस्क्रिप्ट वर्चुअल मशीन 2 (एवीएम 2) के ऑपोड्स पर आधारित था। हालांकि Rebol दिलचस्प लग रहा है! – Wingpad

उत्तर

12

स्टैक आधारित जैसे भाषा Factor में निम्न वाक्यविन्यास है:

2 3 + 5 - print 

यह बराबर है निम्नलिखित सी स्टाइल कोड के प्रतिद्वंद्वी:

print(2 + 3 - 5); 

स्टैक आधारित भाषा का उपयोग करने का लाभ यह है कि इसे कार्यान्वित करना आसान है। इसके अलावा यदि भाषा reverse polish notation का उपयोग करती है, क्योंकि अधिकांश स्टैक आधारित भाषाएं होती हैं, तो आपको अपनी भाषा के front end की आवश्यकता होती है। आपको टोकन को वाक्यविन्यास पेड़ में पार्स करने की आवश्यकता नहीं है क्योंकि टोकन की धारा को डीकोड करने का केवल एक ही तरीका है।

जो आप बनाने की कोशिश कर रहे हैं वह एक स्टैक आधारित प्रोग्रामिंग भाषा नहीं है, लेकिन एक स्टैक आधारित virtual machine है। एप्लिकेशन वर्चुअल मशीन या तो stack based या register based हो सकती है। उदाहरण के लिए, Java Virtual Machine स्टैक आधारित है। यह Java bytecode निष्पादित करता है (जो आप बना रहे हैं - वर्चुअल मशीन के लिए बाइटकोड)। हालांकि प्रोग्रामिंग भाषाएं जो इस बाइटकोड को संकलित करती हैं (जैसे जावा, एरलांग, ग्रोवी, इत्यादि) ढेर आधारित नहीं हैं।

जो आप बनाने की कोशिश कर रहे हैं वह आपकी अपनी आभासी मशीन की असेंबली स्तर भाषा की तरह है, जो स्टैक आधारित होता है। ऐसा कहा जा रहा है कि ऐसा करना काफी आसान होगा - स्टैक आधारित आभासी मशीनें पंजीकृत आधारित वर्चुअल मशीनों को कार्यान्वित करना आसान होती हैं। दोबारा, आपको केवल flex जैसे लेक्सर की आवश्यकता है। यहाँ जावास्क्रिप्ट में एक छोटा सा उदाहरण एक पुस्तकालय lexer कहा जाता है का उपयोग कर रहा है:

var program = "[print(2 + 3)]"; 
 
program += "\n push 2"; 
 
program += "\n push 3"; 
 
program += "\n add"; 
 
program += "\n print"; 
 

 
lexer.setInput(program); 
 

 
var token; 
 
var stack = []; 
 
var push = false; 
 

 
while (token = lexer.lex()) { 
 
    switch (token) { 
 
    case "NUMBER": 
 
     if (push) stack.push(lexer.yytext); 
 
     else alert("Unexpected number."); 
 
     break; 
 
    case "ADD": 
 
     if (push) alert("Expected number."); 
 
     else stack.push(stack.pop() + stack.pop()); 
 
     break; 
 
    case "PRINT": 
 
     if (push) alert("Expected number."); 
 
     else alert(stack.pop()); 
 
     break; 
 
    } 
 

 
    push = token === "PUSH"; 
 
}
<script src="https://rawgit.com/aaditmshah/lexer/master/lexer.js"></script> 
 
<script> 
 
var lexer = new Lexer; 
 

 
lexer.addRule(/\s+/, function() { 
 
    // matched whitespace - discard it 
 
}); 
 

 
lexer.addRule(/\[.*\]/, function() { 
 
    // matched a comment - discard it 
 
}); 
 

 
lexer.addRule(/\d+/, function (lexeme) { 
 
    this.yytext = parseInt(lexeme); 
 
    return "NUMBER"; 
 
}); 
 

 
lexer.addRule(/push/, function() { 
 
    return "PUSH"; 
 
}); 
 

 
lexer.addRule(/add/, function() { 
 
    return "ADD"; 
 
}); 
 

 
lexer.addRule(/print/, function() { 
 
    return "PRINT"; 
 
}); 
 
</script>

यह वास्तव में आसान है। आप प्रोग्राम के साथ परेशान हो सकते हैं और इसे अपनी जरूरतों में संशोधित कर सकते हैं।शुभकामनाएँ।

+0

आपकी प्रतिक्रिया के लिए धन्यवाद, इसने इस मुद्दे के साथ मेरे प्रश्नों को स्पष्ट किया है। मैंने अब एक स्टैक-आधारित वीएम के कार्यान्वयन की शुरुआत की है! – Wingpad

2

मुझे लगता है कि आपको "मेटाआई" पर एक पेपर मिल जाएगा जो वास्तव में प्रबुद्ध है। यह दिखाता है कि पुशडाउन स्टैक कंपाइलर मशीन और इसके लिए एक कंपाइलर को 10 छोटे लेकिन दिमागी झुकाव पृष्ठों में कैसे परिभाषित किया जाए। यह उत्तर देखें: https://stackoverflow.com/a/1005680/120163 एक बार जब आप इसे समझ लेंगे, तो पुशडाउन स्टैक दुभाषिया लिखना हमेशा आसान होगा।

+0

इसके अलावा, आपके उत्तर के लिए धन्यवाद, मैं उस पेपर को पढ़ूंगा जिसे आपने लिंक किया था, उम्मीद है कि यह मदद करता है! – Wingpad

संबंधित मुद्दे

 संबंधित मुद्दे