C, C++, Java, Python, Kotlin 등 정말 많은 프로그래밍 언어들이 있다. 그 종류도 굉장히 다양하고 절차지향언어, 객체지향언어, 스크립트 언어, 최근에는 함수형 프로그래밍 언어까지 나오고 있다. 각 프로그래밍 언어마다 특징이 있고 쓰임새가 있다. 예를 들어 C나 C++ 같은 경우는 포인터를 통한 메모리 직접 접근이 가능하여 매우 빠른 연산이 가능하다. 어셈블리언어 같은 경우 더 Low한 레벨의 프로그래밍 언어이기 때문에 임베디드 시스템이나 하드웨어를 직접 컨트롤 하는 프로그램에 적합하다. 반대로 Java 같은 경우는 JVM이라는 가상 머신 위에서 실행되기 때문에 하드웨어나 시스템에 상관없이 독립적으로 실행이 가능하다. 따라서 내가 어떤 프로그램을 만들고 싶은지 정하고 알맞은 프로그래밍 언어를 택하는 것은 매우 중요하다
그렇다면 프로그래밍 언어는 어떻게 만드는 걸까? 바로 프로그래밍언어론 카테고리에서 다룰 내용이다. 기본적으로 오토마타 내용을 알고 있으면 쉽다. 물론 기초적인 내용은 포스팅할 예정이다.
BrainFuck
문자 |
의미 |
> |
포인터를 증가시킨다. |
< |
포인터를 감소시킨다. |
+ |
포인터가 가리키는 바이트의 값을 증가시킨다. |
- |
포인터가 가리키는 바이트의 값을 감소시킨다. |
. |
포인터가 가리키는 바이트의 값을 ASCII 문자로 출력한다. |
, |
포인터가 가리키는 바이트에 입력받은 문자의 ASCII 값을 넣는다. |
[ |
포인터가 가리키는 바이트의 값이 0이면 짝이 되는 뒤쪽의 |
] |
포인터가 가리키는 바이트의 값이 0이 아니면 짝이 되는 앞쪽의 |
+++++ +++++ initialize counter (cell #0) to 10 [ use loop to set the next four cells to 70/100/30/10 > +++++ ++ add 7 to cell #1 > +++++ +++++ add 10 to cell #2 > +++ add 3 to cell #3 > + add 1 to cell #4 <<<< - decrement counter (cell #0) ] > ++ . print 'H' > + . print 'e' +++++ ++ . print 'l' . print 'l' +++ . print 'o' > ++ . print ' ' << +++++ +++++ +++++ . print 'W' > . print 'o' +++ . print 'r' ----- - . print 'l' ----- --- . print 'd' > + . print '!' > . print '\n'
Compiler & Interpreters
Preprocessor에서 소스 프로그램이 컴파일러로 넘어가고 컴파일러에서 어셈블러로 Target Assembly Program이 넘어간다. 어셈블러에서 링커로는 Reloactable Object Code가 넘어간다. 컴파일러는 모든 과정을 거쳐 기계어를 만들지만 Assembler 이하의 과정은 인터프리터에서는 일어나지 않는다! 기계어로 변환할 필요가 없기 때문이다! 크게 컴파일러 전까지 Analysis과정이라고 부르고 그 이후의 과정을 Synthesis라고 부른다.
Compiler
컴파일러의 구조는 위와 같다.
Scanner
토큰을 구분해서 파서로 넘겨준다. 어떠한 인풋이 들어왔는지 검사를 하여 토큰의 형태로 넘겨주는 것이다. (예를 들어 case, if, for, 변수명 같은 것들을 구분) Lex, JavaCC, Scangen 등
Parser
스캐너로부터 받은 토큰으로 주어진 문법에 맞는지 판단한다. Yacc, JavaCC, llgen 등
댓글