본문 바로가기

Programming/LEX & YACC

LEX 의 구조

lex 프로그램은 크게 세 부분으로 구분된다.


정의절

규칙절

사용자 서브루틴절

실제 코드에서의 형태는 다음과 같다


{%
      
정의절
%}

%%
     
규칙절
%%

      사용자 서브루틴

 

각 부분은 %% % 두개를 담고 있는 행으로 구분한다. 처음 두 부분은 내용이 없더라도 반드시 있어야 한다. 즉 정의절 과 규칙절 은 반드시 있어야 한다.

세번째 부분과 그앞에 있는 %% 행은 생략할 수 있다.

 

정의절

정의절은 리터럴 블록, 정의, 내부 테이블 선언, 시작조건, 변환 등을 포함할 수 있다. 공백으로 시작하는 행은 C 파일에 복사될 때 공백이 제거된다. 이는 주로 /*  */ 로 둘러싸인 주석을 포함할 때 앞의 공백을 제거하기 위한 기능이다.

 

규칙절

규칙절은 패턴으로 이루어진 행과 C 코드를 담고 있다. 공백 또는 %{ %} 사이로 둘러싸인 부분으로 시작하는 행은 C 코드이다. 나머지는 패턴행 이다.

C코드는 생성된 C 파일에 그대로 복사된다. 규칙절의 처음 부분에 존재하는 행들은 생성되는 yacc() 함수의 처음 부분에 놓이며, 반드시 패턴과 관련된 코드 및 스캐너에 대한 초기화 코드에서 사용되는 변수들의 선언을 담고 있어야 한다. 다른 부분에 있는 C 코드는 생성되는 C 파일에 임의의 위치로 복사되며 주석만을 담아야 한다(바로 이방법으로 규칙절에서 동작코드 바깥 부분에 주석을 붙일 수있다).

패턴행은 패턴을 담고 있으며,각 패턴 뒤에는 약간의 공백과 패턴이 매치했을 때 실행될 C 코드가 존재한다. 만약 C 코드가 한 문장 이상이어서 여러행으로 이루어 진다면 반드시 중괄호({ }) 안에 담아야 한다.

Lex 스캐너는 규칙절의 패턴에 입력을 매치 시킨다적절한 매치가 발견될 때마다(이렇게 매치된 입력을 토큰이라 한다) 해당 패턴과 관련된 C코드를 실해한다. 만약 패턴의 뒤에 C 코드 대신 수직바(|, C에서 or 기호)가 있다면, 해당 패턴은 바로 뒤에 있는 패턴과 동일한 C 코드를 공유한다. 입력된 문자에 매치하는 패턴이 존재하지 않으면, Lexer "ECHO;" 코드에 연관된 패턴에 매치한 것처럼 작동한다.

 

사용자 서브루틴절

사용자 서브루틴절의 내용은 Lex를 통해서 C 파일에 그대로 복사된다. 이 절은 보통 규칙에서 호출하는 루틴을 담고 있다. 만약 input(), unput(), output(), ywrap() 을 재정의 한다면 새로운 버전이나 지원 서브루틴이 이 절에 존재해야 한다.

큰 프로그램에서는 Lex 파일을 수정했을 때 다시 컴파일해야 하는 코드의 양을 줄일수 있도록, 사용자 서브루틴절이 아닌 별도의 파일에 지원 코드를 담는것이 더 바람직 하다.


참고 ㅣ lex yacc 존 레빈 , 토니 메이슨 ,더그 브라운 저