FSM c++多種實現方法
阿新 • • 發佈:2021-12-13
bcode parser不使用switch實現
B編碼中有四種類型:string,integer,dictionary,list。示例分別如下:
integer: i43e 表示數字32。
string: 5:world 前面數字表示字元長度為5,字串為world。
dictionary: d9:publisher3:bobe表示key:publisher,value:bob。
list:l4:worlde 表示列表成員world。
實現1:
這種主要也是利用函式指標來儲存一個processor,每個processor對應一個狀態。處理完對應的區塊資訊就返回下一種處理方法。對於巢狀型別,可以使用遞迴來做。
class BecodeParser{ public: void start(const std::string& str) { std::string::const_iterator itr = str.cbegin(); shiftState(itr); while( itr != str.cend() ) { processor(itr); } } void processDictionary(std::string::const_iterator& itr) { // process shiftState(++itr); } void processList(std::string::const_iterator& itr) { // process shiftState(++itr); } void processInterger(std::string::const_iterator& itr) { // process shiftState(++itr); } void processString(std::string::const_iterator& itr) { // process shiftState(++itr); } void shiftState(std::string::const_iterator& itr){ if( *itr == 'l') processor = processList; if( *itr == 'i') processor = processInterger; if( isNumber(itr) ) processor = processString; } void(*processor)(std::string::const_iterator& itr); };
實現2:
利用和型別來實現,在TypeScript中有和型別,但是c++中則沒有。但是cpp可以用基類指標來模擬和型別。具體實現見程式碼。
class AbsBecodeType{ public: virtual AbsBecodeType* Parser(std::string::const_iterator& itr); }; class ListParser: public AbsBecodeType{ public: virtual AbsBecodeType* Parser(std::string::const_iterator& itr); }; class DictionaryParser: public AbsBecodeType{ public: virtual AbsBecodeType* Parser(std::string::const_iterator& itr); }; class IntergerParser: public AbsBecodeType{ public: virtual AbsBecodeType* Parser(std::string::const_iterator& itr) { // processe if( *itr == l) return std::make_shared<ListParser>(); } }; void processBcodeStr(const std::string& str) { std::shared_ptr<AbsBecodeType> processor = std::make_shared<IntergerParser>(); std::string::const_iterator itr = str.cbegin(); while( itr != str.cend() ) { processor.reset(processor->Parser(itr)); } }