আমার কি পার্সার জেনারেটর ব্যবহার করা উচিত বা আমার নিজের কাস্টম লেক্সার এবং পার্সার কোডটি রোল করা উচিত?


81

প্রোগ্রামিং ভাষার ব্যাকরণে কাজ করার প্রতিটি উপায়ে কোন নির্দিষ্ট সুবিধা এবং অসুবিধাগুলি?

কেন / কখন আমার নিজের রোল করব? কেন / কখন আমি একটি জেনারেটর ব্যবহার করব?


দিন Boost.Spirit Qi থেকে একটি শট।
ইব্রাহিম মোহাম্মদী

উত্তর:


78

সত্যিই তিনটি বিকল্প রয়েছে, তিনটিই বিভিন্ন পরিস্থিতিতে ভাল fe

বিকল্প 1: পার্সার জেনারেটর, বা 'আপনাকে কিছু ভাষার বিশ্লেষণ করতে হবে এবং আপনি কেবল এটির কাজ করতে চান

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

এই ক্ষেত্রে, আপনি সম্ভবত পার্সার জেনারেটর ব্যবহার করে সেরা। আপনাকে বিশদটি নিয়ে ঘুরতে হবে না, সঠিকভাবে কাজ করার জন্য আপনাকে প্রচুর জটিল কোড পেতে হবে না, আপনি কেবল ব্যাকরণটি লিখুন ইনপুটটি মেনে চলবে, কিছু হ্যান্ডলিং কোড এবং প্রেস্টো লিখুন: তাত্ক্ষণিক পার্সার।

সুবিধাগুলি পরিষ্কার:

  • একটি স্পেসিফিকেশন লিখতে এটি (সাধারণত) বেশ সহজ, বিশেষত যদি ইনপুট ফর্ম্যাটটি খুব অদ্ভুত না হয় (বিকল্প 2 এটির চেয়ে ভাল হবে)।
  • আপনি সহজেই বোঝা যায় এমন একটি খুব সহজেই রক্ষণাবেক্ষণের কাজটি শেষ করেছেন: ব্যাকরণের সংজ্ঞা সাধারণত কোডের চেয়ে অনেক বেশি প্রাকৃতিক প্রবাহিত হয়।
  • ভাল পার্সার জেনারেটর দ্বারা উত্পাদিত পার্সারগুলি সাধারণত হাতে লিখিত কোডের চেয়ে অনেক দ্রুত faster হাতে লেখা কোড পারবেন দ্রুততর হবে, কিন্তু আপনি আপনার জিনিস জানেন শুধুমাত্র যদি - এই কারণেই বহুল ব্যবহৃত কম্পাইলার একটি হাতে লেখা রিকার্সিভ-বংশদ্ভুত পার্সার ব্যবহার করুন।

পার্সার-জেনারেটরগুলির সাথে আপনার যত্ন নিতে হবে এমন একটি জিনিস: কখনও কখনও আপনার ব্যাকরণকে প্রত্যাখ্যান করতে পারে। বিভিন্ন ধরণের পার্সার এবং কীভাবে তারা আপনাকে কামড়াতে পারে তার সংক্ষিপ্তসার জন্য, আপনি এখানে শুরু করতে চাইতে পারেন । এখানে আপনি প্রচুর বাস্তবায়ন এবং তারা গ্রহণযোগ্য ব্যাকরণগুলির ধরণের একটি ওভারভিউ খুঁজে পেতে পারেন।

বিকল্প 2: হাতে লিখিত পার্সার্স, বা 'আপনি নিজের পার্সার তৈরি করতে চান, এবং আপনি ব্যবহারকারী-বান্ধব হওয়া সম্পর্কে যত্নবান হন'

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

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

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

শিক্ষা-ভিত্তিক, নিজের পার্সার লিখতে জেনারেটর ব্যবহারের চেয়ে আপনাকে আরও বেশি শিখিয়ে দেবে। আপনাকে সর্বোপরি আরও জটিল কোড লিখতে হবে, এবং ঠিক কীভাবে আপনি কোনও ভাষার বিশ্লেষণ করবেন তা বুঝতে হবে। অন্যদিকে, আপনি যদি নিজের ভাষা তৈরি করতে শিখতে চান (সুতরাং ভাষা নকশায় অভিজ্ঞতা অর্জন করুন), বিকল্প 1 বা বিকল্প 3 পছন্দনীয়: আপনি যদি কোনও ভাষা বিকাশ করছেন তবে এটি সম্ভবত অনেক কিছু পরিবর্তন করবে, এবং বিকল্প 1 এবং 3 আপনাকে এটির সাথে একটি সহজ সময় দেয়।

বিকল্প 3: হাতে লিখিত পার্সার জেনারেটর, বা 'আপনি এই প্রকল্পটি থেকে অনেক কিছু শেখার চেষ্টা করছেন এবং আপনি নিফটি কোডের সমাপ্তি বোধ করবেন না আপনি অনেকগুলি পুনরায় ব্যবহার করতে পারেন'

এই পথে আমি বর্তমানে হাঁটছি: আপনি নিজের পার্সার জেনারেটরটি লিখেন । অত্যন্ত অনানুষ্ঠানিক অবস্থায়, এটি করা সম্ভবত আপনাকে সবচেয়ে বেশি শিখিয়ে দেবে।

এরকম একটি প্রকল্প কী করা জড়িত তা আপনাকে ধারণা দেওয়ার জন্য আমি আপনাকে আমার নিজের অগ্রগতি সম্পর্কে বলব।

লেক্সার জেনারেটর

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

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    { // This is just like a lex specification:
      //                    regex   token
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

foreach (CalculatorToken token in
             calculatorLexer.GetLexer(new StringReader("15+4*10")))
{ // This will iterate over all tokens in the string.
    Console.WriteLine(token.Value);
}

// Prints:
// 15
// +
// 4
// *
// 10

ইনপুট স্ট্রিং-টোকেন জোড়গুলি একটি গণিত স্ট্যাকের ধারণাগুলি ব্যবহার করে প্রতিনিধিত্ব করে এমন নিয়মিত অভিব্যক্তিগুলি বর্ণনা করে একটি সম্পর্কিত পুনরাবৃত্ত কাঠামোতে রূপান্তরিত হয়। এরপরে এটি এনএফএ (ননডিটারিস্টিনিস্টিক সসীম অটোমেটন) এ রূপান্তরিত হয়, যা ঘুরে ফিরে ডিএফএ (ডিটারিনিস্টিক সসীম অটোমেটন) এ রূপান্তরিত হয়। তারপরে আপনি ডিএফএর সাথে স্ট্রিংগুলি মিলিয়ে নিতে পারেন।

এইভাবে, আপনি ঠিকঠাক লেশাররা কীভাবে কাজ করে তা আপনি একটি ভাল ধারণা পাবেন। এছাড়াও, আপনি যদি সঠিকভাবে এটি করেন তবে আপনার লেক্সার জেনারেটরের ফলাফল পেশাদার বাস্তবায়ন হিসাবে প্রায় দ্রুত হতে পারে। বিকল্প 2 এর তুলনায় আপনি কোনও অভিব্যক্তি হারাবেন না, এবং বিকল্প 1 এর তুলনায় খুব বেশি ভাব প্রকাশ করবেন না।

আমি আমার লেক্সার জেনারেটরটি কোডের 1600 লাইনের বেশি প্রয়োগ করেছি। এই কোডটি উপরের কাজটি করে, তবে আপনি যখনই প্রোগ্রামটি শুরু করবেন তখনও এটি ফ্লাইটিতে লেক্সার তৈরি করে: আমি কোনও সময়ে ডিস্কে এটি লিখতে কোড যুক্ত করতে যাচ্ছি।

আপনাকে জানতে হবে কিভাবে আপনার নিজের lexer লিখতে চান, এই একটি ভাল জায়গা শুরু হয়।

পার্সার জেনারেটর

তারপরে আপনি নিজের পার্সার জেনারেটর লিখুন। বিভিন্ন ধরণের পার্সার সম্পর্কিত পর্যালোচনা করার জন্য আমি এখানে আবার উল্লেখ করি - থাম্বের নিয়ম হিসাবে, তারা যত বেশি পার্স করতে পারবেন তত ধীর।

গতি আমার পক্ষে সমস্যা নয়, আমি একটি আর্লি পার্সার প্রয়োগ করতে বেছে নিয়েছি। একটি আর্লি পার্সারের উন্নত বাস্তবায়ন অন্যান্য পার্সার প্রকারের থেকে দ্বিগুণ ধীর দেখানো হয়েছে

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

আমার পার্সার জেনারেটর ব্যবহার করে কোনও কোডের টুকরো দেখতে দেখতে এটি দেখতে পাওয়া যায়:

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    {
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

Grammar<IntWrapper, CalculatorToken> calculator
    = new Grammar<IntWrapper, CalculatorToken>(calculatorLexer);

// Declaring the nonterminals.
INonTerminal<IntWrapper> expr = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> term = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> factor = calculator.AddNonTerminal<IntWrapper>();

// expr will be our head nonterminal.
calculator.SetAsMainNonTerminal(expr);

// expr: term | expr Plus term;
calculator.AddProduction(expr, term.GetDefault());
calculator.AddProduction(expr,
                         expr.GetDefault(),
                         CalculatorToken.Plus.GetDefault(),
                         term.AddCode(
                         (x, r) => { x.Result.Value += r.Value; return x; }
                         ));

// term: factor | term Times factor;
calculator.AddProduction(term, factor.GetDefault());
calculator.AddProduction(term,
                         term.GetDefault(),
                         CalculatorToken.Times.GetDefault(),
                         factor.AddCode
                         (
                         (x, r) => { x.Result.Value *= r.Value; return x; }
                         ));

// factor: LeftParenthesis expr RightParenthesis
//         | Number;
calculator.AddProduction(factor,
                         CalculatorToken.LeftParenthesis.GetDefault(),
                         expr.GetDefault(),
                         CalculatorToken.RightParenthesis.GetDefault());
calculator.AddProduction(factor,
                         CalculatorToken.Number.AddCode
                         (
                         (x, s) => { x.Result = new IntWrapper(int.Parse(s));
                                     return x; }
                         ));

IntWrapper result = calculator.Parse("15+4*10");
// result == 55

(দ্রষ্টব্য যে IntWrapper কেবল একটি অন্তর্গত 32, সি ব্যতীত এটির একটি শ্রেণি হওয়া প্রয়োজন, অতএব আমাকে একটি র‌্যাপার শ্রেণি প্রবর্তন করতে হয়েছিল)

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


3
আমি মনে করি আপনি উচ্চ পারফরম্যান্স পার্সার এবং লেক্সার তৈরি করতে যে পরিমাণ কাজের প্রয়োজন তা হ্রাস করেন না।

আমি ইতিমধ্যে আমার নিজস্ব লেক্সার জেনারেটর তৈরি শেষ করেছি এবং আমি তার পরিবর্তে অন্য অ্যালগরিদম বাস্তবায়নের সিদ্ধান্ত নেওয়ার সময় আমার নিজের পার্সার জেনারেটর তৈরির পাশাপাশি ছিলাম far এটি সব কাজ করতে আমার এত বেশি সময় লাগেনি, তবে তারপরেও আমি 'উচ্চ পারফরম্যান্স', কেবল 'ভাল পারফরম্যান্স' এবং 'দুর্দান্ত অ্যাসেম্পটোটিক পারফরম্যান্স'-এর লক্ষ্য রাখি নি - ইউনিকোডের জন্য চলমান সময়গুলি বেশ ভালই পাওয়া যায় এবং সি # ব্যবহার করা ইতিমধ্যে একটি কর্মক্ষমতা ওভারহেড চাপিয়ে দেয়।
অ্যালেক্স দশ ব্রিংক

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

1
এখানে একটি চতুর্থ বিকল্প রয়েছে: পার্সার সংযুক্তকারীগুলি।
ইউরিআলবুউয়ের্কি

@ অ্যালেক্সটেনব্রিংক আপনার কি কোনও সুযোগেই গিথুব অ্যাকাউন্ট আছে? আমি সত্যিই সেই লেজার / পার্সারে হাত পেতে চাই। চিত্তাকর্ষক জিনিস আপনি করেছেন।
বেহরোজ

22

আপনি যদি কখনও না থাকেন তবে কখনও কোনও পার্সার লিখেছেন আমি আপনাকে এটি করার পরামর্শ দিচ্ছি। এটি মজাদার এবং আপনি কীভাবে জিনিসগুলি কাজ করে তা শিখেন এবং পরের বারের জন্য পার্সার লাগানোর পরে পার্সার এবং লেক্সার জেনারেটররা আপনাকে যে প্রচেষ্টা থেকে বাঁচায় তা আপনি প্রশংসা করতে শিখেন ।

আমি আপনাকেও পরামর্শ দিচ্ছি যে আপনি http://compilers.iecc.com/crenshaw/ পড়ার চেষ্টা করুন কেননা এটি কীভাবে করবেন তার প্রতি পৃথিবীতে খুব নিচু মনোভাব রয়েছে।


2
ভাল পরামর্শ এবং একটি খুব দরকারী লিঙ্ক।
ম্যানেরিও

14

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

আপনার নিজের লেখার আরেকটি সুবিধা হ'ল আপনার ব্যাকরণের সাথে একটির সাথে একটি করে চিঠিপত্র না থাকার একটি সহজ উপস্থাপনায় পার্স করা আরও সহজ।

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

বজর্ন স্ট্রাস্ট্রাপ সি -++ এর প্রথম প্রয়োগের জন্য কীভাবে ওয়াইএসিসি ব্যবহার করেছিলেন (সি ++ এর ডিজাইন এবং বিবর্তন দেখুন ) সে সম্পর্কে আলোচনা করে । সেই প্রথম ক্ষেত্রে, তিনি ইচ্ছা করেছিলেন তিনি পরিবর্তে তাঁর নিজের পুনরাবৃত্ত বংশদ্ভুত পার্সার লিখেছেন!


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

++ এই উত্তরটি আমি যা বলি ঠিক তাই। আমি অসংখ্য ভাষা তৈরি করেছি এবং প্রায়শই পুনরাবৃত্ত উত্স ব্যবহার করেছি। আমি কেবল যুক্ত করব যে এমন সময়ও ছিল যখন আমার প্রয়োজনের ভাষাটি সি বা সি ++ (বা লিস্প) এর উপরে কিছু ম্যাক্রোগুলি রেখে খুব সহজভাবে নির্মিত হয়েছিল।
মাইক ডুনলাভে

জাভাসিসির কাছে সেরা ত্রুটির বার্তা রয়েছে বলে দাবি করা হচ্ছে। এছাড়াও, ভি 8 এবং ফায়ারফক্সে জাভাস্ক্রিপ্ট ত্রুটি এবং সতর্কতা বার্তা লক্ষ্য করুন, আমি মনে করি তারা কোনও পার্সার জেনারেটর ব্যবহার করেনি।
মিং-টাং

2
@ শিনকিরোউ: প্রকৃতপক্ষে, এটি সম্ভবত কোনও দুর্ঘটনা নয় যা জাভাসিসি পুনরাবৃত্ত বংশোদ্ভূত পার্সিং ব্যবহার করে।
ম্যাকনিল

10

বিকল্প 3: না হয় (আপনার নিজের পার্সার জেনারেটর রোল)

একটি কারণ ব্যবহার না করার এর ঠিক কারণ ANTLR , বাইসন , কোকো / r , Grammatica , JavaCC , লেবু , ডাঁট , SableCC , Quex , ইত্যাদি - যে মানে এই নয় আপনি অবিলম্বে আপনার নিজের পার্সার + + lexer রোল করা উচিত নয়।

এই সমস্ত সরঞ্জামগুলি কেন পর্যাপ্ত নয় - তা সনাক্ত করুন কেন তারা আপনাকে আপনার লক্ষ্য অর্জন করতে দেয় না?

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


1
আমি প্রথমে পার্সার জেনারেটরগুলির সাথে একমত এবং তারপরে একটি কাস্টম সমাধান চেষ্টা করি, তবে নির্দিষ্ট (ডিস) সুবিধাগুলি কী? এটি প্রায় একটি সাধারণ পরামর্শ।
ম্যানেরিও

1
এটি সাধারণ পরামর্শ - তবে তারপরে আপনি একটি সাধারণ প্রশ্ন জিজ্ঞাসা করেছিলেন। : পি আমি কাল এটির পক্ষে ভাল এবং কনস সম্পর্কে আরও কিছু সুনির্দিষ্ট চিন্তাভাবনা নিয়ে প্রসারিত করব।
পিটার বুটন

1
আমি মনে করি আপনি একটি কাস্টম পার্সার এবং লেক্সার তৈরি করতে প্রয়োজনীয় পরিমাণের পরিমাণটিকে অবমূল্যায়ন করেন। বিশেষ করে একটি পুনরায় ব্যবহারযোগ্য

8

আপনার নিজের পার্সার ঘূর্ণায়মান আপনাকে আপনার ভাষার জটিলতা সম্পর্কে সরাসরি চিন্তা করতে বাধ্য করে। যদি ভাষাটি বিশ্লেষণ করা শক্ত হয় তবে এটি সম্ভবত বোঝা শক্ত হতে চলেছে।

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

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

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


এটি একটি কাস্টম সমাধান রোল করার জন্য একটি আকর্ষণীয় যুক্তি।
ম্যানেরিও

1
খুব সুন্দর. আমি কেবল তথ্যের একটি বিষয় হিসাবে যুক্ত করব যে জোরভালের আগে ফোর্টরানকে জিনিসগুলি বিশ্লেষণের জন্য প্রায় স্বেচ্ছাসেবী (সম্পূর্ণ লাইন) চেহারা প্রয়োজন ছিল। তবে সেই সময় কীভাবে কোনও ভাষা তৈরি করবেন (বা প্রয়োগ করবেন) তাদের কোনও ধারণা ছিল না।
ম্যাকনিল

হাঁটা যাতায়াতের সর্বোত্তম মাধ্যম কারণ এটি আপনাকে ভাবতে সময় দেয় যে আপনি কোথায় যাচ্ছেন তা সত্যই মূল্যবান কিনা is এটি স্বাস্থ্যকরও।
বাবু

6

আমি একবার বাণিজ্যিক প্রয়োগের জন্য একটি পার্সার লিখেছি এবং আমি ইয়্যাক ব্যবহার করেছি । একটি প্রতিযোগিতামূলক প্রোটোটাইপ ছিল যেখানে একজন বিকাশকারী পুরো হাতে হাত দিয়ে সি ++ এ লিখেছিলেন এবং এটি প্রায় পাঁচগুণ ধীর কাজ করেছিল।

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

আমি কেন লেক্ষারটি হাতে লিখেছিলাম তার কারণ ছিল পার্সারের ইনপুট ব্যাকরণ। এটি একটি প্রয়োজনীয়তা ছিল, আমার পার্সার বাস্তবায়নের কিছু মেনে চলতে হয়েছিল, আমি ডিজাইন করা কিছুটির বিপরীতে। (অবশ্যই আমি এটি অন্যরকমভাবে ডিজাইন করতাম And এবং আরও ভাল!) ব্যাকরণটি মারাত্মকভাবে প্রাসঙ্গিক-নির্ভর এবং এমনকি কিছু জায়গায় শব্দার্থবিজ্ঞানের উপরও নির্ভরশীল ছিল depend উদাহরণস্বরূপ সেমিকোলন এক জায়গায় টোকেনের অংশ হতে পারে তবে আলাদা জায়গায় পৃথককারী - কিছু উপাদানগুলির পূর্বে বিশ্লেষণকারী শব্দার্থগত ব্যাখ্যাের ভিত্তিতে। সুতরাং, আমি হাতে লিখিত লেক্সারের মধ্যে এরকম শব্দার্থগত নির্ভরতা "সমাহিত" করেছি এবং এটি আমাকে পুরোপুরি সোজা বিএনএফ দিয়ে রেখেছিল যা ইয়্যাকটিতে প্রয়োগ করা সহজ ছিল।

সংযোজন প্রতিক্রিয়ায় MacNeil : yacc একটি খুব শক্তিশালী বিমূর্ততা প্রোগ্রামার দেয় উপলব্ধ টার্মিনাল, অ-টার্মিনাল, প্রযোজনার এবং স্টাফ যে মত পরিপ্রেক্ষিতে মনে করি। এছাড়াও, yylex()ফাংশন বাস্তবায়ন করার সময় , এটি আমাকে বর্তমান টোকেনটি ফিরিয়ে দেওয়ার দিকে মনোনিবেশ করতে এবং এর আগে বা পরে কী ছিল তা নিয়ে চিন্তিত হতে সহায়তা করেছিল। সি ++ প্রোগ্রামার চরিত্রের স্তরে কাজ করেছিল, এ জাতীয় বিমূর্ততার সুবিধা ছাড়াই এবং আরও জটিল এবং কম দক্ষ অ্যালগরিদম তৈরিতে শেষ হয়েছিল। আমরা উপসংহারে পৌঁছেছি যে ধীর গতির নিজের সাথে সি ++ বা কোনও লাইব্রেরি নেই। আমরা মেমরিতে লোড হওয়া ফাইলগুলির সাথে খাঁটি পার্সিংয়ের গতি পরিমাপ করেছি; আমাদের যদি কোনও ফাইল বাফারিং সমস্যা হয় তবে ইয়্যাক এটি সমাধান করার জন্য আমাদের পছন্দসই সরঞ্জাম না হত।

এছাড়াও যোগ করতে চান : এটি সাধারণত পার্সার লেখার কোনও রেসিপি নয়, এটি একটি নির্দিষ্ট পরিস্থিতিতে কীভাবে কাজ করেছে তার একটি উদাহরণ।


আমি হাতে পাঁচবার ধীর সি ++ বাস্তবায়ন সম্পর্কে কৌতূহল করছি: সম্ভবত এটি ফাইল ফাইলটি খারাপ ছিল? এটি একটি বড় পার্থক্য করতে পারে।
ম্যাকনিল

@ ম্যাকনিল: আমি আমার উত্তরের সাথে একটি পোস্ট পোস্ট করতে যাচ্ছি; মন্তব্যটি খুব দীর্ঘ।
আজহেগ্লোভ

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

3

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

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

তবে, আমি লেসসারদের সম্পর্কে মোটেও আগ্রহী নই, যখন আমার কোনও ব্যবহারের প্রয়োজন হয় (তাই, লেবু) them আপনি হতে পারেন, এবং যদি তাই হয়, কেন একটি না? আমার অনুভূতি আছে যে আপনি উপস্থিত থাকা ব্যবহার করে ফিরে আসবেন, তবে চুলকানি স্ক্র্যাচ করুন যদি আপনার অবশ্যই হয় :)


3
"1 আপনি কীভাবে কোনও লেসারের শেখার বক্ররেখার আঘাত করতে পারেন তার চেয়ে দ্রুত আপনার নিজের রোল করতে পারেন?"
বোবাহ

হ্যাঁ, ভাল পয়েন্ট।
ম্যানেরিও

3

এটি আপনার লক্ষ্য কী তার উপর নির্ভর করে।

আপনি কীভাবে পার্সার / সংকলক কাজ করেন তা জানার চেষ্টা করছেন? তারপরে স্ক্র্যাচ থেকে আপনার নিজের লিখুন। তারা যা করছে তার সমস্ত ইনস এবং আউটসকে প্রশংসা করতে আপনি সত্যিই শিখতে পারবেন এমন একমাত্র উপায়। আমি গত কয়েক মাস ধরে একটি লিখেছিলাম, এবং এটি একটি আকর্ষণীয় এবং মূল্যবান অভিজ্ঞতা হয়েছে, এস্কেপালি বিশেষভাবে 'আহা, সুতরাং ভাষা এক্স এটি কেন করে ...' মুহুর্তগুলি ts

একটি সময়সীমার জন্য কোনও অ্যাপ্লিকেশনের জন্য আপনার কী কী দ্রুত একসাথে রাখা দরকার? তারপরে সম্ভবত পার্সার সরঞ্জামটি ব্যবহার করুন।

আপনার কি এমন কিছু দরকার যা আপনি পরবর্তী 10, 20, এমনকি 30 বছর ধরে প্রসারিত করতে চান? আপনার নিজের লিখুন, এবং আপনার সময় নিন। এটা ভাল হবে।


এটি কম্পাইলারগুলিতে আমার প্রথম কাজ, আমি শিখছি / পরীক্ষা করছি এবং দীর্ঘদিন এটি বজায় রাখার আমার উদ্দেশ্য।
ম্যানেরো

3

আপনি কি মার্টিন ফোলার্স ভাষার ওয়ার্কবেঞ্চ পদ্ধতির বিষয়টি বিবেচনা করেছেন ? নিবন্ধ থেকে উদ্ধৃতি

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

এটি পড়ে, আমি বলব যে আপনার নিজের পার্সার লেখার দিনগুলি শেষ হয়ে গেছে এবং উপলভ্য লাইব্রেরিগুলির মধ্যে একটি ব্যবহার করা ভাল। একবার আপনি গ্রন্থাগারটিতে দক্ষতা অর্জনের পরে ভবিষ্যতে তৈরি করা সমস্ত ডিএসএল সেই জ্ঞান থেকে উপকার পাবেন। এছাড়াও, অন্যদের পার্সিংয়ের ক্ষেত্রে আপনার দৃষ্টিভঙ্গি শিখতে হবে না।

মন্তব্য (এবং সংশোধিত প্রশ্ন) কভার করতে সম্পাদনা করুন

আপনার নিজের ঘূর্ণায়মান সুবিধা

  1. আপনি পার্সারের মালিক হবেন এবং জটিল জটিল সিরিজের মাধ্যমে চিন্তাভাবনার সমস্ত সুন্দর অভিজ্ঞতা অর্জন করবেন
  2. আপনি এমন বিশেষ কিছু নিয়ে আসতে পারেন যা অন্য কেউ ভাবেন নি (অসম্ভব তবে আপনি একটি চালাক অধ্যায় বলে মনে করছেন)
  3. এটি আপনাকে একটি আকর্ষণীয় সমস্যার সাথে জড়িয়ে রাখবে

সুতরাং সংক্ষেপে, আপনি যখন নিজেকে গুরুতরভাবে উত্সাহিত করার জন্য দৃ strongly়ভাবে অনুপ্রাণিত হন এমন গুরুতর কঠিন সমস্যার অন্ত্রের গভীরে গভীরভাবে হ্যাক করতে চান তখন আপনার নিজের রোল করা উচিত।

অন্য কারও পাঠাগার ব্যবহারের সুবিধা

  1. আপনি চাকাটি পুনরায় উদ্ভাবন এড়াতে পারবেন (প্রোগ্রামিংয়ের একটি সাধারণ সমস্যা যা আপনি সম্মত হবেন)
  2. আপনি শেষ ফলাফলটিতে মনোনিবেশ করতে পারেন (আপনি চকচকে নতুন ভাষা) এবং কীভাবে এটি পার্স করা হয় সে সম্পর্কে খুব বেশি চিন্তা করবেন না
  3. আপনি আপনার ভাষা ক্রিয়াতে আরও দ্রুত দেখতে পাবেন (তবে আপনার পুরষ্কারটি কম হবে 'কারণ এটি আপনার সব ছিল না)

অতএব, আপনি যদি দ্রুত পরিণতি চান তবে অন্য কারও পাঠাগারটি ব্যবহার করুন।

সামগ্রিকভাবে, আপনি কতটা সমস্যার মালিক হতে চান তার একটি বিকল্পের নীচে নেমে আসে এবং এইভাবে সমাধানের জন্য। আপনি যদি এটি চান তবে নিজের রোল করুন।


এটি চিন্তার দুর্দান্ত বিকল্প।
ম্যানেরিও

1
@ বিগাউন আপনার প্রশ্নের আরও উত্তরের জন্য সম্পাদিত
গ্যারি রোয়ে

2

আপনার নিজের লেখার বড় সুবিধাটি হ'ল আপনি কীভাবে নিজের লেখা লিখবেন তা জানবেন। ইয়্যাকের মতো সরঞ্জাম ব্যবহারের বড় সুবিধা হ'ল আপনি কীভাবে সরঞ্জামটি ব্যবহার করবেন তা জানবেন। আমি প্রাথমিক অনুসন্ধানের জন্য ট্রিটপের ভক্ত ।


বিশেষ সহায়ক নয়। আপনি সম্ভবত বলেও দিয়েছেন, “গাড়ি চালানো শেখার সুবিধা হ'ল আপনি গাড়ি চালাতে পারেন। বাইক চালানো শেখার সুবিধাগুলি হ'ল আপনি বাইক চালাতে পারেন ”"
জেরিন

1

কেন ওপেন-সোর্স পার্সার জেনারেটরটি কাঁটাচামচ করে এটিকে নিজের তৈরি করে না? আপনি যদি পার্সার জেনারেটর ব্যবহার না করেন তবে আপনি যদি আপনার ভাষার বাক্য বাক্য গঠন করে থাকেন তবে আপনার কোড বজায় রাখা খুব কঠিন হবে।

আমার পার্সারগুলিতে, আমি টোকনাইজ করতে নিয়মিত এক্সপ্রেশন (মানে, পার্ল-স্টাইল) ব্যবহার করেছি এবং কোড পাঠযোগ্যতা বাড়াতে কিছু সুবিধাজনক ফাংশন ব্যবহার করেছি। তবে, পার্সার-উত্পন্ন কোডটি রাষ্ট্রীয় টেবিলগুলি এবং লম্বা switch- caseগুলি তৈরি করে দ্রুত হতে পারে , যা আপনি যদি না .gitignoreসেগুলি থেকে উত্স কোডের আকার বাড়িয়ে তুলতে পারে ।

আমার কাস্টম-লিখিত পার্সারগুলির দুটি উদাহরণ এখানে দেওয়া হয়েছে:

https://github.com/SHiNKiROU/DesignScript - একটি বেসিক উপভাষা, যেহেতু আমি অ্যারে স্বরলিপিতে লুকোহেডগুলি লিখতে খুব অলস ছিলাম, ত্রুটি বার্তাটির গুণমানের ত্যাগ করেছি https://github.com/SHiNKiROU/ExprParser - একটি সূত্র ক্যালকুলেটর। অদ্ভুত রূপক কৌশলগুলি লক্ষ্য করুন


0

"আমাকে কি এই পরীক্ষিত-পরীক্ষিত 'চাকা' ব্যবহার করা উচিত বা এটিকে পুনরায় উদ্ভাবন করা উচিত?"


1
এই "চাকা" আপনি কীসের কথা বলছেন? ;-)
জেসন হোয়াইটহর্ন

আইএমও এই প্রশ্ন সম্পর্কে ভাল মতামত নয়। এটি কেবলমাত্র একটি সাধারণ পরামর্শ যা নির্দিষ্ট ক্ষেত্রে উপযুক্ত নয়। আমি সন্দেহ করতে শুরু করি যে অঞ্চল 51.stackexchange.com/proposals/7848 প্রস্তুতি অকালে বন্ধ ছিল।
ম্যানেরিও

2
যদি চাকাটি পুনরায় উদ্ভাবিত না হয়, তবে আমরা প্রতিদিনের ভিত্তিতে 100kmph + এ ভ্রমণ করতাম না - যদি না আপনি কাঠের অ্যাক্সলে বিশাল ভারী গলিত কাঠের কাঁটাগুলিতে পরামর্শ দিতে যাচ্ছেন তবে ব্যবহৃত আধুনিক টায়ারের অনেকগুলি রূপের চেয়ে ভাল better এত গাড়ি?
পিটার বুটন

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

@ পিটার: কোনও কিছুর পুনর্নবীকরণ করা এক জিনিস (বোঝায় এটি একেবারে আলাদাভাবে করা) তবে অতিরিক্ত প্রয়োজনীয়তা পূরণের জন্য বিদ্যমান সমাধানটিকে আরও পরিমার্জন করা ভাল। আমি সবই 'উন্নতির' জন্য, তবে ইতিমধ্যে সমাধান হওয়া সমস্যার জন্য ড্রয়িং বোর্ডে ফিরে যাওয়া ভুল বলে মনে হচ্ছে।
JBRWilkinson
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.