提升精神解析c和cpp风格的评论

时间:2013-10-03 15:55:10

标签: c++ boost boost-spirit boost-spirit-qi

我正在研究评论有意义的解析器。在你说之前...原因是如果语句A在目标语句的源中有注释,则A的描述应该用A的注释进行评论。或者注释传播。无论如何,为此我必须解析并收集评论,而不仅仅是跳过它们。

这是我到目前为止所做的:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/home/support/iterators/line_pos_iterator.hpp>
#include <boost/spirit/repository/include/qi_confix.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>

using namespace boost::spirit;

#include <boost/fusion/include/adapt_struct.hpp>

////////////////////////////////
// extra facilities
struct get_line_f
{
    template <typename> struct result { typedef size_t type; };
    template <typename It> size_t operator()(It const& pos_iter) const
    {
        return get_line(pos_iter);
    }
};

struct Position
{
    Position()
        : beginLine(-1)
        , endLine(-1)
    {
    }

    size_t beginLine;
    size_t endLine;
};

struct Comment : public Position
{
    Comment()
        : Position()
        , text()
    {
    }

    std::vector<std::string> text;
    std::string source;
};

BOOST_FUSION_ADAPT_STRUCT(Comment,
                            (std::vector<std::string>, text)
                            (std::string, source)
                            (size_t,      beginLine)
                            (size_t,      endLine)
                          )

//
////////////////////////////////

template <typename Iterator>
struct comment : qi::grammar<Iterator, Comment(), qi::space_type>
{
    comment() : comment::base_type(start)
    {
        c_comment %= repository::confix("/*", "*/")[*(char_ - "*/")];

        cpp_comment %= repository::confix("//", eol | eoi)[*(char_ - eol)];

        comments %= *(c_comment | cpp_comment);

        start = raw[ comments[at_c<0>(_val) = _1] ]
                   [
                       at_c<1>(_val) = construct<std::string>(begin(_1), end(_1)),
                       at_c<2>(_val) = get_line_(begin(_1)),
                       at_c<3>(_val) = get_line_(end(_1))
                   ]
        ;
    }

    boost::phoenix::function<get_line_f> get_line_;
    qi::rule<Iterator, Comment(), qi::space_type> start;
    qi::rule<Iterator, std::string()> c_comment;
    qi::rule<Iterator, std::string()> cpp_comment;
    qi::rule<Iterator, std::vector<std::string>()> comments;

};

这是测试代码:

int main()
{
    std::string str[] =
    {
        "/*1234*/",
        "\n\n/*1234*/",
        "// foo bar\n",
        "// foo bar",
        "\n\n    // foo bar\n",
        "/*1234\n5678*/",

    };

    typedef line_pos_iterator<std::string::const_iterator> Iterator;

    for (size_t i = 0; i < sizeof(str) / sizeof(str[0]); ++i)
    {
        comment<Iterator> g;
        Iterator iter(str[i].begin());
        Iterator end(str[i].end());

        Comment comment;
        bool r = phrase_parse(iter, end, g, qi::space, comment);
        if (r && iter == end)
            std::cout << comment.beginLine << comment.source << "\n";
        else
            std::cout << "Parsing failed\n";
    }

}

编辑: 这段代码现在正在编译和工作......感谢您的帮助。

0 个答案:

没有答案