2017-04-11 29 views
12

पार्सिंग अग्रिम में क्षमा करें; मुझे यकीन है कि यह प्रश्न उन लोगों के लिए लगभग बेवकूफ़ प्रतीत होगा जो पार्सर्स और व्याकरण के साथ खेलने के लिए उपयोग किए जाते हैं, लेकिन ये मेरे लिए विदेशी विषय हैं, और यह एक व्यावहारिक मामले में धीरे-धीरे कदम उठाने का मेरा प्रयास है।एक "सरल" व्याकरण

मैं निम्नलिखित 'भाषा' है, जो एक एकल "विशेष संरचना" इस तरह लग रही शामिल है के लिए एक पार्सर लिखने के लिए करना चाहते हैं:

\command[ options ]{ contents } 

सामग्री, कुछ भी हो सकता नेस्टेड आदेशों सहित, और हो सकती है बच निकले ब्रैकेट या बैकस्लाश \{ \} \\। मुझे एहसास है कि "कुछ भी" विशिष्ट नहीं है, लेकिन आदर्श रूप से यदि संभव हो तो उन्हें मिलान करने वाले ब्रैकेट (बचने वाले लोगों को छोड़कर) द्वारा निर्धारित किया जाना चाहिए।

विकल्पों ऐसे name = value के रूप में काम भाव की एक अल्पविराम से अलग किए होना चाहिए, लेकिन मूल्य एक उद्धृत स्ट्रिंग = या , वर्ण युक्त हो सकता है। अंत में पिछला name और command नियमित अभिव्यक्ति \w[\w\d\._-+*]* मान्य करना चाहिए - यानी, पहला अक्षर एक अक्षर होना चाहिए, और शेष वर्ण एक अक्षर, अंक या . _ - + * में से एक होना चाहिए।

नियमित अभिव्यक्तियों के साथ इसे लिखना अत्यधिक जटिल लगता है (उदाहरण के लिए, क्योंकि मानों में उद्धृत वर्ण , = हो सकते हैं, जो अन्यथा असाइनमेंट या नाम/मूल्य जोड़ अलग करेगा)। तो मुझे लगता है कि यहां सबसे उपयुक्त उपकरण एक व्याकरण है, लेकिन सतही रीडिंग के बावजूद, मुझे यकीन नहीं है कि इसे कैसे लिखना है (बीएनएफ, पीईजी, आदि?), किस प्रकार के पार्सर्स का उपयोग करना है (एलआर, रिकर्सिव सभ्य, इत्यादि?) , और मैं व्यावहारिक कार्यक्रम में पार्सिंग आउटपुट का उपयोग कैसे कर सकता हूं।

मैं पाइथन के साथ उत्तर पसंद करूंगा, जो टैग को समझाता है, लेकिन निश्चित रूप से यदि आवश्यक हो तो मैं उपकरणों के संयोजन से पूरी तरह खुश हूं।


नोट: इस LaTeX के बारे में नहीं है। मुझे पाठ्यक्रम की समानता का एहसास है, लेकिन लाटेक्स पिछली भाषा की तुलना में बेहद जटिल है, उदाहरण के लिए संदर्भ कोड के आधार पर चरित्र कोड अलग-अलग होते हैं। मैं केवल एक व्यावहारिक उदाहरण मांग रहा हूं जो (मुझे लगता है) एसओ के लिए काफी आसान है, और फिर भी मेरे दैनिक काम में मेरे लिए पहले से ही उपयोगी होगा।

+0

क्या यह (ला) टीएक्स है? –

+0

नहीं :) चरित्र कोड, '@' -स्टेटमेंट्स इत्यादि के साथ लाटेक्स अधिक जटिल है। इस तरह यह लाटेक्स का एक बहुत ही मजबूत प्रतिबंध है। मैं मुख्य रूप से पूछ रहा हूं क्योंकि मैं ऐसे मामले पर सीखना चाहता हूं जो काम पर पहले से ही उपयोगी हो, और जो (मुझे लगता है) एसओ पर एक जवाब के लिए काफी आसान है। – Sheljohn

+3

शीर्षक * वास्तव में * पार्सिंग के बारे में शीर्षक में पार्सिंग के साथ एक प्रश्न पढ़ने के लिए ताज़ा करना। –

उत्तर

6

अपने व्याकरण को अधिक औपचारिक रूप से व्यक्त करके प्रारंभ करें, जो भी आप पसंद करते हैं। तब

program := element+ 
element := command | literal 
literal := (not '\')+ 

command := '\'identifier options? '{' program '}' 
options := option | options ',' option 
option := identifier '=' value 
value := number | string 

string := '"' (escape | not '\' or '"')* '"' 
escape : = '\' char 

या तो एक पार्सर जेनरेटर (pyParsing, pyYACC, ANTLR) को यह फ़ीड या हाथ से एक पार्सर लिखें: उदाहरण के लिए, अपने विवरण से, एक EBNF इस तरह होगा। बाद के मामले में टॉप-डाउन सबसे आसान विकल्प है: व्याकरण के शीर्ष से शुरू करें और प्रत्येक नियम को एक फ़ंक्शन में परिवर्तित करें जो या तो एक पार्स किए गए एएसटी नोड को वापस कर देगा और इनपुट का उपभोग करेगा या कुछ भी नहीं लौटाएगा या फेंक देगा। उदाहरण:

def program(): 
    elements = [] 
    while next_sym(): 
     elements.append(element()) 
    return {'type': 'program', 'children': elements} 

def element(): 
    return command() or literal() 

def command(): 
    if next_sym() == '\\': 
     get_sym() 
     ...parse command here 
     return {'type': 'command', 'children': ...} 
    return None 

जहां next_sym इनपुट (या None EOF पर) से अगले प्रतीक वापस आती है और get_sym प्रतीक की खपत और इनपुट बफर अग्रिम।

+0

बहुत बहुत धन्यवाद; इस उदाहरण में, 'पहचानकर्ता, संख्या और चार' primitives हैं, या मैं उन्हें परिभाषित करना चाहिए जैसा कि आप बाकी परिभाषित करते हैं? 'स्ट्रिंग' परिभाषा के बारे में, भाग 'नहीं' \ 'या' "'' ब्लैकस्लाश और डबल कोट्स से बचने के लिए मजबूर करता है, क्या यह सही है? – Sheljohn

+0

आप जिस विधि का उपयोग कर रहे हैं, उस पर निर्भर करता है, कुछ जेनरेटर इसके लिए प्राइमेटिव प्रदान करते हैं, अन्य नहीं, तो आपको regexes का उपयोग करके उन्हें परिभाषित करना होगा। – georg

+0

भागने के संबंध में, हाँ, यह सही है। – georg

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