DATOR

코드 자동 생성: 기계어 자동 번역기

Document URL : http://www.dator.co.kr/1660008
개발 및 설계 | Posted on March 08th, 2015 at 21:01 by 밀오 | 조회수 : 13395

0. 서론


코드 자동 생성 또는 실행 가능한 모델을 실현하기 위해 필요한 것이 무엇일까요?

저번 글에서는 이를 위해서 '자동 번역'이 필요하다고 잠깐 언급했었습니다.

이번 글에서는 이를 실현하기 위해 해야 할 것들을 생각해보겠습니다.


1. 번역에 앞서 알아두어야 할 점


일단 '자동' 이라는 단어를 떼놓고, '번역' 자체에 대해 생각해 보겠습니다.


번역이란, 하나의 언어를 다른 언어로 옮기는 작업입니다.

하지만, 이 과정은 데이터의 '손실' 과 '변환' 이 발생하는 작업입니다.


영어의 경우, 인과 관계를 객관적으로 묘사하는 부분이 강한 편입니다.

과거에 일어나서 현재의 결과에 영향을 준 것과, 과거에서 현재까지 진행되어서 현재의 결과에 영향을 주는 것 등을 서로 구분하기도 하고,

둘 이상의 요인이 어떤 건 순방향으로, 어떤 건 역방향으로 작용하여, 그 결과가 어떻게 되었다. 라는 식의 표현이 잘 되어 있습니다.


대신에, 사물에 대한 주관적인 느낌을 표현하는 부분은 약한 편입니다.

누리끼리 하다, 구수하다, 청명하다, 텁텁하다와 같은 표현들은 영어에서 찾기가 어렵습니다.


우리 말로, '길을 가다 넘어져서 손이 발갛게 부어올랐다' 라는 말은

누가, 왜, 어떻게 넘어졌는지에 대한 설명은 부족하지만, 그 결과 손이 부어오른 상태는 자세히 묘사하고 있습니다.

영어로 옮긴다면, '내가 길을 가다 우연히 넘어졌는데, 잠시 뒤에 손이 약간 부었다." 이 정도로 번역될 것입니다.

이 예제에서도, 인과 관계의 데이터가 추가 되었고, 상태에 대해서는 데이터 손실이 발생했습니다.


이는 기계어로의 번역인, 코드 생성에서도 마찬가지로 적용됩니다.


또한, 사람이 생각을 담기 위한 그릇으로 언어를 사용하기는 하지만, 아쉽게도 이는 불충분한 그릇입니다. 

때문에, 사람이 서로 의사 소통을 하는데 있어서, 많은 오해가 생기기도 하고, 다툼이 생기기도 하는 것이 사실입니다.


기계가 사용하는 언어는, 언어의 많은 요소 중에서도 인과관계만 담겨 있습니다. (개발자는 이를 입력/분기/출력 이라고 합니다.)

때문에, 사람의 생각을 정확히 담기에는 터무니 없이 부족한 그릇입니다.


개발을 해보지 않은 사람은, 컴퓨터의 이러한 한계에 대한 인지를 잘 못하는 경우가 많아서,

때로 컴퓨터가 할 수 없는 일을 요구한다거나, 사람이 처리하는 게 더 빠른 작업을 컴퓨터에게 시킨다거나 하는 오류를 범하기도 합니다.

하지만, 번역을 하려면 이 한계에 대해 명확히 알고 있어야 합니다.


위에서 번역에서 주의해야 할 두가지를 언급했습니다.

하나는, 데이터 손실과 변형이 발생한다는 것,

그리고 다른 하나는, 결과물에 명백한 한계가 있다는 것입니다.


자동 번역(코드 자동 생성)을 위해서는,

이 두가지 문제를 어떻게 처리해야 할지 미리 정해놓아야 합니다.


2. 손실과 왜곡이 없는 번역을 위해 필요한 것


이는 한 가지 예를 들면 충분한 설명이 될 것 같습니다.

바로 '유니코드'입니다.

유니코드는 서로 다른 언어를 모두 하나의 코드로 변환하기 위해, 합집합과 그룹의 개념을 도입했습니다.


어쨌든 손실이 없으려면, 최대한 모든 것을 포함할 수 있는 그릇을 준비해야 합니다.

언어가 표현하는 내용을 모두 담을 수 있고, 여기에 더해서 기계어로만 표현할 수 있는 내용도 같이 담도록 해야 합니다.


이를 위해서는 사람의 언어를 하나의 일관된 체계로 정리할 수 있어야 하는데,

현재 이러한 연구가 진행 중인지는 잘 모르겠습니다.

아마도 사람 간의 자동 번역기가 만들어지기 전에는 나오지 않을까 싶습니다.


현재 실용적으로 사용하는 방식은, 우선 사람의 언어를 모두 담는 건 포기합니다.

대신에, 기계가 표현가능한 언어를 담을 수 있는 그릇(표기법)을 만들어 놓고,

사람의 생각을 그 그릇에 담은 뒤에,

최종적으로 각 기계에 맞게 기계어로 번역하는 과정을 수행합니다.


예를 들어, UML 모델로 프로그래밍 언어의 클래스나 메서드를 생성한다던지,

ER 모델로 DB에 테이블을 생성한다던지 하는 작업이 이러한 과정입니다.


현 시점에서 볼 때, 자연어 번역은 기술이 성숙되기를 기다려야 할 것 같지만,

사전 정의된 모델을 기반으로 하는 코드 자동 생성은 가능한 방법입니다.


3. 번역의 한계를 미리 정해놓기


현대 기계가 이해하는 언어 자체의 한계가 있기 때문에, 현대 기계에 사람의 생각을 모두 구현하려는 생각은 버려야 합니다.

이를 위해서는 기존의 True/False 기반의 컴퓨터가 아닌, 신호의 강약을 인식할 수 있는 컴퓨터가 나와야 합니다.

(실제 사람의 신경 전달 체계는, true/false 논리 회로가 아닌 강신호/약신호를 더하고 빼는 방식으로 되어 있습니다.)


간략히 설명하면, 기계는 스위치와 True/False로 표현할 수 있는 모든 걸 표현 가능합니다.

예를 들어, 애매 모호한 확률적인 상황을 표현하거나, 아무런 입력 없이 결과를 도출할 수는 없습니다.


사전 정의된 모델의 경우, 이 한계를 넘어서는 모델은 번역이 불가능하니,

자동 번역의 모델로 사용하기 위해선 이 한계 내에서 모델을 정의해야 합니다.


이러한 모델이 준비되었다면, 이제 자동 번역을 해볼 시간입니다.


4. 모델을 객체와 인터페이스 그리고 호출로 변환하기

 

결과적으로, 기계는 입출력과 스위치 밖에 인식할 수 없기 때문에,

모델의 모든 요소가 입출력과 스위치로 변환되어야 합니다.


많은 연구 끝에 만들어진 현대 프로그래밍 언어는,

사람의 생각을 기계 언어에 담을 수 있는 중간 모델로 널리 사용되고 있습니다.


프로그래밍 언어는, 표현식인 비교, 점프, 반복, 할당, 로드로 구성 되어 있고,

입출력을 저장하기 위한, 변수와 상수가 이를 지원하는 형태입니다.

이들 각각이 결국 기계어의 스위치와 입출력으로 변형되는 것입니다.

변수의 형태는 점점 진화하여, 현대에는 객체의 형태로도 존재합니다.


모델의 각 요소를, 이러한 요소들로 상호 변환할 수 있다면,

모델에서 기계어로, 기계어에서 모델로 상호 변환이 용이할 것입니다.


ER 모델을 예로 들면,

엔터티는 객체로, 속성은 객체의 멤버로 변환 가능하며,

관계는 그 성격에 따라 인터페이스 또는 객체의 상속으로 변환 가능합니다.


이 정도로도 클래스의 '정의'를 하기엔 부족함이 없습니다.

다만, ER 모델에는 '상태' 만 존재하고, (실시간의) '동작' 에 대해서는 정의되어 있지 않아서, ER 모델 단독으로는 프로그램을 만들 수 없습니다.

실제 동작하는 프로그램을 만들기 위해서는, DB를 구동시키는 어플리케이션에 대한 모델이 추가되어야 합니다.


UML의 경우, sequence diagram이 이러한 '동작'에 대해서 정의하고 있습니다.

이러한 동작은 기계어의 점프로 구현됩니다.

sequence diagram에 대해서는 저도 사용해본 적이 없어서 정확한 건 모르겠지만,

인터넷에 돌아다니는 diagram만 보아서는, callback이나 event broadcasting 방식의 호출에 대해서는 표현하기 어려워 보입니다.

만약 UML에 이 방식의 호출을 표현할 수 있는 방법이 있다면, UML만 가지고도 대부분의 프로그램을 모델링 할 수 있습니다.


UML 모델이 기계어를 모델로 표현하기에 가장 적합한 모델로 보이지만,

충분한 모델인지는 아직 잘 모르겠습니다.

(물론 프로그래밍 언어의 경우 충분한 모델이 되지만, 별도의 번역가(개발자)를 필요로 하기 때문에 원래의 목적에서 벗어납니다.)


UML이든 다른 새로운 모델이든,

현대 프로그래밍 언어로 표현 가능한 모든 내용을 모델링 할 수 있는 모델이 있다면,

그 뒤의 상호 자동 번역은 별다른 무리 없이 진행될 것입니다.


5. 짚고 넘어가기


이제 자동 번역에 필요한 것이 정리되었습니다.

우선, 기계어로 변환 가능한 '모델'이 있어야 하고,

모델기계어의 상호 변환 '규칙'을 정의하면 됩니다.


다만, 여기서 주의할 점은 이러한 규칙이 1:1 변환이라면 곤란하다는 점입니다.


자동 번역을 위해 '모델'을 준비하긴 했지만,

우리는 이 모델을 번역가가 필요없는 모델이라고 암묵적으로 동의했습니다.

만약 별도의 번역가가 필요하다면, 개발자가 모델러로 바뀌었을 뿐 상황은 달라진게 없기 때문입니다.

오히려, 모델러가 생각해야 할 일이 늘어나고 작업에 소요되는 시간이 늘어나서, 상황을 악화시킬 수도 있습니다.

(물론 재가용성과 관리 측면에 대해서는 모델이 있는 편이 월등히 낫습니다. 하지만 이는 모델이 간결한 경우에 한합니다.)


1:1 변환이라면, 모델링의 난이도가 개발자가 개발하는 난이도와 동일할 것이고,

또한 '모델'이 상징하는 의미와도 맞지 않습니다.


클래스가 수십개에 인터페이스가 수백이고, 그걸 하나하나 다 표현하는 모델을 생각해 보십시오.

그럴바엔 모델을 간결하게 표현하고, 상세한 내용은 연관 코드를 첨부하는 편이 더 나을 거라고 생각합니다.

때문에, UML은 이점에서 적합한 모델이 아닙니다.


때문에, 저는 모델:기계어=1:M 변환이 가능한 모델이 있어야 한다고 생각합니다.

객체를 클래스 다이어그램의 한 요소로 표현하는 방식이 아니라,

사람의 언어를 기계어로 변환 가능한 중간 단계의 함축적 모델이 필요합니다.


현재 이와 같은 모델이 있나요?

만약 진정한 의미의 코드 자동 번역을 하고 싶다면, 이러한 모델에 대한 연구가 필요합니다.

만약, 이와 같은 모델을 알고 계시다면 댓글로 추가해 주시길 부탁드립니다.


6. 실행 가능한 모델


실행 가능한 모델은 또 다른 문제입니다.


기계어가 실행 코드로 만들어지기 위해서는 중간에 한가지 단계가 필요합니다.

C나 C++의 경우 컴파일이고, Script 언어의 경우 인터프리터가 이 단계를 담당합니다.


컴파일의 경우, 별도의 실행파일이 생성되고 OS를 통해서 이를 실행하는 방식이기 때문에,

모델을 즉시 실행하는 컨셉과는 맞지 않습니다.


즉, 모델에서 즉시 실행하고 서로 상호 작용하기 위해서는,

스크립트 언어가 활용하는 인터프리트 방식이 되어야 합니다.


그런데 여기에 한가지 문제가 생깁니다.

인터프리트 방식은 중간에 별도의 프로세스가 언어를 실시간으로 해석하여 실행하는 방식으로 보면 됩니다.


즉, 컴파일 방식을, 영어로 된 메뉴얼을 한글로 번역한 다음, 번역해 놓은 문서를 읽는 것에 비유한다면,

인터프리트 방식은, 영어로 된 메뉴얼을 중간에 번역자가 붙어서 매번 한글로 번역해서 읽어주는 것에 비유할 수 있습니다.


여기서 번역자가 사람이 아닌 컴퓨터라는 점이 그나마 다행이긴 하지만, 

컴파일 방식에 비해 태생적으로 효율이 떨어지는 방식입니다.


때문에, 속도를 중시하는 프로그램이 필요한 경우, 이 방식은 채택하기 어렵습니다.


결국, 속도와 실시간 실행 둘 중 하나는 포기해야 합니다.


물론 방법이 아예 없는 건 아니지만, 실현 가능성은 매우 낮은 방법입니다.

이해를 돕기위해 좀 더 설명해 보겠습니다.


컴퓨터가 명령을 실행하기 위해서는, 최종적으로 opcode라는 이진수로 된 명령어와 그에 따른 operand를 CPU에 전송하면 됩니다.

하지만 현대 컴퓨터는 OS가 중간에 관리자 역할을 하며, 응응프로그램이 CPU에 피해를 입히지 못하도록 방어합니다.

때문에, 실제 프로그램이 실행되기 위해서는, OS에서 프로그램 실행파일을 읽어서 각 데이터를 메모리에 알맞게 배치하고 명령집합을 읽어서 실행하는 과정을 거쳐야 합니다.


때문에 OS에서 읽을 수 있는 실행파일이 존재해야 정상적인 경로로 프로그램이 실행될 수 있습니다.

이 실행파일을 컴파일러에서 생성하든지, 인터프리터가 담당하든지 해야 하는데, 

둘 다 안되는 상황이니, OS를 우회해서 직접 CPU에 명령을 내리는 방법밖에 없습니다.

보안상 허용될 수 없는 방법입니다.


아니면, 아예 OS 제조사에서 실행가능한 모델을 내장 기능으로 제공해 준다면 가능합니다.

사용자가 커널을 직접 뜯어 고칠 수 있는 OS라면 시도해 볼 수도 있겠습니다.


7. 정리하며


지금까지 코드 자동 생성 및 실행 가능한 모델의 실현에 대해서 생각해 보았습니다.
실현만 된다면, 삶의 개념이 바뀌는 새로운 경험을 할 수 있을 것이라 기대되는 데요,
아쉽지만, 지금까지 살펴본대로, 현대의 기술로는 만족스러운 결과를 얻을 수 없을 것으로 보입니다.


앞으로, 가까운 미래에 이중 몇 가지가 시도될 수 있을 것 같은데요,

그 때, 우리도 한 축을 담당할 수 있었으면 좋겠습니다.

(아마도 누군가는 어디선가 이미 꿈을 꾸고 달리고 있을 겁니다.)


긴 글, 읽어주신 분들 모두 감사드립니다.


Tagged :
   

Comments : 0