Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
8.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: State.cxx
  7. //
  8. // Contents: Finite automata state classes
  9. //
  10. // Classes:
  11. //
  12. // History: 01-21-92 KyleP Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <state.hxx>
  18. #include "stateset.hxx"
  19. //+-------------------------------------------------------------------------
  20. //
  21. // Member: CNFAState::CNFAState, public
  22. //
  23. // Synopsis: Copy constructor
  24. //
  25. // Arguments: [src] -- Source
  26. //
  27. // History: 13-Jul-95 KyleP Created
  28. //
  29. //--------------------------------------------------------------------------
  30. CNFAState::CNFAState( CNFAState const & src )
  31. : CFAState( src ),
  32. _pmoveRest( 0 ),
  33. _cmoveRest( src._cmoveRest ),
  34. _cMove( src._cMove )
  35. {
  36. if ( _cmoveRest > 0 )
  37. {
  38. _pmoveRest = new CMove [_cmoveRest];
  39. RtlCopyMemory( _pmoveRest, src._pmoveRest, _cmoveRest * sizeof(_pmoveRest[0]) );
  40. }
  41. RtlCopyMemory( _moveFirst, src._moveFirst, sizeof(_moveFirst) );
  42. }
  43. //+-------------------------------------------------------------------------
  44. //
  45. // Member: CNFAState::Init, public
  46. //
  47. // Synopsis: Copy initializer
  48. //
  49. // Arguments: [src] -- Source
  50. //
  51. // History: 15-Jul-96 KyleP Created
  52. //
  53. //--------------------------------------------------------------------------
  54. void CNFAState::Init( CNFAState & src )
  55. {
  56. CFAState::Init( src.StateNumber() );
  57. if ( src.IsFinal() )
  58. MakeFinal();
  59. _cMove = src._cMove;
  60. RtlCopyMemory( _moveFirst, src._moveFirst, sizeof(_moveFirst) );
  61. _cmoveRest = src._cmoveRest;
  62. _pmoveRest = src._pmoveRest;
  63. src._cMove = 0;
  64. src._cmoveRest = 0;
  65. src._pmoveRest = 0;
  66. }
  67. //+-------------------------------------------------------------------------
  68. //
  69. // Member: CNFAState::operator =, public
  70. //
  71. // Synopsis: Assignment operator
  72. //
  73. // Arguments: [src] -- Source
  74. //
  75. // History: 13-Jul-95 KyleP Created
  76. //
  77. //--------------------------------------------------------------------------
  78. inline void * operator new( size_t, CNFAState * pthis )
  79. {
  80. return pthis;
  81. }
  82. #if _MSC_VER >= 1200
  83. inline void operator delete( void * p, CNFAState * pthis ) {}
  84. #endif
  85. CNFAState & CNFAState::operator =( CNFAState const & src )
  86. {
  87. CNFAState::~CNFAState();
  88. new (this) CNFAState( src );
  89. return *this;
  90. }
  91. //+-------------------------------------------------------------------------
  92. //
  93. // Member: CNFAState::AddTransition, public
  94. //
  95. // Synopsis: Add new state transition.
  96. //
  97. // Arguments: [symbol] -- On this symbol to...
  98. // [StateNum] -- this state.
  99. //
  100. // History: 20-Jan-92 KyleP Created
  101. //
  102. //--------------------------------------------------------------------------
  103. void CNFAState::AddTransition( UINT symbol, UINT StateNum )
  104. {
  105. //
  106. // First look for an exact match. If this transition exists
  107. // then don't add it again.
  108. //
  109. for ( int i = CNFAState_cFirst-1; i >= 0; i--)
  110. {
  111. if ( _moveFirst[i]._symbol == symbol &&
  112. _moveFirst[i]._iState == StateNum )
  113. {
  114. return;
  115. }
  116. }
  117. if ( _cMove > CNFAState_cFirst )
  118. {
  119. for ( int i = _cMove - CNFAState_cFirst - 1; i >= 0; i--)
  120. {
  121. if ( _pmoveRest[i]._symbol == symbol &&
  122. _pmoveRest[i]._iState == StateNum )
  123. {
  124. return;
  125. }
  126. }
  127. }
  128. //
  129. // New transition. Add it.
  130. //
  131. if ( _cMove < CNFAState_cFirst )
  132. {
  133. //
  134. // Fits in the first (object based) set of moves.
  135. //
  136. _moveFirst[_cMove] = CMove( symbol, StateNum );
  137. }
  138. else
  139. {
  140. //
  141. // Overflow set of moves.
  142. //
  143. if ( _cMove - CNFAState_cFirst >= _cmoveRest )
  144. {
  145. vqDebugOut(( DEB_ITRACE,
  146. "Growing NFA State transition array.\n" ));
  147. CMove * oldpmoveRest = _pmoveRest;
  148. UINT oldcmoveRest = _cmoveRest;
  149. _cmoveRest = (_cmoveRest == 0) ? 2 : _cmoveRest + 5;
  150. _pmoveRest = (CMove *) new char [ _cmoveRest * sizeof( CMove ) ];
  151. memcpy( _pmoveRest, oldpmoveRest, oldcmoveRest * sizeof( CMove ) );
  152. delete oldpmoveRest;
  153. }
  154. _pmoveRest[_cMove - CNFAState_cFirst] = CMove( symbol, StateNum );
  155. }
  156. ++_cMove;
  157. }
  158. //+-------------------------------------------------------------------------
  159. //
  160. // Member: CNFAState::RemoveTransition, public
  161. //
  162. // Synopsis: Removes a transition.
  163. //
  164. // Arguments: [symbol] -- On this symbol to...
  165. // [StateNum] -- this state.
  166. //
  167. // History: 20-Jan-92 KyleP Created
  168. //
  169. //--------------------------------------------------------------------------
  170. void CNFAState::RemoveTransition( UINT symbol, UINT StateNum )
  171. {
  172. //
  173. // Find the transition
  174. //
  175. for ( int i = CNFAState_cFirst-1; i >= 0; i--)
  176. {
  177. if ( _moveFirst[i]._symbol == symbol &&
  178. _moveFirst[i]._iState == StateNum )
  179. {
  180. //
  181. // Move the last transition to this place.
  182. //
  183. if ( _cMove > CNFAState_cFirst )
  184. {
  185. _moveFirst[i] = _pmoveRest[_cMove - CNFAState_cFirst - 1];
  186. }
  187. else
  188. {
  189. _moveFirst[i] = _moveFirst[ _cMove - 1 ];
  190. }
  191. _cMove--;
  192. return;
  193. }
  194. }
  195. if ( _cMove > CNFAState_cFirst )
  196. {
  197. for ( int i = _cMove - CNFAState_cFirst - 1; i >= 0; i--)
  198. {
  199. if ( _pmoveRest[i]._symbol == symbol &&
  200. _pmoveRest[i]._iState == StateNum )
  201. {
  202. _pmoveRest[i] = _pmoveRest[ _cMove - CNFAState_cFirst - 1 ];
  203. _cMove--;
  204. return;
  205. }
  206. }
  207. }
  208. }
  209. //+-------------------------------------------------------------------------
  210. //
  211. // Member: CNFAState::Move, public
  212. //
  213. // Effects: Adds to [ss] the set of states that can be reached from
  214. // this state on [symbol].
  215. //
  216. // Arguments: [ss] -- Output state set.
  217. // [symbol] -- Input symbol.
  218. //
  219. // History: 20-Jan-92 KyleP Created
  220. //
  221. //--------------------------------------------------------------------------
  222. void CNFAState::Move( CStateSet & ss, UINT symbol )
  223. {
  224. for ( int i = (_cMove <= CNFAState_cFirst) ? _cMove-1 : CNFAState_cFirst-1;
  225. i >= 0;
  226. i--)
  227. {
  228. if ( _moveFirst[i]._symbol == symbol ||
  229. ( _moveFirst[i]._symbol == symAny &&
  230. symbol != symEpsilon ))
  231. {
  232. ss.Add( _moveFirst[i]._iState );
  233. }
  234. }
  235. for ( i = _cMove - CNFAState_cFirst - 1; i >= 0; i-- )
  236. {
  237. if ( _pmoveRest[i]._symbol == symbol ||
  238. ( _pmoveRest[i]._symbol == symAny &&
  239. symbol != symEpsilon &&
  240. symbol != symDot ))
  241. {
  242. ss.Add( _pmoveRest[i]._iState );
  243. }
  244. }
  245. }
  246. //
  247. // Debug methods
  248. //
  249. #if (CIDBG == 1)
  250. void CFAState::Display()
  251. {
  252. vqDebugOut(( DEB_REGEX,
  253. "State: %u, Final = %c", _iState, _fFinal ? 'T' : 'F' ));
  254. }
  255. void CNFAState::Display()
  256. {
  257. CFAState::Display();
  258. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME, " -- %u transitions\n", _cMove ));
  259. for ( int i = (_cMove <= CNFAState_cFirst) ? _cMove-1 : CNFAState_cFirst-1;
  260. i >= 0;
  261. i--)
  262. {
  263. if ( _moveFirst[i]._symbol == symEpsilon)
  264. {
  265. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME, "\tEpsilon " ));
  266. }
  267. else if ( _moveFirst[i]._symbol == symAny )
  268. {
  269. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME, "\tAny " ));
  270. }
  271. else
  272. {
  273. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME,
  274. "\t%u ", _moveFirst[i]._symbol ));
  275. }
  276. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME,
  277. "--> %u\n", _moveFirst[i]._iState ));
  278. }
  279. for ( i = _cMove - CNFAState_cFirst - 1; i >= 0; i-- )
  280. {
  281. if ( _pmoveRest[i]._symbol == symEpsilon)
  282. {
  283. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME, "\tEpsilon " ));
  284. }
  285. else if ( _pmoveRest[i]._symbol == symAny )
  286. {
  287. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME, "\tAny " ));
  288. }
  289. else
  290. {
  291. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME,
  292. "\t%u ", _pmoveRest[i]._symbol ));
  293. }
  294. vqDebugOut(( DEB_REGEX | DEB_NOCOMPNAME,
  295. "--> %u\n", _pmoveRest[i]._iState ));
  296. }
  297. }
  298. #endif // (CIDBG == 1)