সমস্যাটি বর্ণনা করার জন্য, ড্যাংলিং অন্য সমস্যাটি কোড সিনট্যাক্সের নির্দিষ্টকরণের ক্ষেত্রে একটি দ্ব্যর্থহীনতা যেখানে এটি অস্পষ্ট হতে পারে, নেফটেড আইএফএস এবং এলেসের ক্ষেত্রে, যা অন্যটির সাথে সম্পর্কিত if
সবচেয়ে সহজ এবং ক্লাসিক উদাহরণ:
if(conditionA)
if(conditionB)
doFoo();
else
doBar();
এটি অস্পষ্ট, যারা হৃদয় দিয়ে ভাষা নির্দিষ্টকরণের সুনির্দিষ্ট জানেন না, যা if
পায় else
(এবং এই নির্দিষ্ট কোড স্নিপেটটি অর্ধ ডজন ভাষায় বৈধ, তবে প্রতিটি ক্ষেত্রে আলাদাভাবে সম্পাদন করতে পারে)।
ড্যাংলিং অন্য নির্মাণটি স্ক্যানারবিহীন পার্সার বাস্তবায়নের ক্ষেত্রে একটি সম্ভাব্য সমস্যা সৃষ্টি করে, কারণ কৌশলটি একবারে ফাইল স্ট্রিমের একটি চরিত্রকে স্লাপ করে দেওয়া হয়, যতক্ষণ না পার্সার দেখতে পায় যে এতে টোকানাইজ করার মতো যথেষ্ট পরিমাণ রয়েছে (অ্যাসেম্বলি বা মধ্যবর্তী ভাষায় এটি সঙ্কলন করছে) । এটি পার্সারকে ন্যূনতম অবস্থা বজায় রাখতে সহায়তা করে; যত তাড়াতাড়ি এটি মনে হয় এটির কাছে টোকেনগুলি ফাইলটিতে লিখার জন্য পর্যাপ্ত তথ্য রয়েছে, এটি এটি করবে। এটি স্ক্যানারহীন পার্সারের শেষ লক্ষ্য; দ্রুত, সহজ, লাইটওয়েট সংকলন।
বিরামচিহ্নের আগে বা পরে নিউলাইনগুলি এবং শ্বেতক্ষেত্র ধরে নেওয়া অর্থহীন (তারা বেশিরভাগ সি-স্টাইলের ভাষায় রয়েছে), এই বিবৃতিটি সংকলককে এইভাবে উপস্থিত হবে:
if(conditionA)if(conditionB)doFoo();else doBar;
কোনও কম্পিউটারে পুরোপুরি পার্স-সক্ষম, সুতরাং আসুন দেখুন। আমি না হওয়া পর্যন্ত আমি একবারে একটি চরিত্র পেয়েছি:
if(conditionA)
ওহ, আমি জানি (সি # তে) এর অর্থ কী, এর অর্থ " push
কন্ডিশনএল এভাল স্ট্যাকের উপরে এবং তারপরে brfalse
যদি সত্য হয় না তবে পরবর্তী সেমিকোলনের পরে বিবৃতিতে ঝাঁপ দাও"। এখনই আমি কোনও সেমিকোলন দেখতে পাচ্ছি না, সুতরাং আপাতত আমি এই নির্দেশের পরে আমার জাম্প অফসেটটি পরবর্তী স্পেসে সেট করব এবং আমি সেমিকোলন না পাওয়া পর্যন্ত আরও নির্দেশাবলীর সন্নিবেশ করায় আমি সেই অফসেটটি বাড়িয়ে দেব। পার্স করা অবিরত ...
if(conditionB)
ঠিক আছে, এটি একই রকমের আইএল অপারেশনগুলির বিশ্লেষণ করে, এবং আমি কেবলমাত্র পার্স করা নির্দেশের পরে তা চলে যায়। আমি কোনও সেমিকোলন দেখতে পাচ্ছি না, তাই আমি আমার পূর্ববর্তী বিবৃতিটির জাম্প অফসেটটি আমার দুটি কমান্ডের দৈর্ঘ্যের দ্বারা বৃদ্ধি করব (একটি ধাক্কার জন্য এবং একটি বিরতির জন্য) এবং তাকাতে থাকব।
doFoo();
ঠিক আছে, এটা সহজ। এটি " call
ডুফু"। আর সেটাই কি আমি সেমিকোলন দেখছি? ঠিক আছে, দুর্দান্ত, এটি লাইনের শেষ। আমি এই দুটি কমান্ডের দৈর্ঘ্য দ্বারা আমার উভয় ব্লকের জাম্প অফসেটগুলিকে বাড়িয়ে দেব এবং ভুলে গিয়েছি যে আমি কখনই যত্ন নিয়েছি। ঠিক আছে, এগিয়ে চলছে ...
else
... আহ ওহ. এটি যতটা সহজ দেখায় তেমন সহজ নয়। ঠিক আছে, আমি যা করছিলাম তা ভুলে গিয়েছিলাম, তবে else
এর অর্থ একটি শর্তযুক্ত ব্রেক স্টেটমেন্ট আছে যা আমি ইতিমধ্যে দেখেছি, তাই আমাকে ফিরে তাকাতে দাও ... হ্যাঁ, ঠিক আছে brfalse
, আমি কিছু "কন্ডিশনবি" চালানোর পরে ঠিক আছে স্ট্যাক, যা কিছু ছিল। ঠিক আছে, এখন আমার break
পরবর্তী বিবৃতি হিসাবে একটি শর্তহীন দরকার । এর পরে যে বক্তব্য আসবে তা এখন অবশ্যই আমার শর্তাধীন বিরতির লক্ষ্য, তাই আমি নিশ্চিত করব যে আমার এটি ঠিক আছে এবং আমি যে শর্তহীন বিরতি রেখেছি তা বাড়িয়ে দেব।
doBar();
এটা সহজ. " call
doBar"। এবং সেমিকোলন আছে, এবং আমি কোনও ধনুর্বন্ধনী কখনও দেখিনি। সুতরাং, নিঃশর্ত break
পরবর্তী বিবৃতিতে লাফিয়ে উঠতে হবে, যাই হোক না কেন, এবং আমি ভুলে যেতে পারি যে আমি কখনই যত্ন নিয়েছি।
সুতরাং, আমাদের কী আছে ... (দ্রষ্টব্য: এটি 10:00 অপরাহ্ন এবং বিট অফসেটগুলি হেক্সাডেসিমালে রূপান্তর করা বা এই কমান্ডগুলির সাহায্যে কোনও ফাংশনের পুরো আইএল শেলটি পূরণ করার মতো মনে হয় না, তাই এটি কেবল ছদ্ম-আইএল লাইন নম্বর ব্যবহার করে যেখানে সাধারণত বাইট অফসেট থাকে):
ldarg.1 //conditionA
brfalse <line 6> //jumps to "break"
ldarg.2 //conditionB
brfalse <line 7> //jumps to "call doBar"
call doFoo
break <line 8> //jumps beyond statement in scope
call doBar
<line 8 is here>
ঠিক আছে, এটি আসলে সঠিকভাবে কার্যকর করে, যদি নিয়মটি (বেশিরভাগ সি-স্টাইলের ভাষাগুলিতে) হয় তবে এটি হল else
নিকটতমের সাথে if
। মৃত্যুদণ্ড কার্যকর নেস্টিং অনুসরণ করতে ইচ্ছুক, এটি এইরূপে কার্যকর করা হবে, যেখানে শর্ত A মিথ্যা হলে, স্নিপেটের পুরো অবশিষ্টটি এড়িয়ে যায়:
if(conditionA)
if(conditionB)
doFoo();
else
doBar();
... তবে এটি নির্লজ্জতার দ্বারা এটি করে, কারণ বাইরের if
স্টেটমেন্টের সাথে যুক্ত বিরতিটি অভ্যন্তরেরbreak
শেষের দিকে বিবৃতিতে লাফ দেয় , যা সম্পূর্ণ বিবরণের বাইরেও এক্সিকিউশন পয়েন্টার নেয়। এটি একটি অতিরিক্ত অপ্রয়োজনীয় লাফ, এবং এই উদাহরণটি যদি আরও জটিল হয় তবে পার্সড এবং টোকেনাইজ করা থাকলে এটি আর কাজ করতে পারে না। if
এছাড়াও, যদি ভাষাটির স্পেসিফিকেশনটি বলে যে একটি ঝোলা else
প্রথমটির অন্তর্গত if
, এবং যদি শর্তA মিথ্যা হয় তবে doBar কার্যকর করা হয়, যখন কন্ডিশনএ সত্য হয় তবে কন্ডিশনবি নয় তবে এরকম কিছুই ঘটে না?
if(conditionA)
if(conditionB)
doFoo();
else
doBar();
পার্সারটি if
সর্বকালের অস্তিত্বটিকে ভুলে গিয়েছিল এবং তাই এই সাধারণ পার্সার অ্যালগরিদমটি কার্যকর কোডের কিছু না বলে সঠিক কোড তৈরি করতে পারে না।
এখন, পার্সারটি দীর্ঘ সময়ের জন্য এটির if
s এবং গুলিগুলি মনে রাখার জন্য যথেষ্ট স্মার্ট হতে পারে else
, তবে যদি ভাষা অনুমানটি else
দুটি if
সেকেন্ডের পরে প্রথমটিকে একটি করে বলে if
, এটি দুটি if
মিলিয়ে else
s এর সাথে সমস্যা সৃষ্টি করে :
if(conditionA)
if(conditionB)
doFoo();
else
doBar();
else
doBaz();
পার্সার প্রথমটি দেখতে পাবে, প্রথমটির সাথে else
মিলবে if
, তারপরে দ্বিতীয়টি দেখবে এবং আতঙ্কিত হবে "আমি আবার কী করছিলাম" মোডে। এই মুহুর্তে পার্সারের পরিবর্তে একটি পরিবর্তনীয় স্থানে প্রচুর কোড পেল যে এটি ইতিমধ্যে আউটপুট ফাইল প্রবাহে ইতিমধ্যে ধাক্কা দিত।
এই সমস্ত সমস্যার সমাধান আছে এবং কী-যদি? তবে, হয় স্মার্ট হওয়ার প্রয়োজনীয় কোডটি পার্সার অ্যালগরিদমের জটিলতা বৃদ্ধি করে, বা পার্সারকে এই বোবা হতে দেয় এমন ভাষা নির্দিষ্ট করে ভাষা উত্স কোডের ক্রিয়াপদ বৃদ্ধি করে, যেমন বন্ধকরণের বিবৃতি যেমন end if
নেস্টেড ইঙ্গিত দেওয়ার প্রয়োজন হয় বা বন্ধনীগুলি নির্দেশ করে যদি if
বিবৃতিটির একটি থাকে else
(উভয়ই অন্যান্য ভাষার শৈলীতে সাধারণত দেখা যায়)।
এটি বেশ কয়েকটি if
বিবৃতিগুলির একটি মাত্র সাধারণ উদাহরণ এবং সংকলকটি যে সমস্ত সিদ্ধান্ত নিয়েছিল সেগুলি দেখুন এবং এটি খুব সহজেই যে কোনও উপায়ে বিভ্রান্ত হতে পারে। আপনার প্রশ্নের উইকিপিডিয়ায় যে নিরীহ বিবৃতি রয়েছে তার পিছনে এটিই বিশদ।