| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 | 2 |
| 3 """This module implements a Finite State Machine (FSM). In addition to state | 3 """This module implements a Finite State Machine (FSM). In addition to state |
| 4 this FSM also maintains a user defined "memory". So this FSM can be used as a | 4 this FSM also maintains a user defined "memory". So this FSM can be used as a |
| 5 Push-down Automata (PDA) since a PDA is a FSM + memory. | 5 Push-down Automata (PDA) since a PDA is a FSM + memory. |
| 6 | 6 |
| 7 The following describes how the FSM works, but you will probably also need to | 7 The following describes how the FSM works, but you will probably also need to |
| 8 see the example function to understand how the FSM is used in practice. | 8 see the example function to understand how the FSM is used in practice. |
| 9 | 9 |
| 10 You define an FSM by building tables of transitions. For a given input symbol | 10 You define an FSM by building tables of transitions. For a given input symbol |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 defined then the process() method will call the associated action function and | 57 defined then the process() method will call the associated action function and |
| 58 then set the current state to the next_state. This lets you define a default | 58 then set the current state to the next_state. This lets you define a default |
| 59 transition as a catch-all case. You can think of it as an exception handler. | 59 transition as a catch-all case. You can think of it as an exception handler. |
| 60 There can be only one default transition. | 60 There can be only one default transition. |
| 61 | 61 |
| 62 Finally, if none of the previous cases are defined for an input_symbol and | 62 Finally, if none of the previous cases are defined for an input_symbol and |
| 63 current_state then the FSM will raise an exception. This may be desirable, but | 63 current_state then the FSM will raise an exception. This may be desirable, but |
| 64 you can always prevent this just by defining a default transition. | 64 you can always prevent this just by defining a default transition. |
| 65 | 65 |
| 66 Noah Spurrier 20020822 | 66 Noah Spurrier 20020822 |
| 67 |
| 68 PEXPECT LICENSE |
| 69 |
| 70 This license is approved by the OSI and FSF as GPL-compatible. |
| 71 http://opensource.org/licenses/isc-license.txt |
| 72 |
| 73 Copyright (c) 2012, Noah Spurrier <noah@noah.org> |
| 74 PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY |
| 75 PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE |
| 76 COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. |
| 77 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 78 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 79 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 80 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 81 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 82 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 83 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 84 |
| 67 """ | 85 """ |
| 68 | 86 |
| 69 class ExceptionFSM(Exception): | 87 class ExceptionFSM(Exception): |
| 70 | 88 |
| 71 """This is the FSM Exception class.""" | 89 """This is the FSM Exception class.""" |
| 72 | 90 |
| 73 def __init__(self, value): | 91 def __init__(self, value): |
| 74 self.value = value | 92 self.value = value |
| 75 | 93 |
| 76 def __str__(self): | 94 def __str__(self): |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 be a string or any iterable object. """ | 248 be a string or any iterable object. """ |
| 231 | 249 |
| 232 for s in input_symbols: | 250 for s in input_symbols: |
| 233 self.process (s) | 251 self.process (s) |
| 234 | 252 |
| 235 ############################################################################## | 253 ############################################################################## |
| 236 # The following is an example that demonstrates the use of the FSM class to | 254 # The following is an example that demonstrates the use of the FSM class to |
| 237 # process an RPN expression. Run this module from the command line. You will | 255 # process an RPN expression. Run this module from the command line. You will |
| 238 # get a prompt > for input. Enter an RPN Expression. Numbers may be integers. | 256 # get a prompt > for input. Enter an RPN Expression. Numbers may be integers. |
| 239 # Operators are * / + - Use the = sign to evaluate and print the expression. | 257 # Operators are * / + - Use the = sign to evaluate and print the expression. |
| 240 # For example: | 258 # For example: |
| 241 # | 259 # |
| 242 # 167 3 2 2 * * * 1 - = | 260 # 167 3 2 2 * * * 1 - = |
| 243 # | 261 # |
| 244 # will print: | 262 # will print: |
| 245 # | 263 # |
| 246 # 2003 | 264 # 2003 |
| 247 ############################################################################## | 265 ############################################################################## |
| 248 | 266 |
| 249 import sys, os, traceback, optparse, time, string | 267 import sys, os, traceback, optparse, time, string |
| 250 | 268 |
| 251 # | 269 # |
| 252 # These define the actions. | 270 # These define the actions. |
| 253 # Note that "memory" is a list being used as a stack. | 271 # Note that "memory" is a list being used as a stack. |
| 254 # | 272 # |
| 255 | 273 |
| 256 def BeginBuildNumber (fsm): | 274 def BeginBuildNumber (fsm): |
| 257 fsm.memory.append (fsm.input_symbol) | 275 fsm.memory.append (fsm.input_symbol) |
| 258 | 276 |
| 259 def BuildNumber (fsm): | 277 def BuildNumber (fsm): |
| 260 s = fsm.memory.pop () | 278 s = fsm.memory.pop () |
| 261 s = s + fsm.input_symbol | 279 s = s + fsm.input_symbol |
| 262 fsm.memory.append (s) | 280 fsm.memory.append (s) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 print 'Numbers may be integers. Operators are * / + -' | 322 print 'Numbers may be integers. Operators are * / + -' |
| 305 print 'Use the = sign to evaluate and print the expression.' | 323 print 'Use the = sign to evaluate and print the expression.' |
| 306 print 'For example: ' | 324 print 'For example: ' |
| 307 print ' 167 3 2 2 * * * 1 - =' | 325 print ' 167 3 2 2 * * * 1 - =' |
| 308 inputstr = raw_input ('> ') | 326 inputstr = raw_input ('> ') |
| 309 f.process_list(inputstr) | 327 f.process_list(inputstr) |
| 310 | 328 |
| 311 if __name__ == '__main__': | 329 if __name__ == '__main__': |
| 312 try: | 330 try: |
| 313 start_time = time.time() | 331 start_time = time.time() |
| 314 parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(),
usage=globals()['__doc__'], version='$Id: FSM.py 490 2007-12-07 15:46:24Z noah
$') | 332 parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(),
usage=globals()['__doc__'], version='$Id: FSM.py 533 2012-10-20 02:19:33Z noah
$') |
| 315 parser.add_option ('-v', '--verbose', action='store_true', default=False
, help='verbose output') | 333 parser.add_option ('-v', '--verbose', action='store_true', default=False
, help='verbose output') |
| 316 (options, args) = parser.parse_args() | 334 (options, args) = parser.parse_args() |
| 317 if options.verbose: print time.asctime() | 335 if options.verbose: print time.asctime() |
| 318 main() | 336 main() |
| 319 if options.verbose: print time.asctime() | 337 if options.verbose: print time.asctime() |
| 320 if options.verbose: print 'TOTAL TIME IN MINUTES:', | 338 if options.verbose: print 'TOTAL TIME IN MINUTES:', |
| 321 if options.verbose: print (time.time() - start_time) / 60.0 | 339 if options.verbose: print (time.time() - start_time) / 60.0 |
| 322 sys.exit(0) | 340 sys.exit(0) |
| 323 except KeyboardInterrupt, e: # Ctrl-C | 341 except KeyboardInterrupt, e: # Ctrl-C |
| 324 raise e | 342 raise e |
| 325 except SystemExit, e: # sys.exit() | 343 except SystemExit, e: # sys.exit() |
| 326 raise e | 344 raise e |
| 327 except Exception, e: | 345 except Exception, e: |
| 328 print 'ERROR, UNEXPECTED EXCEPTION' | 346 print 'ERROR, UNEXPECTED EXCEPTION' |
| 329 print str(e) | 347 print str(e) |
| 330 traceback.print_exc() | 348 traceback.print_exc() |
| 331 os._exit(1) | 349 os._exit(1) |
| OLD | NEW |