2016-02-22 6 views
5

मैं यह समझने की कोशिश कर रहा हूं कि कोई grako द्वारा उत्पन्न पार्सर द्वारा पार्स किए गए दस्तावेज़ को फिर से कैसे बना सकता है।ग्रैको "कोड" पीढ़ी

ग्रैको स्रोत कोड में गहरी दफन करने के बाद, मेरा मानना ​​है कि मुझे अंततः समझ में आया है कि एएसटी से जेनरेट किए गए दस्तावेज़ में कोई कैसे लौटाता है। क्या कोई कृपया जांच सकता है कि मेरी निम्नलिखित समझ सही है, और अगर मुझे अधिक सीधी आगे की विधि है तो मुझे बताएं?

  1. कोई एक पीईजी व्याकरण बनाता है जो पार्स करना चाहता है। ग्रैको एक पार्सर क्लास और इसके आधार पर एक सेमेटिक्स क्लास बनाता है।
  2. एक व्यक्ति के व्याकरण में प्रत्येक नियम के लिए एक अलग वर्ग (grako.model.Node का उप-वर्ग) युक्त एक पाइथन मॉड्यूल (हाथ से) बनाता है (हाथ से)। प्रत्येक वर्ग में कम से कम नियत नियम में प्रत्येक नामित तत्व के लिए पैरामीटर के साथ एक कन्स्ट्रक्टर होना चाहिए और इसके मूल्यों को कक्षा संपत्ति में संग्रहीत करना चाहिए।
  3. एक (हाथ से) उत्पन्न अर्थ विज्ञान वर्ग उपवर्गों इसी वर्ग एक 2.
  4. एक के लिए टेम्पलेट परिभाषित करने grako.codegen.ModelRenderer का एक उपवर्ग (हाथ से) बनाता है एक अजगर मॉड्यूल चरण में बनाए गए द्वारा प्रत्येक नियम के लिए ast को बदलने के लिए किसी के व्याकरण में प्रत्येक नियम (अधिक या कम) के लिए "कोड" पीढ़ी।
  5. एक उत्पादन को बनाने के लिए grako.codegen.CodeGenerator().render(...) पर टेम्पलेट युक्त नोड सबक्लास और पायथन मॉड्यूल युक्त एएसटी को खिलाता है।

क्या यह सही हो सकता है? यह बिल्कुल सहज नहीं लगता है।

  • एक कदम 2 & 3 की महत्वपूर्ण प्रयास जानकारी है कि पहले से ही एएसटी में निहित है की दुकान से ज्यादा कुछ नहीं करने के लिए के माध्यम से क्यों जाना चाहते हैं?
  • एएसटी से सीधे काम करने के बजाय इस दृष्टिकोण का क्या फायदा है?
  • क्या चरण 2 & 3 स्वचालित करने या सहेजने का कोई तरीका है यदि कोई केवल मूल व्याकरण में दस्तावेज़ बनाना चाहता है?
  • एक पीईजी व्याकरण परिभाषा को देखते हुए, क्या यह स्वचालित रूप से "कोड जनरेटर जनरेटर" बनाने के लिए सैद्धांतिक रूप से संभव है जैसे कोई "पार्सर जनरेटर" बनाता है?

उत्तर

4

आप कैसे Grako ही व्याकरण पार्स को देखें, तो आप देखेंगे कि चरण 2 वर्गों कृत्रिम एक ModelBuilderSemantics वंशज द्वारा बनाई गई हैं:

# from grako/semantics.py 
class GrakoSemantics(ModelBuilderSemantics): 
    def __init__(self, grammar_name): 
     super(GrakoSemantics, self).__init__(
      baseType=grammars.Model, 
      types=grammars.Model.classes() 
     ) 
     self.grammar_name = grammar_name 
     self.rules = OrderedDict() 
... 

वर्गों अगर वे नहीं कर रहे हैं संश्लेषित कर रहे हैं types= पैरामीटर में मौजूद है। ModelBuilderSemantics की आवश्यकता है सब है कि प्रत्येक व्याकरण नियम एक पैरामीटर है कि इसी Node के लिए वर्ग के नाम देता है वहन करती है:,

module::Module = .... ; 

या,

module(Module) = ... ; 

चरण 3 अपरिहार्य है क्योंकि अनुवाद निर्दिष्ट किया जाना चाहिए " कहीं"। ग्रैको का तरीका strCodeGenerator द्वारा प्रेषित प्रेषण के साथ निर्दिष्ट इनलाइन के लिए अनुमति देता है, जो अनुवाद करने का मेरा पसंदीदा तरीका है।लेकिन मैं grako.model.DepthFirstNodeWalker का उपयोग करता हूं, जब मुझे केवल एक मॉडल से जानकारी खींचने की आवश्यकता होती है, जैसे प्रतीक तालिका या कंप्यूटिंग मीट्रिक उत्पन्न करते समय।

चरण 3 स्वचालित नहीं किया जा सकता है क्योंकि लक्षित भाषा के अर्थशास्त्र में स्रोत भाषा के अर्थशास्त्र को मानचित्रण करने के लिए मस्तिष्क शक्ति की आवश्यकता होती है, भले ही स्रोत और लक्ष्य समान हों।

एक भी JSON की तरह अजगर संरचना कि parse() या grako.model.Node.asjson(), उत्पन्न करता है (एएसटी) आप का सुझाव के रूप में traversing के साथ भाग प्राप्त कर सकते हैं, लेकिन संसाधन कोड एक-दूसरे शब्दकोश, या एक सूची भेद करने के लिए if-then-elseif से भरा होगा दूसरे से मॉडलों के साथ पदानुक्रम में हर निर्देश के रूप में एक पायथन वर्ग प्रकार के रूप में है।

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

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