2012-10-12 22 views
7

किसी ने मुझे कुछ मदद की वाक्य रचना के साथ भाषा के लिए एक ocaml दुभाषिया के निर्माण दे सकते हैं:ocaml दुभाषिया

Prog ::= Def* Expr 
Def ::= id id* = Expr 
Expr ::= int | id | Expr '+' Expr | Expr '*' Expr | id Expr* | if Expr then Expr else Expr 

अब तक मैं इस किया था:

type expr = I of int 
| Id of string 
| Add of expr * expr 
| Multiply of expr * expr 
| If of expr * expr * expr 

let rec evaluate = function 
| I n -> n 
| Add(e1,e2) -> evaluate e1 + evaluate e2 
| Multiply(e1,e2) -> evaluate e1 * evaluate e2 
| If(a,b,c) -> if evaluate a<>0 then evaluate b else evaluate c 

यह किसी भी अच्छा है?

उत्तर

6

आपके व्याकरण में एक आईडी को या तो उत्पादन Expr ::= id या Expr ::= id Expr* से मिलान किया जा सकता है। दूसरे शब्दों में, एक नाली फ़ंक्शन एप्लिकेशन के बीच अंतर करने का कोई तरीका नहीं है (id Expr* उत्पादन को फ़ंक्शन एप्लिकेशन से मिलान करना चाहिए) और चर। हो सकता है कि आप इसके बजाय id Expr+ (नलिका फ़ंक्शन एप्लिकेशन को अस्वीकार कर दें)।

आपका मौजूदा कोड ठीक लग रहा है, लेकिन यह अधूरा है:

आपका expr प्रकार व्याकरण के id Expr* उत्पादन के लिए एक निर्माता याद आ रही है, यानी आप एक निर्माता है कि समारोह अनुप्रयोगों का प्रतिनिधित्व करता है खो रहे हैं। आपको एक जोड़ना चाहिए और उसके बाद evaluate फ़ंक्शन पर इसके लिए एक केस जोड़ना चाहिए।

आपके evaluate फ़ंक्शन में आप Id कन्स्ट्रक्टर के लिए एक केस खो रहे हैं। उस मामले को पहचानकर्ताओं से मूल्यों (इन्ट्स) तक मैपिंग में दिए गए पहचानकर्ता के मान को देखना चाहिए। इसके अंत में आपके evaluate फ़ंक्शन को अतिरिक्त तर्क के रूप में ऐसा मैपिंग लेना चाहिए। इसे पहचानकर्ताओं से कार्यों में एक और मैपिंग भी लेनी चाहिए, जिसे आप फ़ंक्शन एप्लिकेशन के मामले में फ़ंक्शन नामों को लूप करने के लिए उपयोग कर सकते हैं।

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

फिर आपको एक ऐसा फ़ंक्शन लिखना चाहिए जो परिभाषाओं की एक सूची लेता है और चर और कार्यों के लिए मैपिंग बनाता है। प्रत्येक परिवर्तनीय परिभाषा के लिए इसे दाईं ओर अभिव्यक्ति का मूल्यांकन करना चाहिए और परिणामी मानों को अपने चर मैपिंग में जोड़ना चाहिए। प्रत्येक फ़ंक्शन परिभाषा के लिए, आपको फ़ंक्शन मैपिंग में अपने फ़ंक्शन प्रकार का मान जोड़ना चाहिए। परिभाषाओं को संसाधित करने के बाद, आपको उस अभिव्यक्ति के साथ अपने evaluate फ़ंक्शन और तर्कों के रूप में बनाए गए दो मैपिंग को कॉल करके अंतिम अभिव्यक्ति का मूल्यांकन करना चाहिए।

अंततः आपके पास प्रोग्राम को पार्स करने के लिए कोई कोड नहीं है, लेकिन मुझे लगता है कि यह जानबूझकर हो सकता है।

+0

क्या आप मुझे परिभाषाओं की प्रक्रिया का प्रतिनिधित्व करने के लिए कोड का एक उदाहरण दिखा सकते हैं? मुझे पार्सिंग के लिए कोड की आवश्यकता नहीं है, और मैंने आईडी कन्स्ट्रक्टर को नहीं लिखा है क्योंकि मुझे नहीं पता था कि अगर आप मुझे दिखा सकते हैं। – Spreadzz

+0

@Spreadzz टाइप प्रकार 'टाइप def = स्ट्रिंग * स्ट्रिंग सूची * expr' की तरह कुछ होगा, या यदि आप चर और फ़ंक्शन परिभाषाओं के बीच अंतर करना चाहते हैं, तो स्ट्रिंग * अभिव्यक्ति के def = varDef टाइप करें। स्ट्रिंग * स्ट्रिंग सूची * अभिव्यक्ति' का FunDef। – sepp2k

+0

क्या आप मुझे मेरे व्याख्याकर्ता में जोड़ें और गुणा करने के प्रकार def दिखा सकते हैं ताकि मैं पूरी तरह से समझ सकूं? – Spreadzz