क्या C ++ संदर्भ-मुक्त या संदर्भ-संवेदनशील है?


405

मैं अक्सर दावे सुनता हूं कि C ++ एक संदर्भ-संवेदनशील भाषा है। निम्नलिखित उदाहरण लें:

a b(c);

क्या यह एक चर परिभाषा या एक फ़ंक्शन घोषणा है? यह प्रतीक के अर्थ पर निर्भर करता है c। यदि cएक चर है , तो प्रकार a b(c);नाम bके एक चर को परिभाषित करता है a। इसके साथ प्रत्यक्ष रूप से आरंभ किया जाता है c। लेकिन अगर cएक प्रकार है , तो a b(c);एक फ़ंक्शन की घोषणा करता है जिसका नाम bए है cऔर रिटर्न ए a

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

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

तो, C ++ संदर्भ-मुक्त या संदर्भ-संवेदनशील है?


12
@CarlNorum कृपया मुझे C ++ का एक एकल व्याकरण नियम दिखाएं जिसमें इसके बाएँ-किनारे पर एक भी गैर-टर्मिनल चिह्न नहीं है और मैं तुरंत आपको विश्वास करूँगा।
fredoverflow

9
IIUC यह उस पर थोड़ा निर्भर करता है जहां आप संदर्भ-संवेदनशीलता के लिए रेखा खींचते हैं। मुझे लगता है कि मैंने देखा है कि लोग तर्क देते हैं कि लगभग सभी टाइप की गई प्रोग्रामिंग लैंग्वेज संदर्भ-संवेदनशील हैं, इसलिए नहीं कि आप उनके लिए CFG पार्सिंग टूल के साथ एक प्रैक्टिकल कंपाइलर नहीं बना सकते, बल्कि इसलिए कि कुछ अवैध प्रोग्राम्स को पार्स करके ऐसे कार्यान्वयन "धोखा" देते हैं और केवल बाद में उन्हें अस्वीकार करना, प्रकार की जाँच के दौरान। इसलिए यदि आप बीमार टाइप के कार्यक्रमों को भाषा में नहीं मानते हैं (CS अर्थ में, यानी तार का एक सेट) तोता को स्वीकार करना चाहिए, C ++ से अधिक भाषाएं संदर्भ-संवेदनशील हैं।

6
@ डीडीएमजी: नहीं, आप गलत हैं। औपचारिक भाषा सिद्धांत में कोई "पार्सिंग" या "शब्दार्थ" नहीं है, बस "भाषा" जो कि तार का एक समूह है।
jpalecek

27
अब तक किसी भी उत्तर ने वास्तव में "संदर्भ-मुक्त व्याकरण" की आपकी परिभाषा को संबोधित नहीं किया है। मेरे दिमाग में, इस सवाल का सही उत्तर या तो परिशिष्ट A में एक उत्पादन का हवाला देता है जो आपकी परिभाषा के अनुकूल नहीं है, या यह दर्शाता है कि आपकी परिभाषा गलत है या अपर्याप्त है। डटे रहो!
लाइटवेट दौड़ ऑर्बिट में

8
देखें क्या डी का व्याकरण वास्तव में संदर्भ-मुक्त है? । वास्तव में, मुझे लगता है कि यहाँ हर किसी को उस प्रश्न और उसके उत्तर को पढ़ना चाहिए!
लाइटवेट दौड़ ऑर्बिट

जवाबों:


341

नीचे मेरा (वर्तमान) पसंदीदा प्रदर्शन है कि पार्सिंग सी ++ क्यों (शायद) ट्यूरिंग-पूर्ण है , क्योंकि यह एक प्रोग्राम दिखाता है जो सिंटैक्टिक रूप से सही है यदि और केवल यदि एक पूर्णांक अभाज्य है।

इसलिए मैं जोर देकर कहता हूं कि C ++ न तो संदर्भ-मुक्त है और न ही संदर्भ-संवेदनशील है

यदि आप किसी भी उत्पादन के दोनों किनारों पर मनमाने ढंग से प्रतीक अनुक्रम की अनुमति देते हैं, तो आप चॉम्स्की पदानुक्रम में एक टाइप -० व्याकरण ("अप्रतिबंधित") का उत्पादन करते हैं , जो संदर्भ-संवेदनशील व्याकरण की तुलना में अधिक शक्तिशाली है; अप्रतिबंधित व्याकरण ट्यूरिंग-पूर्ण है। एक संदर्भ-संवेदनशील (टाइप -1) व्याकरण एक उत्पादन के बाएं हाथ के संदर्भ के कई प्रतीकों की अनुमति देता है, लेकिन उसी संदर्भ को उत्पादन के दाहिने हाथ की ओर दिखाई देना चाहिए (इसलिए नाम "संदर्भ-संवेदनशील")। [१] प्रसंग-संवेदी व्याकरण रैखिक-बाउंड ट्यूरिंग मशीनों के बराबर हैं ।

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

भले ही, C ++ को कंप्यूटर द्वारा पार्स किया जा सकता है, इसलिए यह निश्चित रूप से ट्यूरिंग मशीन द्वारा पार्स किया जा सकता है। नतीजतन, एक अप्रतिबंधित व्याकरण इसे पहचान सकता है। वास्तव में ऐसा व्याकरण लिखना अव्यावहारिक होगा, यही कारण है कि मानक ऐसा करने की कोशिश नहीं करता है। (निचे देखो।)

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

लेकिन किसी भी घटना में, जैसे auto b = foo<IsPrime<234799>>::typen<1>();कि कार्यक्रम में लाइन 21 (यानी ), भाव बिल्कुल भी अस्पष्ट नहीं हैं; वे केवल संदर्भ के आधार पर अलग तरह से पार्स किए जाते हैं। समस्या की सरलतम अभिव्यक्ति में, कुछ विशिष्ट पहचानकर्ताओं की श्रेणीबद्धता इस बात पर निर्भर करती है कि उन्हें कैसे घोषित किया गया है (प्रकार और कार्य, उदाहरण के लिए), जिसका अर्थ है कि औपचारिक भाषा को इस तथ्य को पहचानना होगा कि दो मनमाना लंबाई समान कार्यक्रम समान हैं (घोषणा और उपयोग)। इसे "कॉपी" व्याकरण द्वारा मॉडल किया जा सकता है, जो कि व्याकरण है जो एक ही शब्द की दो लगातार सटीक प्रतियों को पहचानता है। पम्पिंग लेम्मा के साथ यह साबित करना आसान हैयह भाषा संदर्भ-मुक्त नहीं है। इस भाषा के लिए एक संवेदी-संवेदनशील व्याकरण संभव है, और इस प्रश्न के उत्तर में एक टाइप -० व्याकरण प्रदान किया गया है: /math/163830/context-sensitive-grammar-for-the-the- कॉपी-भाषा

यदि कोई सी ++ को पार्स करने के लिए एक संदर्भ-संवेदनशील (या अप्रतिबंधित) व्याकरण लिखने का प्रयास करता है, तो यह संभवतः ब्रह्मांड को स्क्रिबब्लिंग्स से भर देगा। C ++ को पार्स करने के लिए ट्यूरिंग मशीन लिखना एक समान रूप से असंभव उपक्रम होगा। यहां तक ​​कि सी ++ प्रोग्राम लिखना भी मुश्किल है, और जहां तक ​​मुझे पता है कि कोई भी सही साबित नहीं हुआ है। यही कारण है कि मानक एक पूर्ण औपचारिक व्याकरण प्रदान करने का प्रयास नहीं करता है, और यह तकनीकी अंग्रेजी में कुछ पार्सिंग नियमों को लिखने का विकल्प क्यों चुनता है।

सी ++ मानक में एक औपचारिक व्याकरण जैसा दिखता है, सी ++ भाषा के वाक्यविन्यास की पूरी औपचारिक परिभाषा नहीं है। यह प्रीप्रोसेसिंग के बाद भाषा की पूरी औपचारिक परिभाषा भी नहीं है, जिसे औपचारिक रूप देना आसान हो सकता है। (यह भाषा नहीं होगी, हालांकि: मानक द्वारा परिभाषित C ++ भाषा में प्रीप्रोसेसर शामिल है, और प्रीप्रोसेसर के संचालन को एल्गोरिदम के रूप में वर्णित किया गया है क्योंकि यह किसी भी व्याकरणिक औपचारिकता में वर्णन करना बहुत कठिन होगा। यह उस अनुभाग में है। मानक जहां लेक्सिकल अपघटन का वर्णन किया गया है, उन नियमों सहित जहां इसे एक से अधिक बार लागू किया जाना चाहिए।)

विभिन्न व्याकरण (लेक्सिकल विश्लेषण के लिए दो अतिव्यापी व्याकरण, एक जो प्रीप्रोसेसिंग से पहले होता है और दूसरा, यदि आवश्यक हो, बाद में, "सिंटैक्टिक" व्याकरण) को इस महत्वपूर्ण नोट के साथ परिशिष्ट ए में एकत्र किया जाता है (जोर जोड़ा):

C ++ सिंटैक्स का यह सारांश समझ में सहायता के लिए है। यह भाषा का सटीक विवरण नहीं है । विशेष रूप से, यहाँ वर्णित व्याकरण मान्य C ++ निर्माण के एक सुपरसेट को स्वीकार करता है । घोषणा से अभिव्यक्ति को अलग करने के लिए वितरण नियम (6.8, 7.1, 10.2) लागू होना चाहिए। इसके अलावा, अभिगम नियंत्रण, अस्पष्टता, और प्रकार के नियमों का उपयोग सिंटैक्टिक रूप से मान्य लेकिन अर्थहीन निर्माणों को हटाने के लिए किया जाना चाहिए।

अंत में, यहाँ वादा किया कार्यक्रम है। पंक्ति 21 वाक्यविन्यास रूप से सही है यदि और केवल यदि N IsPrime<N>प्राइम है। अन्यथा, typenएक पूर्णांक है, कोई टेम्पलेट नहीं है, इसलिए typen<1>()इसे पार्स किया गया है, (typen<1)>()जो कि वाक्यविन्यास रूप से गलत है क्योंकि ()एक वाक्यात्मक रूप से मान्य अभिव्यक्ति नहीं है।

template<bool V> struct answer { answer(int) {} bool operator()(){return V;}};

template<bool no, bool yes, int f, int p> struct IsPrimeHelper
  : IsPrimeHelper<p % f == 0, f * f >= p, f + 2, p> {};
template<bool yes, int f, int p> struct IsPrimeHelper<true, yes, f, p> { using type = answer<false>; };
template<int f, int p> struct IsPrimeHelper<false, true, f, p> { using type = answer<true>; };

template<int I> using IsPrime = typename IsPrimeHelper<!(I&1), false, 3, I>::type;
template<int I>
struct X { static const int i = I; int a[i]; }; 

template<typename A> struct foo;
template<>struct foo<answer<true>>{
  template<int I> using typen = X<I>;
};
template<> struct foo<answer<false>>{
  static const int typen = 0;
};

int main() {
  auto b = foo<IsPrime<234799>>::typen<1>(); // Syntax error if not prime
  return 0;
}

[१] इसे अधिक तकनीकी रूप से रखने के लिए, एक संदर्भ-संवेदनशील व्याकरण में प्रत्येक उत्पादन का रूप होना चाहिए:

αAβ → αγβ

जहां Aएक गैर टर्मिनल और है α, βसंभवतः व्याकरण प्रतीकों में से खाली दृश्यों रहे हैं, और γएक गैर खाली अनुक्रम है। (व्याकरण के प्रतीक या तो टर्मिनल या गैर-टर्मिनल हो सकते हैं)।

इसे A → γकेवल संदर्भ में पढ़ा जा सकता है [α, β]। एक संदर्भ-मुक्त (टाइप 2) व्याकरण में, αऔर βखाली होना चाहिए।

यह पता चला है कि आप व्याकरण को "मोनोटोनिक" प्रतिबंध के साथ प्रतिबंधित कर सकते हैं, जहां हर उत्पादन फॉर्म का होना चाहिए:

α → βजहां |α| ≥ |β| > 0  ( |α|मतलब "की लंबाई α")

यह साबित करना संभव है कि मोनोटोनिक व्याकरण द्वारा मान्यता प्राप्त भाषाओं का सेट बिल्कुल वैसा ही है जैसा कि संदर्भ-संवेदनशील व्याकरण द्वारा मान्यता प्राप्त भाषाओं का सेट है, और यह अक्सर मामला है कि यह मोनोटोनिक व्याकरण पर आधार प्रमाणों के लिए आसान है। नतीजतन, यह "संदर्भ-संवेदनशील" देखने के लिए बहुत आम है क्योंकि इसका मतलब "मोनोटोनिक" था।


27
इसलिए न केवल यह संदर्भ के प्रति संवेदनशील है, बल्कि इसे किसी भी संदर्भ पर निर्भर करने के लिए बनाया जा सकता है, जिसे आप टेम्परिंग में पूरा कर सकते हैं।
पिल्ला

7
@ ओमहरदाद, ओपी "संदर्भ-संवेदनशील भाषा" कहता है, संदर्भ-संवेदनशील व्याकरण नहीं। अस्पष्टता एक व्याकरण की एक विशेषता है, न कि भाषा। भाषा वास्तव में संदर्भ-संवेदनशील है, लेकिन इसलिए नहीं कि इसके लिए एक विशेष व्याकरण अस्पष्ट है।
रिसी

2
ध्यान दें कि मेरा उदाहरण अस्पष्ट नहीं है। यह एक वैध कार्यक्रम की एक स्पष्ट अभिव्यक्ति है। यदि आप पंक्ति 21 में मान बदलते हैं, तो यह बीमार हो सकता है। लेकिन न तो मामले में यह अस्पष्ट है।
रिसी

5
मुझे एक संदेह है: जैसा कि आप दिखाते हैं, टेम्प्लेट मूल्यांकन का परिणाम एक अच्छी तरह से गठित और एक बीमार प्रोग्राम के बीच अंतर कर सकता है। टेम्प्लेट मूल्यांकन ट्यूरिंग-पूर्ण है। तो सही ढंग से यह निर्धारित नहीं किया जाएगा कि क्या भाषा में एक स्ट्रिंग है (C ++) को ट्यूरिंग-पूर्णता की आवश्यकता है? जैसा कि आप कहते हैं, एक संदर्भ-संवेदनशील भाषा "बस" एक "रैखिक बाउंड ऑटोमेटन" है, जो ट्यूरिंग-पूर्ण AFAIK नहीं है। या क्या आपका तर्क सी ++ मानक का उपयोग करता है जो टेम्पलेट मूल्यांकन गहराई सहित कुछ चीजों पर डालता है?

4
@AntonGolov: उस उदाहरण का मेरा मूल संस्करण सिर्फ इतना ही किया (आप इसे एक साधारण के लिए 0अंदर डालकर प्राप्त कर सकते हैं ()), लेकिन मुझे लगता है कि यह इस तरह से अधिक दिलचस्प है, क्योंकि यह दर्शाता है कि आपको पहचानने के लिए भी टेम्पलेट की आवश्यकता है एक स्ट्रिंग एक वाक्यात्मक रूप से सही C ++ प्रोग्राम है। यदि दोनों शाखाएँ संकलित होती हैं, तो मुझे इस तर्क के लिए कड़ी मेहनत करनी होगी कि अंतर "अर्थ" है। उत्सुकता से, यद्यपि मुझे अक्सर "वाक्य-विन्यास" को परिभाषित करने की चुनौती दी जाती है, किसी ने कभी भी "अर्थ" की परिभाषा की पेशकश नहीं की है, "सामान के अलावा मुझे नहीं लगता कि वाक्य-विन्यास" है :)
rici

115

सबसे पहले, आप ठीक ही मनाया वहाँ सी ++ मानक के अंत में व्याकरण में कोई संदर्भ संवेदनशील नियम हैं, ताकि व्याकरण है विषय से मुक्त।

हालाँकि, यह व्याकरण C ++ भाषा का ठीक-ठीक वर्णन नहीं करता है, क्योंकि यह गैर-C ++ प्रोग्राम जैसे कि उत्पादन करता है

int m() { m++; }

या

typedef static int int;

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

अब, (अज्ञानी) लोग (आमतौर पर भाषा सिद्धांतकार नहीं, लेकिन पार्सर डिजाइनर) आमतौर पर निम्नलिखित कुछ अर्थों में "संदर्भ-मुक्त नहीं" का उपयोग करते हैं

  • अस्पष्ट
  • बाइसन के साथ पार्स नहीं किया जा सकता है
  • एलएल (के), एलआर (के), एलएएलआर (के) या जो भी पार्सर-परिभाषित भाषा वर्ग उन्होंने नहीं चुना

मानक के पीछे का व्याकरण इन श्रेणियों को संतुष्ट नहीं करता है (अर्थात यह अस्पष्ट है, LL (k) नहीं है ...) इसलिए C ++ व्याकरण उनके लिए "संदर्भ-मुक्त नहीं" है। और एक अर्थ में, वे सही हैं यह एक काम C ++ पार्सर का उत्पादन करने के लिए बहुत मुश्किल है।

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


7
ambiguity doesn't have anything to do with context-sensitivityयह मेरा अंतर्ज्ञान भी था, इसलिए मैं किसी को (ए) सहमत देखकर खुश हूं, और (बी) इसे समझाऊं जहां मैं नहीं कर सकता था। मेरा मानना ​​है कि यह उन सभी तर्कों को अयोग्य ठहराता है जो आधारित हैं a b(c);, और मूल प्रश्न को आंशिक रूप से संतुष्ट करते हैं जिसका आधार संदर्भ संवेदनशीलता के दावों के "अक्सर सुना-सुनाया" होने के कारण अस्पष्टता के कारण होता है ... खासकर जब व्याकरण के लिए वास्तव में भी अस्पष्टता होती है। एमवीपी।
ऑर्बिट

6
@KonradRudolph: मानक क्या कहता है "एक कार्यान्वयन-परिभाषित मात्रा है जो पुनरावर्ती तात्कालिकता की कुल गहराई पर सीमा को निर्दिष्ट करती है, जिसमें एक से अधिक टेम्पलेट शामिल हो सकते हैं। तात्कालिकता में एक अनंत पुनरावृत्ति का परिणाम अपरिभाषित है।" (14.7.1p15) मेरा मतलब है कि इसका मतलब यह है कि प्रत्येक वैध सी ++ प्रोग्राम को समझने के लिए कार्यान्वयन की आवश्यकता नहीं है, न कि बहुत बड़ी पुनरावृत्ति गहराई वाले कार्यक्रम अमान्य हैं। केवल वही जिन्हें अमान्य के रूप में चिह्नित किया गया है, वे अनंत पुनरावृत्ति गहराई वाले हैं।
रिसी

3
@KonradRudolph: मेरा विवाद है कि यह "सामान्य संदर्भ" है। यह तथ्य कि मैंने उस जटिल लेख को पढ़ा है और इस छोटे से तथ्य को समझने के लिए इसे पर्याप्त रूप से समझना नहीं है, उसे प्रदर्शित करने के लिए पर्याप्त होना चाहिए। ऐसा नहीं है कि आपने कुछ ऐसा कहा है जैसे "कंप्यूटर आमतौर पर बिजली का उपयोग करते हैं", या "बिट्स सही या गलत हो सकते हैं"।
में ऑर्बिट

3
यदि यह तथ्य वास्तव में बहुत व्यापक रूप से ज्ञात है, तो मुझे लगता है कि यह एक संदर्भ खोजने की तुलना में यह आसान होगा कि लंबाई के बारे में बहस की जाए या नहीं कि किसी को प्रदान किया जाना चाहिए। रचनात्मक का उल्लेख नहीं है।
सैमुअल एडविन वार्ड

5
जहाँ तक मैं बता सकता हूँ, @ कोनराड से गलती हुई जब उन्होंने कहा कि "संवेदनशील संवेदनशील ट्यूरिंग के बराबर है।" (कम से कम, अगर वह "ट्यूरिंग एन्यूरिबल" को "ट्यूरिंग पूर्ण" द्वारा निरूपित कर रहा था), और तब से इस गलती को पहचानने में असमर्थ रहा है। यहाँ उचित समुचित समावेश संबंध के लिए एक संदर्भ दिया गया है: en.wikipedia.org/wiki/Chomsky_hierarchy
pnkfelix

61

हाँ। निम्न अभिव्यक्ति के प्रकार के संदर्भ के आधार पर संचालन का एक अलग क्रम है :

संपादित करें: जब ऑपरेशन का वास्तविक क्रम बदलता है, तो इसे सजाने के पहले एक "नियमित" संकलक का उपयोग करना अविश्वसनीय रूप से कठिन हो जाता है जो एक अनिर्दिष्ट एएसटी को पार्स करता है (टाइप जानकारी का प्रचार करना)। उल्लेखित अन्य संदर्भ संवेदनशील चीजें इसकी तुलना में "बल्कि आसान" हैं (ऐसा नहीं है कि टेम्पलेट मूल्यांकन बिल्कुल आसान है)।

#if FIRST_MEANING
   template<bool B>
   class foo
   { };
#else
   static const int foo = 0;
   static const int bar = 15;
#endif

के बाद:

static int foobar( foo < 2 ? 1 < 1 : 0 > & bar );

सी के लिए उस समस्या को हल क्यों नहीं किया जा सकता है, यह याद करके कि किस प्रकार की परिभाषाएँ गुंजाइश में हैं?
ब्लिसॉर्बलेड

1
@ ब्लेज़रब्लेड: एक कंपाइलर "क्लीन" बनाने का एक तरीका है कि किसी कार्य को एक श्रृंखला में स्वतंत्र चरणों में अलग किया जाए, जैसे इनपुट से एक पार्स ट्री बनाना और उसके बाद एक चरण जो कि टाइप विश्लेषण करता है। C ++ आपको या तो 1 पर मजबूर करता है) इन चरणों को एक या 2 में मर्ज करता है) दस्तावेज़ को दोनों / सभी संभव व्याख्याओं के अनुसार पार्स करता है, और प्रकार रिज़ॉल्यूशन चरणों को सही व्याख्या के लिए संकीर्ण करने की अनुमति देता है।
सैम हैरवेल

@ 280Z28: सहमत हैं, लेकिन यह सी के लिए भी मामला है; मुझे लगता है कि इस सवाल का एक अच्छा जवाब यह दिखाना चाहिए कि सी ++ सी से भी बदतर क्यों है। पीएचडी थीसिस यहां से जुड़ी है जो यह करती है कि: stackoverflow.com/a/243447/53974
Blaisorblade

26

अपने प्रश्न का उत्तर देने के लिए, आपको दो अलग-अलग प्रश्नों को अलग करने की आवश्यकता है।

  1. लगभग हर प्रोग्रामिंग भाषा का मात्र वाक्य-विन्यास संदर्भ-मुक्त है। आमतौर पर, इसे एक विस्तारित बैकस-नौर फॉर्म या संदर्भ-मुक्त ग्राम के रूप में दिया जाता है।

  2. हालाँकि, भले ही कोई प्रोग्राम प्रोग्रामिंग भाषा द्वारा परिभाषित संदर्भ-मुक्त ग्राम के अनुरूप हो, यह आवश्यक रूप से एक वैध कार्यक्रम नहीं है। कई गैर-संदर्भ-मुक्त पॉपर्टीज हैं जिन्हें एक कार्यक्रम को एक वैध कार्यक्रम होने के लिए संतुष्ट करना पड़ता है। उदाहरण के लिए, सबसे सरल ऐसी संपत्ति चर का दायरा है।

निष्कर्ष निकालना, C ++ संदर्भ-मुक्त है या नहीं, यह आपके द्वारा पूछे गए प्रश्न पर निर्भर करता है।


5
यह ध्यान रखना दिलचस्प है कि आपको अपनी प्रोग्रामिंग भाषा के लिए CFG प्राप्त करने के लिए अक्सर "मात्र वाक्यविन्यास" स्तर कम रखना होगा। उदाहरण के लिए C को लें। आप सोच सकते हैं कि सी में एक साधारण चर घोषणा के लिए व्याकरण नियम होगा VARDECL : TYPENAME IDENTIFIER, लेकिन आपके पास ऐसा नहीं हो सकता है, क्योंकि आप सीएफ स्तर पर अन्य पहचानकर्ताओं से टाइप नामों को अलग नहीं कर सकते हैं। एक अन्य उदाहरण: सीएफ स्तर पर, आप यह तय नहीं कर सकते कि पार्स a*bडिक्लेरेशन ( bटाइप पॉइंटर के लिए a) या मल्टीप्लेक्शन के रूप में पार्स किया जाए ।
लाक

2
@ एलसीसी: हां, इसे इंगित करने के लिए धन्यवाद! वैसे, मुझे यकीन है कि मात्र वाक्यविन्यास के लिए एक अधिक सामान्यतः प्रयुक्त तकनीकी शब्द है । क्या कोई सही शब्द है?
दान

4
@ दान: आप जिस बारे में बात कर रहे हैं, वह कुछ संदर्भ-मुक्त व्याकरण द्वारा दी गई भाषा का एक अनुमान है। निश्चित रूप से इस तरह के एक अनुमान परिभाषा के अनुसार सह-मुक्त है। यह वह अर्थ है जिसमें प्रोग्रामिंग भाषाओं की चर्चा करते समय "वाक्यविन्यास" का अक्सर उपयोग किया जाता है।
रीइनियरिएपोस्ट

13

आप Bjarne Stroustrup द्वारा C ++ के डिज़ाइन और विकास पर एक नज़र डालना चाह सकते हैं । इसमें वह C ++ के शुरुआती संस्करण को पार्स करने के लिए yacc (या समान) का उपयोग करने की कोशिश कर रहे अपनी समस्याओं का वर्णन करता है, और इच्छा करता है कि उसने इसके बजाय पुनरावर्ती वंश का उपयोग किया हो।


वाह धन्यवाद। मुझे आश्चर्य है कि अगर यह वास्तव में किसी भी कृत्रिम भाषा को पार्स करने के लिए सीएफजी से अधिक शक्तिशाली कुछ का उपयोग करने के बारे में सोचने के लिए समझ में आता है ।
डर्विन थंक

C ++ के कबाड़ को समझने के लिए महान पुस्तक। मैं सुझाव देता हूं कि यह समझने के लिए कि C ++ ऑब्जेक्ट कैसे काम करता है, Lippman's C ++ ऑब्जेक्ट मॉडल के अंदर है। हालांकि दोनों थोड़ा दिनांकित हैं लेकिन वे अभी भी एक अच्छे पढ़े लिखे हैं।
मैट प्राइस

"मेटा-एस" क्विन टायलर जैक्सन द्वारा एक संदर्भ-संवेदनशील पार्सिंग इंजन है। मैंने इसका उपयोग नहीं किया है, लेकिन वह एक प्रभावशाली कहानी बताता है। कॉम्प.कॉम में अपनी टिप्पणी देखें, और rnaparse.com/MetaS%20defined.htm
इरा बैक्सटर

@ आईबैक्सटर: आज आपका एक्स-रे एमआईए है - और सॉफ्टवेयर के ठोस संदर्भ मायावी लगते हैं (Google खोज किसी भी अच्छे लीड को प्रदान नहीं करता है, या तो 'साइट: rnaparse.com मेटा-एस' या 'क्वैस्टन जैकसन मेटा- के साथ) s '; बिट्स और टुकड़े हैं, लेकिन meta-s.com एक गैर-जानकारीपूर्ण वेब-साइट की ओर जाता है, उदाहरण के लिए)।
जोनाथन लेफ़लर

@ जोनाथन: थोड़ी देर हो गई, बस आपकी शिकायत पर गौर किया। दुनो क्यों लिंक खराब है, मैंने सोचा कि जब मैंने इसे लिखा था तो यह अच्छा था। Quinn comp.compilers में बहुत सक्रिय हुआ करते थे। Google परतदार लग रहा है, यह सब मुझे मिल सकता है: group.google.com/group/comp.compilers/browse_thread/thread/… IIRC, उसने MetaS के अधिकारों के लिए हवाई में फिर से बाजार में कुछ संगठन के अधिकारों पर हस्ताक्षर किए। यह देखते हुए कि यह कितना अजीब था, IMHO अपने डेथ वारंट पर हस्ताक्षर कर रहा है। बहुत चालाक योजना की तरह लग रहा था।
इरा बैक्सटर

12

हाँ C ++ संदर्भ संवेदनशील है, बहुत ही संवेदनशील संदर्भ है। आप केवल संदर्भ मुक्त पार्सर का उपयोग करके फ़ाइल के माध्यम से पार्सिंग करके सिंटैक्स ट्री का निर्माण नहीं कर सकते क्योंकि कुछ मामलों में आपको पिछले ज्ञान से प्रतीक को जानने की आवश्यकता है (यानी पार्स करते समय एक प्रतीक तालिका का निर्माण करें)।

पहला उदाहरण:

A*B;

क्या यह गुणन अभिव्यक्ति है?

या

क्या यह Bचर का एक प्रकार का सूचक है A?

यदि A एक चर है, तो यह एक अभिव्यक्ति है, यदि A टाइप है, तो यह एक सूचक घोषणा है।

दूसरा उदाहरण:

A B(bar);

क्या यह फंक्शन प्रोटोटाइप barप्रकार का तर्क है ?

या

क्या यह घोषित Bप्रकार है Aऔर ए के कंस्ट्रक्टर को barएनीलाइज़र के रूप में स्थिर बनाता है?

आपको फिर से जानना होगा कि क्या barएक चर या प्रतीक तालिका से एक प्रकार है।

तीसरा उदाहरण:

class Foo
{
public:
    void fn(){x*y;}
    int x, y;
};

यह मामला है जब पार्सिंग करते समय प्रतीक तालिका का निर्माण मदद नहीं करता है क्योंकि x और y की घोषणा फ़ंक्शन परिभाषा के बाद आती है। तो आपको पहले कक्षा की परिभाषा के माध्यम से स्कैन करने की आवश्यकता है, और x * y को एक अभिव्यक्ति है, और एक सूचक घोषणा या जो कुछ भी नहीं बताने के लिए दूसरी परिभाषा में विधि परिभाषाओं को देखें।


1
A B();फ़ंक्शन परिभाषा में भी एक फ़ंक्शन घोषणा है। सबसे
डरावने

"आप फ़ाइल के माध्यम से बस पार्स करके वाक्यविन्यास के पेड़ का निर्माण नहीं कर सकते" FALSE। मेरा जवाब देखिए।
इरा बैक्सटर

10

C ++ को GLR पार्सर के साथ पार्स किया गया है। इसका मतलब है कि स्रोत कोड को पार्स करने के दौरान, पार्सर अस्पष्टता का सामना कर सकता है, लेकिन इसे जारी रखना चाहिए और निर्णय लेना चाहिए कि बाद में किस व्याकरण नियम का उपयोग करना है ।

यह भी देखो,

C ++ को LR (1) पार्सर से पार्स क्यों नहीं किया जा सकता है?


याद रखें कि संदर्भ-मुक्त व्याकरण एक प्रोग्रामिंग भाषा सिंटैक्स के सभी नियमों का वर्णन नहीं कर सकता है । उदाहरण के लिए, एक अभिव्यक्ति प्रकार की वैधता की जांच करने के लिए, व्याकरण का उपयोग किया जाता है।

int x;
x = 9 + 1.0;

आप संदर्भ-मुक्त व्याकरण के साथ निम्नलिखित नियम का वर्णन नहीं कर सकते हैं : असाइनमेंट का राइट साइड लेफ्ट साइड साइड का एक ही प्रकार का होना चाहिए।


4
अधिकांश C ++ पार्सर GLR पार्सिंग तकनीक का उपयोग नहीं करते हैं। जीसीसी नहीं करता है। कुछ करते हैं। जो करता है, उसके लिए semanticdesigns.com/Products/FrontEnds/CppFrontEnd.html देखें ।
इरा बैक्सटर

10

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

यह यहां भी पूछा गया है: संदर्भ-संवेदनशीलता बनाम अस्पष्टता

यहाँ एक संदर्भ-मुक्त व्याकरण है:

<a> ::= <b> | <c>
<b> ::= "x"
<c> ::= "x"

यह अस्पष्ट है, इसलिए इनपुट "x" को पार्स करने के लिए आपको कुछ संदर्भ की आवश्यकता है (या अस्पष्टता के साथ रहते हैं, या "चेतावनी: E8271 - इनपुट लाइन 115 में अस्पष्ट है")। लेकिन यह निश्चित रूप से एक संदर्भ-संवेदनशील व्याकरण नहीं है।


किसी उत्पादन के बाएँ हाथ पर कई चिन्ह होने से इस समस्या का समाधान कैसे होता है? मुझे नहीं लगता कि यह जवाब सवाल का जवाब दे रहा है।
user541686

1
मेरा जवाब पहले वाक्य के जवाब में है: "मैं अक्सर दावे सुनता हूं कि सी ++ एक संदर्भ-संवेदनशील भाषा है।" यदि वे दावे अनौपचारिक रूप से "संदर्भ-संवेदनशील" अभिव्यक्ति का उपयोग करते हैं, तो कोई समस्या नहीं है। मुझे नहीं लगता कि C ++ औपचारिक रूप से संदर्भ-संवेदनशील है।
ओमरी बरेल

मुझे लगता है कि सी ++ है औपचारिक रूप से संदर्भ के प्रति संवेदनशील है, लेकिन समस्या मैं आ रही हैं कि मुझे समझ नहीं आता कि कैसे एक संदर्भ के प्रति संवेदनशील व्याकरण सी ++ पार्स करने होगा एक CFG से कोई भी और सफलता के लिए होता है।
user541686

6

कोई भी अल्गोल जैसी भाषा संदर्भ-मुक्त नहीं है, क्योंकि उनके पास ऐसे नियम हैं जो अभिव्यक्तियों और कथनों को बाध्य करते हैं जो पहचानकर्ता उनके प्रकार के आधार पर प्रकट हो सकते हैं, और क्योंकि बयानों की संख्या पर कोई सीमा नहीं है जो घोषणा और उपयोग के बीच हो सकती है।

सामान्य समाधान एक संदर्भ-मुक्त पार्सर लिखना है जो वास्तव में मान्य कार्यक्रमों के एक सुपरसेट को स्वीकार करता है और संदर्भ-संवेदनशील भागों को तदर्थ में रखता है। नियमों "अर्थ" कोड है।

C ++ इसके आगे अच्छी तरह से चला जाता है, इसके ट्यूरिंग-पूर्ण टेम्पलेट सिस्टम के लिए धन्यवाद। स्टैक ओवरफ्लो प्रश्न 794015 देखें ।




5

यह संदर्भ के प्रति संवेदनशील है, जैसा a b(c);कि दो मान्य पार्स हैं- घोषणा और परिवर्तनशील। जब आप कहते हैं, "यदि cएक प्रकार है", तो यह संदर्भ है, वहीं, और आपने बिल्कुल वर्णन किया है कि कैसे C ++ इसके प्रति संवेदनशील है। यदि आपके पास "क्या है" का संदर्भ नहीं हैc ?" आप इस असंदिग्ध रूप से पार्स नहीं कर सकते।

यहाँ, संदर्भ टोकन के विकल्प में व्यक्त किया गया है - यदि कोई नाम टाइप करता है तो पार्सर एक पहचानकर्ता को एक टाइपकेन टोकन के रूप में पढ़ता है। यह सबसे सरल संकल्प है, और संदर्भ-संवेदनशील (इस मामले में) होने की जटिलता से बचा जाता है।

संपादित करें: बेशक, संदर्भ संवेदनशीलता के अधिक मुद्दे हैं, मैंने केवल आपके द्वारा दिखाए गए पर ध्यान केंद्रित किया है। खासतौर पर इसके लिए टेम्प्लेट्स काफी खराब होते हैं।


1
इसके अलावा a<b<c>>d, सही है? (आपका उदाहरण वास्तव में सी से एक क्लासिक है , जहां यह संदर्भ-मुक्त होने के लिए एकमात्र बाधा है।)
केरेक एसबी

मुझे लगता है कि यह एक लेक्सिंग समस्या है। लेकिन निश्चित रूप से एक ही श्रेणी में है, हाँ।
पिल्ला

2
प्रश्नकर्ता यह नहीं पूछता कि यह C से अधिक संदर्भ-संवेदनशील कैसे है, केवल यह दिखाने के लिए कि यह संदर्भ-संवेदनशील है।
पिल्ला

तो .. है सी ++ अधिक संदर्भ के प्रति संवेदनशील सी से?
केरेक एसबी

2
@DeadMG मुझे नहीं लगता कि आप सवाल का जवाब दे रहे हैं (मुझे नहीं लगता कि मैं भी था)। किसी उत्पादन के बाईं ओर टर्मिनल होने से इस समस्या का समाधान कैसे होता है?
user541686

5

C ++ मानक में प्रस्तुतियों को संदर्भ-मुक्त लिखा जाता है, लेकिन जैसा कि हम सभी जानते हैं कि वास्तव में भाषा को सटीक रूप से परिभाषित नहीं किया गया है। वर्तमान भाषा में अधिकांश लोग अस्पष्टता के रूप में जो कुछ देखते हैं (मुझे विश्वास है) को एक संदर्भ संवेदनशील व्याकरण के साथ स्पष्ट रूप से हल किया जा सकता है।

सबसे स्पष्ट उदाहरण के लिए, आइए मोस्ट वैक्सिंग पार्स पर विचार करें int f(X);:। यदि Xएक मूल्य है, तो यह fएक चर के रूप में परिभाषित करता है जिसे इसके साथ आरंभ किया जाएगा X। यदि Xएक प्रकार है, तो यह एक प्रकार के fएकल पैरामीटर लेने वाले फ़ंक्शन के रूप में परिभाषित करता हैX

व्याकरणिक दृष्टिकोण से देखने पर, हम इसे इस तरह देख सकते हैं:

A variable_decl ::= <type> <identifier> '(' initializer ')' ';'

B function_decl ::= <type> <identifier> '(' param_decl ')' ';'

A ::= [declaration of X as value]
B ::= [declaration of X as type]

बेशक, पूरी तरह से सही होने के लिए हमें अन्य प्रकार की घोषणाओं की हस्तक्षेप की संभावना के लिए कुछ अतिरिक्त "सामान" जोड़ने की आवश्यकता होगी (यानी, ए और बी दोनों वास्तव में "एक्स के रूप में घोषित करने सहित घोषणाएं होनी चाहिए ..." , या उस आदेश पर कुछ)।

यह अभी भी एक सामान्य CSG से अलग है, हालांकि (या कम से कम जो मुझे उनकी याद दिलाता है)। यह एक प्रतीक तालिका के निर्माण पर निर्भर करता है - वह हिस्सा जो विशेष रूप से पहचानता हैX रूप से एक प्रकार या मूल्य के रूप में , न कि केवल कुछ प्रकार के बयान से पहले, लेकिन सही प्रतीक / पहचानकर्ता के लिए सही प्रकार का बयान।

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


(संदर्भ-मुक्त) निर्माण सबसे अच्छे पार्सिंग को काफी अच्छी तरह से परिभाषित करते हैं, इसलिए इसे एक संदर्भ मुक्त पार्सिंग इंजन द्वारा पार्स किया जा सकता है। यह कि पार्स पूरा होने के बाद तक कई व्याख्याओं में से किसकी व्याख्या करने की समस्या को मान्य किया जाता है, लेकिन सिर्फ पार्सर और नाम रिज़ॉल्वर की इंजीनियरिंग को आसान बनाते हैं, क्योंकि वे पारंपरिक सी ++ पार्सर की तरह पेचीदा होते हैं। एएसटी को सबसे अधिक पार्सिंग के लिए देखें: stackoverflow.com/questions/17388771/…
इरा बैक्सटर

5

गैर-संदर्भ-मुक्त व्याकरण के सबसे सरल मामले में टेम्पलेट्स से जुड़े पार्सिंग भाव शामिल हैं।

a<b<c>()

यह या तो पार्स कर सकता है

template
   |
   a < expr > ()
        |
        <
      /   \
     b     c

या

 expr
   |
   <
 /   \
a   template
     |
     b < expr > ()
          |
          c

दो एएसटी को केवल 'ए' - पूर्व एएसटी की घोषणा की जांच करके ही खंडित किया जा सकता है यदि 'ए' एक टेम्पलेट है, या बाद में नहीं तो।


मेरा मानना ​​है कि सी ++ 11 बाद की व्याख्या को अनिवार्य करता है, और आपको पूर्व में ऑप्ट-इन में पार्न्स को जोड़ना होगा।
जोसेफ गार्विन

1
@ जोसेफगर्विन, नहीं। C ++ जनादेश जो <एक ब्रैकेट होना चाहिए अगर वह हो सकता है (उदाहरण के लिए, यह एक पहचानकर्ता का अनुसरण करता है जिसका नाम टेम्पलेट है)। C ++ 11 ने उस आवश्यकता को जोड़ा >और जो >>कि उपयोग किए जाने योग्य है, यदि क्लोज ब्रैकेट के रूप में पहले वर्ण की व्याख्या की जाए। यह a<b>c>जहां aएक टेम्पलेट है , वहां के पार्सिंग को प्रभावित करता है लेकिन इसका कोई प्रभाव नहीं पड़ता है a<b<c>
रिसी

@ हारून: यह कैसे सरल है a();(जो expr.callया तो है expr.type.conv)?
रिसी

@rici: उफ़, मुझे नहीं पता था कि यह असममित था।
जोसेफ गार्विन 14

5
क्या आप अस्पष्टता , या संदर्भ संवेदनशीलता का वर्णन कर रहे हैं?
corazza

4

C ++ टेम्प्लेट को ट्यूरिंग पावरफुल दिखाया गया है। हालांकि एक औपचारिक संदर्भ नहीं है, यहाँ उस संबंध में देखने के लिए एक जगह है:

http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html

मैं एक अनुमान (एक लोककथाओं के रूप में पुराना और संक्षिप्त सीएसीएम सबूत दिखाऊंगा कि 60 में ALGOL एक CFG द्वारा रिप्रेजेंट नहीं किया जा सकता है) और कहता है कि C ++ इसलिए सही ढंग से केवल एक CFG द्वारा पार्स नहीं किया जा सकता है। सीएफजी, विभिन्न टीपी तंत्र के साथ मिलकर या तो एक पेड़ के पास या कटौती की घटनाओं के दौरान - यह एक और कहानी है। एक सामान्य अर्थ में, हॉल्टिंग समस्या के कारण, कुछ C ++ प्रोग्राम मौजूद हैं जिन्हें सही / गलत नहीं दिखाया जा सकता है लेकिन फिर भी यह सही / गलत है।

{पीएस- मेटा-एस के लेखक के रूप में (ऊपर कई लोगों द्वारा उल्लिखित) - मैं सबसे अधिक आश्वस्त रूप से कह सकता हूं कि थॉटिक न तो दोषपूर्ण है, न ही मुफ्त में उपलब्ध सॉफ्टवेयर है। शायद मैंने अपनी प्रतिक्रिया के इस संस्करण को इस तरह से शब्दों में पिरोया है कि मैं नष्ट न हो जाऊं और न ही मतदान करूं -३।


3

C ++ संदर्भ मुक्त नहीं है। मैंने इसे कुछ समय पहले कंपाइलर लेक्चर में सीखा था। एक त्वरित खोज ने यह लिंक दिया, जहां "सिंटैक्स या शब्दार्थ" अनुभाग बताता है कि C और C ++ संदर्भ मुक्त क्यों नहीं हैं:

विकिपीडिया टॉक: संदर्भ-मुक्त व्याकरण

सादर,
ओवंस


2

जाहिर है, अगर आप प्रश्नवाचक शब्द लेते हैं, तो पहचानकर्ता वाली लगभग सभी भाषाएं संदर्भ के प्रति संवेदनशील होती हैं।

यह जानने की जरूरत है कि क्या एक पहचानकर्ता एक प्रकार का नाम (एक वर्ग का नाम, एक नाम जो typedef द्वारा शुरू किया गया है, एक टाइपमेन टेम्प्लेट पैरामीटर है), एक टेम्पलेट नाम या कोई अन्य नाम सही रूप से पहचानकर्ता के कुछ उपयोग करने में सक्षम है। उदाहरण के लिए:

x = (name)(expression);

एक कास्ट है अगर nameएक प्रकार का नाम है और एक फ़ंक्शन कॉल है यदि nameएक फ़ंक्शन नाम है। एक अन्य मामला तथाकथित "मोस्ट वेस्टिंग पार्स" है जहां परिवर्तनीय परिभाषा और फ़ंक्शन डिक्लेरेशन में अंतर करना संभव नहीं है (एक नियम है जो कह रहा है कि यह फ़ंक्शन डिक्लेरेशन है)।

उस कठिनाई ने typenameऔर templateआश्रित नामों के साथ की आवश्यकता को पेश किया है । जहाँ तक मुझे पता है कि C ++ के शेष संदर्भ संवेदी नहीं हैं (अर्थात इसके लिए एक संदर्भ मुक्त व्याकरण लिखना संभव है)।


2

मेटा-एस "क्विन टायलर जैक्सन द्वारा एक संदर्भ-संवेदनशील पार्सिंग इंजन है। मैंने इसका उपयोग नहीं किया है, लेकिन वह एक प्रभावशाली कहानी बताता है। कॉम्प.कॉम में अपनी टिप्पणियों की जाँच करें, और rnaparse.com/MetaS%Eddefined.htm देखें। - इरा बैक्सटर 25 जुलाई को 10:42 बजे

सही लिंक पार्सिंग एनजाइन्स है

मेटा-एस एक डिफेक्ट कंपनी की संपत्ति थी जिसे थॉथिक कहा जाता था। मैं मेटा-एस की नि: शुल्क प्रतिलिपि किसी को भी भेज सकता हूं और मैंने अनुसंधान पार्सिंग अनुसंधान में इसका उपयोग किया है। कृपया ध्यान दें "उदाहरण pseudoknot व्याकरण" उदाहरण के फ़ोल्डरों में शामिल एक गैर-जैव सूचना विज्ञान, अमित्र प्रोग्रामर द्वारा लिखा गया था और मूल रूप से काम नहीं करता है। मेरे व्याकरण एक अलग दृष्टिकोण लेते हैं और काफी अच्छी तरह से काम करते हैं।


यह वास्तव में एक दिलचस्प खोज है।
डेरविन थंक

0

यहां एक बड़ा मुद्दा यह है कि शब्द "संदर्भ-मुक्त" और "संदर्भ-संवेदनशील" कंप्यूटर विज्ञान के भीतर थोड़े अनपेक्षित हैं। सी ++ के लिए, संदर्भ-संवेदनशीलता अस्पष्टता की तरह दिखती है, लेकिन सामान्य रूप से यह जरूरी नहीं है।

C / ++ में, यदि किसी फ़ंक्शन बॉडी के अंदर केवल एक स्टेटमेंट की अनुमति है। यह संदर्भ-संवेदनशील बनाने के लिए प्रतीत होता है, है ना? नहीं। संदर्भ-मुक्त व्याकरणों को वास्तव में उस संपत्ति की आवश्यकता नहीं होती है जहां आप कोड की कुछ पंक्ति को निकाल सकते हैं और यह निर्धारित कर सकते हैं कि क्या यह मान्य है। यह वास्तव में संदर्भ-मुक्त का मतलब नहीं है। यह वास्तव में सिर्फ एक लेबल है जो अस्पष्ट रूप से संबंधित है कि यह कैसा लगता है।

अब, यदि किसी फ़ंक्शन बॉडी के भीतर एक स्टेटमेंट को तत्काल व्याकरणिक पूर्वजों (जैसे कि एक पहचानकर्ता एक प्रकार या चर का वर्णन करता है) के बाहर परिभाषित किसी चीज़ पर निर्भर करता है, जैसा कि a * b;मामले में है, तो यह वास्तव में, संदर्भ-संवेदनशील है। यहां कोई वास्तविक अस्पष्टता नहीं है; यदि aयह एक प्रकार का और एक गुणन है तो एक सूचक की घोषणा के रूप में पार्स किया जाएगा ।

संदर्भ-संवेदनशील होने के लिए जरूरी नहीं कि "कठिन परिश्रम" हो। सी वास्तव में इतना कठिन नहीं है क्योंकि कुख्यात a * b;"अस्पष्टता" को typedefपहले से सामना करने वाले प्रतीक तालिका के साथ हल किया जा सकता है । उस मामले को हल करने के लिए इसे किसी भी मनमाने ढंग से टेंपरेचर इंस्टेंटिएशन (जो कि ट्यूरिंग कंप्लीट साबित हुआ है) की आवश्यकता नहीं है, जैसे C ++ इस अवसर पर होता है। यह वास्तव में एक सी प्रोग्राम लिखना संभव नहीं है जो समय की एक सीमित मात्रा में संकलित नहीं करेगा, भले ही इसमें वही संदर्भ-संवेदनशीलता हो जो सी ++ करता है।

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


-4

यह उत्तर कहता है कि C ++ संदर्भ-मुक्त नहीं है ... इसका एक निहितार्थ (उत्तरदाता द्वारा नहीं) है कि इसे पार्स नहीं किया जा सकता है, और उत्तर एक कठिन कोड उदाहरण प्रस्तुत करता है जो एक अवैध C ++ प्रोग्राम का उत्पादन करता है यदि एक निश्चित निरंतर नहीं है अभाज्य संख्या।

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

आराम करने के लिए पार्सबिलिटी के बारे में सवाल सेट करने के लिए, मैं अनुभवजन्य साक्ष्य प्रदान करता हूं कि सी ++ के लिए संदर्भ-मुक्त व्याकरण हैं, जो कि मौजूदा जीएलआर के साथ पार्सिंग द्वारा स्रोत पाठ के संदर्भ-मुक्त पार्स के लिए एएसटी का उत्पादन करने के लिए इस्तेमाल किया जा सकता है। -पर आधारित उपकरण जो एक स्पष्ट व्याकरण द्वारा संचालित होता है।

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

यदि आपका मतलब क्या है, यह निर्धारित करें कि क्या स्रोत प्रोग्राम वैध सी ++ स्रोत कार्यक्रमों के सेट का सदस्य है , तो मैं सहमत हूं कि समस्या बहुत कठिन है। लेकिन यह पार्स नहीं कर रहा है कि समस्या है।

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

मूल मान 234799 के साथ एएसटी पर टूल का नाम / प्रकार रिज़ॉल्वर चलाना सफल होता है। 234797 मान के साथ नाम रिज़ॉल्वर त्रुटि संदेश के साथ (जैसा कि अपेक्षित) विफल रहता है, "टाइपेन एक प्रकार नहीं है।" और इस प्रकार वह संस्करण मान्य C ++ प्रोग्राम नहीं है।

967 tree nodes in tree.
15 ambiguity nodes in tree.
(translation_unit@Cpp~GCC5=2#6b11a20^0 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
 (declaration_seq@Cpp~GCC5=1021#6b06640^1#6b11a20:1 {10} Line 1 Column 1 File C:/temp/prime_with_templates.cpp
  (pp_declaration_seq@Cpp~GCC5=1022#6b049a0^1#6b06640:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
   (declaration@Cpp~GCC5=1036#6b04980^1#6b049a0:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
   |(template_declaration@Cpp~GCC5=2079#6b04960^1#6b04980:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
   | (template_parameter_list@Cpp~GCC5=2082#6afbde0^1#6b04960:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |  (template_parameter@Cpp~GCC5=2085#6afbd80^1#6afbde0:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |   (parameter_declaration@Cpp~GCC5=1611#6afbd40^1#6afbd80:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |   |(basic_decl_specifier_seq@Cpp~GCC5=1070#6afb880^1#6afbd40:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |   | (decl_specifier@Cpp~GCC5=1073#6afb840^1#6afb880:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |   |  (trailing_type_specifier@Cpp~GCC5=1118#6afb7e0^1#6afb840:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
   |   |   (simple_type_specifier@Cpp~GCC5=1138#6afb7a0^1#6afb7e0:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |  )trailing_type_specifier#6afb7e0
   |   | )decl_specifier#6afb840
   |   |)basic_decl_specifier_seq#6afb880
   |   |(ptr_declarator@Cpp~GCC5=1417#6afbc40^1#6afbd40:2 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
   |   | (noptr_declarator@Cpp~GCC5=1421#6afbba0^1#6afbc40:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
   |   |  (declarator_id@Cpp~GCC5=1487#6afbb80^1#6afbba0:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   (id_expression@Cpp~GCC5=317#6afbaa0^1#6afbb80:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   |(unqualified_id@Cpp~GCC5=319#6afb9c0^1#6afbaa0:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   | (IDENTIFIER@Cpp~GCC5=3368#6afb780^1#6afb9c0:1[`V'] Line 1 Column 15 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |)unqualified_id#6afb9c0
   |   |   )id_expression#6afbaa0
   |   |  )declarator_id#6afbb80
   |   | )noptr_declarator#6afbba0
   |   |)ptr_declarator#6afbc40
   |   )parameter_declaration#6afbd40
   |  )template_parameter#6afbd80
   | )template_parameter_list#6afbde0
   | (declaration@Cpp~GCC5=1033#6b04940^1#6b04960:2 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |  (block_declaration@Cpp~GCC5=1050#6b04920^1#6b04940:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   (simple_declaration@Cpp~GCC5=1060#6b04900^1#6b04920:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   |(basic_decl_specifier_seq@Cpp~GCC5=1070#6b048e0^1#6b04900:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   | (decl_specifier@Cpp~GCC5=1073#6b048c0^1#6b048e0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   |  (type_specifier@Cpp~GCC5=1110#6b048a0^1#6b048c0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   |   (class_specifier@Cpp~GCC5=1761#6b04880^1#6b048a0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   |   |(class_head@Cpp~GCC5=1763#6afb980^1#6b04880:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
   |   |   | (class_key@Cpp~GCC5=1791#6afbca0^1#6afb980:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp)class_key
   |   |   | (IDENTIFIER@Cpp~GCC5=3368#6afbcc0^1#6afb980:2[`answer'] Line 1 Column 25 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   | (optional_base_clause@Cpp~GCC5=1872#6afba60^1#6afb980:3 Line 1 Column 32 File C:/temp/prime_with_templates.cpp)optional_base_clause
   |   |   |)class_head#6afb980
   |   |   |(member_specification@Cpp~GCC5=1794#6b042e0^1#6b04880:2 {2} Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   | (member_declaration_or_access_specifier@Cpp~GCC5=1806#6b04060^1#6b042e0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |  (member_declaration@Cpp~GCC5=1822#6b04040^1#6b04060:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   (function_definition@Cpp~GCC5=1632#6b04020^1#6b04040:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |(function_head@Cpp~GCC5=1673#6afbec0^1#6b04020:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   | (ptr_declarator@Cpp~GCC5=1417#6afbfe0^1#6afbec0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |  (noptr_declarator@Cpp~GCC5=1422#6afbf80^1#6afbfe0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |   (noptr_declarator@Cpp~GCC5=1421#6afbf60^1#6afbf80:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |(declarator_id@Cpp~GCC5=1487#6afbea0^1#6afbf60:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |   | (id_expression@Cpp~GCC5=317#6afbb40^1#6afbea0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |  (unqualified_id@Cpp~GCC5=319#6afbc80^1#6afbb40:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   (IDENTIFIER@Cpp~GCC5=3368#6afbc20^1#6afbc80:1[`answer'] Line 1 Column 34 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |   |   |  )unqualified_id#6afbc80
   |   |   |   |   | )id_expression#6afbb40
   |   |   |   |   |)declarator_id#6afbea0
   |   |   |   |   )noptr_declarator#6afbf60
   |   |   |   |   (parameter_declaration_clause@Cpp~GCC5=1559#6afbd00^1#6afbf80:2 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |(pp_parameter_declaration_list@Cpp~GCC5=1570#6afb940^1#6afbd00:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   | (pp_parameter_declaration_seq@Cpp~GCC5=1574#6afb800^1#6afb940:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |  (parameter_declaration@Cpp~GCC5=1610#6afb9a0^1#6afb800:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   (basic_decl_specifier_seq@Cpp~GCC5=1070#6afbf40^1#6afb9a0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |(decl_specifier@Cpp~GCC5=1073#6afbfa0^1#6afbf40:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   | (trailing_type_specifier@Cpp~GCC5=1118#6afbfc0^1#6afbfa0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |  (simple_type_specifier@Cpp~GCC5=1140#6afb860^1#6afbfc0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |   |   |   |   | )trailing_type_specifier#6afbfc0
   |   |   |   |   |   |)decl_specifier#6afbfa0
   |   |   |   |   |   )basic_decl_specifier_seq#6afbf40
   |   |   |   |   |  )parameter_declaration#6afb9a0
   |   |   |   |   | )pp_parameter_declaration_seq#6afb800
   |   |   |   |   |)pp_parameter_declaration_list#6afb940
   |   |   |   |   )parameter_declaration_clause#6afbd00
   |   |   |   |   (function_qualifiers@Cpp~GCC5=1438#6afbce0^1#6afbf80:3 Line 1 Column 46 File C:/temp/prime_with_templates.cpp)function_qualifiers
   |   |   |   |  )noptr_declarator#6afbf80
   |   |   |   | )ptr_declarator#6afbfe0
   |   |   |   |)function_head#6afbec0
   |   |   |   |(function_body@Cpp~GCC5=1680#6b04000^1#6b04020:2 Line 1 Column 46 File C:/temp/prime_with_templates.cpp
   |   |   |   | (compound_statement@Cpp~GCC5=888#6afbee0^1#6b04000:1 Line 1 Column 46 File C:/temp/prime_with_templates.cpp)compound_statement
   |   |   |   |)function_body#6b04000
   |   |   |   )function_definition#6b04020
   |   |   |  )member_declaration#6b04040
   |   |   | )member_declaration_or_access_specifier#6b04060
   |   |   | (member_declaration_or_access_specifier@Cpp~GCC5=1806#6b042c0^1#6b042e0:2 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |  (member_declaration@Cpp~GCC5=1822#6b04820^1#6b042c0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   (function_definition@Cpp~GCC5=1632#6b04280^1#6b04820:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   |(function_head@Cpp~GCC5=1674#6b04220^1#6b04280:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b040e0^1#6b04220:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   |  (decl_specifier@Cpp~GCC5=1073#6b040c0^1#6b040e0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   |   (trailing_type_specifier@Cpp~GCC5=1118#6b040a0^1#6b040c0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |(simple_type_specifier@Cpp~GCC5=1138#6b04080^1#6b040a0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |   |   |   )trailing_type_specifier#6b040a0
   |   |   |   |  )decl_specifier#6b040c0
   |   |   |   | )basic_decl_specifier_seq#6b040e0
   |   |   |   | (ptr_declarator@Cpp~GCC5=1417#6b04200^1#6b04220:2 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |  (noptr_declarator@Cpp~GCC5=1422#6b041e0^1#6b04200:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   (noptr_declarator@Cpp~GCC5=1421#6b041a0^1#6b041e0:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |(declarator_id@Cpp~GCC5=1487#6b04180^1#6b041a0:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   | (id_expression@Cpp~GCC5=317#6b04160^1#6b04180:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |  (unqualified_id@Cpp~GCC5=320#6b04140^1#6b04160:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   (operator_function_id@Cpp~GCC5=2027#6b04120^1#6b04140:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |(operator@Cpp~GCC5=2070#6b04100^1#6b04120:1 Line 1 Column 62 File C:/temp/prime_with_templates.cpp)operator
   |   |   |   |   |   )operator_function_id#6b04120
   |   |   |   |   |  )unqualified_id#6b04140
   |   |   |   |   | )id_expression#6b04160
   |   |   |   |   |)declarator_id#6b04180
   |   |   |   |   )noptr_declarator#6b041a0
   |   |   |   |   (parameter_declaration_clause@Cpp~GCC5=1558#6afba40^1#6b041e0:2 Line 1 Column 65 File C:/temp/prime_with_templates.cpp)parameter_declaration_clause
   |   |   |   |   (function_qualifiers@Cpp~GCC5=1438#6b041c0^1#6b041e0:3 Line 1 Column 66 File C:/temp/prime_with_templates.cpp)function_qualifiers
   |   |   |   |  )noptr_declarator#6b041e0
   |   |   |   | )ptr_declarator#6b04200
   |   |   |   |)function_head#6b04220
   |   |   |   |(function_body@Cpp~GCC5=1680#6b04300^1#6b04280:2 Line 1 Column 66 File C:/temp/prime_with_templates.cpp
   |   |   |   | (compound_statement@Cpp~GCC5=889#6b04760^1#6b04300:1 Line 1 Column 66 File C:/temp/prime_with_templates.cpp
   |   |   |   |  (pp_statement_seq@Cpp~GCC5=894#6b04780^1#6b04760:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
   |   |   |   |   (statement@Cpp~GCC5=857#6b04440^1#6b04780:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |(jump_statement@Cpp~GCC5=1011#6afba80^1#6b04440:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
   |   |   |   |   | (pm_expression@Cpp~GCC5=551#6b04380^1#6afba80:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |  (cast_expression@Cpp~GCC5=543#6b04360^1#6b04380:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   (unary_expression@Cpp~GCC5=465#6b04340^1#6b04360:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |(primary_expression@Cpp~GCC5=307#6b04320^1#6b04340:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   | (id_expression@Cpp~GCC5=317#6b042a0^1#6b04320:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |  (unqualified_id@Cpp~GCC5=319#6b04260^1#6b042a0:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
   |   |   |   |   |   |   (IDENTIFIER@Cpp~GCC5=3368#6b04240^1#6b04260:1[`V'] Line 1 Column 74 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |   |   |   |  )unqualified_id#6b04260
   |   |   |   |   |   | )id_expression#6b042a0
   |   |   |   |   |   |)primary_expression#6b04320
   |   |   |   |   |   )unary_expression#6b04340
   |   |   |   |   |  )cast_expression#6b04360
   |   |   |   |   | )pm_expression#6b04380
   |   |   |   |   |)jump_statement#6afba80
   |   |   |   |   )statement#6b04440
   |   |   |   |  )pp_statement_seq#6b04780
   |   |   |   | )compound_statement#6b04760
   |   |   |   |)function_body#6b04300
   |   |   |   )function_definition#6b04280
   |   |   |  )member_declaration#6b04820
   |   |   | )member_declaration_or_access_specifier#6b042c0
   |   |   |)member_specification#6b042e0
   |   |   )class_specifier#6b04880
   |   |  )type_specifier#6b048a0
   |   | )decl_specifier#6b048c0
   |   |)basic_decl_specifier_seq#6b048e0
   |   )simple_declaration#6b04900
   |  )block_declaration#6b04920
   | )declaration#6b04940
   |)template_declaration#6b04960
   )declaration#6b04980
  )pp_declaration_seq#6b049a0
  (pp_declaration_seq@Cpp~GCC5=1022#6b06620^1#6b06640:2 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
   (declaration@Cpp~GCC5=1036#6b06600^1#6b06620:1 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
   |(template_declaration@Cpp~GCC5=2079#6b065e0^1#6b06600:1 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
   | (template_parameter_list@Cpp~GCC5=2083#6b05460^1#6b065e0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |  (template_parameter_list@Cpp~GCC5=2083#6b05140^1#6b05460:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   (template_parameter_list@Cpp~GCC5=2083#6b04ee0^1#6b05140:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |(template_parameter_list@Cpp~GCC5=2082#6b04cc0^1#6b04ee0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   | (template_parameter@Cpp~GCC5=2085#6b04ca0^1#6b04cc0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |  (parameter_declaration@Cpp~GCC5=1611#6b04c80^1#6b04ca0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |   (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04a40^1#6b04c80:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |   |(decl_specifier@Cpp~GCC5=1073#6b04a20^1#6b04a40:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |   | (trailing_type_specifier@Cpp~GCC5=1118#6b04a00^1#6b04a20:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
   |   |   |  (simple_type_specifier@Cpp~GCC5=1138#6b049e0^1#6b04a00:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |   | )trailing_type_specifier#6b04a00
   |   |   |)decl_specifier#6b04a20
   |   |   )basic_decl_specifier_seq#6b04a40
   |   |   (ptr_declarator@Cpp~GCC5=1417#6b04c40^1#6b04c80:2 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   |(noptr_declarator@Cpp~GCC5=1421#6b04be0^1#6b04c40:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   | (declarator_id@Cpp~GCC5=1487#6b04bc0^1#6b04be0:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   |  (id_expression@Cpp~GCC5=317#6b04b60^1#6b04bc0:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   |   (unqualified_id@Cpp~GCC5=319#6b04ac0^1#6b04b60:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
   |   |   |   |(IDENTIFIER@Cpp~GCC5=3368#6b049c0^1#6b04ac0:1[`no'] Line 3 Column 15 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |   )unqualified_id#6b04ac0
   |   |   |  )id_expression#6b04b60
   |   |   | )declarator_id#6b04bc0
   |   |   |)noptr_declarator#6b04be0
   |   |   )ptr_declarator#6b04c40
   |   |  )parameter_declaration#6b04c80
   |   | )template_parameter#6b04ca0
   |   |)template_parameter_list#6b04cc0
   |   |(template_parameter@Cpp~GCC5=2085#6b04ec0^1#6b04ee0:2 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
   |   | (parameter_declaration@Cpp~GCC5=1611#6b04ea0^1#6b04ec0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
   |   |  (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04b40^1#6b04ea0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
   |   |   (decl_specifier@Cpp~GCC5=1073#6b04ba0^1#6b04b40:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
   |   |   |(trailing_type_specifier@Cpp~GCC5=1118#6b04c60^1#6b04ba0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
   |   |   | (simple_type_specifier@Cpp~GCC5=1138#6b04580^1#6b04c60:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |   |)trailing_type_specifier#6b04c60
   |   |   )decl_specifier#6b04ba0
   |   |  )basic_decl_specifier_seq#6b04b40
   |   |  (ptr_declarator@Cpp~GCC5=1417#6b04e60^1#6b04ea0:2 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
   |   |   (noptr_declarator@Cpp~GCC5=1421#6b04e40^1#6b04e60:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
   |   |   |(declarator_id@Cpp~GCC5=1487#6b04de0^1#6b04e40:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
   |   |   | (id_expression@Cpp~GCC5=317#6b04d80^1#6b04de0:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
   |   |   |  (unqualified_id@Cpp~GCC5=319#6b04ce0^1#6b04d80:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
   |   |   |   (IDENTIFIER@Cpp~GCC5=3368#6b04560^1#6b04ce0:1[`yes'] Line 3 Column 24 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |  )unqualified_id#6b04ce0
   |   |   | )id_expression#6b04d80
   |   |   |)declarator_id#6b04de0
   |   |   )noptr_declarator#6b04e40
   |   |  )ptr_declarator#6b04e60
   |   | )parameter_declaration#6b04ea0
   |   |)template_parameter#6b04ec0
   |   )template_parameter_list#6b04ee0
   |   (template_parameter@Cpp~GCC5=2085#6b05120^1#6b05140:2 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
   |   |(parameter_declaration@Cpp~GCC5=1611#6b05100^1#6b05120:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
   |   | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04d20^1#6b05100:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
   |   |  (decl_specifier@Cpp~GCC5=1073#6b04dc0^1#6b04d20:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
   |   |   (trailing_type_specifier@Cpp~GCC5=1118#6b04e80^1#6b04dc0:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
   |   |   |(simple_type_specifier@Cpp~GCC5=1140#6b046e0^1#6b04e80:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |   )trailing_type_specifier#6b04e80
   |   |  )decl_specifier#6b04dc0
   |   | )basic_decl_specifier_seq#6b04d20
   |   | (ptr_declarator@Cpp~GCC5=1417#6b05080^1#6b05100:2 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
   |   |  (noptr_declarator@Cpp~GCC5=1421#6b05020^1#6b05080:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
   |   |   (declarator_id@Cpp~GCC5=1487#6b05000^1#6b05020:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
   |   |   |(id_expression@Cpp~GCC5=317#6b04fa0^1#6b05000:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
   |   |   | (unqualified_id@Cpp~GCC5=319#6b04f00^1#6b04fa0:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
   |   |   |  (IDENTIFIER@Cpp~GCC5=3368#6b046c0^1#6b04f00:1[`f'] Line 3 Column 33 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   | )unqualified_id#6b04f00
   |   |   |)id_expression#6b04fa0
   |   |   )declarator_id#6b05000
   |   |  )noptr_declarator#6b05020
   |   | )ptr_declarator#6b05080
   |   |)parameter_declaration#6b05100
   |   )template_parameter#6b05120
   |  )template_parameter_list#6b05140
   |  (template_parameter@Cpp~GCC5=2085#6b05440^1#6b05460:2 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
   |   (parameter_declaration@Cpp~GCC5=1611#6b05420^1#6b05440:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
   |   |(basic_decl_specifier_seq@Cpp~GCC5=1070#6b05160^1#6b05420:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
   |   | (decl_specifier@Cpp~GCC5=1073#6b04fe0^1#6b05160:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
   |   |  (trailing_type_specifier@Cpp~GCC5=1118#6b050e0^1#6b04fe0:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
   |   |   (simple_type_specifier@Cpp~GCC5=1140#6b050c0^1#6b050e0:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp)simple_type_specifier
   |   |  )trailing_type_specifier#6b050e0
   |   | )decl_specifier#6b04fe0
   |   |)basic_decl_specifier_seq#6b05160
   |   |(ptr_declarator@Cpp~GCC5=1417#6b053e0^1#6b05420:2 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
   |   | (noptr_declarator@Cpp~GCC5=1421#6b053c0^1#6b053e0:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
   |   |  (declarator_id@Cpp~GCC5=1487#6b05360^1#6b053c0:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
   |   |   (id_expression@Cpp~GCC5=317#6b05280^1#6b05360:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
   |   |   |(unqualified_id@Cpp~GCC5=319#6b051a0^1#6b05280:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
   |   |   | (IDENTIFIER@Cpp~GCC5=3368#6b046a0^1#6b051a0:1[`p'] Line 3 Column 40 File C:/temp/prime_with_templates.cpp)IDENTIFIER
   |   |   |)unqualified_id#6b051a0
   |   |   )id_expression#6b05280
   |   |  )declarator_id#6b05360
   |   | )noptr_declarator#6b053c0
   |   |)ptr_declarator#6b053e0
   |   )parameter_declaration#6b05420
   |  )template_parameter#6b05440
   | )template_parameter_list#6b05460

यह निर्धारित करना कि यह परिवर्तनशील घोषणा है या गुणन एक प्रकार की जाँच सुविधा नहीं है। इसके अलावा मुझे उस सेल्फ-प्रमोशन के सामान के आपके जवाब को भी फिर से खंगालना पड़ा।
पिल्ला

@ सहायता: आप कह सकते हैं कि आपको क्या पसंद है, लेकिन यह है कि उपकरण कैसे काम करता है। उपकरण का नाम हटाना संभवत: लोगों को यह बताने के लिए होगा कि उपकरण का नाम क्या है।
इरा

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