Ejemplo n.º 1
0
		//=========================================================================================
		/// <summary>Задать строку для нового разбора на токены.</summary>
		public void SetSource(string text)
		{
			this.CurrentState = null;
			this.ReturnPreviousToken = false;
			this.Errors.Clear();
			this._Reader.SetSource(text);
		}
Ejemplo n.º 2
0
 //=========================================================================================
 /// <summary>Задать строку для нового разбора на токены.</summary>
 public void SetSource(string text)
 {
     this.CurrentState        = null;
     this.ReturnPreviousToken = false;
     this.Errors.Clear();
     this._Reader.SetSource(text);
 }
Ejemplo n.º 3
0
        //=========================================================================================
        /// <summary>Получить очередной токен.</summary>
        public Token ReadNextToken()
        {
            if (this.ReturnPreviousToken && this.LastToken != null)
            {
                this.ReturnPreviousToken = false;
                return(this.LastToken);
            }

            ///Пропускаем все пробелы
            char cChar;

            do
            {
                cChar = this._Reader.ReadChar();
                if (cChar == '\0')
                {
                    return(null);
                }
            }while (char.IsWhiteSpace(cChar));

            ///Становимся на начальное состояние
            this.CurrentState = this.Specification.StartState;
            ///Засекаем начало токена
            int iStart     = this._Reader.Position - 1;
            var pointStart = this._Reader.PreviousPoint;

            while (true)
            {
                ///Ищем следующее состояние на основании текущего символа
                var oNewState = this.CurrentState.GetNextState(cChar);
                ///Если мы перешли в состоянии ошибки, генерим ошибку
                if (oNewState == this.Specification.FailState)
                {
                    this.Errors.Add(this.CurrentState.GetExpectationToString());
                }
                ///Если пора выходить
                if (oNewState == this.Specification.EndState)
                {
                    var oToken = this.GetToken(iStart, pointStart, this._Reader.Position - 1, this._Reader.PreviousPoint);
                    ///Возвращаемся на символ назад, чтобы в следующий раз начать с правильной позиции
                    this._Reader.BackToChar();
                    return(oToken);
                }
                if (oNewState == null)
                {
                    throw new NullReferenceException(this.CurrentState.Name);
                }
                this.CurrentState = oNewState;

                ///Читаем новый символ
                cChar = this._Reader.ReadChar();
                if (cChar == '\0')
                {
                    return(this.GetToken(iStart, pointStart, this._Reader.Position, this._Reader.Point));
                }
            }
        }
Ejemplo n.º 4
0
		//=========================================================================================
		/// <summary>Получить очередной токен.</summary>
		public Token ReadNextToken()
		{
			if (this.ReturnPreviousToken && this.LastToken != null)
			{
				this.ReturnPreviousToken = false;
				return this.LastToken;
			}

			///Пропускаем все пробелы
			char cChar;
			do
			{
				cChar = this._Reader.ReadChar();
				if (cChar == '\0')
					return null;
			}
			while (char.IsWhiteSpace(cChar));

			///Становимся на начальное состояние
			this.CurrentState = this.Specification.StartState;
			///Засекаем начало токена
			int iStart = this._Reader.Position - 1;
			var pointStart = this._Reader.PreviousPoint;

			while (true)
			{
				///Ищем следующее состояние на основании текущего символа
				var oNewState = this.CurrentState.GetNextState(cChar);
				///Если мы перешли в состоянии ошибки, генерим ошибку
				if (oNewState == this.Specification.FailState)
				{
					this.Errors.Add(this.CurrentState.GetExpectationToString());
				}
				///Если пора выходить
				if (oNewState == this.Specification.EndState)
				{
					var oToken = this.GetToken(iStart, pointStart, this._Reader.Position - 1, this._Reader.PreviousPoint);
					///Возвращаемся на символ назад, чтобы в следующий раз начать с правильной позиции
					this._Reader.BackToChar();
					return oToken;
				}
				if (oNewState == null)
					throw new NullReferenceException(this.CurrentState.Name);
				this.CurrentState = oNewState;

				///Читаем новый символ
				cChar = this._Reader.ReadChar();
				if (cChar == '\0')
					return this.GetToken(iStart, pointStart, this._Reader.Position, this._Reader.Point);
			}
		}
Ejemplo n.º 5
0
        //=========================================================================================
        public ScannerSpecification()
        {
            this.Literals   = new List <Literal>();
            this.States     = new List <StateScannerState>();
            this.StartState = new StateScannerState("<start>");
            this.EndState   = new StateScannerState("<end>");
            this.FailState  = new StateScannerState("<fail>");
            this.States.Add(this.StartState);
            this.States.Add(this.EndState);
            this.States.Add(this.FailState);

            this.StartState.SetDefaultLink(this.FailState);
            this.FailState.SetDefaultLink(this.EndState);
        }
Ejemplo n.º 6
0
		//=========================================================================================
		public ScannerSpecification()
		{
			this.Literals = new List<Literal>();
			this.States = new List<StateScannerState>();
			this.StartState = new StateScannerState("<start>");
			this.EndState = new StateScannerState("<end>");
			this.FailState = new StateScannerState("<fail>");
			this.States.Add(this.StartState);
			this.States.Add(this.EndState);
			this.States.Add(this.FailState);

			this.StartState.SetDefaultLink(this.FailState);
			this.FailState.SetDefaultLink(this.EndState);
		}
Ejemplo n.º 7
0
        //=========================================================================================
        /// <summary>Создать новое состояние или взять уже существующее, в которое мы переходим из указанного при получении на входе указанного символа.</summary>
        StateScannerState CreateOrGetState(StateScannerState from, Literal incoming, string stateName, string tokenName)
        {
            StateScannerState oState;

            if (from.Entries.TryGetValue(incoming, out oState))
            {
                if (oState == this.EndState)
                {
                    string sMsg = string.Format("Ambiguous link {0}->{1}: {2} or {3}.",
                                                from.Name, incoming.Name, from.ResultTokenName, tokenName);
                    throw new ArgumentException(sMsg);
                }
                return(oState);
            }

            StateScannerState oNewState = new StateScannerState(stateName);

            from.AddLink(incoming, oNewState);
            this.States.Add(oNewState);
            oNewState.ResultTokenName = tokenName;
            return(oNewState);
        }
Ejemplo n.º 8
0
        //=========================================================================================
        internal void AddBoundedToken(string name, string start, string end, string escape, int startlen, int endlen)
        {
            ///Находим начальные и конечные литералы
            Literal[] startLiterals = GetLiteralsFromString(start);
            Literal[] endLiterals   = GetLiteralsFromString(end);

            ///Состояние, в котором будут приняты все символы между ограничителями
            StateScannerState oReccurentState;

            ///Создаем состояния для обработки входных ограничителей
            {
                StateScannerState oCurrentState = this.StartState;
                for (int i = 0; i < startLiterals.Length; i++)
                {
                    string sStateName = string.Format("<{0}_start_{1}>", name, i);
                    var    oNewState  = this.CreateOrGetState(oCurrentState, startLiterals[i], sStateName, name);
                    if (oNewState.ElseState == null)
                    {
                        oNewState.SetDefaultLink(this.FailState);
                    }
                    oCurrentState = oNewState;
                }
                oReccurentState = oCurrentState;
            }

            ///Будем находиться в этом состоянии, пока не придет конечный ограничитель
            oReccurentState.SetDefaultLink(oReccurentState);

            ///Выходное состояние
            StateScannerState oEndState;

            ///Создаем состояния для обработки выходных ограничителей
            {
                ///Состояние, на которое нужно перейти в случае, если прерывается цепочка конечных ограничителей,
                ///но вместе с тем поступил первый ограничитель из этой цепочки.
                StateScannerState oFirstEndState = null;
                ///Номер такого состояния
                int iFirstEndState = 0;
                for (int i = 1; i < endLiterals.Length; i++)
                {
                    if (endLiterals[i] == endLiterals[0])
                    {
                        iFirstEndState = i;
                    }
                    else
                    {
                        break;
                    }
                }
                StateScannerState oCurrentState = oReccurentState;
                for (int i = 0; i < endLiterals.Length; i++)
                {
                    string sStateName = string.Format("<{0}_end_{1}>", name, i);
                    var    oNewState  = this.CreateOrGetState(oCurrentState, endLiterals[i], sStateName, name);
                    if (i == iFirstEndState)
                    {
                        if (string.IsNullOrEmpty(escape))
                        {
                            oFirstEndState = oNewState;
                        }
                    }
                    if (oFirstEndState != null)
                    {
                        oNewState.AddLink(endLiterals[0], oFirstEndState);
                    }
                    oNewState.SetDefaultLink(oReccurentState);
                    oCurrentState = oNewState;
                }
                oEndState = oCurrentState;
            }
            oEndState.SetDefaultLink(this.EndState);
            oEndState.StartLimiterLength = startlen;
            oEndState.EndLimiterLength   = endlen;

            var oEscapeLiteral = this.GetLiteralByName(escape);

            if (oEscapeLiteral != null)
            {
                StateScannerState oNextState = oReccurentState.GetNextState(oEscapeLiteral);
                if (oNextState == null || oNextState == oReccurentState.ElseState)
                {
                    string sStateName = string.Format("<{0}_escape>", name);
                    var    oNewState  = this.CreateOrGetState(oReccurentState, oEscapeLiteral, sStateName, name);
                    oNewState.SetDefaultLink(oReccurentState);
                }
                else
                {
                    oNextState.AddLink(startLiterals[0], oReccurentState);
                }
            }
        }
Ejemplo n.º 9
0
		//=========================================================================================
		/// <summary>Переход по умолчанию, который выполняется, если не срабатывают условия других переходов.</summary>
		internal void SetDefaultLink(StateScannerState state)
		{
			this.ElseState = state;
		}
Ejemplo n.º 10
0
		//=========================================================================================
		internal void AddLink(Literal literal, StateScannerState state)
		{
			this.Entries.Add(literal, state);
		}
Ejemplo n.º 11
0
		//=========================================================================================
		/// <summary>Создать новое состояние или взять уже существующее, в которое мы переходим из указанного при получении на входе указанного символа.</summary>
		StateScannerState CreateOrGetState(StateScannerState from, Literal incoming, string stateName, string tokenName)
		{
			StateScannerState oState;
			if (from.Entries.TryGetValue(incoming, out oState))
			{
				if (oState == this.EndState)
				{
					string sMsg = string.Format("Ambiguous link {0}->{1}: {2} or {3}.",
						from.Name, incoming.Name, from.ResultTokenName, tokenName);
					throw new ArgumentException(sMsg);
				}
				return oState;
			}

			StateScannerState oNewState = new StateScannerState(stateName);
			from.AddLink(incoming, oNewState);
			this.States.Add(oNewState);
			oNewState.ResultTokenName = tokenName;
			return oNewState;
		}
Ejemplo n.º 12
0
 //=========================================================================================
 /// <summary>Переход по умолчанию, который выполняется, если не срабатывают условия других переходов.</summary>
 internal void SetDefaultLink(StateScannerState state)
 {
     this.ElseState = state;
 }
Ejemplo n.º 13
0
 //=========================================================================================
 internal void AddLink(Literal literal, StateScannerState state)
 {
     this.Entries.Add(literal, state);
 }