রিপ্রেজেন্টারের ভেতরে নরমালাইজেশন


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

  • সমাধানের কোড একটি অ্যাবস্ট্রাক্ট সিনট্যাক্স ট্রি (AST)-তে পার্স করুন
  • AST-তে নরমালাইজেশন প্রয়োগ করুন
  • নরমালাইজড AST একটি স্ট্রিং-এ রূপান্তর করুন
  • নরমালাইজড AST স্ট্রিংটি representation.txt নামের একটি ফাইলে লিখুন (দেখুন ইন্টারফেস)

তবে মনে রাখবেন, রিপ্রেজেন্টেশন অবশ্যই একটি AST হতে হবে না, এটি সাধারণ (নরমালাইজড) কোডও হতে পারে, আপনার ট্র্যাকের জন্য যেটি সবচেয়ে ভালো কাজ করে সেটিই।

শুরু করার জন্য এখন আমরা কিছু কমন নরমালাইজেশন স্ট্র্যাটেজি দেখব।

নোট ১: নরমালাইজেশনের উদাহরণগুলো একটির ওপর আরেকটি তৈরি হয় না, প্রতিটি কেবল একটি নির্দিষ্ট নরমালাইজেশন দেখায়। একটি বাস্তব রিপ্রেজেন্টার এগুলো ক্রমান্বয়ে প্রয়োগ করতে চাইবে।

নোট ২: এই নির্দেশিকাগুলোর কোড C#-এ থাকবে, তবে নির্দেশিকাগুলো ভাষা-নিরপেক্ষ।

আইডেন্টিফায়ার নরমালাইজ করুন

রিপ্রেজেন্টেশন যাতে নাম-নিরপেক্ষ হয়, সেজন্য ব্যবহারকারীর দেওয়া নাম (যেমন ভ্যারিয়েবল, ফাংশন ইত্যাদি) প্লেসহোল্ডার দিয়ে প্রতিস্থাপন করা যায়। এক্ষেত্রে একটি mapping.json তৈরি করা উচিত (দেখুন ইন্টারফেস)।

মনে রাখা জরুরি, স্কোপ নির্বিশেষে সব অভিন্ন নাম অবশ্যই একই প্লেসহোল্ডার দিয়ে প্রতিস্থাপন করতে হবে।

সোর্স কোড

public static class Fake
{
    public static int Test(int input)
    {
        var test = input + 2;
        return test;
    }
}

রিপ্রেজেন্টেশন

public static class PLACEHOLDER_1
{
    public static int PLACEHOLDER_2(int PLACEHOLDER_3)
    {
        var PLACEHOLDER_4 = PLACEHOLDER_3 + 2;
        return PLACEHOLDER_4;
    }
}

হোয়াইট স্পেস নরমালাইজ করুন

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

সোর্স কোড

using   System;

     public static    class Fake
{
    public     static   DateTime Add    (DateTime    birthDate)
    {
        return birthDate.Add( TimeSpan.FromSeconds   (   10  ) )   ;
    }
}

রিপ্রেজেন্টেশন

public static class Fake
{
    public static DateTime Add(DateTime birthDate)
    {
        return birthDate.Add(TimeSpan.FromSeconds(10));
    }
}

ব্লক নরমালাইজ করুন

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

সোর্স কোড

public static class Fake {
    public static int Test() {
        if (1 > 2) {
            return 0;
        }

        return 1;
    }
}

রিপ্রেজেন্টেশন

public static class Fake
{
    public static int Test()
    {
        if (1 > 2)
        {
            return 0;
        }

        return 1;
    }
}

তাৎপর্যহীন কোড সরিয়ে ফেলুন

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

সোর্স কোড

/*
   These are some very nice
   comments spanning multiple lines
*/
public static class Fake
{
    // Nice method
    public static string Test()
    {
        return "Test"; // This is very nice
    }
}

রিপ্রেজেন্টেশন

public static class Fake
{
    public static string Test()
    {
        return "Test";
    }
}

যেখানে তাৎপর্যহীন, সেখানে ক্রম নরমালাইজ করুন

কিছু ক্ষেত্রে কোডের ক্রম গুরুত্বপূর্ণ নয়। একই কোড ভিন্ন ক্রমে থাকলে যাতে ভিন্ন রিপ্রেজেন্টেশন তৈরি না করে, সেজন্য এটি সাজানো কার্যকর হতে পারে। সাধারণত সাজানোর বিষয়গুলো হলো ফাংশন বা ডিক্লারেশন। কোন মেট্রিকের ভিত্তিতে সাজাবেন তা খুঁজে বের করা কঠিন হতে পারে, আর বাস্তবায়নও কঠিন। একটি মেট্রিক হতে পারে নোডে কতগুলো AST চাইল্ড নোড আছে, আরেকটি হতে পারে প্রথম চাইল্ড নোডের টাইপের নাম।

এই উদাহরণটি একধরনের ফাংশন দৈর্ঘ্য অনুসারে সাজায়:

সোর্স কোড

public static class Fake
{
    public static string Test2()
    {
        int a = "Test2";
        return a;
    }

    public static string Test()
    {
        return "Test";
    }
}

রিপ্রেজেন্টেশন

public static class Fake
{
    public static string Test()
    {
        return "Test";
    }

    public static string Test2()
    {
        int a = "Test2";
        return a;
    }
}