2012-05-19 12 views
11

के बीच सी 11 व्याकरण अस्पष्टता मैं एन 1570 के बंद सी11 के लिए एक लेक्स/yacc व्याकरण लिखने की कोशिश कर रहा हूं। मेरे अधिकांश व्याकरण को सूचनात्मक वाक्यविन्यास सारांश से क्रियापद प्रतिलिपि बनाई गई है, लेकिन कुछ yacc संघर्ष उत्पन्न हुए हैं। मैंने उनमें से सभी को हल करने में कामयाब रहा है: एक 'एटॉमिक' का उपयोग एक प्रकार के विनिर्देशक के रूप में किया जाता है और जब इसे एक प्रकार क्वालीफायर के रूप में उपयोग किया जाता है तो कुछ अस्पष्टता दिखाई देती है।_11 एटमिक प्रकार विनिर्देशक और क्वालीफायर

विनिर्देशक रूप में, _Atomic तुरंत कोष्ठक द्वारा पीछा किया जाता है, इसलिए मुझे लगता है कि इसका सी के छोटे-छोटे सिंटैक्स के साथ कुछ करना है जो घोषणाकर्ताओं को कोष्ठक में रहने की अनुमति देता है, इस प्रकार कोष्ठक तुरंत क्वालीफायर का पालन करने की अनुमति देता है। लेकिन मेरा व्याकरण पहले से ही जानता है कि टाइपिफ नामों को अन्य पहचानकर्ताओं से कैसे अलग किया जाए, इसलिए yacc को अंतर पता होना चाहिए, है ना?

मैं अपने जीवन के लिए एक ऐसे मामले के बारे में सोच नहीं सकता जब यह वास्तव में संदिग्ध होगा।

मुझे संदेह है कि इससे मदद मिलती है, लेकिन जब मैं yacc's -v ध्वज का उपयोग करता हूं तो मुझे प्रासंगिक राज्य आउटपुट मिलता है। "परमाणु" स्पष्ट रूप से "_Atomic"

state 23 

    152 atomic_type_specifier: ATOMIC . '(' type_name ')' 
    156 type_qualifier: ATOMIC . 

    '(' shift, and go to state 49 

    '('  [reduce using rule 156 (type_qualifier)] 
    $default reduce using rule 156 (type_qualifier) 
+0

व्याकरण में विशिष्ट विनिर्देशक और क्वालीफायर काफी हद तक एक गैर-तिमाही है क्योंकि घोषणाएं विनिर्देशकों और क्वालीफायरों को किसी भी क्रम में मिश्रित कर सकती हैं: 'बिना हस्ताक्षरित int', 'हस्ताक्षरित const int', 'int unsigned const', ... – Kaz

उत्तर

7

हाँ, मुझे लगता है कि विनिर्देश में अस्पष्टता है के लिए मेरे टोकन नाम है। लो

_Atomic int (*f)(int); 
यहाँ _Atomic

एक प्रकार-क्वालीफायर है। (एक समारोह के रिटर्न प्रकार के रूप में यह ज्यादा समझ में नहीं आता है, लेकिन मान्य है, मुझे लगता है)। अब इस वैकल्पिक रूप

int _Atomic (*f)(int); 

सामान्य रूप से ले प्रकार- क्वालिफायर int के बाद आ सकता है और यह अन्य घोषणा के बराबर होना चाहिए। लेकिन अब _Atomic कोष्ठक के बाद किया जाता है, इसलिए को एक प्रकार-विनिर्देशक के रूप में व्याख्या किया जाना चाहिए जो तब एक वाक्यविन्यास त्रुटि है। मुझे लगता है कि एक उदाहरण पकाया जा सकता है जहां *f को वैध typedef द्वारा प्रतिस्थापित किया जा सकता है।

6.7.2.4 p4

परमाणु प्रकार के साथ जुड़े गुण के पहले वाक्य पर एक नज़र डालें केवल भाव कि lvalues ​​हैं के लिए सार्थक कर रहे हैं।

यह स्पष्ट रूप से इंगित करता है कि वे वापसी प्रकारों के कार्यों की अपेक्षा नहीं करते हैं _Atomic योग्य।

संपादित करें:

ही अस्पष्टता के लिए

_Atomic int (*A)[3]; 

जो सही भावना और जो (तीन परमाणु पूर्णांकों की एक सरणी के लिए सूचक) हम

के रूप में फिर से लिखने में सक्षम होना चाहिए बनाता है तब आती है,
int _Atomic (*A)[3]; 

संपादित करें 2: यह देखने के लिए कि एक टाई होने का मानदंड कोष्ठक में पे disambiguating नहीं है निम्नलिखित मान्य C99 कोड ले:

typedef int toto; 

int main(void) { 
    const int toto(void); 
    int const toto(void); 
    const int (toto)(void); 
    int const (toto)(void); 
    return toto(); 
} 

यह एक समारोह के रूप totomain अंदर redeclares। और सभी चार पंक्तियां एक ही कार्य के लिए वैध प्रोटोटाइप हैं। अब एक क्वालीफायर

typedef int toto; 

int main(void) { 
    int _Atomic (toto)(void); 
    return toto(); 
} 

इस const साथ संस्करण के रूप में मान्य होना चाहिए के रूप में _Atomic का उपयोग करें। अब हमारे पास एक ऐसा मामला है जहां _Atomic के बाद एक प्रकार के साथ कंस्ट्रैसिसिस है, लेकिन फिर भी यह एक प्रकार-विनिर्देशक नहीं है।

+0

जब आप कहते हैं , "लेकिन अब _Atomic कोष्ठक के बाद किया जाता है, इसलिए इसे एक प्रकार-क्वालीफायर के रूप में व्याख्या किया जाना चाहिए" मैं आपका मतलब मानता हूं, "लेकिन अब _ एटॉमिक का पालन करने के बाद होता है, इसलिए इसे एक प्रकार-विनिर्देशक के रूप में व्याख्या किया जाना चाहिए"? –

+2

खैर, परमाणु-प्रकार-विनिर्देशक नियम ब्रांड्स में एक प्रकार के नाम के लिए कॉल करता है, न कि घोषणाकर्ता, इसलिए मुझे नहीं लगता कि '_Atomic (* कुछ भी)' एक तारांकन के साथ कभी वैध परमाणु-प्रकार होगा -specifier। लेकिन मैंने हाल ही में इसे मानक में देखा (6.7.2.4 - 4): ** यदि _Atomic कीवर्ड तुरंत बाएं कोष्ठक द्वारा पीछा किया जाता है, तो इसे एक प्रकार के विनिर्देशक (एक प्रकार के नाम के साथ) के रूप में व्याख्या किया जाता है, न कि क्वालीफायर टाइप करें। ** इस मामले में कभी अस्पष्टता नहीं होगी। पेंटिचेस का अर्थ टाइप विनिर्देशक है, कोई भी ब्रांड्स क्वालीफायर का मतलब नहीं है। अब किसी भी तरह से मेरे व्याकरण में उस नियम को शामिल करने के लिए ... –

+0

@MichaelBurr, हाँ, धन्यवाद, मैं इसे संपादित करूंगा। –

9

ठीक है, चाहे हम व्याकरणिक रूप से संदिग्ध मामले के साथ आ सकते हैं, इससे कोई फर्क नहीं पड़ता। N1570 की धारा 6.7.2.4 अनुच्छेद 4 कहा गया है कि:

_Atomic कीवर्ड तुरंत एक बाएं कोष्ठक द्वारा पीछा किया जाता है, यह एक प्रकार निर्दिष्टकर्ता (एक प्रकार नाम के साथ) के रूप में नहीं एक प्रकार क्वालीफायर के रूप में व्याख्या की है,।

इसे लागू करने के लिए, मैंने बस अपने लेक्स नियमों में क्वालीफायर अलग टोकन के रूप में एक विशिष्ट और _Atomic के रूप में _Atomic बनाया।

"_Atomic"/{WHITESPACE}*"(" {return ATOMIC_SPECIFIER;} 
"_Atomic"     {return ATOMIC_QUALIFIER;} 

मैं अपेक्षाकृत लेक्स के लिए सामान्य रूप में/याक और पार्सर जनरेटर नया हूँ, लेकिन मेरे पेट का कहना है कि यह एक हैक की तरह है। साथ ही, लेक्स में पिछला संदर्भ वाक्यविन्यास क्या होगा?

+1

यदि इसमें टिप्पणियां हैं तो यह असफल हो जाएगी। – o11c

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