void Symbol(out List <StateScannerState> newStates, List <StateScannerState> startStates, List <StateScannerState> endStates) { newStates = null; if (la.kind == 1) { Get(); var oTokenSpec = this.Spec.GetLiteralByName(t.val); if (oTokenSpec == null) { this.SemErr(t.val); return; } StateScannerState oNextState = null; foreach (var oStartState in startStates) { if (oStartState.Entries.TryGetValue(oTokenSpec, out oNextState)) { break; } } if (oNextState == null) { string sStateName = "<" + (this.Spec.States.Count - 2).ToString() + ">"; oNextState = new StateScannerState(sStateName); this.Spec.States.Add(oNextState); } foreach (var oStartState in startStates) { if (!oStartState.Entries.ContainsKey(oTokenSpec)) { oStartState.AddLink(oTokenSpec, oNextState); oStartState.SetDefaultLink(this.Spec.FailState); } } newStates = new List <StateScannerState> { oNextState }; } else if (la.kind == 3) { Get(); Expression(out newStates, startStates, endStates); Expect(4); } else if (la.kind == 5) { Get(); Expression(out newStates, startStates, endStates); Expect(6); if (newStates != null) { newStates.AddRange(startStates); } } else if (la.kind == 7) { Get(); Expression(out newStates, startStates, endStates); Expect(8); if (newStates != null && startStates != null) { ///startStates в данном случае - это элементы перед началом необязательная части, которая может повторяться многократно. ///Надо организовать цикл повторяющейся части, а для этого нам нужен переход на ее начало. ///Значит для всех конечных состояний (newStates) мы делаем переходы по таким же условиям, что и для startStates. foreach (var oStartState in startStates) { foreach (var oEntry in oStartState.Entries) { foreach (var oNewState in newStates) { if (!oNewState.Entries.ContainsKey(oEntry.Key)) { oNewState.AddLink(oEntry.Key, oEntry.Value); } } } } ///Поскольку мы имеем дело с необязательно конструкцией, которая может быть, а может и не быть, ///то входные состояния дальше мы будем обрабатывать так же как и выходные. newStates.AddRange(startStates); } } else { SynErr(10); } }
void Symbol(out List<StateScannerState> newStates, List<StateScannerState> startStates, List<StateScannerState> endStates ) { newStates = null; if (la.kind == 1) { Get(); var oTokenSpec = this.Spec.GetLiteralByName(t.val); if (oTokenSpec == null) { this.SemErr(t.val); return; } StateScannerState oNextState = null; foreach (var oStartState in startStates) { if (oStartState.Entries.TryGetValue(oTokenSpec, out oNextState)) break; } if (oNextState == null) { string sStateName = "<" + (this.Spec.States.Count - 2).ToString() + ">"; oNextState = new StateScannerState(sStateName); this.Spec.States.Add(oNextState); } foreach (var oStartState in startStates) if (!oStartState.Entries.ContainsKey(oTokenSpec)) { oStartState.AddLink(oTokenSpec, oNextState); oStartState.SetDefaultLink(this.Spec.FailState); } newStates = new List<StateScannerState> { oNextState }; } else if (la.kind == 3) { Get(); Expression(out newStates, startStates, endStates); Expect(4); } else if (la.kind == 5) { Get(); Expression(out newStates, startStates, endStates); Expect(6); if (newStates != null) newStates.AddRange(startStates); } else if (la.kind == 7) { Get(); Expression(out newStates, startStates, endStates); Expect(8); if (newStates != null && startStates != null) { ///startStates в данном случае - это элементы перед началом необязательная части, которая может повторяться многократно. ///Надо организовать цикл повторяющейся части, а для этого нам нужен переход на ее начало. ///Значит для всех конечных состояний (newStates) мы делаем переходы по таким же условиям, что и для startStates. foreach (var oStartState in startStates) foreach (var oEntry in oStartState.Entries) foreach (var oNewState in newStates) if (!oNewState.Entries.ContainsKey(oEntry.Key)) oNewState.AddLink(oEntry.Key, oEntry.Value); ///Поскольку мы имеем дело с необязательно конструкцией, которая может быть, а может и не быть, ///то входные состояния дальше мы будем обрабатывать так же как и выходные. newStates.AddRange(startStates); } } else SynErr(10); }