본문 바로가기

Programming/LEX & YACC

LEX 와 YACC 의 동작 원리

LEX

 

Lex 는 기본적으로 단어들로 이루어진 문장에서 지정한 Token을 하나하나 꺼내오게 된다.

 

yylex() 라는 함수는 lex 에 의하여 구성된 lexer 의 호출 함수 이다. 다시 말해 yylex() 함수를 호출하면 lexer 는 주어진 문장에서 정해진 규칙에 의하여 토큰을 하나하나 꺼내어 온다. 이렇게 꺼내어 오면서 특정한 등록된, 즉 각 토큰에 정해놓은 함수 또는 문장( c 함수 또는 c 문장) 을 호출하게 된다.

 

lexer yylex() 에 의하여 문장에서 토콘을 꺼내오는 것을 시작하며 모든 토큰이 다 읽혀 질때까지 yylex() 를 끝내지 않는다

 

Lex 혼자서도 어느정도 구문 분석을 하여 수행할 수 있다. Lex 에 의하여 만들어진 lexer 자신도 얼마든지 yacc 없이 특정한 문장을 읽어 우리가 원하는 동작을 구현할 수도 있다. lexer 에서 토큰이 하나하나 나올때 마다 특정한 행동을 수행하도록 하면 된다. 그러나 계산기와 같은 동작을 수행할 때 우리는 산술연산의 우선순위같은것을 정해 줘야 한다. 이런 c 코드를 만들기 위해서는 많은 노력이 필요하다. lexer에 의하여 나오는 토큰들을 수집하여, 수집된 토큰들을 나름대로 정리하여 원하는 계산 혹은 동작을 수행해야 한다. 이러기 위해서는 앞에서 언급했듯이 많은 노력이 필요로 하다. 이러한 노력을 줄이기 위하여 yacc를 사용하는 것이다.

 


 

YACC

 

Yacc 는 문장에 어떠한 토큰들에 의하여 구성된 문법이 있다고 생각하고, 이러한 문법에 맞는 문장이 있는지를 검사하여 해당 문장이 나타나면 lex 와 마찬가지로 정해진 함수 또는 문장( c 함수, c 문장)을 수행하도록 하는 기능을 한다.

 

다음과 같은 문장이 있다고 생각해 보자.

3+(1+2)*4

여기서 우리는 3 1 2 4 라는 숫자 토큰이 있고 + * , ( ) 라는 산술연산 토큰을 만들어 낼 수 있다. 이러한 토큰을 끄집어 내는 동작은 lex 를 이용하면 매우 쉽다.

 

이렇게 나온 토큰을 특정한 계산방식( 여기서는 산술 연산 계산 방식)을 구축하여 결과를 얻는 과정이 필요하다. 이러한 과정을 만들어 내는 것으로 yacc가 아주 편하게 되어 있다.


lex는 토큰들을 하나하나 가져오고, 이렇게 가져온 토큰들을 모아서 특정한 패턴으로 분석하여 결과를 만들어 주는 것이 바로 yacc 인 것이다.