आमतौर पर टिप्पणियों को कैसे पार्स किया जाता है?


31

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

उदाहरण के लिए, टोकन के साथ एक टोकन 'हस्तक्षेप' के भीतर एक टिप्पणी अंतर्निहित होनी चाहिए या नहीं? आमतौर पर, कुछ इस तरह है:

Sys/* comment */tem.out.println()

वैध?

साथ ही, यदि भाषा नई रेखाओं के प्रति संवेदनशील है, और टिप्पणी नई पंक्ति में फैली हुई है, तो क्या नई रेखा पर विचार किया जाना चाहिए या नहीं?

stuff stuff /* this is comment
this is still comment */more stuff 

माना जाता है

stuff stuff more stuff

या

stuff stuff
more stuff

?

मुझे पता है कि कुछ विशिष्ट भाषाएं क्या करती हैं, न ही मैं राय की तलाश में हूं, लेकिन मैं इस बात की तलाश कर रहा हूं कि क्या कोई आम सहमति है: क्या आम तौर पर टोकन और नई लाइनों के संबंध में एक चिह्न द्वारा अपेक्षित है?


मेरा विशेष संदर्भ विकी जैसा मार्कअप है।


क्या टिप्पणी के अंदर नई रेखा मौजूद है? टिप्पणी में इसे किसी अन्य चरित्र से अलग क्यों माना जाएगा?

1
@Snowman वहाँ है कि परिप्रेक्ष्य, लेकिन दूसरी ओर अगर टोकन 'x' का विशेष अर्थ है यदि इसका पहला टोकन लाइन पर है और यह स्रोत पर और देखने वाले दोनों लोगों के लिए लाइन पर पहला टोकन प्रतीत होता है। पार्सर पढ़ने लाइन-दर-लाइन। एक दुविधा की तरह लगता है इसलिए मैंने सवाल पूछा।
स्लेज

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

जवाबों:


40

आमतौर पर टिप्पणियां टोकन प्रक्रिया के भाग के रूप में स्कैन (और खारिज) की जाती हैं, लेकिन पार्स करने से पहले। एक टिप्पणी एक टोकन विभाजक की तरह काम करती है यहां तक ​​कि इसके आसपास व्हाट्सएप की अनुपस्थिति में भी।

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

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

return /*
       */ 17

के बराबर है

return 17

नहीं

return
17

सिंगल-लाइन टिप्पणियां लाइन ब्रेक को संरक्षित करती हैं, अर्थात

return // single line comment
    17

के बराबर है

return
17

नहीं

return 17

चूंकि टिप्पणियों को स्कैन किया जाता है, लेकिन पार्स नहीं किया जाता है, वे घोंसले के लिए नहीं होते हैं। इसलिए

 /*  /* nested comment */ */

एक वाक्यविन्यास त्रुटि है, क्योंकि टिप्पणी पहले द्वारा खोली गई है और पहले /*से बंद है*/


3
अधिकांश भाषाओं में इन-लाइन टिप्पणियों ( /* like this */) को एक व्हाट्सएप और ईओएल-टर्मिनेटेड टिप्पणियों ( // like this) को एक रिक्त लाइन के बराबर माना जाता है ।
9000

@JacquesB तो मैं टिप्पणियों को इलाज करने के बारे में सोच रहा हूं कि स्रोत से उनकी संपूर्णता को शून्य-चौड़ाई वाले स्थान के रूप में प्रतिस्थापित किया जा रहा है , जो कि आप जो सुझाव दे रहे हैं, उसके बराबर लगता है।
स्लेज

1
@ सार एक साधारण स्थान ठीक काम करना चाहिए, और ASCII कोड पेज में निहित है।
जॉन डेवोरक

@JanDvorak एक स्थान उपस्थिति को प्रभावित करेगा और समझ को हटा देगा और "एक टिप्पणी वास्तव में नहीं है" के शब्दार्थों के करीब है। प्राथमिक रेंडरिंग आउटपुट HTML होगा, इसलिए मेरे मामले में ASCII उतना मुद्दा नहीं है जितना कि ब्राउज़र यूनिकोड का समर्थन करता है। मैंने कहा, मेरा मानना ​​है कि सी मानक जनादेश है कि टिप्पणियों को एक ही स्थान से बदल दिया जाता है।
स्लेज

1
कुछ भाषाओं, विशेष रूप से रैकेट, में नेस्टेड मल्टी-लाइन टिप्पणियां हैं: (define x #| this is #| a sub-comment |# the main comment |# 3) xपैदावार 3
30:15 बजे wchargin

9

प्रश्न का उत्तर देने के लिए:

क्या आम तौर पर एक आम सहमति है जो आमतौर पर एक मार्क अप द्वारा अपेक्षित है?

मैं कहूंगा कि एक टोकन के अंदर एम्बेडेड टिप्पणी कानूनी होने की उम्मीद कोई नहीं करेगा।

अंगूठे के एक सामान्य नियम के रूप में, टिप्पणियों को व्हाट्सएप के समान माना जाना चाहिए। किसी भी जगह जो कि बाहरी व्हाट्सएप के लिए मान्य होगी, को भी एक एम्बेडेड टिप्पणी करने की अनुमति दी जानी चाहिए। एकमात्र अपवाद तार होगा:

trace("Hello /*world*/") // should print Hello /*world*/

स्ट्रिंग्स के अंदर टिप्पणियों का समर्थन करना काफी अजीब होगा, और उन्हें थकाऊ बना देगा!


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

3
स्ट्रिंग से बचने के बारे में उस बिट के लिए +1। हालाँकि, आपके उदाहरण में, मैं आमतौर पर Hello /* world*/!टिप्पणी के सीमांकक को दबाने के बजाय इसे मुद्रित करने की अपेक्षा करूंगा । इसके अलावा, प्रोग्रामर में आपका स्वागत है!
8bittree

1
धन्यवाद 8 बिट्ट्री! और यह पूरी तरह से मेरा मतलब है। पर्याप्त रूप से, मुझे अपने उत्तर में ** से बचने की भी आवश्यकता है ....
कॉनर क्लार्क

2
सामान्य रूप से @ArtB, "प्रतिस्थापन द्वारा पार्सिंग" किनारे के मामलों और अन्य विशेषताओं के साथ बातचीत के साथ सड़क पर बहुत मुश्किल हो जाता है, और शुरुआत से सबसे अच्छा बचा जाता है।
हॉब्स

7

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

इसलिए उदाहरण के Sys temलिए दो टोकन हैं, जबकि Systemएक है। यदि आप तुलना करते हैं new Foo()और newFoo()इनमें से एक Fooदूसरी कॉल का एक उदाहरण का निर्माण करेगा, तो इसकी उपयोगिता अधिक स्पष्ट हो सकती है newFoo

टिप्पणियां व्हॉट्सएप के एक रन के रूप में एक ही भूमिका निभा सकती हैं, जैसे new/**/Foo()काम करता है new Foo()। बेशक यह अधिक जटिल हो सकता है, उदाहरण के लिए new /**/ /**/ Foo()या whatnot।

तकनीकी रूप से, पहचानकर्ताओं के भीतर टिप्पणियों की अनुमति देना संभव होना चाहिए, लेकिन मुझे संदेह है कि यह विशेष रूप से व्यावहारिक है।

अब, श्वेत-रिक्त संवेदनशील भाषाओं का क्या?

अजगर के दिमाग में आता है और इसका एक बहुत ही सरल उत्तर है: कोई ब्लॉक टिप्पणी नहीं। आप के साथ एक टिप्पणी शुरू करते हैं #और फिर पार्सर ठीक वैसे ही काम करता है जैसे कि बाकी लाइन मौजूद नहीं थी लेकिन इसके बजाय सिर्फ एक नई पंक्ति थी।

इसके विपरीत, जेड ब्लॉक टिप्पणियों के लिए अनुमति देता है , जहां ब्लॉक उसी इंडेंटेशन स्तर पर वापस आने पर समाप्त होता है। उदाहरण:

body
  //-
    As much text as you want
    can go here.
  p this is no longer part of the comment

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


हम्म, newline असली मुद्दा है क्योंकि हम टिप्पणियों के लिए HTML \ XML सिंटैक्स का उपयोग कर रहे हैं, इसलिए यह बहु-पंक्ति होगा।
स्लेज

3
@ArtB यदि आप HTML / XML सिंटैक्स का उपयोग कर रहे हैं, तो यह केवल उनके व्यवहार का उपयोग करने के लिए बुद्धिमान हो सकता है।
8bittree

1
@ 8 बिट्टी समझ में आता है, ऐसा सोचना चाहिए था। मैं प्रश्न छोड़ दूंगा क्योंकि यह इस तरह से अधिक उपयोगी होगा।
स्लेज

3

अतीत में मैंने लेक्सिकल विश्लेषण के एक हिस्से के रूप में टिप्पणियों को एक टोकन में बदल दिया है। वही तार के लिए जाता है। वहां से, जीवन आसान है।

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

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

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

मुझे उम्मीद है कि समझ में आता है / मदद करता है।


इसलिए यदि आपके पास कोड है console.log(/*a comment containing "quotes" is possible*/ "and a string containing /*slash-star, star-slash*/ is possible"), जहां एक टिप्पणी में उद्धरण हैं और एक स्ट्रिंग में वाक्यविन्यास में टिप्पणी करते हैं, तो लेक्सर इसे सही तरीके से टोकन कैसे जानता होगा? क्या आप अपना जवाब संपादित कर सकते हैं, उन मामलों का सामान्य विवरण प्रदान कर सकते हैं?
छारवे

1

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

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

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

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

टिप्पणियों के साथ गैर-टिप्पणी टोकन की व्याख्या करने का विचार व्याकरण से टिप्पणियों को पूरी तरह से हटाना है।

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

एक बहुत अच्छा कार्यान्वयन जावा भाषा के लिए एक्लिप्स कंपाइलर इन्फ्रास्ट्रक्चर है। वे टोकन के दौरान टिप्पणियों को संरक्षित करते हैं और एएसटी के भीतर टिप्पणियों का प्रतिनिधित्व करते हैं - जहां तक ​​मुझे याद है। इसके अलावा, यह पार्सर / एएसटी कार्यान्वयन स्वरूपण को संरक्षित करता है।

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