示例#1
0
        /// <summary>Matches a string. Works with single or double quotes and escaping.</summary>
        /// <returns>Wether a string was matched.</returns>
        public bool MatchString()
        {
            LexScanner scanner = MakeScanner();

            // single will be true for single quotes, false for double quotes.
            bool single = scanner.At('\'');

            // Not a string.
            if (!single && !scanner.At('\"'))
            {
                return(false);
            }

            char lookingFor = single ? '\'' : '\"';

            bool escaped = false;

            // Look for end of string.
            do
            {
                scanner.Advance();
                if (scanner.At('\\') && !escaped)
                {
                    escaped = true;
                }
                else if (escaped)
                {
                    escaped = false;
                }
            }while (!scanner.ReachedEnd && (escaped || !scanner.At(lookingFor)));
            scanner.Advance();

            PushToken(scanner, TokenType.String);
            return(true);
        }
示例#2
0
        bool MatchBlockComment()
        {
            LexScanner scanner = MakeScanner();

            if (!scanner.At('/') || !scanner.At('*', 1))
            {
                return(false);
            }

            scanner.Advance();
            scanner.Advance();

            // Match every character to the end of the line.
            while (!scanner.ReachedEnd)
            {
                if (scanner.At('*') && scanner.At('/', 1))
                {
                    scanner.Advance();
                    scanner.Advance();
                    break;
                }
                scanner.Advance();
            }

            // Done.
            Accept(scanner);
            return(true);
        }
示例#3
0
        /// <summary>Unknown token.</summary>
        public void Unknown()
        {
            LexScanner scanner = MakeScanner();

            PushToken(new Token(Content[Index].ToString(), new DocRange(new DocPos(Line, Column), new DocPos(Line, Column + 1)), TokenType.Unknown));
            scanner.Advance();
            Accept(scanner);
        }
示例#4
0
        /// <summary>Matches a string. Works with single or double quotes and escaping.</summary>
        /// <returns>Whether a string was matched.</returns>
        public bool MatchString(bool continueInterpolatedString = false, bool single = false)
        {
            LexScanner scanner = MakeScanner();

            // Interpolated string.
            bool interpolated = continueInterpolatedString || scanner.Match('$');

            if (!continueInterpolatedString)
            {
                // single will be true for single quotes, false for double quotes.
                single = scanner.Match('\'');

                // Not a string.
                if (!single && !scanner.Match('\"'))
                {
                    return(false);
                }
            }

            char lookingFor = single ? '\'' : '\"';

            //escaped will be 0 whenever it's not escaped
            bool escaped = false;

            // Look for end of string.
            while (!scanner.ReachedEnd && (escaped || !scanner.Match(lookingFor)))
            {
                var progressCheck = scanner.Index;

                // If this is an interpolated string, look for a '{' that is not followed by another '{'.
                if (interpolated && scanner.Match('{') && !scanner.Match('{'))
                {
                    Token resultingToken = scanner.AsToken(continueInterpolatedString ? TokenType.InterpolatedStringMiddle : TokenType.InterpolatedStringTail);
                    if (single)
                    {
                        resultingToken.Flags |= TokenFlags.StringSingleQuotes;
                    }
                    PushToken(resultingToken);
                    Accept(scanner);
                    return(true);
                }

                escaped = escaped ? false : scanner.Match('\\');

                // If the scanner did not progress, advance.
                if (progressCheck == scanner.Index)
                {
                    scanner.Advance();
                }
            }

            PushToken(scanner, interpolated ? TokenType.InterpolatedStringHead : TokenType.String);
            return(true);
        }
示例#5
0
 /// <summary>Skips whitespace.</summary>
 public void Skip()
 {
     do
     {
         LexScanner scanner = MakeScanner();
         while (!scanner.ReachedEnd && scanner.AtWhitespace())
         {
             scanner.Advance();
         }
         Accept(scanner);
     } while(MatchLineComment() || MatchBlockComment());
 }
示例#6
0
        /// <summary>Matches a symbol.</summary>
        /// <returns>Whether a symbol was matched.</returns>
        public bool MatchSymbol(char symbol, TokenType tokenType)
        {
            LexScanner scanner = MakeScanner();

            if (scanner.Match(symbol))
            {
                PushToken(scanner.AsToken(tokenType));
                Accept(scanner);
                return(true);
            }
            return(false);
        }
示例#7
0
        // * Matchers *

        /// <summary>Matches a keyword.</summary>
        /// <param name="keyword">The name of the keyword that will be matched.</param>
        /// <param name="tokenType">The type of the created token.</param>
        /// <returns>Whether the keyword was matched.</returns>
        public bool MatchKeyword(string keyword, TokenType tokenType)
        {
            LexScanner scanner = MakeScanner();

            if (scanner.Match(keyword) && !scanner.AtIdentifierChar())
            {
                PushToken(scanner.AsToken(tokenType));
                Accept(scanner);
                return(true);
            }
            return(false);
        }
示例#8
0
        /// <summary>Skips whitespace.</summary>
        public bool Skip()
        {
            bool       preceedingWhitespace = false;
            LexScanner scanner = MakeScanner();

            while (!scanner.ReachedEnd && scanner.AtWhitespace())
            {
                if (scanner.At('\n'))
                {
                    preceedingWhitespace = true;
                }
                scanner.Advance();
            }
            Accept(scanner);
            return(preceedingWhitespace);
        }
示例#9
0
        /// <summary>Matches a number.</summary>
        /// <returns>Whether a number was matched.</returns>
        public bool MatchNumber()
        {
            LexScanner scanner = MakeScanner();

            // Get the number.
            bool foundLeftNumber = false;

            while (scanner.AtNumeric())
            {
                scanner.Advance();
                foundLeftNumber = true;
            }

            Skip();

            // At decimal
            if (scanner.At('.'))
            {
                scanner.Advance();
                Skip();

                // Get the decimal.
                bool decimalFound = false;
                while (scanner.AtNumeric())
                {
                    scanner.Advance();
                    decimalFound = true;
                }

                if (!decimalFound && !foundLeftNumber)
                {
                    return(false);
                }
            }
            // No decimal and no left number.
            else if (!foundLeftNumber)
            {
                return(false);
            }

            // Done.
            PushToken(scanner, TokenType.Number);
            return(true);
        }
示例#10
0
        /// <summary>Matches an identifier.</summary>
        /// <returns>Whether an identifier was matched.</returns>
        public bool MatchIdentifier()
        {
            LexScanner scanner = MakeScanner();

            // Advance while the current character is an identifier.
            while (!scanner.ReachedEnd && scanner.AtIdentifierChar())
            {
                scanner.Advance();
            }

            // Push the token if it is accepted.
            if (scanner.WasAdvanced)
            {
                PushToken(scanner.AsToken(TokenType.Identifier));
                Accept(scanner);
                return(true);
            }
            return(false);
        }
示例#11
0
        bool MatchActionComment()
        {
            LexScanner scanner = MakeScanner();

            // Action comment.
            if (!scanner.At('#'))
            {
                return(false);
            }

            // Match every character to the end of the line.
            scanner.Advance();
            while (!scanner.ReachedEnd && !scanner.At('\n'))
            {
                scanner.Advance();
            }

            // Done.
            PushToken(scanner, TokenType.ActionComment);
            return(true);
        }
示例#12
0
        /// <summary>Matches a string. Works with single or double quotes and escaping.</summary>
        /// <returns>Wether a string was matched.</returns>
        public bool MatchString()
        {
            LexScanner scanner = MakeScanner();

            // single will be true for single quotes, false for double quotes.
            bool single = scanner.At('\'');

            // Not a string.
            if (!single && !scanner.At('\"'))
            {
                return(false);
            }

            char lookingFor = single ? '\'' : '\"';

            //escaped will be 0 whenever it's not escaped
            int escaped = 0;

            // Look for end of string.
            do
            {
                scanner.Advance();
                if (scanner.At('\\') && escaped == 0)
                {
                    escaped = 2;
                }
                else if (escaped > 0)
                {
                    escaped -= 1;
                }
            }while (!scanner.ReachedEnd && ((escaped > 0) || !scanner.At(lookingFor)));
            scanner.Advance();

            PushToken(scanner, TokenType.String);
            return(true);
        }
示例#13
0
 private void PushToken(LexScanner scanner, TokenType tokenType)
 {
     _push.PushToken(scanner.AsToken(tokenType));
     Accept(scanner);
 }
示例#14
0
 private void Accept(LexScanner scanner)
 {
     Index  = scanner.Index;
     Line   = scanner.Line;
     Column = scanner.Column;
 }