যখন পর্যাপ্ত পরিমাণে লেক্সিং করা হয়, আপনার কখন ইবিএনএফ প্রয়োজন?
ইবিএনএফ সত্যিই ব্যাকরণের শক্তিতে খুব বেশি যোগ করে না । চমকস্কির নরমাল ফর্ম (সিএনএফ) ব্যাকরণ নিয়মগুলির তুলনায় এটি কেবল একটি সুবিধা / শর্টকাট স্বরলিপি / "সিনট্যাকটিক চিনি" । উদাহরণস্বরূপ, EBNF বিকল্প:
S --> A | B
আপনি প্রতিটি বিকল্প উত্পাদন আলাদাভাবে তালিকাভুক্ত করে সিএনএফ অর্জন করতে পারেন:
S --> A // `S` can be `A`,
S --> B // or it can be `B`.
EBNF থেকে alচ্ছিক উপাদান:
S --> X?
আপনি সিএনএফ-এ একটি অবিচ্ছিন্ন উত্পাদন ব্যবহার করে অর্জন করতে পারেন , এটি হ'ল একটি যা খালি স্ট্রিং দ্বারা প্রতিস্থাপিত হতে পারে (এখানে কেবল খালি উত্পাদন দ্বারা চিহ্নিত করা হয়; অন্যরা এপিসিলন বা ল্যাম্বদা বা ক্রস সার্কেল ব্যবহার করে):
S --> B // `S` can be `B`,
B --> X // and `B` can be just `X`,
B --> // or it can be empty.
B
উপরের শেষের মতো একটি ফর্মের একটি উত্পাদনকে "ইরেজোর" বলা হয়, কারণ এটি অন্যান্য প্রযোজনায় (যা কিছু অন্যের পরিবর্তে খালি স্ট্রিং তৈরি করে) মুছতে পারে।
ইবিএনএফ থেকে শূন্য বা আরও পুনরাবৃত্তি:
S --> A*
আপনি পুনরাবৃত্ত প্রযোজনা ব্যবহার করে ওটান করতে পারেন , এটি হ'ল এটি যে কোনও জায়গায় নিজেকে এম্বেড করে। এটি দুটি উপায়ে করা যেতে পারে। প্রথমটি পুনরুক্তি বাকি রয়েছে (যা সাধারণত এড়ানো উচিত, কারণ টপ-ডাউন রিকার্সিভ ডেসেন্ট পার্সাররা এটি বিশ্লেষণ করতে পারে না):
S --> S A // `S` is just itself ended with `A` (which can be done many times),
S --> // or it can begin with empty-string, which stops the recursion.
এটি শূন্য বা তার বেশি মাত্র পরে একটি খালি স্ট্রিং (শেষ পর্যন্ত) উত্পন্ন করে জেনেও A
একই স্ট্রিং ( তবে একই ভাষা নয়! ) রাইট-রিকার্সন ব্যবহার করে প্রকাশ করা যেতে পারে :
S --> A S // `S` can be `A` followed by itself (which can be done many times),
S --> // or it can be just empty-string end, which stops the recursion.
এবং যখন +
EBNF থেকে এক বা একাধিক পুনরাবৃত্তি আসে:
S --> A+
এটি একটিকে প্রমাণ A
করে *
এবং আগের মতো ব্যবহার করে করা যেতে পারে:
S --> A A*
যা আপনি সিএনএফ-তে প্রকাশ করতে পারেন (আমি এখানে সঠিক রিক্রুশন ব্যবহার করি; অন্যকে নিজে অনুশীলন হিসাবে বের করার চেষ্টা করুন):
S --> A S // `S` can be one `A` followed by `S` (which stands for more `A`s),
S --> A // or it could be just one single `A`.
এটি জেনে, আপনি সম্ভবত একটি নিয়মিত প্রকাশের (যা নিয়মিত ব্যাকরণ ) ব্যাকরণকে চিনতে পারবেন যা কেবলমাত্র টার্মিনাল প্রতীকগুলি নিয়ে গঠিত একটি একক EBNF উত্পাদনে প্রকাশ করা যেতে পারে। আরও সাধারণভাবে, আপনি যখন প্রযোজনাগুলির সাথে অনুরূপ দেখতে পান আপনি নিয়মিত ব্যাকরণগুলি চিনতে পারবেন:
A --> // Empty (nullable) production (AKA erasure).
B --> x // Single terminal symbol.
C --> y D // Simple state change from `C` to `D` when seeing input `y`.
E --> F z // Simple state change from `E` to `F` when seeing input `z`.
G --> G u // Left recursion.
H --> v H // Right recursion.
তা হল, কেবল খালি স্ট্রিং, টার্মিনাল প্রতীক, বিকল্প এবং রাষ্ট্র পরিবর্তনের জন্য সাধারণ অ টার্মিনালগুলি ব্যবহার করা এবং পুনরাবৃত্তি অর্জনের জন্য কেবল পুনরাবৃত্তি ব্যবহার করা (পুনরাবৃত্তি, যা কেবল লিনিয়ার পুনরাবৃত্তি - যা গাছের মতো শাখা নয়)। এর চেয়ে বেশি উন্নত আর কিছুই নেই, তবে আপনি নিশ্চিত হন যে এটি নিয়মিত বাক্য গঠন এবং এটির জন্য আপনি কেবল লেসার দিয়ে যেতে পারেন।
তবে যখন আপনার সিনট্যাক্সটি নীচের মতো গাছের মতো, স্ব-অনুরূপ, নেস্টেড কাঠামো উত্পাদন করতে একটি অ-তুচ্ছ উপায় হিসাবে পুনরাবৃত্তি ব্যবহার করে:
S --> a S b // `S` can be itself "parenthesized" by `a` and `b` on both sides.
S --> // or it could be (ultimately) empty, which ends recursion.
তাহলে আপনি সহজেই দেখতে পাবেন যে এটি নিয়মিত প্রকাশের মাধ্যমে সম্পন্ন করা যায় না, কারণ আপনি এটিকে কোনও একক ইবিএনএফ উত্পাদনে সমাধান করতে পারবেন না; আপনি S
অনির্দিষ্টকালের জন্য বিকল্পটি শেষ করবেন , যা সর্বদা উভয় পক্ষেই অন্য a
এস এবং b
এস যুক্ত করবে । লেক্সারস (আরও সুনির্দিষ্টভাবে: লেক্সারদের দ্বারা ব্যবহৃত ফাইনাইট স্টেট অটোমেটা) স্বেচ্ছাসেবী সংখ্যা গণনা করতে পারে না (তারা সীমাবদ্ধ, মনে আছে?), সুতরাং তারা জানে না যে এতগুলি সংখ্যার a
সাথে সমানভাবে মিলিত করার জন্য সেখানে কতজন ছিল b
। এর মতো ব্যাকরণগুলিকে প্রসঙ্গমুক্ত ব্যাকরণ বলা হয় (খুব কমপক্ষে) এবং তাদের পার্সার প্রয়োজন।
প্রসঙ্গবিহীন ব্যাকরণগুলি পার্স করার জন্য সুপরিচিত, তাই এগুলি প্রোগ্রামিং ভাষার ভাষার বাক্য গঠন বর্ণনা করার জন্য ব্যাপকভাবে ব্যবহৃত হয়। তবে আরও কিছু আছে। কখনও কখনও আরও সাধারণ ব্যাকরণের প্রয়োজন হয় - যখন আপনার কাছে একই সাথে স্বাধীনভাবে গণনা করার জন্য আরও বেশি জিনিস থাকে। উদাহরণস্বরূপ, আপনি যখন এমন একটি ভাষা বর্ণনা করতে চান যেখানে কেউ বৃত্তাকার বন্ধনী এবং স্কোয়ার ধনুর্বন্ধনী আন্তঃবিহীন ব্যবহার করতে পারে তবে সেগুলি একে অপরের সাথে সঠিকভাবে তৈরি করতে হবে (ধনুর্বন্ধনী সহ বন্ধনীগুলি, বৃত্তাকার সাথে বৃত্তাকার)। এ জাতীয় ব্যাকরণকে প্রসঙ্গে সংবেদনশীল বলা হয় । আপনি এটি দ্বারা এটি সনাক্ত করতে পারবেন যে এটির বাম দিকে (তীরের আগে) একাধিক চিহ্ন রয়েছে। উদাহরণ স্বরূপ:
A R B --> A S B
বিধি প্রয়োগের "প্রসঙ্গ" হিসাবে আপনি বাম দিকের এই অতিরিক্ত চিহ্নগুলি সম্পর্কে ভাবতে পারেন। কিছু পূর্বশর্ত হতে পারে, postconditions ইত্যাদি উদাহরণস্বরূপ, উপরে নিয়ম প্রতিস্থাপন করে দেবে R
মধ্যে S
, কিন্তু শুধুমাত্র যখন এটি মধ্যে আছে A
এবং B
সেই যাব A
এবং B
নিজেদের অপরিবর্তিত। এই জাতীয় বাক্য গঠনটি পার্স করা সত্যিই শক্ত, কারণ এটির জন্য একটি পূর্ণ-বিকাশযুক্ত ট্যুরিং মেশিন প্রয়োজন। এটি সম্পূর্ণ অন্য গল্প, তাই আমি এখানেই শেষ করব।