2010-04-06 16 views
9

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

अब, सबकुछ अब तक स्पष्ट है (<>+-,.) - एक चीज़ को छोड़कर: लूप ([])। मुझे लगता है कि आप यहां से (अत्यंत कठिन) बीएफ वाक्य रचना पता:

  • मैं कैसे लागू करते हैं बीएफ मेरे दुभाषिया में लूप?

छद्म कोड कैसे दिख सकता है? जब दुभाषिया लूप शुरू होता है तो मुझे क्या करना चाहिए ([) या लूप एंड (])?

जांच की जा रही है, तो पाश जारी रखना चाहिए या रोक समस्या (current cell==0) नहीं है, लेकिन:

  • कब और कहाँ मैं जाँच करने के लिए है?
  • कैसे पता चलेगा कि लूप शुरुआत कहां स्थित है?
  • नेस्टेड लूप को कैसे संभालें?

चूंकि लूप को घोंसला किया जा सकता है, मुझे लगता है कि मैं केवल वर्तमान लूप की प्रारंभिक स्थिति वाले चर का उपयोग नहीं कर सकता।

मैंने विभिन्न भाषाओं में बहुत छोटे बीएफ दुभाषियों को लागू किया है, मुझे आश्चर्य है कि वे लूप काम करने में कैसे कामयाब रहे लेकिन इसे समझ नहीं पाए।

+1

डुप्लिकेट: http://stackoverflow.com/questions/1055758/creating-a-brainfk-parser-whats-the-best-method-of-parsing-loop-operators –

उत्तर

8

जब आप [ पर पहुंचते हैं, तो आप डेटा पॉइंटर का परीक्षण करते हैं।

यदि यह बात गलत है, तो आप अगले मिलान किया] चरित्र के लिए स्कैन तक की गिनती आप कितने [ देख सकते हैं और सुनिश्चित करें कि आप उन्हें बंद निशान के रूप में आप प्रत्येक ] देख बना सकते हैं।

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

जैसे ही आप आंतरिक लूप में घोंसला करते हैं, स्टैक प्रत्येक लूप के संदर्भ को स्पष्ट रूप से रिकॉर्ड करेगा।

stack (wikipedia) देखें। यह असेंबली प्रोग्राम फ़ंक्शन कॉल से कैसे निपटता है, यह समान है।

+0

मैं पहले से ही मेरे ढेर में बनाया गया था प्रोग्रामिंग भाषा तो यह बढ़िया है: डी – sub

1

मैं अपने दुभाषिया में बीएफ लूप कैसे कार्यान्वित करूं?

यह बात है - यह पूरी तरह से आपकी भाषा पर निर्भर करता है। एक स्टैक-आधारित प्रोग्रामिंग भाषा (या कोई भी भाषा जो स्टैक का उपयोग कर सकती है) के मामले में, @ आरजेएच ने एक अच्छा समाधान दिया है। अन्य भाषाएं अलग-अलग समाधानों का उपयोग करेंगी, जैसे रिकर्सन (यानी एक ढेर का निहित उपयोग)।

1

मेरे सिर के ऊपर से, यह में कुछ त्रुटियों हो सकता है, लेकिन कुछ इस तरह काम करना चाहिए:

char* interpret(char* instructions){ 
    char* c = instructions; 
    while (*c) { 
    if (*c == ".") putchar(*p); 
    else if (*c == ",") *p = getchar(); 
    else if (*c == '+') (*p)++; 
    else if (*c == '-') (*p)--; 
    else if (*c == '<') p--; 
    else if (*c == '>') p++; 
    else if (*c == '[') c = interpret(c+1); 
    else if (*c == ']') { if (*p) c = instructions else return c; } 
    c++; 
    } 
    return 0; 
} 

कॉल brainf * सी.के. स्रोत कोड के साथ व्याख्या। सूचक पी वर्तमान स्मृति स्थिति के लिए है। एक स्पॉट करते समय एक रिकर्सिव कॉल करें [। एक का सामना करते समय इस रिकर्सिव कॉल से वापस लौटें]।

+0

एचएम के उत्तर के लिए धन्यवाद .. केवल अगर यह कभी "]" से मुकाबला नहीं करता है, क्योंकि यदि ऐसा होता है, तो वह उस चरित्र का स्थान वापस कर देगा। लेकिन एक सेगफॉल्ट प्राप्त करना, भले ही यह अमान्य इनपुट के कारण हो, बहुत अच्छा नहीं है, नहीं :) एक बार फिर, समाधान का एक मोटा चित्र, स्पष्ट रूप से एक निर्दोष नहीं। – Jakob

+0

ओह ठीक है, मुझे याद आया। मैंने अपनी टिप्पणी हटा दी। – sepp2k

0

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

5

यहां दुभाषिया का मेरा "अनुकूलन" संस्करण है, जो लूप कूदता है।

def interpret2(code): 
    data = [0] * 5000 # data memory 
    cp = 0    # code pointer 
    dp = 0    # data pointer 
    # pre-compile a jump table 
    stack = [] 
    jump = [None] * len(code) 
    for i,o in enumerate(code): 
     if o=='[': 
      stack.append(i) 
     elif o==']': 
      jump[i] = stack.pop() 
      jump[jump[i]] = i 
    # execute 
    while cp < len(code): 
     cmd = code[cp] 
     if cmd == '>': dp += 1 
     elif cmd == '<': dp -= 1 
     elif cmd == '+': data[dp] += 1 
     elif cmd == '-': data[dp] -= 1 
     elif cmd == '.': stdout.write(chr(data[dp])) 
     elif cmd == ',': data[dp] = ord(stdin.read(1)) 
     elif cmd == '[' and not data[dp]: # skip loop if ==0 
      cp = jump[cp] 
     elif cmd == ']' and data[dp]:  # loop back if !=0 
      cp = jump[cp] 
     cp += 1 

यह कोड का एक सूखा रन करता है, कोष्ठक (एक ढेर में) का ट्रैक रखने और समानांतर jump सरणी जो बाद में निष्पादन के दौरान विचार-विमर्श किया जाता है में गोटो पतों चिह्नित करता है।

मैंने लंबे समय से चलने वाले बीएफ कार्यक्रम (पीआई के एन अंकों की गणना) पर निष्पादन की गति की तुलना की और यह एक निर्दोष कार्यान्वयन की तुलना में गति 2x में वृद्धि हुई जिसमें स्रोत से बाहर निकलने के लिए आगे स्कैन किया गया है [और पीछे की तरफ स्कैन किया गया]।

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