Changeset 865


Ignore:
Timestamp:
Jun 23, 2003, 2:58:43 PM (18 years ago)
Author:
luba
Message:
  • To_m_Int function creates a string which consists only of acceptable terms
  • from the sourse expression
File:
1 edited

Legend:

Unmodified
Added
Removed
  • to-imperative/trunk/library/Convert/to_int.cc

    r821 r865  
    1414namespace Convert
    1515{
     16/*
     171. Ищем цифру, + или -.
     18    - Если встретили + или -, переходим к шагу 2.
     19    - Если встретили цифру, переходим к шагу 3.
     20    - Если встретили пробел, ищем дальше.
     21    - Если встретили что-то ещё, то $fail.
     22    - Если кончилась строка, полученная из текущего терма, берём след.
     23    - Если выражение кончилось, то $fail.
     242. Ищем первую цифру.
     25    - Сдвигаемся на символ влево.
     26    - Если это цифра, переходим к шагу 3.
     27    - Если что-то ещё, то $fail.
     28    - Если не смогли сдвинуться, потому что строка кончилась, берём
     29      след. терм.
     30    - Если выражение кончилось, то $fail.
     313. Ищем первую ненулевую цифру.
     32    - Если встретили ненулевую цифру, переходим к шагу 4.
     33    - Если встретили 0, ищем дальше.
     34    - Если встретили пробел, то кладём текущую строку во вспомогательную
     35      и переходим к последнему шагу.
     36    - Если встретили что-то ещё, то $fail.
     37    - Если кончилась строка, полученная из текущего терма, берём след.
     38    - Если выражение кончилось, то возвращаем ShortInt::create_expr(0).
     394. Считываем цифры и только цифры.
     40    - Если встретили цифру, повторяем шаг 4.
     41    - Если встретили пробел, то приплюсовываем текущую строку ко
     42      вспомогательной и переходим к последнему шагу.
     43    - Если встретили что-то ещё, то $fail.
     44    - Если кончилась строка, полученная из текущего терма, то
     45      приплюсовываем её к нашей вспомогательной строке, и берём след.
     46      терм.
     47    - Если выражение кончилось, то приплюсовываем текущую строку, и
     48      вызываем нужный create_expr от вспомогательной строки.
     49Последний шаг. Обработка завершающих пробелов.
     50    - Если встретили пробел, повторяем шаг.
     51    - Если встретили что-то ещё, то $fail.
     52    - Если кончилась строка, берём след. терм.
     53    - Если выражение кончилось, вызываем нужный create_expr от
     54      вспомогательной строки.
     55
     56*/
    1657
    1758RF_FUNC (To_m_Int, (RF_ARG e_Exp), (RF_RES s_Int))
    1859  Term* t = e_Exp.get_first();
     60  Term* p = e_Exp.get_last();
    1961
     62  pxx::WString str;
    2063  pxx::WString s;
    21   for (; t < e_Exp.get_last(); t++)
    22     s = s + pxx::WString(*t);
     64  size_t j = 0;
     65  size_t k = 0;
     66  size_t len = 0;
     67  size_t length = 0;
     68  bool found = false;
     69  bool space = false;
     70  bool sign = false;
     71  bool digit = false;
    2372
    24   //используется для того, чтобы наличие нулей в начале
    25   //не увеличивало длину числа
    26   //
    27   bool was_zero = false;
     73  for (; t < p; t++) {
     74    s = WString(*t);
     75    len = s.get_length();
     76    for (size_t i = 0; i < len; i++) {
     77      if (s[i] == '+' ) {
     78        found = true; sign = true; k = i; break;
     79      }
     80      else
     81      if (s[i] == '-') {
     82        if (t->get_type() == type_char) {
     83          str = str + s; length++; k = i;
     84        }
     85        found = true; sign = true;
     86        break;
     87      }
     88      else
     89      if (iswdigit(s[i])) {
     90        found = true; k = i; break;
     91      }
     92      else
     93      if (s[i] != ' ') retfail;
     94    }
     95    if (found) break;
     96    else
     97    if (t == p - 1) retfail;
     98  }
    2899
    29   bool prev_sym = false;
    30   bool prev_space = false;
    31 
    32   //показывает, был ли знак '+' или '-' уже
    33   bool flag = false;
    34 
    35   uintptr_t len = 0;
    36   uintptr_t len_max = ShortInt::max_len;
    37   size_t i = 0;
    38   //пропустим все пробелы в начале
    39   for (; i < s.get_length(); i++) {
    40     if (s[i] == ' ') continue;
     100  for (; t < p; t++) {
     101    s = WString(*t);
     102    len = s.get_length();
     103    for (; k < len; k++) {
     104      if (sign) {
     105        sign = false; continue;
     106      }
     107      else
     108      if (iswdigit(s[k])) {
     109        if (s[k] != '0') {
     110          digit = true;
     111          j = k;
     112          break;
     113        }
     114      }
     115      else retfail;
     116    }
     117    if (digit) break;
    41118    else
    42       break;
     119    if (t == p - 1)
     120        s_Int = ShortInt::create_expr(0);
     121    else k = 0;
    43122  }
    44123 
    45   for ( ; i < s.get_length(); i++) {
    46     if (iswdigit(s[i])) {
    47       if(prev_space)
    48           retfail; //встретилась цифу, а пробелы уже были
    49       else {
    50       if (s[i] != '0'){
    51   //если символ не 0, учитываем его длину
    52         len++;
    53         prev_sym = true;
     124  for (; t < p; t++) {
     125    s = WString(*t);
     126    len = s.get_length();
     127    for (; j < len; j++) {
     128      if (s[j] == ' ') {
     129        str = str + s; space = true; length += len; break;
    54130      }
    55131      else
    56   //если 0 уже встречался и были пробелы: ' 0  0'
    57       if (was_zero && prev_space) retfail;
    58       else
    59   //если символ 0 и до этого были символы, надо его посчитать в длине
    60   //и запомнить, что был предыдущий символ 0
    61   //
    62       if (prev_sym){
    63         len++;
    64         was_zero = true; prev_sym = true;
    65       }
     132      if (!iswdigit(s[j])) retfail;
     133      else
     134      if (j == len - 1) {
     135        str = str + s; length += len;
    66136      }
    67137    }
    68       else
    69   //если символ оказался знаком '+' или '-', то проверить, не было ли
    70   //символов до того
    71   //
    72       if ((s[i] == '+' || s[i] == '-'))
    73         if (flag || prev_sym)
    74           retfail; //встретила знак, а он уже был
    75         else {
    76           len++;
    77           flag = true;
    78         }
    79       else
    80   //символ - пробел, запомнить, что был пробел
    81   //
    82       if(s[i] == ' ') prev_space = true;
    83       else
    84   //не цифра и не знак, и не пробел
    85   //
    86         retfail;
     138    if (space) break;
     139    else
     140      j = 0;
     141  }
    87142
    88      
     143  for (; t < p; t++) {
     144    s = WString(*t);
     145    len = s.get_length();
     146    for (; j < len; j++) {
     147      if (s[j] != ' ')
     148        retfail;
     149    }
     150    j = 0;
     151  }   
     152
     153  if (length < ShortInt::max_len) {
     154    s_Int = ShortInt::create_expr(str);
    89155  }
    90   //проверить, что длина не больше, чем допустимая
    91   if (len >= len_max)
     156  else
    92157    RF_LIB_ERROR("Argument too large for conversion");
    93  
    94   s_Int = ShortInt::create_expr(s);
    95158
    96159RF_END
Note: See TracChangeset for help on using the changeset viewer.