예제 #1
0
        /// <summary>
        /// Checks to see if a given token (representing a closing delimeter has properties. If it does then adds warning to that token
        /// </summary>
        /// <param name="closingToken">token representing delimeter</param>
        /// <param name="tokenStream">remaining token stream</param>
        private void WarnIfClosingTokenHasProperties(Token closingToken, IWaneTokenStream tokenStream)
        {
            //check for closing token properties
            Token possiblePropertyToken = tokenStream.Peek();

            if (possiblePropertyToken != null && IsPropertiesStartDelimeter(possiblePropertyToken))
            {
                //check if has full properties
                List<Token> propertyTokens = GetRawTokensUntilAndIncludingEndingDelimeter(possiblePropertyToken, tokenStream);

                if (propertyTokens.Count > 0)
                    closingToken.AddWarning("Can not put properties on closing delimeters.");
            }
        }
예제 #2
0
        /// <summary>
        /// Processes a stream or substream of tokens
        /// </summary>
        /// <param name="tokenStream">tokens to process</param>
        /// <returns>list of tokens</returns>
        private List<Token> ProcessTokenStream(IWaneTokenStream tokenStream)
        {
            var tokens = new List<Token>();
            bool isEscaping = false;

            while (!tokenStream.IsEndOfStream)
            {
                Token currentToken = tokenStream.ReadNextToken();

                //handle escaped token
                if (isEscaping)
                {
                    currentToken.ChangeTokenTypeToText();
                    isEscaping = false;
                }

                //check if escape character and is escaping something
                isEscaping = DelimeterCausesEscape(currentToken, tokenStream);

                if (IsCustomDelimeter(currentToken) && !isEscaping)
                {
                    List<Token> handledTokens = HandleCustomDelimeter(currentToken, tokenStream);
                    tokens.AddRange(handledTokens);
                }
                else if (currentToken.TokenType == TokenType.NewLine)
                    tokens.Add(currentToken);
                else if(!isEscaping)
                    AppendTextToTokens(tokens, currentToken);
            }

            return tokens;
        }
예제 #3
0
        /// <summary>
        /// Handles a custom delimeter from it's start until it's end.
        /// Also handles tokens within those custom delimeters
        /// </summary>
        /// <param name="currentToken">current token (which is a delimeter)</param>
        /// <param name="tokenStream"></param>
        private List<Token> HandleCustomDelimeter(Token currentToken, IWaneTokenStream tokenStream)
        {
            if (!IsCustomDelimeter(currentToken))
                throw new ArgumentException("Expected custome delimeter", "currentToken");

            var tokens = new List<Token>();

            currentToken.IsStartingDelimeter = true;
            tokens.Add(currentToken);

            //find ending delimeter
            List<Token> tokensToInspect = GetRawTokensUntilAndIncludingEndingDelimeter(currentToken, tokenStream);

            if (tokensToInspect.Count > 0)
            {
                //remove ending token else this will not be processed properly
                Token closingToken = tokensToInspect.Last();
                tokensToInspect.RemoveAt(tokensToInspect.Count - 1);

                var internalStream = new WaneEnumerableTokenStream(tokensToInspect);

                //get and remove properties
                ExtractPropertiesFromTokenListAndApplyToCurrentToken(currentToken, internalStream);

                if (!internalStream.IsEndOfStream)
                {
                    List<Token> procesedInternalStreamTokens = ProcessTokenStream(internalStream);
                    tokens.AddRange(procesedInternalStreamTokens);
                }

                //add closing delimeter token
                closingToken.IsEndingDelimeter = true;
                tokens.Add(closingToken);

                WarnIfClosingTokenHasProperties(closingToken, tokenStream);
            }
            else
            {
                //no closing delimeter
                currentToken.ChangeTokenTypeToText();
                currentToken.AddWarning("Delimeter start does not have a matching end delimeter, or the actual start delimeter has been escaped");
            }

            return tokens;
        }
예제 #4
0
        /// <summary>
        /// Gets a sub stream of tokens to parse
        /// </summary>
        /// <param name="findEndingTokenFor">searches for a matching token in the stream, the match will be the end of the sub-stream (or then end of the text will be)</param>
        /// <param name="tokenStream">token stream being read from</param>
        /// <returns>sub stream of tokens, or empty list if no ending delimeter</returns>
        private List<Token> GetRawTokensUntilAndIncludingEndingDelimeter(Token findEndingTokenFor, IWaneTokenStream tokenStream)
        {
            var subStream = new List<Token>();
            bool hasFoundEndingToken = false;
            string endingDelimeter = _delimeterSet.GetEndingDelimterForStartingDelimeter(findEndingTokenFor.Text);

            Token endingToken = tokenStream.Find(endingDelimeter);

            if (endingToken != null)
            {
                while (!tokenStream.IsEndOfStream && !hasFoundEndingToken)
                {
                    Token token = tokenStream.ReadNextToken();
                    subStream.Add(token);

                    hasFoundEndingToken = token.Text == endingToken.Text;
                }
            }

            return subStream;
        }
예제 #5
0
        /// <summary>
        /// Extracts tokens which represent properties for a given token and apply put those properties onto the token
        /// </summary>
        /// <param name="currentToken">token that will have properties added to it</param>
        /// <param name="tokenStream">token stream to inspect</param>
        private void ExtractPropertiesFromTokenListAndApplyToCurrentToken(Token currentToken, IWaneTokenStream tokenStream)
        {
            if (IsPropertiesStartDelimeter(tokenStream.Peek()))
            {
                List<Token> rawPropertyTokens = GetRawTokensUntilAndIncludingEndingDelimeter(tokenStream.Peek(), tokenStream);

                if (rawPropertyTokens.Count == 0)
                    currentToken.AddWarning("Properties start delimeter found, but could not find ending properties delimeter.");
                else if(rawPropertyTokens.Count == 2)
                    currentToken.AddWarning("Properties declaration contains no key value pairs. Could not construct properties.");
                else
                    ProcessProperties(currentToken, rawPropertyTokens);
            }
        }
예제 #6
0
        /// <summary>
        /// Determines if a token causes the next token to be escaped
        /// </summary>
        /// <param name="currentToken">the current token to check if it's an escape char, and if the escape char is escaping</param>
        /// <param name="tokenStream">remaining token stream</param>
        /// <returns>true if causes escape, otherwise false</returns>
        private bool DelimeterCausesEscape(Token currentToken, IWaneTokenStream tokenStream)
        {
            if (IsEscapeDelimieter(currentToken))
            {
                Token nextToken = tokenStream.Peek();

                if (nextToken.IsDelimeter)
                    return true;
                else
                    currentToken.ChangeTokenTypeToText();
            }

            return false;
        }