Пример #1
0
        private void ScanIdentifierOrKeyword(ref TokenInfo tokenInfo)
        {
            var startOffset   = _textData.Position;
            var currentOffset = startOffset;
            var chars         = _textData.SourceCode;

            while (chars.Length > currentOffset)
            {
                switch (chars[currentOffset])
                {
                case 'a':
                case 'b':
                case 'c':
                case 'd':
                case 'e':
                case 'f':
                case 'g':
                case 'h':
                case 'i':
                case 'j':
                case 'k':
                case 'l':
                case 'm':
                case 'n':
                case 'o':
                case 'p':
                case 'q':
                case 'r':
                case 's':
                case 't':
                case 'u':
                case 'v':
                case 'w':
                case 'x':
                case 'y':
                case 'z':
                case 'A':
                case 'B':
                case 'C':
                case 'D':
                case 'E':
                case 'F':
                case 'G':
                case 'H':
                case 'I':
                case 'J':
                case 'K':
                case 'L':
                case 'M':
                case 'N':
                case 'O':
                case 'P':
                case 'Q':
                case 'R':
                case 'S':
                case 'T':
                case 'U':
                case 'V':
                case 'W':
                case 'X':
                case 'Y':
                case 'Z':
                    currentOffset++;
                    break;

                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    if (currentOffset == startOffset)
                    {
                        throw new FormatException("Первым символом идентификатора не может быть число");
                    }
                    currentOffset++;
                    break;

                default:
                    goto EndOfLoop;
                }
            }

EndOfLoop:

            var length = currentOffset - startOffset;

            tokenInfo.Text = chars.Substring(startOffset, length);

            if (TryGetKeyword(tokenInfo.Text, out var kind))
            {
                tokenInfo.kind = kind;
            }
            else
            {
                tokenInfo.kind = SyntaxKind.IdentifierToken;
            }

            _textData.AdvanceChar(length);
        }
Пример #2
0
        //private int counter;

        internal static List <ISyntaxToken> GetTokens(TextData data)
        {
            TokenInfo tokenInfo = new TokenInfo
            {
                kind        = SyntaxKind.None,
                specialType = SpecialType.None,
            };

            var lexer = new Lexer(data);

            var tempTokens = new List <ISyntaxToken>();

            while (!data.IsEndOfData)
            {
                switch (data.PeekChar())
                {
                case ' ':
                case '\n':
                case '\r':
                case '\0':
                    //Here we skip whitespace
                    data.AdvanceChar();
                    tokenInfo.kind = SyntaxKind.None;
                    break;

                case '+':
                    tokenInfo.position = data.Position;

                    if (data.PeekChar(1) == '+')
                    {
                        tokenInfo.kind = SyntaxKind.PlusPlusToken;
                        data.AdvanceChar(2);
                    }
                    else if (data.PeekChar(1) == '=')
                    {
                        tokenInfo.kind = SyntaxKind.PlusEqualToken;
                        data.AdvanceChar(2);
                    }
                    else
                    {
                        tokenInfo.kind = SyntaxKind.PlusToken;
                        data.AdvanceChar();
                    }
                    break;

                case '-':
                    tokenInfo.position = data.Position;

                    if (data.PeekChar(1) == '-')
                    {
                        tokenInfo.kind = SyntaxKind.MinusMinusToken;
                        data.AdvanceChar(2);
                    }
                    else if (data.PeekChar(1) == '=')
                    {
                        tokenInfo.kind = SyntaxKind.MinusEqualToken;
                        data.AdvanceChar(2);
                    }
                    else
                    {
                        tokenInfo.kind = SyntaxKind.MinusToken;
                        data.AdvanceChar();
                    }
                    break;

                case '*':
                    tokenInfo.position = data.Position;

                    if (data.PeekChar(1) == '=')
                    {
                        tokenInfo.kind = SyntaxKind.MultEqualToken;
                        data.AdvanceChar(2);
                    }
                    else
                    {
                        tokenInfo.kind = SyntaxKind.MultToken;
                        data.AdvanceChar();
                    }

                    break;

                case '/':
                    tokenInfo.position = data.Position;

                    if (data.PeekChar(1) == '=')
                    {
                        tokenInfo.kind = SyntaxKind.DivEqualToken;
                        data.AdvanceChar(2);
                    }
                    else
                    {
                        tokenInfo.kind = SyntaxKind.DivEqualToken;
                        data.AdvanceChar();
                    }

                    break;

                case '=':
                    tokenInfo.position = data.Position;

                    if (data.PeekChar(1) == '=')
                    {
                        tokenInfo.kind = SyntaxKind.EqualEqualToken;
                        data.AdvanceChar(2);
                    }
                    else
                    {
                        tokenInfo.kind = SyntaxKind.EqualToken;
                        data.AdvanceChar();
                    }

                    break;

                case '(':
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.OpeningBracket;
                    data.AdvanceChar();
                    break;

                case '{':
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.OpeningBrace;
                    data.AdvanceChar();
                    break;

                case ')':
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.ClosingBracket;
                    data.AdvanceChar();
                    break;

                case '}':
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.ClosingBrace;
                    data.AdvanceChar();
                    break;

                case '\'':
                    lexer.ScanCharacter(ref tokenInfo);
                    break;

                case ';':
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.SemicolonToken;
                    data.AdvanceChar();
                    break;

                case 'a':
                case 'b':
                case 'c':
                case 'd':
                case 'e':
                case 'f':
                case 'g':
                case 'h':
                case 'i':
                case 'j':
                case 'k':
                case 'l':
                case 'm':
                case 'n':
                case 'o':
                case 'p':
                case 'q':
                case 'r':
                case 's':
                case 't':
                case 'u':
                case 'v':
                case 'w':
                case 'x':
                case 'y':
                case 'z':
                case 'A':
                case 'B':
                case 'C':
                case 'D':
                case 'E':
                case 'F':
                case 'G':
                case 'H':
                case 'I':
                case 'J':
                case 'K':
                case 'L':
                case 'M':
                case 'N':
                case 'O':
                case 'P':
                case 'Q':
                case 'R':
                case 'S':
                case 'T':
                case 'U':
                case 'V':
                case 'W':
                case 'X':
                case 'Y':
                case 'Z':
                    lexer.ScanIdentifierOrKeyword(ref tokenInfo);
                    break;

                case '"':
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    lexer.ScanNumericOrLiteralValue(ref tokenInfo);
                    break;

                default:
                    tokenInfo.position = data.Position;
                    tokenInfo.kind     = SyntaxKind.Unknown;
                    tokenInfo.Text     = data.PeekChar().ToString();
                    data.AdvanceChar();
                    break;
                }

                if (tokenInfo.kind != SyntaxKind.None)
                {
                    tempTokens.Add(GetToken(ref tokenInfo));
                }
            }



            return(tempTokens);
        }