2016-10-10 10 views
7

मैं व्याकरण के लिए एक पुस्तकालय बना रहा हूं जिसमें 2 अलग-अलग व्याख्याएं होंगी: 1) व्याकरण के आधार पर तारों को पार्सिंग 2) व्याकरण द्वारा परिभाषित भाषा में स्ट्रिंग उत्पन्न करना।स्कैला + बिल्लियों में फ्री मोनाड्स के साथ मनमाना पेड़ का उपयोग

लाइब्रेरी व्याकरण के एएसटी को मुफ्त मोनड के रूप में बनाने के लिए बिल्लियों का उपयोग करती है। हालांकि, ऐसा लगता है कि यह एकदम सही फिट नहीं हो सकता है क्योंकि मुक्त मोनैड मेरी एएसटी की एक सूची-जैसे प्रतिनिधित्व बनाते हैं जो कथन सूचियों के लिए अच्छा है, लेकिन एक व्याकरण एक कथन सूची से बहुत दूर है और मनमानी पेड़ संरचना के बहुत करीब है।

मैं ~ ऑपरेटर का उपयोग करके अपने पेड़ों को लागू करने में कामयाब रहा ताकि 2 ग्रामों को समेकित किया जा सके। एएसटी तब व्याकरण की एक सूची है जो स्वयं मनमानी एएसटी हैं।

मेरा प्रश्न है: एक मुक्त मोनड में एएसटी के उप-योगों की पुन: देखभाल करने का एक अच्छा तरीका क्या है?

मेरे वर्तमान कार्यान्वयन is here:

def parserInterpreter: GrammarA ~> ParserInterpreterState = 
new (GrammarA ~> ParserInterpreterState) { 
    def apply[A](fa: GrammarA[A]): ParserInterpreterState[A] = 
    fa match { 
     case Regx(regexp) => parseRegex(regexp) 
     case Optional(b) => parseOptional(b.foldMap(this)) 
     case m @ Multi(g) => 
     def x: State[String, A] = 
      State.apply(state => { 
      g.foldMap(this) 
       .run(state) 
       .map { 
       case (s, ParseSuccess(_)) => x.run(s).value 
       case r @ (s, ParseFailure()) => (s, ParseSuccess(s).asInstanceOf[A]) 
       } 
       .value 
      }) 
     x 
     case Choice(a, b) => 
     State.apply(state => { 
      val runA = a.foldMap(this).run(state).value 
      if (runA._2.asInstanceOf[ParseResult[_]].isSuccess) 
      runA 
      else { 
      b.foldMap(this).run(state).value 
      } 
     }) 
    } 
} 

नोट विशेष रूप से, कि Multi मामले आदेश रिकर्सिवली सबट्री व्याख्या करने के लिए में असुरक्षित प्रत्यावर्तन (अर्थात पूंछ नहीं पुनरावर्ती) का उपयोग करता है। क्या ऐसा करने के लिए इससे अच्छा तरीका है?

Please click here for the source code.

उत्तर

0

आप एक पार्सर/सुंदर प्रिंटर पुस्तकालय का निर्माण कर रहे हैं, तो आप वस्तुओं जोड़ तोड़ कर रहे हैं शायद monads नहीं हैं। आप बिल्लियों 'InvariantMonoidal (और यह मुफ्त कंटरपार्ट, FreeInvariantMonoidal) का उपयोग करना चाह सकते हैं। संबंधित ट्यूटोरियल में कोडेक्स पर a section है जो आपको दिलचस्प लगेगा।

संबंधित मुद्दे