·º½º(Lex)¿Í ¾à(Yacc):

ÄÄÆÄÀÏ·¯ ±¸¼ºÀ» À§ÇÑ ´ëÇ¥Àû ¼ÒÇÁÆ®¿þ¾î µµ±¸



■ ·º½º(Lex)¿Í ¾à(Yacc)Àº ¹«¾ùÀΰ¡?

ÄÄÆÄÀÏ·¯ÀÇ ±¸¼ºÀ» µµ¿ÍÁÖ´Â ´ëÇ¥ÀûÀÎ ¼ÒÇÁÆ®¿þ¾î µµ±¸µéÀÔ´Ï´Ù. ¿ø·¡ À¯´Ð½º(Unix)ÀÇ »ê½ÇÀÎ AT&T º§ ¿¬±¸¼Ò(Bell Laboratories)¿¡¼­ À¯´Ð½º ½Ã½ºÅÛÀÇ À¯Æ¿¸®Æ¼(utility)·Î¼­ °³¹ßµÇ¾ú½À´Ï´Ù. °¢°¢ÀÇ °³¹ßÀÚ´Â ·º½º´Â ¸¶Å© ·¹½ºÅ©(Mark Lesk), ¾àÀº ½ºÆ¼ºê Àò½¼(Steve Johnson)ÀÔ´Ï´Ù. ÀÌÈÄ ÀÌ µµ±¸µéÀÇ À¯¿ë¼ºÀÌ È®ÀεǸ鼭 ¼Ö¶ó¸®½º(Solaris)³ª ¸®´ª½º(Linux)¿Í °°Àº À¯´Ð½º °è¿­ÀÇ ¿î¿µÃ¼Á¦´Â ¹°·ÐÀ̰í, ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® À©µµ¿ìÁî(Windows) µîÀÇ »óÀÌÇÑ ¿î¿µÃ¼Á¦¿¡µµ À̽Ä(porting)µÇ¾î¼­ ³Î¸® »ç¿ëµÇ°í ÀÖ½À´Ï´Ù.


■ ·º½º¿Í ¾àÀº °øÂ¥Àΰ¡?

ÇöÀç À¯´Ð½º °è¿­ »ó¿ë(ßÂéÄ) ¿î¿µÃ¼Á¦ÀÇ °æ¿ì ·º½º¿Í ¾àÀº ±âº» À¯Æ¿¸®Æ¼ÀÇ ÀϺημ­ Æ÷ÇԵǾî ÀÖ½À´Ï´Ù. ±×·¯³ª ·º½º¿Í ¾àÀÇ ÆÇ±Ç(copyright)Àº º§ ¿¬±¸¼Ò°¡ °¡Áö°í ÀÖÀ¸¹Ç·Î, ¸®´ª½º¿Í °°Àº FSF(Free Software Foundation)ÀÇ Á¤½ÅÀ» Ç¥¹æÇÏ´Â ¿î¿µÃ¼Á¦ÀÇ °æ¿ì´Â °¢°¢ ·º½º¿Í ¾àÀÇ GNU ¹öÀü(version)ÀÎ Ç÷º½º(flex)¿Í ¹ÙÀ̽¼(bison)ÀÌ °®Ãß¾îÁ® ÀÖ½À´Ï´Ù. ±× ¿Üµµ ¿©·¯ ¿î¿µÃ¼Á¦¸¦ À§ÇÑ ¾à°£¾¿ ´Ù¸¥ ·º½º¿Í ¾àÀÇ ¹öÀüµéÀÌ ÀÖ½À´Ï´Ù. À©µµ¿ìÁî »ó¿¡¼­ ½Ã±×À©(Cygwin) ½Ã½ºÅÛÀ» »ç¿ëÇÑ´Ù¸é ¼³Ä¡ÇÒ ¶§ Ç÷º½º¿Í ¹ÙÀ̽¼À» ¼±ÅÃÇÏ¿© »ç¿ëÇÏ´Â °ÍÀÌ °¡Àå ÆíÇÒ °ÍÀÔ´Ï´Ù.


■ Ç÷º½º ¿¹Á¦ 1 (ÁÙ ¹øÈ£ ºÙÀ̱â)


%{

/*

*   line numbering 1

*/


int          lineno = 1;

%}


%%


\n           { lineno++; ECHO; }

^.*$         printf("%d\t%s", lineno, yytext);


■ Ç÷º½º ¿¹Á¦ 2 (ÁÙ ¹øÈ£ ºÙÀ̱â)


%{

/*

*   line numbering 2

*/


int          lineno = 0;

%}


%%


^.*\n       printf("%d\t%s", ++lineno, yytext);


■ Ç÷º½º ¿¹Á¦ 3 (±ÛÀÚ, ´Ü¾î, ÁÙ ¼ö ¼¼±â)


%{

/*

*   word count

*/


int          nchar, nword, nline;

%}


%%


\n           ++nchar, ++nline;

[^ \t\n]+   ++nword, nchar += yyleng;

.            ++nchar;


%%


int main(void)

{

      yylex();

      printf("%d\t%d\t%d\n", nchar, nword, nline);

      return 0;

}


■ Ç÷º½º ¿¹Á¦ 4 (ÆÄ½ºÄ®(Pascal) ºÎºÐÁýÇÕÀÇ ¾îÈÖ ºÐ¼®)


%{

/*

*   Pascal subset

*/


#include            <stdio.h>


#define             ID     256

#define             NUMBER 257

#define             IF     258

#define             THEN   259

#define             ELSE   260

#define             RELOP 261

#define             LT     262

#define             LE     263

#define             EQ     264

#define             NE     265

#define             GT     266

#define             GE     267

%}


delim               [ \t\n]

ws                   {delim}+

letter              [A-Za-z]

digit               [0-9]

id                   {letter}({letter}|{digit})*

number              {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?


%%


{ws}         ;

if           printf("Keyword if: (%d)\n", IF);

then         printf("Keyword then: (%d)\n", THEN);

else         printf("Keyword else: (%d)\n", ELSE);

{id}         printf("Identifier: (%s, %d)\n", yytext, install_id());

{number}    printf("Number: (%s, %d)\n", yytext, install_num());

"<"          printf("Relational Operator: (%d, %d)\n", RELOP, LT);

"<="         printf("Relational Operator: (%d, %d)\n", RELOP, LE);

"="          printf("Relational Operator: (%d, %d)\n", RELOP, EQ);

"<>"         printf("Relational Operator: (%d, %d)\n", RELOP, NE);

">"          printf("Relational Operator: (%d, %d)\n", RELOP, GT);

">="         printf("Relational Operator: (%d, %d)\n", RELOP, GE);


%%


int install_id(void)

{

      static int entry_index = 0;


      return (++entry_index);

}


int install_num(void)

{

      int p = yyleng - 1;

      int value = 0;


      value = *(yytext + p) - '0';

      while (--p >= 0) value = value * 10 + yytext[p] - '0';

      return value;

}

int main(void)

{

      printf("Lexical analysis started.\n\n");

      yylex();

      printf("\nLexical analysis done.\n");

      return 0;

}


■ ¹ÙÀ̽¼ ¿¹Á¦ 1 (°£´ÜÇÑ °è»ê±â)


%{

#include <ctype.h>


void yyerror(const char *);

%}


%token DIGIT


%%

lines       :      lines line

              |      line

              ;

line         :      expr '\n'     { printf("%d\n", $1); }

              ;

expr         :      expr '+' term { $$ = $1 + $3; }

              |      term

              ;

term         :      term '*' factor     { $$ = $1 * $3; }

              |      factor

              ;

factor      :      '(' expr ')' { $$ = $2; }

              |      DIGIT

              ;


%%

void yyerror(const char *s)

{

   printf("%s\n", s);

}


int yylex(void)

{

   int c;


   while ((c = getchar()) == ' ' || c == '\t') ;

   if (isdigit(c)) {

      yylval = c - '0';

      return DIGIT;

   }

   return c;

}


int main(void)

{

   return yyparse();

}


■ Ç÷º½º¿Í ¹ÙÀ̽¼ ¿¹Á¦ 1 (°£´ÜÇÑ °è»ê±â)


%{

#include <ctype.h>

#include "calc2.tab.h"

%}


delim       [ \t]

ws           {delim}+

digit       [0-9]


%%

{ws}         ;

{digit}     { yylval = yytext[0] - '0'; return DIGIT; }

\n|.         return yytext[0];



%{

void yyerror(const char *);

%}


%token DIGIT

%token QUIT


%%

lines       :      lines line

              |      line

              ;

line         :      expr '\n'     { printf("%d\n", $1); }

              ;

expr         :      expr '+' term { $$ = $1 + $3; }

              |      term

              ;

term         :      term '*' factor     { $$ = $1 * $3; }

              |      factor

              ;

factor      :      '(' expr ')' { $$ = $2; }

              |      DIGIT

              ;


%%

void yyerror(const char *s)

{

   printf("%s\n", s);

}


int main(void)

{

   printf("Calculator started\n\n");

   yyparse();

   printf("\nCalculator terminated\n");

}