में बिल्डिंग एएसटी मैं योजना के सबसेट के लिए एक रिकर्सिव वंश पार्सर बनाने के लिए ओकैमल का उपयोग कर रहा हूं। यहाँ व्याकरण है: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 के लिए:
इसलिए मेरी समझ के लिए, या तो मुझे एस्पिलॉन के लिए एक प्लेसहोल्डर शामिल करना होगा या जैसा आपने बताया है दिया गया व्याकरण समायोजित करना होगा। ऐसा लगता है कि ईपीएसलॉन समस्या को खत्म करना है। क्या इसका मतलब है जब भी मैं एपिसिलन देखता हूं, मैंने व्याकरण को फिर से लिखा है? – lovetostrike
मैं हां, अवधारणा में कहूंगा। अभ्यास में इसका मतलब है कि आप अपने पार्सर में आगे बढ़ते हैं। यदि आप हाथ से पार्सर लिख रहे हैं तो आप शायद व्याकरण को फिर से लिखने में काफी समय व्यतीत किए बिना काम कर सकते हैं। –
यदि एस एक प्रकार का बी, सी, प्रकार expr देता है, मैं एस में भाग() के लिए वापस क्या करना चाहिए? – lovetostrike