Пример #1
0
        public IEnumerable <IEnumerable <Token <TokenType> > > ReadItemsToClosureTrimmed(TokenType open, TokenType close, TokenType separator, BracketPairs bracketPairs)
        {
            SkipSpace();
            _stack.Clear();
            Token <TokenType> token = null;

            int start = _pos;

            while (!End)
            {
                token = PeekToken();
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Allows nesting
                {
                    _stack.Push(token);
                }
                else if (bracketPairs.ContainsClosing(token.Identifier) || token.Identifier == close) // Allows nesting
                {
                    // Since this method assumes that the first opening bracket was already read, an empty _stack indicates main scope closure.
                    if (!_stack.Any() && token.Identifier == close)
                    {
                        yield return(_tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray());

                        _pos++;
                        yield break;
                    }

                    var lastOpening = _stack.Pop();
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier))
                    {
                        throw new RantException(_source, token,
                                                "Invalid closure '"
                                                + lastOpening.Value
                                                + " ... "
                                                + token.Value
                                                + "' - expected '"
                                                + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier))
                                                + "'");
                    }
                }
                else if (token.Identifier == separator && !_stack.Any())
                {
                    yield return(_tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray());

                    _pos++;
                    TakeAll(TokenType.Whitespace);
                    start = _pos;
                    continue;
                }

                _pos++;
            }
            throw new RantException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }
Пример #2
0
        public IEnumerable <Token <TokenType> > ReadToScopeClose(TokenType open, TokenType close, BracketPairs bracketPairs)
        {
            SkipSpace();
            _stack.Clear();
            Token <TokenType> token = null;

            while (!End)
            {
                token = ReadToken();
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Allows nesting
                {
                    _stack.Push(token);
                }
                else if (bracketPairs.ContainsClosing(token.Identifier) || token.Identifier == close) // Allows nesting
                {
                    // Since this method assumes that the first opening bracket was already read, an empty _stack indicates main scope closure.
                    if (!_stack.Any() && token.Identifier == close)
                    {
                        yield break;
                    }

                    var lastOpening = _stack.Pop();
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier))
                    {
                        throw new RantException(_source, token,
                                                "Invalid closure '"
                                                + lastOpening.Value
                                                + " ... "
                                                + token.Value
                                                + "' - expected '"
                                                + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier))
                                                + "'");
                    }
                }
                yield return(token);
            }
            throw new RantException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }
Пример #3
0
        public IEnumerable<Token<TokenType>> ReadToScopeClose(TokenType open, TokenType close, BracketPairs bracketPairs)
        {
            SkipSpace();
            _stack.Clear();
            Token<TokenType> token = null;
            while (!End)
            {
                token = ReadToken();
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Allows nesting
                {
                    _stack.Push(token);
                }
                else if (bracketPairs.ContainsClosing(token.Identifier) || token.Identifier == close) // Allows nesting
                {
                    // Since this method assumes that the first opening bracket was already read, an empty _stack indicates main scope closure.
                    if (!_stack.Any() && token.Identifier == close)
                    {
                        yield break;
                    }

                    var lastOpening = _stack.Pop();
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier))
                    {
                        throw new ManhoodException(_source, token,
                            "Invalid closure '"
                            + lastOpening.Value
                            + " ... "
                            + token.Value
                            + "' - expected '"
                            + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier))
                            + "'");
                    }
                }
                yield return token;
            }
            throw new ManhoodException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }
Пример #4
0
        public IEnumerable<IEnumerable<Token<TokenType>>> ReadItemsToClosureTrimmed(TokenType open, TokenType close, TokenType separator, BracketPairs bracketPairs)
        {
            SkipSpace();
            _stack.Clear();
            Token<TokenType> token = null;

            int start = _pos;
            while (!End)
            {
                token = PeekToken();
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Allows nesting
                {
                    _stack.Push(token);
                }
                else if (bracketPairs.ContainsClosing(token.Identifier) || token.Identifier == close) // Allows nesting
                {
                    // Since this method assumes that the first opening bracket was already read, an empty _stack indicates main scope closure.
                    if (!_stack.Any() && token.Identifier == close)
                    {
                        yield return _tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray();
                        _pos++;
                        yield break;
                    }

                    var lastOpening = _stack.Pop();
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier))
                    {
                        throw new ManhoodException(_source, token,
                            "Invalid closure '"
                            + lastOpening.Value
                            + " ... "
                            + token.Value
                            + "' - expected '"
                            + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier))
                            + "'");
                    }
                }
                else if (token.Identifier == separator && !_stack.Any())
                {
                    yield return _tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray();
                    _pos++;
                    TakeAll(TokenType.Whitespace);
                    start = _pos;
                    continue;
                }

                _pos++;
            }
            throw new ManhoodException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }
Пример #5
0
        public IEnumerable<IEnumerable<Token<TokenType>>> ReadMultiItemScope(TokenType open, TokenType close, TokenType separator, BracketPairs bracketPairs)
        {
            _stack.Clear();
            // This exception should not happen when running patterns - only if I mess something up in the code.
            if (!IsNext(open)) throw new InvalidOperationException("The specified opening token does not occur at the reader position.");

            int start = _pos + 1;
            Token<TokenType> token = null;

            while (!End)
            {
                // Peek but don't consume - this saves some calculations later on.
                token = PeekToken();

                // Opening bracket
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Previous bracket allows nesting
                {
                    _stack.Push(token);
                }

                // Closing bracket
                else if (bracketPairs.ContainsClosing(token.Identifier) || close == token.Identifier) // Previous bracket allows nesting
                {
                    var lastOpening = _stack.Pop();

                    // Handle invalid closures
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier)) // Not in main pair
                    {
                        throw new ManhoodException(_source, token, 
                            "Invalid closure '"
                            + lastOpening.Value
                            + " ... " 
                            + token.Value 
                            + "' - expected '" 
                            + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier)) 
                            + "'");
                    }

                    // If the _stack is empty, this is the last item. Stop the iterator.
                    if (!_stack.Any())
                    {
                        yield return _tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray();
                        _pos++;
                        yield break;
                    }
                }

                // Separator
                else if (token.Identifier == separator && _stack.Count == 1)
                {
                    yield return _tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray();
                    start = _pos + 1;
                }

                // Move to next position
                _pos++;
            }
            throw new ManhoodException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }
Пример #6
0
        public IEnumerable <IEnumerable <Token <TokenType> > > ReadMultiItemScope(TokenType open, TokenType close, TokenType separator, BracketPairs bracketPairs)
        {
            _stack.Clear();
            // This exception should not happen when running patterns - only if I mess something up in the code.
            if (!IsNext(open))
            {
                throw new InvalidOperationException("The specified opening token does not occur at the reader position.");
            }

            int start = _pos + 1;
            Token <TokenType> token = null;

            while (!End)
            {
                // Peek but don't consume - this saves some calculations later on.
                token = PeekToken();

                // Opening bracket
                if (bracketPairs.ContainsOpening(token.Identifier) || open == token.Identifier) // Previous bracket allows nesting
                {
                    _stack.Push(token);
                }

                // Closing bracket
                else if (bracketPairs.ContainsClosing(token.Identifier) || close == token.Identifier) // Previous bracket allows nesting
                {
                    var lastOpening = _stack.Pop();

                    // Handle invalid closures
                    if (!bracketPairs.Contains(lastOpening.Identifier, token.Identifier)) // Not in main pair
                    {
                        throw new RantException(_source, token,
                                                "Invalid closure '"
                                                + lastOpening.Value
                                                + " ... "
                                                + token.Value
                                                + "' - expected '"
                                                + Lexer.Rules.GetSymbolForId(bracketPairs.GetClosing(lastOpening.Identifier))
                                                + "'");
                    }

                    // If the _stack is empty, this is the last item. Stop the iterator.
                    if (!_stack.Any())
                    {
                        yield return(_tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray());

                        _pos++;
                        yield break;
                    }
                }

                // Separator
                else if (token.Identifier == separator && _stack.Count == 1)
                {
                    yield return(_tokens.SkipWhile((t, i) => i < start).TakeWhile((t, i) => i < _pos - start).ToArray());

                    start = _pos + 1;
                }

                // Move to next position
                _pos++;
            }
            throw new RantException(_source, null, "Unexpected end of file - expected '" + Lexer.Rules.GetSymbolForId(close) + "'.");
        }