右上➚

プログラミングに関するメモをのこしていきます

C++ の複雑な型を整形するプログラムを作りました

テンプレートをバリバリ使っている C++ プログラムのコンパイルエラーが,死ぬほど辛かったので作りました. 型を綺麗に出力するだけです. C++の型版 jq みたいなやつありそうだけど無いのかな?

agatan/tf

たとえば,

boost::spirit::x3::raw_directive<boost::spirit::x3::lexeme_directive<boost::spirit::x3::sequence<boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::alpha_tag>, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >, boost::spirit::x3::kleene<boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::alnum_tag>, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> > > > > >::parse<__gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<char> >, boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, const std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<char> > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag>, boost::spirit::x3::unused_type> >, std::__cxx11::basic_string<char>, char>

こんなエラーがよく有りますよね.

これを tf の標準入力に流しこむと,

boost::spirit::x3::raw_directive<
    boost::spirit::x3::lexeme_directive<
        boost::spirit::x3::sequence<
            boost::spirit::x3::alternative<
                boost::spirit::x3::char_class<
                    boost::spirit::char_encoding::standard,
                    boost::spirit::x3::alpha_tag
                >,
                boost::spirit::x3::literal_char<
                    boost::spirit::char_encoding::standard,
                    boost::spirit::x3::unused_type
                >
            >,
            boost::spirit::x3::kleene<
                boost::spirit::x3::alternative<
                    boost::spirit::x3::char_class<
                        boost::spirit::char_encoding::standard,
                        boost::spirit::x3::alnum_tag
                    >,
                    boost::spirit::x3::literal_char<
                        boost::spirit::char_encoding::standard,
                        boost::spirit::x3::unused_type
                    >
                >
            >
        >
    >
>::parse<
    __gnu_cxx::__normal_iterator<
        constchar*,
        std::__cxx11::basic_string<
            char
        >
    >,
    boost::spirit::x3::context<
        boost::spirit::x3::error_handler_tag,
        conststd::reference_wrapper<
            boost::spirit::x3::error_handler<
                __gnu_cxx::__normal_iterator<
                    constchar*,
                    std::__cxx11::basic_string<
                        char
                    >
                >
            >
        >,
        boost::spirit::x3::context<
            boost::spirit::x3::skipper_tag,
            constboost::spirit::x3::char_class<
                boost::spirit::char_encoding::ascii,
                boost::spirit::x3::space_tag
            >,
            boost::spirit::x3::unused_type
        >
    >,
    std::__cxx11::basic_string<
        char
    >,
    char
>

こうなります.

単純に <, >, , を見てインデントを調整しながら出力しているだけです. 空白はスキップします.

構文解析とかは全くしていないので,コンパイルエラーをそのまま流し込んでも悲惨な事になります. あと今気がついたのですが,const hogeconsthoge になっていますね. 修正しました

boost::spirit::x3::raw_directive<
    boost::spirit::x3::lexeme_directive<
        boost::spirit::x3::sequence<
            boost::spirit::x3::alternative<
                boost::spirit::x3::char_class<
                    boost::spirit::char_encoding::standard,
                    boost::spirit::x3::alpha_tag
                >,
                boost::spirit::x3::literal_char<
                    boost::spirit::char_encoding::standard,
                    boost::spirit::x3::unused_type
                >
            >,
            boost::spirit::x3::kleene<
                boost::spirit::x3::alternative<
                    boost::spirit::x3::char_class<
                        boost::spirit::char_encoding::standard,
                        boost::spirit::x3::alnum_tag
                    >,
                    boost::spirit::x3::literal_char<
                        boost::spirit::char_encoding::standard,
                        boost::spirit::x3::unused_type
                    >
                >
            >
        >
    >
>::parse<
    __gnu_cxx::__normal_iterator<
        const char *,
        std::__cxx11::basic_string<
            char
        >
    >,
    boost::spirit::x3::context<
        boost::spirit::x3::error_handler_tag,
        const std::reference_wrapper<
            boost::spirit::x3::error_handler<
                __gnu_cxx::__normal_iterator<
                    const char *,
                    std::__cxx11::basic_string<
                        char
                    >
                >
            >
        >,
        boost::spirit::x3::context<
            boost::spirit::x3::skipper_tag,
            const boost::spirit::x3::char_class<
                boost::spirit::char_encoding::ascii,
                boost::spirit::x3::space_tag
            >,
            boost::spirit::x3::unused_type
        >
    >,
    std::__cxx11::basic_string<
        char
    >,
    char
>