2011-03-07 17 views
5

मुझे कुछ विशेष डेटा संरचनाओं को पार्स करने की आवश्यकता है। वे कुछ हद तक एक तरह-सी प्रारूप है कि इस तरह मोटे तौर पर लग रहा है में हैं:कोड (पाइथन में) का विश्लेषण कैसे करें?

Group("GroupName") { 
    /* C-Style comment */ 
    Group("AnotherGroupName") { 
     Entry("some","variables",0,3.141); 
     Entry("other","variables",1,2.718); 
    } 
    Entry("linebreaks", 
      "allowed", 
      3, 
      1.414 
     ); 
} 

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

क्या इस तरह की फाइलों को पार्स करने के लिए कोई अच्छा पायथनिक तरीका है?
आप इसे पार्स करने के बारे में कैसे जाएंगे?

यह इस सामान्य फ़ाइल प्रारूप के बारे में स्ट्रिंग को पार्स करने के बारे में अधिक सामान्य प्रश्न है।

+3

[यह आलेख] (http://nedbatchelder.com/text/python-parsers.html) आपके लिए ब्याज का हो सकता है। –

उत्तर

6

pyparsing का उपयोग करना (मार्क Tolonen, मैं सिर्फ के बारे में "पोस्ट सबमिट" जब अपनी पोस्ट के माध्यम से आया था क्लिक करने के लिए किया गया था), यह बहुत सीधा है - नीचे दिए गए कोड में एम्बेडेड टिप्पणी देखें:

data = """Group("GroupName") { 
    /* C-Style comment */ 
    Group("AnotherGroupName") { 
     Entry("some","variables",0,3.141); 
     Entry("other","variables",1,2.718); 
    } 
    Entry("linebreaks", 
      "allowed", 
      3, 
      1.414 
     ); 
} """ 

from pyparsing import * 

# define basic punctuation and data types 
LBRACE,RBRACE,LPAREN,RPAREN,SEMI = map(Suppress,"{}();") 
GROUP = Keyword("Group") 
ENTRY = Keyword("Entry") 

# use parse actions to do parse-time conversion of values 
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda t:float(t[0])) 
integer = Regex(r"[+-]?\d+").setParseAction(lambda t:int(t[0])) 

# parses a string enclosed in quotes, but strips off the quotes at parse time 
string = QuotedString('"') 

# define structure expressions 
value = string | real | integer 
entry = Group(ENTRY + LPAREN + Group(Optional(delimitedList(value)))) + RPAREN + SEMI 

# since Groups can contain Groups, need to use a Forward to define recursive expression 
group = Forward() 
group << Group(GROUP + LPAREN + string("name") + RPAREN + 
      LBRACE + Group(ZeroOrMore(group | entry))("body") + RBRACE) 

# ignore C style comments wherever they occur 
group.ignore(cStyleComment) 

# parse the sample text 
result = group.parseString(data) 

# print out the tokens as a nice indented list using pprint 
from pprint import pprint 
pprint(result.asList()) 

प्रिंटों

[['Group', 
    'GroupName', 
    [['Group', 
    'AnotherGroupName', 
    [['Entry', ['some', 'variables', 0, 3.141]], 
    ['Entry', ['other', 'variables', 1, 2.718]]]], 
    ['Entry', ['linebreaks', 'allowed', 3, 1.4139999999999999]]]]] 

(दुर्भाग्य से, वहाँ कुछ भ्रम की स्थिति के बाद से pyparsing पार्स टोकन के लिए संरचना प्रदान करने के लिए, एक "समूह" वर्ग को परिभाषित करता हो सकता है - ध्यान दें कि कैसे एक प्रविष्टि में मूल्य सूचियों क्योंकि सूची अभिव्यक्ति एक pyparsing समूह में संलग्न है वर्गीकृत किया हो ।)

+3

आपने ओ'रेली बुकस्टोर में अभी $ 10 अर्जित किए हैं! – bastibe

1

इस पर निर्भर करता है कि आपको कितनी बार इसकी आवश्यकता है और यदि वाक्यविन्यास वही रहता है। यदि उत्तर "अक्सर" और "अधिक या कम हां" होते हैं तो मैं सिंटैक्स को व्यक्त करने और PyPEG या LEPL जैसे टूल के साथ उस भाषा में एक विशिष्ट पार्सर लिखने का एक तरीका देखता हूं। पार्सर नियमों को परिभाषित करना बड़ा काम है, जब तक कि आपको उसी तरह की फाइलों को पार्स करने की आवश्यकता न हो, अक्सर यह प्रभावी रूप से प्रभावी नहीं हो सकता है।

लेकिन यदि आप पीईपीईजी पेज देखते हैं तो यह आपको बताता है कि पार्स किए गए डेटा को एक्सएमएल में कैसे आउटपुट करना है ताकि यदि वह उपकरण आपको पर्याप्त शक्ति नहीं देता है, तो आप एक्सएमएल उत्पन्न करने के लिए इसका इस्तेमाल कर सकते हैं और फिर उदाहरण का उपयोग कर सकते हैं। Xml को पार्स करने के लिए lxml

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