title: C# Parse IF-ELSE Statement
body: <p><strong>UPDATE</strong></p>
  
  <p>I don´t want you to do my Work and write code for me I just wanted a nurge in the right Direction!</p>
  
  <p>So I have to be more specific with my Problem, give me a chance to do some work on this and I will update my question with the results ;-)</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I´ve solved my Problem with Roslyn maybe not very elegant but it work for my needs, here is the code ;-)</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using Roslyn.Compilers;
  using Roslyn.Compilers.CSharp;
  
  namespace ParserTest
  {
      public class MyParser
      {
          private int _currentLevel = 1;
  
          public void TestMethod()
          {
              string testString =
              @"  if(@ISEMPTY(temp.tis_filterstatus2))
                  {
                      tis_datasheet_selection.is_selected = 'Y'
                  }
                  else
                  {
                      if(@ISEMPTY(temp.tis_programmtyp_filter)) { }
                      else
                      {
                           AND tis_programme_v.type = '@SUB(temp.tis_programmtyp_filter)'
                      }
                      if(@ISEMPTY(temp.tis_programmfilter)) { }
                      else
                      {
                           AND tis_programme_v.programm LIKE '@SUB(temp.tis_programmfilter)%'
                      }";
  
              var result = this.Parse(testString);
              var finalResult = this.GenerateDsl(result);
          }
  
          public List&lt;IfStatement&gt; Parse(string strToParse)
          {
              var result = new List&lt;IfStatement&gt;();
              var syntaxTree = SyntaxTree.ParseText(@"using System;class C{static void M(){" + strToParse + "}}");
  
              var rootNodes = syntaxTree.GetRoot().DescendantNodes().Where(getRootNodes);
  
              result = rootNodes.Select(n =&gt; ToIfStatement(n, null)).ToList();
              ApplyNestingLevel(result);
  
              return result;
          }
  
          private string GenerateDsl(List&lt;IfStatement&gt; list)
          {
              var sb = new StringBuilder();
  
              foreach(var ifStmt in list)
              {
                  IfStatementToDsl(ifStmt, sb);
              }
              return sb.ToString();
          }
  
          private string IfStatementToDsl(IfStatement ifStmt, StringBuilder sb)
          {
              string sqr = "";
              for (int i = 0; i &lt; ifStmt.Level; i++)
              {
                  sqr += "'";
              }
  
              sb.Append("@IF(");
              sb.Append(ifStmt.Condition.ApplyLevel(ifStmt.Level) + "," + sqr);
              sb.Append(ifStmt.Statement.ApplyLevel(ifStmt.Level));
              if(ifStmt.Childs.Count &gt; 0)
              {
                  foreach(var c in ifStmt.Childs)
                  {
                      IfStatementToDsl(c, sb);
                  }
              }
              sb.Append(sqr + "," + sqr);
              if(ifStmt.Else != null)
              {
                  sb.Append(ifStmt.Else.Statement.ApplyLevel(ifStmt.Level));
  
                  foreach(var c in ifStmt.Else.Childs)
                  {
                      IfStatementToDsl(c, sb);
                  }
              }
              sb.Append(sqr + ")");
              return sb.ToString();
          }
  
          #region Parsing-Methods
  
          private IfStatement ToIfStatement(SyntaxNode node, SyntaxNode parent)
          {
              var ifNode = (IfStatementSyntax)node;
  
              var ifStmt = new IfStatement
              {
                  Condition = ifNode.Condition.ToString(),
                  Statement = GetIfStatement(ifNode),
                  Childs = GetIfChilds(ifNode)
              };
              if (ifNode.Else != null)
              {
                  ifStmt.Else = new ElseStatement
                  {
                      Statement = GetElseStatement(ifNode.Else),
                      Childs = GetElseChilds(ifNode.Else)
                  };
              }
              return ifStmt;
          }
  
          private List&lt;IfStatement&gt; GetIfChilds(IfStatementSyntax node)
          {
              var childs = node.Statement.DescendantNodes().Where(n =&gt; WhereIfNodes(n, node));
              return childs.Select(n =&gt; ToIfStatement(n, node)).ToList();
          }
  
          private List&lt;IfStatement&gt; GetElseChilds(ElseClauseSyntax node)
          {
              var childs = node.Statement.DescendantNodes().Where(n =&gt; WhereElseNodes(n, node));
              return childs.Select(n =&gt; ToIfStatement(n, node)).ToList();
          }
  
          private string GetIfStatement(IfStatementSyntax node)
          {
              var result = node.Statement.DescendantNodes().Where(n =&gt; WhereIfStatement(n, node));
              string returnValue = "";
              foreach (var n in result)
              {
                  returnValue += n.ToString();
              }
              return returnValue.CleanString();
          }
  
          private string GetElseStatement(ElseClauseSyntax node)
          {
              var result = node.Statement.DescendantNodes().Where(n =&gt; WhereElseStatement(n, node));
              string returnValue = "";
              foreach (var n in result)
              {
                  returnValue += n.ToString() + " ";
              }
              return returnValue.CleanString();
          }
  
          private void ApplyNestingLevel(List&lt;IfStatement&gt; list)
          {
              foreach (var item in list)
              {
                  item.Level = _currentLevel;
                  if (item.Childs.Count &gt; 0 || (item.Else != null &amp;&amp; item.Else.Childs.Count &gt; 0))
                  {
                      _currentLevel++;
                  }
                  ApplyNestingLevel(item.Childs);
                  if (item.Else != null)
                  {
                      ApplyNestingLevel(item.Else.Childs);
                  }
              }
          }
  
          #endregion
  
          #region Linq Where-Conditions
  
          private bool WhereIfNodes(SyntaxNode node, IfStatementSyntax parent)
          {
              if(node.Kind == SyntaxKind.IfStatement &amp;&amp; (node.Parent.Parent == parent))
              {
                  return true;
              }
              return false;
          }
  
          private bool WhereElseNodes(SyntaxNode node, ElseClauseSyntax parent)
          {
              if (node.Kind == SyntaxKind.IfStatement &amp;&amp; (node.Parent.Parent == parent))
              {
                  return true;
              }
              return false;
          }
  
          private bool WhereIfStatement(SyntaxNode node, IfStatementSyntax parent)
          {
              if ((node.Kind == SyntaxKind.ExpressionStatement || node.Kind == SyntaxKind.LocalDeclarationStatement) 
                  &amp;&amp; (node.Parent.Parent == parent))
              {
                  return true;
              }
              return false;
          }
  
          private bool WhereElseStatement(SyntaxNode node, ElseClauseSyntax parent)
          {
              if ((node.Kind == SyntaxKind.ExpressionStatement || node.Kind == SyntaxKind.LocalDeclarationStatement) 
                  &amp;&amp; (node.Parent.Parent == parent))
              {
                  return true;
              }
              return false;
          }
  
          private Func&lt;SyntaxNode, bool&gt; getRootNodes =
              n =&gt; n.Kind == SyntaxKind.IfStatement &amp;&amp;
                  (n.Parent.Parent.Kind != SyntaxKind.ElseClause &amp;&amp; n.Parent.Parent.Kind != SyntaxKind.IfStatement);
  
          #endregion
      }
  
      public class IfStatement
      {
          public int Level { get; set; }
  
          public string Condition { get; set; }
  
          public string Statement { get; set; }
  
          public ElseStatement Else { get; set; }
  
          public List&lt;IfStatement&gt; Childs { get; set; }
      }
  
      public class ElseStatement
      {
          public string Statement { get; set; }
  
          public List&lt;IfStatement&gt; Childs { get; set; }
      }
  
      public static class Ext
      {
          public static string CleanString(this string value)
          {
              return value.Replace("\t", "").Replace("\n", "").Replace("\r", "");
          }
  
          public static string ApplyLevel(this string value, int level)
          {
              int multiplier = level * 2;
              if (level == 0) 
                  multiplier = 1;
              var sb = new StringBuilder(multiplier);
              for (int i = 0; i &lt; multiplier; i++)
              {
                  sb.Append("'");
              }
              return value.Replace("'", sb.ToString());
          }
      }
  }
  </code></pre>
  
  <p>I have to write if-else Statements in a Domain-Specific-Language which is really a pain in the ass!</p>
  
  <p>(The DSL is from a Third-Party-Tool which I have to use to generate WHERE-Statements for SQL-Queries)</p>
  
  <p>Syntax:</p>
  
  <pre><code>@IF(@ISEMPTY(@SUB(temp.last_name))),'if true','else')
  </code></pre>
  
  <p>@SUB() reads a textboxvalue</p>
  
  <p>Sample:</p>
  
  <pre><code>@IF(@ISEMPTY(@SUB(temp.last_name))),'','account_contact.last_name = ''DOE'' ')
  </code></pre>
  
  <p>you have to double your single-quotes in the else statement and if you want to nest different "if-else" every time you go a level deeper you have to double the doubled single-quotes!</p>
  
  <p>You see it´s not very simple to write if you have complicated contitions...</p>
  
  <p>So I thought I write a parser that transforms a normal if-else statement to this DSL-Syntax!</p>
  
  <p>The Parser should create objects of this class:</p>
  
  <pre><code>public class IfCondition
  {
      public int ID { get; set; }
  
      public int ParentID { get; set; }
  
      public int Level { get; set; }
  
      public string Condition { get; set; }
  
      public string Content { get; set; }
  
      public string ElseContent { get; set; }
  }
  </code></pre>
  
  <p>based on a Collection of this Objects I could generate the DSL-Statements!</p>
  
  <p>So my Problem is I really don´t have a clue, how to parse a String like this:</p>
  
  <pre><code>IF(@ISEMPTY(@SUB(temp.last_name))) { } 
  ELSE
  {
     IF(@SUB(temp.test) = 'Y')
     {
         account_contact.last_name = 'DOE'
     }
     ELSE
     {
         account_contat.first_name = "JOHN"
     }
  }
  </code></pre>
  
  <p>can somebody give me a nudge in the right direction?</p>