·º½º(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");
}