কোনও সংকলক ঠিক কীভাবে টাইপ ত্রুটি থেকে পুনরুদ্ধার করে?


10

আমি বেশ কয়েকটি কাগজপত্র, নিবন্ধ এবং বিভাগ 4.1.4, সংকলকগুলির অধ্যায় 4 : নীতি, কৌশল এবং সরঞ্জাম (দ্বিতীয় সংস্করণ) (ওরফে "দ্য ড্রাগন বুক") পড়েছি যা সকলেই সিনট্যাক্টিকাল সংকলক ত্রুটি পুনরুদ্ধারের বিষয়ে আলোচনা করে। যাইহোক, বেশ কয়েকটি আধুনিক সংকলক নিয়ে পরীক্ষার পরে, আমি দেখেছি যে তারা শব্দার্থ ত্রুটিগুলি পাশাপাশি সিনট্যাকটিক ত্রুটিগুলি থেকেও পুনরুদ্ধার করে ।

আমি সংশ্লেষ সংক্রান্ত সম্পর্কিত ত্রুটিগুলি থেকে পুনরুদ্ধারকারী সংস্থাগুলির পিছনে অ্যালগরিদম এবং কৌশলগুলি বেশ ভালভাবে বুঝতে পারি, তবে আমি ঠিক বুঝতে পারি না যে সংকলক কীভাবে শব্দার্থত ত্রুটি থেকে পুনরুদ্ধার করতে পারে।

আমার বিমূর্ত সিনট্যাক্স ট্রি থেকে কোড উত্পন্ন করতে আমি বর্তমানে দর্শনার্থীর প্যাটার্নটির সামান্য প্রকরণ ব্যবহার করছি। নিম্নলিখিত সংক্ষেপগুলি সংকলন করে আমার সংকলকটি বিবেচনা করুন:

1 / (2 * (3 + "4"))

সংকলকটি নিম্নলিখিত বিমূর্ত সিনট্যাক্স ট্রি তৈরি করবে:

      op(/)
        |
     -------
    /       \ 
 int(1)    op(*)
             |
          -------
         /       \
       int(2)   op(+)
                  |
               -------
              /       \
           int(3)   str(4)

কোড-জেনারেশন পর্বটি তখন বিমূর্তভাবে বিমূর্ত সিনট্যাক্স ট্রিকে অবিচ্ছিন্নভাবে অনুসরণ করতে এবং ধরণের চেকিং করতে ভিজিটর প্যাটার্নটি ব্যবহার করবে। সংক্ষিপ্ত বিবরণটি আন্তঃব্যক্তির অন্তর্ভাগে না আসা পর্যন্ত বিমূর্ত সংশ্লেষ গাছটি অতিক্রম করা হবে; (3 + "4")। সংকলকটি তখন প্রকাশের প্রতিটি দিক যাচাই করে এবং দেখে যে তারা শব্দার্থগতভাবে সমতুল্য নয়। সংকলক একটি প্রকার ত্রুটি উত্থাপন করে। সমস্যাটি এখানেই রয়েছে। সংকলক এখন কি করা উচিত ?

সংকলকটি এই ত্রুটিটি থেকে পুনরুদ্ধার করতে এবং এক্সপ্রেশনগুলির বাইরের অংশগুলি পরীক্ষা করে চালিয়ে যাওয়ার জন্য, এটি কোনও প্রকারের ( intবা str) এক্সপ্রেশনটির অন্তঃস্থ অংশটি মূল্যায়ন থেকে ভাবের পরবর্তী অন্তঃস্থ অংশে ফিরে আসতে হবে । তবে এটির ফিরে আসার মতো কোনও প্রকার নেই । যেহেতু কোনও ধরণের ত্রুটি ঘটেছে তাই কোনও প্রকারকে ছাড় দেওয়া হয়নি।

একটি সম্ভাব্য সমাধান যা আমি পোস্ট করেছি, তা হ'ল যদি কোনও ধরণের ত্রুটি ঘটে থাকে তবে একটি ত্রুটি উত্থাপন করা উচিত এবং একটি বিশেষ মান যা ধরণের ত্রুটি ঘটেছে তা বোঝায়, পূর্ববর্তী বিমূর্ত সিনট্যাক্স ট্রি ট্রভার্সাল কলগুলিতে ফিরে আসা উচিত। যদি পূর্ববর্তী ট্র্যাভারসাল কলগুলির এই মানটির মুখোমুখি হয় তবে তারা জানে যে বিমূর্ত সিনট্যাক্স গাছের গভীরে একটি প্রকার ত্রুটি ঘটেছে এবং কোনও প্রকারকে ছাড়ানোর চেষ্টা করা এড়ানো উচিত। যদিও এই পদ্ধতিটি কাজ করছে বলে মনে হচ্ছে এটি খুব অকার্যকর বলে মনে হচ্ছে। যদি কোনও অভিব্যক্তির অন্তর্নিহিত অংশটি বিমূর্ত সিনট্যাক্স গাছের গভীরে থাকে, তবে সংকলককে অনেকগুলি পুনরাবৃত্ত কল করতে হবে কেবল এটি উপলব্ধি করতে যে কোনও আসল কাজ করা সম্ভব নয় এবং কেবল প্রতিটি থেকে ফিরে আসা উচিত।

আমি উপরে বর্ণিত পদ্ধতিটি কি ব্যবহৃত (আমি সন্দেহ করি)। যদি তাই হয়, এটি কার্যকর না? যদি তা না হয়, কম্পাইলাররা শব্দার্থক ত্রুটিগুলি থেকে পুনরুদ্ধার করার সময় ঠিক কী কী পদ্ধতি ব্যবহার করা হয়?


3
খুব নিশ্চিত যে এটি ব্যবহৃত হয়, এবং আপনি কেন এটি যথেষ্ট দক্ষ বলে মনে করেন না? প্রকারের চেকিং করতে, সংকলকটিকে যাইহোক পুরো গাছটি হাঁটতে হবে । একটি ত্রুটি সন্ধানের পরে সংকলকটি একটি শাখা মুছে ফেলতে দেয় বলে একটি শব্দার্থিক ব্যর্থতা আরও কার্যকর।
তেলস্তিন

উত্তর:


8

আপনার প্রস্তাবিত ধারণাটি মূলত সঠিক।

মূলটি হ'ল এএসটি নোডের ধরণটি একবারেই গণনা করা হয় এবং তারপরে সংরক্ষণ করা হয়। যখনই আবার টাইপের প্রয়োজন হয়, এটি কেবল সঞ্চিত প্রকারটি পুনরুদ্ধার করে। রেজোলিউশনটি যদি কোনও ত্রুটিতে শেষ হয় তবে পরিবর্তে একটি ত্রুটি প্রকার সংরক্ষণ করা হবে।


3

একটি আকর্ষণীয় পদ্ধতির ত্রুটির জন্য একটি বিশেষ ধরণের থাকা। যখন এই জাতীয় ত্রুটিটি প্রথম সম্মুখীন হয়, তখন ডায়াগোনস্টিক লগ হয় এবং ত্রুটির ধরণটি এক্সপ্রেশনটির ধরণ হিসাবে ফিরে আসে। এই ত্রুটি ধরণের কিছু আকর্ষণীয় বৈশিষ্ট্য রয়েছে:

  • এতে করা যে কোনও অপারেশন সফল হয় (একই মূল ত্রুটির কারণে ত্রুটি বার্তাগুলির ক্যাসকেড প্রতিরোধের জন্য)
  • ত্রুটি প্রকারের সাথে কোনও বস্তুর উপর সঞ্চালিত যে কোনও ক্রিয়াকলাপের ফলাফলেরও ত্রুটি টাইপ থাকে
  • যদি কোনও ত্রুটি ধরণের কোড উত্পন্ন হয় তবে কোড জেনারেটর স্পটটি ব্যবহার করে এবং ব্যর্থ হয় এমন কোড জেনারেট করে (যেমন একটি ব্যতিক্রম ছুঁড়ে ফেলে, বিসর্জন দেয় বা আপনার ভাষার জন্য উপযুক্ত যা কিছু)

এই সংমিশ্রণের মাধ্যমে, আপনি আসলে সফলভাবে কোডটি সংকলন করতে পারেন যাতে টাইপ ত্রুটি রয়েছে এবং যতক্ষণ না সেই কোডটি আসলে ব্যবহার না করা হয় কোনও রানটাইম ত্রুটি ঘটবে না। এটি কার্যকর হতে পারে, উদাহরণস্বরূপ, আপনাকে কোডটির কিছু অংশের জন্য ইউনিট পরীক্ষা চালানোর অনুমতি দেবে যা প্রভাবহীন।


জুলস উত্তরটির জন্য ধন্যবাদ। যথেষ্ট মজাদার, এটি হ'ল পদ্ধতিটি আমি ব্যবহার করে শেষ করেছি। মহান মন একসাথে ভাবেন, তাই না? ;-)
খ্রিস্টান ডিন

2

যদি কোনও শব্দার্থত ত্রুটি থাকে, তবে একটি সংকলিত ত্রুটি বার্তাটি ব্যবহারকারীকে জারি করা হয়।

এটি হয়ে গেলে, ইনপুট প্রোগ্রামটি ত্রুটিযুক্ত হওয়ায় সংকলন বাতিল করা ঠিক আছে - এটি ভাষায় কোনও আইনী প্রোগ্রাম নয়, তাই এটি সহজভাবে প্রত্যাখ্যান করা যায়।

এটি বেশ কঠোর, যদিও, আরও নরম বিকল্প রয়েছে। যে কোনও কোড জেনারেশন এবং আউটপুট ফাইল জেনারেশন বাতিল করুন, তবু আরও ত্রুটি দেখার জন্য কিছু চালিয়ে যান।

উদাহরণস্বরূপ, এটি কেবলমাত্র বর্তমান অভিব্যক্তি গাছের জন্য আরও কোনও ধরণের বিশ্লেষণ বাতিল করতে পারে এবং পরবর্তী বিবৃতিগুলি থেকে অভিব্যক্তি প্রক্রিয়াকরণ চালিয়ে যেতে পারে।


2

আসুন ধরে নেওয়া যাক আপনার ভাষাটি পূর্ণসংখ্যার যোগ করার অনুমতি দেয় এবং +অপারেটরের সাথে স্ট্রিংগুলি যোগ করার অনুমতি দেয় allows

যেহেতু int + stringঅনুমোদিত নয়, উইলের মূল্যায়ন করার +ফলে একটি ত্রুটি প্রতিবেদন করা হবে। সংকলকটি কেবল টাইপ হিসাবে ফিরে আসতে পারেerror । অথবা এটি আরও চালাক হতে পারে, যেহেতু int + int -> intএবং string + string -> stringঅনুমোদিত, এটি "ত্রুটি, ইনট বা স্ট্রিং হতে পারে" ফিরে আসতে পারে।

তারপরে *অপারেটরটি আসে এবং আমরা ধরে নিই যে কেবল int + intএটি অনুমোদিত। কম্পাইলার তারপর সিদ্ধান্ত নিতে পারে যে +আসলে ফিরে যাওয়ার কথা ছিল int, এবং টাইপ জন্য ফিরে *তারপর হবে intকোনো ত্রুটি বার্তা ছাড়া।


আমি মনে করি আমি @ অনুসরণকারীকে অনুসরণ করছি, তবে "" অপারেটর বলতে আপনার অর্থ কী ? টাইপ ছিল?
খ্রিস্টান ডিন

@ ক্রিশ্চিয়ানডিয়ান-এর উদ্ধৃতিগুলিতে একটি নক্ষত্র রয়েছে যা রেন্ডার পরিবর্তে মার্কডাউন মার্কআপ হিসাবে ব্যাখ্যা করা হচ্ছে।
জ্যাকরব 4

আমি উত্তরে একটি সম্পাদনা জমা দিয়েছি যা আমার সম্পাদনাটি পিয়ার পর্যালোচনা হওয়ার সাথে সাথেই সমস্যার সমাধান করবে।
জেকরব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.