1. 程式人生 > 其它 >FSM c++多種實現方法

FSM c++多種實現方法

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));
    }
}