⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeformatterfactory.cs

📁 C#更新版的C语言的词法分析器
💻 CS
字号:
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace CodeFormatter
{
    /// <summary>
    /// CodeFormatterFactory 的摘要说明。
    /// c 代码解析,不支持中文
    /// </summary>
    public class CodeFormatterFactory
    {
        /*源代码*/
        private string sourceCode = "";

        /*C语言所有关键字,共32个*/
        ArrayList KeyWordList = new ArrayList();

        /*运算、限界符*/
        ArrayList LimitList = new ArrayList();

        /*常量表*/
        ArrayList ConstList = new ArrayList();

        /*标识符*/
        ArrayList IdentifierList = new ArrayList();

        /*输出*/
        ArrayList OutputList = new ArrayList();

        public CodeFormatterFactory()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
            init();
        }

        public string SourceCode
        {
            get { return this.sourceCode; }
            set { this.sourceCode = value; }
        }

        public string ParseMessages
        {
            get
            {
                string pm = "";

                IEnumerator ie = this.OutputList.GetEnumerator();
                while (ie.MoveNext())
                    pm += ie.Current.ToString() + "\r\n";
                return pm;
            }
        }

        private void init()
        {
            /*C语言所有关键字,共32个*/
            string[] key = new string[]{" ","auto","break","case","char","const","continue","default","do","double",
                                 "else","enum","extern","float","for","goto","if","int","long","register",
                                 "return","short","signed","sizeof","static","struct","switch","typedef",
                                 "union","unsigned","void","volatile","while"};
            /*运算、限界符*/
            string[] limit = new string[]{" ","(",")","[","]","->",".","!","++","--","&","~",
                                   "*","/","%","+","-","<<",">>","<","<=",">",">=","==","!=","&&","||",
                                   "=","+=","-=","*=","/=",",",";","{","}","#","_","'"};

            this.KeyWordList.Clear();
            this.KeyWordList.TrimToSize();
            for (int i = 1; i < key.Length; i++)
                this.KeyWordList.Add(key[i]);

            this.LimitList.Clear();
            this.LimitList.TrimToSize();
            for (int i = 1; i < limit.Length; i++)
                this.LimitList.Add(limit[i]);

            this.ConstList.Clear();
            this.ConstList.TrimToSize();

            this.IdentifierList.Clear();
            this.IdentifierList.TrimToSize();

            this.OutputList.Clear();
            this.OutputList.TrimToSize();
        }

        /*******************************************
        * 十进制转二进制函数
        *******************************************/
        private string dtb(string buf)
        {
            int[] temp = new int[20];
            string binary = "";
            int val = 0, i = 0;

            /*先将字符转化为十进制数*/
            try
            {
                val = Convert.ToInt32(buf);
            }
            catch
            {
                val = 0;
            }

            if (val == 0)
            {
                return (val.ToString());
            }

            i = 0;
            while (val != 0)
            {
                temp[i++] = val % 2;
                val /= 2;
            }

            binary = "";
            for (int j = 0; j <= i - 1; j++)
                binary += (char)(temp[i - j - 1] + 48);

            return (binary);
        }

        /*******************************************
        * 根据不同命令查表或造表函数
        *******************************************/
        private int find(string buf, int type, int command)
        {
            int number = 0;
            string temp;

            IEnumerator ie = null;
            ArrayList al = null;
            switch (type)
            {
                case 1://关键字表
                    ie = this.KeyWordList.GetEnumerator();
                    break;
                case 2://标识符表
                    ie = this.IdentifierList.GetEnumerator();
                    break;
                case 3://常数表
                    ie = this.ConstList.GetEnumerator();
                    break;
                case 4://运算、限界符表
                    ie = this.LimitList.GetEnumerator();
                    break;
            }

            if (ie != null)
                while (ie.MoveNext())
                {
                    temp = ie.Current.ToString();
                    if (temp.Trim().ToLower() == buf.Trim().ToLower())
                    {
                        return number;
                    }
                    number++;
                }

            if (command == 1)
            {
                /*找不到,当只需查表,返回0,否则还需造表*/
                return 0;
            }

            switch (type)
            {
                case 1: al = this.KeyWordList; break;
                case 2: al = this.IdentifierList; break;
                case 3: al = this.ConstList; break;
                case 4: al = this.LimitList; break;
            }
            if (al != null)
                al.Add(buf);

            return number + 1;
        }
        /*******************************************
        * 数字串处理函数
        *******************************************/
        private void cs_manage(string buffer)
        {
            string binary = dtb(buffer);
            int result = find(binary, 3, 2);
            this.OutputList.Add(String.Format("{0}\t\t\t3\t\t\t{1}", buffer, result));
        }

        /*******************************************
        * 字符串处理函数 
        *******************************************/
        private void ch_manage(string buffer)
        {
            int result = find(buffer, 1, 1);
            if (result != 0)
            {
                this.OutputList.Add(String.Format("{0}\t\t\t1\t\t\t{1}", buffer, result));
            }
            else
            {
                result = find(buffer, 2, 2);
                this.OutputList.Add(String.Format("{0}\t\t\t2\t\t\t{1}", buffer, result));
            }
        }

        /*******************************************
        * 出错处理函数
        *******************************************/
        private void er_manage(char error, int lineno)
        {
            this.OutputList.Add(String.Format("错误关键字: {0} ,所在行: {1}", error, lineno));
        }

        /*******************************************
        * 转换Char数组为string
        ******************************************/
        private string joinString(char[] array, int Length)
        {
            string s = "";
            if (array.Length > 0)
                for (int i = 0; i < Length; i++)
                {
                    if (array[i] != '\0')
                    {
                        s += array[i];
                    }
                    else
                    {
                        break;
                    }
                }
            return s;
        }

        private char getchc(ref int n)
        {
            char[] c = sourceCode.ToCharArray();
            if (n < c.Length)
            {
                char r = c[n];
                n++;
                return r;
            }
            return sourceCode[sourceCode.Length - 1];
        }
        /*******************************************
        * 扫描程序
        ********************************************/
        public void Parse()
        {
            //StreamWriter fpout = null;
            char ch;
            int i = 0, line = 1;
            int count, result, errorno = 0;
            char[] array = new char[30];
            string word = "";

            /*按字符依次扫描源程序,直至结束*/
            int n = 0;

            while (n < sourceCode.Length - 1)
            {
                i = 0;
                ch = getchc(ref n);
                /*以字母开头*/
                if (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '_'))
                {
                    while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '_') || ((ch >= '0') && (ch <= '9')))
                    {
                        array[i++] = ch;
                        ch = getchc(ref n);
                    }
                    array[i++] = '\0';
                    word = joinString(array, array.Length);
                    ch_manage(word);
                    if (n < sourceCode.Length) n--;
                }
                else if (ch >= '0' && ch <= '9')
                {
                    /*以数字开头*/
                    while (ch >= '0' && ch <= '9')
                    {
                        array[i++] = ch;
                        ch = getchc(ref n);
                    }
                    array[i++] = '\0';
                    word = joinString(array, array.Length);
                    cs_manage(word);
                    if (n < sourceCode.Length) n--;
                }
                else if ((ch == ' ') || (ch == '\t'))
                    /*消除空格符和水平制表符*/
                    ;
                else if (ch == '\n')
                    /*消除回车并记录行数*/
                    line++;
                else if (ch == '/')
                {
                    /*消除注释*/
                    ch = getchc(ref n);
                    if (ch == '=')
                    {
                        /*判断是否为‘/=’符号*/
                        this.OutputList.Add(String.Format("/=\t\t\t4\t\t\t32"));
                    }
                    else if (ch != '*')
                    {
                        /*若为除号,写入输出*/
                        this.OutputList.Add(String.Format("/\t\t\t4\t\t\t13"));
                        n--;
                    }
                    else if (ch == '*')
                    {
                        /*若为注释的开始,消除包含在里面的所有字符*/
                        count = 0;
                        ch = getchc(ref n);
                        while (count != 2)
                        {
                            /*当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束*/
                            count = 0;
                            while (ch != '*')
                                ch = getchc(ref n);
                            count++;
                            ch = getchc(ref n);
                            if (ch == '/')
                                count++;
                            else
                                ch = getchc(ref n);
                        }
                    }
                }
                else if (ch == '"')
                {
                    /*消除包含在双引号中的字符串常量*/
                    this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37", ch));
                    while (ch != '"')
                        ch = getchc(ref n);
                    this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37", ch));
                }
                else
                {
                    /*首字符为其它字符,即运算限界符或非法字符*/
                    array[0] = ch;
                    /*再读入下一个字符,判断是否为双字符运算、限界符*/
                    ch = getchc(ref n);
                    /*若该字符非结束符*/
                    if (n < sourceCode.Length)
                    {
                        array[1] = ch;
                        array[2] = '\0';
                        word = joinString(array, 2);
                        result = find(word, 4, 1); /*先检索是否为双字符运算、限界符*/
                        if (result == 0)
                        {
                            /*若不是*/
                            array[2] = '\0';
                            word = joinString(array, 1);
                            result = find(word, 4, 1);
                            /*检索是否为单字符运算、限界符*/
                            if (result == 0)
                            {
                                /*若还不是,则为非法字符*/
                                er_manage(array[0], line);
                                errorno++;
                                n--;
                            }
                            else
                            {
                                /*若为单字符运算、限界符,写入输出并将扫描指针回退一个字符*/
                                this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}\t", word, result));
                                n--;
                            }
                        }
                        else
                        {
                            /*若为双字符运算、限界符,写输出*/
                            this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}", word, result));
                        }
                    }
                    else
                    {
                        /*若读入的下一个字符为结束符*/
                        array[2] = '\0';
                        word = joinString(array, 1);
                        /*只考虑是否为单字符运算、限界符*/
                        result = find(word, 4, 1);
                        /*若不是,转出错处理*/
                        if (result == 0)
                            er_manage(array[0], line);
                        else
                        {
                            /*若是,写输出*/
                            this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}", word, result));
                        }
                    }
                }
                ch = getchc(ref n);
            }
            /*报告错误字符个数*/
            this.OutputList.Add(String.Format("\n共有 {0} 个错误.\n", errorno));
        }

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -