14

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

+0

मेरे प्रोग्रामिंग भाषाओं पाठ्यक्रम कुछ पुरानी है, तो आप मुझे एक linke बताते हैं कि क्यों अजगर एक CFG नहीं है दे सकते हैं? – RedDeckWins

+2

पायथन भाषा एक संदर्भ मुक्त व्याकरण का पालन करती है - वे भी बीएनएफ पोस्ट करते हैं! http://www.python.org/doc/current/ref/grammar.txt आप यहां एक संदर्भ मुक्त व्याकरण की औपचारिक परिभाषा के बारे में पढ़ सकते हैं: http://en.wikipedia.org/wiki/Context_free_grammar – cdleary

+1

सहमत , पायथन निश्चित रूप से एक संदर्भ मुक्त भाषा है। इंडेंट में एक इंडेंट या डिंडेंट टोकन में परिणाम जो व्याकरण में प्रतीक हैं। इन टोकन को पहचानने के लिए आपको एक विशेष टोकनेज़र की आवश्यकता होगी हालांकि वास्तविक व्याकरण को 100% प्रामाणिक ईमानदार-से-भलाई संदर्भ मुक्त होने से नहीं रोकता है। –

उत्तर

2

मुझे किसी भी ट्यूटोरियल/गाइड के बारे में पता नहीं है, लेकिन आप tinypy के स्रोत को देखने का प्रयास कर सकते हैं, यह भाषा की तरह एक अजगर का एक बहुत छोटा कार्यान्वयन है।

6

आप पाइथन, Python: Myths about Indentation पार्सिंग पर इस बल्कि लिखित निबंध को पढ़ना चाहेंगे।

जब मैं एक संदर्भ मुक्त पार्सर याक की तरह कुछ का उपयोग कर लिखने के लिए प्रयास नहीं किया है, मैं इसे एक सशर्त lexer का उपयोग कर यूआरएल में वर्णित के रूप खरोज परिवर्तन टोकन वापस जाने के लिए संभव हो सकता है लगता है। http://www.python.org/doc/current/ref/grammar.txt

+0

सावधान रहें: व्याकरण और एक भाषा के बीच एक अंतर है। –

2

एक भाषा में खरोज का उपयोग करना जरूरी नहीं है कि भाषा के व्याकरण संदर्भ मुक्त नहीं किया जा सकता:

वैसे, यहाँ python.org से आधिकारिक अजगर व्याकरण है। अर्थात। इंडेंटेशन निर्धारित करेगा कि किस दायरे में एक बयान मौजूद है। एक बयान अभी भी एक बयान होगा चाहे वह किस क्षेत्र में परिभाषित किया गया हो (स्कोप को आमतौर पर संकलक/दुभाषिया के एक अलग हिस्से द्वारा संभाला जा सकता है, आमतौर पर एक अर्थपूर्ण पार्स के दौरान)।

ने कहा कि एक अच्छा संसाधन एंटीलर उपकरण (http://www.antlr.org) है। टूल के लेखक ने एंटरलर (http://www.pragprog.com/titles/tpantlr/the-definitive-antlr-reference) का उपयोग करके भाषाओं के लिए पार्सर्स बनाने पर भी एक पुस्तक बनाई है। बहुत अच्छा प्रलेखन और उदाहरण के बहुत सारे व्याकरण हैं।

0

सिर्फ इसलिए कि एक भाषा महत्वपूर्ण इंडेंटेशन का उपयोग करती है इसका मतलब यह नहीं है कि यह मूल रूप से संदर्भ-संवेदनशील है। उदाहरण के तौर पर, हास्केल महत्वपूर्ण इंडेंटेशन का उपयोग करता है, और (मेरे ज्ञान के लिए) इसका व्याकरण संदर्भ मुक्त है।

एक संदर्भ के प्रति संवेदनशील व्याकरण की आवश्यकता होती है रूबी से इस स्निपेट हो सकता है स्रोत का एक उदाहरण:

my_essay = << END_STR 
This is within the string 
END_STR 

<< self 
    def other_method 
    ... 
    end 
end 

एक और उदाहरण स्काला के XML मोड होगा:

def doSomething() = { 
    val xml = <code>def val <tag/> class</code> 
    xml 
} 

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

अंतिम नोट के रूप में, यदि आप वास्तव में संदर्भ-संवेदनशील पार्सिंग टूल की आवश्यकता है, तो आप कुछ कम कठोर औपचारिक तकनीकों का प्रयास कर सकते हैं। पार्सर संयोजकों का उपयोग स्कैला के पार्सिंग में किया जाता है। उनके पास कुछ परेशान सीमाएं हैं (कोई लेक्सिंग नहीं), लेकिन वे एक खराब उपकरण नहीं हैं। एएलएलआर जैसे एलएल (*) उपकरण भी इस तरह के "विज्ञापन" पार्सिंग भागने को व्यक्त करने में अधिक उपयुक्त लगते हैं। संदर्भ-संवेदनशील व्याकरण के साथ Yacc या Bison का उपयोग करने की कोशिश न करें, वे आसानी से ऐसी अवधारणाओं को व्यक्त करने के लिए सख्त हैं।

1

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

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

यदि आप एक हाथ से लिखे गए टॉप-डाउन पार्सर लिखते हैं, तो आप जो भी नियम चाहते हैं, वहां कहीं भी लागू कर सकते हैं, जहां भी आप चाहें। यह वही है जो त्रुटि वसूली प्रदान करना आसान बनाता है। महत्वपूर्ण व्हाइटस्पेस को लागू करने के लिए यह आपके लिए भी छोटा होगा। आप आसानी से स्टोर कर सकते हैं कि वर्तमान इंडेंटेशन स्तर आपके पार्सर क्लास के अंदर एक चर में है, और जब आप एक नई लाइन पर टोकन का सामना करते हैं तो ब्लॉक को रोकना बंद कर सकते हैं जिसमें मौजूदा इंडेंटेशन स्तर से कम कॉलम स्थिति है। इसके अलावा, संभावना है कि आप अपने व्याकरण में अस्पष्टता में भागने जा रहे हैं। व्यापक उपयोग में अधिकांश "उत्पादन" भाषाओं में वाक्य रचनात्मक अस्पष्टताएं होती हैं। एक अच्छा उदाहरण सी # में जेनेरिक है (अभिव्यक्ति संदर्भ में "<" के आस-पास अस्पष्टताएं हैं, यह या तो "कम से कम" ऑपरेटर हो सकती है, या "जेनेरिक तर्क सूची" की शुरुआत हो सकती है)। एक हाथ से लिखित पार्सर हल करने की अस्पष्टताएं जैसे कि तुच्छ हैं। आप केवल थोड़ी-थोड़ी गैर-निर्धारणवाद जोड़ सकते हैं जहां आपको इसके बाकी पार्सर पर अपेक्षाकृत कम प्रभाव पड़ता है,

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

मैं कहूंगा कि अगर पार्सर जनरेटर केवल एक अच्छा विकल्प है:

  1. आप एक IDE कभी लेखन पर योजना कभी नहीं,
  2. भाषा वास्तव में सरल वाक्य रचना, या
  3. है आपको एक पार्सर को बहुत जल्दी चाहिए, और खराब उपयोगकर्ता अनुभव
+0

सी एक पार्सर जनरेटर (yacc) का उपयोग करके बनाया गया था। स्कैला को संयोजकों का उपयोग करके बनाया गया है, जो एक अंतर्निहित पार्सर जेनरेटर की तरह हैं। हाथ से एक पार्सर बनाना गैर-मामूली मामले में त्रुटि-प्रवण और बनाए रखना मुश्किल है। मैं आपके सभी तीन कारणों से असहमत हूं। :-) –

+0

कमांड लाइन कंपाइलर्स के लिए, पार्सर जनरेटर ठीक हैं। एक बैच पार्सर को अधिक त्रुटि वसूली की आवश्यकता नहीं है। इंटरैक्टिव परिदृश्यों के लिए, तथापि, मैं वास्तव में आप एक हाथ से लिखा पार्सर की जरूरत है। मेरे अनुभव हाथ लिखा पारसर्स में लिखने के लिए बहुत आसान कर रहे हैं, और यह भी अपेक्षाकृत आसान बनाए रखने के लिए कर रहे हैं। –

+0

कुछ अर्थ में मैं आपका बिंदु देख सकता हूं। संपादक कंपाइलर्स से बहुत अलग हैं। हालांकि, आम तौर पर, मुझे लगता है कि एक संपादक पार्सर को उत्पादन नियमों को अनजाने में चुनने की आवश्यकता के कारण केवल शीर्ष-डाउन (यैक तल-अप के विपरीत) होना चाहिए। –

1

क्या आप री डी अहो, सेठी, उलमैन: "कंपाइलर्स: सिद्धांत, तकनीक, और उपकरण"? यह एक शास्त्रीय भाषा संदर्भ पुस्तक है।

/एलन

1

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

अहो, सेठी और उलमैन पढ़ना (इसे "ड्रैगन बुक" के नाम से जाना जाता है) एक अच्छी योजना है। अन्य योगदानकर्ताओं के विपरीत, मैं कहता हूं कि आपको पहले पार्कर जनरेटर जैसे Yacc और Bison के साथ खेलना चाहिए, और केवल तभी जब आप जला जाएंगे क्योंकि आप उस उपकरण के साथ कुछ नहीं कर सकते हैं, तो आप एलएल (*) Antlr की तरह पार्सर।

+0

मैंने Yacc और Bison के साथ एक बार सरल कंपाइलर लिखा था। और ... जीसीसी के लिए सम्मान। – zie1ony

5

मैं इस विषय पर उपलब्ध कुछ साहित्यों पर पढ़कर पहले समस्या से खुद को परिचित कर दूंगा। Aho et द्वारा क्लासिक कंपाइलर्स पुस्तक। अल।गणित और कंप विज्ञान पर भारी हो सकता है, लेकिन जैक क्रेन्शॉ द्वारा Let's Build a Compiler लेखों का एक और अधिक अपरिवर्तनीय पाठ है। यह लेखों की एक श्रृंखला है जिसे श्री क्रेंशॉ ने 80 के उत्तरार्ध में वापस लिखा था और यह कभी लिखे गए कंपाइलरों पर सबसे कम सराहनीय पाठ है। दृष्टिकोण सरल और बिंदु पर है: श्री क्रेन्शॉ दिखाता है "" दृष्टिकोण जो काम करता है। आप आसानी से कुछ शाम के दौरान सामग्री के माध्यम से जा सकते हैं और एक कंपाइलर के बारे में बहुत अच्छी समझ है। कुछ चेतावनी यह है कि पाठ में उदाहरण टर्बो पास्कल में लिखे गए हैं और कंपेलर 68 के असेंबलर उत्सर्जित करते हैं। उदाहरण अधिक मौजूदा प्रोग्रामिंग भाषा के लिए बंदरगाह के लिए काफी आसान हैं और इसके लिए मैं पाइथन का पुनर्मूल्यांकन करता हूं। लेकिन यदि आप उदाहरणों के साथ पालन करना चाहते हैं तो आपको कम से कम Turbo Pascal 5.5 और a 68K assembler and emulator की आवश्यकता होगी। पाठ आज भी प्रासंगिक है और इन पुरानी तकनीकों का उपयोग वास्तव में मजेदार है। मैं इसे संकलक पर किसी के पहले पाठ के रूप में अत्यधिक अनुशंसा करता हूं। अच्छी खबर यह है कि पाइथन और रूबी जैसी भाषाएं खुली हैं और आप यह समझने के लिए सी स्रोत कोड डाउनलोड और अध्ययन कर सकते हैं कि यह कैसे किया जाता है।

+0

यह एक अच्छा लिंक है, लेकिन यह ओपी का जवाब कैसे देता है? यह द्वारा –

19

एक संदर्भ मुक्त व्याकरण, केवल एक है जिसे कोड को सही तरीके से पार्स करने के लिए प्रतीक तालिका की आवश्यकता नहीं होती है। एक संदर्भ-संवेदनशील व्याकरण करता है।

डी प्रोग्रामिंग भाषा एक संदर्भ मुक्त व्याकरण का एक उदाहरण है। सी ++ एक संदर्भ संवेदनशील है। (उदाहरण के लिए, टी * एक्स एक्स को सूचकांक टी के रूप में घोषित कर रहा है, या यह एक्स द्वारा एक्स को गुणा कर रहा है? हम केवल यह देखने के लिए प्रतीक तालिका में टी को देखकर बता सकते हैं कि यह एक प्रकार या चर है या नहीं।)

व्हाइटस्पेस के पास इसके साथ कुछ लेना देना नहीं है।

डी एक संदर्भ मुक्त व्याकरण का उपयोग करता है ताकि इसे पार्सिंग को सरल बनाया जा सके, और ताकि सरल उपकरण इसे पार्स कर सकें (जैसे संपादकों को हाइलाइट करना सिंटैक्स)।

+0

टी * x आत्म है या '=' की बाईं तरफ के दोनों डी में और जीसीसी के तहत एक सूचक मंदी माना जाता है। मैं थोड़ी देर पहले इसमें भाग गया था। – BCS

+0

टी * एक्स; यदि यह एक घोषणा है और इसके गुणा होने पर मान्य है तो स्वयं ही मान्य है। मैं यह मानने के लिए स्वाभाविक रूप से सही नहीं सोचता कि यह हमेशा एक सूचक डीलरेशन होता है। (मैं 2 * 3 लिख सकते हैं, तो मैं भी उतनी ही आसानी से पूर्णांक टी = 2 की तरह कुछ लिख सकता है; पूर्णांक एक्स = 3; टी * x; भले ही परिणाम खो दिया है) – Dan

+0

अगर वहाँ की घोषणा संकेत के लिए एक अलग प्रतीक था , $ कहो, उपरोक्त उदाहरण संदर्भ मुक्त हो जाएगा? –

2

तुम सच में भाषा डिजाइन और कार्यान्वयन पर एक अजीब लेने के लिए जा रहे हैं, तो आप अपने बुकशेल्फ के लिए निम्न जोड़ सकते हैं:

  • भाषा उपयोगितावाद, स्कॉट एट अल प्रोग्रामिंग।
  • प्रोग्रामिंग भाषाओं में डिजाइन अवधारणाओं, तुर्बक एट अल।
  • आधुनिक कंपाइलर डिज़ाइन, ग्र्यून एट अल। (मैं sacrilegiously Aho एट अल द्वारा करने के लिए "ड्रैगन पुस्तक" इस पसंद करते हैं।) जैसे

Gentler परिचय:

  • Crenshaw के ट्यूटोरियल (के रूप में @ 'जोनास Gorauskas' यहाँ ने सुझाव दिया)
  • पैर
  • मार्टिन फाउलर की हाल ही में काम के द्वारा निश्चित ANTLR संदर्भ DSLs

पर आप भी अपने कार्यान्वयन भाषा पर विचार करना चाहिए। यह उन क्षेत्रों में से एक है जहां विभिन्न भाषाओं बड़े पैमाने पर उनकी सुविधा में भिन्न होते हैं। आपको LISP, F #/OCaml, और गिलद ब्राचा की नई भाषा न्यूज़पीक जैसी भाषाओं पर विचार करना चाहिए।

+0

+1। महान किताब अकेले परिशिष्ट में भाषा का पेड़ अमूल्य है। http://books.google.com/books?id=GBISkhhrHh8C&printsec=frontcover&dq=scott+programming+language+pragmatics&source=bl&ots=Gh_83WcsNC&sig=jiQr88XuCWLX8yaHxtGSC3dCam4&hl=en&ei=ZwjoTK-FIs_rsgbGzLSOCQ&sa=X&oi=book_result&ct=result&resnum=4&sqi=2&ved=0CDYQ6AEwAw# v = onepage और q & f = false page820 –

3

"संदर्भ-मुक्त" एक सापेक्ष शब्द है। अधिकांश संदर्भ-मुक्त पार्सर्स वास्तव में उस भाषा के एक सुपरसेट को पार्स करते हैं जो संदर्भ-मुक्त है और फिर परिणामी पार्स पेड़ को जांचने के लिए जांचें कि यह वैध है या नहीं।उदाहरण के लिए, निम्न दो सी कार्यक्रमों सी के विषय से मुक्त व्याकरण के अनुसार मान्य हैं, लेकिन एक जल्दी से संदर्भ-चेकिंग के दौरान विफल रहता है:

int main() 
{ 
    int i; 
    i = 1; 
    return 0; 
} 

int main() 
{ 
    int i; 
    i = "Hello, world"; 
    return 0; 
} 

संदर्भ से नि: शुल्क, i = "Hello, world"; एक पूरी तरह से वैध काम है, लेकिन संदर्भ में आप देख सकते हैं कि प्रकार सभी गलत हैं। यदि संदर्भ char* i; था तो यह ठीक रहेगा। तो संदर्भ मुक्त पार्सर उस असाइनमेंट के साथ कुछ भी गलत नहीं देख पाएगा। यह तब तक नहीं है जब संकलक प्रकारों की जांच शुरू करता है (जो संदर्भ निर्भर हैं) कि यह त्रुटि को पकड़ लेगा।

कुछ भी है कि एक कुंजीपटल के साथ उत्पादन किया जा सकता विषय से मुक्त रूप में पार्स किया जा सकता; कम से कम आप जांच सकते हैं कि उपयोग किए गए सभी वर्ण मान्य हैं (केवल सभी प्रदर्शित करने योग्य यूनिकोड वर्ण वाले तारों का सेट एक संदर्भ मुक्त व्याकरण है)। एकमात्र सीमा यह है कि आपका व्याकरण कितना उपयोगी है और आपके परिणामी पार्स पेड़ पर आपको कितना संदर्भ-संवेदनशील जांच करना है।

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

+0

ऐसा एकमात्र उत्तर लगता है जो वास्तव में "संदर्भ मुक्त", "व्याकरण" और "भाषा" का अर्थ समझता है और ओपी को संबोधित करता है। +1 –

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