using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Text; namespace Rokojori { public class LexerEvent { string _type; int _offset; int _length; string _match; public string match => _match; public LexerEvent( string type, int offset, int length ) { Set( type, offset, length ); } public string type { get { return _type; } } public int offset { get { return _offset; } } public int length { get { return _length; } } string _mode = null; public string mode { get { if ( _mode != null ) { return _mode; } var modeDelimiterPosition = type.IndexOf( LexerMatcher.FullTypeDelimiter ); if ( modeDelimiterPosition == -1 ) { _mode = ""; return _mode; } _mode = type.Substring( 0, modeDelimiterPosition ); return _mode; } } public bool isError { get { return this.length == -1; } } public bool isDone { get { return this.length == -2; } } public void Set( string type, int offset, int length ) { this._type = type; this._offset = offset; this._length = length; } public LexerEvent Copy() { return new LexerEvent( _type, _offset, _length ); } public int end { get { return this._offset + _length; } } public override string ToString() { return "Token{ '" + type + "' (" + offset + "-" + end + ") }"; } public void GrabMatch( string source ) { if ( _length < 0 ) { return; } _match = source.Substring( offset, length ); } public bool Is( string type, string match = null ) { var typeCorrect = type == null || type == this.type; if ( ! typeCorrect ) { return false; } return match == null || match == this.match; } public bool Is( LexerMatcher matcher, string match = null ) { return Is( matcher == null ? null : matcher.type, match ); } public enum FindResultType { Found, KeepSearching, NotFound, Error } public class FindResult { public FindResultType type = FindResultType.NotFound; public int index; } public static string GetMatchFromRange( List tokens, int offset, int length ) { var match = new StringBuilder(); for ( int i = 0; i < length; i++ ) { match.Append( tokens[ offset + i ].match ); } return match.ToString(); } public static FindResult Find( List tokens, int offset, System.Func evaluator ) { var result = new FindResult(); for ( int i = offset; i < tokens.Count; i++ ) { var tokenResult = evaluator( tokens[ i ] ); if ( tokenResult == FindResultType.Error || tokenResult == FindResultType.Found ) { result.type = tokenResult; result.index = i; return result; } } return result; } public static FindResult FindClosingBracket( List tokens, int offset ) { var openTypes = new List(){ "(","[","{" }; var closingTypes = new List(){ ")","]","}" }; var token = tokens[ offset ]; var bracketIndex = openTypes.IndexOf( token.match ); if ( bracketIndex == -1 ) { var result = new FindResult(); result.type = FindResultType.NotFound; result.index = offset; return result; } var opener = openTypes[ bracketIndex ]; var closer = closingTypes[ bracketIndex ]; var counter = ( LexerEvent le ) => { if ( le.Is( LexerMatcherLibrary.BracketMatcher, closer ) ) { return -1; } if ( le.Is( LexerMatcherLibrary.BracketMatcher, opener ) ) { return 1; } return 0; }; return FindCloser( tokens, offset, counter ); } public static FindResult FindCloser( List tokens, int offset, System.Func counter ) { var result = new FindResult(); var currentValue = 0; for ( int i = offset; i < tokens.Count; i++ ) { var countResult = counter( tokens[ i ] ); currentValue += countResult; if ( currentValue == 0 ) { result.type = FindResultType.Found; result.index = i; return result; } } return result; } } }