অপ্রয়োজনীয় পার্থক্য থাকা সমাধানগুলো যাতে একই রিপ্রেজেন্টেশন পায়, সেজন্য রিপ্রেজেন্টারের নরমালাইজেশন প্রয়োগ করা উচিত। সাধারণভাবে, একটি নরমালাইজড রিপ্রেজেন্টেশন তৈরির প্রক্রিয়া দেখতে এমন হয়:
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;
}
}