2008-12-04 6 views
5

में एक डीएसएल के लिए एक कंपाइलर लिखना मैं पाइथन में एक गेम लिख रहा हूं और मानचित्र डेटा फ़ाइलों के लिए एक डीएसएल बनाने का फैसला किया है। मुझे पता है कि मैं रेगेक्स के साथ अपना खुद का पार्सर लिख सकता हूं, लेकिन मुझे आश्चर्य है कि क्या मौजूदा पायथन उपकरण हैं जो इसे अधिक आसानी से कर सकते हैं, जैसे PHP इंजन में re2c का उपयोग किया जाता है।पायथन

कुछ अतिरिक्त जानकारी:

  • हाँ, मैं एक डीएसएल की जरूरत है , और यहां तक ​​कि अगर मैं नहीं मैं अभी भी इमारत के अनुभव और एक परियोजना में से एक का उपयोग करना चाहता था।
  • डीएसएल में केवल डेटा (घोषणात्मक?) है, इसे "निष्पादित" नहीं किया जाता है। अधिकांश लाइनों देखो की तरह:

    SOMETHING: !abc @123 #xyz/123

    मैं सिर्फ आंकड़ों के पेड़ पढ़ने की जरूरत है।

उत्तर

3

हाँ, वहाँ कई हैं - बहुत से - उपकरण पार्स करने, लेकिन मानक पुस्तकालय में एक भी नहीं।

मैंने जो देखा वह PLY और SPARK लोकप्रिय हैं। PLY yacc की तरह है, लेकिन आप पाइथन में सब कुछ करते हैं क्योंकि आप अपने व्याकरण को डॉकस्ट्रिंग में लिखते हैं।

व्यक्तिगत रूप से, मुझे पार्सर संयोजकों (कार्यात्मक प्रोग्रामिंग से लिया गया) की अवधारणा पसंद है, और मुझे pyparsing पसंद है: आप अपने व्याकरण और क्रियाओं को सीधे अजगर में लिखते हैं और इसे शुरू करना आसान है। हालांकि, मैंने अपने स्वयं के पेड़ नोड प्रकारों को क्रियाओं के साथ समाप्त कर दिया, हालांकि उनके डिफ़ॉल्ट ParserElement प्रकार का उपयोग करने के बजाय।

अन्यथा, आप मौजूदा घोषणात्मक भाषा जैसे YAML का भी उपयोग कर सकते हैं।

11

मैं हमेशा pyparsing से प्रभावित हूं। लेखक, पॉल मैकगुइर python list/comp.lang.python पर सक्रिय है और हमेशा इसके बारे में किसी भी प्रश्न के साथ बहुत उपयोगी रहा है।

+0

मैं यह सुझाव दिया है | अगर तुम यह पहले से ही नहीं किया था! PyParsing भयानक है। –

6

यहां एक ऐसा दृष्टिकोण है जो वास्तव में अच्छा काम करता है।

abc= ONETHING(...) 
xyz= ANOTHERTHING(...) 
pqr= SOMETHING(this=abc, that=123, more=(xyz,123)) 

घोषणात्मक। आसान पार्स।

और ...

यह वास्तव में पायथन है। कुछ वर्ग घोषणाएं और काम किया जाता है। डीएसएल वास्तव में कक्षा घोषणा है।

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

+0

मुझे पता है तुम क्या कह रहे हैं, लेकिन उन सभी टिप्पणियों लेखन, कोष्ठक, बराबर, उपसर्गों वास्तविक डेटा करना मुश्किल होता है। साथ ही, यह विधि PHP या जावा जैसी अधिक वर्बोज़ भाषाओं के लिए अच्छी तरह से पोर्ट नहीं करती है। –

+0

@ पीटर। सहमत नहीं हैं। आप स्थितित्मक तर्कों का उपयोग कर सकते हैं और लेबल और = को खत्म कर सकते हैं। यह पूरी तरह से जावा में अनुवाद करता है। एक घोषणात्मक डीएसएल परिभाषित करने के लिए पहले ही उत्पादन अनुप्रयोगों में इसका इस्तेमाल किया गया है। –

+0

मैंने देखा है क्या आप एक आंतरिक डीएसएल के रूप में भेजा सुझाव दे रहे हैं। मुझे यह विधि पसंद है। एक समस्या यह हो सकती है कि विधि अन्य भाषाओं में बंदरगाह करता है (मैंने सी # में लागू इस तरह की सामग्री देखी है) आपके डीएसएल का सटीक वाक्यविन्यास शायद थोड़ा सा बदल जाएगा। नक्शा फाइल पोर्टेबल नहीं होगी। – Mendelt

2

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

इसे लागू करने के लिए, मैं वास्तव में फ़ाइल को पार्स करने के लिए सीधे पाइथन स्ट्रिंग हैंडलिंग (स्प्लिट(), स्लाइसिंग इत्यादि) का उपयोग करता हूं।मुझे पाइथन स्ट्रिंग क्षमताओं को मेरी अधिकांश (सरल) पार्सिंग आवश्यकताओं के लिए पर्याप्त होना चाहिए।

दूसरों द्वारा उल्लिखित पुस्तकालयों के अलावा, अगर मैं कुछ जटिल और आवश्यक उचित पार्सिंग क्षमताओं को लिख रहा था, तो शायद मैं ANTLR का उपयोग करता हूं, जो पाइथन (और अन्य भाषाओं) का समर्थन करता है।

2

पीटर,

DSLs ताकि आप अपने आप :-) की रक्षा के लिए हालांकि जरूरत नहीं है, एक अच्छी बात कर रहे हैं, आप एक आंतरिक डीएसएल पर विचार किया है? इन्हें बाहरी (पार्स किए गए) डीएसएल बनाम इतने सारे पेशेवर हैं कि वे कम से कम विचार करने योग्य हैं। मूल भाषा की शक्ति के साथ एक डीएसएल मिश्रण वास्तव में आप के लिए समस्याओं के बहुत सारे हल करती है, और अजगर, आंतरिक DSLs पर वास्तव में बुरा नहीं है with बयान काम के साथ।

+1

कैसे 'with'statement आंतरिक DSLs के लिए उपयोगी आता है? मैं उत्सुक हूँ – fferri

2

एक आप का वर्णन कर रहे हैं के रूप में "छोटे भाषाओं" के लिए, मैं एक साधारण विभाजन, shlex (ध्यान रखें कि # एक टिप्पणी को परिभाषित करता है) या रेगुलर एक्सप्रेशन का उपयोग। के रूप में मैं नहीं जानता कि आप के लिए वास्तव में क्या देख रहे

>>> line = 'SOMETHING: !abc @123 #xyz/123' 

>>> line.split() 
['SOMETHING:', '!abc', '@123', '#xyz/123'] 

>>> import shlex 
>>> list(shlex.shlex(line)) 
['SOMETHING', ':', '!', 'abc', '@', '123'] 

निम्नलिखित, एक उदाहरण है।

>>> import re 
>>> result = re.match(r'([A-Z]*): !([a-z]*) @([0-9]*) #([a-z0-9/]*)', line) 
>>> result.groups() 
('SOMETHING', 'abc', '123', 'xyz/123') 
0

कथात्मक अजगर की तर्ज पर, मैं 'bpyml' जो आप वर्बोज़ टैग के बिना एक और अधिक एक्सएमएल संरचित तरह से अजगर में डेटा की घोषणा की सुविधा देता है कहा जाता है एक सहायक मॉड्यूल लिखा था, यह भी एक्सएमएल से/परिवर्तित किया जा सकता , लेकिन वैध पायथन है।

https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts/modules/bpyml.py

उदाहरण उपयोग http://wiki.blender.org/index.php/User:Ideasman42#Declarative_UI_In_Blender