//========================================================================================= /// <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); }
//========================================================================================= 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); } } }
//========================================================================================= /// <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; }