2012-04-23 3 views
0

Я пытаюсь преобразовать IF заявления, как показано нижеПреобразование если заявление условного оператора

SET RESULT = IF(C>(X-2), (A+B), C) //IF C< X-2 return A+B otherwise return C 

в условный оператор, как показано ниже

SET RESULT = C>(X-2)?(A+B):C 

Я написал код, который просканировать всю строку и вид вхождений IF, ( и ,. Мой алгоритм не работает, когда есть более чем 1 IF заявление, например, как показано ниже

SET RESULT = IF(C>(X-2), IF(P>C,2,3),C) 

Вот код ...

 string data = "SET RESULT=IF(C>(X-2), (A+B), C)"; 
     string output = string.Empty; 

     int indexofIF = data.IndexOf("IF"); 
     int obCount = 0; 
     int cbCount = 0; 
     if (indexofIF > -1) 
     { 
      string script = data.Substring(indexOfIF, (data.Length-indexOfIF-1)) 
      for(int index=0; index<script.Length; index++) 
      { 
       int obIndex = data.IndexOf('(', index); 
       if(obIndex>-1) 
        obCount++; 
       int cbIndex = data.IndexOf(')', index); 
       if(cbIndex>-1) 
        cbCount++; 

       if(obCount==cbCount)//Found the end of If statement 
       { 
        string tempData = data.Substring(0, index); 
        int count = tempData.Count(f => f == ',');//Get the number of occurences of ',' 
        if (count == 2)//There are only 2 commas 
        { 
         int firstIndex = tempData.IndexOf(','); 
         int lastIndex = tempData.LastIndexOf(','); 
         string condtion = tempData.Substring(3, (firstIndex - 4)); 
         string trueCond = tempData.Substring(firstIndex + 1, (lastIndex - firstIndex - 1)); 
         string falseCond = tempData.Substring(lastIndex + 1, (index - lastIndex - 1)); 
         output = condtion + "?" + trueCond + ":" + falseCond; 

        } 
        else //More than 2 commas 
        { 

        } 
       } 

      } 

     } 

Я не уверен, если это будет работать для сложных сценариев. Есть ли лучший способ сделать это? Возможно, используя regex или любую другую операцию замены струн.

ответ

0

Вы на правильном пути.

Я:

  • Прочитайте каждый символ в небольшой буфер
  • оценить буфер для поиска слово «IF»
  • установлен флаг так, вы знаете, что в операторе IF
  • ясно буфер
  • оценки для круглых скобок
  • отслеживать открытия/закрытия скобок
  • не выполнять любую дополнительную логику (например, запятую синтаксического анализа)
  • продолжаются до конца строки

Возможно, используя регулярное выражение или любую другую операцию замены строки ..

(IF.*?(?=IF|$)) вспыхивает несколько операторов IF, но он не обрабатывает дополнительный синтаксический анализ и требует, чтобы входные данные соответствовали строгой структуре. Следить за скобками сложно или невозможно (см. Комментарии к этому ответу) и более легко обрабатывается конечным автоматом.

Лично мне нравится управление/гибкость синтаксического анализа. Такие инструменты, как Code Mirror, используют этот подход для синтаксического анализа исходного кода.

Вы можете обнаружить, что регулярное выражение полезно после того, как вы успешно извлекли часть строки (например, чтобы разложить формулу, например A + B > C, на ее части).

+0

Произвольное совпадающее совпадение парнов не является обычным языком, поэтому вы не найдете чисто регулярное выражение, если не ограничиваете пространство проблем. –

+0

@RaymondChen - согласился, единственный способ сделать работу с регулярным выражением состоял в том, чтобы ограничить входные данные фиксированным числом скобок, которые я не рассматриваю как жизнеспособное решение. –

+0

FWIW, так называемые «регулярные выражения» Perl5 и те, что заимствовали у него на многих языках, фактически могут соответствовать произвольно вложенным парам разделителей, используя рекурсивную интерполяцию.Не то, чтобы я рекомендовал это делать. В любом случае, я не думаю, что C#. –

Смежные вопросы