Ejemplo n.º 1
0
        /// <summary>
        /// Attempts to execute a transducer with content from a <see cref="StringCodeReader" />. If the
        /// state reached is not a terminal state, the reader is rewinded to it's initial position.
        /// </summary>
        /// <typeparam name="OutputT"></typeparam>
        /// <param name="transducer"></param>
        /// <param name="reader"></param>
        /// <param name="output"></param>
        /// <returns>Whether the state reached was a terminal state.</returns>
        public static Boolean TryExecute <OutputT>(this Transducer <Char, OutputT> transducer, ICodeReader reader, [MaybeNull] out OutputT output)
        {
            if (transducer is null)
            {
                throw new ArgumentNullException(nameof(transducer));
            }
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var start = reader.Position;
            TransducerState <Char, OutputT> state = transducer.InitialState;

            while (reader.Position != reader.Length)
            {
                if (!state.TransitionTable.TryGetValue(reader.Peek() !.Value, out TransducerState <Char, OutputT>?tmp))
                {
                    break;
                }
                state = tmp;
                reader.Advance(1);
            }

            if (state.IsTerminal)
            {
                output = state.Output;
                return(true);
            }

            reader.Restore(start);
            // Since the analyzer doesn't seems to obey [MaybeNull], we ignore the warning
            output = default;
            return(false);
        }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        public Option <Token <TTokenType> > TryConsume(ICodeReader reader, DiagnosticList diagnostics)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var start = reader.Position;

            reader.Advance(Prefix.Length);
            return(new Token <TTokenType>(
                       _id,
                       _type,
                       new Range <int>(start, reader.Position),
                       _isTrivia,
                       _value,
                       Prefix));
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public Option <Token <TTokenType> > TryConsume(ICodeReader reader, DiagnosticList diagnostics)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var start  = reader.Position;
            var result = _expression != null?reader.PeekRegex(_expression) : reader.PeekRegex(_regex !);

            if (result.Success)
            {
                reader.Advance(result.Length);
                return(new Token <TTokenType>(
                           _id,
                           _type,
                           new Range <int>(start, reader.Position),
                           _isTrivia,
                           _converter != null ? _converter(result, diagnostics) : result.Value,
                           result.Value));
            }

            return(default);