अधिकांश प्रोग्रामिंग भाषाओं को एक पहचानकर्ता को घोषित करने की अनुमति नहीं देने के लिए डिज़ाइन किया गया है जो एक नंबर से शुरू होता है। मैं सिर्फ कारण जानने के लिए उत्सुक था। मैंने पहले ही वेब खोज लिया है, लेकिन संतोषजनक स्पष्टीकरण नहीं मिला।
अधिकांश प्रोग्रामिंग भाषाओं को एक पहचानकर्ता को घोषित करने की अनुमति नहीं देने के लिए डिज़ाइन किया गया है जो एक नंबर से शुरू होता है। मैं सिर्फ कारण जानने के लिए उत्सुक था। मैंने पहले ही वेब खोज लिया है, लेकिन संतोषजनक स्पष्टीकरण नहीं मिला।
जवाबों:
C / C ++ में, एक अक्षर के बाद वाली संख्या को एक संख्यात्मक स्थिरांक माना जाता है और इसके बाद आने वाली स्ट्रिंग, स्थिरांक के प्रकार को योग्य बनाती है। इसलिए उदाहरण के लिए (ये वीसी ++ हैं, निश्चित नहीं हैं कि वे कितने मानक हैं):
इसलिए ए) यह लेक्सर के लिए आसान है क्योंकि डैनियल ने कहा, लेकिन यह भी ख) यह एक स्पष्ट अंतर बनाता है क्योंकि 0y एक चर हो सकता है लेकिन 0u कभी नहीं होगा। प्लस अन्य क्वालीफायर, जैसे "i64" को "एल" या "यू" की तुलना में बाद में जोड़ा गया था और वे जरूरत पड़ने पर अधिक जोड़ने के विकल्प को खुला रखना चाहते हैं।
लीकर को लागू करने वाले लोगों की सुविधा। (नहीं, गंभीरता से, यह इसके बारे में है। विभिन्न भाषाओं के अन्य कारण हैं, लेकिन यह अंततः उसी के लिए नीचे आता है।)
0flu
एक शाब्दिक 0glu
था और एक स्थानीय पहचानकर्ता था।
int 0u = 5; unsigned int x = 0u;
की व्याख्या को चुनने का कोई अच्छा तरीका नहीं है, हालांकि आप इस कोड की व्याख्या को परिभाषित करने के लिए चुनते हैं (संभवतः या तो x == 0 या x == 5), लोग भ्रमित होने वाले हैं अस्पष्टता के कारण। यहां तक कि अगर यह संकलक को इस तरह से लागू करने के लिए तुच्छ थे, तो एक अच्छा डिजाइनर संभवतः ऐसा नहीं करेगा।
निम्नलिखित 2 मामलों पर विचार करें:
मान लेते हैं कि एक पहचानकर्ता एक संख्या से शुरू हो सकता है।
तो नीचे जैसा एक बयान मान्य होगा (चूंकि एक पहचानकर्ता में 1 या अधिक वर्ण हो सकते हैं):
int 3;
जब मैं एक कार्यक्रम में उपरोक्त चर का उपयोग करने की कोशिश करता हूं, तो इसका परिणाम संकलक अस्पष्टता में होगा:
int 3, ए;
3 = 5;
एक = 3;
कथन a=3
में 3 की भूमिका क्या है (क्या यह मान 5 के साथ एक चर है या यह अंक 3 है)?
जैसा कि ऊपर दिए गए उदाहरण के विपरीत है, मान लेता है कि एक भाषा को वास्तव में पहचानकर्ताओं को एक संख्या से शुरू करने की अनुमति थी, जबकि अभी भी पहचानकर्ता के रूप में उपयोग किए जा रहे अंकों को अस्वीकार करना। इससे निम्नलिखित समस्याएं हो सकती हैं:
चर के बारे में भाषा नियम जो कहता है कि एक चर में 1 या अधिक वर्ण शामिल हो सकते हैं, को एक जटिल नियम में पुनर्परिभाषित करना होगा: जैसे एक चर में एक या अधिक वर्ण हो सकते हैं और यह अद्वितीय होना चाहिए जब यह एक संख्या के साथ शुरू नहीं होता है एक नंबर (आदि) के साथ शुरू होने पर यह एकल वर्ण लंबाई का नहीं हो सकता है।)
कंपाइलर को सभी अंको (जैसे 333) और वैध वर्णमाला प्रत्ययों (जैसे 34 एल) को चर नामों के रूप में उपयोग किए जाने पर त्रुटि मामलों की जांच और रिपोर्ट करनी होगी। पाइथन और जेएस जैसी ढीली टाइप की गई भाषाओं में, जहां आप उन्हें घोषित किए बिना मक्खी पर चर का उपयोग कर सकते हैं, यहां तक कि सभी अंकों से जुड़े विशेष मामलों की जांच करना भी असंभव हो सकता है। उदाहरण के लिए if (33==5)
, 33 एक त्रुटिपूर्ण अघोषित परिवर्तनीय संस्करण हो सकता है जिसे उपयोगकर्ता ने घोषित किया है। लेकिन संकलक इसे पहचानने और त्रुटि की रिपोर्ट करने में सक्षम नहीं होगा।
इस प्रतिबंध को बनाने से प्रोग्रामर को पहचानकर्ता नामों के रूप में संख्याओं का उपयोग करने से रोका जा सकेगा।
int char = float
होगा?
int
है कि यह एक कीवर्ड है और पहचानकर्ता नहीं है। ठीक है, int
उच्च पूर्वता है जैसा कि संख्यात्मक lexemes होगा।
int 3,a; 3=5; a=3;
कथन a = 3 में, 3 की पहचान एक पहचानकर्ता के रूप में या एक संख्या के रूप में की गई है? यह अस्पष्टता का कारण बनता है। आशा है कि यह स्पष्ट है।
अधिकांश भाग के लिए इसका कंपाइलर लेखकों और पार्सिंग दक्षता के लिए आसान बनाने के साथ कोई लेना-देना नहीं है, लेकिन, एक सिंटेक्स को डिजाइन करने के साथ अधिक है जो स्पष्ट पठनीय और अस्पष्ट कोड को प्रोत्साहित करता है।
इसके भाषा डिजाइनरों ने सोचा कि नंबर 1 की तरह संख्यात्मक शाब्दिक को सीधे सादे 1 के रूप में लिखना अच्छा होगा ।
भाषा सिंटैक्स को डिजाइन करना काफी संभव होगा, जहां न्यूमेरिक शाब्दिक को किसी तरह से उदाहरण के लिए उद्धृत किया जाता है, इसलिए नंबर एक के लिए नंबरिक शाब्दिक को ~ 1 ~ के रूप में एन्कोड किया गया था और उद्धरण चिह्नों में संलग्न नहीं एक कीवर्ड के रूप में व्यवहार नहीं किया गया था। ।
तो आप जैसे बयान बयान कर सकते हैं:
1 = ~2~
two = 1 * ~2~
लेकिन:
2 = ~3~
six = 2 + 2
कोड का अनुसरण करने के लिए आप जो भी वाक्यविन्यास अस्पष्ट और कठिन चुनते हैं, वह अपरिहार्य है।
सी भाषा और अधिकांश "घुंघराले कोष्ठक" सी से उतरी भाषाओं ने प्रोग्रामर को सीधे ऑक्टल और हेक्साडेसिमल शाब्दिकों को कोड करने की अनुमति देना अच्छा माना, और, यदि यह महत्वपूर्ण था तो शाब्दिक के प्रकार को निर्दिष्ट करने के लिए। इसलिए
010 // Octal 10 = 8;
0x10 // Hexadecimal 10 = 16;
5l // long integer with decimal value 5
2.0d // double float with value 2
इसलिए, भले ही आपने चर नामों को संख्याओं और अक्षरों के संयोजन के बाद शुरू किया हो, जिसमें कम से कम एक अक्षर शामिल हो, आप प्रोग्रामर को यह तय करने की समस्या के साथ प्रस्तुत करेंगे कि क्या किसी दिए गए समूह ने एक चर नाम या एक संख्यात्मक शाब्दिक गठन किया है या नहीं
2lll = 22 // OK
2ll = 2 // compiler error
इस तरह की अस्पष्टता किसी को भी प्रोग्राम लिखने या पढ़ने में मदद नहीं करेगी।
बारीकी से संबंधित वास्तविक दुनिया उदाहरण के लिए आप PL / 1 भाषा को देख सकते हैं, जिनके डिजाइनरों ने सोचा था कि खोजशब्दों को चर नामों के रूप में उपयोग करने में सक्षम होना एक अच्छा विचार है:
IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;
IF IF THEN ELSE = IF; ELSE THEN = ELSE;
DO WHILE (WHILE = DO); END = WHILE + DO; END;
मान्य कोड है जो संकलित करता है और निष्पादित करता है।
फोरट्रान का इस बात पर बहुत प्रभाव पड़ा कि बाद की भाषाओं को कैसे डिजाइन किया गया। आरंभिक (इनमें से कुछ समस्याएं तब से तय हो गई हैं) फोरट्रान में लगभग कोई नियम नहीं था कि आप किसी पहचानकर्ता को क्या नाम दे सकते हैं। इसने संकलक और प्रोग्रामर दोनों के लिए भाषा को बेहद कठिन बना दिया। यहाँ एक क्लासिक उदाहरण है:
if if .eq. then then = else else else = endif endif
K I K K I I K I I K
यहां मैंने K और पहचानकर्ताओं (चर नामों) के साथ "भाषा के प्रमुख शब्द" को चिह्नित किया है। I. यह देखते हुए कि वर्तनी में कोई अंतर नहीं है, मुझे लगता है कि आप शायद समझ सकते हैं कि यह कैसे भ्रमित हो सकता है। निस्संदेह, यह एक चरम उदाहरण है, और यह किसी ने कभी भी कोड को इस तरह से लिखने की संभावना नहीं है। कभी-कभी लोगों ने भाषा के प्रमुख शब्दों को पहचानकर्ता नामों के रूप में "रीसायकल" किया था - और बहुत सारे मामलों में एक सरल टाइपो कोड में परिणाम हो सकता है कि भाषा की कल्पना को इस तरह से पार्स किया जाना चाहिए, भले ही यह बिल्कुल भी इरादा न हो। एक अन्य प्रसिद्ध उदाहरण के लिए, इसकी तुलना करें:
do 10 i = 1,10
इसके लिए:
do 10 i = 1.10
पहला एक लूप है - 10 बार कोड के एक खंड को पुनरावृत्त करना। हालाँकि, दूसरी, अल्पविराम को एक दशमलव बिंदु में बदल दिया गया है, इसलिए यह 1.10
एक चर नाम के मान को असाइन कर रहा है do 10 i
।
इसका मतलब यह भी था कि फोरट्रान पार्सर लिखना अपेक्षाकृत कठिन था - आप निश्चित नहीं हो सकते हैं कि do
लाइन की शुरुआत में लाइन के अंत तक पहुंचने तक वास्तव में एक महत्वपूर्ण शब्द था, और सत्यापित किया कि सभी अन्य तत्व do
पाश उपस्थित थे। पार्सर को आम तौर पर "बैकट्रैक" के लिए तैयार रहना पड़ता था, शुरू से "सही" (लेकिन अक्सर अनपेक्षित) उत्तर के लिए लाइन को फिर से पार्स करते हुए वास्तव में क्या था।
इस के कुछ ही वर्षों के बाद, भाषा डिजाइनरों (उनमें से ज्यादातर वैसे भी) विपरीत चरम की ओर चला गया - उपयोगकर्ताओं शिकायत के बिना संभव के रूप में ज्यादा के रूप में भाषा के बारे में लगभग सब कुछ सीमित भी ज्यादा।
प्रारंभिक रूप से, उदाहरण के लिए, मूल रूप से कहा गया है कि आप पहचानकर्ता के हिस्से के रूप में एक प्रमुख शब्द का उपयोग भी नहीं कर सकते हैं - उदाहरण के लिए, (यानी, लूप की शुरुआत , असाइनमेंट नहीं ) के fora=1
रूप में पार्स किया जाएगा । यह स्पष्ट रूप से पर्याप्त शिकायतें उत्पन्न करता है कि यह बहुत लंबे समय तक नहीं चला। एक अंक के साथ एक पहचानकर्ता शुरू करने के बारे में नियम ने स्पष्ट रूप से बहुत सारी शिकायतें उत्पन्न नहीं की हैं, इसलिए इसका उपयोग कम से कम (अधिकांश भाषाओं में) किया जाता है।for a = 1
for
संभवतः यह सम्मेलन बहुत ही प्रारंभिक ऐतिहासिक भाषा के डिजाइन निर्णयों से विकसित हुआ है, क्योंकि प्रारंभिक मशीनों पर पूरे संकलक, जिसमें लेक्सिकल विश्लेषण भी शामिल है, कुछ के-वर्ड्स में चलना था, वर्तमान मोबाइल उपकरणों पर सिर्फ प्रथम-स्तरीय प्रोसेसर डेटा कैश की तुलना में कम मेमोरी, इसलिए अनुमत चर नाम बहुत सीमित थे, और बहुत कम ऑप कोड में संख्यात्मक स्थिरांक से अलग होना आसान था।
इस प्रकार, यह सम्मेलन बन गया कि प्रोग्रामर की पीढ़ियों का उपयोग किस लिए किया जाता है।
यह प्रोग्रामिंग भाषा के लिए तार्किक रूप से आवश्यक नियम नहीं है, बल्कि कई भाषा डिजाइनरों द्वारा उपयोग किए जाने वाले सम्मेलन है।
मैं मौलिक रूप से भिन्न भाषा डिज़ाइन कर सकता हूं जो पहचानकर्ताओं के लिए सभी वर्णों को अनुमति देता है। सभी कोड लाइनों के लिए, पहले 20 वर्ण कथन प्रकार का वर्णन करेंगे, फिर अगले 20 वर्ण कथन के लिए पहले प्रतीक को परिभाषित करेंगे, और अगला 20 वर्ण कथन के लिए परिचालित होता है। यह भाषा स्टैक प्रोसेसर पर निष्पादित की जाएगी।
01234567890123456789 01234567890123456789 01234567890123456789
decl symbol 12345
assign value 12345 12345
decl symbol 99999
assign value 99999 12345
push 12345
push 99999
add
print top
इस कोड को नीचे C के रूप में अनुवादित किया जा सकता है:
int i12345 = 12345;
int i99999 = 12345;
printf("%d", i12345+i9999);
बस इतना ही। यह अर्थहीन है और संख्या-में-पहचानकर्ता नियम भी तार्किक आधार पर व्यर्थ है।
"लेसर के लिए सुविधा" के अलावा, मुझे लगता है कि यह "पाठक के लिए सुविधा" पर भी विचार करने योग्य है।
कोड पढ़ते समय, आपको जल्दी और बार-बार पहचानने की जरूरत है कि कौन से शब्द पहचानकर्ता हैं, और कौन से नंबर हैं। शुरुआत में एक अंक की तलाश करना हमारे दृश्य पैटर्न-मिलान पर आसान है; अगर हम ध्यान से सभी पात्रों की जाँच करने के लिए सुनिश्चित करने के लिए यह एक घर का काम होगा।
इस सवाल का जवाब ऑटोमेटा या अधिक सटीक परिमित ऑटोमेटा में निहित है जो नियमित अभिव्यक्ति को परिभाषित करता है। नियम यह है ... कंपाइलर को हर वर्ण को तय करने के लिए सटीक एल्गोरिदम या नियमों की आवश्यकता होती है जो वे पार्स करते हैं। यदि पहचानकर्ताओं को संख्या के साथ शुरू करने की अनुमति दी गई थी, तो संकलक एक तय समय में होगा..तो आने वाले टोकन की प्रकृति के बारे में ... क्या यह एक संख्या या एक पहचानकर्ता होगा ... और संकलक पहले के पदों पर वापस नहीं आ सकता है। .so..तो संकलक को यह स्पष्ट कर दें कि आने वाला टोकन ठीक-ठीक पहचानकर्ता या संख्या है ... यह प्रतिबंध है ... इस का coz ... कंपाइलर पहले चरित्र को स्कैन करके ही जानता है कि आने वाला टोकन एक पहचानकर्ता या एक संख्या है।