词法分析完整代码

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public enum types
    {
        KeyID=1,ParID,Ints,Operator,Split,Floats,ElseID//类型的枚举类型的定义
    }
    //用来存放识别出的单词
    public  class  IDS
    {
        public types type;//类型
        public string data;//值
        public IDS next;//指向下一个IDS的指针
    }
    public  class AccidenceAnalyse
    {
        #region 成员变量
        public char[] AllChars;
        /// <summary>
        /// 全局变量指针,指向当前字符
        /// </summary>
        private int CurrentP;
        private StringBuilder ResultStr;
        private  int _KeyIDnum = 0;
        private  int _ParIDnum = 0;
        private int _IntNum = 0;
        private int _FloatNum = 0;
        private int _SplitNum = 0;
        private int _OperatorNum = 0;
        public int _ElseNum = 0;
        private int _AllNum = 0;
        public int AllNum
        { get { return _AllNum; } }
        public int KeyIDnum
        {
            get { return _KeyIDnum;}
        }
        public int ParIDnum
        {
            get { return _ParIDnum;}
        }
        public int FloatNum
        { get { return _FloatNum; } }
        public int IntNum
        { get { return _IntNum; } }
        public int SplitNum
        { get { return _SplitNum; } }
        public int OperatorNum
        { get { return _OperatorNum; } }
        public int ElseNum
        { get { return _ElseNum; } }
        public  IDS KeyID_Identify;//保留字
        public  IDS ParID_Identify;//普通标识符
        public IDS Ints_Identify;//无符号整数
        public IDS Operator_Identify;//运算符
        public IDS Split_Identify;//分隔符
        public IDS Floats_Identify;//小数
        public IDS ElseID_Identify;

        public IDS HeaderLink;//头指针
        public IDS TailLink;//尾指针
        private char[] tempch;
        #endregion
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public AccidenceAnalyse()
        {
            AllChars = null; CurrentP = 0;//指向当前字符串中第一个字符
            _KeyIDnum = 0; _ParIDnum = 0; _IntNum = 0; _FloatNum = 0;
            _OperatorNum = 0; _SplitNum = 0; _ElseNum = 0;
            KeyID_Identify = new IDS(); KeyID_Identify.next = null;
            ParID_Identify = new IDS(); ParID_Identify.next = null;
            Ints_Identify = new IDS(); Ints_Identify.next = null;
            Operator_Identify = new IDS(); Operator_Identify.next = null;
            Split_Identify = new IDS(); Split_Identify.next = null;
            Floats_Identify = new IDS(); Floats_Identify.next = null;
            ElseID_Identify = new IDS(); ElseID_Identify.next  = null;
            HeaderLink = new IDS(); HeaderLink.next = null;
            TailLink = HeaderLink;
            tempch = new char[50];
            ResultStr =new StringBuilder ();

        }
        /// <summary>
        /// 带参数的构造函数
        /// </summary>
        /// <param name="_chars">参数char[]</param>
        public AccidenceAnalyse(char[] _chars)
            : this()
        {
            AllChars = _chars;
        }
        /// <summary>
        /// 关键字集合,按字母排序
        /// </summary>
        private static string[] KeyWords = {"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"                                            
                                             };
        private static char [] SplitChar={',',';','{','}','(',')','/"','/'','[',']','//'};
        private static char[] OperatorChar = {'+','-','*','/','%','=','<','>' };
 
        public  char[] StrToChar(string srcStr)
        {
            return srcStr.ToCharArray();
        }
        public  string CharToStr(char[] srcChar)
        {
            return srcChar.ToString();
        }
        /// <summary>
        /// 判断一个字符串是不是关键字
        /// </summary>
        /// <param name="srcStr">待判断的字符串</param>
        /// <returns>如果是关键字则返回true,否则返回false</returns>
        private  bool IsKeyWord(string srcStr)
        {//此处需要改进,应该选用效率较高的折半查找或其他效率更高的查找方法
            if (srcStr != null && srcStr != "")
            {
                int low = 0, high = 31, mid = 15; bool flag=false;
                while (low < high)
                {
                    if (KeyWords[mid].CompareTo (srcStr)>0)
                        high = mid - 1;
                    else if (KeyWords[mid] .CompareTo (srcStr)<0)
                        low = mid + 1;
                    else  break;
                    mid = (low + high) / 2;
                }
                if (KeyWords[mid] == srcStr)
                    flag = true;
                return flag;
            }

            return false;
        }
        private bool IsNumberic()
        {//判断当前字符是否为数字
            return IsNumberic(AllChars[CurrentP]);
        }
        private bool IsNumberic(char ch)
        {//判断给定字符是否为数字
            if (ch >= '0' && ch <= '9')
                return true;
            return false;
        }
        private bool IsChar()
        {//判断当前字符是否为字符
             if ((AllChars[CurrentP] >= 'a' && AllChars[CurrentP] <= 'z')||(AllChars[CurrentP] >= 'A' && AllChars[CurrentP] <= 'Z'))
                return true;
            return false;
        }
        private bool IsUnderline()
        {//判断当前字符是否为下划线
            if (AllChars[CurrentP] == '_') return true;
            return false;
        }
        private bool IsSplitChar()
        {//判断是否为分隔符
            bool flag=false;
            foreach (char ch in SplitChar)
            {
                if (AllChars[CurrentP]==ch )
                { flag = true; break;}
            }
            return flag;
        }
        /// <summary>
       /// 取得当前字符的前一个字符
       /// </summary>
       /// <param name="i">当前字符的下标</param>
       /// <returns>返回下标为i-1的字符</returns>
        private char GetPreChar(int i)
        {
            if (i>0&&i<AllChars .Length +1)
                 return AllChars[i - 1];
            return ' ';
        }
       /// <summary>
       /// 取得当前字符的后一个字符
       /// </summary>
       /// <param name="i">当前字符的下标</param>
       /// <returns>返回下标为i+1的字符</returns>
        private char GetBacChar(int i)
        {
                 return AllChars[i + 1];
        }
        /// <summary>
        /// 移动CurrentP直到遇见第一个非空格换行的字符,用来过滤程序前所有的换行与回车
        /// </summary>
        private void GetChar()
        {
            if (CurrentP < AllChars.Length)
                while (CurrentP <AllChars .Length &&(AllChars[CurrentP] == ' '||AllChars [CurrentP]=='/r'||AllChars [CurrentP]=='/n'||AllChars[CurrentP]=='/t'))
                    GetNextChar();
        }
        private void DefaultChar()
        {
            while (AllChars[CurrentP] == ' ' || AllChars[CurrentP] == '/r' || AllChars[CurrentP] == '/n' || AllChars[CurrentP] == '/t')
            {
                GetNextChar();
                if (CurrentP < AllChars.Length) break;
            }
        }
        /// <summary>
        /// 将指针向下移动一个位置
        /// </summary>
        private void GetNextChar()
        {
                CurrentP++;
        }
        private void IDAnalyse()
        {
            int p = 0;
             do{
                tempch[p++] = AllChars[CurrentP];
                GetNextChar();
                 if(CurrentP >=AllChars .Length )break ;
            }while((IsChar()||IsNumberic()||IsUnderline()));
            tempch[p] = '/0';
            string tempstring = new string(tempch, 0, p);
            types temptype;
            if (IsKeyWord(tempstring))
                temptype = types.KeyID;
            else
                temptype = types.ParID;
            AppendNodeByType(temptype, tempstring);
        }
        private void NumAnalyse()
        {
            int p = 0; types temptype = types.Ints;
            do
            {
                tempch[p++] = AllChars[CurrentP];
                GetNextChar();
                if (CurrentP >= AllChars.Length) break;
            } while ( IsNumberic());
            if (AllChars[CurrentP] == '.'&& IsNumberic( GetBacChar(CurrentP)))
            {
                do
                {
                    tempch[p++] = AllChars[CurrentP];
                    GetNextChar();
                } while (CurrentP < AllChars.Length && IsNumberic());
                temptype = types.Floats;
            }
            tempch[p] = '/0';
            string tempstring = new string(tempch ,0,p);
            AppendNodeByType(temptype , tempstring);
       
        }
        private void OperatorAnalyse()
        {
            int p = 0;
            string tempstring = null;
            switch (AllChars[CurrentP])
            {
                case '+':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while (AllChars[CurrentP] == '=' || AllChars[CurrentP] == '+');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;
                case '-':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '-');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;
                case '*':
                case '=':
                case '%':
                case '!':
                case '^':
                case '/':
                        do
                        {
                            tempch[p++] = AllChars[CurrentP]; GetNextChar();
                            if (CurrentP >= AllChars.Length) break;
                        } while (AllChars[CurrentP] == '=');
                        CurrentP--;
                        tempch[p] = '/0';
                        tempstring = new string(tempch, 0, p);
                     break;
                case '~':
                    tempstring = new string(AllChars[CurrentP], 1);
                    break;
                case '|':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '|');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;
                case '>':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '>');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;
                case '<':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while ( AllChars[CurrentP] == '=' || AllChars[CurrentP] == '<');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;
                case '&':
                    do
                    {
                        tempch[p++] = AllChars[CurrentP]; GetNextChar();
                        if (CurrentP >= AllChars.Length) break;
                    } while (AllChars[CurrentP] == '=' || AllChars[CurrentP] == '&');
                    CurrentP--;
                    tempch[p] = '/0';
                    tempstring = new string(tempch, 0, p);
                    break;

            }
            if (tempstring != null)
                AppendNodeByType(types.Operator, tempstring);
        }
        /// <summary>
        /// //分析参数字符串,例如分析语句 char *p="string" 中的string
        /// </summary>
        private void ParStringAnalyse()
        {
            int p=0;
             if (AllChars[CurrentP] == '/"')
            {
                do
                {
                    tempch[p++] = AllChars[CurrentP]; GetNextChar();
                } while (CurrentP < AllChars.Length && AllChars[CurrentP] != '/"');
                tempch[p] = '/0';
                string tempstring = new string(tempch, 0, p);
                AppendNodeByType(types.ElseID, tempstring);
            }
        }
        /// <summary>
        /// 将分析得到的单词添加到对应的链表中
        /// </summary>
        /// <param name="_type">单词的类型</param>
        /// <param name="_data">单词的值</param>
        private void AppendNodeByType(types _type, string _data)
        {
            IDS temp = new IDS(); temp.next = null;
            temp.data = _data; temp.type = _type;
            switch (_type)
            {
                case types.KeyID:
                    _KeyIDnum++; temp.next = KeyID_Identify.next;
                    KeyID_Identify.next = temp;
                    break;
                case types.ParID:
                    _ParIDnum++; temp.next = ParID_Identify.next;
                    ParID_Identify.next = temp;
                    break;
                case types.Ints:
                    _IntNum++;
                    temp.next = Ints_Identify.next;
                    Ints_Identify.next = temp;
                    break;
                case types.Floats:
                    _FloatNum++; temp.next = Floats_Identify.next;
                    Floats_Identify.next = temp;
                    break;
                case types.Operator:
                    _OperatorNum++; temp.next = Operator_Identify.next;
                    Operator_Identify.next = temp;
                    break;
                case types.Split:
                    _SplitNum++; temp.next = Split_Identify.next;
                    Split_Identify.next = temp;
                    break;
                case types.ElseID:
                    _ElseNum++; temp.next = ElseID_Identify.next;
                    ElseID_Identify.next = temp;
                    break;
                default :
                
                    break;
            }
               _AllNum++; TailLink.next = temp; TailLink = temp;
        }
        private void AppendNode(types _type, string _data)
        {
 
        }
        /// <summary>
        /// 按类返回分析的结果字符串
        /// </summary>
        /// <returns>分析结果字符串</returns>
        public string ReturnResultsByType()
        {
            ResultStr.AppendLine("普通标识符如下(总数" + _ParIDnum + "):");
            PrintOneResult (ParID_Identify,_ParIDnum); ;
            ResultStr.AppendLine("关键字如下(总数" + _KeyIDnum + "):");
            PrintOneResult(KeyID_Identify, _KeyIDnum);
            ResultStr.AppendLine("整型数字如下(总数" + _IntNum + "):");
            PrintOneResult(Ints_Identify, _IntNum);
            ResultStr.AppendLine("浮点数字如下(总数" + _FloatNum + "):");
            PrintOneResult(Floats_Identify, _FloatNum);
            ResultStr.AppendLine("分隔符如下(总数" + _SplitNum + "):");
            PrintOneResult(Split_Identify, _SplitNum);
            ResultStr.AppendLine("操作符如下(总数" + _OperatorNum + "):");
            PrintOneResult(Operator_Identify, _OperatorNum);
            ResultStr.AppendLine("其他如下(总数" + _ElseNum + "):");
            PrintOneResult(ElseID_Identify, _ElseNum);
            return ResultStr.ToString ();
        }
        public string ReturnAllresults()
        {
             ResultStr.AppendLine("分析结果如下:");
            PrintOneResult(HeaderLink, _AllNum);
            return ResultStr.ToString ();
        }
        private void PrintOneResult(IDS Header, int number)
        {
            for (int i = 0; i < number; i++)
            {
                Header = Header.next;
                 ResultStr .Append("(" + ((int)Header.type).ToString() + "," + Header.data + ") /r/n ");
            }
        }
        public void Analyse()
        {
              GetChar();//将指针移动到程序的第一个字符
            while (CurrentP < AllChars.Length)
            {
                if (AllChars[CurrentP] == '/' && GetBacChar(CurrentP) == '*')//注释的开始
                {
                    do
                    {//将注释略过,不分析
                        GetNextChar();
                    } while (CurrentP < AllChars.Length && !(AllChars[CurrentP] == '/' && (GetPreChar(CurrentP) == '*')));
                    GetNextChar();//将最后读取到的'/'字符掠过
                }
              //  ParStringAnalyse();
                if (CurrentP >= AllChars.Length)
                    break;
                if (CurrentP <AllChars .Length&&IsChar() )
                {
                    IDAnalyse();
                }
                if (CurrentP < AllChars.Length && IsNumberic())
                {
                    NumAnalyse();
                }
                if (CurrentP < AllChars.Length && IsSplitChar())
                {
                    string tempstring = new string(AllChars[CurrentP], 1);
                    AppendNodeByType(types.Split, tempstring);
                }
                if (CurrentP <AllChars .Length )
                OperatorAnalyse();
                GetNextChar();
            }


        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值