예제 #1
0
        /// <summary>
        /// Tokenizes an identifier.
        /// </summary>
        /// <returns>The state result</returns>
        private StateResult Identifier()
        {
            // We assume the first character has been considered.
            TakeCurrent();
            // Take all characters that are considered identifiers.
            TakeUntil(c => !HandlebarsHelpers.IsIdentifierPart(c));

            HandlebarsSymbol symbol = null;

            if (HaveContent)
            {
                var keyword = HandlebarsKeywordDetector.SymbolTypeForIdentifier(Buffer.ToString());
                var type    = HandlebarsSymbolType.Identifier;
                if (keyword != null)
                {
                    type = HandlebarsSymbolType.Keyword;
                }
                symbol = new HandlebarsSymbol(CurrentStart, Buffer.ToString(), type)
                {
                    Keyword = keyword
                };
            }
            // Start a new symbol.
            StartSymbol();

            return(Stay(symbol));
        }
예제 #2
0
        /// <summary>
        /// Continues the content of the tag.
        /// </summary>
        /// <param name="raw">True if we are expected a raw tag.</param>
        /// <returns>The state result.</returns>
        private StateResult ContinueTagContent(bool raw)
        {
            if (CurrentCharacter == '@')
            {
                TakeCurrent();

                return(Stay(EndSymbol(HandlebarsSymbolType.At)));
            }

            if (HandlebarsHelpers.IsIdentifierStart(CurrentCharacter))
            {
                return(Identifier());
            }

            if (Char.IsDigit(CurrentCharacter))
            {
                return(NumericLiteral());
            }

            switch (CurrentCharacter)
            {
            case '.':
            {
                TakeCurrent();
                if (CurrentCharacter == '/')
                {
                    // We've matched a link to the current context.
                    TakeCurrent();
                    return(Stay(EndSymbol(HandlebarsSymbolType.CurrentContext)));
                }

                if (CurrentCharacter == '.' && Peek() == '/')
                {
                    // We've matched a link to the parent context.
                    TakeCurrent();
                    TakeCurrent();
                    return(Stay(EndSymbol(HandlebarsSymbolType.ParentContext)));
                }

                // We've matched a dot, which could be part of an expression.
                return(Stay(EndSymbol(HandlebarsSymbolType.Dot)));
            }

            case '/':
            {
                TakeCurrent();
                // We've matched a forward-slash, which could be part of an expression.
                return(Stay(EndSymbol(HandlebarsSymbolType.Slash)));
            }

            case ' ':
            {
                // Take all the available whitespace.
                TakeUntil(c => !ParserHelpers.IsWhiteSpace(c));
                return(Stay(EndSymbol(HandlebarsSymbolType.WhiteSpace)));
            }

            case '~':
            {
                TakeCurrent();
                // We've reached a '~' character, so jump to the end of the tag.
                return(Transition(EndSymbol(HandlebarsSymbolType.Tilde), () => EndTag(raw)));
            }

            case '"':
            case '\'':
            {
                var quote = CurrentCharacter;
                TakeCurrent();
                // We've reached a quoted literal.
                return(QuotedLiteral(quote));
            }

            case '=':
            {
                // We're reached a map assignment.
                TakeCurrent();
                return(Stay(EndSymbol(HandlebarsSymbolType.Assign)));
            }

            case '}':
            {
                // We've reached a closing tag, so transition away.
                return(Transition(() => EndTag(raw)));
            }

            default:
            {
                CurrentErrors.Add(new Error("Unexpected character: " + CurrentCharacter, CurrentLocation));
                return(Transition(Stop));
            }
            }
        }