एक ही वरीयता के दो बाइनरी ऑपरेटरों के साथ भाषा, बाएं-सहयोगी और दाएं-सहयोगी


11

वहाँ किसी भी प्रोग्रामिंग (या पटकथा) भाषा (या कुछ डोमेन विशिष्ट भाषा) दो द्विआधारी ऑपरेटरों कर रहे हैं oplऔर oprकी एक ही पूर्वता के साथ oplकिया जा रहा बाएं साहचर्य और oprसही-साहचर्य किया जा रहा है?

(मुझे ऐसा कोई उदाहरण नहीं मिला, लेकिन मैं उस अजीब मामले को संभालने के लिए कुछ पार्सर को सामान्य रूप से कोड करने की कोशिश कर रहा हूं)

होगा कैसे फार्म के भाव x opl y opr z या x opr y opl z पार्स किया जा सकता? और अधिक आम तौर पर और भी अधिक ऑपरेंड के साथ?


4
अगर दर्द होता है, तो ऐसा मत करो।
कोडइन्चोस

1
हास्केल में, आप अपने स्वयं के infix ऑपरेटरों को अपनी स्वयं की प्राथमिकताओं के साथ परिभाषित कर सकते हैं, और आपको इस मामले में एक त्रुटि मिलती है; यदि आपके पास x <@ y @> zके साथ <@किया जा रहा बाएं साहचर्य और @>किया जा रहा है सही-साहचर्य, GHC आप एक "पूर्वता पार्स करने में त्रुटि" देता है: "मिश्रण नहीं कर सकता ' <@' [infixl 0] और ' @>' [infixr 0] एक इन्फ़िक्स अभिव्यक्ति में" (मैं कहाँ परिभाषित उदाहरण के लिए स्तर 0 पर ये ऑपरेटर)।
एंटाल स्पेक्टर-जैबुस्की

@ एंटालसेक्टर-ज़बस्की: यह एक शानदार जवाब होगा!
बेसिल स्टेयरनेविच

@ एंटालसेक्टर-ज़बूसकी: स्विफ्ट में समान। मुझे लगता है कि आप वास्तव में ऑपरेटरों को परिभाषित कर सकते हैं, लेकिन एक अभिव्यक्ति में आपको सभी बाएं सहयोगी या सभी सही सहयोगी ऑपरेटरों को एक ही पूर्वता के साथ उपयोग करना होगा। तो आप x leftop y leftop z, या x rightop y rightop z का उपयोग कर सकते हैं, लेकिन x leftop y rightop z का नहीं।
gnasher729

@BasileStarynkevitch: जैसा आप चाहें! चूंकि आपने "लचीले पार्सर" का उल्लेख किया है, इसलिए मैंने कुछ और अस्पष्ट भाषाओं को शामिल किया है, जिनमें बहुत लचीले पार्सर हैं (कभी भी चाहते थे if_then_else_या [1;2;3]पुस्तकालयों में परिभाषित किया गया था?)।
एंटाल स्पेक्टर-ज़बूसकी

जवाबों:


10

यहां तीन भाषाएं हैं जो आपको अपने स्वयं के ऑपरेटरों को परिभाषित करने देती हैं, जो ढाई अलग-अलग चीजें करते हैं! हास्केल और कोक दोनों ही शेंनिगन्स के इन प्रकारों को अस्वीकार करते हैं - लेकिन अलग-अलग - जबकि एग्दा इस तरह की संघातियों के मिश्रण की अनुमति देता है।


सबसे पहले, हास्केल में , आपको बस ऐसा करने की अनुमति नहीं है। आप अपने स्वयं के ऑपरेटरों को परिभाषित कर सकते हैं और उन्हें अपनी पसंद की पूर्वता (0–9 से) और संबद्धता दे सकते हैं। हालाँकि, हास्केल रिपोर्ट आपको संघातियों को मिलाने से रोकती है :

एक ही मिसाल के साथ लगातार अविभाजित ऑपरेटरों को वाक्य रचना त्रुटि से बचने के लिए या तो बाएं या दाएं साहचर्य होना चाहिए। [हास्केल 2010 की रिपोर्ट, चौ। 3]

इसलिए, जीएचसी में , यदि हम एक पूर्ववर्ती स्तर पर बाएं-सहयोगी ( infixl) ऑपरेटर <@और दाएं-सहयोगी ऑपरेटर @>को परिभाषित करते हैं - मान लें कि 0 - तो मूल्यांकन x <@ y @> zत्रुटि देता है

पूर्वगामी पार्सिंग त्रुटि
    ' <@' [ infixl 0] और ' @>' [ infixr 0] को एक ही infix अभिव्यक्ति में नहीं मिला सकती है

(वास्तव में, आप एक ऑपरेटर को infix होने की घोषणा कर सकते हैं लेकिन गैर-सहयोगी, जैसे ==, ताकि x == y == zएक वाक्यविन्यास त्रुटि हो!)


दूसरी ओर, भरोसेमंद टाइप की गई भाषा / प्रमेय कहावत अगड़ा है (जो कि, बेशक, मुख्य रूप से कम मुख्यधारा है)। Agda में किसी भी भाषा का सबसे अधिक निंदनीय वाक्य रचना है, जो मुझे पता है, मिक्सफिक्स ऑपरेटरों का समर्थन : मानक पुस्तकालय में फ़ंक्शन होता है

if_then_else_ : ∀ {a} {A : Set a} → Bool → A → A → A

जो, जब कहा जाता है, लिखा जाता है

if b then t else f

अंडरस्कोर में भरने वाले तर्कों के साथ! मैं इसका उल्लेख करता हूं क्योंकि इसका मतलब है कि इसे अविश्वसनीय रूप से लचीली पार्सिंग का समर्थन करना है। स्वाभाविक रूप से, AGDA भी (अपने पूर्वता स्तर पर मनमाने ढंग से प्राकृतिक संख्या की सीमा, और 0-100 में आम तौर पर कर रहे हैं, हालांकि) स्थिरता घोषणाओं है, और AGDA करता है एक ही पूर्वता लेकिन अलग fixities के ऑपरेटरों मिश्रण करने की अनुमति। हालाँकि, मैं इस बारे में दस्तावेज़ में जानकारी नहीं ढूँढ सकता, इसलिए मुझे प्रयोग करना था।

चलो हमारे <@और @>ऊपर से पुन: उपयोग करें । दो सरल मामलों में, हमारे पास है

  • x <@ y @> zपार्सिंग के रूप में x <@ (y @> z); तथा
  • x @> y <@ zपार्सिंग के रूप में (x @> y) <@ z

मुझे लगता है कि एजडा क्या करती है, लाइन को "लेफ्ट एसोसिएटिव" और "राइट एसोसिएटिव" चंक्स में समूहित किया जाता है, और - जब तक मैं गलत चीजों के बारे में नहीं सोच रहा हूँ - सही-एसोसिएटिव चंक को आसन्न तर्कों को हथियाने में "प्राथमिकता" मिलती है। तो वह हमें देता है

a <@ b <@ c @> d @> e @> f <@ g

पार्सिंग के रूप में

(((a <@ b) <@ (c @> (d @> (e @> f)))) <@ g

या

<Code> (((a <@ b) <@ (c @> (d </ code> @> (e @> f))) के पार्स ट्री) <@ g

हालाँकि, मेरे प्रयोगों के बावजूद, मैंने पहली बार गलत लिखा था कि मैंने इसे लिखा था, जो शिक्षाप्रद हो सकता है :-)

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


अंत में, वहाँ प्रमेय-कहावत / निर्भरता से टाइप की गई भाषा Coq है , जिसमें Agda की तुलना में अधिक लचीला वाक्यविन्यास है क्योंकि इसके वाक्यविन्यास एक्सटेंशन वास्तव में नए वाक्य रचना के लिए विशिष्टताओं को लागू करके और फिर उन्हें मुख्य भाषा में फिर से लिखना (अस्पष्ट रूप से मैक्रो-जैसे) हैं , मुझे लगता है)। Coq में, सूची सिंटैक्स [1; 2; 3]मानक लाइब्रेरी से एक वैकल्पिक आयात है। नए वाक्यविन्यास भी चर बाँध सकते हैं!

एक बार फिर, कोक में, हम अपने स्वयं के इनफिक्स ऑपरेटरों को परिभाषित कर सकते हैं और उन्हें पूर्व स्तर (099 से, ज्यादातर) और संबद्धता दे सकते हैं। हालाँकि, Coq में, प्रत्येक पूर्ववर्ती स्तर में केवल एक समरूपता हो सकती है । इसलिए अगर हम <@वाम-सहयोगी के @>रूप में परिभाषित करते हैं और फिर समान स्तर पर दाएँ-सहयोगी के रूप में परिभाषित करने का प्रयास करते हैं - कहते हैं, 50 - हमें मिलता है

त्रुटि: स्तर 50 पहले से ही बाएं साहचर्य घोषित किया गया है, जबकि यह अब सही सहयोगी होने की उम्मीद है

Coq में अधिकांश ऑपरेटर 10 के स्तर से विभाज्य हैं; अगर मेरे पास सहानुभूति के मुद्दे हैं (ये स्तर के सहसंबंध वैश्विक हैं), तो मैंने आम तौर पर किसी भी दिशा में एक स्तर (आमतौर पर ऊपर) को टक्कर दी है।


2
(जी, भाषाओं का एक अजीब चयन। क्या आप बता सकते हैं कि मैं प्रोग्रामिंग भाषा सिद्धांत का अध्ययन करता हूं ?:-P)
एंटाल स्पेक्टर-ज़बस्की

आपके विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। BTW, आपने चित्र कैसे बनाया (किस टूल के साथ graphviz?)
बेसिल स्टायरनेविच

BTW, "पूर्वता" के बजाय "शुद्धता" क्यों?
बेसिल स्टैरनेवविच

@BasileStarynkevitch: यह इस बात पर निर्भर करता है कि आपका मतलब कहां है। अगर आप कोक सेक्शन में मतलब रखते हैं, तो यह सिर्फ एक गलती थी :-) (और एक जो अब तय हो गई है!)
एंटाल स्पेक्टर-ज़ब्यूस्की

1
@BasileStarynkevitch: इसके अलावा, मैंने तस्वीर के बारे में आपके सवाल को याद किया! मैंने कहा कि LaTeX पैकेज qtree के साथ , और इसे LaTeXit में प्रस्तुत किया , Mac के लिए एक LaTeX स्निपेट रेंडरर। प्रासंगिक स्रोत कोड था \ttfamily \Tree[.<@ [.<@ [.<@ a b ] [.@> c [.@> d [.@> e f ]]]] g ]
एंटाल स्पेक्टर-ज़बूसकी

2

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

उनके पास एक पार्स फ़ंक्शन होता है जो पहले अभिव्यक्ति के सबसे बाएं शब्द को पार्स करके काम करता है, फिर नए ऑपरेटरों और दाहिने हाथ की शर्तों को तब तक बाध्यकारी करता है जब तक वे उचित रूप से बाँधते हैं। बाएं-सहयोगी ऑपरेटर्स दाहिने हाथ की शर्तों को बांधेंगे, जिसमें एक ही पूर्वता तक की और सहित पूर्ववर्तीता है, जबकि राइट-एसोसिएटिव ऑपरेटर्स केवल अपने पूर्ववर्ती स्तर तक बाँधते हैं, लेकिन इसमें शामिल नहीं हैं। मुझे विश्वास है कि यह उसी पार्स ट्री के रूप में होता है जो ऊपर उद्धृत किया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.