view Implab/Formats/BufferScanner.cs @ 175:96a89dcb4060 ref20160224

sync
author cin
date Mon, 21 Mar 2016 18:41:45 +0300
parents 983df35b3ca1
children
line wrap: on
line source

using System;
using Implab.Automaton.RegularExpressions;
using Implab.Automaton;
using System.Diagnostics;

namespace Implab.Formats {
    public struct BufferScanner<TTag> {
        readonly DFAStateDescriptor<TTag>[] m_dfa;
        int m_state;
        int m_pos;

        public BufferScanner(DFAStateDescriptor<TTag>[] dfa, int initialState) {
            m_dfa = dfa;
            m_state = initialState;
        }

        public int Position {
            get { return m_pos; }
        }

        /// <summary>
        /// Scan this instance.
        /// </summary>
        /// <returns><c>true</c> - additional data required</returns>
        public bool Scan(int[] buffer, int position, int length) {
            var hi = position + length;
            m_pos = position;

            while (position < hi) {
                var next = m_dfa[m_state].transitions[buffer[position]];
                if (next == DFAConst.UNREACHABLE_STATE) {
                    if (m_dfa[m_state].final)
                        return false;

                    throw new ParserException(
                        String.Format(
                            "Unexpected symbol"
                        )
                    );
                }
                m_pos++;
                m_state = next;
            }

            return true;
        }

        public void Eof() {
            if (!m_dfa[m_state].final)
                throw new ParserException(
                    String.Format(
                        "Unexpected EOF"
                    )
                );
        }

        public TTag[] GetTokenTags() {
            return m_dfa[m_state].tags;
        }
    }
}