Advertisement
Apjjm

ATDD Scripting: StringParsing (New)

Jun 7th, 2012
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.47 KB | None | 0 0
  1. ///////////////////////////////
  2. //Begin String Parsing
  3. ///////////////////////////////
  4. /* String Parsing functions V3.0 *\
  5.  *
  6.  * float[] parseStringToFloatArray(string &in asString)- parses all floats out of a string. Signs, exponent & decimals supported
  7.  * int[] parseStringToIntArray(string &in asString)    - Parses all integers out of a string. Signs & exponent supported.
  8.  * uint parseStringUInt(string &in asString)           - Fast UINT parser over entire string (Extracts digits)
  9.  *
  10. \* Written by: Apjjm             */
  11.  
  12. ///////////////////////////////
  13. //+ Float Parsing
  14. ///////////////////////////////
  15. float[] parseStringToFloatArray(string &in asString)
  16.  {
  17.    float[] output = {};
  18.    int integer = 0;      //Integer part of the number
  19.    float decimal = 0;      //Decimal part of the number
  20.    int exponent = 0;      //Exponent of the number
  21.    bool negativeInteger = false; //Is the integer part negative
  22.    bool negativeExponent = false; //Is the exponent part negative
  23.    double dMul = 1;             //Multiplier for the decimal
  24.    bool readNumber = false;      //Read a number yet or not (stops +. etc returning 0's).
  25.    
  26.    //Parsing loop
  27.    int state = 0;
  28.    string temp = asString + "!"; //Add an invalid character to end of string
  29.    for(uint i=0; i<temp.length(); i++)
  30.     {
  31.       //Determine properties about this character
  32.       uint8 chr = temp[i];
  33.       int  digit = _parseDigit(chr);
  34.       int sign     = _parseSign(chr);
  35.       bool isExponent = _parseHasExponent(chr);
  36.       bool isDecimalP = _parseHasDecimalPoint(chr);
  37.       bool isWhitesp  = _parseHasWhitespace(chr);
  38.       bool isDigit    = digit != -1;
  39.      
  40.       switch(state)
  41.       {
  42.          case 0: //Initial state
  43.             {
  44.                if(sign != 0)      { negativeInteger=(sign<0); integer =0; state=1; } //Read +/-XX
  45.                else if(isDigit)   { integer = digit; state = 1; readNumber=true; } //Read N
  46.                else if(isDecimalP){ state = 2; } //Read .XX -> Assume 0.XX
  47.                break;
  48.             }
  49.          case 1: //Read the number part of the float
  50.             {
  51.                if(isDigit)         { integer = (integer * 10) + digit; readNumber=true; } //Read NNXX
  52.                else if(isDecimalP) { state = 2; }            //Read NN.XX
  53.                else if(isExponent && readNumber) { state = 3; } //Read NNeXX -> assume NN.0eXX
  54.                else if(readNumber) { state = -1; }            //Finished reading the number.
  55.                else                { state = 0;  }
  56.                break;
  57.             }
  58.          case 2: //Read the decimal part of the float
  59.             {
  60.                if(isDigit)         { decimal += float(digit) * dMul; dMul *= 0.1; readNumber=true; }
  61.                else if(isExponent && readNumber) { state = 3; }
  62.                else if(readNumber) { state = -1; }
  63.                else                { state = 0;  }
  64.                break;
  65.             }
  66.          case 3: //Ignore a single whitespace char after the exponent.
  67.             {
  68.                if(isDigit)         { exponent = digit; state = 5; } //Read NNeXX
  69.                else if(isWhitesp)  { state = 4; } //Read NNe XX
  70.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; }
  71.                else                { state = -1; }
  72.                break;
  73.             }
  74.          case 4: //Read a +/- Sign or a digit for the exponent
  75.             {
  76.                if(isDigit)         { exponent = digit; state = 5; } //Read NNe NX
  77.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; } //Read NNe +/-XX
  78.                else                { state = -1; }
  79.                break;
  80.             }
  81.          case 5: //Reading the exponent
  82.             {
  83.                if(isDigit) { exponent = (exponent * 10) + digit; } //Read NNe NX
  84.                else        { state = -1; }
  85.                break;
  86.             }
  87.       }
  88.       //At the end of a number?
  89.       if(state < 0)
  90.        {
  91.           //Construct the number & add it to the output array
  92.          int index = output.length(); output.resize(index+1);
  93.          output[index] = _parseFloatHelper(integer,decimal,exponent,negativeInteger,negativeExponent);
  94.          //Reset parsing state
  95.          state = 0; integer=0; decimal=0; exponent=0; dMul =1;
  96.          negativeInteger=false; negativeExponent=false; readNumber=false;
  97.          //This terminating char was possibly the start of next number. Start from this character
  98.          if(isDecimalP || sign!=0) i-=1;
  99.        }
  100.    }
  101.    
  102.    return output;
  103.  }
  104.  
  105. float _parseFloatHelper(int integer, float decimal, int exponent, bool negI, bool negE)
  106.  {
  107.    //Calculate the number with no exponent applied
  108.    float x = float(integer) + decimal * 0.1f;
  109.    //Apply 10^E
  110.    float mul = negE?0.1f:10.0f;
  111.    for(int i=0; i<exponent; i++)
  112.       x = x*mul;
  113.    //Apply sign of the number
  114.    return negI?-x:x;
  115.  }
  116. ///////////////////////////////
  117. //- Float Parsing
  118. ///////////////////////////////
  119. ///////////////////////////////
  120. //+ Integer Parsing
  121. ///////////////////////////////
  122. int[] parseStringToIntArray(string &in asString)
  123.  {
  124.    int[] output = {};
  125.    int integer = 0;      //Integer part of the number
  126.    int exponent = 0;      //Exponent of the number
  127.    bool negativeInteger = false; //Is the integer part negative
  128.    bool negativeExponent = false; //Is the exponent part negative
  129.    bool readNumber = false;      //Read a number yet or not (stops +e etc returning 0's).
  130.    
  131.    //Parsing loop
  132.    int state = 0;
  133.    string temp = asString + "!"; //Add an invalid character to end of string
  134.    for(uint i=0; i<temp.length(); i++)
  135.     {
  136.       //Determine properties about this character
  137.       uint8 chr = temp[i];
  138.       int  digit = _parseDigit(chr);
  139.       int sign     = _parseSign(chr);
  140.       bool isExponent = _parseHasExponent(chr);
  141.       bool isWhitesp  = _parseHasWhitespace(chr);
  142.       bool isDigit    = digit!=-1;
  143.      
  144.       switch(state)
  145.       {
  146.          case 0: //Initial state
  147.             {
  148.                if(sign != 0)      { negativeInteger=(sign<0); integer =0; state=1; } //Read +/-XX
  149.                else if(isDigit)   { integer = digit; state = 1; readNumber=true; } //Read N
  150.                break;
  151.             }
  152.          case 1: //Read the number part
  153.             {
  154.                if(isDigit)           { integer = (integer * 10) + digit; readNumber=true; } //Read NNXX
  155.                else if(isExponent && readNumber) { state = 3; } //Read NNeXX -> assume NN.0eXX
  156.                else if(readNumber)   { state = -1; }            //Finished reading the number.
  157.                else                  { state = 0;  }
  158.                break;
  159.             }
  160.          case 3: //Ignore a single whitespace char after the exponent.
  161.             {
  162.                if(isDigit)         { exponent = digit; state = 5; } //Read NNeXX
  163.                else if(isWhitesp)  { state = 4; } //Read NNe XX
  164.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; }
  165.                else                { state = -1; }
  166.                break;
  167.             }
  168.          case 4: //Read a +/- Sign or a digit for the exponent
  169.             {
  170.                if(isDigit)         { exponent = digit; state = 5; } //Read NNe NX
  171.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; } //Read NNe +/-XX
  172.                else                { state = -1; }
  173.                break;
  174.             }
  175.          case 5: //Reading the exponent
  176.             {
  177.                if(isDigit)  { exponent = (exponent * 10) + digit; } //Read NNe NX
  178.                else         { state = -1; }
  179.                break;
  180.             }
  181.       }
  182.       //At the end of a number?
  183.       if(state < 0)
  184.        {
  185.           //Construct the number & add it to the output array
  186.          int index = output.length(); output.resize(index+1);
  187.          output[index] = _parseIntHelper(integer,exponent,negativeInteger,negativeExponent);
  188.          //Reset parsing state
  189.          state = 0; integer=0; exponent=0; readNumber=false;
  190.          negativeInteger=false; negativeExponent=false;
  191.          //This terminating char was possibly the start of next number. Start from this character
  192.          if(sign!=0) i-=1;
  193.        }
  194.    }
  195.    
  196.    return output;
  197.  }
  198.  
  199. int _parseIntHelper(int integer, int exponent, bool negI, bool negE)
  200.  {
  201.    //Calculate the number with no exponent applied
  202.    int x = integer;
  203.    //Apply 10^E
  204.    for(int i=0; i<exponent; i++)
  205.       x = negE?(x/10):(x*10);
  206.    //Apply sign of the number
  207.    return negI?-x:x;
  208.  }
  209. ///////////////////////////////
  210. //- Integer Parsing
  211. ///////////////////////////////
  212. ///////////////////////////////
  213. //+ Fast UINT Parse
  214. ///////////////////////////////
  215. uint parseStringUInt(string &in asString) {
  216.     uint output = 0;
  217.     for(uint i=0; i<asString.length(); i++) {
  218.       int digit = _parseDigit(asString[i]);
  219.       output = (digit != -1)?(10*output+digit):(output); }
  220.     return output;
  221. }
  222. ///////////////////////////////
  223. //-
  224. ///////////////////////////////
  225.  
  226. //+ Parsing Helper Functions
  227. int _parseDigit(uint8 digit) {
  228.     int d = digit-48; //48 is ASCII code for 0
  229.     return ((d >= 0)&&(d<=9)) ? d : -1;
  230. }
  231. int _parseSign(uint8 chr) {
  232.  if (chr == 45) return -1;
  233.  else if(chr == 43) return 1;
  234.  else return 0;
  235. }
  236. bool _parseHasExponent(uint8 chr) { return (chr == 69) || (chr == 101); }
  237. bool _parseHasDecimalPoint(uint8 chr) { return (chr==46); }
  238. bool _parseHasWhitespace(uint8 chr) { return (chr == 43)||(chr == 32); }
  239. //-
  240.  
  241. ///////////////////////////////
  242. //End String Parsing
  243. ///////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement