OCaml

2012-11-30 29 views
6

में बिल्डिंग एएसटी मैं योजना के सबसेट के लिए एक रिकर्सिव वंश पार्सर बनाने के लिए ओकैमल का उपयोग कर रहा हूं। यहाँ व्याकरण है:OCaml

S -> a|b|c|(T) 
    T -> ST | Epsilon 

तो कहते हैं कि मेरे पास है:

type expr = 
     Num of int | String of string | Tuple of expr * expr 

स्यूडोकोड

इन कार्यों expr प्रकार वापस जाने के लिए एएसटी

parseS lr = 
    if head matches '(' then 
    parseL lr 
    else 
    match tokens a, b, or c 

पहले का उपयोग करते हुए निर्माण करने के लिए है एस का सेट जो टोकन हैं और '(':

parseL lr = 
    if head matches '(' or the tokens then 
     Tuple (parseS lr, parseL lr) 
    else 
     match Epsilon 

मेरा प्रश्न है "मैं कैसे एप्सिलॉन भाग के बाद से मैं सिर्फ वापस नहीं लौट सकते() के लिए वापसी करते हैं?"। एक ओकैमल फ़ंक्शन को एक ही रिटर्न प्रकार की आवश्यकता होती है और यहां तक ​​कि अगर मैं एपिसिल भाग के लिए खाली छोड़ देता हूं, तो ओकैमल अभी भी यूनिट प्रकार मानता है। उदाहरण के लिए, LALR (1) ocamlyacc या camlp4 आधारित डालूँगा (के) parsers के लिए:

उत्तर

6

जहाँ तक मैं देख सकता हूं, आपका एएसटी आपके व्याकरण से मेल नहीं खाता है।

आप अपने व्याकरण में ईपीएसलॉन का प्रतिनिधित्व करने के लिए अपने एएसटी प्रकार में विशेष रूप से खाली नोड रखने से समस्या का समाधान कर सकते हैं।

या, आप अपने व्याकरण को ईपीएसलॉन के कारक के रूप में बदल सकते हैं।

यहाँ कोई एप्सिलॉन के साथ एक बराबर व्याकरण है:

S -> a|b|c|()|(T) 
T -> S | S T 
+0

इसलिए मेरी समझ के लिए, या तो मुझे एस्पिलॉन के लिए एक प्लेसहोल्डर शामिल करना होगा या जैसा आपने बताया है दिया गया व्याकरण समायोजित करना होगा। ऐसा लगता है कि ईपीएसलॉन समस्या को खत्म करना है। क्या इसका मतलब है जब भी मैं एपिसिलन देखता हूं, मैंने व्याकरण को फिर से लिखा है? – lovetostrike

+0

मैं हां, अवधारणा में कहूंगा। अभ्यास में इसका मतलब है कि आप अपने पार्सर में आगे बढ़ते हैं। यदि आप हाथ से पार्सर लिख रहे हैं तो आप शायद व्याकरण को फिर से लिखने में काफी समय व्यतीत किए बिना काम कर सकते हैं। –

+0

यदि एस एक प्रकार का बी, सी, प्रकार expr देता है, मैं एस में भाग() के लिए वापस क्या करना चाहिए? – lovetostrike

4

शायद बजाय पार्सर कार्यों बनाने के लिए मैन्युअल रूप से यह विद्यमान तरीकों का उपयोग करने के लिए बेहतर है?

+1

या [menhir] (http://gallium.inria.fr/~fpottier/menhir/)। – Thomash

+2

धन्यवाद दोस्तों :)। लेकिन मैं मौजूदा उपयोगिताओं का उपयोग नहीं कर सकता क्योंकि यह एक अभ्यास है। – lovetostrike