본질적이지 않은 차이가 있는 풀이들이 같은 표현을 갖도록 하려면, Representer가 정규화를 적용해야 해요. 일반적으로 정규화된 표현을 만드는 과정은 다음과 같아요:
representation.txt라는 파일에 작성해요 (인터페이스 참고)다만 표현이 반드시 AST일 필요는 없고, 일반적인(정규화된) 코드일 수도 있어요. 트랙에 가장 잘 맞는 방법을 선택하면 돼요.
시작하는 데 도움이 되도록, 몇 가지 일반적인 정규화 전략을 소개할게요.
참고 1: 정규화 예제들은 서로 기반하지 않고, 각각 하나의 특정 정규화만 보여줘요. 실제 Representer는 이것들을 연속해서 적용하는 것이 좋아요.
참고 2: 이 가이드라인의 코드는 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;
}
}
모든 코드 조각이 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
}
}
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;
}
}