─━ IT ━─

자바와 SAX 파서로 XML 기반의 프로그래밍 언어를 만들다

DKel 2021. 8. 16. 01:12
반응형
처음에 프로그래밍 언어를 만들어 보고 싶은 생각은 없었나요? 아니면 어떻게 단순한 텍스트 파일에 불과한 소스 파일을 프로그램으로 실행할 수 있는지 구조를 알고 싶다고 느낀 적은 없나요? 구조를 알기 위해서는 실제로 만들어 보는 것이 가장 좋습니다.결국 어느 쪽이든 프로그래밍 언어를 만들게 되겠군요.그런데 만일 그렇게 생각했다고 해서, 프로그래밍 언어에 대한 책을 집어들면 끝없이 자구 해석(소스 파일중의 문자열을 정수나 연산자등의 분해하는 것)에 대해 설명하고 있으므로 모처럼 솟은 흥미가 순식간에 사라져 버리는, 그런 경험은 없습니까.물론, 「진짜」의 프로그래밍 언어를 만들려면 거기서 더욱 열의가 생길 필요가 있지요.근데 단순히 관심만 있는 거라면 더 쉽게 갑자기 프로그래밍 언어 자체를 만드는 게 좋잖아요.따라서 자구해석과 구문해석(자구해석의 결과로부터 문의 구성을 조사하는 것)없이 갑자기 프로그래밍 언어를 프로그램 해 봅시다.이러한 해석 처리는 인간이 소스 파일을 기술하는 시점에서 끝난 것으로 해 버리면 되기 때문입니다.구체적으로는 프로그래밍 언어의 소스 파일을 XML 로 기술하고 SAX 파서로부터 요소나 문자를 읽은 시점에서 직접 구문해석목을 작성합니다.그 결과, 바로 실행 가능한 프로그래밍 언어를 구현할 수 있습니다.대상 독자 여기에서는 구현 언어로서 Java 를 이용합니다.이 기사의 프로그램은 Java에 의한 이하의 구현기술의 실례로 구성되어 있습니다.SAX 파서를 직접 이용하여 프로그램 고유의 객체 구조(여기서는 Interpreter 패턴 인스턴스)를 생성합니다.기사에서 해설을 조금 시도하지만 Interpreter 패턴은 물론 Strategy 패턴, Factoy Method 패턴, Abstract Factory 패턴, Singleton 패턴, Builder 패턴 등의 구현 예시로도 참조할 수 있습니다.필요한 환경 J2SE 1.4 이상을 상정합니다.샘플은 javac에 -source 1.4를 옵션지정하고 컴파일한 것을 1.5.0상에서 실행하고 동작확인을 하고 있습니다.ant 1.6 이상 또는 NetBeans 4.0 이상
소스 파일이 여러 개로 나누어져 있기 때문에 ant의 빌드 스크립트를 준비하고 있습니다.일괄적으로 빌드하기 위해서는 ant 자체나 ant 스크립트를 프로젝트에서 직접 다룰 수 있는 NetBeans 4.0 이상을 이용하는 것이 좋습니다.
JUnit 3 . 8 . 1
소스 파일안에 테스트 프로그램을 준비해 두었습니다.실제로 테스트 프로그램을 빌드해 움직이려면 junit 가 필요합니다.우리가 목표한 대로 프로그래밍 언어이기 때문에 변수, 대입, 제어구문으로 if-then-else와 while을 구현을 하셔야 됩니다.또한 자바에서 개발하기 때문에 자바 객체도 이용할 수 있는 것이 좋습니다.나중에는 프로그래밍 언어 자신의 디버깅을 위해서라도 콘솔 출력 기능은 준비해야 합니다.이상으로부터 우선, 다음의 Java의 프로그램에 상당하는 처리를 실행 가능한 프로그래밍 언어의 실장을 목표로 합니다.구현의 목표로 하는 프로그램
public class Sample {
public static void main ( String [ ] args ) {
if ( args . length == 0) {
System . out . println ( ′ no args ′ ) ;
} else {
int i = 0;
while ( args . length > i ) {
System . out . println ( args [ i ] ) ;
i++ ;
}
System . out . println ( ′ done ′ ) ;
}
}
}어떤 언어로 할지 디자인하는 것은 본래 가장 재미있는 부분 중 하나이지만, 여기에서는 구현 방법을 보여주는 것이 목적이므로 가능한 한 간단하게 하겠습니다.또, 세세한 것은 결정하지 않고, 어쨌든 실장 범위를 편하게 실장하는 것을 우선합시다.우선 여기에서는 다음 XML(sample.xml)을 실제 소스 파일로 상정합니다.sample . xml
< ? xml version = ′ 1 . 0 ′ encoding = ′ shift _ jis ′ ? >
< oreprog >
< if >
< condition type = ′ eq ′ >
< call name = ′ args ′ method = ′ size ′ / > < value type = ′ int ′ value = ′ 0 ′ / >
< / condition >
< block >
< value type = ′ string ′ value = ′ no args ′ / > < / print >
< / block >
< block >
< var type = ′ int ′ name = ′ i ′ value = ′ 0 ′ / >
< while >
< condition type = ′ gt ′ >
< call name = ′ args ′ method = ′ size ′ / > < value name = ′ i ′ / >
< / condition >
< block >
< call name = ′ args ′ method = ′ get ′ > < value name = ′ i ′ / >
< / call > < / print >
< var type = ′ int ′ name = ′ i ′ >
< value name = ′ i ′ / > < value type = ′ int ′ value = ′ 1 ′ / > < / add >
< / var >
< / block >
< / while >
< value type = ′ string ′ value = ′ done ′ / > < / print >
< / block >
< / if >
XML 의 요소명을 제어구문이나 연산자로서 대응시키고 있는 것이 목표의 프로그램과 읽어 비교하면 이해할 수 있다고 생각합니다.요소명과 구문목의 노드를 직접 대응시킴으로써 XML 읽기와 동시에 구문목을 생성할 수 있도록 한 것이군요.덧붙여 본기사에서는 이후, 여기서 작성하는 프로그래밍 언어를 루트 요소명으로부터 「oreprog(올레프로그)」라고 부르기로 하겠습니다.파일 구성 다운로드 받은 파일은 zip으로 압축되어 있습니다.전개하면 「intp」라고 하는 디렉토리를 정점으로 한 디렉토리 계층이 생깁니다.즉시 실행할 수 있도록 컴파일이 끝난 클래스 파일도 첨부되어 있습니다.소스파일은 모두 시프트 JIS로 인코딩하였습니다.ant의 빌드스크립트 입니다.프로그램 본체입니다.파일 수를 억제하기 위해 작은 클래스는 static 내부 클래스로서 실장하고 있으므로, 본 기사에서는 주로 이 소스 파일에 대해 해설합니다.직선수(value 요소 지원) 처리 클래스입니다.리플렉션을 이용하여 문자열에서 개체를 생성합니다.지원하는 것은 int, long, String(xml에 기술할 때는 string과 소문자가 됩니다), 컨스트럭터의 인수에 하나의 String을 취하는 오브젝트의 생성입니다.변수(var요소 지원) 처리 클래스입니다.ValueExpression.java를 상속받았습니다.오브젝트의 메서드 호출(call 요소 지원) 처리 클래스입니다.리플렉션을 이용하여 주어진 객체의 메서드를 호출합니다.프로그램을 짧게 하기 위해서, 메소드의 검색에 대해서는 매우 한정된 기능 밖에 실장하고 있지 않습니다.조건 판단(condition 요소에 대응) 처리 클래스입니다.OreProg.java를 상속받아 oreprog에 독자적인 언어 확장을 구현하는 샘플 프로그램입니다.원래의 Ore Prog에 손을 넣지 않고, 새로운 구문요소로서 int형의 정수를 도입하고 있습니다.sample.xml 입니다.필자가 테스트에 이용한 xml 입니다.ExProg 테스트에 이용한 xml 입니다. JUnit을 이용한 테스트 프로그램입니다.value, var, call, if, condition, block, while 요소를 테스트합니다.빌드 후의 클래스 파일을 격납해 두었습니다.ant의 디폴트 타깃은 이 디렉토리에 클래스를 생성합니다.샘플 실행 명령줄에서 zip을 펼친 디렉토리(intp)에 들어가서 set CLASSPATH= [펼친 디렉토리 이름] intpuildclasses;% CLASSPATH%
java com.example.prog.OreProg test/sample.xml [인수...]로 입력하면 실행할 수 있습니다.덧붙여 CLASSPATH 환경 변수의 설정은 이용의 환경에 맞추어 조정해 주세요.다음은 Mac OS X에서의 실행 예시입니다.$ cd / var / tmp / intp
$ export CLASSPATH = / var / tmp / intp / build / classes : $ CLASSPATH
$ java com . example . prog . OreProg test / sample . xml
no args
$ java com . example . prog . OreProg test / sample . xml a b c
a
b
c
done인수로 부여한 문자열이 순차적으로 프린트되며 마지막에 done으로 출력되는 것을 확인할 수 있습니다.덧붙여 J2SE 1.4.2 로 실행하는 경우(J2SE 1.4.2_08 으로 확인)는 이하와 같이 -D옵션을 사용해 SAX 파서의 지정이 필요합니다.$ java - Dorg . xml . sax . driver = org . apache . crimson . parser . XMLReaderImpl
com . example . prog . OreProg test / sample . xml a b c 指定 しない 場合 、 Exception in thread ′ main ′ org . xml . sax . SAXException :
System property org.xml.sax.driver not specified라는 예외가 됩니다.
반응형