2009-04-27 14 views
31

जब लोग यह कहते हैं तो लोगों का क्या अर्थ है? प्रोग्रामर और कंपाइलर्स के लिए क्या प्रभाव हैं?जब लोग कहते हैं कि सी ++ में "अनावश्यक व्याकरण" है तो लोगों का क्या अर्थ है?

+5

कौन से लोग? वे कहां कह रहे हैं? –

+1

मुझे संदेह है कि यहां अधिकांश लोगों को यह नहीं पता कि कंप्यूटर विज्ञान में "अनिश्चित" का क्या अर्थ है। विकिपीडिया आलेख देखें: http://en.wikipedia.org/wiki/Undecidable_problem –

+2

अधिकांश सामान मैं सी ++ के बारे में "अनावश्यक" व्याकरण वाले Google के लिए Google पर कह सकता हूं कि केवल एक बयान का अर्थ पिछली परिभाषाओं पर निर्भर करता है, यानी इसके संदर्भ पर। वाह, कितना अपरिहार्य! यह कहने जैसा है कि एक बास्केटबॉल खेल "अनिश्चित रूप से" अच्छा या बुरा है क्योंकि यह इस बात पर निर्भर करता है कि आगे कौन है और शेष समय क्या है। –

उत्तर

52

यह इस तथ्य से संबंधित है कि सी ++ की टेम्पलेट सिस्टम Turing complete है। इसका मतलब है (सैद्धांतिक रूप से) कि आप किसी भी अन्य ट्यूरिंग पूर्ण भाषा या सिस्टम का उपयोग कर टेम्पलेट्स के साथ संकलित समय पर कुछ भी गणना कर सकते हैं।

इसका दुष्प्रभाव है कि कुछ स्पष्ट रूप से मान्य सी ++ प्रोग्राम संकलित नहीं किए जा सकते हैं; संकलक कभी तय नहीं कर पाएगा कि कार्यक्रम मान्य है या नहीं। यदि संकलक सभी कार्यक्रमों की वैधता का निर्णय ले सकता है, तो यह Halting problem को हल करने में सक्षम होगा।

ध्यान दें कि इसका सी ++ व्याकरण की अस्पष्टता से कोई लेना देना नहीं है।


संपादित करें: जोश हैबरमैन एक उत्कृष्ट उदाहरण है कि सी के लिए एक पार्स पेड़ के निर्माण ++ वास्तव में undecideable है के साथ नीचे टिप्पणी में और एक blog post में बताया। व्याकरण की अस्पष्टता के कारण, अर्थात् विश्लेषण से वाक्यविन्यास विश्लेषण को अलग करना असंभव है, और चूंकि अर्थपूर्ण विश्लेषण अपरिहार्य है, इसलिए वाक्यविन्यास विश्लेषण भी है।

भी देखें (जोश की पोस्ट से लिंक):

+2

हास्यास्पद, C++ में ट्यूरिंग पूर्ण टेम्पलेट सिस्टम वह है जो मैं अपनी सबसे बड़ी शक्तियों में से एक मानता हूं। –

+4

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

+7

@Evan, यह सी ++ प्रोग्रामर के लिए एक ताकत है जिसमें आप संकलन समय पर चीजों की गणना कर सकते हैं। हालांकि, यह एक अच्छा सी ++ संकलक लिखना अधिक कठिन बनाता है। –

13

इसका क्या अर्थ है कि सी ++ व्याकरण वाक्य रचनात्मक रूप से संदिग्ध है, कि आप कुछ कोड लिख सकते हैं जो संदर्भ के आधार पर अलग-अलग चीजों का मतलब हो सकता है। (व्याकरण एक भाषा की वाक्य रचना का वर्णन है। यह क्या निर्धारित करता है कि a + b, एक अतिरिक्त ऑपरेशन है चर ए और बी से जुड़े है।)

उदाहरण के लिए, foo bar(int(x));, लिखित रूप में कहा जाता है, एक चर की घोषणा हो सकती है बार, प्रकार foo, int (x) प्रारंभकर्ता होने के साथ। यह बार नामक एक समारोह की घोषणा भी हो सकता है, एक int ले रहा है, और एक foo लौट रहा है। यह भाषा के भीतर परिभाषित किया गया है, लेकिन व्याकरण के हिस्से के रूप में नहीं।

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

+4

यदि आप इसे 'foo * bar (int (x)) बनाते हैं तो यह हो सकता है: (ए) एक अभिव्यक्ति, (बी) ऑब्जेक्ट घोषणा या (सी) फ़ंक्शन घोषणा। –

2

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

कंपेलरों को लिखने वालों के लिए निहितार्थ यह है कि उन्हें भाषा को संकलित करने के लिए बहुत अधिक समय और प्रयास करना पड़ता है।

8

"कुछ लोगों" योसी Kreinin शामिल हैं, तो वह क्या here लिखते हैं के आधार पर ...

इस उदाहरण पर विचार:

x * y(z); 

दो अलग-अलग संदर्भों में:

int main() { 
    int x, y(int), z; 
    x * y(z); 
} 

और

int main() { 
    struct x { x(int) {} } *z; 
    x * y(z); 
} 

... वह इसका मतलब है "आप देख कर तय नहीं कर सकता एक्स * वाई (जेड) पर मैं टी एक अभिव्यक्ति या घोषणा है। " पहले मामले में, इसका मतलब है "तर्क ज़ेड के साथ कॉल फ़ंक्शन वाई, फिर एक्स के साथ ऑपरेटर * (int, int) और फ़ंक्शन कॉल के वापसी मूल्य का आह्वान करें, और अंत में परिणाम को छोड़ दें।" दूसरे मामले में, इसका मतलब है कि "y एक स्ट्रक्चर एक्स के लिए एक पॉइंटर है, जिसे इंगित करने के लिए आरंभ किया गया है (कचरा & टाइम-बम) पता जेड करता है।"

कहें कि आपके पास कोबोलमैनिया का फिट था और भाषा में डेक्लेयर जोड़ा गया। फिर दूसरा

int main() { 
    DECLARE struct x { x(int) {} } *z; 
    DECLARE x * y(z); 
} 

और निर्णायकता दिखाई देगी। ध्यान दें कि निर्णायक होने से पॉइंटर-टू-कचरा समस्या दूर नहीं होती है।

+9

बेशक, यह सी ++ तक सीमित नहीं है - उदाहरण के लिए, बेसिक पर विचार करें - "x = 1" असाइनमेंट या परीक्षण है? केवल संदर्भ में आप बता सकते हैं। –

+1

योसी क्रेइनिन "सी ++ व्याकरण को अपरिहार्य बनाने में समस्या" के बारे में बात करता है, लेकिन यह बकवास है; वास्तव में वही वेबसाइट कहीं और, यह बताते हुए कि सी ++ में अनावश्यक व्याकरण है, कहता है कि "यह दिखाता है (एक अंतर्ज्ञानी स्तर पर) कि सी ++ व्याकरण काफी संदर्भ-संवेदनशील है।" http://yosefk.com/c++fqa/defective.html#defect-2 – Blaisorblade

+1

@anon: बेसिक में यह जानने के लिए पर्याप्त है कि आप किस उत्पादन से मेल खाते हैं "y = 1", यानी यदि यह अभिव्यक्ति है या एक बयान। सी ++ अधिक जटिल है, उसी चरित्र अनुक्रम के समान स्थिति में और उसी तत्काल संदर्भ में पूरी तरह से अलग-अलग चीजों का अर्थ हो सकता है। – Blaisorblade

4

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

+0

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

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

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