• 状态机学习(四)解析四则运算式 词法分析


    #include <string>
    #include <iostream>
    using namespace std;

    char* testStr = "12+345-6*8/9";

    typedef enum {
    BAD_TOKEN,
    NUMBER_TOKEN,
    ADD_OPERATOR_TOKEN,
    SUB_OPERATOR_TOKEN,
    MUL_OPERATOR_TOKEN,
    DIV_OPERATOR_TOKEN,
    END_OF_LINE_TOKEN
    } TokenKind;

    typedef struct {
    TokenKind kind;
    unsigned value;
    string s;
    } Token;

    typedef enum {
    INITIAL_STATUS,
    IN_INT_PART_STATUS
    } LexerStatus;
    //==========================================

    static size_t gParseIndex = 0;

    bool GetToken(Token& token,const string& strContent) {
    LexerStatus status = INITIAL_STATUS;
    token.kind = BAD_TOKEN;
    char currentChar = '\0';
    size_t numBegIndex = 0;
    size_t numEndIndex = 0;
    while (gParseIndex < strContent.size())
    {
    //数字状态跳出
    if(status == IN_INT_PART_STATUS &&
    !isdigit(strContent[gParseIndex]) ) {
    numEndIndex = gParseIndex;
    token.kind = NUMBER_TOKEN;
    token.s = strContent.substr(numBegIndex, numEndIndex- numBegIndex);
    return true;
    }
    // 空格略过 换行结束函数
    if (isspace(strContent[gParseIndex])) {
    if (strContent[gParseIndex] == '\r' ||
    strContent[gParseIndex] == '\n') {
    token.kind = END_OF_LINE_TOKEN;
    return true;
    }
    else {
    gParseIndex++;
    continue;
    }
    }

    if (isdigit(strContent[gParseIndex])) {
    if (status != IN_INT_PART_STATUS) {
    status = IN_INT_PART_STATUS;
    numBegIndex = gParseIndex;
    }
    gParseIndex++;
    continue;
    }

    if (strContent[gParseIndex] == '+') {
    token.kind = ADD_OPERATOR_TOKEN;
    token.s = strContent[gParseIndex];
    gParseIndex++;
    return true;
    }
    else if (strContent[gParseIndex] == '-') {
    token.kind = SUB_OPERATOR_TOKEN;
    token.s = strContent[gParseIndex];
    gParseIndex++;
    return true;
    }
    else if (strContent[gParseIndex] == '*') {
    token.kind = MUL_OPERATOR_TOKEN;
    token.s = strContent[gParseIndex];
    gParseIndex++;
    return true;
    }
    else if (strContent[gParseIndex] == '/') {
    token.kind = DIV_OPERATOR_TOKEN;
    token.s = strContent[gParseIndex];
    gParseIndex++;
    return true;
    }

    cerr << "Parse Error " << endl;
    token.kind = BAD_TOKEN;
    return false;
    }
    // 最后结尾 检查是否数字字符串状态需要跳出
    if (status == IN_INT_PART_STATUS &&
    gParseIndex == strContent.size()) {
    numEndIndex = gParseIndex;
    token.kind = NUMBER_TOKEN;
    token.s = strContent.substr(numBegIndex, numEndIndex - numBegIndex);
    return true;
    }

    token.kind = END_OF_LINE_TOKEN;
    return true;
    }

    #define TEST_MACRO
    #ifdef TEST_MACRO


    void ParseLinetest(string s) {
    Token token;
    gParseIndex = 0;
    while (1) {
    if (GetToken(token, s)) {
    if (token.kind == END_OF_LINE_TOKEN) {
    break;
    }
    else {
    cout << "kind = " << token.kind
    << ", str = " << token.s << endl;
    }
    }

    }
    }


    int main()
    {
    ParseLinetest(testStr);
    return 0;
    }

  • 相关阅读:
    ASP.NET2.0中用Gridview控件操作数据
    有关petShop的几篇文章
    用多活动结果集优化ADO.NET2.0数据连接
    设计数据层组件并在层间传递数据
    google的语法?
    PHP导出Excel方法
    header ContentType类型
    40条优化php代码的小实例
    strstr 不错的技巧
    PHP 截取字符串专题
  • 原文地址:https://www.cnblogs.com/itdef/p/6159808.html
Copyright © 2020-2023  润新知