程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 仿查詢分析器的C#計算器——3.詞法分析(5)

仿查詢分析器的C#計算器——3.詞法分析(5)

編輯:關於C語言

接下來介紹各個工廠類。首先是關鍵字工廠TokenKeywordFactory。當TokenFactory分析到英文字母的時候,把任務轉交給 TokenKeyWordFactory。該類從分析得到的第一個英文字母開始向後分析,如果後面還是英文字母或者數字,則繼續向後分析,否則結束分析。 在這裡關鍵字允許包含數字,但第一個字符必須是英文字母。分析結束後,截取分析得到的字符串,然後到交給ProduceToken方法產生一個 TokenRecord類的實例。

在ProduceToken方法中,首先判斷傳入的字符串是否存在於關鍵字字典中,如果不存在則報錯,如果存在則用反射產生一個對應類的實例。 其中有些關鍵字是常量,所以進行了特殊處理,需要設置記號對象的值和類型。

以上工作完成後,調整分析指針的位置,回到TokenFactory類,執行後續分析。TokenKeyWordFactory的代碼如下:

/// <summary>
    /// 關鍵字工廠
    /// </summary>
    /// <remarks>Author:Alex Leo</remarks>
    internal class TokenKeyWordFactory : TokenFactory
    {
        private static SortedDictionary<string, string> m_DictionaryKeyWord = new SortedDictionary<string, string>();
        /// <summary>
        /// 獲取關鍵字字典
        /// </summary>
        /// <returns>關鍵字字典</returns>
        /// <remarks>Author:Alex Leo; Date:2008-5-19;</remarks>
        internal static SortedDictionary<string, string> GetKeyWordDictionary()
        {
            if (m_DictionaryKeyWord.Count == 0)
            {
                m_DictionaryKeyword = TokenFactory.GetOperateTokenDictionary (OperateTokenTypeEnum.TokenKeyWord);
            }

            return m_DictionaryKeyWord;
        }


        /// <summary>
        /// 詞法分析
        /// </summary>
        /// <param name="TokenList">記號對象列表</param>
        /// <param name="Code">源表達式</param>
        /// <param name="Index">分析序號</param>
        /// <remarks>Author:Alex Leo</remarks>
        public static new void LexicalAnalysis(List<TokenRecord> TokenList, string Code, ref int Index)
        {
            int intIndexCurrent = Index;//當前序號
            bool blnContinue = true;
            //string strTempChar = "";//獲取臨時字符
            char chrTemp;
            string strTempWord = "";//獲取臨時字符串

            while (blnContinue && intIndexCurrent < Code.Length)
            {
                chrTemp = Code[intIndexCurrent];
                //關鍵字支持大小寫字母及數字,但不允許以數字開頭
                if (char.IsLetter(chrTemp) || char.IsDigit(chrTemp))
                {
                    intIndexCurrent += 1;//把當前序號後移
                }
                else
                {
                    blnContinue = false;
                }
            }

            strTempWord = Code.Substring(Index, intIndexCurrent - Index);//獲取臨時詞
            TokenRecord Token = ProduceToken(strTempWord, Index);
            TokenList.Add(Token);

            Index = intIndexCurrent - 1;//設置指針到讀取結束位置
        }

        /// <summary>
        /// 產生記號對象
        /// </summary>
        /// <param name="TokenWord">分析得到的單詞</param>
        /// <param name="Index">當前序號</param>
        /// <returns>記號對象</returns>
        /// <remarks>Author:Alex Leo</remarks>
        protected static new TokenRecord ProduceToken(string TokenWord, int Index)
        {
            TokenRecord Token;

            if (GetKeywordDictionary().ContainsKey(TokenWord.ToLower()))
            {
                string strFullClassName = "ConExpress.Calculator." + GetKeywordDictionary() [TokenWord.ToLower()];
                Type TokenType = Type.GetType(strFullClassName);
                Token = (TokenRecord)Activator.CreateInstance(TokenType, new object[] { Index, TokenWord.Length });
                //對常數的特殊處理
                switch (TokenWord.ToLower())
                {
                    case "pi"://以下為常量記號對象
                        Token.TokenValueType = typeof(double);
                        Token.TokenValue = Math.PI;
                        break;
                    case "e":
                        Token.TokenValueType = typeof(double);
                        Token.TokenValue = Math.E;
                        break;
                    case "true":
                        Token.TokenValueType = typeof(bool);
                        Token.TokenValue = true;
                        break;
                    case "false":
                        Token.TokenValueType = typeof(bool);
                        Token.TokenValue = false;
                        break;
                    default:
                        break;
                }
            }
            else
            {
                //錯誤字符串,拋出錯誤,語法錯誤
                throw new SyntaxException(Index, TokenWord.Length, "未知表達式:" + TokenWord);
            }

            return Token;
        }//ProduceToken
    }//class TokenKeyWordFactory

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved