예제 #1
0
        /// <summary>
        /// Consumes a token and asserts that it is of a given kind. Calls <see cref="Move"/> and returns
        /// the previous value of <see cref="Current"/>.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown if <paramref name="requiredKind"/> is
        /// <see cref="TokenKind.Default"/>.</exception>
        /// <param name="requiredKind">The required kind. This may not be
        /// <see cref="TokenKind.Default"/>.</param>
        /// <returns>The next token for consumption.</returns>
        public Token Require(TokenKind requiredKind)
        {
            if (requiredKind == TokenKind.Default)
            {
                throw new ArgumentException(Strings.RequiredInvalidToken, "requiredKind");
            }

            Token result = this.Current;

            if (result.Kind != requiredKind)
            {
                throw G4ParseFailureException.UnexpectedToken(this.Current);
            }

            this.Move();
            return(result);
        }
예제 #2
0
        /// <summary>Parses a G4 non-terminal.</summary>
        /// <exception cref="G4ParseFailureException">Thrown when the input is not valid.</exception>
        /// <returns>A GrammarSymbol containing the non-terminal.</returns>
        public GrammarSymbol ParseNonTerminal()
        {
            ImmutableArray <Annotation> annotations = _iterator.ConsumeAnnotations();
            Token current = _iterator.Consume();

            if (current.Kind == TokenKind.Identifier)
            {
                return(new GrammarSymbol(current, SymbolKind.Identifier, annotations));
            }

            if (current.Kind == TokenKind.Lparen)
            {
                GrammarSymbol result = this.ParseAlternation();
                _iterator.Require(TokenKind.Rparen);
                return(result);
            }

            if (current.Kind != TokenKind.String)
            {
                throw G4ParseFailureException.UnexpectedToken(current);
            }

            if (_iterator.Current.Kind == TokenKind.Dots)
            {
                CheckForBadCharacterRangeCharacterLength(current);
                _iterator.Move(); // dots
                Token secondString = _iterator.Require(TokenKind.String);
                CheckForBadCharacterRangeCharacterLength(secondString);
                CheckForCorrectlyOrderedCharacterRange(current, secondString);
                return(new GrammarSymbol(current, secondString, SymbolKind.CharacterRange));
            }
            else
            {
                return(new GrammarSymbol(current, SymbolKind.String));
            }
        }