Пример #1
0
        public static void ParseStream <T>(StreamReader reader, System.Action <Data, T> dataReceiver, T custom)
        {
            var phase      = ParsePhase.New;
            int lineNumber = 1;

            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                                #if LOG_LINE
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(String.Format("TryParseLine[{0}]\n{1}", lineNumber, line));
                                #endif
                try
                {
                    phase = ParseLine(line, lineNumber, phase, dataReceiver, custom);
                }
                catch (LexException e)
                {
                    e.line = line;
                    e.row  = lineNumber;
                    throw e;
                }
                ++lineNumber;
            }
            if (ParsePhase.Note == phase)
            {
                var exception = new LexException(Error.NoteNoEnd);
                exception.content = "No \"*/\"";
                throw exception;
            }
        }
Пример #2
0
        public static Number TryParseNumber(Token token, string str)
        {
            var number = new Number();

            switch (token)
            {
            case Token.Int8:
                number.i_8 = DoTryParseNumber <sbyte>(token, str, sbyte.TryParse);
                break;

            case Token.UInt8:
                number.ui_8 = DoTryParseNumber <byte>(token, str, byte.TryParse);
                break;

            case Token.Int16:
                number.i_16 = DoTryParseNumber <short>(token, str, short.TryParse);
                break;

            case Token.UInt16:
                number.ui_16 = DoTryParseNumber <ushort>(token, str, ushort.TryParse);
                break;

            case Token.Int32:
                number.i_32 = DoTryParseNumber <int>(token, str, int.TryParse);
                break;

            case Token.UInt32:
                number.ui_32 = DoTryParseNumber <uint>(token, str, uint.TryParse);
                break;

            case Token.Int64:
                number.i_64 = DoTryParseNumber <long>(token, str, long.TryParse);
                break;

            case Token.UInt64:
                number.ui_64 = DoTryParseNumber <ulong>(token, str, ulong.TryParse);
                break;

            case Token.Float:
                number.f = DoTryParseNumber <float>(token, str, float.TryParse);
                break;

            case Token.Double:
                number.d = DoTryParseNumber <double>(token, str, double.TryParse);
                break;

            default:
            {
                var exception = new LexException(Error.InvalidToken);
                exception.content = token.ToString();
                throw exception;
            }
            }
            return(number);
        }
Пример #3
0
 internal static void Log_LexException(LexException e)
 {
     Console.ForegroundColor = ConsoleColor.Red;
     Console.Write(String.Format("LexException: {0}, {1}\n at [{2},{3}]: ", e.errorCode.ToString(), e.content, e.row, e.col));
     if (null != e.line && 0 < e.col && e.line.Length >= e.col)
     {
         Console.ForegroundColor = ConsoleColor.Black;
         Console.Write(e.line.Substring(0, e.col - 1));
         Console.ForegroundColor = ConsoleColor.Red;
         Console.Write(e.line[e.col - 1]);
         Console.ForegroundColor = ConsoleColor.Black;
         Console.WriteLine(e.line.Substring(e.col));
     }
 }
Пример #4
0
        private static T DoTryParseNumber <T>(Token token, string str, NumberParseFunc <T> parseFunc)
        {
            T v;

            if (parseFunc(str, out v))
            {
                return(v);
            }
            else
            {
                var exception = new LexException(Error.ParseNumberFailed);
                exception.content = str;
                exception.col     = (int)token;
                throw exception;
            }
        }
Пример #5
0
        private static string ParseFunc_String(string line, ref int i, ref ParsePhase phase, char separator)
        {
            var begIndex = i + 1;
            var endIndex = IndexOfStringEnd(line, begIndex, separator);

            if (i < endIndex)
            {
                var str = line.Substring(begIndex, endIndex - i);
                i = endIndex;
                return(str);
            }
            else
            {
                var exception = new LexException(Error.StringNoEnd);
                exception.col = i + 1;
                throw exception;
            }
        }
Пример #6
0
        public static ParsePhase ParseLine <T>(string line, int lineNumber, ParsePhase phase, System.Action <Data, T> dataReceiver, T custom)
        {
            if (string.IsNullOrEmpty(line))
            {
                return(phase);
            }
            int i = 0;

            if (ParsePhase.Note == phase)
            {
                var endIndex = line.IndexOf("*/");
                if (0 > endIndex)
                {
                                        #if LOG_NOTE
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Console.WriteLine(line);
                                        #endif
                    return(phase);
                }
                                #if LOG_NOTE
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine(line.Substring(0, endIndex + 2));
                                #endif
                phase = ParsePhase.New;
                i     = endIndex + 2;
            }
            for (; i < line.Length; ++i)
            {
                var       startI = i;
                Data      data   = null;
                var       c      = line[i];
                ParseFunc func;
                if (StartCharMap.TryGetValue(c, out func))
                {
                    if (null != func)
                    {
                        data = func(line, ref i, ref phase);
                    }
                }
                else if ('_' == c)
                {
                    // identify
                    var identify = ParseFunc_Identify(line, ref i, ref phase, c);
                    data = new Data(Token.Identify, identify);
                }
                else if (char.IsLetter(c))
                {
                    var     identify = ParseFunc_Identify(line, ref i, ref phase, c);
                    Keyword k;
                    if (Enum.TryParse(identify, true, out k) &&
                        ("API" == identify || identify.ToLower() == identify))
                    {
                        // keyword
                        data = new Data(Token.Keyword, k);
                    }
                    else
                    {
                        // identify
                        data = new Data(Token.Identify, identify);
                    }
                }
                else if (char.IsDigit(c))
                {
                    // constant
                    data = ParseFunc_Number(line, ref i, ref phase, c);
                }
                else if (!char.IsWhiteSpace(c))
                {
                    var exception = new LexException(Error.InvalidCharactor);
                    exception.col = i + 1;
                    throw exception;
                }
                if (null != data)
                {
                    data.line = line;
                    data.row  = lineNumber;
                    data.col  = startI + 1;
                    dataReceiver(data, custom);
                }
            }
            return(phase);
        }
Пример #7
0
        private static Data ParseFunc_Number(string line, ref int i, ref ParsePhase phase, char c)
        {
            /*
             * number phase
             * 0: scan number
             * 1: scan float or double
             * 2: scan end char
             * 3: check next char is not(letter,digit,_)
             */
            Token token       = Token.Int32;
            int   numberPhase = 0;
            int   j           = i + 1;

            for (; j < line.Length; ++j)
            {
                var d = line[j];
                switch (numberPhase)
                {
                case 0:
                    switch (d)
                    {
                    case 't':
                        numberPhase = 3;
                        token       = Token.Int8;
                        continue;

                    case 's':
                        numberPhase = 3;
                        token       = Token.Int16;
                        continue;

                    case 'l':
                        numberPhase = 3;
                        token       = Token.Int64;
                        continue;

                    case 'f':
                        numberPhase = 3;
                        token       = Token.Float;
                        continue;

                    case 'u':
                        numberPhase = 2;
                        token       = Token.UInt32;
                        continue;

                    case '.':
                        numberPhase = 1;
                        token       = Token.Double;
                        continue;
                    }
                    break;

                case 1:
                    if ('f' == d)
                    {
                        numberPhase = 3;
                        token       = Token.Float;
                        continue;
                    }
                    break;

                case 2:
                    switch (d)
                    {
                    case 't':
                        numberPhase = 3;
                        token       = Token.UInt8;
                        continue;

                    case 's':
                        numberPhase = 3;
                        token       = Token.UInt16;
                        continue;

                    case 'l':
                        numberPhase = 3;
                        token       = Token.UInt64;
                        continue;
                    }
                    break;

                case 3:
                    if ('_' == d || '.' == d || char.IsLetterOrDigit(d))
                    {
                        var exception = new LexException(Error.InvalidCharactor);
                        exception.col = j + 1;
                        throw exception;
                    }
                    else
                    {
                        // end
                        var data = new Data(token);
                        data.number = TryParseNumber(token, line.Substring(i, j - i));
                        i           = j - 1;
                        return(data);
                    }
                }
                if (!char.IsDigit(d))
                {
                    if ('_' == d || '.' == d || char.IsLetter(d))
                    {
                        var exception = new LexException(Error.InvalidCharactor);
                        exception.col = j + 1;
                        throw exception;
                    }
                    else
                    {
                        // end
                        var data = new Data(token);
                        data.number = TryParseNumber(token, line.Substring(i, j - i));
                        i           = j - 1;
                        return(data);
                    }
                }
            }
            return(null);
        }