Question

I have built a parser using a FSM/Pushdown Automaton approach like here (and it works, well!): C++ FSM design and ownership It allows me to exit gracefully and output a helpful error message to the user when something goes wrong at the parser stage.

I have been wondering about a good way to get that done in the rest of my program, and naturally, the parser approach popped in my mind...

I would make every object a state, which has a single event() function that has a switch statement calling object specific functions depending on the stage of execution I am. I can keep track of that with object-specific enum's, and keep the code more readable (case parser is more readable than case 5). This will allow me to close off the pushdown tree of states I have created (using the m_parent* approach in my other question).

Is this good design (forcing everything in a FSM-mode)? Is there a better way, and how much more complicated will it be (I find the FSM pretty easy to implement and test)?

Thanks for the suggestions!

PS: I know boost has about everything one may ever need, but I want to limit external dependencies, especially on boost. c++0x is ok though (but not really relevant here I think)

Was it helpful?

Solution

What you are doing is a bit like building a (simple) virtual machine in your programme. An FSM tends to be a good fit for some restricted problems such as lexing and parsing, and as you've probably noted, you can get quite a bit of logging and error management 'for free'.

However, if you try to apply the FSM pattern to everything (which is going to be tough for e.g. GUI programmes which contain quite a lot of state you normally wouldn't want to make into explicit states), you're going to realize that you also need facilities to debug your FSM (since the C++ debugger won't understand your states and events) and facilities to link and reuse states (since the states won't be OO level constructs). If you ever want to hand over your code to someone else, he or she is going to need additional training to use your FSM successfully. Are you going to want to keep one FSM engine for multiple applications? If so, how are you going to deal with versioning and upgrades?

Use the right tool for the right job. Every approach has its strengths and weaknesses. Your solution adds another layer of complexity: you can deal with logging and error handling in more C++-ish ways. If you're not happy with writing C++ code, you might consider other existing languages, rather than building an FSM language only you understand.

OTHER TIPS

Most people would use inheritance instead of switch/case/default. However, the idea of forcing everything to be one way is inherently wrong. You should always approach each required functionality on it's own merits.

You can always take a look at boost.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top