2011-01-16 11 views
6

में तारों की एक सूची को जोड़ना मैं एक लिस्प को सी अनुवादक लिख रहा हूं और मुझे तारों को संभालने में समस्या है।प्रोलॉग

define(F) --> fun_unary(F), !. 

fun_unary(F) --> "(define (", label(Fun), spaces, label(Arg1), ")", spaces, expr(Body), ")", 
    {swritef(F, "data *%t(data *%t) { return(%t); }", [Fun, Arg1, Body])}, !. 


funs([F]) --> define(F), !. 
funs([F|Fs]) --> define(F), spaces, funs(Fs), !. 

अब मैं कार्यों के किसी भी संख्या पढ़ सकते हैं और उन्हें एक ही स्ट्रिंग के रूप में वापस करना चाहते: यह एक कोड एक सी बराबर करने के लिए एक एकल लिस्प समारोह बदल देती है। ऊपर funs सबसे अच्छा मैं के साथ आ सकता है, लेकिन यह इस तरह काम करता है:

?- funs(F, "(define (carzero l) (= (car l) 0)) (define (zero n) (= 0 n))", []). 
F = ["data *carzero(data *l) { return(eq(car(l), make_atom_int(0))); }", "data *zero(data *n) { return(eq(make_atom_int(0), n)); }"]. 

मैं कुछ इस तरह चाहते हैं जबकि:

F = "data *carzero(data *l) { return(eq(car(l), make_atom_int(0))); }\n\ndata *zero(data *n) { return(eq(make_atom_int(0), n)); }". 

ताकि मैं अच्छी तरह से कर सकते हैं swritef एक पूरा कार्यक्रम में है , #include एस और मुख्य() के बीच। एक वैकल्पिक समाधान सूची को संभालने के लिए उच्चतम स्तर अनुवादक को संशोधित करना है। यह ठीक से इस तरह दिखता है:

program(P) --> define(F), {swritef(P, "#include \"lisp2c.h\" \n\n%t \nint main() { return 0; }", [F])}, !. 

मैं इन दोनों में से कोई भी कैसे करूं? मैं एसडब्ल्यूआई प्रोलॉग का उपयोग कर रहा हूं।

+0

विषय पंक्ति का उल्लेख है Prolog जबकि के शरीर सवाल "लिस्प टू सी" अनुवाद के बारे में पूछता है। मुझे यह पता लगाने में सहायता करें कि यहां क्या है। कोड स्निपेट प्रोलॉग की तरह थोड़ा दिखते हैं, शायद इसलिए क्योंकि विशेष डीसीजी वाक्यविन्यास नियमों के लिए प्रोलॉग के अधिक बुनियादी वाक्यविन्यास के साथ भ्रमित हो रहा है। जबकि विषय पंक्ति "प्रोलॉग में तारों की एक सूची" के बारे में पूछती है, ऐसा लगता है कि लिस्प कोड शामिल स्ट्रिंग्स का विश्लेषण करता है। स्ट्रिंग्स की सूची का संबंध प्रोलॉग में अपेक्षाकृत सरल कार्य है। आपका उदाहरण भविष्यवाणी ** मजेदार/2 ** सुझाव देता है कि आप कुछ नए अक्षरों के पात्रों में फेंकना चाहते हैं ... – hardmath

+0

... लगातार तारों को संयोजित किया जा रहा है। यदि यह प्रश्न का दायरा है, तो मैं इसका उत्तर दे सकता हूं, और हम वाक्यविन्यास के भ्रम को हल कर सकते हैं (यदि आवश्यक हो)। – hardmath

+0

लिस्प से सी अनुवाद यह है कि कार्यक्रम क्या करता है। कार्यक्रम व्यक्तिगत मामलों का अनुवाद करने के लिए डीसीजी वाक्यविन्यास का उपयोग करते हुए प्रोलॉग में लिखा गया है। अधिकांश अनुमानित पार्स लिस्प कोड, उनके तर्क के परिणामस्वरूप सी कोड है। मैं concatenated तारों के बीच दो newlines चाहता हूँ। उम्मीद है कि यह है। – Igor

उत्तर

4

अब उद्देश्य के लिए इसे आवश्यक है के लिए अलग स्थापना, के एक Prolog विधेय है कि एक स्ट्रिंग में स्ट्रिंग की एक सूची, कोनकैटेनेट्स तार के प्रत्येक लगातार जोड़ी के बीच एक डबल न्यू लाइन रखने लिखने (लेकिन के अंत में नहीं जाने जेरी पोस्ट किए गए उदाहरण के आधार पर आउटपुट स्ट्रिंग)।

SWI-Prolog मैनुअल: आम तौर पर मैं the documentation करने के लिए "गहरा" लिंक पोस्ट चाहते हैं, लेकिन SWI-Prolog साइट यूआरएल की एक शैली है कि कई ब्राउज़र/प्लगइन संयोजनों के साथ क्रॉस-साइट स्क्रिप्टिंग (XSS) चेतावनी चलाता है का उपयोग करता है । तो इसके बजाय मैं उचित सेक्शन के लिंक से संदर्भित करूंगा।

धारा 4.22 तारों में पाठ का प्रतिनिधित्व करना (भाग में) कहता है, "डिफ़ॉल्ट रूप से स्ट्रिंग ऑब्जेक्ट्स में कोई व्याख्यात्मक प्रतिनिधित्व नहीं होता है और इस प्रकार केवल नीचे या विदेशी भाषा इंटरफ़ेस के माध्यम से भविष्यवाणियों का उपयोग करके बनाया जा सकता है।" यह थोड़ा उलझन में हो सकता है, क्योंकि एसडब्ल्यूआई-प्रोलॉग स्ट्रिंग को डबल-उद्धृत टेक्स्ट के रूप में लिखता है, लेकिन चरित्र कोड की सूचियों के रूप में डबल-उद्धृत टेक्स्ट (डिफ़ॉल्ट रूप से) पढ़ता है।

strSepCat([ ],_,Empty) :- 
    string_to_list(Empty,[ ]). 
strSepCat([H|T],Separator,StrCat) :- 
    strSepCat(T,Separator,H,StrCat). 

strSepCat([ ],_,StrCat,StrCat). 
strSepCat([H|T],Sep,Str,Cat) :- 
    string_concat(Sep,H,SepH), 
    string_concat(Str,SepH,StrSepH), 
    strSepCat(T,Sep,StrSepH,Cat). 

ध्यान दें कि हम दो विधेय, strSepCat/3 और परिभाषित किया है:

यहाँ एक विधेय है कि एक सूची में तार, कोनकैटेनेट्स लगातार स्ट्रिंग जोड़े के बीच में एक और स्ट्रिंग सेपरेटर डालने के लिए कोड है strSepCat/4। पूर्व को बाद के शब्दों में परिभाषित किया गया है, प्रोलॉग में एक विशिष्ट डिजाइन पैटर्न जो एक संचयक के रूप में अतिरिक्त तर्क प्रस्तुत करता है जो रिकर्सन पूर्ण होने पर आउटपुट से जुड़ता है। tail recursive परिभाषा प्राप्त करने में ऐसी तकनीक अक्सर सहायक होती है।

विधेय strSepCat/3 का उपयोग करने के लिए, हम आम तौर पर (के लिए एस्केप अनुक्रम) दो नई-पंक्तियों के साथ विभाजक स्ट्रिंग के निर्माण के लिए आवश्यकता होगी:,

?- funs(Fs,Lisp,[ ]), string_to_list(Sep,"\n\n"), strSepCat(Fs,Sep,CProg). 
1

Prolog में तार के बाद से वास्तव में चरित्र कोड की सूची कर रहे हैं, आपको लगता है कि यह भी नई-पंक्तियों सम्मिलित करता है एक कस्टम विधेय में append उपयोग कर सकते हैं:

concat_program([], ""). 
concat_program([L|Ls], Str) :- 
    concat_program(Ls, Str0), 
    append("\n\n", Str0, Str1), 
    append(L, Str1, Str). 

उपयोग:

funs(Fs, Lisp, []), 
concat_program(Fs, P), 
write("#include ...\n"), 
writef(P). 
+0

मज़ेदार (एफ, "(परिभाषित (शून्य x) 0) (परिभाषित करें (एक एन) 1)", []), concat_program (एफ, एक्स)। गलत है। – Igor

+0

'एफ = [" डेटा * कारज़रो (डेटा * एल) {वापसी (ईक (कार (एल), make_atom_int (0)));} "," डेटा * शून्य (डेटा * एन) {वापसी (eq (make_atom_int (0), एन));} "], concat_program (एफ, एक्स)। 'काम करता है। मैं नहीं देख सकता कि आपके शेष कोड में क्या गलत है क्योंकि आपने पूर्ण व्याकरण नहीं दिया है। –

+0

सामान्य विचार सही है लेकिन मुझे लगता है कि "प्रोलॉग में तार वास्तव में वर्ण कोड की सूचियां हैं" उपयोग में प्रोलॉग कार्यान्वयन के लिए दोषपूर्ण हो सकता है। एसडब्ल्यूआई-प्रोलॉग स्ट्रिंग्स और कॉन्सटेनेशन के लिए यह चर्चा देखें: http://www.sci.hkbu.edu.hk/scilab/doc/prolog/sec-3.20.html – hardmath

2

के बारे में क्या DCG अंकन का उपयोग तारों को जोड़ने के लिए?

concat([]) --> []. 
concat([List|Lists]) --> List, "\n\n", concat(Lists). 
संबंधित मुद्दे