³ª. ½ºÅ¸ÀÏ

´ÙÀ½Àº CParseCpp Ŭ·¡½ºÀÇ ±¸Çö ¼Ò½ºÀÌ´Ù. ºÐ¼® µ¿ÀÛÀÌ ´Ù¼Ò º¹ÀâÇϱ⠶§¹®¿¡ ±æÀÌ°¡ Á¶±Ý ±æ´Ù.

 

enum {

     CPP_CON_NORMAL,

     CPP_CON_BLOCKCOMMENT,

     CPP_CON_LINECOMMENT,

     CPP_CON_STRING,

     CPP_CON_CHAR

};

 

enum {

     CPP_STYLE_NORMAL,

     CPP_STYLE_COMMENT,

     CPP_STYLE_STRING,

     CPP_STYLE_CHAR,

     CPP_STYLE_NUMBER,

     CPP_STYLE_KEYWORD,

     CPP_STYLE_PREPROCESSOR

};

 

CParseCpp::CParseCpp()

{

     lstrcpy(arStyle[0].name,"º¸Åë");

     arStyle[0].fore=(DWORD)-1;

     lstrcpy(arStyle[1].name,"ÁÖ¼®");

     arStyle[1].fore=RGB(0,0,0);

     arStyle[1].back=RGB(192,192,192);

     lstrcpy(arStyle[2].name,"¹®ÀÚ¿­");

     arStyle[2].fore=RGB(0,128,0);

     lstrcpy(arStyle[3].name,"¹®ÀÚ");

     arStyle[3].fore=RGB(0,128,0);;

     lstrcpy(arStyle[4].name,"¼ýÀÚ");

     arStyle[4].fore=RGB(0,0,255);

     lstrcpy(arStyle[5].name,"Å°¿öµå");

     arStyle[5].fore=RGB(255,0,0);

     lstrcpy(arStyle[6].name,"Àü󸮱â");

     arStyle[6].fore=RGB(255,0,255);

}

 

TCHAR *CParseCpp::GetInfo(int iIndex)

{

     switch (iIndex) {

     case 0:

          return (TCHAR *)1;

     case 1:

          return TEXT(" \t\r\n\"\¡¯\\.,<>:;/()[]{}~!@#%^&*-+=?|");

     case 2:

          return TEXT("//");

     case 3:

          return TEXT("/*");

     case 4:

          return TEXT("*/");

     case 5:

          return TEXT("{");

     case 6:

          return TEXT("}");

     }

     return 0;

}

 

void CParseCpp::ParseLine(CApiEdit &ae,int nLine)

{

     DWORD Context;

     int s,e,i;

     int nUnit=0;

     int idpos,idend;

 

     if (pInfo[nLine].pUnit[0].pos != -1)

          return;

 

     if (nLine == 0) {

          Context=CPP_CON_NORMAL;

     } else {

          Context=pInfo[nLine-1].Context;

     }

 

     s=ae.pLine[nLine].Start;

     e=ae.pLine[nLine].End;

     idpos=s;

 

     switch(Context) {

     case CPP_CON_NORMAL:

          MakeParseInfo(nLine,nUnit,s,CPP_STYLE_NORMAL);

          break;

     case CPP_CON_STRING:

          MakeParseInfo(nLine,nUnit,s,CPP_STYLE_STRING);

          break;

     case CPP_CON_CHAR:

          MakeParseInfo(nLine,nUnit,s,CPP_STYLE_CHAR);

          break;

     case CPP_CON_BLOCKCOMMENT:

          MakeParseInfo(nLine,nUnit,s,CPP_STYLE_COMMENT);

          break;

     case CPP_CON_LINECOMMENT:

          if (ae.pLine[nLine].nLine != 0) {

              MakeParseInfo(nLine,nUnit,s,CPP_STYLE_COMMENT);

              goto EndParse;

          } else {

              MakeParseInfo(nLine,nUnit,s,CPP_STYLE_NORMAL);

              Context=CPP_CON_NORMAL;

              break;

          }

     }

 

     for (i=s;i<e;i++) {

          switch(Context) {

          case CPP_CON_NORMAL:

              if (ae.buf[i]==¡®/¡¯ && ae.buf[i+1]==¡®*¡¯) {

                   Context=CPP_CON_BLOCKCOMMENT;

              }

              if (ae.buf[i]==¡®/¡¯ && ae.buf[i+1]==¡®/¡¯) {

                   Context=CPP_CON_LINECOMMENT;

              }

              if (ae.buf[i]==¡®\"¡®) {

                   Context=CPP_CON_STRING;

              }

              if (ae.buf[i]==¡®\¡¯¡¯) {

                   Context=CPP_CON_CHAR;

              }

 

              if (Context!=CPP_CON_NORMAL || strchr(GetInfo(1),ae.buf[i]) || i==e-1) {

                   if (i==e-1 && !strchr(GetInfo(1),ae.buf[i])) {

                        idend=i;

                   } else {

                        idend=i-1;

                   }

 

                   if (idend-idpos+1 >= 1) {

                        if (IsKeyword(ae,idpos,idend)) {

                             MakeParseInfo(nLine,nUnit,idpos,CPP_STYLE_KEYWORD);

                             MakeParseInfo(nLine,nUnit,idend+1,CPP_STYLE_NORMAL);

                        } else

                        if (IsNumber(ae,idpos,idend)) {

                             MakeParseInfo(nLine,nUnit,idpos,CPP_STYLE_NUMBER);

                             MakeParseInfo(nLine,nUnit,idend+1,CPP_STYLE_NORMAL);

                        } else

                        if (idpos!=s && ae.buf[idpos-1]==¡®#¡¯) {

                             if (IsPreProcessor(ae,idpos-1,idend)) {

                                 MakeParseInfo(nLine,nUnit,idpos-1,CPP_STYLE_PREPROCESSOR);

                                 MakeParseInfo(nLine,nUnit,idend+1,CPP_STYLE_NORMAL);

                             }

                        }

                   }

 

                   idpos=i+1;

              }

 

              switch (Context) {

              case CPP_CON_NORMAL:

                   break;

              case CPP_CON_BLOCKCOMMENT:

                   MakeParseInfo(nLine,nUnit,i,CPP_STYLE_COMMENT);

                   i++;

                   break;

              case CPP_CON_LINECOMMENT:

                   MakeParseInfo(nLine,nUnit,i,CPP_STYLE_COMMENT);

                   goto EndParse;

              case CPP_CON_STRING:

                   MakeParseInfo(nLine,nUnit,i,CPP_STYLE_STRING);

                   break;

              case CPP_CON_CHAR:

                   MakeParseInfo(nLine,nUnit,i,CPP_STYLE_CHAR);

                   break;

              }

              continue;

          case CPP_CON_BLOCKCOMMENT:

              if (ae.buf[i]==¡®*¡¯ && ae.buf[i+1]==¡®/¡¯) {

                   i++;

                   MakeParseInfo(nLine,nUnit,i+1,CPP_STYLE_NORMAL);

                   Context=CPP_CON_NORMAL;

                   idpos=i+1;

              }

              continue;

          case CPP_CON_STRING:

              if (ae.buf[i]==¡®\\¡¯) {

                   i++;

                   continue;

              }

              if (ae.buf[i]==¡®\"¡®) {

                   MakeParseInfo(nLine,nUnit,i+1,CPP_STYLE_NORMAL);

                   Context=CPP_CON_NORMAL;

                   idpos=i+1;

              }

              continue;

          case CPP_CON_CHAR:

              if (ae.buf[i]==¡®\\¡¯) {

                   i++;

                   continue;

              }

              if (ae.buf[i]==¡®\¡¯¡¯) {

                   MakeParseInfo(nLine,nUnit,i+1,CPP_STYLE_NORMAL);

                   Context=CPP_CON_NORMAL;

                   idpos=i+1;

              }

              continue;

          }

     }

 

     if (Context==CPP_CON_STRING || Context==CPP_CON_CHAR) {

          if (ae.buf[e]==¡®\r¡¯ && ae.buf[e-1]!=¡®\\¡¯) {

              Context=CPP_CON_NORMAL;

          }

     }

 

EndParse:

     pInfo[nLine].Context=Context;

}

 

BOOL CParseCpp::IsKeyword(CApiEdit &ae,int s, int e)

{

     static TCHAR *keyword=" auto break bool case char class const "

          "continue default delete do double else explicit enum "

          "extern float for friend goto if inline int long "

          "new namespace operator private protected public register "

          "return short signed sizeof static struct switch "

          "template this try typedef union unsigned using "

          "virtual void volatile while __asm __fastcall __based "

          "__cdecl __pascal __inline ";

 

     return IsStringExist(keyword,ae.buf+s,e-s+1,TRUE);

}

 

BOOL CParseCpp::IsPreProcessor(CApiEdit &ae,int s, int e)

{

     static TCHAR *preproc=" #define #elif #else #endif #error #if #ifdef "

          "#ifndef #include #line #pragma #undef ";

 

     return IsStringExist(preproc,ae.buf+s,e-s+1,TRUE);

}

 

C ¼Ò½º´Â °ø¹é, ¸íĪ, Å°¿öµå, ±¸µÎÁ¡, ¿¬»êÀÚ, »ó¼ö, ÁÖ¼® µîÀÇ 7°¡Áö ¿ä¼Ò·Î ±¸¼ºµÈ´Ù. ÀÌ·± ¹®¹ýÀûÀÎ ±¸ºÐ´ë·Î ¼Ò½º¸¦ Á¤È®ÇÏ°Ô Çؼ®ÇÏ·Á¸é °ÅÀÇ ÄÄÆÄÀÏ·¯ ¼öÁØÀÇ Äڵ尡 ÇÊ¿äÇÏ´Ù. ¸íĪ°ú ÀÏ¹Ý ¹®ÀÚ¿­À» ±¸ºÐÇÏ·Á¸é º¯¼ö ¼±¾ð¹®À̳ª ÇÔ¼ö ¿øÇüÀ» Çؼ®ÇØ¾ß ÇϹǷΠ±¸¹® °­Á¶ Á¤µµ·Î´Â ¾î¸²µµ ¾ø´Ù. »Ó¸¸ ¾Æ´Ï¶ó ¹®¹ý´ë·Î Á¤È®ÇÏ°Ô ¿ä¼Ò¸¦ ³ª´­ ÇÊ¿äµµ ¾ø´Âµ¥ °ø¹é¿¡ ½ºÅ¸ÀÏÀ» ÁÖ´Â °ÍÀº ½ÇÁúÀûÀ¸·Î Àǹ̰¡ ¾øÀ¸¸ç ¿¬»êÀÚ³ª ±¸µÎÁ¡±îÁö °­Á¶ÇÒ ÇÊ¿ä´Â ¾ø´Â °ÍÀÌ´Ù.

±×·¡¼­ ¿©±â¼­´Â ¾ð¾îÀÇ ¹®¹ýÀûÀÎ ±âÁغ¸´Ù ÇüÅÂÀûÀÎ ±âÁØ¿¡ ÀÇÇØ ½ºÅ¸ÀÏÀ» ºÎ¿©Çϱâ·Î ÇÑ´Ù. C ¼Ò½º´Â ´ÙÀ½ ÀÏ°ö °¡Áö ½ºÅ¸ÀÏ·Î ±¸ºÐÇÏ¸ç °¢ ½ºÅ¸ÀÏÀº °íÀ¯ÀÇ »ö»óÀ¸·Î Ãâ·ÂÇÒ ¼ö ÀÖ´Ù.

 

½ºÅ¸ÀÏ

¼³¸í

º¸Åë ¹®ÀÚ¿­

¸íĪ, ±¸µÎÁ¡À» Æ÷ÇÔÇÑ ÀϹÝÀûÀÎ ¹®ÀÚ¿­ÀÌ´Ù.

ÁÖ¼®

/* */·Î µÑ·¯½ÎÀÎ ºí·Ï ÁÖ¼®°ú //·Î ½ÃÀ۵Ǵ ÇÑ ÁÙ ÁÖ¼®ÀÌ´Ù.

¹®ÀÚ¿­ »ó¼ö

°ãµû¿ÈÇ¥·Î µÑ·¯½ÎÀÎ ¹®ÀÚ¿­ÀÌ´Ù.

¹®ÀÚ »ó¼ö

Ȭµû¿ÈÇ¥·Î µÑ·¯½ÎÀÎ ¹®ÀÚ¿­ÀÌ´Ù.

¼ýÀÚ

¾Æ¶óºñ¾Æ ¼ýÀÚ ¶Ç´Â 16Áø¼ö·Î µÈ ¼ýÀÚ »ó¼öÀÌ´Ù.

Å°¿öµå

C ¾ð¾îÀÇ ¿¹¾à¾îÀÌ´Ù.

Àü󸮱â

#include µîÀÇ Æ¯º°ÇÑ Àüó¸® ¸í·ÉÀÌ´Ù.

 

ÀÌ ºÐ·ù´Â Àý´ëÀûÀÎ °ÍÀº ¾Æ´Ï¸ç ºÐ¼®±â Á¦ÀÛÀÚ¿¡ µû¶ó¼­ Á¶±Ý¾¿ ´Þ¶óÁú ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î ¹®ÀÚ¿­ »ó¼ö¿Í ¹®ÀÚ »ó¼ö´Â ÇϳªÀÇ ½ºÅ¸ÀÏ·Î ÅëÇÕÇÒ ¼ö ÀÖÀ¸¸ç ¸íĪÀ̳ª ±¸µÎÁ¡À» º°µµÀÇ ½ºÅ¸ÀÏ·Î ºÐÇÒÇÒ ¼öµµ ÀÖ´Ù. ¿©±â¼­´Â ÀÌ ºÐ·ù´ë·Î ½ºÅ¸ÀÏÀ» Á¤ÀÇÇÒ °ÍÀÌ´Ù.

ºÐ¼®±â´Â ½ºÅ¸ÀÏ ¿Ü¿¡µµ ÀÌÀü ÁÙÀÇ ºÐ¼®°á°ú¸¦ ÀúÀåÇϱâ À§ÇÑ ÄÁÅؽºÆ®°ªÀ» Á¤ÀÇÇÑ´Ù. C ¾ð¾î´Â ´ÙÀ½ ÁÙ±îÁö À̾îÁö´Â ½ºÅ¸ÀÏ·Î ÁÖ¼®°ú ¹®ÀÚ(¿­) »ó¼ö¸¦ °¡Áö°í ÀÖÀ¸¹Ç·Î ÀÏ¹Ý ÄÁÅؽºÆ®¸¦ Æ÷ÇÔÇÏ¿© ÃÑ 7°³ÀÇ ÄÁÅؽºÆ®°ªÀ» Á¤ÀÇÇÑ´Ù. ºí·Ï ÁÖ¼®°ú ÇÑ ÁÙ ÁÖ¼®Àº °°Àº ÁÖ¼® ½ºÅ¸ÀÏÀÌÁö¸¸ Çؼ® ¹æ¹ýÀÌ ´Ù¸£±â ¶§¹®¿¡ µÎ °³ÀÇ ÄÁÅؽºÆ®·Î ºÐ¸®ÇÑ´Ù. ½ºÅ¸ÀÏ°ª°ú ÄÁÅؽºÆ®°ªÀº ´Ü¼øÇÑ Á¤¼öÀ̹ǷΠ¿­°ÅÇüÀ¸·Î ¼±¾ðÇÏ¿´´Ù.

»ý¼ºÀÚ´Â ½ºÅ¸ÀÏÀÇ »ö»óÀÎ arStyle ¹è¿­À» ÃʱâÈ­ÇÑ´Ù. °¢ ½ºÅ¸ÀϺ°·Î À̸§°ú »ö»ó°ªÀ» ´ëÀÔÇÏ¿´´Ù. ÀÌ Äڵ带 º¸¸é ÁÖ¼®Àº ȸ»ö ¹ÙÅÁ¿¡ °ËÁ¤»öÀÌ¸ç ¹®ÀÚ¿­Àº ±âº» ¹ÙÅÁ»ö¿¡ ¿¬µÎ»öÀ̶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. »ý¼ºÀÚ¿¡¼­ Á¤ÀÇÇÏ´Â arStyleÀÇ ÃʱⰪÀº ºÐ¼®±âÀÇ µðÆúÆ® »ö»óÀÌ µÇ´Âµ¥ Â÷ÈÄ¿¡ ¼³Á¤ ±â´ÉÀ» ÅëÇØ »ç¿ëÀÚ°¡ º¯°æÇÒ ¼öµµ ÀÖ´Ù.

GetInfo ÇÔ¼öÀÇ ±¸Á¶´Â ¹«Ã´ °£´ÜÇÏ´Ù. ºÐ¼®±â ID·Î´Â 1À» ¸®ÅÏÇϴµ¥ TCHAR *·Î ij½ºÆÃÇؼ­ ¸®ÅÏÇØ¾ß ÇÑ´Ù. GetInfo(0)À» È£ÃâÇÏ´Â ÂÊ¿¡¼­´Â ÀÌ °ªÀ» ´Ù½Ã int·Î ij½ºÆÃÇÑ ÈÄ ºñ±³ÇØ¾ß ÇÒ °ÍÀÌ´Ù. Àμö·Î Àü´ÞµÇ´Â À妽º¿¡ µû¶ó C ¾ð¾î¿¡¼­ »ç¿ëµÇ´Â ±¸ºÐÀÚ ¸ñ·Ï°ú ÇÑ ÁÙ ÁÖ¼®, ºí·Ï ÁÖ¼® ±âÈ£µéÀ» ¸®ÅÏÇÏ°í ÀÖ´Ù. ÀÌ °ªµéÀº È£½ºÆ®°¡ ºÐ¼®±âº°·Î ´Ù¸¥ 󸮸¦ ÇÏ°íÀÚ ÇÒ ¶§ »ç¿ëµÈ´Ù.

ParseLine ÇÔ¼ö´Â ÇÑ ÁÙÀÇ ¹®¹ýÀ» ºÐ¼®Çϱâ À§ÇØ ¸î °³ÀÇ µµ¿ì¹Ì ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ´ëÇ¥ÀûÀ¸·Î IsKeyword ÇÔ¼ö¸¦ ºÐ¼®Çغ¸ÀÚ. ÀÌ ÇÔ¼ö´Â keyword Æ÷ÀÎÅÍ¿¡ C ¾ð¾îÀÇ Å°¿öµå¿¡ ÇØ´çÇÏ´Â ´Ü¾îÀÇ ¸ñ·ÏÀ» ÀúÀåÇسõ°í ÀÖ´Ù. ÁÖÀÇÇÒ °ÍÀº ÀÌ·± »ó¼ö ¹®ÀÚ¿­ Æ÷ÀÎÅÍ´Â ¹Ýµå½Ã staticÀ¸·Î ¼±¾ðÇÏ¿© Àü¿ª ¸Þ¸ð¸®¿¡¼­ ÇÑ ¹ø¸¸ ÃʱâÈ­Çϵµ·Ï ÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. ¸¸¾à ÀÌ ¹è¿­À» Áö¿ªº¯¼ö·Î ¼±¾ðÇÑ´Ù¸é ÇÔ¼ö°¡ È£ÃâµÉ ¶§¸¶´Ù ½ºÅÿ¡ ÃʱâÈ­µÇ¹Ç·Î ¾ÆÁÖ ´À·ÁÁø´Ù. ´õ±¸³ª ÀÌ ÇÔ¼ö´Â ¹Ýº¹ÀûÀ¸·Î ÀÚÁÖ È£ÃâµÇ±â ¶§¹®¿¡ ¼Óµµ ÀúÇÏ°¡ ¾ÆÁÖ ¶Ñ·ÇÇÏ°Ô ³ªÅ¸³­´Ù.

IsKeyword ÇÔ¼ö´Â ApiEditÀÇ ·¹ÆÛ·±½º ae¿Í Á¶»çÇÒ ¹®ÀÚ¿­ÀÇ ½ÃÀÛÀ§Ä¡ s, ³¡ À§Ä¡ e¸¦ Àü´Þ¹Þ¾Æ buf[s]~buf[e]±îÁöÀÇ ¹®ÀÚ¿­ÀÌ C ¾ð¾îÀÇ Å°¿öµåÀÎÁö Á¶»çÇÑ´Ù. Á¶»çÇÒ ¹®ÀÚ¿­ÀÌ keyword °¡ °¡¸®Å°´Â ¹®ÀÚ¿­ ¸ñ·Ï Áß ÇϳªÀÎÁö °Ë»çÇØ ±× °á°ú¸¦ ¸®ÅÏÇÏ¸é µÈ´Ù. CParse¿¡ ¹®ÀÚ¿­ ¸ñ·ÏÀ» °Ë»öÇÏ´Â IsStringExist ÇÔ¼ö°¡ ÀÌ¹Ì ÀÛ¼ºµÇ¾î ÀÖÀ¸¹Ç·Î ÀÌ ÇÔ¼ö¸¸ È£ÃâÇÏ¸é ¿ÀÇÁ¼Â s~e»çÀÌ¿¡ ÀÖ´Â ¹®ÀÚ¿­ÀÌ Å°¿öµåÀÎÁö ¾Æ´ÑÁö ¾Ë¾Æ³¾ ¼ö ÀÖ´Ù. C ¾ð¾î´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸ºÐÇϹǷΠbCase Àμö´Â TRUE·Î Àü´ÞÇØ¾ß ÇÑ´Ù.

IsPreProcessor ÇÔ¼öµµ Å°¿öµå ºñ±³ ÇÔ¼ö¿Í ¿ÏÀüÈ÷ µ¿ÀÏÇÏ°Ô ÀÛ¼ºµÇ¾î ÀÖ´Ù. ´Ù¸¸ Àü󸮱⠸ñ·ÏÀ» °¡Áö´Â preproc ¹®ÀÚ¿­ »ó¼ö°¡ ´Ù¸£°Ô ÀÛ¼ºµÇ¾î ÀÖÀ» »ÓÀÌ´Ù. ÀÌÈÄ ´Ù¸¥ ºÐ¼®±â¿¡¼­µµ ű×, ¼Ó¼º, ¿¬»êÀÚ µîÀÇ ¸ñ·ÏÀ» °Ë»öÇÒ ¶§ µ¿ÀÏÇÑ ¹æ¹ýÀ¸·Î ÇÔ¼ö¸¦ ÀÛ¼ºÇÏ¸é µÈ´Ù. ¸ñ·ÏÀ» ±¸¼ºÇÏ´Â ¹®ÀÚ¿­ »ó¼ö¸¦ ¸¸µç ÈÄ ÀÌ »ó¼ö¿Í °Ë»öÇÒ ¹®ÀÚ¿­À» IsStringExist·Î ³Ñ°Ü Áֱ⸸ ÇÏ¸é µÈ´Ù. À̶§ °Ë»ö ¼Óµµ¸¦ Çâ»ó½ÃÅ°·Á¸é °¡±ÞÀû ÀÚÁÖ ³ª¿À´Â ¹®ÀÚ¿­À» ¾ÕÂÊ¿¡ ¹èÄ¡Çϸé ÁÁ´Ù.