Ejemplo n.º 1
0
        public static Result <ImmutableArray <ColumnSort> > ParseSortLevel(string annotationValue)
        {
            var sortLevel = ImmutableArray.CreateBuilder <ColumnSort>();

            var context = new LexingContext(new Lexer(annotationValue));

            var usedFieldNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (!context.TryLex(SyntaxKind.Identifier, SyntaxKind.EndOfInput))
            {
                return(Result.Error(context.ErrorMessage !));
            }

            while (context.CurrentToken.Kind != SyntaxKind.EndOfInput)
            {
                var fieldName        = context.CurrentToken.Value !;
                var directionKeyword = (SyntaxKind?)null;

                if (!context.TryLex(SyntaxKind.AscKeyword, SyntaxKind.DescKeyword, SyntaxKind.CommaToken, SyntaxKind.EndOfInput))
                {
                    return(Result.Error(context.ErrorMessage !));
                }

                switch (context.CurrentToken.Kind)
                {
                case SyntaxKind.AscKeyword:
                case SyntaxKind.DescKeyword:
                    directionKeyword = context.CurrentToken.Kind;

                    if (!context.TryLex(SyntaxKind.CommaToken, SyntaxKind.EndOfInput))
                    {
                        return(Result.Error(context.ErrorMessage !));
                    }
                    break;
                }

                if (!usedFieldNames.Add(fieldName))
                {
                    return(Result.Error($"The field name ‘{fieldName}’ appears more than once."));
                }

                sortLevel.Add(new ColumnSort(
                                  fieldName,
                                  ascendingOrder: (directionKeyword ?? SyntaxKind.AscKeyword) == SyntaxKind.AscKeyword));

                if (context.CurrentToken.Kind == SyntaxKind.CommaToken)
                {
                    if (!context.TryLex(SyntaxKind.Identifier))
                    {
                        return(Result.Error(context.ErrorMessage !));
                    }
                }
            }

            return(Result.Success(sortLevel.ToImmutable()));
        }
Ejemplo n.º 2
0
        public ILexicalToken Produce(LexingContext context)
        {
            var start  = context.Position;
            var input  = context.Input.Span;
            var length = input.Length;

            var c = input[start];

            if (!c.IsInlineWhiteSpaceOrCaretControl())
            {
                return(null);
            }

            var pos = start;

            while (true)
            {
                if (pos == length)
                {
                    context.Position += pos - start;
                    return(null); // todo: wrong? in a case of string of spaces, what the result would be?
                }

                c = input[pos];
                switch (c)
                {
                case '\t':
                case ' ':
                case '\v':
                case '\f':
                case '\r':
                case '\n':
                    pos++;
                    break;

                default:
                    var delta = pos - start;
                    context.Position += delta;
                    return(EmptyToken.Instance);
                }
            }
        }
Ejemplo n.º 3
0
 public ILexicalToken Produce(LexingContext context)
 {
     var start = context.Position;
     var input = context.Input.Span[start..];
Ejemplo n.º 4
0
        public ILexicalToken Produce(LexingContext context)
        {
            // todo checks. consider LexicalTokenProducerBase + ProduceImpl

            var start = context.Position;
            var input = context.Input.Span[start..];
Ejemplo n.º 5
0
        public ILexicalToken Produce(LexingContext context)
        {
            var text   = context.Input.Span;
            var length = text.Length;

            var c = text[context.Position];

            if (c == '"')
            {
                var start = context.Position;
                var pos   = start + 1; // skip '"'

                var sb = new StringBuilder();

                while (true)
                {
                    if (pos == length)
                    {
                        throw Helper.CreateException(ParsingErrorTag.UnclosedString, pos);
                    }

                    c = text[pos];

                    if (c.IsCaretControl())
                    {
                        throw Helper.CreateException(ParsingErrorTag.NewLineInString, pos);
                    }

                    if (c == '\\')
                    {
                        if (pos + 1 == length)
                        {
                            throw Helper.CreateException(ParsingErrorTag.UnclosedString, length);
                        }

                        var nextChar = text[pos + 1];
                        if (nextChar == 'u')
                        {
                            var remaining = length - (pos + 1);
                            if (remaining < 5)
                            {
                                throw Helper.CreateException(ParsingErrorTag.BadEscape, pos);
                            }

                            var hexNumString = text.Slice(pos + 2, 4);
                            var codeParsed   = int.TryParse(
                                hexNumString,
                                NumberStyles.HexNumber,
                                CultureInfo.InvariantCulture,
                                out var code);

                            if (!codeParsed)
                            {
                                throw Helper.CreateException(ParsingErrorTag.BadEscape, pos);
                            }

                            var unescapedChar = (char)code;
                            sb.Append(unescapedChar);

                            pos += 6;
                            continue;
                        }
                        else
                        {
                            var replacement = GetReplacement(nextChar);
                            if (replacement.HasValue)
                            {
                                sb.Append(replacement);
                                pos += 2;
                                continue;
                            }
                            else
                            {
                                throw Helper.CreateException(ParsingErrorTag.BadEscape, pos);
                            }
                        }
                    }

                    pos++;

                    if (c == '"')
                    {
                        break;
                    }

                    sb.Append(c);
                }

                var delta = pos - start;
                var str   = sb.ToString();

                var token = new StringToken(
                    start,
                    delta,
                    str,
                    "C");

                context.Position += delta;
                return(token);
            }

            return(null);
        }