代码之家  ›  专栏  ›  技术社区  ›  Smit Ycyken

正在分析*。包含使用boost::regex的枚举的cpp文件。

  •  0
  • Smit Ycyken  · 技术社区  · 7 年前

    std::string sourceString = readFromFile(typesHDestination);
    boost::smatch xResults;
    std::string::const_iterator Start = sourceString.cbegin();
    std::string::const_iterator End = sourceString.cend();
    
    while (boost::regex_search(Start, End, xResults, boost::regex("(?<data_type>enum|enum\\s+class)\\s+(?<enum_name>\\w+)\\s*\{(?<content>[^\}]+?)\\s*\}\\s*")))
    {
        std::cout << xResults["data_type"]
            << " " << xResults["enum_name"] << "\n{\n";
    
        std::string::const_iterator ContentStart = xResults["content"].begin();
        std::string::const_iterator ContentEnd = xResults["content"].end();
        boost::smatch xResultsInner;
    
        while (boost::regex_search(ContentStart, ContentEnd, xResultsInner, boost::regex("(?<name>\\w+)(?:(?:\\s*=\\s*(?<value>[^\,\\s]+)(?:(?:,)|(?:\\s*)))|(?:(?:\\s*)|(?:,)))")))
        {
            std::cout << xResultsInner["name"] << ": " << xResultsInner["value"] << std::endl;
    
            ContentStart = xResultsInner[0].second;
        }
    
        Start = xResults[0].second;
        std::cout << "}\n";
    }
    

    如果枚举没有注释,则可以。 Output

    我试图添加命名组 <comment> (\/{2}\s*.+) -带有双斜杠的注释示例。

    我用这个测试过 online regex 使用boost::regex。

    1. 第一步-从*。cpp文件到 <data_type> <enum_name> <content>

    (?'data\u type'enum | enum\s+class)\s+(?'enum\u name'\w+\s*{\s*(?'content'[^}]]+?)\s*}\s*

    1. 从…起 <content> <name> <value> <comment>

    (?'name'\w+((?:\s*=\s*(?'value'[^\,\s/]+)(?:(?:,)|(?:\s*))|(?:(?:\s*)|(?:(?:\s*))|(?:,))

    最后一个包含错误。有没有办法修复它并添加功能以在组中存储元素?

    2 回复  |  直到 7 年前
        1
  •  0
  •   Shakiba Moshiri    7 年前

    正如一些评论所说,用 正则表达式 除了一些简单的案例

    例如,此源文件来自: http://en.cppreference.com/w/cpp/language/enum

    #include <iostream>
    
    // enum that takes 16 bits
    enum smallenum: int16_t
    {
        a,
        b,
        c
    };
    
    
    // color may be red (value 0), yellow (value 1), green (value 20), or blue (value 21)
    enum color
    {
        red,
        yellow,
        green = 20,
        blue
    };
    
    // altitude may be altitude::high or altitude::low
    enum class altitude: char
    { 
         high='h',
         low='l', // C++11 allows the extra comma
    }; 
    
    // the constant d is 0, the constant e is 1, the constant f is 3
    enum
    {
        d,
        e,
        f = e + 2
    };
    
    //enumeration types (both scoped and unscoped) can have overloaded operators
    std::ostream& operator<<(std::ostream& os, color c)
    {
        switch(c)
        {
            case red   : os << "red";    break;
            case yellow: os << "yellow"; break;
            case green : os << "green";  break;
            case blue  : os << "blue";   break;
            default    : os.setstate(std::ios_base::failbit);
        }
        return os;
    }
    
    std::ostream& operator<<(std::ostream& os, altitude al)
    {
        return os << static_cast<char>(al);
    }
    
    int main()
    {
        color col = red;
        altitude a;
        a = altitude::low;
    
        std::cout << "col = " << col << '\n'
                  << "a = "   << a   << '\n'
                  << "f = "   << f   << '\n';
    } 
    

    这个 按键图案 以下是:从 enum ; 枚举 ; 会有这么多的可能性!为此,你可以使用 .*? 懒惰的明星

    因此,如果我想提取所有 enums

    注意:这不是有效的方法

    boost::regex rx( "^\\s*(enum.*?;)" );
    
    boost::match_results< std::string::const_iterator > mr; // or boost::smatch
    
    
    std::ifstream ifs( "file.cpp" );
    const uintmax_t file_size = ifs.seekg( 0, std::ios_base::end ).tellg();
                                ifs.seekg( 0, std::ios_base::beg );   // rewind
    
    std::string whole_file( file_size, ' ' );
    ifs.read( &*whole_file.begin(), file_size );
    ifs.close();
    
    while( boost::regex_search( whole_file, mr, rx ) ){
        std::cout << mr.str( 1 ) << '\n';
        whole_file = mr.suffix().str();
    } 
    

    输出将是:

    enum smallenum: int16_t
    {
        a,
        b,
        c
    };
    enum color
    {
        red,
        yellow,
        green = 20,
        blue
    };
    enum class altitude: char
    {
         high='h',
         low='l', // C++11 allows the extra comma
    };
    enum
    {
        d,
        e,
        f = e + 2
    };
    

    当然,对于这样简单的事情,我更喜欢使用:

    perl -lne '$/=unlef;print $1 while/^\s*(enum.*?;)/smg' file.cpp  
    

    如果你想单独匹配每个部分,这个模式可以帮助你吗

    ^\s*(enum[^{]*)\s*({)\s*([^}]+)\s*(};)

    但是,除了一些简单的源文件之外,这不是一个好主意。自从 具有自由风格,并非所有代码编写者都遵循标准规则。例如,对于上面的模式,我假设 (};) } 附带

        2
  •  0
  •   Smit Ycyken    7 年前

    我认为使用正则表达式解析复杂数据并不是最好的解决方案。I'v省略了几个主要条件。首先,我解析了一些生成的源代码,其中包含EMUN和enum类。所以代码没有什么奇怪的地方,代码是规则的。所以我用正则表达式解析常规代码。

    (第一步相同,第二步固定)

    1. <data_type> <enum_name> <content> 正则表达式:

    (?'data\u type'enum | enum\s+class)\s+(?'enum\u name'\w+\s*{\s*(?'content'[^}]]+?)\s*}\s*

    1. 从…起 <content> <name> <value> <comment>

    ^\s*(?'name'\w+(:(?:\s*=\s*(?'value'[^,\n/]+)|(?:[^,\s/] ))(?:(?:\ s) $)|(?:\s*,\s*$)|(?:[^/] /{2} \s

    enter image description here