InputScanner.cs
84 lines
| 2.6 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r228 | using Implab.Automaton; | ||
using System; | ||||
using System.Collections.Generic; | ||||
using System.Linq; | ||||
cin
|
r229 | using System.Runtime.CompilerServices; | ||
cin
|
r228 | using System.Text; | ||
using System.Threading.Tasks; | ||||
namespace Implab.Formats { | ||||
public class InputScanner<TTag> { | ||||
readonly TTag[] m_tags; | ||||
readonly int m_initialState; | ||||
readonly int[,] m_dfa; | ||||
readonly CharMap m_alphabet; | ||||
readonly bool[] m_final; | ||||
int m_position; | ||||
int m_state; | ||||
public InputScanner(int[,] dfaTable, bool[] finalStates, TTag[] tags, int initialState, CharMap alphabet) { | ||||
Safe.ArgumentNotNull(dfaTable, nameof(dfaTable)); | ||||
Safe.ArgumentNotNull(finalStates, nameof(finalStates)); | ||||
Safe.ArgumentNotNull(tags, nameof(tags)); | ||||
Safe.ArgumentNotNull(alphabet, nameof(alphabet)); | ||||
m_dfa = dfaTable; | ||||
m_final = finalStates; | ||||
m_tags = tags; | ||||
m_initialState = initialState; | ||||
m_alphabet = alphabet; | ||||
} | ||||
public TTag Tag { | ||||
cin
|
r229 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
cin
|
r228 | get { | ||
return m_tags[m_state]; | ||||
} | ||||
} | ||||
public int Position { | ||||
cin
|
r229 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
cin
|
r228 | get { | ||
return m_position; | ||||
} | ||||
} | ||||
public bool IsFinal { | ||||
cin
|
r229 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
cin
|
r228 | get { | ||
return m_final[m_state]; | ||||
} | ||||
} | ||||
cin
|
r229 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public void ResetState() { | ||||
cin
|
r228 | m_state = m_initialState; | ||
} | ||||
public InputScanner<TTag> Clone() { | ||||
var clone = new InputScanner<TTag>(m_dfa, m_final, m_tags, m_initialState, m_alphabet); | ||||
clone.m_state = m_state; | ||||
clone.m_position = m_position; | ||||
return clone; | ||||
} | ||||
cin
|
r229 | //[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public bool Scan(char[] data, int offset, int max) { | ||||
cin
|
r228 | var next = m_state; | ||
while(offset < max) { | ||||
next = m_dfa[next, m_alphabet.Translate(data[offset])]; | ||||
if (next == AutomatonConst.UNREACHABLE_STATE) { | ||||
// scanner stops on the next position after last recognized symbol | ||||
m_position = offset; | ||||
return false; | ||||
} | ||||
m_state = next; | ||||
offset++; | ||||
} | ||||
m_position = offset; | ||||
return true; | ||||
} | ||||
} | ||||
} | ||||