/// <summary> /// The initial partitions are formed by the following /// rules: /// Every accept state shares a partition with all other /// accept states that have the same semantic action. /// All other states go in the partition "otherStates". /// /// Addendum, Version 0.3: start states must be kept out /// of the otherStates partition, otherwise prefixes can /// be chopped off by, for example, concluding that states /// {1,3} are equivalent in the following FSA. They are, /// but the computation of yytext is broken if you merge! /// /// a b c d /// (start state) 1---->2---->3---->4-----(5) (accept state) /// /// c d /// (start state) 1---->7---->(5) (accept state) /// /// The inverse transition function is computed at the same /// time as the initial partition is performed. /// </summary> /// <param name="list">The list of all DStates</param> internal void PopulatePartitions(List <DFSA.DState> list) { PartitionBlock blk = null; dfsa.origLength = list.Count; for (int i = 1; i < list.Count; i++) { DFSA.DState dSt = list[i]; if (dSt.accept != null) { blk = FindPartition(dSt); } else if (dSt.isStart) { blk = startStates; } else { blk = otherStates; } blk.AddState(dSt); dSt.block = blk; // now create the inverse transition function for (int j = 0; j < dfsa.MaxSym; j++) { DFSA.DState pred = dSt.GetNext(j); if (pred != null) { pred.AddPredecessor(dSt, j); } } } // Now add the eofState as an accept state. // This is *despite* the state not having an accept reference! blk = MkNewBlock(); acceptStates.Add(blk); blk.AddState(list[0]); list[0].block = blk; // And now finally initialize the pair list. worklist.Push(startStates); worklist.Push(otherStates); // EXPERIMENTAL foreach (PartitionBlock lst in acceptStates) { worklist.Push(lst); } }