এটি একটি বড় বিষয় নয় বরং আপনাকে মুগ্ধ করে "ছোকরা পড়ুন একটি বই, বাচ্চা" দিয়ে মুছে ফেলার পরিবর্তে আমি আনন্দের সাথে আপনাকে আপনার মাথাটি মুড়ে দেওয়ার জন্য আপনাকে পয়েন্টার দেব।
বেশিরভাগ সংকলক এবং / অথবা দোভাষী এই জাতীয় কাজ করে:
টোকেনাইজ করুন : কোড পাঠ্যটি স্ক্যান করুন এবং এটিকে টোকেনের তালিকায় বিভক্ত করুন।
এই পদক্ষেপটি জটিল হতে পারে কারণ আপনি কেবল ফাঁকা জায়গাগুলিতে স্ট্রিংটি বিভক্ত করতে পারবেন না, আপনাকে if (bar) foo += "a string";
এটি 8 টি টোকেনের তালিকা: স্বীকৃতি দিতে হবে: WORD, OPEN_PAREN, WORD, CLOSE_PAREN, WORD, ASIGNMENT_ADD, STRING_LITERAL, TERMINATOR আপনি দেখতে পাচ্ছেন, খালি জায়গাগুলিতে সোর্স কোডটি বিভক্ত করা কার্যকর হবে না, আপনাকে প্রতিটি অক্ষরকে ক্রম হিসাবে পড়তে হবে, সুতরাং যদি আপনি কোনও বর্ণানুক্রমিক চরিত্রের মুখোমুখি হন তবে আপনি অক্ষরগুলি পড়া অবধি চালিয়ে যান যতক্ষণ না আপনি একটি অ্যালফানাম চরিত্র এবং সেই স্ট্রিংটিতে আঘাত না করেন শুধু পড়ার একটি ওয়ার্ড যা পরে আরও শ্রেণিবদ্ধ করা হয়। আপনার টোকেনাইজারটি কতটা দানাদার তা আপনি নিজেই স্থির করে নিতে পারেন: এটি "a string"
STRING_LITERAL নামক একটি টোকেন হিসাবে গিলে পরে আরও পার্স করার জন্য, বা এটি দেখে কিনা"a string"
ওপেন_কোটি, ইউএনপ্রেসডটেক্সট, ক্লোলোকোয়েট বা যাই হোক না কেন, কোডিং করার সাথে সাথে আপনার নিজের সিদ্ধান্ত নিতে পারা এটি কেবলমাত্র একটি পছন্দ।
লেক্স : সুতরাং এখন আপনার কাছে টোকেনের একটি তালিকা রয়েছে। আপনি সম্ভবত ওয়ার্ডের মতো অস্পষ্ট শ্রেণিবিন্যাসের সাথে কিছু টোকেন ট্যাগ করেছেন কারণ প্রথম পাসের সময় আপনি অক্ষরের প্রতিটি স্ট্রিংয়ের প্রেক্ষাপট বের করার চেষ্টা করে খুব বেশি প্রচেষ্টা ব্যয় করেন না। সুতরাং এখন আপনার উত্স টোকেনগুলির তালিকাটি আবার পড়ুন এবং আপনার ভাষার কীওয়ার্ডগুলির উপর ভিত্তি করে প্রতিটি অস্পষ্ট টোকেনকে আরও নির্দিষ্ট টোকেন টাইপের সাথে পুনরায় শ্রেণিবদ্ধ করুন। সুতরাং আপনার একটি ওয়ার্ড রয়েছে যেমন "যদি", এবং "যদি" আপনার বিশেষ কীওয়ার্ডের তালিকাতে যদি প্রতীক আইএফ বলে থাকে তবে আপনি সেই চিহ্নটির চিহ্নের চিহ্নটি WORD থেকে IF এ পরিবর্তন করতে পারেন, এবং কোনও বিশেষ ওয়ার্ড যা আপনার বিশেষ কীওয়ার্ড তালিকায় নেই? যেমন ওয়ার্ড ফু, একটি পরিচয়দাতা।
বিশ্লেষণ করুন : সুতরাং এখন আপনি if (bar) foo += "a string";
এমন লেক্সড টোকেনগুলির একটি তালিকা ঘুরিয়েছেন যা দেখতে এইরকম: যদি ওপেন_প্যারেন আইডেন্টিফার ক্লুলারপেন আইডেন্টিফায়ার এএসআইএন_এডিডি STRING_LITERAL টার্মিনেটর। পদক্ষেপটি টোকেনের ক্রমকে বিবৃতি হিসাবে স্বীকৃতি দিচ্ছে। এটি পার্সিং হয়। আপনি ব্যাকরণ ব্যবহার করে এটি করুন যেমন:
স্ট্যাটেন্ট: = এএসআইজিএন_এক্সপ্রেসন | IF_STATEMENT
আইএফপ্যাটেমেন্ট: = আইএফ, প্যারেন_এক্সপ্রেসন, স্ট্যাটামেন্ট
এএসআইজিএন_এক্সপ্রেসন: = আইডেন্টিফায়ার, এএসআইজিএন_ওপি, ভ্যালু
PAREN_EXPPressSION: = OPEN_PAREN, VALUE, CLOSE_PAREN
মান: = আইডেন্টিফায়ার | STRING_LITERAL | PAREN_EXPRESSION
ASIGN_OP: = EQUAL | এএসআইজিএন_এডিডি | ASIGN_SUBTRACT | ASIGN_MULT
যে প্রযোজনাগুলি "|" ব্যবহার করে শর্তগুলির মধ্যে অর্থ "এর সাথে কোনওটির সাথে মিলে যাওয়া", যদি এটির শর্তাবলীর মধ্যে কমা থাকে তবে এর অর্থ "শর্তগুলির এই ক্রমটি মেলান"
আপনি কিভাবে এটি ব্যবহার করব? প্রথম টোকেন দিয়ে শুরু করে, এই প্রযোজনাগুলির সাথে আপনার টোকেনগুলির ক্রমটি মিলানোর চেষ্টা করুন। সুতরাং প্রথমে আপনি আপনার টোকেন তালিকাকে স্ট্যাটামেন্টের সাথে মেলে দেখার চেষ্টা করুন, সুতরাং আপনি স্ট্যাটামেন্টের বিধিটি পড়েন এবং এটিতে বলা হয় "একটি স্ট্যাটামেন্ট হয় এএসআইজিএন_এক্সপ্রেসন বা একটি আইপিপ্যাটেমেন্ট" তাই আপনি প্রথমে এএসআইজিএন_এক্সপ্রেসনের সাথে মেলে যাবার চেষ্টা করুন, তাই আপনি এএসআইজিএন_এক্সপ্রেশনের ব্যাকরণের নিয়মটি সন্ধান করুন এবং এটিতে বলা হয়েছে "ASIGN_EXPPressION একটি IDENTIFIER এবং তারপরে একটি ASIGN_OP এর পরে একটি ভ্যালু হয়, সুতরাং আপনি আইডেন্টিফায়ারের জন্য ব্যাকরণের নিয়মটি দেখেছেন এবং দেখেন যে পরিচয়কারীর জন্য কোনও ব্যাকরণ রুক নেই তাই এর অর্থ পরিচয়দাতা একটি" টার্মিনাল "যার অর্থ এটি আর প্রয়োজন হয় না এটি মিলানোর জন্য পার্সিং করা যাতে আপনি এটি সরাসরি আপনার টোকেনের সাথে মেলে দেখার চেষ্টা করতে পারেন But তবে আপনার প্রথম উত্স টোকেনটি যদি একটি আইএফ হয়, এবং আইএফ আইডেন্টিফায়ার হিসাবে একই নয় তবে ম্যাচটি ব্যর্থ হয়েছিল। এখন কি? আপনি STATEMENT নিয়মে ফিরে যান এবং পরবর্তী শব্দটির সাথে মেলে দেখার চেষ্টা করুন: আইএফপ্যাটেমেন্ট। আপনি যদি আইএফপিএটিএমএনটি অনুসন্ধান করেন, এটি আইএফ দিয়ে শুরু হয়, যদি আইএফ-এর অনুসন্ধান শুরু হয়, আইএফ যদি একটি টার্মিনাল হয়, আপনার প্রথম টোকেনের সাথে টার্মিনালের তুলনা করুন, যদি টোকেন ম্যাচ করে, দুর্দান্ত চলছে, পরের শব্দটি PAREN_EXPressionION, অনুসন্ধানে পারেন_এক্সপ্রেসন, এটি টার্মিনাল নয়, এটি প্রথম পদটি কী, PAREN_EXPPressION OPEN_PAREN দিয়ে শুরু হয়, অনুসন্ধান OPEN_PAREN, এটি একটি টার্মিনাল, আপনার পরবর্তী টোকেনের সাথে OPEN_PAREN এর সাথে মেলে, এটি মিলছে, .... ইত্যাদি on
এই পদক্ষেপের কাছে যাওয়ার সহজতম উপায় হ'ল পার্স () নামক একটি ফাংশন যা আপনি এটি উত্স কোড টোকেনটি দিয়ে যাচ্ছেন যা আপনি মেলাতে চেষ্টা করছেন এবং সেই ব্যাকরণ শর্তটি যা আপনি এটির সাথে মেলানোর চেষ্টা করছেন। ব্যাকরণ পদটি যদি টার্মিনাল না হয় তবে আপনি পুনরাবৃত্তি করবেন: আপনি পার্সকে কল করুন () আবার এটি একই উত্স টোকন এবং এই ব্যাকরণের নিয়মের প্রথম শব্দটি পেরিয়ে যাচ্ছেন। এ কারণেই একে বলা হয় "রিকার্সিভ ডেসেন্ট পার্সার" পার্স () ফাংশন সোর্স টোকেনগুলি পড়ার ক্ষেত্রে আপনার বর্তমান অবস্থানটি ফিরিয়ে দেয় (বা সংশোধন করে), এটি মূলত মিলিত অনুক্রমের শেষ টোকেনটি ফেরত দেয় এবং আপনি পরবর্তী কলটি চালিয়ে যান পার্স () সেখান থেকে।
প্রতিবার পার্স () এএসআইজিএন_এক্সপ্রেসনের মতো একটি প্রোডাকশনের সাথে মেলে আপনি সেই কাঠামোর টুকরো উপস্থাপন করে একটি কাঠামো তৈরি করেন। এই কাঠামোটিতে মূল উত্স টোকেনগুলির উল্লেখ রয়েছে। আপনি এই কাঠামোর একটি তালিকা তৈরি শুরু করেন। আমরা এই পুরো কাঠামোটিকে বিমূর্ত সিনট্যাক্স ট্রি (এএসটি) বলব
সংকলন এবং / বা সম্পাদন করুন : আপনার ব্যাকরণে কিছু নির্দিষ্ট প্রোডাকশনের জন্য আপনি হ্যান্ডলার ফাংশন তৈরি করেছেন যে কোনও এএসটি কাঠামো দেওয়া হলে এটি এএসটির সেই অংশটিকে সংকলন বা সম্পাদন করে।
সুতরাং আসুন আপনার এএসটি-র অংশটি দেখুন যা এএসআইজিএন_এডিডি টাইপ করে। সুতরাং একজন দোভাষী হিসাবে আপনার কাছে একটি ASIGN_ADD_execute () ফাংশন রয়েছে। এই ফাংশনটি পার্স গাছের সাথে মিলে যায় এমন এএসটি অংশ হিসাবে পাস করা হয়েছে foo += "a string"
, সুতরাং এই ফাংশনটি সেই কাঠামোটির দিকে নজর দেয় এবং এটি জানে যে কাঠামোর প্রথম পদটি অবশ্যই একটি পরিচয়কারী হতে হবে, এবং দ্বিতীয় পদটি অবশ্যই ভ্যালু, সুতরাং ASIGN_ADD_execute () VALU পদটি একটি VALUE_eval () ফাংশনে পাস করে যা মেমরিতে মূল্যায়নকৃত মানকে উপস্থাপন করে এমন কোনও বস্তু ফেরত দেয়, তারপরে ASIGN_ADD_execute () আপনার ভেরিয়েবল সারণীতে "foo" এর অনুসন্ধান করে এবং eval_value () দ্বারা ফিরে আসা যা কিছু আছে তার একটি রেফারেন্স সঞ্চয় করে) ফাংশন।
এটি একটি দোভাষী। একটি সংকলক এর পরিবর্তে হ্যান্ডলার ফাংশনগুলি এএসটি কার্যকর করার পরিবর্তে বাইট কোড বা মেশিন কোডে অনুবাদ করে।
ফ্লেক্স এবং বাইসনের মতো সরঞ্জামগুলি ব্যবহার করে 1 থেকে 3 এবং কয়েকটি 4 টি পদক্ষেপ সহজ করা যায়। (যেমন। লেক্স এবং ইয়্যাক) তবে স্ক্র্যাচ থেকে নিজেকে একজন অনুবাদক লিখতে সম্ভবত কোনও প্রোগ্রামার অর্জন করতে পারে এমন সবচেয়ে শক্তিশালী অনুশীলন। অন্যান্য সমস্ত প্রোগ্রামিং চ্যালেঞ্জগুলি সামিট-টিংয়ের পরে এটি তুচ্ছ মনে হয়।
আমার পরামর্শটি ছোট থেকে শুরু করুন: একটি ক্ষুদ্র ব্যাকরণ সহ একটি ক্ষুদ্র ভাষা এবং কিছু সাধারণ বক্তব্যকে বিশ্লেষণ ও সম্পাদন করার চেষ্টা করুন, তারপরে সেখান থেকে বাড়ুন।
এগুলি পড়ুন, এবং শুভকামনা!
http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c
http://en.wikipedia.org/wiki/Recursive_descent_parser
lex
, সম্পর্কে তথ্য পেতে পারেন ।yacc
bison