Spirit - 해당되는 글 3건
C++에는 IO Stream library와 STL이 표준 라이브러리로 있습니다.
둘은 모두 std라는 namespace를 사용합니다.
그 외에 C Standard Library도 사용할 수 있죠.
IO Stream은 입출력에 관련된 것이고,
STL은 자료구조와 알고리즘에 대한 것입니다.

C++을 주로 사용하는 프로그래머라면, 이제 Boost 라이브러리도 알아둘 필요가 있습니다.

STL을 사용해보신 분은 아시겠지만, MFC나 C standard library처럼, 클래스 정의나 함수 정의만 보고 "아 이것은 이렇게 사용하면 되겠구나.." 라고 하기 힘듭니다.

Boost는 한 발 더 나아갑니다. 완전 모르겠습니다.

우선 Boost 라이브러리에 대해 말씀드리지요.
Boost 라이브러리는 C++ 라이브러리입니다. 대부분이 STL처럼 템플릿 라이브러리입니다. 그리고, Boost 라이브러리는 여러 하위 라이브러리들의 집합입니다. 하위 라이브러리들은 모두 70개가 조금 안됩니다. 휴우~ 이것들을 다 공부할 필요는 없습니다. 필요한 것만 하면 되지요.
Boost 라이브러리는 뭐다라고 단정지어 말하기 힘듭니다. STL과 굳이 구분을 하자면, 저는 보통 이렇게 이야기합니다.

"STL은 알고리즘이고, Boost는 유틸리티야."

완전히 옳은 것은 아닙니다. 하지만, 이렇게 생각하는 것이 속 편합니다. 하지만, 이러한 경향이 매우 강하지요.
하위 라이브러리는 매우 다양합니다.
graph와 같이 알고리즘을 구현한 것도 있고, functional이나 lambda와 같이 functional programming을 지원하는 것도 있습니다. 그런가 하면, regex++과 같이 정규표현식을 파싱하는 것도 있고, iostreams와 같이 iostream 라이브러리를 확장한 것도 있습니다.
ref와 같이 크기가 매우 작은 (작은 헤더 파일 하나) 라이브러리도 있는가 하면, Spirit과 같이 엄청 큰 규모의 라이브러리도 있습니다.

한 마디로, Boost는 C++을 위한 종합 선물 세트!!!

그 중, 제가 요즘 공부했던 Spirit이라는 라이브러리는 문자열 파싱에 관심있는 분이라면 꼭 한 번 보시는 것도 좋습니다.
가장 유명한 Parser generator로는 Lex/Yacc과 그 후손들인 Flex/Bison과 같은 LALR(1) 파서 생성기가 있고, ANTLR과 같은 LL(k) 파서 생성기가 있습니다.
비록 성능은 이들에 미치지 못하지만, 매우 많은 장점을 지닌 파서 생성기가 바로 Spirit입니다.
장점만 나열해보지요.
  • 완전한 C++ 코드이다. 따라서 C++에서 사용하는 디버깅 등이 모두 사용 가능하다.
  • Debugging과 Exception(Error) handling을 위한 많은 기능이 제공된다.
  • C++ 컴파일러 외에 다른 툴이 필요하지 않다.
  • <중요> Symbol table과 Parser Tree, Abstract Syntax Tree를 알아서 만들어주거나 매우 만들기 쉽다.
  • 동적 파서를 쓸 수 있다. (이거 참 유용할 듯합니다.)
제가 네 번에 걸쳐 세미나를 했을 때, Lex/Yacc에 비해 좋은 점을 모르겠다고 합니다. 그 분은 Lex/Yacc에 익숙하니까 그렇죠. Yacc에 symantic action을 넣으려면, C 코드로 난잡하게 집어넣고, 순서도 맞춰야 하고... 좀 복잡하죠. 그런데, Spirit은 symantic action이 들어갈 곳이 매우 직관적입니다.
그리고, 구문 분석기와 어휘 분석기가 따로 존재하지 않습니다. 그냥 알아서 합니다. 하하하

Spirit을 이해하기 위해서는 C++ 템플릿을 가지고 똥도 닦을 수 있어야 합니다. Spirit은 템플릿 라이브러리입니다. 게다가, Expression Template이라는 것을 사용합니다. (이전 글에서 잠깐 언급했는데, 이해하기 상당히 난해합니다. -_-;) STL에서도 나오는 Function object 혹은 Functor라는 것은 땅바닥에 눌러붙은 껌처럼 생각할 수 있어야 합니다.

그러한 과정을 거친 끝에, 겨우 온라인 문서를 다 봤습니다. 아.. 대충 이해는 가는데, 써먹으려니 또 막막하네요. 호호 그래도 많이많이 써먹어야죠.

아직까지는 C++과 같은 복잡한 문법 컴파일러는 못만든다고 합니다. C 파서는 Spirit으로 누가 만들어놨더군요. 저는 C++코드를 파싱하여 Visual Studio 등과 같은 툴에 있는 'Class view'와 같은 것을 만드려고 합니다. 어짜피 타입 이름과, 식별자들만 파악할 거니까 그리 어렵지 않게 할 수 있겠죠?

C++을 쓰시는 분들.. Boost 라이브러리 한 번 거들떠 보자.
Trackbacks  1 | Comments 




Expression Template은 Todd Veldhuizen이라는 사람이 1995년에 발표한 논문입니다. 논문 본문은 아래의 링크에 있습니다.

http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html

Expression Template이라는 것은 참 재밌습니다.

int foo(int a);

라는 함수가 있다고 하죠. 이 함수는 정수를 입력받아 정수를 리턴합니다.

int i = 20;

이라고 i라는 변수를 정의했습니다.

foo(i * 30 + i / 2);

와 같이 호출했다면 어떤 일이 벌어질까요? 프로그램이 실행 중일 때, i가 20인 걸 알고, 실제로는 다음과 같은 호출이 일어납니다.

foo(610);

그렇죠? 이를 early evaluation이라고 합니다. 미리 계산되어 인자로 들어간다는 의미지요.
그런데, Expression template은 lazy evaluation입니다. 수식이 일단 인자로 들어가고, 함수 내부에서 계산이 이루어집니다. 진짜 내부 구현을 들여다보면 좀 다르게 구현되어 있지만, 개념 상으로는 그렇습니다. 자세한 구현은 논문을 보시면 될 테고,

template<typename T>
int bar(T a);

라는 함수가 있고,

class Ca;
Ca x;

라는 클래스와 그것의 인스턴스가 있습니다. 다소 놀라운 일이 벌어집니다.

bar(x * 30 + x / 2);

이렇게 호출 할 수 있습니다. 뭐 이렇게 얘기할 수 있겠죠.
*와 +와 /가 Ca라는 클래스에 대해 operator overloading 되어있으면 되고, bar()라는 함수는 결국 Ca 타입의 reference나 value를 입력받지 않겠느냐
네, 맞습니다. 그렇게 됩니다. (하지만, 최종으로 넘어가는 클래스가 Ca가 아니라는 거~~) 여기까지는 이상할 게 없죠? 그런데 문제는 x가 무엇이냐는 겁니다. 그냥 단순히 객체를 넘기고자 했다면, 저렇게 요상한 식을 써서 넘길 리가 없죠. 저건 누가 봐도 수식입니다. 뭔가 계산하고 싶은 것이고, x는 (객체로 구현이 되어는 있지만) 변수입니다.

여기서는 argument placeholder라고 해서, 나중에 그 값이 결정됩니다. 눈치 빠른 사람들은 뭐가 다른 것인지 아시겠죠?

네, foo()에서 i는 입력으로 들어갈 때 이미 값이 20이라고 결정되어 있지만, bar()의 x는 값이 결정되어 있지 않습니다. 그럼, 언제 그 값을 알 수 있을까요?

여기서 functor 혹은 function object라는 것이 등장합니다. 이것은 STL을 공부하신 분은 아실 것입니다. 객체를 함수처럼 사용하는 겁니다. 즉, 클래스가 operator()() 함수를 가지고 있는 것이지요. 아니면, 미리 약속된 이름의 멤버 함수가 있을 것입니다. bar() 함수에서, 파라미터로 넘어간 객체의 특정 메쏘드를 호출할 때, 그 값이 결정됩니다. 즉,

x는 'x * 20 + x / 2'가 만들어내는 functor의 parameter입니다.

여기서 또 새로운 개념, Lambda Expression이 들어갑니다. x가 바로 Lambda... 음..

그리고, *, +, / 즉, operator*(), operator+(), operator/()는 모두 higher order function  혹은 functional이라고 부릅니다. 함수를 입력받아, 함수를 리턴하니까요...

오늘 세미나 시간에 이걸 설명하려고 했습니다... 어제부터...

그런데... 역시나.. 설명이 잘 안됩니다..

저도 공부하는데 무지 오래걸리긴 했는데, 전달도 잘 안되네요.. 아직 빠삭하게 알지 못해서리.. STL도 잘 모르는데요 뭐..

왜 이런 것들을 설명하냐구요?

Boost의 Spirit이라는 라이브러리를 설명하는 중이었는데, 저것들을 알아야해요~~ -_-;


Trackbacks  0 | Comments 




C++의 준 표준 라이브러인 Boost 라이브러리 중,
Spirit이라는 Parser generator library를 보고 있어.

아... 이 녀석 사용하기는 쉬운 라이브러리인데,
개념이 무척 어려워...

어쩌다 보면 수학 공부하는 것 같기도 하고..

차라리 Flex-Bison이나 ANTLR같은 툴을 사용하는 것이 나을 듯도 싶지만,
Spirit만 제대로 학습하면 나의 C++ 테크닉은 일취월장할 것 같아.

여기 나오는 개념만 봐도..

1. Function Object (Functor)
2. Expression Template
3. Meta-Function
4. Curiously Recurring Template Pattern
5. Currying
6. Higher order function (Functional)

음...
대부분 수학에서 나온 개념인데, 이것들 이해하느라 힘들었어.
Meta-function은 아직도 이해 못하겠다.

근데, 앞으로 Lamda function이니 등등 더 나온다는 거~~

존나 프로그래밍 실력 늘겠다..

이거 공부하면서 느꼈는데, 세상에는 정말 천재들이 많아.
어찌 이런 것들을 생각했는지..

Trackbacks  1 | Comments 
permalink alones
2007.07.19 13:27 댓글에 댓글수정/삭제
Function Pointer 관련 번역 및 정리 작업을 한 포스트에 Functor에 대한 내용이 조금 있어서 trackback 날렸습니다.

좋은 내용이 많을 것 같은 느낌이 드네요 ^^ 종종 놀러 오겠습니다.
(※ 예전에 VS2005 관련 덧글 보고 왔습니다~)




풀리비’s Blog is powered by Daum & Tattertools.com