⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib6.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        
      } // end if
   else
      {
#ifdef PARSER_DEBUG_ON
printf("\nEOF");
#endif
      return(NULL);
      }
   
   } // end if
else
   {
#ifdef PARSER_DEBUG_ON
printf("\nFstream NULL.");
#endif
   return(NULL);
   } // end else

} // end Getline

// sets the comment string ///////////////////////////////////////

int CPARSERV1::SetComment(char *string)
{
// sets the comment string
if (strlen(string) < PARSER_MAX_COMMENT)
   {
   strcpy(comment, string);
   return(1);
   } // end if
else
   return(0);

} // end SetComment

// find pattern in line //////////////////////////////////////////

int CPARSERV1::Pattern_Match(char *string, char *pattern, ...)
{
// this function tries to match the pattern sent in pattern with
// the sent string, the results are sent back to the sender in the
// variable arguments as well as stored in the parameter passing area

// string literal                        = ['string']
// floating point number                 = [f]
// integer number                        = [i]
// match a string exactly ddd chars      = [s=ddd] 
// match a string less than ddd chars    = [s<ddd] 
// match a string greater than ddd chars = [s>ddd]
// for example to match "vertex: 34.234 56.34 12.4
// ['vertex'] [f] [f] [f]

char token_type[PATTERN_MAX_ARGS];         // type of token, f,i,s,l
char token_string[PATTERN_MAX_ARGS][PATTERN_BUFFER_SIZE];   // for literal strings this holds them
char token_operator[PATTERN_MAX_ARGS];     // holds and operators for the token, >, <, =, etc.
int  token_numeric[PATTERN_MAX_ARGS];      // holds any numeric data to qualify the token

char buffer[PARSER_BUFFER_SIZE]; // working buffer

// a little error testing
if ( (!string || strlen(string)==0) || (!pattern || strlen(pattern)==0) )
   return(0);

// copy line into working area
strcpy(buffer, string);

int tok_start  = 0, 
    tok_end    = 0,
    tok_restart = 0,
    tok_first_pass = 0,
    num_tokens = 0;

// step 1: extract token list
while(1)
    {
    // eat whitepace
    while(isspace(pattern[tok_start]) )
          tok_start++;
    
    // end of line?
    if (tok_start >= strlen(pattern))
       break;    

    // look for beginning of token '['
    if (pattern[tok_start] == '[')
       {
       // now look for token code
       switch(pattern[tok_start+1])
             {
             case PATTERN_TOKEN_FLOAT:  // float
             {
             // make sure token is well formed
             if (pattern[tok_start+2]!=']')
                return(0); // error

             // advance token scanner
             tok_start+=3;

             // insert a float into pattern
             token_type[num_tokens] = PATTERN_TOKEN_FLOAT;  // type of token, f,i,s,l
             strcpy(token_string[num_tokens],"");           // for literal strings this holds them
             token_operator[num_tokens] = 0;                // holds and operators for the token, >, <, =, etc.
             token_numeric[num_tokens]  = 0; 

             // increment number of tokens
             num_tokens++;

#ifdef PARSER_DEBUG_ON
printf("\nFound Float token");
#endif
             } break;

             case PATTERN_TOKEN_INT:  // integer
             {
             // make sure token is well formed
             if (pattern[tok_start+2]!=']')
                return(0); // error

             // advance token scanner
             tok_start+=3;

             // insert a int into pattern
             token_type[num_tokens] = PATTERN_TOKEN_INT;  // type of token, f,i,s,l
             strcpy(token_string[num_tokens],"");         // for literal strings this holds them
             token_operator[num_tokens] = 0;              // holds and operators for the token, >, <, =, etc.
             token_numeric[num_tokens]  = 0; 

             // increment number of tokens
             num_tokens++;

#ifdef PARSER_DEBUG_ON
printf("\nFound Int token");
#endif

             } break;

             case PATTERN_TOKEN_LITERAL: // literal string
             {
             // advance token scanner to begining literal string
             tok_start+=2;
             tok_end = tok_start;
              
             // eat up string
             while(pattern[tok_end]!=PATTERN_TOKEN_LITERAL)
                  tok_end++;

             // make sure string is well formed
             if (pattern[tok_end+1]!=']')
                return(0);

             // insert a string into pattern              
 
             // literal string lies from (tok_start - (tok_end-1)
             memcpy(token_string[num_tokens], &pattern[tok_start], (tok_end - tok_start) );
             token_string[num_tokens][(tok_end - tok_start)] = 0; // null terminate
             
             token_type[num_tokens] = PATTERN_TOKEN_LITERAL;  // type of token, f,i,s,'
             token_operator[num_tokens] = 0;                 // holds and operators for the token, >, <, =, etc.
             token_numeric[num_tokens]  = 0; 

#ifdef PARSER_DEBUG_ON
printf("\nFound Literal token = %s",token_string[num_tokens]);
#endif

             // advance token scanner
             tok_start = tok_end+2;

             // increment number of tokens
             num_tokens++;

             } break;

             case PATTERN_TOKEN_STRING: // ascii string varying length
             {
             // look for comparator
             if (pattern[tok_start+2] == '=' || 
                 pattern[tok_start+2] == '>' ||
                 pattern[tok_start+2] == '<' )
                {
                // extract the number
                tok_end = tok_start+3;

                while( isdigit(pattern[tok_end] ) )
                      tok_end++;

                // check for well formed
                if (pattern[tok_end]!=']')
                   return(0);

                // copy number in ascii to string and convert to real number
                memcpy(buffer, &pattern[tok_start+3], (tok_end - tok_start) );
                buffer[tok_end - tok_start] = 0;
                 
                // insert a string into pattern
                token_type[num_tokens] = PATTERN_TOKEN_STRING;     // type of token, f,i,s,l
                strcpy(token_string[num_tokens],"");               // for literal strings this holds them
                token_operator[num_tokens] = pattern[tok_start+2]; // holds and operators for the token, >, <, =, etc.
                token_numeric[num_tokens]  = atoi(buffer);

                } // end if
             else
                 return(0); // not well formed

#ifdef PARSER_DEBUG_ON
printf("\nFound String token, comparator: %c, characters: %d", token_operator[num_tokens], token_numeric[num_tokens]);
#endif
             // advance token scanner
             tok_start = tok_end+1; 

             // increment number of tokens
             num_tokens++;

             } break;             

             default: break;

             } // end switch

       } // end if
    
    // end of line?
    if (tok_start >= strlen(pattern))
       break;    

    } // end while

#ifdef PARSER_DEBUG_ON
printf("\nstring to parse: %s", string);
printf("\nPattern to scan for: %s", pattern);
printf("\nnumber of tokens found %d", num_tokens);
#endif

// at this point we have the pattern we need to look for, so look for it
int pattern_state = PATTERN_STATE_INIT; // initial state for pattern recognizer
int curr_tok = 0;                 // test for num_tokens
char token[PATTERN_BUFFER_SIZE];  // token under consideration

// enter scan state machine
while(1)
      {
      switch(pattern_state)
      {
      case PATTERN_STATE_INIT:
           {
           // initial state for pattern
           strcpy(buffer, string);

           tok_start      = 0; 
           tok_end        = 0;
           tok_restart    = 0;
           tok_first_pass = 1;
           curr_tok       = 0;

           // reset output arrays
           num_pints = num_pfloats = num_pstrings = 0;

           // transition to restart         
           pattern_state = PATTERN_STATE_RESTART;

           } break;
 
      case PATTERN_STATE_RESTART:
           {
           // pattern may still be here?
           curr_tok       = 0;
           tok_first_pass = 1;

           // error detection
           if (tok_end >= strlen(buffer))
              return(0);

           // restart scanner after first token from last pass
           tok_start = tok_end = tok_restart;

           // start validating tokens
           pattern_state = PATTERN_STATE_NEXT;

           } break;
 
      case PATTERN_STATE_NEXT:
           {
           // have we matched pattern yet?
           if (curr_tok >= num_tokens)
           {   
           pattern_state = PATTERN_STATE_MATCH;       
           }
           else
           {
           // get next token
           if (tok_end >= strlen(buffer))
              return(0);

           tok_start = tok_end;
           while(isspace(buffer[tok_start])) tok_start++;
           tok_end = tok_start;

           while(!isspace(buffer[tok_end]) && tok_end < strlen(buffer)) tok_end++;
              
           // copy token
           memcpy(token, &buffer[tok_start], tok_end - tok_start);
           token[tok_end - tok_start] = 0;

           // check for error
           if (strlen(token)==0) 
              return(0);

           // remember position of first token, so we can restart after it on next pass
           // if need
           if (tok_first_pass)
               {
               tok_first_pass = 0; 
               tok_restart = tok_end;
               } // end if

           // we have the token, set state to check for that token
           switch(token_type[curr_tok])
                 {
                 case PATTERN_TOKEN_FLOAT:
                      {
                      pattern_state = PATTERN_STATE_FLOAT;
                      } break;
                 case PATTERN_TOKEN_INT:    
                      {
                      pattern_state = PATTERN_STATE_INT;
                      } break;
                 case PATTERN_TOKEN_STRING: 
                      {
                      pattern_state = PATTERN_STATE_STRING;
                      } break;
                 case PATTERN_TOKEN_LITERAL:
                      {
                      pattern_state = PATTERN_STATE_LITERAL;
                      } break;

                 default: break;

                 } // end switch
           
           } // end else

           } break;
 
      case PATTERN_STATE_FLOAT:
           {
           // simply validate this token as a float
           float f = IsFloat(token);

           if (f!=FLT_MIN)
              {
              pfloats[num_pfloats++] = f;

              // get next token
              curr_tok++;
              pattern_state = PATTERN_STATE_NEXT;
              } // end if                
           else
              {
              // error pattern doesn't match, restart
              pattern_state = PATTERN_STATE_RESTART;
              } // end else

           } break;
 
      case PATTERN_STATE_INT:
           {
           // simply validate this token as a int
           int i = IsInt(token);

           if (i!=INT_MIN)
              {
              pints[num_pints++] = i;

              // get next token
              curr_tok++;
              pattern_state = PATTERN_STATE_NEXT;
              } // end if                
           else
              {
              // error pattern doesn't match, restart
              pattern_state = PATTERN_STATE_RESTART;
              } // end else

           } break;
 
      case PATTERN_STATE_LITERAL:
           {
           // simply validate this token by comparing to data in table
           if (strcmp(token, token_string[curr_tok]) == 0)
              {
              // increment number of pstrings found and insert into table
              strcpy(pstrings[num_pstrings++], token);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -