示例#1
0
        private void ParseStart(PreTokenEnumerator enumerator, ref FlatTokenParserState state)
        {
            var peek = enumerator.Peek(4);

            if (peek == "---\n")
            {
                state = FlatTokenParserState.InFrontMatter;
                enumerator.Next(4);
                return;
            }

            peek = enumerator.Peek(5);

            if (peek == "---\r\n")
            {
                state = FlatTokenParserState.InFrontMatter;
                enumerator.Next(4); // Next() will trim /r/n
                return;
            }

            state = FlatTokenParserState.InPreamble;
        }
示例#2
0
        private void ParseFrontMatter(PreTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref FlatTokenParserState state)
        {
            var peek = enumerator.Peek(4);

            if (peek == "---\n")
            {
                state = FlatTokenParserState.InPreamble;
                enumerator.Next(4);
                return;
            }

            peek = enumerator.Peek(5);

            if (peek == "---\r\n")
            {
                state = FlatTokenParserState.InPreamble;
                enumerator.Next(5);
                return;
            }

            var next = enumerator.Next();

            switch (next)
            {
            case "#":
                state = FlatTokenParserState.InFrontMatterComment;
                break;

            case "\n":
            case "\r":
                break;

            default:
                state = FlatTokenParserState.InFrontMatterOption;
                frontMatterName.Append(next);
                break;
            }
        }
示例#3
0
        private void ParsePreamble(ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "{":
                if (enumerator.Peek() == "{")
                {
                    token.AppendPreamble("{");
                    enumerator.Next();
                }
                else
                {
                    token.Location = enumerator.Location.Clone();
                    tokenContent.Append("{");

                    state = FlatTokenParserState.InTokenName;
                }
                break;

            case "}":
                if (enumerator.Peek() == "}")
                {
                    token.AppendPreamble("}");
                    enumerator.Next();
                    break;
                }
                throw new ParsingException($"Unescaped character '}}' in template.", enumerator);


            default:
                token.AppendPreamble(next);
                break;
            }
        }
示例#4
0
        private void ParseTokenValue(PreTemplate template, ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();
            var peek = enumerator.Peek();

            tokenContent.Append(next);

            switch (next)
            {
            case "{":
                throw new ParsingException($"Unexpected character '{{' in token '{token.Name}'", enumerator);

            case "}" when inFrontMatterToken == false:
            case "\n" when inFrontMatterToken:
                token.IsFrontMatterToken = inFrontMatterToken;
                AppendToken(template, token, ref tokenContent, options);
                token = new PreToken();
                if (inFrontMatterToken)
                {
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            case "'":
                state = FlatTokenParserState.InTokenValueSingleQuotes;
                break;

            case "\"":
                state = FlatTokenParserState.InTokenValueDoubleQuotes;
                break;

            case " ":
                switch (peek)
                {
                case " ":
                case "}" when inFrontMatterToken == false:
                case "\n" when inFrontMatterToken:
                case ":":
                    break;

                default:
                    if (token.HasValue)
                    {
                        throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                    }
                    break;
                }

                break;

            case "}" when inFrontMatterToken:
            case "\n" when inFrontMatterToken == false:
                throw  new ParsingException($"'{token.Name}' unexpected character: {next}", enumerator);

            default:
                token.AppendValue(next);
                break;
            }
        }
示例#5
0
        private void ParseTokenName(PreTemplate template, ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();
            var peek = enumerator.Peek();

            tokenContent.Append(next);

            switch (next)
            {
            case "{":
                throw new ParsingException($"Unexpected character '{{' in token '{token.Name}'", enumerator);

            case "}":
                if (inFrontMatterToken)
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                else
                {
                    AppendToken(template, token, ref tokenContent, options);
                    token = new PreToken();
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            case "$":
                token.TerminateOnNewline = true;
                switch (peek)
                {
                case " ":
                case "?":
                case "*":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "?":
                token.Optional = true;
                switch (peek)
                {
                case " ":
                case "$":
                case "*":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }

                if (token.Required)
                {
                    throw new ParsingException($"Required token {token.Name} can't be Optional", enumerator);
                }

                break;

            case "*":
                token.Repeating = true;
                token.Optional  = true;
                switch (peek)
                {
                case " ":
                case "$":
                case "?":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "!":
                token.Required = true;
                switch (peek)
                {
                case " ":
                case "*":
                case "$":
                case "?":
                case "}":
                case ":":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }

                if (token.Optional)
                {
                    throw new ParsingException($"Optional token {token.Name} can't be Required", enumerator);
                }

                break;

            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            case "=":
                state = FlatTokenParserState.InTokenValue;
                break;

            case " ":
                switch (peek)
                {
                case " ":
                case "*":
                case "$":
                case "?":
                case "}":
                case ":":
                case "!":
                case "=":
                    break;

                case "\n" when inFrontMatterToken:
                    break;

                default:
                    if (string.IsNullOrWhiteSpace(token.Name) == false)
                    {
                        throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                    }
                    break;
                }

                break;

            case "\n":
                if (inFrontMatterToken)
                {
                    token.IsFrontMatterToken = true;
                    AppendToken(template, token, ref tokenContent, options);
                    token = new PreToken();
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                break;

            default:
                if (ValidTokenNameCharacters.Contains(next))
                {
                    token.AppendName(next);
                }
                else
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                break;
            }
        }