वाक्य रचना त्रुटि किस प्रक्रिया में होती है? (टोकन या पार्सिंग)


23

मैं संकलन और व्याख्या को समझने की कोशिश कर रहा हूं, कुल छवि के आधार पर कदम दर कदम। इसलिए मैं http://www.cs.man.ac.uk/~pjj/farrell/com.html.html यह लेख पढ़ते हुए एक प्रश्न पर आया था

इसे कहते हैं :

संकलक के अगले चरण को पार्सर कहा जाता है। संकलक के इस भाग में भाषा के व्याकरण की समझ है। यह सिंटैक्स त्रुटियों की पहचान करने और आंतरिक डेटा संरचनाओं में एक त्रुटि मुक्त कार्यक्रम का अनुवाद करने के लिए जिम्मेदार है जिसे किसी अन्य भाषा में व्याख्या या लिखा जा सकता है।

लेकिन मैं यह पता नहीं लगा सका कि टोकन किस तरह से दिए गए स्ट्रीम को ठीक से टोकन कर सकता है जिसमें सिंटैक्स त्रुटि है।

यह वहां पर अटक जाना चाहिए या पार्सर को कुछ गलत जानकारी देनी चाहिए। मेरा मतलब है कि टोकन भी एक प्रकार का अनुवादक नहीं है?

तो यह कैसे टोकन के दौरान कोड की शाब्दिक भ्रष्ट लाइनों को दूर करता है।

टोकेनाइज़र हेडिंग के ऊपर लिंक के अंदर टोकन का एक उदाहरण है ।

जैसा कि मैं समझता हूं कि टोकन का रूप ऐसा लगता है, अगर कोड में कुछ गड़बड़ है तो भ्रष्ट भी हो जाएगा।

क्या आप कृपया मेरी गलतफहमी को स्पष्ट कर सकते हैं?

जवाबों:


32

एक टोकन सिर्फ एक पार्सर अनुकूलन है। टोकनर के बिना पार्सर को लागू करना पूरी तरह से संभव है।

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

$a + $b

टोकन द्वारा प्रतिनिधित्व किया जा सकता है

Variable('$a'),
Plus('+'),
Variable('$b')

टोकनधारक इस संदर्भ में एक टोकन संभव है या नहीं इस पर विचार नहीं करता है। उदाहरण के लिए, इनपुट

$a $b + +

खुशी से टोकन स्ट्रीम का उत्पादन करेगा

Variable('$a'),
Variable('$b'),
Plus('+'),
Plus('+')

जब पार्सर तब इन टोकन का उपभोग करता है, तो यह ध्यान देगा कि दो चर एक दूसरे का अनुसरण नहीं कर सकते हैं, और न ही दो infix ऑपरेटर कर सकते हैं। (ध्यान दें कि अन्य भाषाओं में अलग-अलग वाक्य-विन्यास होते हैं जहाँ इस तरह की टोकन स्ट्रीम कानूनी हो सकती है, लेकिन PHP में नहीं)।

टोकनर चरण में एक पार्सर अभी भी विफल हो सकता है। उदाहरण के लिए, एक अवैध चरित्र हो सकता है:

$a × ½ — 3

एक PHP टोकनर इस इनपुट को उसके नियमों से मिलान करने में असमर्थ होगा, और मुख्य पार्सिंग शुरू होने से पहले एक त्रुटि उत्पन्न करेगा।

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


तो हम सोच सकते हैं कि जैसा कि पार्सर का एक हिस्सा है और सिंटैक्स त्रुटि हो सकती है या तो सिंटैक्स त्रुटि रूप के अनुसार चरण या पार्सिंग चरण टोकन हो सकता है। स्पष्टीकरण के लिए धन्यवाद।
FZE

4
@FZE: आप ऐसा सोच सकते हैं , लेकिन यह भ्रामक है। लेक्सिंग "सिर्फ एक पार्सर अनुकूलन" नहीं है। बल्कि, लेक्सिंग एक भौतिक प्रतिनिधित्व (पात्रों का कुछ अनुक्रम) को एक तार्किक प्रतिनिधित्व (उन पात्रों द्वारा दर्शाए गए टोकन) में बदल देता है। इस तरह एक पंक्ति के अंत का प्रतिनिधित्व करती है की तरह ज़रा सी बात से पार्सर को अलग कर देता है, या आप एक तार्किक और के रूप में प्रतिनिधित्व करने के लिए तय andया &&किसी और या कुछ और। यह (अधिकतर) पार्सिंग से अलग और अलग है। अनुकूलन (यदि कोई हो) लगभग आकस्मिक दुष्प्रभाव है।
जेरी कॉफिन

@JerryCoffin आगे की व्याख्या के लिए धन्यवाद, यह अब और अधिक समझ में आता है।
FZE

2
@JerryCoffin, एमोन सही है कि अंतर मौलिक नहीं है। आप एक सुसंगत बीएनएफ व्याकरण बना सकते हैं जो "लेक्सर" और "पार्सर" दोनों भागों को कवर करता है। हम आम तौर पर नियमों को निम्न स्तर (जैसे, संख्या, अतिरिक्त ऑपरेटर) और उच्च स्तर (योग) में वर्गीकृत करते हैं, लेकिन व्याकरण ही ऐसा कोई भेद नहीं करता है।
पॉल ड्रेपर

1
@PaDraper सुनिश्चित नहीं है कि पहले चरण के रूप में एक नियमित भाषा को अलग करना सही विकल्प है। उदाहरण के लिए मिलान किए गए जोड़े (नियमित नहीं) कुछ भाषाओं में स्ट्रिंग शाब्दिक वर्णन करने के लिए आवश्यक हो सकते हैं, फिर भी पहले चरण में उन्हें संभालने के लिए अभी भी समझ में आता है। बैक-ट्रैकिंग को कम करना / कम करना एक बेहतर दिशानिर्देश की तरह लगता है।
CodesInChaos

16

आप आमतौर पर पार्सर से आने वाले अधिकांश वाक्यविन्यास त्रुटियों की अपेक्षा करेंगे , न कि लेक्सर की।

लेक्सर एक त्रुटि उत्पन्न करेगा अगर (और ज्यादातर केवल अगर) इनपुट में कुछ ऐसा है जिसे टोकन नहीं किया जा सकता है। कई भाषाओं में, हालांकि, लगभग किसी भी क्रम के पात्रों को किसी प्रकार के टोकन में बदल दिया जा सकता है, इसलिए यहां त्रुटियां काफी असामान्य हैं।

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


11

Tokenizer सिर्फ टोकन में चरित्र धारा विभाजित होता है। tokenizer पीओवी से यह पूरी तरह से वैध है:

1 * * 1

और कुछ इस तरह से अनुवाद ["1", MULTIPLY, MULTIPLY, "1"] करता है : केवल पार्सर ऐसे भावों को अस्वीकार कर सकता है - यह जानता है कि बहु ऑपरेटर किसी अन्य बहुपरत ऑपरेटर का अनुसरण नहीं कर सकता है। उदाहरण के लिए जावास्क्रिप्ट में यह उत्पादन करता है:

Uncaught SyntaxError: Unexpected token *(…)

ऐसी त्रुटियां हैं, जिन्हें टोकन द्वारा पता लगाया जा सकता है। उदाहरण के लिए अधूरा स्ट्रिंग शाब्दिक: "abcया अमान्य संख्याएँ 0x0abcdefg:। उन्हें अभी भी सिंटैक्स त्रुटियों के रूप में रिपोर्ट किया जा सकता है:

Uncaught SyntaxError: Unexpected token ILLEGAL

नोट हालांकि टोकन को मान्यता नहीं दी गई थी और इसे रिपोर्ट किया गया है ILLEGAL

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