Tuesday, June 3, 2014

Delimiter Matching

Below is the C# program to check whether the delimiters are opened and closed correctly. The program only supports for 3 kinds of delimiters, including (), {}, and [].

A stack is used to store the opening delimiters including the line and the column whether the delimiter appears.

You can download the complete program at https://dl.dropboxusercontent.com/u/7046415/Blogger/CheckMatchingDelimeter.exe

amespace CheckMatchingDelimeter
{
    class Program
    {
        static private List openDelimeters = new List() { '(', '{', '[' };
        static private List closeDelimeters = new List() { ')', '}', ']' };

        struct DelimiterInfo
        {
            public char c;
            public int line;
            public int col;

            public DelimiterInfo(char c, int line, int col)
            {
                this.c = c;
                this.line = line;
                this.col = col;
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Run this execution file to check delimeter open/close matching of files in the same folder.");
            string directory = Directory.GetCurrentDirectory();

            string name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;


            foreach (var file in Directory.GetFiles(directory))
            {
                if (Path.GetFileName(file) != name + ".exe")
                {
                    Console.WriteLine("Process " + Path.GetFileName(file));

                    string[] fileContent = File.ReadAllLines(file);
                    Stack delimeters = new Stack();
                    for (int i = 0; i < fileContent.Length; i++)
                    {
                        HandleLine(fileContent[i], i + 1, delimeters);
                    }

                    if (delimeters.Count > 0)
                    {
                        foreach (DelimiterInfo delimeter in delimeters)
                        {
                            Console.WriteLine("Line " + delimeter.line + ", Col " + delimeter.col + ": Lack of close");
                        }

                    }
                }
            }

            Console.WriteLine("Enter to exit!");
            Console.Read();
        }

        static void HandleLine(string line, int lineIndex, Stack delimeters)
        {
            for (int i = 0; i < line.Length; i++ )
            {
                char c = line[i];

                if (openDelimeters.Contains(c))
                {
                    delimeters.Push(new DelimiterInfo(c, lineIndex, i + 1));
                }
                else if (closeDelimeters.Contains(c))
                {
                    if (delimeters.Count == 0)
                    {
                        Console.WriteLine("Line " + lineIndex + ", Col " + (i+1) + ": No open before close");
                    }
                    else if (IsMatch(delimeters.Peek().c, c))
                    {
                        delimeters.Pop();
                    }
                    else
                    {
                        delimeters.Pop();
                        Console.WriteLine("Line " + lineIndex + ", Col " + (i + 1) + ": Mismatch");
                    }
                }
            }
  
        }

        private static bool IsMatch(char current, char next)
        {
            for(int i = 0; i < openDelimeters.Count; i++)
            {
                if(openDelimeters[i] == current && closeDelimeters[i]== next)
                {
                    return true;
                }
            }

            return false;
        }
    }
}