Next: , Previous: Handling Comments, Up: Useful Code   [Contents][Index]


9.2 ʸ»úÎó¥ê¥Æ¥é¥ë¤Î½èÍý

ʸ»úÎó¤Ï¡¢ ¤½¤ì¤¬ÆþÎϤȤ·¤ÆÍ¿¤¨¤é¤ì¤¿»þ¤ËÇË´þ¤µ¤ì¤Ê¤¤¤È¤¤¤¦ÅÀ¤Ç¡¢ ¥³¥á¥ó¥È¤È¤Ï¼ã´³°Û¤Ê¤ê¤Þ¤¹¡£ ¤·¤«¤·¡¢ ´ðËÜŪ¤Ê¥¢¥×¥í¡¼¥Á¤ÏƱ¤¸¤Ç¤¹¡£ Â裱¤ÎÊýË¡¤È¤·¤Æ¤Ï¡¢ input()¤ò»È¤Ã¤ÆÊ¸»úÎó¤ò½èÍý¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ ¥³¡¼¥É¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

/*
 * string1.lex: input()¤ò»È¤Ã¤ÆÊ¸»úÎó¤ò½èÍý¤¹¤ë
 */

%{
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>

#define ALLOC_SIZE 32 /* ¥Ð¥Ã¥Õ¥¡¤Î¡ÊºÆ¡Ë³ä¤êÅö¤ÆÍÑ */

#define isodigit(x) ((x) >= '0' && (x) <= '7') 
#define hextoint(x) (isdigit((x)) ? (x) - '0'\
                                   : ((x) - 'A') + 10)  

void yyerror(char *message)
{
  printf("\nError: %s\n",message);
}

%}

%%

\" {
   int  inch,count,max_size;
   char *buffer;
   int  temp;

   buffer   = malloc(ALLOC_SIZE);
   max_size = ALLOC_SIZE;
   inch     = input();
   count    = 0;
   while(inch != EOF && inch != '"' && inch != '\n'){
      if(inch == '\\'){
        inch = input();
        switch(inch){
        case '\n': inch = input(); break;
        case 'b' : inch = '\b';    break;
        case 't' : inch = '\t';    break;
        case 'n' : inch = '\n';    break;
        case 'v' : inch = '\v';    break;
        case 'f' : inch = '\f';    break;
        case 'r' : inch = '\r';    break;
        case 'X' :  
        case 'x' : inch = input();
                   if(isxdigit(inch)){
                     temp = hextoint(toupper(inch));
                     inch = input();
                     if(isxdigit(inch)){
                       temp = (temp << 4) + 
                             hextoint(toupper(inch));
                     } else {
                       unput(inch);
                     }
                     inch = temp; 
                   } else {
                     unput(inch);
                     inch = 'x';
                   }
           break;
        default:
           if(isodigit(inch)){
              temp = inch - '0';
              inch = input();
              if(isodigit(inch)){
                temp = (temp << 3) + (inch - '0');
              } else {
                unput(inch);
                goto done;
              }
              inch = input();
              if(isodigit(inch)){
                temp = (temp << 3) + (inch - '0');
              } else {
                unput(inch);
              }
           done:
              inch = temp; 
           }
        } 
     }
      buffer[count++] = inch;
      if(count >= max_size){
         buffer = realloc(buffer,max_size + ALLOC_SIZE);
         max_size += ALLOC_SIZE;
      }           
      inch = input();
   }
   if(inch == EOF || inch == '\n'){
     yyerror("Unterminated string.");
   }
   buffer[count] = '\0';
   printf("String = \"%s\"\n",buffer);
   free(buffer);
 }
.  
\n
%%

¤³¤Î¥¹¥­¥ã¥Ê¤Ï¡¢ Ê£¿ô¹Ô¤Ë¤ï¤¿¤ëʸ»úÎó¤ä¡¢ ÍÍ¡¹¤Ê¥¨¥¹¥±¡¼¥×¡¦¥·¡¼¥±¥ó¥¹¤ò½èÍý¤·¤Þ¤¹¡£ ¤Þ¤¿¡¢ ʸ»úÎ󤬤ɤΤ褦¤ÊŤµ¤Ç¤â¹½¤ï¤Ê¤¤¤è¤¦¤Ë¡¢ ưŪ¥Ð¥Ã¥Õ¥¡¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£ ¤³¤ì¤ÈƱ¤¸¤³¤È¤ò¥¹¥¿¡¼¥È¾õÂÖ¤ò»È¤Ã¤Æ¹Ô¤¦¥³¡¼¥É¤Ï¡¢ °Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

/*
 * string2.lex: ¥¹¥¿¡¼¥È¾õÂÖ¤ò»È¤Ã¤ÆÊ¸»úÎó¤ò¥¹¥­¥ã¥ó¤¹¤ëÎã
 */

%{
#include <ctype.h>

#define isodigit(x) ((x) >= '0' && (x) <= '7') 
#define hextoint(x) (isdigit((x)) ? (x) - '0' \
                                  : ((x) - 'A') + 10)  

char *buffer      = NULL;
int  buffer_size  = 0;

void yyerror(char *message)
{
  printf("\nError: %s\n",message);
}

%}

%x STRING

hex (x|X)[0-9a-fA-F]{1,2}
oct [0-7]{1,3}

%%

\"                { 
                    buffer      = malloc(1); 
                    buffer_size = 1; strcpy(buffer,"");
                    BEGIN(STRING);
                  }
<STRING>\n        {
                     yyerror("Unterminated string");       
                     free(buffer);
                     BEGIN(INITIAL);
                  }
<STRING><<EOF>>   {
                     yyerror("EOF in string");       
                     free(buffer);
                     BEGIN(INITIAL);
                  }
<STRING>[^\\\n"]  {
                    buffer_size += yyleng;
                    buffer = realloc(buffer,buffer_size+1);
                    strcat(buffer,yytext);
                  }
<STRING>\\\n      /* ¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿²þ¹Ô¤ò̵»ë¤¹¤ë */
<STRING>\\{hex} {
                    int temp =0,loop = 0, foo;
                    for(loop=yyleng-2; loop>0; loop--){
                      temp <<= 4;
                      foo    = toupper(yytext[yyleng-loop]);
                      temp += hextoint(foo);
                    } 
                    buffer = realloc(buffer,buffer_size+1);
                    buffer[buffer_size-1] = temp;
                    buffer[buffer_size]   = '\0';
                    buffer_size += 1;
                  }
<STRING>\\{oct} {
                    int temp =0,loop = 0;
                    for(loop=yyleng-1; loop>0; loop--){
                      temp  <<= 3;
                      temp  += (yytext[yyleng-loop] - '0');
                    } 
                    buffer = realloc(buffer,buffer_size+1);
                    buffer[buffer_size-1] = temp;
                    buffer[buffer_size]   = '\0';
                    buffer_size += 1;
                  }
<STRING>\\[^\n]   {
                    buffer = realloc(buffer,buffer_size+1);
                    switch(yytext[yyleng-1]){
                    case 'b' : buffer[buffer_size-1] = '\b';  
                               break;
                    case 't' : buffer[buffer_size-1] = '\t';
                               break;
                    case 'n' : buffer[buffer_size-1] = '\n';
                               break;
                    case 'v' : buffer[buffer_size-1] = '\v';
                               break;
                    case 'f' : buffer[buffer_size-1] = '\f';
                               break;
                    case 'r' : buffer[buffer_size-1] = '\r';
                               break;
                    default  : buffer[buffer_size-1] = 
                                    yytext[yyleng-1];
                    }
                    buffer[buffer_size] = '\0';
                    buffer_size += 1;
                  }
<STRING>\"        {
                    printf("string = \"%s\"",buffer); 
                    free(buffer);
                    BEGIN(INITIAL);
                  }
%%

¤³¤Î¥¹¥­¥ã¥Ê¤Ï¡¢ string1.lex¤è¤ê¤â¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤Æ¤¤¤Æ¡¢ ¤ª¤½¤é¤¯¤Ï¤è¤êʬ¤«¤ê¤ä¤¹¤¤¤Ç¤·¤ç¤¦¡£ ¥¨¥é¡¼¤Î¥ë¡¼¥ë¤Ï¡¢ INITIAL¾õÂÖ¤ËÌá¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ ¤³¤¦¤·¤Ê¤¤¤È¡¢ ¥¹¥­¥ã¥Ê¤ÏÉÔÅö¤Êʸ»úÎó¤ÈÀµÅö¤Êʸ»úÎó¤È¤ò·ë¹ç¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£ ¤³¤³¤Ç¤â¡¢ Flex¤Î¥Ð¥Ã¥Õ¥¡¡ÊYY_BUF_SIZE¡Ë¤¬½½Ê¬¤ËÂ礭¤¤¤È¤¤¤¦¤³¤È¤ò¤¢¤Æ¤Ë¤»¤º¡¢ ưŪ¥Ð¥Ã¥Õ¥¡¤ò»È¤¤¤Þ¤·¤¿¡£ ÆâÉô¥Ð¥Ã¥Õ¥¡¤¬½½Ê¬¤ËÂ礭¤¤¤È¤¤¤¦³Î¿®¤¬»ý¤Æ¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ yytext¤À¤±¤ò»È¤¦¤³¤È¤â²Äǽ¤Ç¤¹¡£ ¤³¤Î¾ì¹ç¤Ë¤Ï¡¢ yytext¤Î±¦Ã¼¤¬³Î¼Â¤ËºÇ½é¤Î°ÌÃÖ¤Ëα¤Þ¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬½ÅÍפǤ¹¡£ ¤è¤ê¾Ü¤·¤¤¾ðÊó¤Ë¤Ä¤¤¤Æ¤Ï¡¢ Flex and C¤Îyymore¤Î¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£


Next: , Previous: Handling Comments, Up: Useful Code   [Contents][Index]