मैं एक पंक्ति को पढ़ने का तरीका जानने के लिए GNU Prolog दस्तावेज़ पढ़ रहा हूं एक end_of_file परमाणु तक पहुंचने तक इनपुट का। इस तरह के लक्ष्य को लिखने के लिए मेरा छद्म कोड यहां दिया गया है:

read_until_end(Chars, Out):
   if peek_char unifies with end_of_file, Out = Chars
   otherwise, get the current character, add it to a buffer, and keep reading

मैंने इसे इस तरह कार्यान्वित किया:

read_until_end(Chars, Out) :-
    peek_char(end_of_file) -> Out = Chars;
    peek_char(C) -> read_until_end([C | Chars], Out).

prompt(Line) :-
    write('> '),
    read_until_end([], Line).

यहाँ आरईपीएल में क्या होता है:

| ?- prompt(Line).
> test

Fatal Error: global stack overflow (size: 32768 Kb, reached: 32765 Kb, environment variable used: GLOBALSZ)

अगर मैं read_until_end की दूसरी शाखा के लिए C का प्रिंट आउट लेता हूं, तो मैं देख सकता हूं कि peek_char हमेशा मुझे एक ही वर्ण 'b' देता है। मुझे लगता है कि मुझे किसी प्रकार के इनपुट कैरेक्टर इंडेक्स या ऐसा कुछ प्रगति करने का एक तरीका चाहिए, लेकिन मुझे दस्तावेज़ीकरण में ऐसा करने का कोई तरीका नहीं मिल रहा है। अगर मुझे कोई रास्ता पता था, तो शायद मुझे ऐसे पॉइंटर की प्रगति के लिए रिकर्सन का उपयोग करना होगा, क्योंकि मेरे पास कोई परिवर्तनीय स्थिति नहीं हो सकती है, लेकिन इसके अलावा, मुझे नहीं पता कि क्या करना है। क्या किसी के पास कोई सलाह है?

0
Caspian Ahlberg 22 पद 2020, 00:49

1 उत्तर

सबसे बढ़िया उत्तर

आप अगला वर्ण प्राप्त करने के लिए peek_char/1 का उपयोग कर रहे हैं, लेकिन वह विधेय धारा से वर्ण का उपभोग नहीं करता है (यह केवल धारा को "झांकता है")। इसलिए आपके कोड में एक अनंत रिकर्सन होता है जो वैश्विक स्टैक ओवरफ़्लो के साथ समाप्त होता है।

आपको get_char/1 का उपयोग स्ट्रीम से चरित्र को पढ़ने और उपभोग करने के लिए करना चाहिए, और reverse/2 एकत्रित वर्णों की सूची:

read_until_end(Chars, Out) :-
    get_char(Char),
    (
     Char = end_of_file -> reverse(Chars, Out)
    ;
     read_until_end([Char | Chars], Out)
    ).

सूची को उलटने की आवश्यकता से बचने के लिए आप सूची को क्रम में बनाने के लिए अपनी प्रक्रियाओं को थोड़ा संशोधित कर सकते हैं (एक संचयक का उपयोग किए बिना):

read_until_end(Output) :-
    get_char(Char),
    (
     Char = end_of_file -> Output=[]
    ;
     (
       Output=[Char|NOutput],
       read_until_end(NOutput)
     )
    ).

prompt(Line) :-
    write('> '),
    read_until_end(Line).
3
gusbro 22 पद 2020, 07:11