পার্সার ইনপুটটি স্পর্শ করার আগে সাধারণত পার্সারগুলি সাধারণত শেখানো হয় তাদের একটি লেজার স্টেজ থাকে। লেক্সার (এছাড়াও "স্ক্যানার" বা "টোকেনাইজার") ইনপুটটিকে ছোট টোকেনগুলিতে ছেঁকে দেয় যা কোনও প্রকারের সাথে টিকা দেওয়া থাকে। এটি প্রধান পার্সারকে প্রতিটি অক্ষরকে টার্মিনাল হিসাবে বিবেচনা করার পরিবর্তে টোকেনগুলি টার্মিনাল উপাদান হিসাবে ব্যবহার করতে দেয়, যা লক্ষণীয় দক্ষতা লাভের দিকে নিয়ে যায়। বিশেষত, লেক্সার সমস্ত মন্তব্য এবং সাদা স্থানও সরাতে পারে। তবে, একটি পৃথক টোকনাইজার পর্বের অর্থ হ'ল কীওয়ার্ডগুলি সনাক্তকারী হিসাবেও ব্যবহার করা যাবে না (যদি না ভাষা স্ট্রপিংকে সমর্থন করে যা কিছুটা অনুকূল হয়ে পড়েছে বা সিগিলের মতো সমস্ত সনাক্তকারীকে উপসর্গ না করে $foo
)।
কেন? ধরে নেওয়া যাক আমাদের কাছে একটি সাধারণ টোকেনাইজার রয়েছে যা নিম্নলিখিত টোকেনগুলি বোঝে:
FOR = 'for'
LPAREN = '('
RPAREN = ')'
IN = 'in'
IDENT = /\w+/
COLON = ':'
SEMICOLON = ';'
টোকেনাইজার সর্বদা দীর্ঘতম টোকেনের সাথে মিলবে এবং শনাক্তকারীদের চেয়ে কীওয়ার্ড পছন্দ করবে। সুতরাং interesting
হিসাবে lexed করা হবে IDENT:interesting
, কিন্তু in
যেমন হিসাবে IN
কখনও lexed হবে IDENT:interesting
। একটি কোড স্নিপেট মত
for(var in expression)
টোকেন প্রবাহে অনুবাদ করা হবে
FOR LPAREN IDENT:var IN IDENT:expression RPAREN
এখন পর্যন্ত, যে কাজ করে। তবে যে কোনও ভেরিয়েবলকে ভেরিয়েবলের পরিবর্তে in
মূলশব্দ হিসাবে লেক্স করা IN
হত যা কোডটি ভেঙে দেয়। লেক্সার টোকেনগুলির মধ্যে কোনও রাজ্য রাখে না এবং আমরা জানতে পারি না যে in
সাধারণত লুপের জন্য থাকা ছাড়া সাধারণত একটি পরিবর্তনশীল হওয়া উচিত। এছাড়াও, নিম্নলিখিত কোডটি আইনী হওয়া উচিত:
for(in in expression)
প্রথমটি in
একটি সনাক্তকারী হবে, দ্বিতীয়টি কীওয়ার্ড হবে।
এই সমস্যাটির জন্য দুটি প্রতিক্রিয়া রয়েছে:
প্রাসঙ্গিক কীওয়ার্ডগুলি বিভ্রান্তিকর, এর পরিবর্তে কীওয়ার্ডগুলি পুনরায় ব্যবহার করুন।
জাভাতে অনেকগুলি সংরক্ষিত শব্দ রয়েছে, যার মধ্যে কিছু প্রোগ্রামারদের সি ++ থেকে জাভাতে স্যুইচিংয়ে আরও সহায়ক ত্রুটি বার্তা সরবরাহ করা ছাড়া কোনও ব্যবহার নেই। নতুন কীওয়ার্ডগুলি কোড যুক্ত করে। প্রাসঙ্গিক কীওয়ার্ডগুলি যুক্ত করা কোডের পাঠকের কাছে বিভ্রান্তিকর কারণ যদি না তাদের ভাল বাক্য গঠন হাইলাইট করে এবং তা কার্যকরকরণ কার্যকর করে তোলে কারণ তাদের আরও উন্নত পার্সিং কৌশল ব্যবহার করতে হবে (নীচে দেখুন)।
আমরা যখন ভাষাটি প্রসারিত করতে চাই, তখন একমাত্র বুদ্ধিমান পন্থাটি হ'ল প্রতীকগুলি ব্যবহার করা যা ভাষা ভাষায় আগে আইনী ছিল না। বিশেষত, এগুলি সনাক্তকারী হতে পারে না। ফোরচ লুপ সিনট্যাক্সের সাহায্যে জাভা বিদ্যমান :
কীওয়ার্ডটিকে নতুন অর্থ সহ পুনরায় ব্যবহার করেছে । ল্যাম্বডাসের সাহায্যে জাভা একটি ->
কীওয়ার্ড যুক্ত করেছিল যা পূর্বে কোনও আইনী প্রোগ্রামে ঘটতে পারে না ( -->
এটি এখনও বৈধ হিসাবে প্রেরণ করা হবে '--' '>'
এবং এর ->
আগে যেমন লেক্স করা হয়েছিল '-', '>'
, তবে সেই ক্রমটি পার্সার দ্বারা প্রত্যাখ্যাত হবে)।
প্রাসঙ্গিক কীওয়ার্ডগুলি ভাষাগুলি সরল করে, আসুন সেগুলি বাস্তবায়ন করি
লেক্সারগুলি নির্বিচারে কার্যকর। তবে পার্সারের আগে কোনও লেসার চালানোর পরিবর্তে, আমরা সেগুলি পার্সারের সাহায্যে চালাতে পারি। নীচের অংশীদারগণ সর্বদা টোকেন ধরণের সেট জানেন যা কোনও নির্দিষ্ট স্থানে গ্রহণযোগ্য হবে। পার্সার তারপরে লেক্সারের কাছে বর্তমান অবস্থানে এই ধরণের যে কোনও একটির সাথে মিলে যাওয়ার অনুরোধ করতে পারে। প্রতিটি লুপে, পার্সারটি ·
ভেরিয়েবলটি সন্ধানের পরে (সরলীকৃত) ব্যাকরণ দ্বারা চিহ্নিত পজিশনে থাকবে :
for_loop = for_loop_cstyle | for_each_loop
for_loop_cstyle = 'for' '(' declaration · ';' expression ';' expression ')'
for_each_loop = 'for' '(' declaration · 'in' expression ')'
এই অবস্থানে, আইনী টোকেনগুলি হয় SEMICOLON
বা IN
না, তবে তা নয় IDENT
। একটি কীওয়ার্ডটি in
পুরোপুরি দ্ব্যর্থহীন।
এই নির্দিষ্ট উদাহরণে, উপরের ডাউন পার্সারগুলির কোনও সমস্যা নেই কারণ আমরা উপরের ব্যাকরণটি আবার লিখতে পারি
for_loop = 'for' '(' declaration · for_loop_rest ')'
for_loop_rest = · ';' expression ';' expression
for_loop_rest = · 'in' expression
এবং সিদ্ধান্তের জন্য প্রয়োজনীয় সমস্ত টোকেন ব্যাকট্র্যাকিং ছাড়াই দেখা যায়।
ব্যবহারযোগ্যতা বিবেচনা করুন
জাভা সর্বদা শব্দার্থক এবং সিনট্যাকটিক সরলতার দিকে ঝুঁকছে। উদাহরণস্বরূপ, ভাষা অপারেটর ওভারলোডিং সমর্থন করে না কারণ এটি কোডটিকে আরও জটিল করে তুলবে। সুতরাং প্রতিটি লুপ সিনট্যাক্সের মধ্যে in
এবং এর মধ্যে সিদ্ধান্ত নেওয়ার সময় :
, আমাদের বিবেচনা করতে হবে যেগুলি কম বিভ্রান্তিকর এবং ব্যবহারকারীদের কাছে আরও স্পষ্ট। চরম ঘটনা সম্ভবত হবে
for (in in in in())
for (in in : in())
(দ্রষ্টব্য: জাভা জন্য টাইপ নাম, ভেরিয়েবল, এবং পদ্ধতি পৃথক নামব্যবধান হয়েছে আমার মনে হয় বেশিরভাগ এই একটা ভুল ছিল, এই গড় পরে ভাষা নকশা যোগ করার জন্য হয়ে যায়।। আরো ভুল।)
কোন বিকল্পটি পুনরাবৃত্ত পরিবর্তনশীল এবং পুনরাবৃত্ত সংকলনের মধ্যে আরও স্পষ্টত ভিজ্যুয়াল বিভাজন সরবরাহ করে? আপনি কোডটির দিকে তাকালে কোন বিকল্পটি আরও দ্রুত স্বীকৃত হতে পারে? আমি খুঁজে পেয়েছি যে পৃথক চিহ্নগুলি শব্দের একটি স্ট্রিংয়ের চেয়ে ভাল যখন এটি এই মানদণ্ডে আসে। অন্যান্য ভাষার আলাদা আলাদা মান রয়েছে। উদাহরণস্বরূপ পাইথন ইংরেজিতে অনেক অপারেটরকে বানান করে যাতে তারা প্রাকৃতিকভাবে পড়তে পারে এবং সহজেই বুঝতে পারে তবে সেই একই বৈশিষ্ট্যগুলি এক নজরে পাইথনের টুকরোটি বোঝা বেশ কঠিন করে তুলতে পারে।