पहचानकर्ताओं को एक संख्या से क्यों नहीं शुरू करना चाहिए?


32

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


4
क्या आपके पास एक परिवर्तनीय नाम का एक भी उदाहरण है जहां यह स्पष्टता और पठनीयता के लिए लाभ होगा?
सुरक्षित रखें

5
@Secure: 3dspline, 4seasonPizza, 2pdfConverter, 8bitInt, ...
उपयोगकर्ता अज्ञात

6
फोर्थ इसकी अनुमति देता है। बिल्ट-इन में से: 2DUP, 2DROP, 2SWAP, 2> R, 2R @, 2R>, 0 =, इत्यादि
पीटर मोर्टेंसन

जैसा कि टीसीएल करता है, लेकिन मुझे नहीं लगता कि कोई भी मानक टीसीएल कमांड एक नंबर
jk से

1
SO पर समान संभव: stackoverflow.com/questions/342152/…
Ciro Santilli 中心:::

जवाबों:


51

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

  • 0 - हस्ताक्षरित पूर्णांक
  • 0l - लंबे पूर्णांक पर हस्ताक्षर किए
  • 0u - अहस्ताक्षरित पूर्णांक
  • 0i64 - 64 बिट हस्ताक्षरित पूर्णांक

इसलिए ए) यह लेक्सर के लिए आसान है क्योंकि डैनियल ने कहा, लेकिन यह भी ख) यह एक स्पष्ट अंतर बनाता है क्योंकि 0y एक चर हो सकता है लेकिन 0u कभी नहीं होगा। प्लस अन्य क्वालीफायर, जैसे "i64" को "एल" या "यू" की तुलना में बाद में जोड़ा गया था और वे जरूरत पड़ने पर अधिक जोड़ने के विकल्प को खुला रखना चाहते हैं।


7
इसके अलावा, हेक्स संख्या 0xd + के रूप में लिखी जाती है, जहां d + 1 अधिक हेक्स अंक 0-एफ है - इसलिए 0xbeef एक पूरी तरह से मान्य "संख्या" है।
tcrosley

20
आप लोग महसूस करते हैं कि मैं एक भाषा कल्पना के लिए नहीं जा रहा था, लेकिन केवल कुछ उदाहरणों को स्पष्ट करने के लिए उदाहरण दिए, है ना?
DXM

6
पुन: "वे यदि आवश्यक हो तो अधिक जोड़ने के विकल्प को खुला रखना चाहते हैं": और C ++ 11 यहां तक ​​कि आप अपना खुद का जोड़ सकते हैं; http://en.wikipedia.org/wiki/C+11#User-defined_literals देखें ।
बर्बाद करें

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

1
@LarryGritz: "लगातार शब्दों को अलग-अलग करने से रिक्त स्थान दसवीं शताब्दी ईस्वी के बारे में एक सामान्य रिवाज बन गया, और 1957 तक चला, जब फोरट्रान ने अभ्यास को छोड़ दिया।" -सुन फोरट्रान संदर्भ मैनुअल (विकी से)। फोरट्रान के अपने विशेष कारण थे क्योंकि उन्होंने तय किया था कि सामान्य रूप से रिक्त स्थान वैकल्पिक थे। आधुनिक भाषाएं जैसे उनके व्हाट्सएप। आप अल्गोल के साथ अपने दम पर हैं, लेकिन मैं कितना आधुनिक है कि एक भी नहीं हूं। दूसरी ओर C / C ++ / C # / F # सभी प्रत्यय हैं।
DXM

49

लीकर को लागू करने वाले लोगों की सुविधा। (नहीं, गंभीरता से, यह इसके बारे में है। विभिन्न भाषाओं के अन्य कारण हैं, लेकिन यह अंततः उसी के लिए नीचे आता है।)


2
खूंटी या अन्य आधुनिक पार्सिंग तकनीकों का उपयोग करके अंकों के साथ शुरू होने वाले अभिन्न शाब्दिक और पहचानकर्ताओं के बीच अंतर करना आसान होगा। यहां तक ​​कि आदिम लेकर्स का उपयोग करने वाले कंपाइलर उन्हें एक ही टोकन श्रेणी में डाल सकते हैं और बाद में अंतर कर सकते हैं। यह बहुत ही अजीब होगा यदि उदा 0fluएक शाब्दिक 0gluथा और एक स्थानीय पहचानकर्ता था।
डैनियल लुबरोव

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

2
@ डैनियलपिटमैन: आपको किसी भी प्रकार के विश्वसनीय वितरण को करने के लिए सिमेंटिक विश्लेषण की आवश्यकता होगी, ताकि इसे लेसर में न किया जा सके। निर्णय लेक्सर से बाहर धक्का देने से पार्सर अधिक जटिल हो जाता है, और इससे क्या लाभ होता है? बहुत ही खराब लागत / लाभ की स्थिति के अलावा, इस मामले int 0u = 5; unsigned int x = 0u;की व्याख्या को चुनने का कोई अच्छा तरीका नहीं है, हालांकि आप इस कोड की व्याख्या को परिभाषित करने के लिए चुनते हैं (संभवतः या तो x == 0 या x == 5), लोग भ्रमित होने वाले हैं अस्पष्टता के कारण। यहां तक ​​कि अगर यह संकलक को इस तरह से लागू करने के लिए तुच्छ थे, तो एक अच्छा डिजाइनर संभवतः ऐसा नहीं करेगा।
जोरन

10
मुख्य सुविधा मेरे सिर में पार्सर के लिए है, न कि भाषा के निर्माता के लिए।
कोडइन्चोस 11

2
यह अभी भी कई लोगों के लिए आश्चर्य की बात है कि लेक्सिकल विश्लेषण आमतौर पर एक कंपाइलर / दुभाषिया का सबसे धीमा चरण होता है।
हिप्पिट्रैएल

20

निम्नलिखित 2 मामलों पर विचार करें:

मामला एक

मान लेते हैं कि एक पहचानकर्ता एक संख्या से शुरू हो सकता है।

तो नीचे जैसा एक बयान मान्य होगा (चूंकि एक पहचानकर्ता में 1 या अधिक वर्ण हो सकते हैं):

int 3;

जब मैं एक कार्यक्रम में उपरोक्त चर का उपयोग करने की कोशिश करता हूं, तो इसका परिणाम संकलक अस्पष्टता में होगा:

int 3, ए;
3 = 5;
एक = 3;

कथन a=3में 3 की भूमिका क्या है (क्या यह मान 5 के साथ एक चर है या यह अंक 3 है)?

केस 2

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

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

  • कंपाइलर को सभी अंको (जैसे 333) और वैध वर्णमाला प्रत्ययों (जैसे 34 एल) को चर नामों के रूप में उपयोग किए जाने पर त्रुटि मामलों की जांच और रिपोर्ट करनी होगी। पाइथन और जेएस जैसी ढीली टाइप की गई भाषाओं में, जहां आप उन्हें घोषित किए बिना मक्खी पर चर का उपयोग कर सकते हैं, यहां तक ​​कि सभी अंकों से जुड़े विशेष मामलों की जांच करना भी असंभव हो सकता है। उदाहरण के लिए if (33==5), 33 एक त्रुटिपूर्ण अघोषित परिवर्तनीय संस्करण हो सकता है जिसे उपयोगकर्ता ने घोषित किया है। लेकिन संकलक इसे पहचानने और त्रुटि की रिपोर्ट करने में सक्षम नहीं होगा।

इस प्रतिबंध को बनाने से प्रोग्रामर को पहचानकर्ता नामों के रूप में संख्याओं का उपयोग करने से रोका जा सकेगा।


2
इस तर्क के तहत, पहचानकर्ताओं में वर्ण नहीं हो सकते क्योंकि वे कीवर्ड के लिए अस्पष्ट होंगे। क्या आप सोच सकते हैं कि यह कितना विनाशकारी int char = floatहोगा?
पब

4
@Pubby: मैं यह नहीं देखता कि आप कुछ अतिरिक्त गैर-समझदारी के बारे में क्या कह सकते हैं, जिसे मैं अभी तक समझ नहीं पाया हूं। आपकी टिप्पणी का क्या अर्थ है?
13:90 पर aml90

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

@Pubby: अस्पष्टता से मेरा मतलब था कि संकलक को यह नहीं पता होगा कि मैं किस नाम के संदर्भ में चर नाम (यहां तक ​​कि लेक्सिकल पूर्वता का उपयोग करके) का उपयोग कर रहा हूं। उदाहरण के लिए, इस कोड पर विचार करें: int 3,a; 3=5; a=3; कथन a = 3 में, 3 की पहचान एक पहचानकर्ता के रूप में या एक संख्या के रूप में की गई है? यह अस्पष्टता का कारण बनता है। आशा है कि यह स्पष्ट है।
13:90 पर aml90

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

11

अधिकांश भाग के लिए इसका कंपाइलर लेखकों और पार्सिंग दक्षता के लिए आसान बनाने के साथ कोई लेना-देना नहीं है, लेकिन, एक सिंटेक्स को डिजाइन करने के साथ अधिक है जो स्पष्ट पठनीय और अस्पष्ट कोड को प्रोत्साहित करता है।

इसके भाषा डिजाइनरों ने सोचा कि नंबर 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;

मान्य कोड है जो संकलित करता है और निष्पादित करता है।


C को यूनिक्स के लिए पोर्टेबल असेंबली के रूप में डिजाइन किया गया था। यूनिक्स मूल रूप से एक 18-बिट मशीन के लिए डिज़ाइन किया गया था, जहां ऑक्टल प्रिंटिंग के लिए एक अच्छा फिट है उसी तरह हेक्स 8/16/32-बिट मशीन मूल्यों को प्रिंट करने के लिए एक अच्छा फिट है। इसलिए उन्हें वास्तव में अष्टक की आवश्यकता थी।

इसके अलावा बिट टिडलिंग के लिए (या, XOR, AND, NOT) और डिवाइस चालकों को लागू करने के लिए एक शाब्दिक के सटीक आकार के साथ-साथ मूल्य को निर्दिष्ट करना महत्वपूर्ण है!
जेम्स एंडरसन

10

फोरट्रान का इस बात पर बहुत प्रभाव पड़ा कि बाद की भाषाओं को कैसे डिजाइन किया गया। आरंभिक (इनमें से कुछ समस्याएं तब से तय हो गई हैं) फोरट्रान में लगभग कोई नियम नहीं था कि आप किसी पहचानकर्ता को क्या नाम दे सकते हैं। इसने संकलक और प्रोग्रामर दोनों के लिए भाषा को बेहद कठिन बना दिया। यहाँ एक क्लासिक उदाहरण है:

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 = 1for


IMHO यह वास्तविक कारण के सबसे करीब है। फोरट्रान जैसी प्रारंभिक भाषाएं, कुछ मायनों में, बहुत असंरचित थीं, जिससे मजबूत संकलक लिखने में कठिनाई हो रही थी और स्रोत कोड को सही ढंग से देखने के लिए मनुष्यों के लिए कठिनाई हो रही थी। "Do10i = ..." एक उत्कृष्ट और प्रसिद्ध उदाहरण है। जैसे-जैसे भाषाएँ विकसित हुईं, कुछ नियम और कड़े हो गए। अल्गोल संभवत: मानक के दादा हैं "पहचानकर्ता पत्रों से शुरू होते हैं और उसके बाद अक्षर या संख्या हो सकती है" अंगूठे का नियम।
लैरी ग्रिट्ज

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

1

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

इस प्रकार, यह सम्मेलन बन गया कि प्रोग्रामर की पीढ़ियों का उपयोग किस लिए किया जाता है।


1

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

मैं मौलिक रूप से भिन्न भाषा डिज़ाइन कर सकता हूं जो पहचानकर्ताओं के लिए सभी वर्णों को अनुमति देता है। सभी कोड लाइनों के लिए, पहले 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);

बस इतना ही। यह अर्थहीन है और संख्या-में-पहचानकर्ता नियम भी तार्किक आधार पर व्यर्थ है।


0

"लेसर के लिए सुविधा" के अलावा, मुझे लगता है कि यह "पाठक के लिए सुविधा" पर भी विचार करने योग्य है।

कोड पढ़ते समय, आपको जल्दी और बार-बार पहचानने की जरूरत है कि कौन से शब्द पहचानकर्ता हैं, और कौन से नंबर हैं। शुरुआत में एक अंक की तलाश करना हमारे दृश्य पैटर्न-मिलान पर आसान है; अगर हम ध्यान से सभी पात्रों की जाँच करने के लिए सुनिश्चित करने के लिए यह एक घर का काम होगा।


0

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

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