Click here to Skip to main content
15,885,537 members
Articles / Programming Languages / C#

An Implementation of Regular Expression Parser in C#

Rate me:
Please Sign up or sign in to vote.
4.91/5 (43 votes)
24 Jun 2009CPOL8 min read 185.2K   7.2K   116  
An article on how one can implement regular expression parser
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using RegularExpression;

namespace Driver
{
  public partial class frmNfa : Form
  {

    RegEx m_regEx = new RegEx();
    bool m_bFirstTime = true;

    public frmNfa()
    {
      InitializeComponent();
    }

    private void btnCompile_Click(object sender, EventArgs e)
    {
      if (txtRegEx.Text.Length == 0)
      {
        MessageBox.Show("You must enter a regular expression before compiling.");
        txtRegEx.Select();
        return;
      }
      StringBuilder sb = new StringBuilder(10000);
      try
      {
        ErrorCode errCode = m_regEx.CompileWithStats(this.txtRegEx.Text, sb);
        if (errCode != ErrorCode.ERR_SUCCESS)
        {
          string sErrSubstring = txtRegEx.Text.Substring(m_regEx.GetLastErrorPosition(), m_regEx.GetLastErrorLength());
          string sFormat = "Error occured during compilation.\nCode: {0}\nAt: {1}\nSubstring: {2}";
          sFormat = String.Format(sFormat, errCode.ToString(), m_regEx.GetLastErrorPosition(), sErrSubstring );
          txtRegEx.Select(m_regEx.GetLastErrorPosition(), m_regEx.GetLastErrorLength() );
          MessageBox.Show(sFormat);
          txtRegEx.Select();
          return;
        }
        this.matchDS.Clear();
      }
      catch (Exception ex)
      {
        MessageBox.Show("Error occured during compilation.\n\n" + ex.Message);
        txtRegEx.Select();
        return;
      }
      txtStat.Text = sb.ToString();
      m_bFirstTime = true;
    }

    private void txtStat_KeyDown(object sender, KeyEventArgs e)
    {
      m_bFirstTime = true;

    }

    private void txtStat_MouseDown(object sender, MouseEventArgs e)
    {
      m_bFirstTime = true;

    }

    private void btnFindAll_Click(object sender, EventArgs e)
    {
      if (!m_regEx.IsReady())
      {
        MessageBox.Show("You must first compile a regular expression.");
        txtRegEx.Focus();
        return;
      }

      matchDS.Clear();
      matchDS.AcceptChanges();

      int nFoundStart = -1;
      int nFoundEnd = -1;
      int nStartAt = 0;
      int nMatchLength = -1;

      do
      {
        bool bFound = m_regEx.FindMatch(txtSearchString.Text, nStartAt, txtSearchString.Text.Length - 1, ref nFoundStart, ref nFoundEnd);
        if (bFound == true)
        {
          string sSubstring = "{Empty String}";
          nMatchLength = nFoundEnd - nFoundStart + 1;
          if (nMatchLength > 0)
          {
            sSubstring = txtSearchString.Text.Substring(nFoundStart, nMatchLength);
          }
          matchDS.MatchInfo.AddMatchInfoRow(sSubstring, nFoundStart, nFoundEnd, nMatchLength);
          matchDS.AcceptChanges();
          nStartAt = nFoundEnd + 1;
        }
        else
        {
          nStartAt++;
        }
      } while (nStartAt < txtSearchString.Text.Length);


    }

    private void btnFindNext_Click(object sender, EventArgs e)
    {
      if (!m_regEx.IsReady())
      {
        MessageBox.Show("You must first compile a regular expression.");
        txtRegEx.Focus();
        return;
      }
      int nFoundStart = -1;
      int nFoundEnd = -1;
      int nStartAt = -1;

      if (m_bFirstTime)
      {
        nStartAt = txtSearchString.SelectionStart;
        m_bFirstTime = false;
      }
      else
      {
        nStartAt = txtSearchString.SelectionStart + 1;
      }

      bool bFound = m_regEx.FindMatch(txtSearchString.Text, nStartAt, txtSearchString.Text.Length - 1, ref nFoundStart, ref nFoundEnd);
      if (bFound)
      {
        int nMatchLength = nFoundEnd - nFoundStart + 1;
        if (nMatchLength == 0)
        {
          MessageBox.Show("Matched an empty string at position " + nFoundStart.ToString() + ".");
        }
        else
        {
          txtSearchString.Select();
          txtSearchString.Select(nFoundStart, nMatchLength);
        }
      }
      else
      {
        MessageBox.Show("No match found.");
      }
    }

    private void grdResult_RowEnter(object sender, DataGridViewCellEventArgs e)
    {
      try
      {
        DataRowView drv = (DataRowView)grdResult.Rows[e.RowIndex].DataBoundItem;
        MatchInfoDS.MatchInfoRow r = (MatchInfoDS.MatchInfoRow)drv.Row;

        txtSearchString.Select(r.StartIndex, r.Length);
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }

    private void txtSearchString_KeyDown(object sender, KeyEventArgs e)
    {
      m_bFirstTime = true;
    }

    private void txtSearchString_MouseDown(object sender, MouseEventArgs e)
    {
      m_bFirstTime = true;
    }


    private void txtSearchString_Enter(object sender, EventArgs e)
    {
      this.AcceptButton = btnFindAll;

    }

    private void txtRegEx_Enter(object sender, EventArgs e)
    {
      this.AcceptButton = btnCompile;

    }


    private void chkGreedy_CheckedChanged(object sender, EventArgs e)
    {
      m_regEx.UseGreedy = chkGreedy.Checked;

    }

    private void btnFindFirst_Click(object sender, EventArgs e)
    {
      if (!m_regEx.IsReady())
      {
        MessageBox.Show("You must first compile a regular expression.");
        txtRegEx.Focus();
        return;
      }
      int nFoundStart = -1;
      int nFoundEnd = -1;

      bool bFound = m_regEx.FindMatch(txtSearchString.Text, 0, txtSearchString.Text.Length - 1, ref nFoundStart, ref nFoundEnd);
      if (bFound)
      {
        int nMatchLength = nFoundEnd - nFoundStart + 1;
        if (nMatchLength == 0)
        {
          MessageBox.Show("Matched an empty string at position " + nFoundStart.ToString() + ".");
        }
        else
        {
          txtSearchString.Select();
          txtSearchString.Select(nFoundStart, nMatchLength);
        }
      }
      else
      {
        MessageBox.Show("No match found.");
      }
    }

    private void TestMatch()
    {
      RegEx re = new RegEx();
      string sPattern = "a_*p";
      ErrorCode errCode = re.Compile(sPattern);

      if (errCode != ErrorCode.ERR_SUCCESS)
      {
        string sErrSubstring = sPattern.Substring(re.GetLastErrorPosition(), re.GetLastErrorLength());
        string sFormat = "Error occured during compilation.\nCode: {0}\nAt: {1}\nSubstring: {2}";
        sFormat = String.Format(sFormat, errCode.ToString(), m_regEx.GetLastErrorPosition(), sErrSubstring);
        MessageBox.Show(sFormat);
        return;
      }

      int nFoundStart = -1;
      int nFoundEnd = -1;
      string sToSearch = "appleandpotato";

      bool bFound = m_regEx.FindMatch(sToSearch, 0, sToSearch.Length - 1, ref nFoundStart, ref nFoundEnd);
      if (bFound)
      {
        int nMatchLength = nFoundEnd - nFoundStart + 1;
        if (nMatchLength == 0)
        {
          MessageBox.Show("Matched an empty string at position " + nFoundStart.ToString() + ".");
        }
        else
        {
          string sMatchString = sToSearch.Substring(nFoundStart, nMatchLength);

          MessageBox.Show("Match found at: " + nFoundStart.ToString() + "\n" + sMatchString);          
        }
      }
      else
      {
        MessageBox.Show("No match found.");
      }

    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Denmark Denmark
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions