Rock과 Classic음악의 조화를 뜻하는 이름의 RocKlassic 공연이 어제 밤에 KAIST 노천극장에서 열렸다. 내가 좋아하는 함신익 지휘자가 대전시향을 떠난 이후로 한동안 문화생활을 하지 않다가 오랜만에 학교에서 하는 좋은 공연이 있어 참가하게 되었다.
노천극장이 가득찰 정도의 많은 사람들이 모였다. 공연은 모두 KAIST 학생들에 의해서 이루어졌는데, 특히 반도네온(bandoneon) 이라는 악기의 음색이 상당히 매력적이였다. 독일 종교음악을 위해 만들어진 악기가 아르헨티나로 넘어가면서 이상 야릇한(?) 느낌을 주는 악기로 활용되었다고 하는데, 특히 이 악기로 연주한 왕의남자 OST는 감동적이였다. 개인적으론 “냉정과 열정사이 OST”의 피아노곡 연주가 가장 좋았고 유진박의 “드라마틱 펑크” 연주도 좋았는데 …
“드라마틱 펑크”의 연주는 매우 멋졌으나 연주자의 옷차림이 다소 올드하였기에 그 나이가 의심되어 유인물을 살펴보니 학부 4학년이였다. 옆에 있는 묘령의(?) 아가씨와 그 이야기를 하는데 옆에 있는 꼬마 아가씨가 엄마랑 대화하는게 들렸다.
“엄마! 난 아저씨인 줄 알았어. 뚱뚱하잖아”
“조용히 해라. 저 오빠가 들으면 섭섭하겠어.”
동측기숙사 위로 가을하늘
일주일의 방학(?)이 끝나고 이번주 부터 다시 SDA 어학원을 나가고 있다. 매일 6시에 일어나는 생활이 주초에는 너무 힘들었는데 이제 좀 적응이 된 모양인지 컨디션이 나쁘지 않았다. 주변이 모두 평지라서 그런지 가을하늘은 너무나 광활한 느낌을 준다.
6시에 일어나서 6시 30분에 동측쪽문 버스 정류장에서 185번을 타고 학원으로 간다. 교실에 도착하면 6시 50분쯤! 약간은 이제 지루하기도 한 수업을 마치면 학교로 돌아와야 하는데 이때 항상 고민하게 된다. 버스를 타자니 타이밍이 안맞아 10~15분을 기다려야 한다. 그래서 어제 오늘은 날씨도 선선해서 걸어서 학교로 돌아왔다.
갑천 징검다리
시내를 가로질러 갑천 징검다리를 건너면 8시 30분이 되기 전에 학교 정문에 도달할 수 있다. 중간에 세븐일레븐에 들려 천원짜리 한줄김밥이나 삼각김밥을 사가지고 갑천을 지날 때 먹으면 아침식사까지 해결하는데 걸리는 시간은 버스를 타고 와서 학교식당에서 식사를 해결할때 보다 적게 소모된다.
Preference는 IDE에서 흔히 볼 수 있는 환경설정을 의미한다. 우리가 어떤 특정 플러그인을 개발할 때, 그 플러그인에 특화된 환경설정이 필요한 경우가 있다. 예를 들어 설명하자면, 이전에 소개한 바 있지만 Esterel 언어는 소프트웨어 언어인 C로도 컴파일이 되고 하드웨어 언어인 Verilog로도 컴파일이 가능하다.
Preferences in Eclipse
Esterel 언어를 위한 개발환경에서 위와 같은 환경설정이 존재한다면 각 항목의 체크유무에 따라 소스코드의 컴파일시에 생성되는 아웃풋 파일의 종류를 결정할 수 있다. 이와 같은 작업을 위해서 알아야 할 확장점(Extension Point)에는 두가지가 있으며 이를 포함한 plugin.xml의 일부분의 내용은 다음과 같다.
첫번째 확장점인 org.eclipse.ui.preferencePages을 이용해 Preference page에 기여할 수 있으며, 두번째 확장점인 org.eclipse.core.runtime.preferences에서는 환경설정의 기본값을 지정할 수 있다.
우선 첫번째 확장점을 위한 클래스인 VicodePreferencePage를 살펴보자. 이 클래스는 PreferencePage를 상속하며 UI를 만드는 createContents() 메서드, Restore Defaults 버튼을 눌렀을 때 호출되는 performDefaults(), OK 버튼을 눌렀을 때 호출되는 performOk() 메서드등으로 구성되어 있다. 메서드 이름만으로 각 메서드의 역할을 알 수 있을 것이다.
다음 생성자(Constructor)와 performOk() 메서드를 통해서 환경설정을 어떻게 이용하는지 알아보자.
public VicodePreferencePage() {
super(); setPreferenceStore(Activator.getDefault().getPreferenceStore()); setDescription(“Development environment settings for VICODE”);
fCheckBoxes = new ArrayList<Button>();
}
public boolean performOk() { IPreferenceStore store = getPreferenceStore();
for (int i = 0; i < fCheckBoxes.size(); i++) {
Button button = (Button) fCheckBoxes.get(i);
String key = (String) button.getData(); store.setValue(key, button.getSelection()); }
return super.performOk();
}
생성자에서는 setPreferenceStore() 메서드를 호출하여 preference page에서 사용할 preference 저장소를 지정한다. performOk() 메서드에서는 preference 저장소를 얻어와 여기에 setValue() 메서드를 이용해 <key, value>의쌍으로 환경설정을 저장한다. 저장할 수 있는 값들은 boolean, double, float, int, String, long 등의 simple data type중에 하나이어야 한다. 위의 예제는 플러그인이 UI에 기여하는 경우(Activator 클래스가 AbstractUIPlugin를 상속하는 경우)에 해당하며 그렇지 않은 경우(Plugin 클래스를 상속하는 경우)에는 getPluginPreferences 메서드를 사용해야 한다.
정리하면 생성자에서 preference 저장소를 지정한 후, createContents() 메서드에서 preference page에 들어가는 UI를 작성한다. 그리고 각 버튼에 해당하는 코드를 작성한다. 이는 UI에 입력된 정보를 환경설정에 저장하거나 그 반대의 일이 될 것이다.
지금부터는 환경설정의 기본값(Default)를 지정하기 위한 클래스인 Defaults를 살펴보자. 여기서는 간단히 initializeDefaultPreferences() 메서드에서 setDefault() 메서드를 호출해서 각 key에 해당하는 기본값을 지정하기만 하면 된다.
public void initializeDefaultPreferences() {
// TODO Auto-generated method stub
// get preference store IPreferenceStore store = Activator.getDefault().getPreferenceStore(); store.setDefault(“CDE_ESTEREL_C”, true);
store.setDefault(“CDE_ESTEREL_VERILOG”, true);
store.setDefault(“CDE_ESTEREL_BLIF”, false); }
지금까지 Eclipse plug-in 개발시에 preference를 활용하는 방법을 살펴보았다. 아래 첨부한 소스코드를 읽어보면 쉽게 이해할 수 있을 것이다. 예제코드에서 UI 부분은 JDT의 JavaBasePreferencePage 클래스의 것을 응용하였다.
Visitor 패턴은 AST(Abstract Syntax Tree)와 같은 자료구조를 순회하면서 필요한 작업을 정의하기에 용이하다. 이를 처음으로 접하게 된 것은 CEC(Comlumbia Esterel Compiler)의 소스코드를 분석할때였다. CEC는 Esterel 소스코드를 파싱하여 이를 XML 형태의 IR(Intermediate Representation)로 저장한다. CEC는 C++ 언어로 프로그램되어 있는데 XML 형태의 IR은 C++의 클래스 구조로 구성된 AST에 대응된다.
배경은 이쯤에서 정리하고 본론으로 들어가보자. Esterel 언어는 하드웨어 언어인 Verilog로 컴파일되기도 하고 소프트웨어 언어인 C로 컴파일 되기도 하는 신기한(?)언어인데, Esterel 소스코드로 부터 C언어 코드가 나오기까지 IR을 XML 포맷으로 유지하며 여러단계의 독립적인 프로그램을 거치게 된다. 이때마다 XML 파일을 읽어 AST를 구축한 후 Visitor 패턴을 이용해 AST를 순회하며 필요한 작업을 수행한다. 물론 그러한 작업에 의해 AST가 수정되면 수정된 상태의 AST가 다시 XML형태로 저장된다.
Esterel Source Code – Parser – Expander – Dismantler – GRC synthesizer – C generator – C Source code
필자가 하고 있는 일은 동시설계 개발환경에서 Esterel 언어를 기반으로 임베디드 시스템을 정의하는 방법론을 제시하고 그 것으로 부터 임베디드 시스템 구현에 필요한 여러가지 인터페이스를 자동으로 생성하는 것이다. 임베디드 시스템을 XML 형태의 언어로 정의하도록 하고 이를 파싱하여 저장하는 나름의(?) AST를 자바 클래스로 구축하였다. 인터페이스 생성등 다양한 작업이 AST를 기반으로 이루어질 것 이며, 여기서는 AST에 저장되어 있는 정보를 다시 XML로 출력하는 프로그램을 예로 들어 Visitor 패턴을 설명하려고 한다.
모든 AST의 클래스들은 다음과 같은 AbstractSpec 추상클래스를 상속한다. 여기에는 Visitor 패턴을 위한 메서드인 welcome 추상 메서드가 정의되어 있다.
package kr.ac.kaist.vicode.spec;
public abstract class AbstractSpec {
public abstract void welcome(Visitor v);
}
그리고 당연히 모든 AST 노드에 해당하는 클래스들은 welcome 메서드를 정의해야 하는데 그 내용은 모두 다음과 같이 동일하다. 굳이 설명하자면 파라메터로 넘어온 visitor를 이용해서 자기 자신에 해당하는 visit 메서드를 호출하게 하는 것 이다.
public void welcome(Visitor v)
{
v.visit(this);
}
다음으로 해야할 일은 Visitor 클래스를 생성하는 것이다. Visitor 패턴을 이용하는 클래스는 이 클래스를 상속받아서 visit 메서드를 구현하기만 하면 된다. 즉 파라메터로 입력받은 AST 노드에 해당하는 작업을 visit 메서드에 정의하면 된다.
package kr.ac.kaist.vicode.spec;
public abstract class Visitor {
public abstract void visit(Spec n);
public abstract void visit(Communication n);
public abstract void visit(Api n);
public abstract void visit(Rule n);
public abstract void visit(DataFunc n);
public abstract void visit(SignalFunc n);
public abstract void visit(SignalDecl n);
public abstract void visit(State n);
public abstract void visit(Transition n);
public abstract void visit(Set n);
}
Visitor 패턴을 사용하기 위한 준비작업은 모두 끝이 났다. 지금부터는 AST에 저장되어 있는 정보를 Visitor 패턴을 이용하여 AST를 순회하면서 XML형태로 출력하는 예제를 살펴본다. Spec2Xml 클래스는 Vistor 클래스를 상속하여 Visitor 패턴을 구현하고 있다. 각 visit 매서드에서 하는 일은 크게 두가지다. 하나는 해당 노드에 해당하는 작업을 수행하는 것이고, 나머지 하나는 자식 노드를 방문하게 하는 일인데 이과정을 위해서 단순히 각 AST 노드의 welcome 메서드를 호출하는 print 메서드를 정의하였다.
Vistor 패턴의 시작은 간단하다. AST의 최상위 노드에 대해서 print 메서드를 호출하면 자신의 자식노드에 대해서 visit 메서드를 호출하게 되고 이러한 일련의 과정을 통해 경우에 따라서 모든 노드를 방문하며 특정 작업을 수행할 수 있다. 위의 예제에서 Spec은 AST의 최상위 노드에 해당하며 이는 3가지 자식노드 (communication, api, rule)을 가지고 있으며 각각에 대해서 visit 메서드가 호출되도록 한다.
지금까지 살펴본 것 처럼 Visitor 패턴은 AST와 유사한 자료구조를 빠짐없이 탐색하며 특정작업을 수행하기에 적합한 방법론을 제공한다. 특히 컴파일러나 인터프리터와 같이 AST를 사용하는 프로그램에서 잘 활용하면 유지보수가 용이하고 코드가 깔끔한 코드를 작성하는데 큰 도움이 될 것 같다.
이번 주말 서울에 다녀오면서 읽었던 책. 토요일 외출에서 돌아오는 길 지하철에서, 대전행 새마을 열차에서 대부분을 읽고 학교로 돌아오는 버스에서 비로소 책의 마지막 장을 넘길 수 있었다. 시골의사의 아름다운 동행 : 첫번째 이야기는 주로 저자가 운영하는 병원에서 겪었던 이야기를 바탕으로 하고 있는 반면에 두번째 이야기는 이야기를 나열했다기 보다는 어떤 경험으로부터 얻을 수 있는 삶의 교훈을 초점으로 책이 엮어졌다는 생각이 들었다.
의술을 펼치면서 삶과 죽음의 경계에서 저자가 느꼈던 혼란을 털어놓기도 하고, 나병환자를 대하는 자신의 솔직한 느낌과 부끄러웠던 기억을 있는 그대로 책에 옮겨놓았다. 책의 표지에 써있는 “죽도록 사람답게 살아가는 법을 알아가며” 라는 말이 정말로 어울리는 삶의 이야기와 그의 생각이 담겨있다. 특히 나는 평생에 걸쳐 모진 시련을 겪고도 남을 돕는 일에서 삶의 행복을 느끼는 한 할머니의 이야기가 가장 감동적이였다.
정작 행복하면서도 행복을 느끼지 못하는 우리가 상상조차 할 수 없는 아픔과 시련을 겪는 많은 사람들의 이야기를 접하며 그러한 일들이 반드시 남의 이야기가 아니라는 생각을 하게 되었다. 내가 사랑하는 사람이 혹은 나 자신이 언젠가 사고를 당하거나 큰병에 걸려 병상에 눕게 될지 모르는 일이기 때문이다. 요근래 읽는 책들에서 주는 교훈은 한결같다. 바로 여기 지금에 살아라!
이번 이야기들은 ‘자신’의 입장에서 쓴 기록이 많다.
그래서 때로는 이야기들이 느슨하거나 다소 감정적으로 흐를 때가 있다.
하지만 나는 정말 내 삶의 일부인 그들의 이야기가 하고 싶었다.