Ahhoz, hogy a lényegtelen eltéréseket mutató megoldások reprezentációja ugyanaz legyen, a representernek normalizálásokat kell alkalmaznia. A normalizált reprezentáció létrehozásának folyamata általában így néz ki:
representation.txt nevű fájlba (lásd az interfészt)Megjegyzendő azonban, hogy a reprezentációnak nem kell AST-nak lennie: lehet sima (normalizált) kód is, attól függően, hogy mi működik a legjobban a kurzusod számára.
Hogy segítsünk az indulásban, most bemutatunk néhány gyakori normalizálási stratégiát.
megjegyzés: a normalizálási példák nem épülnek egymásra, mindegyik csak egy-egy konkrét normalizálást mutat be. Egy valódi representer ezeket egymás után alkalmazná.
megjegyzés: az útmutatóban szereplő kód C#-ban lesz, de maga az útmutató nyelvfüggetlen.
Ahhoz, hogy a reprezentációk függetlenek legyenek az elnevezésektől, a felhasználó által definiált neveket (például változók, függvények stb.) helyőrzőkkel lehet helyettesíteni. Ebben az esetben létre kell hozni egy mapping.json fájlt (lásd az interfészt).
Fontos megjegyezni, hogy minden azonos nevet ugyanazzal a helyőrzővel kell helyettesíteni, függetlenül a scope-tól.
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;
}
}
A következetlen szóközhasználat olyan gyakori, hogy a normalizálása az egyik leggyakoribb normalizálási lépés. A sorvégeket is normalizálni kell.
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));
}
}
Sok nyelvben a felhasználónak bizonyos szabadsága van abban, hogyan definiál egy blokkot (vagy scope-ot). Például a legtöbb C-szerű nyelvben a scope-ot kapcsos zárójelek közé zárjuk. Általában nem számít, hogy ugyanabba a sorba teszed-e őket vagy a következőbe, ezért ezt normalizálni lehet.
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;
}
}
Nem a kód minden része lényeges a representer számára, így azok eltávolíthatók. Például a legtöbb nyelvben a megjegyzések lényegtelenek, és nyugodtan eltávolíthatók.
/*
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";
}
}
Bizonyos esetekben a kód sorrendje nem számít. Hogy megakadályozzuk, hogy ugyanaz a kód más sorrendben más reprezentációt hozzon létre, érdemes lehet rendezni. Általában a rendezendő elemek függvények vagy deklarációk. Trükkös lehet megtalálni, hogy mi alapján rendezz, és a megvalósítása is trükkös lehet. Az egyik szempont lehet, hogy hány AST-csomópont gyermeke van az adott csomópontnak, a másik pedig az első gyermekcsomópont típusának a neve.
Ez a példa valamilyen függvényhossz szerint rendez:
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;
}
}