نرمال‌سازی در بازنمایی‌گرها


برای اینکه solutionهایی که تفاوت‌های غیرضروری دارند، representation یکسانی داشته باشند، Representer باید نرمال‌سازی‌ها را اعمال کند. به‌طور کلی، فرایند ساختن یک representation نرمال‌شده این‌طور است:

  • کد solution را به یک درخت نحو انتزاعی (AST) تجزیه کنید
  • نرمال‌سازی‌ها را روی AST اعمال کنید
  • AST نرمال‌شده را به یک رشته تبدیل کنید
  • رشته‌ی AST نرمال‌شده را در فایلی به اسم representation.txt بنویسید (به رابط نگاه کنید)

البته توجه کنید که representation لزوماً نباید یک AST باشد؛ می‌تواند کد معمولی (نرمال‌شده) باشد، هرکدام که برای track شما بهتر جواب می‌دهد.

برای اینکه شروع کار راحت‌تر شود، حالا چند راهبرد رایج نرمال‌سازی را معرفی می‌کنیم.

نکته ۱: مثال‌های نرمال‌سازی بر پایه‌ی یکدیگر بنا نشده‌اند؛ هرکدام فقط یک نرمال‌سازی مشخص را نشان می‌دهند. یک Representer واقعی این‌ها را پشت سر هم اعمال می‌کند.

نکته ۲: کد این راهنماها به زبان C# نوشته شده است، اما خودِ راهنماها به زبان خاصی وابسته نیستند.

نرمال‌سازی شناسه‌ها

برای اینکه representationها مستقل از اسم‌گذاری باشند، می‌توان اسم‌های تعریف‌شده توسط کاربر (مثل متغیرها، توابع و غیره) را با «جانگهدارها» جایگزین کرد. در این حالت باید یک mapping.json تولید شود (به رابط نگاه کنید).

نکته‌ی مهم این است که همه‌ی اسم‌های یکسان، صرف‌نظر از «محدوده»، باید با جانگهدار یکسانی جایگزین شوند.

کد منبع

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

Representation

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  ) )   ;
    }
}

Representation

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;
    }
}

Representation

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

        return 1;
    }
}

حذف کدهای بی‌اهمیت

همه‌ی بخش‌های کد برای Representer مهم نیستند و می‌توان آن‌ها را حذف کرد. برای مثال، در بیشتر زبان‌ها کامنت‌ها بی‌اهمیت‌اند و می‌توان با خیال راحت حذفشان کرد.

کد منبع

/*
   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
    }
}

Representation

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

نرمال‌سازی ترتیب، آنجا که بی‌اهمیت است

در بعضی موارد، ترتیب کد اهمیتی ندارد. برای اینکه کد یکسان با ترتیب متفاوت، representationهای متفاوتی تولید نکند، مرتب‌کردن آن می‌تواند مفید باشد. معمولاً مواردی که باید مرتب شوند، توابع یا اعلان‌ها هستند. پیدا کردن معیار (معیارهای) مرتب‌سازی و همچنین پیاده‌سازی آن ممکن است دشوار باشد. یک معیار می‌تواند تعداد فرزندان گره‌ی AST باشد، و معیار دیگر، اسم نوع اولین گره‌ی فرزند.

این مثال بر اساس نوعی از طول تابع مرتب می‌کند:

کد منبع

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

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

Representation

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

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