Design Pattern Examples
Overview of object-oriented design patterns
_state_class_private.py
Go to the documentation of this file.
7
8from io import StringIO
9
10from .state_interface import CurrentState, IStateBehavior, IStateContext, SpecialCase
11
12
24def _CurrentStateToString(state : CurrentState) -> str:
25 stateAsString = ""
26
27 match state:
28 case CurrentState.Initial:
29 stateAsString = "Initial"
30
31 case CurrentState.NormalText:
32 stateAsString = "NormalText"
33
34 case CurrentState.DoubleQuotedText:
35 stateAsString = "DoubleQuotedText"
36
37 case CurrentState.SingleQuotedText:
38 stateAsString = "SingleQuotedText"
39
40 case CurrentState.EscapedDoubleQuoteText:
41 stateAsString = "EscapedDoubleQuoteText"
42
43 case CurrentState.EscapedSingleQuoteText:
44 stateAsString = "EscapedSingleQuoteText"
45
46 case CurrentState.StartComment:
47 stateAsString = "StartComment"
48
49 case CurrentState.LineComment:
50 stateAsString = "LineComment"
51
52 case CurrentState.BlockComment:
53 stateAsString = "BlockComment"
54
55 case CurrentState.EndBlockComment:
56 stateAsString = "EndBlockComment"
57
58 case CurrentState.Done:
59 stateAsString = "Done"
60
61 case _:
62 stateAsString = "Unknown ({0})".format(state)
63
64 return stateAsString
65
66
67#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
69# State class definitions
70#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
71#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
72
73
81
82
96 def GoNext(self, context : IStateContext) -> CurrentState:
97 nextState = CurrentState.NormalText
98 character = context.GetNextCharacter()
99
100 match character:
101 case SpecialCase.EOF_CHAR:
102 nextState = CurrentState.Done
103
104 case '"':
105 context.OutputCharacter(character)
106 nextState = CurrentState.DoubleQuotedText
107
108 case '\'':
109 context.OutputCharacter(character)
110 nextState = CurrentState.SingleQuotedText
111
112 case '/':
113 nextState = CurrentState.StartComment
114
115 case _:
116 context.OutputCharacter(character)
117
118 return nextState
119
120
121
123
124
125
133
134
148 def GoNext(self, context : IStateContext) -> CurrentState:
149 nextState = CurrentState.DoubleQuotedText
150
151 character = context.GetNextCharacter()
152
153 match character:
154 case SpecialCase.EOF_CHAR:
155 nextState = CurrentState.Done
156
157 case '"':
158 context.OutputCharacter(character)
159 nextState = CurrentState.NormalText
160
161 case '\\':
162 context.OutputCharacter(character)
163 nextState = CurrentState.EscapedDoubleQuoteText
164
165 case _:
166 context.OutputCharacter(character)
167
168 return nextState
169
170
171
173
174
175
183
184
198 def GoNext(self, context : IStateContext) -> CurrentState:
199 nextState = CurrentState.SingleQuotedText
200
201 character = context.GetNextCharacter()
202
203 match character:
204 case SpecialCase.EOF_CHAR:
205 nextState = CurrentState.Done
206
207 case '\'':
208 context.OutputCharacter(character)
209 nextState = CurrentState.NormalText
210
211 case '\\':
212 context.OutputCharacter(character)
213 nextState = CurrentState.EscapedSingleQuoteText
214
215 case _:
216 context.OutputCharacter(character)
217
218 return nextState
219
220
221
223
224
225
234
235
249 def GoNext(self, context : IStateContext) -> CurrentState:
250 nextState = CurrentState.DoubleQuotedText
251
252 character = context.GetNextCharacter()
253
254 match character:
255 case SpecialCase.EOF_CHAR:
256 nextState = CurrentState.Done
257
258 case _:
259 context.OutputCharacter(character)
260
261 return nextState
262
263
264
266
267
268
277
278
292 def GoNext(self, context : IStateContext) -> CurrentState:
293 nextState = CurrentState.SingleQuotedText
294
295 character = context.GetNextCharacter()
296
297 match character:
298 case SpecialCase.EOF_CHAR:
299 nextState = CurrentState.Done
300
301 case _:
302 context.OutputCharacter(character)
303
304 return nextState
305
306
307
309
310
311
319
320
334 def GoNext(self, context : IStateContext) -> CurrentState:
335 nextState = CurrentState.StartComment
336
337 character = context.GetNextCharacter()
338
339 match character:
340 case SpecialCase.EOF_CHAR:
341 nextState = CurrentState.Done
342
343 case '/':
344 nextState = CurrentState.LineComment
345
346 case '*':
347 nextState = CurrentState.BlockComment
348
349 case _:
350 # Is not the start of a comment so output the leading slash
351 # that led to the state followed by the character we just
352 # processed.
353 context.OutputCharacter('/')
354 context.OutputCharacter(character)
355 nextState = CurrentState.NormalText
356
357 return nextState
358
359
360
362
363
364
370
371
385 def GoNext(self, context : IStateContext) -> CurrentState:
386 nextState = CurrentState.LineComment
387
388 character = context.GetNextCharacter()
389
390 match character:
391 case SpecialCase.EOF_CHAR:
392 nextState = CurrentState.Done
393
394 case '\n':
395 context.OutputCharacter(character)
396 nextState = CurrentState.NormalText
397
398 case _:
399 # We are in a comment to be removed, so do nothing here.
400 pass
401
402 return nextState
403
404
405
407
408
409
415
416
430 def GoNext(self, context : IStateContext) -> CurrentState:
431 nextState = CurrentState.BlockComment
432
433 character = context.GetNextCharacter()
434
435 match character:
436 case SpecialCase.EOF_CHAR:
437 nextState = CurrentState.Done
438
439 case '*':
440 nextState = CurrentState.EndBlockComment
441
442 case _:
443 # We are in a comment to be removed, so do nothing here.
444 pass
445
446 return nextState
447
448
449
451
452
453
460
461
475 def GoNext(self, context : IStateContext) -> CurrentState:
476 nextState = CurrentState.BlockComment
477
478 character = context.GetNextCharacter()
479
480 match character:
481 case SpecialCase.EOF_CHAR:
482 nextState = CurrentState.Done
483
484 case '/':
485 nextState = CurrentState.NormalText
486
487 case _:
488 # We are still in a block comment to be removed, so do nothing here.
489 pass
490
491 return nextState
492
493
494
496
497
498
503
504
512 def GoNext(self, context : IStateContext) -> CurrentState:
513 # Do nothing (Yes! Another Null Object example!)
514 return CurrentState.Done
515
516
517#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
518#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
519# State class factory definition
520#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
521#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
522
523
524
526
527
538 def CreateState(state : CurrentState) -> IStateBehavior:
539 stateBehavior = None # type: IStateBehavior
540 match state:
541 case CurrentState.NormalText:
542 stateBehavior = State_NormalText()
543
544 case CurrentState.DoubleQuotedText:
545 stateBehavior = State_DoubleQuotedText()
546
547 case CurrentState.SingleQuotedText:
548 stateBehavior = State_SingleQuotedText()
549
550 case CurrentState.EscapedDoubleQuoteText:
551 stateBehavior = State_EscapedDoubleQuoteText()
552
553 case CurrentState.EscapedSingleQuoteText:
554 stateBehavior = State_EscapedSingleQuoteText()
555
556 case CurrentState.StartComment:
557 stateBehavior = State_StartComment()
558
559 case CurrentState.LineComment:
560 stateBehavior = State_LineComment()
561
562 case CurrentState.BlockComment:
563 stateBehavior = State_BlockComment()
564
565 case CurrentState.EndBlockComment:
566 stateBehavior = State_EndBlockComment()
567
568 case CurrentState.Done:
569 stateBehavior = State_Done()
570
571 case _:
572 msg = "Unknown state: {0}. Cannot create a state class.".format(
574 raise ValueError(msg)
575
576 return stateBehavior
577
578
579#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
580#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
581# State Context implementation class definition
582#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
583#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
584
585
586
594
595 #--------------------------------------------------------------------
596 # StateContext_Class implementation.
597 #--------------------------------------------------------------------
598
599
607 def _SetNextState(self, newState : CurrentState) -> None:
608 if newState != self._currentState:
609 if newState not in self._stateBehaviors:
610 self._stateBehaviors[newState] = State_Factory.CreateState(newState)
611
612 print(" --> State Transition: {0} -> {1}".format(
614 _CurrentStateToString(newState)))
615
617 self._currentState = newState
618
619
620
621 def __init__(self) -> None:
622 self._inputText = ""
623 self._textIndex = 0
624 self._outputText = StringIO()
625 self._stateBehaviors = {} # type: dict[CurrentState, IStateBehavior]
626 self._currentState = CurrentState.Initial
627 self._currentStateBehavior = None # type: IStateBehavior
628
629
649
650
651 #--------------------------------------------------------------------
652 # StateContext_Class public entry points.
653 #--------------------------------------------------------------------
654
655
662 def RemoveComments(self, text : str) -> str:
663 self._inputText = text
664 self._textIndex = 0;
665 self._outputText.close()
666 self._outputText = StringIO()
667 self._currentState = CurrentState.Initial
668 self._SetNextState(CurrentState.NormalText)
669
670 while (self._currentState != CurrentState.Done):
671 nextState = self._currentStateBehavior.GoNext(self)
672 self._SetNextState(nextState)
673
674 return self._outputText.getvalue()
675
676
677 #--------------------------------------------------------------------
678 # IStateContext interface implementation.
679 #--------------------------------------------------------------------
680
681
686 def GetNextCharacter(self) -> int:
687 character = SpecialCase.EOF_CHAR
688
689 if self._textIndex < len(self._inputText):
690 character = self._inputText[self._textIndex]
691 self._textIndex += 1
692 return character
693
694
698 def OutputCharacter(self, character : int) -> None:
699 if character != SpecialCase.EOF_CHAR:
700 self._outputText.write(character)
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Represents being inside a double-quote string where filtering is essentially turned off until the end...
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Represents being in an escaped character sequence inside a double- quoted string.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Represents being in an escaped character sequence inside a single- quoted string.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Class factory for generating the state class instances.
IStateBehavior CreateState(CurrentState state)
Create an instance of the specified state class.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Represents being inside a single-quoted string where filtering is effectively turned off until the en...
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
Represents the possible start of a line or block comment.
CurrentState GoNext(self, IStateContext context)
Process the next character from the context, returning the next state the context should move to.
None _SetNextState(self, CurrentState newState)
Helper method to transition the state machine to the specified state.
_currentState
A value from the CurrentState enumeration indicating the current state of the machine.
_stateBehaviors
Maps values from the CurrentState enumeration to instances of the IStateBehavior representing the beh...
_currentStateBehavior
The current behavior (that is, a reference to the IStateBehavior instance) for the current state.
str RemoveComments(self, str text)
Entry point for callers to filter text.
None OutputCharacter(self, int character)
Save the character to the accumulation of the filtered text.
Represents a class that implements one state of the state machine.
Represents the context as passed to each state class.
str _CurrentStateToString(CurrentState state)
Convert the CurrentState enumeration to a string for output purposes.