Beispiel #1
0
        /// <summary>
        /// 数值
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetConstentNumber(Token result, AnalyzingContext context)
        {
            char ch = context.CurrentChar();

            if (ch == '0')//可能是八进制或十六进制数
            {
                if (context.NextLetterIndex + 1 < context.SourceCode.Length)
                {
                    char c = context.SourceCode[context.NextLetterIndex + 1];
                    if (c == 'x' || c == 'X')
                    {//十六进制数
                        return(GetConstentHexadecimalNumber(result, context));
                    }
                    else if (ch.GetCharType() == SourceCodeCharType.Number)
                    {//八进制数
                        return(GetConstentOctonaryNumber(result, context));
                    }
                    else//十进制数
                    {
                        return(GetConstentDecimalNumber(result, context));
                    }
                }
                else
                {//源代码最后一个字符 0
                    result.TokenType = new TokenType("number", "0", "number");
                    return(true);
                }
            }
            else//十进制数
            {
                return(GetConstentDecimalNumber(result, context));
            }
        }
        /// <summary>
        /// 从<code>context.NextLetterIndex</code>开始获取下一个<code>Token</code>
        /// </summary>
        /// <returns></returns>
        protected Token NextToken(AnalyzingContext context)
        {
            var result = new Token();

            result.Line              = context.CurrentLine;
            result.Column            = context.CurrentColumn;
            result.IndexOfSourceCode = context.NextLetterIndex;
            var count = context.SourceCode.Length;

            if (context.NextLetterIndex < 0 || context.NextLetterIndex >= count)
            {
                return(result);
            }
            var  gotToken = false;
            char ch       = context.CurrentChar();
            SourceCodeCharType charType = ch.GetCharType();

            gotToken = TryGetToken(context, result, charType);
            if (gotToken)
            {
                result.Length = context.NextLetterIndex - result.IndexOfSourceCode;
                return(result);
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 跳过多行注释
        /// </summary>
        /// <returns></returns>
        protected virtual void SkipMultilineNote(AnalyzingContext context)
        {
            int count = context.SourceCode.Length;

            while (context.NextLetterIndex < count)
            {
                if (context.CurrentChar() == '*')
                {
                    context.NextLetterIndex++;
                    if (context.NextLetterIndex < count)
                    {
                        if (context.CurrentChar() == '/')
                        {
                            context.NextLetterIndex++;
                            break;
                        }
                        else
                        {
                            context.NextLetterIndex++;
                        }
                    }
                }
                else
                {
                    context.NextLetterIndex++;
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// 十六进制数
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetConstentHexadecimalNumber(Token result, AnalyzingContext context)
        {
            char          c;
            StringBuilder tag = new StringBuilder(context.SourceCode.Substring(context.NextLetterIndex, 2));

            context.NextLetterIndex += 2;
            string numberSerial = GetNumberSerial(context, 16);

            tag.Append(numberSerial);
            if (context.NextLetterIndex < context.SourceCode.Length)
            {
                c = context.CurrentChar();
                if (c == 'l' || c == 'L')
                {
                    tag.Append(c);
                    context.NextLetterIndex++;
                }
            }
            if (string.IsNullOrEmpty(numberSerial))
            {
                result.LexicalError = true;
                result.TokenType    = new TokenType("number",
                                                    string.Format("十六进制数[{0}]格式错误。", tag.ToString()),
                                                    "number");
            }
            else
            {
                result.TokenType = new TokenType("number", tag.ToString(), "number");
            }
            return(true);
        }
Beispiel #5
0
        /// <summary>
        /// 十进制数
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetConstentDecimalNumber(Token result, AnalyzingContext context)
        {
            char          ch = context.CurrentChar();
            StringBuilder tag = new StringBuilder();
            string        numberSerial1, numberSerial2, numberSerial3;

            numberSerial1 = GetNumberSerial(context, 10);
            tag.Append(numberSerial1);
            result.LexicalError = string.IsNullOrEmpty(numberSerial1);
            if (context.NextLetterIndex < context.SourceCode.Length)
            {
                //ch = context.CurrentChar();
                if (ch == 'l' || ch == 'L')
                {
                    tag.Append(ch);
                    context.NextLetterIndex++;
                }
                if (ch == '.')
                {
                    tag.Append(ch);
                    context.NextLetterIndex++;
                    numberSerial2 = GetNumberSerial(context, 10);
                    tag.Append(numberSerial2);
                    result.LexicalError = result.LexicalError || string.IsNullOrEmpty(numberSerial2);
                    if (context.NextLetterIndex < context.SourceCode.Length)
                    {
                        ch = context.CurrentChar();
                    }
                }
                if (ch == 'e' || ch == 'E')
                {
                    tag.Append(ch);
                    context.NextLetterIndex++;
                    if (context.NextLetterIndex < context.SourceCode.Length)
                    {
                        ch = context.CurrentChar();
                        if (ch == '+' || ch == '-')
                        {
                            tag.Append(ch);
                            context.NextLetterIndex++;
                        }
                    }
                    numberSerial3 = GetNumberSerial(context, 10);
                    tag.Append(numberSerial3);
                    result.LexicalError = result.LexicalError || string.IsNullOrEmpty(numberSerial3);
                }
            }
            if (result.LexicalError)
            {
                result.TokenType = new TokenType("number",
                                                 string.Format("十进制数[{0}]格式错误,无法解析。", tag.ToString()),
                                                 "number");
            }
            else
            {
                result.TokenType = new TokenType("number", tag.ToString(), "number");
            }
            return(true);
        }
        /// <summary>
        /// 未知符号
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetUnknown(Token result, AnalyzingContext context)
        {
            string content = context.CurrentChar().ToString();

            result.TokenType = new TokenType(
                "__unknown", content, "unknown");
            result.LexicalError = true;
            //result.Tag = string.Format("发现未知字符[{0}]。", result.Detail);
            context.NextLetterIndex++;
            return(true);
        }
Beispiel #7
0
        /// <summary>
        /// space tab \r \n
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetSpace(Token result, AnalyzingContext context)
        {
            char c = context.CurrentChar();

            context.NextLetterIndex++;
            if (c == '\n')// || c == '\r') //换行:Windows:\r\n Linux:\n
            {
                context.CurrentLine++;
                context.CurrentColumn = 1;
            }
            return(false);
        }
Beispiel #8
0
        /// <summary>
        /// 跳过单行注释
        /// </summary>
        /// <returns></returns>
        protected virtual void SkipSingleLineNote(AnalyzingContext context)
        {
            int  count = context.SourceCode.Length;
            char cNext;

            while (context.NextLetterIndex < count)
            {
                cNext = context.CurrentChar();
                if (cNext == '\r' || cNext == '\n')
                {
                    break;
                }
                context.NextLetterIndex++;
            }
        }
Beispiel #9
0
 /// <summary>
 /// 数字序列
 /// </summary>
 /// <param name="sourceCode"></param>
 /// <param name="scale">进制</param>
 /// <returns></returns>
 protected virtual string GetNumberSerial(AnalyzingContext context, int scale)
 {
     if (scale == 10)
     {
         return(GetNumberSerialDecimal(context));
     }
     if (scale == 16)
     {
         return(GetNumberSerialHexadecimal(context));
     }
     if (scale == 8)
     {
         return(GetNumberSerialOctonary(context));
     }
     return(string.Empty);
 }
Beispiel #10
0
        /// <summary>
        /// 八进制数序列
        /// </summary>
        /// <param name="sourceCode"></param>
        /// <returns></returns>
        protected virtual string GetNumberSerialOctonary(AnalyzingContext context)
        {
            StringBuilder result = new StringBuilder(String.Empty);
            char          c;

            while (context.NextLetterIndex < context.SourceCode.Length)
            {
                c = context.CurrentChar();
                if ('0' <= c && c <= '7')
                {
                    result.Append(c);
                    context.NextLetterIndex++;
                }
                else
                {
                    break;
                }
            }
            return(result.ToString());
        }
        /// <summary>
        /// 获取标识符(函数名,变量名,等)
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual bool GetIdentifier(Token result, AnalyzingContext context)
        {
            StringBuilder builder = new StringBuilder();

            while (context.NextLetterIndex < context.SourceCode.Length)
            {
                char ch = context.CurrentChar();
                var  ct = ch.GetCharType();
                if (ct == SourceCodeCharType.Letter ||
                    ct == SourceCodeCharType.Number ||
                    ct == SourceCodeCharType.UnderLine)
                {
                    builder.Append(ch);
                    context.NextLetterIndex++;
                }
                else
                {
                    break;
                }
            }
            string content = builder.ToString();
            // specify if this string is a keyword
            bool isKeyword = false;

            foreach (var item in this.GetKeywords())
            {
                if (item.NickName == content)
                {
                    result.TokenType = new TokenType(item.TokenType, content, content);
                    isKeyword        = true;
                    break;
                }
            }
            if (!isKeyword)
            {
                result.TokenType = new TokenType(
                    "identifier", content, "identifier");
            }

            return(true);
        }
        /// <summary>
        /// 分析源代码获得Token序列
        /// </summary>
        /// <returns></returns>
        public TokenList Analyze(string sourceCode)
        {
            var tokens = new TokenList();

            if (string.IsNullOrEmpty(sourceCode))
            {
                return(tokens);
            }

            int count   = sourceCode.Length;
            var context = new AnalyzingContext(sourceCode);

            while (context.NextLetterIndex < count)
            {
                var tk = NextToken(context);
                if (tk != null)
                {
                    tokens.Add(tk);
                }
            }

            return(tokens);
        }
 /// <summary>
 /// 从ptNextLetter开始获取下一个Token
 /// </summary>
 /// <returns></returns>
 protected abstract bool TryGetToken(AnalyzingContext context, Token result, SourceCodeCharType charType);
 protected virtual bool Getunderline(Token result, AnalyzingContext context)
 {
     return(GetIdentifier(result, context));
 }
Beispiel #15
0
 protected virtual bool GetNumber(Token result, AnalyzingContext context)
 {
     return(GetConstentNumber(result, context));
 }