Neoteny

반응형

무선 인터넷 프로토콜, WAP 3
WML과 WMLScript
이번 호에는 WAP에서 사용되는 언어인 WML과 WML 스크립트(WMLS)에 대해서 알아 볼 것이다. WML은 HTML을 연상하면 되고 WML 스크립트는 보통 웹에서 사용되는 자바 스크립트 같은 것들을 연상하면 될 것이다. 실제로도 유사한 부분들이 매우 많으므로 그리 낯설지는 않을 것이다.
이제는 독자 모두 WAP이라는 단어에 대해서 낯설지 않을 것이라 생각된다. 처음 WAP이라는 주제로 기사를 연재하기 시작했을 때만 해도 WAP은 특별히 그 분야에 종사하고 있는 사람이거나 관심이 있는 사람이 아니라면 그렇게 익숙한 단어는 아니었다. 하지만 이제는 우리 나라의 무선 통신 업계가 하나 둘 WAP을 구현해서 사용하고 있는 시점에 이르렀다. 실제 WAP을 통해서 우리가 그동안 인터넷을 통해서만 할 수 있었던 여러 작업들을 할 수 있게 되었다는 것은 대단한 기술적 변화가 아닐 수 없다(물론, 앞으로 IMT-2000이 상용화 되었을 경우에는 말할 것도 없다).
무선 통신 시장은 매우 빠르게 성장하고 있으며 새로운 고객과 서비스에 접근하고 있다. WAP은 운영자와 공급자가 진보된 서비스와 차별화되고 유동적인 서비스를 창조하기 위해 트랜스포트, 세션, 애플리케이션 레이어 프로토콜 등을 제공한다. WAP 구조에 대한 부가적인 정보를 원한다면 Wireless Application Protocol 아키텍쳐 스펙을 참조하기 바란다. 먼저 WML에 대해서 알아보도록 하자.

WML
WML은 대역폭이 좁은 디바이스에 적합하도록 설계되었다. 작은 디스플레이와 제한된 사용자 입력 장치, 좁은 대역폭의 네트워크 연결, 제한된 메모리와 컴퓨터 자원 등이 제한 요소로 작용한다. 이를 위해 WML은 다음의 주요 기능을 포함하고 있다.

·텍스트 표현과 레이아웃 - WML 은 다양한 포맷과 레이아웃을 포함한 텍스트와 이미지를 지원한다.
·덱/카드 - WML에서 모든 정보는 카드와 덱의 집합으로 구성되어 있다. 카드는 사용자와 상호 작용할 수 있는 것을 하나 이상 정의한다. 예를 들면, 선택 메뉴, 텍스트 입력 필드 등이 있다. 사용자는 일련의 WML 카드를 통해서 볼 수 있고, 각 컨텐트를 알 수 있으며, 요청된 정보에 들어가 선택을 하고 다른 카드로 이동한다. 카드는 덱으로 그룹화 되어 있고 WML 덱은 HTML에서 URL에 의해 개체화 되는 컨텐트 이동 단위인 페이지와 유사하다.
·카드 사이의 연결 - WML은 카드와 덱을 관리하고 디바이스에서의 이벤트 핸들링을 수행한다. 디바이스에서 이벤트 핸들링은 스크립트를 실행하고 이동하는데 사용된다. WML은 또한 HTML4에서 사용하는 것과 유사한 링크를 지원하고 있다.
·스트링 전달과 스테이트 관리 - 모든 WML 덱은 스테이트 모델을 사용해서 전달될 수 있다. 변수는 스트링을 대신해서 사용될 수 있고 런타임에 변환된다. 이런 전달은 네트워크 자원을 보다 효율적으로 사용할 수 있도록 한다.
 
WML과 URL
월드 와이드 웹은 디바이스와 정보의 네트워크이다. 다음 세 가지 영역에서 폭 넓은 상호 작용을 보장한다.

·일관된 네이밍 모델. 네이밍은 URL로 구현된다. URL은 네트워크 자원을 지명하는 표준적인 방법으로 제공되고 있다.
·정보 이동을 위한 표준 프로토콜(예, HTTP)
·표준 컨텐트 타입(예, HTML, WML)

WML은 월드 와이드 웹에서 사용하는 HTML과 동일한 참조 구조를 사용한다고 가정한다. 컨텐트는 URL을 사용하여 명명되고 WSP처럼 HTTP 세만틱을 갖는 표준 프로토콜을 사용하여 패치된다. URL은 RFC2396에 정의되어 있다. URL을 정의하기 위해서 사용되는 캐릭터 셋도 그곳에 정의되어 있다. WML에서 URL은 다음의 상황에서 사용된다.

·이동, 예를 들면 하이퍼링크 등을 사용하려고 하는 경우
·외부 자원, 예를 들면 이미지나 스크립트를 사용하려고 할 경우

WML 브라우저는 반드시 WAE에 정의된 URL 스킴을 구현해야만 하고 WML 프라그먼트 앵커는 우물 정(#)표시 다음에 오는 URL 다큐먼트에 의해서 정의된다. 이 프라그먼트 앵커는 WML 덱 내에서 각각의 WML 카드를 구별하기 위해 사용된다. 만약 프라그먼트가 정의되지 않았다면 URL은 모든 덱에서 지정될 수 없다. 또한 어떤 컨텐트에서 덱 URL은 덱의 첫 번째 카드에 정의되어 있다. 그 URL을 사용하는데 있어서 RFC2396에 정의된 것처럼 상대적 URL을 사용할 수도 있다. RFC2396에서는 WML 덱의 컨텐트에서 상대적인 URL 주소를 해석할 수 있도록 하고 있다. WML 덱의 기본 URL은 덱에 정의되어 있는 URL이 된다.

캐릭터 셋
WML은 XML 언어이고 XML 다큐먼트 캐릭터 셋을 그대로 가져다 사용하고 있다. SGML 구조에서 다큐먼트 캐릭터 셋은 모든 논리적 캐릭터들의 집합이다. SGML이나 XML 다큐먼트는 단순히 정수 토큰들의 연속이다. 이 정수 토큰은 다큐먼트를 형성하는데 사용된다.
XML과 WML에서 다큐먼트 캐릭터 셋은 ISO/IEC-10646의 유니버셜 캐릭터 셋이다. 현재 이 캐릭터 셋은 유니코드 2.0에서 개체화되고 있다. WML은 XML과 ISO10646에서의 발전과 앞으로의 변화에 모두 적용될 것이다. 이 다큐먼트에서 ISO10646이라는 용어와 유니코드라는 용어는 동일한 도큐먼트 캐릭터 셋을 나타내고 서로 동일하게 사용된다.
WML덱이 완전한 유니코드 인코딩을 사용하는데 필요한 요구 사항들은 없다. 유니코드에서는 캐릭터의 적당한 부분을 포함하는 어떤 캐릭터 인코딩도 사용될 수 있을 것이다. 예를 들면 US-ASCII나 ISO-8859-1, UTF-8같은 것들이 있다. UTF-8이나 UTF-16에서 사용하여 인코딩되지 않은 다큐먼트는 XML 스펙에서 정의된 것으로 인코딩되며 컨텐트 타입, 메타 정보를 포함해야 한다.
WML 다큐먼트는 HTML4에서 정의된 캐릭터 인코딩을 사용하여 인코드된다. WML 다큐먼트의 캐릭터 인코딩은 사용자 에이전트 특성에 적합한 인코딩으로 전환될 수 있다. 그러나 이와 같이 전환된 코딩은 정보의 손실을 초래할 수도 있으므로 다큐먼트의 인코딩을 지원하는 것은 피해야 할 사항이다. 만약 이러한 전환 코딩이 요구된다면 다큐먼트가 사용자 에이전트로 이동되기 전에 이루어져야 한다.
WML은 XML 애플리케이션이므로 XML 다큐먼트의 캐릭터 인코딩은 XML 스펙에 정의된 대로 결정된다. 보통의 경우 항상 다큐먼트의 캐릭터 인코딩을 검사하는 것이 가능하다. 만약 다큐먼트에서 표현되지 않는다면 메타 http 구문은 캐릭터 인코딩을 결정하는데 결코 사용되지 않는다.
WML 다큐먼트가 XML과 다른 형식으로 이동된다면(예를 들면 이진 WBXML 형식으로) 그 형식에 적절한 규칙이 캐릭터 인코딩을 결정하는 데 사용된다. WML 다큐먼트가 외부 정보에 의해서 수행될 때 캐릭터 인코딩을 결정하기 위해서 가능한 정보의 다중 소스가 존재할 것이다. 이 경우에는 관련된 프라이어티와의 충돌을 핸들링하는 알맞은 방법이 상위 수준 프로토콜로 특정화 된다.
WML 참조 프로세싱 모델은 다음과 같다. 사용자 에이전트는 이 프로세싱 모델 혹은 이와 차별되지 않는 모델로 구현되어야만 한다.

· 사용자 에이전트는 캐릭터 인코딩을 인지하고 수행하기 위해 모든 캐릭터를 유니 코드로 맵핑한다.
· 개체의 어떤 처리도 다큐먼트 캐릭터 셋에서 수행된다.

주어진 캐릭터 인코딩은 다큐먼트 캐릭터 셋의 모든 캐릭터를 표현하는 것이 가능하지 않을 수도 있다. 이와 같은 인코딩 혹은 디바이스 캐릭터에서 사용자가 직접적으로 어떤 다큐먼트 캐릭터 입력을 허용하지 않을 때, 제작자와 사용자는 캐릭터 개체를 사용하게 된다. 즉 캐릭터 개체는 다큐먼트 캐릭터 셋으로부터 어떤 캐릭터를 진입시키기 위한 캐릭터 인코딩에 독립적인 메카니즘이다.
참조 프로세싱 모델의 중요한 점은 모든 숫자 캐릭터 개체가 다큐먼트 캐릭터 셋(유니코드)에 대해서 참조되고 현재 다큐먼트 인코딩(charset)에 대해서는 그렇지 않다는 것이다. 이것은 Į이 현재 캐릭터 인코딩과는 독립적으로 항상 같은 논리적 캐릭터를 참조하는 것을 말한다.
WML은 캐릭터 개체 형식을 다음과 같이 지원한다.

· ‘&’ 혹은 ‘&lt’와 같은 지명된 캐릭터 개체
· ‘ ’와 같은 십진수 캐릭터 개체
· ‘ ’와 같은 16진수 캐릭터 개체

다음의 7가지 캐릭터 개체가 WML의 처리에 있어서 특별히 중요한 것들이다.

<!ENTITY qout “&#34;”> <!-- 쿼테이션 마크-->
<!ENTITY amp “&#38;#38;”> <!-- 엠퍼샌드-->
<!ENTITY apos “&#39;”> <!-- 어퍼스트로프-->
<!ENTITY lt “&#38;#60;”> <!-- 보다 적은(less then)-->
<!ENTITY gt “&#62;”> <!-- 보다 큰(greater then)-->
<!ENTITY nbsp “&#160;”> <!non breaking 스페이스-->
<!ENTITY ahy “&#173;”> <!소프트 하이픈-->

WML 구문
WML은 XML로부터 대부분의 구문 구조를 가져왔다. 그러므로 XML을 알고 있는 사람들은 따로 시간을 투자하여 WML을 공부할 필요가 없을 것이다. 물론 XML을 모르고 지내던 사람들일지라도 너무나 간단하고 쉽게 되어 있기 때문에 금방 익힐 수 있을 것이다.

① 개체
WML 텍스트는 숫자 혹은 지시된 캐릭터 개체를 포함할 수 있다. 이런 개체들은 다큐먼트 캐릭터 셋에서 특정 캐릭터를 정의한다. 개체는 WML에서 빠져 나와야 하거나 텍스트 에디터에 진입하기 어려울 수도 있는 다큐먼트 캐릭터 셋에서 캐릭터를 정의하는데 사용된다. 예를 들어 엠퍼센드(&)는 ‘&amp;’으로 지시된 개체에 의해서 표현될 수 있다. 모든 개체는 위에서 볼 수 있었던 것과 같이 엠퍼센트로 시작해서 세미콜론으로 끝을 맺는다.

② 요소
요소들은 WML 덱에 대한 구조적인 정보와 모든 마크업을 정의한다. 요소는 시작 태그와 내용, 그리고 종료 태그로 되어 있다. 요소는 다음의 두 구조 중 하나를 사용한다.

  <tag> 내용 </tag> 혹은 <tag/>

내용을 포함한 요소는 시작 태그와 종료 태그에 의해서 정의되고 공백 요소는 내용이 없는 <tag/>를 사용한다.

③ 속성
WML 속성은 요소에 대한 부가적인 정보를 정의한다. 항상 요소의 시작 태그에서 정의된다. 예는 다음과 같다.

 <tag attr=”abcd”/>

속성 이름은 WML NAME이고 대문자와 소문자를 구별한다. WML은 모든 속성 값이 쌍따옴표나 홑따옴표를 사용해야 한다. 홑따옴표는 값이 쌍따옴표에 의해서 정의될 때 속성 값으로 포함될 수 있고 그 반대의 경우도 가능하다.

④ 주석
WML은 XML 주석 스타일을 따른다. 앞에서 캐릭터 개체의 예를 보여주면서 사용되었던 것과 같은 형식으로 <!-- 주석 -->을 사용한다. 주석은 WML 제작자에 의해서 사용되고 사용자 에이전트에서는 나타나지 않는다. WML 주석은 네스트 될 수 없다.

⑤ 변수
WML 카드와 덱은 변수를 사용해서 전달될 수 있다. 카드 혹은 덱으로 변수를 전달하기 위해서 다음에 오는 구문을 사용한다.

 $identifier
 $(identifier)
 $(identifier:conversion)
공백문자가 변수의 끝에 나타나지 않을 때 괄호를 사용한다. 변수는 WML에서 우선 순위가 가장 높고, 구문 중 어느 곳에서든지 사용될 수 있다. ‘$’ 캐릭터는 변수의 기초를 나타낸다.

⑥ 대소문자 구별
XML은 대소문자를 구별하는 언어이다. XML에서 구문 구조를 가져온 WML 역시 이 특성을 갖고 있다. 이 특성은 WML 덱을 파싱할 때 수행되며 모든 WML 태그와 속성이 대소문자를 가려야 한다는 것을 의미한다. 덧붙여서 열거된 속성 값도 대소문자를 구별한다. 

이벤트와 이동
WML은 이동과 이벤트 핸들링 모델을 포함한다. 연관된 요소는 제작자가 사용자 에이전트 이벤트의 처리를 정의하도록 한다. 이벤트는 제작자에 의해서 태스크에 바운드될 것이다. 이벤트가 발생했을 때 바운드 태스크가 실행된다. 이를 통해 제작자가 정의한 URL로 이동하는 것과 같이 다양한 태스크가 정의된다. 이벤트 바인딩은 do와 onevent와 같은 몇몇 요소들에 의해서 선언된다.
WML은 제작자가 편리하고 효과적인 방법으로 되돌아가기를 관리하도록 하는 간단한 이동 히스토리 모델을 포함한다. 이것은 사용자 에이전트 히스토리가 현재 카드에 도착하기 위해 거쳐온 이동 패스를 갖는 URL 스택으로 모델링되어 있다. 다음과 같은 세가지 연산이 히스토리 스택에서 수행될 수 있다.

· 리셋 - 히스토리 스택은 현재 카드를 포함하고 있는 장소에서 리셋된다.
· 푸시 - 새로운 URL이 새로운 카드에 이동하면서 히스토리 스택에 푸시된다.
· 팝 - 현재 카드의 URL은 반대로 이동하기 위해 되돌려진다.

사용자 에이전트는 이동 히스토리를 구현해야 한다. 각 카드가(예를 들면, go 요소 내의 href 속성을 통해서) 극명하게 특정 URL을 통해 접근되므로, 카드로의 진입은 대부분의 최근 등록에 대해 개별적이라 할지라도 히스토리 스택에 덧붙여져야 한다. 최소한 각 등록은 카드의 절대적 URL을 저장해야만 한다. get이나 post와 같은 메쏘드로 포스트필드의 값, 요청 헤더, 카드에 접근하는데 사용된다. 히스토리 데이터에서 어떠한 변수의 참조는 등록이 스택에 첨가되기 전에 변수의 현재 값으로 교체되어야 한다.
사용자 에이전트는 prev 태스크가 실행되면 히스토리에서 이전 카드로 사용자가 되돌아가야 한다. prev 실행은 prev 태스크가 실행될 때 히스토리 스택으로부터 현재 카드 URL을 꺼낸다.

스테이트 모델
WML은 사용자 에이전트 스테이트를 관리한다. 그 내용는 다음과 같다.

· 변수 - WML 카드 혹은 덱의 내용과 특성을 변화시키기 위해 사용되는 매개변수
· 히스토리 - 이동 히스토리. 이것은 효과적인 거꾸로 이동을 가능하게 하는데 사용된다.
· 구현에 의존적인 스테이트 - 사용자 에이전트 구현과 행동에 연관된 다른 스테이트들

리스트 1 : WML의 사용 예
<wml>
   <card>
     <p>
     <do type=“accept”>
       <go href=“#card2”/>
     </do>
     Hello world!
     This is the first card...
     </p>
   </card>

   <card id=“card2”>
      <p>
      This is the second card.
      Goodbye.
      </P>
   </card>
</wml>

WML 덱의 구조
WML 데이터는 카드의 집합으로 구성된다. 카드의 단일 집합은 WML 덱으로 참조된다. 각 카드는 컨텐트와 이동 스펙을 포함하며 사용자는 일련의 카드를 통해서 이동하고 각 내용에 접근하며 요청된 정보로 진입한다. 또한 다른 카드를 선택하고 이동하거나 혹은 이전에 접근했던 카드에 되돌아갈 수도 있다.
이제 간단한 WML 예를 통해서 WML에 대해서 알아보자.
리스트 1은 두 개의 카드를 갖고 있는 하나의 덱을 구현한 것이다. 카드는 카드 요소에 의해서 표현된다. 덱이 로딩된 후에 사용자 에이전트는 첫 번째 카드를 보여줄 것이다. 사용자가 DO 요소를 활성화시킨다면 사용자 에이전트는 두 번째 카드를 보여줄 것이다.
head 요소는 메타-데이터와 접근 제어 요소를 포함해서 전반적으로 덱에 연관된 정보를 포함한다. access 요소는 덱 전체의 접근 제어 정보를 나타낸다. 하나 이상의 access 요소를 포함한 덱은 에러를 발생시킨다. 덱이 access 요소를 포함하지 않으면 접근 제어는 사용할 수 없게 될 것이다. 접근 제어가 사용할 수 없게 되면 어떤 덱에 있는 카드도 이 덱에 접근할 수 없다. meta 요소는 WML 덱에 연관된 메타-정보를 포함한다. 메타-정보는 적절한 이름과 값을 정의한다.
template 요소는 덱에서 카드를 위한 템플릿을 선언한다. template 요소에서 정의된 이벤트 바인딩은 덱에 있는 모든 카드에 적용된다. template 요소에 있는 이벤트 바인딩 정의는 모든 카드 요소에서 정의되는 것과 동일하다. 카드 요소는 template 요소에 정의된 수행을 덮어씌울 것이다. 특히 다음을 기억해둘 필요가 있다.

· template 요소에 정의된 DO요소는 두 개의 요소가 동일한 NAME 속성 값을 갖는다면  개별적으로 카드에 오버라이드될 것이다.
· template 요소에서 정의된 고유 이벤트 바인딩은 카드 요소의 이벤트 바인딩의 정의에 의해 오버라이드될 것이다.

WML 덱은 카드의 집합이다. 각 카드는 다양한 컨텐트를 포함할 수 있다. 카드와 함께 사용자 상호 작용의 컨텐트는 사용자 에이전트에 의해 표현된 방법과 카드가 갖고 있는 컨텐트 타입에 의존적이다.

사용자 에이전트
WML에 변수를 나타내는 것은 HTML과 같은 다른 마크업 언어에 존재하지 않는 잠재적인 보안 문제를 노출시킨다. 특히, 특정 변수 스테이트는 사용자에 의해 사적인 용도로 사용될 가능성이 있다. 사용자는 보안 서비스에 사적인 정보를 전송하는 동안 보안이 안된 서비스는 다른 방법으로 사용자 에이전트로부터 그 정보를 탐색할 수 없어야 한다.
우리는 지금까지 WML에 대해 살펴보았다. 필자가 처음 HTML을 접했을 때 간단한 태그 몇 가지로 웹에 다양하게 뿌려지는 것을 보고 매우 흥미있었던 기억이 있다. WML을 접했을 때도 마찬가지였다. 필자는 단말기 업체로 유명한 노키아와 에릭슨에서 제작한 WAP 시뮬레이터로 WML을 만들어서 화면에 디스플레이되는 모습까지 보았었다. 독자들도 접할 기회가 된다면 그러한 시뮬레이터로 직접 구동을 해 보는 것이 WML을 이해하는데 훨씬 빠르고 효과적으로 익힐 수 있을 것이다.
지금까지 WML에 대해서 알아보았으니 WMLS에 대해 알아보도록 하자.

WMLS
WML 스크립트 언어는 WAP 애플리케이션 레이어 부분이므로 클라이언트 쪽의 순차적인 로직에 첨가되어 사용될 수 있다. 이것은 ECMA 스크립트 [ECMA262]에 기초하고 있지만 낮은 대역폭에서 씬 클라이언트와의 통신을 효율적으로 할 수 있도록 지원하고 있다. WML 스크립트는 클라이언트 측에 정보를 공급하기 위해 WML(Wireless Markup Language)과 함께 사용될 수 있으며 독립적인 툴로 사용될 수 있도록 설계되었다.
ECMA 스크립트와 WML 스크립트의 주요 차이점은 WML 스크립트는 정의된 바이트 코드와 인터프리터 참조 구조를 갖는다는 것이다. 오늘날 좁은 밴드 통신 채널로 사용할 수 있는 이 방법이 가장 효율적이며 클라이언트에 요구되는 메모리를 최소화한다. ECMA 스크립트 언어의 진보된 모습은 언어를 더욱 작게, 바이트 코드로 컴파일하기 쉽게, 배우기 쉽게 만들어졌다. 예를 들어 WML 스크립트는 순차적인 언어이고 논리적으로 설치된 표준 라이브러리를 지원한다.
리스트 2는 WML 스크립트에 대한 코드이다. 보통 사용하는 스크립트 코드와 유사하다는 것을 단번에 알 수 있을 것이다.

리스트 2 : WML 스크립트의 예
function count(str)  {
  car result = 0; // Initialized once
  while (str != “”)  {
    var ind = 0; // Initialized every time
    // modify string
  };
  return result
};

function example(param)  {
   var a = 0;
   if (param > a)  {
    var b = a+1; // Variables a and b can be used
   } else  {
     var c = a+2; // Variables a, b and c can ve used
   };
   return a; // Variable a, b and c are accessible
};

왜 스크립팅인가?
WML 스크립트는 WAP 구조에 일반적 스크립팅 능력을 제공하도록 설계되었다. 특히, WML 스크립트는 WML을 보강하기 위해 사용될 수도 있다. WML은 XML(Extensible Markup Language)에 기초한 마크업 언어이다. 이것은 셀룰러 폰과 삐삐처럼 좁은 밴드를 위한 애플리케이션을 정의하기 위해 사용되도록 설계되었다. 이 컨텐트는 텍스트, 이미지, 선택 리스트 등을 구현할 수 있다. 컨텐트를 디스플레이 하는데 사용되는 클라이언트 디바이스를 지원하는 한,  단순한 정의가  사용자 인터페이스를 더 읽기 쉽도록 만드는데 사용될 수 있다. 그러나 이 모든 컨텐트가 스태틱이고 WML 자체를 수정하지 않고 언어를 확장하기 위한 방법은 없다. 다음은 WML에 의해서 지원되지 않는 것들이다.

· 사용자 입력의 정당성을 확인한다.
· 디바이스 설비에 대한 접근. 예를 들면, 폰에서 프로그래머가 전화 호출을 만들고 메시지를 이동하고 전화에 전화부를 추가하고 SIM 카드 접근을 허용하는 것이 있다.
· 메시지와 다이얼로그를 논리적으로 일반화해서 경보와 에러 메시지, 확인 등을 보여주기 위한 고가의 라운드 트립을 위한 요구를 감소한다.
· 디바이스 소프트웨어에 확장을 허용하고 배치된 후에 디바이스 환경을 설정한다.
WML 스크립트는 이러한 제한을 극복하도록 설계되었고 제한된 능력으로 클라이언트에서 좁은 대역폭의 통신 링크에서 사용 가능한 기능성을 제공하도록 설계되었다.

WMLS를 사용하는 이점
씬 모바일 클라이언트로 사용될 수 있는 다수의 서비스는 WML로 구현할 수 있다. 스크립팅은 표준 브라우징과 WML의 구현 능력을 향상시킨다. 이것은 더욱 향상된 UI 기능을 지원하고, 클라이언트에 정보를 첨가하고, 디바이스와 그것의 주변 장치 기능에 접근을 제공하며 서버와 클라이언트 사이에 데이터를 이동하기 위해 사용되는 대역폭의 양을 감소하는데 사용될 수 있다.
WML 스크립트는 ECMA 스크립트 [ECMA262]에 기초한다. 또한 향상된 모바일 서비스를 제공할 수 있도록 개발자들이 새로운 개념을 따로 배울 필요가 없다는 것이 장점이다.

WML 스크립트 핵(core)
WML 스크립트 언어에 대한 목적은 ECMA 스크립트 언어 스펙 [ECMA262] core와 유사하다. 기본 타입과 변수, 익스프레션과 스테이트먼트를 정의하는 ECMA 스크립트 언어 스펙의 부분이 core라고 불려진다. 이것은 거의 WML 스크립트 스펙과 거의 유사하다.

자동 데이터 타입 변환 규칙
경우에 따라 WML 스크립트 연산자는 그들의 피연산자로서 특정 데이타 타입을 요구한다. WML 스크립트는 이러한 연산자의 요구 사항을 수용하기 위해 자동 데이터 타입 전환을 지원한다. 이는 다음에 자세하게 다루도록 하겠다.

① 일반적인 변환 규칙
WML 스크립트는 미약한 타입 언어이고 다양한 선언은 타입을 특이화하지 않는다. 그러나, 내부적으로 언어는 다음과 같은 데이터 타입을 처리한다.

· Boolean : 부울값 참과 거짓을 표현한다.
· Integer : 정수 값을 표현한다.
· Floating-point : 플로팅 포인트 값을 표현한다.
· String : 일련의 캐릭터들로 표현된다.
· Invalid : 단일 값 invalid로 타입을 표현한다.

변수는 특정 시간 동안 위의 타입들 중에 하나를 갖게 된다. WML 스크립트는 typeof라는 연산자를 제공한다. 이 연산자는 변수나 표현식의 현재 타입을 결정하는데 사용된다.
각 WML 스크립트 연산자는 이미 정의된 피연산자 타입의 값의 집합을 수용한다. 제공된 피연산자가 올바른 데이터 타입이 아닐 때는 자동 변환이 발생한다.

② 연산자 데이터 타입 변환 규칙
이전의 변환 규칙은 두 개의 데이터 타입사이에서 가능한 것이다. WML 스크립트 역시 이러한 규칙을 사용한다. 피연산자 데이터 타입과 값이 수행되는 연산을 선택하고 필요한 데이터 타입 변환을 수행한다. 규칙은 다음과 같다.

· 부가적인 변환 규칙은 단계마다 정의된다. 각 단계는 피연산자에 대한 연산과 데이터 타입이 정의되고 반환 값이 정의될 때까지 주어진 순서대로 수행된다.
· 피연산자 값의 타입은 요구된 타입과 알맞으면 그 값이 사용된다.
· 피연산자 값이 요구된 타입과 맞지 않으면 현재 데이타 타입을 요구된 타입으로의 변환이 시도된다.
· 변환 규칙이 피연산자에 정의되어 변환이 수행되면 연산자는 변환된 값으로 수행되고 그 결과가 연산자의 값으로 반환된다.
· 올바른 변환이 하나 이상의 피연산자를 정의하면 변환은 수행되지 않고 부가적인 변환 규칙이 다음 단계에 수행된다.

WML 스크립트 바이트 코드 인터프리터
WML 스크립트 언어의 텍스트 포맷은 WML 스크립트 바이트 코드 인터프리터에 의해 인터프리트되기 전 바이너리 형식으로 컴파일된다. WML 스크립트 컴파일러는 WML 스크립트 컴파일 단위를 WML 스크립트 바이트 코드로 인코딩한다. WML스크립트 컴파일 단위는 프라그마와 몇몇의 WML 스크립트 함수를 포함한 단위이다. WML 스크립트 컴파일러는 입력으로 하나의 컴파일 단위를 취해서 WML 스크립트 바이트 코드를 형성한다.

① 인터프리터의 구조
WML 스크립트 인터프리터는 WML 스크립트 바이트 코드를 입력받아서 함수가 호출될 때 인코드된 함수를 실행시킨다. 그림 1은 WML스크립트 바이트 코드가 인터프리트되는 주요 모습이다.
WML 스크립트 인터프리터는 WML 바이트 코드로 인코드된 컴파일 단위에서 함수를 호출하고 실행할 수 있다. 각 함수는 몇 개의 파라미터와 원하는 동작이 일어나도록 표현된 명령을 정의한다. 따라서 WML 스크립트 함수 호출은 함수와 함수 호출 인자와 함수가 선언된 컴파일 단위를 정의해야만 한다. 완전히 실행되면 WML 스크립트 인터프리터는 호출자에게 제어와 반환 값을 되돌려준다.
WML 스크립트 함수를 실행하기 위해 WML 스크립트 인터프리터는 다음의 스테이트 정보를 유지한다.

· IP(Instruction pointer) : 바이트 코드 내 명령에 대한 포인터
· 변수 : 함수 파라미터와 변수를 유지한다.
· 피연산자 스택 : 호출된 함수에 인자를 전달하고 호출자에게 되돌려준다.
· 함수 호출 스택 : WML 스크립트 함수는 현재 혹은 분리된 컴파일 단위에서 다른 함수를 호출할 수 있고 라이브러리 함수 호출을 만든다. 함수 호출 스택은 함수와 그들의 반환 주소에 대한 정보를 유지한다.

② 캐릭터 셋
WML 스크립트 인터프리터는 스트링 연산에 대한 단지 하나의 캐릭터 셋을 사용해야만 한다. 다른 캐릭터 셋과 인코딩 사이의 전환 코딩은 WML 스크립트 스트링 연산이 오직 자신의 캐릭터 셋을 사용하여 수행될 때만 가능하다. 자신의 캐릭터 셋은 Lang 라이브러리에 있는 함수 Lang.characterSet()를 사용하여 알 수 있다.

③ URL 호출
URL 호출 구조를 정의하는 문법을 알아보도록 하겠다. 이 문법은 함수 호출을 갖는 WML 스크립트 방법과 유사하고 US-ASCII 캐릭터 셋의 단말 심볼을 갖는다.

http://www.host.com/scr#foo(1,-3,’hello’)  //OK
http://www.host.com/scr#bar(1,-3+1,’good’) //Error
http://www.host.com/scr#bar(foo(1,-3,’hello’)) //Error
사용자 에이전트는 URL과 프라그먼트 앵커를 사용해서 정보를 제공함으로써 외부 WML 스크립트 함수를 호출할 수 있다. 이를 위해 컴파일 단위 URL(http:// www.x.com/myScript.scr)과 프라그먼트 앵커로 쓰일 함수 이름과 파라미터(testFunc(‘test%20argument’,-8))가 사용된다. 예는 다음과 같다.

http://www.x.com/mySrcipts.src#testFunc(‘Test%20argument’,-8))

이 URL이 WML 스크립트 컴파일 단위를 표시하게 된다. 이 때 호출에 실패하는 경우는 다음과 같다.

· Access 제어를 체크하는 것은 수행된다. 호출자가 컴파일 단위를 호출하는 것이 올바르게 되지 않으면 호출은 실패한다.
· 프라그먼트 앵커에서 정의된 함수 이름은 컴파일 단위에서 외부 함수와 맞는지 확인한다. 맞지 않으면 호출은 실패한다.
· 프라그먼트 앵커에서 파라미터 리스트는 파싱되고 적절한 타입의 주어진 인자는 함수에 전달된다. 파라미터 리스트가 인밸리드이면 호출은 실패한다.

URL 호출은 URL 탈출와 URL 호출을 갖는 컨텐트 포맷에 의해 제공된 다른 탈출 메카니즘을 사용할 수 있다.
WML 스크립트는 RFC2396에 정의된 상대적인 URL을 사용한다. RFC2396은 WML 스크립트 컴파일 단위의 문맥에서 상대 URL을 해석하는데 사용되는 메쏘드를 정의한다. WML 스크립트의 기본 URL은 컴파일 단위에서 정의한 URL이다.

④ 바이트 코드 세만틱
이제 WML 스크립트 바이트 코드를 일반화하는데 사용되어야 하는 인코딩 규칙을 설명하겠다. 이러한 규칙에 따라 WML 스크립트 컴파일러는 WML 스크립트 인터프리터의 수행으로부터 가정될 수 있는 것들을 정의한다.
함수 인자는 WML 스크립트나 라이브러리 함수 호출에서 WML 스크립트 함수에 존재하는 순서대로 피연산자 스택에 존재해야 한다. 따라서 첫 번째 인자는 피연산자 스택에 첫 번째에 들어가고 두 번째 인자는 그 다음에 들어간다. 호출을 실행하는 명령은 피연산자 스택으로부터 인자를 꺼내고 적절한 함수 변수를 초기화하여 사용한다.
WML 스크립트 함수는 유일한 변수 인덱스를 사용하여 변수를 참조한다. 이 인덱스는 각각 호출된 WML 스크립트 함수를 정의한 정보들에 적합해야 한다. 그 정보에는 함수가 수용하는 인자의 개수, 함수에 의해서 사용되는 지역변수의 개수가 포함된다. 따라서 변수 인덱스 할당은 다음에 오는 규칙을 사용하여 실행된다.

· 함수 인자 :함수 인자에 대한 인덱스는 우선적으로 할당되어야 한다. 할당은 피연산자 스택에 넣어진 순서대로 수행된다. 함수 인자를 위해 할당된 인덱스의 수는 함수에 의해 수용되는 인자의 수와 일치해야 한다. 따라서 만약 함수가 N개의 인자를 수용한다면 마지막 변수의 인덱스는 N-1이 될 것이다. 함수가 인자를 갖지 않을 때는 변수 인덱스가 할당되지 않는다.
· 지역변수: 지역변수를 위한 인덱스는 함수 인자를 위해 사용되지 않은 첫 번째 변수 인덱스에 연속적으로 할당된다. 지역변수를 위해 할당된 인덱스의 수는 함수에 의해 사용된 지역변수의 수와 동일해야 한다.

함수의 끝에서 반환 구문이 없을 경우 엠프티 스트링을 반환해야 한다. 컴파일러는 인터프리터가 반환 명령이 없는 함수의 끝에 도달하면 엠프티 스트링을 반환한다고 가정한다.
WML 스크립트 컴파일러는 WML스크립트 인터프리터는 모든 함수 지역 변수를 엠프티 스트링으로 초기화한다. 따라서 컴파일러는 초기화 없이 선언된 변수에 대한 초기화 코드를 넣을 필요가 없다.
WML스크립트는 WML 스크립트 컴파일 단위에서 함수에 접근을 제어하도록 두 개의 메카니즘을 제공한다. external 키워드와 특정 접근 제어 프라그마가 그것이다. 따라서 WML스크립트 인터프리터는 다음에 오는 동작을 지원한다.

· 외부 함수 : external로 선언된 함수는 다른 컴파일 단위로부터 호출될 수 있다.
· 접근 제어 : 컴파일 단위에서 정의된 외부 함수로의 접근은 주어진 접근 도메인과 접근 경로와 일치시켜서 다른 컴파일 단위로부터 접근이 허용된다.

바이트 코드 검사
바이트 코드 검사는 바이트 코드가 실행되기 위해 사용되기 전 혹은 사용되는 동안에 발생한다. 이러한 검사의 목적은 WML 스크립트 바이트 코드 스펙을 컨텐트가 올바르게 따르고 있는지를 확인하는 것이다. 만약 이것이 실패하게 되면 바이트 코드는 실행되지 않거나 실행이 중지된다. 실패는 WML 스크립트 인터프리터 호출자에게 알려진다.
이제 WML 스크립트 인터프리터에서 수행되는 체크에 대해 살펴보기로 한다.
통합적인 체크
우선 체크되어야 할 부분은 버전에 대한 확인으로, 바이트 코드 버전은 WML 스크립트 인터프리터에 의해 지원되는 바이트코드 버전과 비교되어야 한다. 이 때 바이트 코드 버전의 주(major) 버전은 인터프리터에 의해 지원되는 바이트 코드의 주 버전과 맞아야 하고 바이트 코드의 부(minor) 버전은 WML 스크립트 인터프리터에 의해 지원되는 부버전와 같거나 낮아야만 한다. 또한 바이트 코드의 사이즈는 컨텐트의 바이트 사이즈와 정확히 일치해야 한다.
다음으로 상수 풀 검사가 수행되어야 한다. 이 검사에서는 상수의 개수와 상수의 사이즈에 대한 확인이 수행된다. 상수 풀에 정의된 상수의 수는 상수 풀에 저장된 상수의 수와 동일해야 하며, 각 상수는 WML 스크립트 바이트 코드 스펙 또는 상수 개체의 부분으로서 제공되는 파라미터 사이즈에 정의된 올바른 바이트 수와 일치해야 한다.
프라그마 풀 검사에서는 프라그마의 수와 프라그마 타입에 대한 확인이 수행된다. 프라그마 풀에서 정의된 프라그마의 수는 프라그마 풀로 저장된 프라그마의 수와 같아야 하며 프라그마 풀의 프라그마 타입을 정의하는데 사용되는 수는 지원되는 프라그마 타입과 동일해야 한다.
상수 풀 인덱스 확인에서는 접근 제어 도메인과 경로가 스트링 상수를 지정하고 있는지 여부와 메타-정보 프라그마에서 사용된 상수 풀 인덱스가 스트링 상수를 지정하고 있는지 여부를 검사한다.
함수 풀 검사에서는 함수 이름의 수와 인덱스가 적합한지 여부를 확인하기 위해 함수 이름 테이블을 검사하고 함수 이름이 올바른 함수 이름 캐릭터를 갖는지 확인한다. 이 때 함수 이름은 WML 스크립트의 함수 이름 규칙에 따라야 한다. 또한 테이블은 반드시 최소한 하나 이상의 이름을 가지고 있어야 한다. 이와 함께 함수 프롤로그가 올바른지를 확인하게 되며 이 검사에서는 인자와 지역변수의 수가 적합한지, 함수의 사이즈가 적합한지 여부를 검사하게 된다. 이 때 인자와 지역변수의 합은 256을 넘어서는 안되고, 함수의 사이즈는 함수 프롤로그에 정의된 크기와 일치해야 한다.

런-타임 확인
런-타임 확인은 실행되는 동안 사용된 명령이 올바른지, 또 사용하는 파라미터 값이 올바른지에 대해 검사하는 과정이다. 이 때 주로 확인하는 사항은 다음과 같다.

· 바이트 코드가 올바른 명령을 포함하는지 확인
· 지역 변수 참조가 올바른지 확인 : 참조는 함수 프롤로그에서 함수 지역 변수의 수에 의해 정의된 묶음 내 존재한다.
· 상수 참조가 올바른지 확인 : 참조는 상수 풀의 상수 수에 의해 정의된 묶음 내에 존재한다. 각 명령에 의해 정의된 올바른 상수 타입을 지적하고 해야 한다. URL 참조의 경우 언급된 상수 스트링은 올바른 URL을 포함하고 있어야 하며 함수 이름 참조의 경우 언급된 상수 스트링은 WML 스크립트 함수 이름을 포함해야 한다.
· 표준 라이브러리 인덱스와 라이브러리 함수 인덱스가 올바른지 확인 : 인덱스는 WML 스크립트 표준 라이브러리 스펙에 의해 정의된 묶음에 존재한다.
· 지역 함수 호출 인덱스 확인 : 함수 인덱스는 함수 풀에 정의된 함수의 수와 동일해야 한다.
· 함수 묶음 내에 점프가 있는지 확인 : 모든 점프는 정의된 함수 내에서 유효하다.
· 점프의 타겟이 올바른지 확인 : 모든 점프의 목적지는 하나의 명령어 시작점에 위치한다.
· 함수의 끝이 올바른지 확인 : 함수는 하나의 명령어 중간에서 끝나서는 안된다.

런타임 에러 검출과 처리
WML 스크립트 함수는 모든 상황에서 올바르게 작동되기를 기대하는 사용자를 위한 서비스를 구현하기 때문에, 에러 핸들링은 매우 중요한 요소이다. 이는 언어가 예외 메카니즘을 제공하지 않는 동안 에러를 막는 툴을 제공하거나 에러를 알리고 적절한 행동을 발생시키는 툴을 제공한다는 것을 의미한다. 프로그램 실행을 중지하는 것은 어떠한 대안도 가능하지 않은 경우에 사용되는 최후의 상황이다.
바이트 코드를 다운 받아서 실행할 때 발생할 수 있는 예외 상황으로는 다음과 같은 것들이 있다.

① 에러 검출
에러 검출의 목적은 열거된 상황에 따르는 에러를 프로그래머가 검출하기 위한 풀을 제공하는 것이다. WML 스크립트는 미약한 타입형 언어이기 때문에 특정 기능이 부적절한 데이터 타입에 의해 발생되는 에러를 검출하는데 사용된다.
 
· 주어진 변수가 올바른 값을 갖는지 확인 : WML 스크립트는 타입 확인 라이브러리 함수(Lang.isInt(), Lang.parseInt(), Lang.parseFloat())를 지원한다.
· 주어진 변수가 올바른 타입을 갖는지 확인 : WML 스크립트는 typeof, isvalid를 지원한다.
② 에러 핸들링
에러 핸들링은 에러가 이미 발생한 경우에 나타난다. 이것은 에러가 에러 검출에 의해 보호되지 못하거나 그렇게 하기에는 너무 어려운 상황에 발생한다. 다음의 두 가지 경우로 나눌 수 있다.

· Fatal 에러 : 프로그램을 중지시키는 것이다. WML 스크립트 함수는 항상 다른 사용자 에이전트로부터 호출되기 때문에 프로그램 중지는 항상 호출한 사용자 에이전트에게 전달된다.
· Non-fatal 에러 : 특정 반환 값으로 프로그램에 에러가 표시될 수 있고 프로그램은 적절한 행동을 결정할 수 있다.

이것으로 WMLS에 대해서도 마치도록 하겠다. 문법적인 사항은 굳이 포함하지 않았다. 그 이유는 일반적으로 사용되는 언어와 거의 유사하고 특히 자바 스크립트 같은 스크립트 언어를 아는 사용자라면 너무나 간단하게 익힐 수 있기 때문이다.
WAP은 이제 인터넷처럼 곧 우리 일상 생활에 일부분으로 자리잡을 것이다. 인터넷이 처음 등장해서 보편적으로 사용되기 전까지 인터넷을 사용할 수 있는 사람들은 많은 수가 아니었다. 그것은 사용하는 것이 어려워서가 결코 아니었을 것이다. 그것이 제대로 알려지기까지의 시간이 그만큼 소요되었던 것이라고 생각된다. WAP 역시 마찬가지이다. 사용하는 것에 있어서는 별다른 어려운 점이 있는 것이 아님에도 불구하고 이에 대해서 알지 못하고 있는 것이 장애 요인인 것이다. 적어도 프로그램세계의 독자만은 그러한 정보에 대해 조금이나마 한발 앞서나갈 수 있기를 바라면서 이번 호를 마친다.

정리쪾천영호 기자 |chunyh@pserang.co.kr|

반응형