boost :: spirit递归命令式c ++语法:BOOST_FUSION_ADAPT_STRUCT失败

时间:2016-11-29 17:26:57

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

我一直在研究语法来解析c ++中的命令式语句(if / else / do / while / for / switch等)。所有其他语句都保存为字符串。 我目前只使用if / else进行测试(尽管其他语句在变体中应该类似)。 不幸的是我收到编译时错误:

  

错误1错误C2440:'返回' :无法转换为' std :: vector<   someSeqNode,性病::分配器< 泰 - >>' to' boost :: fusion :: vector<   someSeqNode,boost :: fusion :: void ,boost :: fusion :: void_,   boost :: fusion :: void_,boost :: fusion :: void_,boost :: fusion :: void_,   boost :: fusion :: void_,boost :: fusion :: void_,boost :: fusion :: void_,   升压::融合:: void_> &安培;'

     
    第80行的

(ifElseStruct的BOOST_FUSION_ADAPT_STRUCT的右括号)

  

我发现有关BOOST_FUSION_ADAPT_STRUCT和属性传播的编译问题的唯一其他问题是在只有一个成员的结构上,或者在自适应结构和规则之间存在不兼容的属性。

似乎无法适应ifElseStruct.ifContent,但我不明白为什么。解析typedef它实际上只是vector<变体LT; ifElseStruct,string>>。

递归是问题吗?如果是这样,我该如何解决?

#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3

#pragma region INCLUDE_STUFF
#include <vector>
#include <string>
#include <iostream>
//boost includes for parser and some collection types (e.g. tuple)
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix/fusion.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/spirit/include/qi_raw.hpp>
#include <boost/variant.hpp>
#include "vectorStreamOp.h"//overload stream operator << for std::vector -> for BOOST_SPIRIT_DEBUG
#pragma endregion INCLUDE_STUFF

#pragma region NAMESPACE_STUFF
//to shorten calls fruther down
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using std::string;
using std::cout;
using std::endl;
using std::vector;
using boost::spirit::qi::parse;
using boost::optional;
using phx::ref;
using phx::at_c;
using qi::char_;
using qi::lexeme;
using qi::_1;
using qi::lit;
using qi::alnum;
using qi::alpha;
using qi::space;
using qi::raw;
using qi::as_string;
#pragma endregion NAMESPACE_STUFF

#pragma region STRUCT_STUFF
/*later make this variant with all impStatementVariants -> either make this a vector to have sequences on all levels or make imperativeCpp derive from this
-> typedef variant<
recursive_wrapper<ifElseStruct>,
recursive_wrapper<switchStruct>,
recursive_wrapper<forStruct>,
recursive_wrapper<whileStruct>,
recursive_wrapper<doWhileStruct>
*/
struct ifElseStruct;
typedef boost::variant<ifElseStruct, string> someSeqNode;

struct ifElseStruct
{
    string ifCond;
    vector<someSeqNode> ifContent;
    optional<vector<someSeqNode>> elseContent;

    //for BOOST DEBUG
    friend std::ostream& operator<< (std::ostream& stream, const ifElseStruct& var) {
        stream << "ifCond: " << var.ifCond << "   ifContent: " << var.ifContent << endl << "elseContent:" << var.elseContent;
        return stream;
    }
};

BOOST_FUSION_ADAPT_STRUCT(
    ifElseStruct,
    (string, ifCond)
    (vector<someSeqNode>, ifContent)
    (optional<vector<someSeqNode>>, elseContent)
    )
#pragma endregion STRUCT_STUFF

#pragma region GRAMMAR_STUFF
    //GRAMMAR for flowcontrol (branching and looping)
    template<typename Iterator, typename Skipper> struct imperativeGrammar :qi::grammar<Iterator, vector<someSeqNode>(), Skipper>
{
    imperativeGrammar() : imperativeGrammar::base_type(startRule)
    {
        startRule = *(recursiveImpCpp | nestedSomething); //vector<variant<ifElseStruct(), string>>
        recursiveImpCpp = ifElseNormalRule.alias() /*| switchRule | whileRule | forRule ...*/;

        //attr: ifElseStruct containing-> string, vector<someSeqNode>, optional<vector<someSeqNode>>
        ifElseNormalRule = lit("if")>> '(' >> condition >> ')' >> ifElseContent >> -(lit("else") >> ifElseContent);

        condition = *~char_(")");//TODO: replace with nestedSomething rule
        ifElseContent = ('{' >> startRule >> '}') /*| singleStatement*/;

        singleStatement = !recursiveImpCpp >> (qi::as_string[*~char_(";")] >> qi::as_string[char_(';')]);
        nestedSomething = !recursiveImpCpp >> qi::as_string[*~char_("(){}")]
            >> -(raw['(' >> nestedSomething >> ')']) >> -(raw['{' >> nestedSomething >> '}'])
            >> !recursiveImpCpp >> qi::as_string[*~char_("(){}")];

        BOOST_SPIRIT_DEBUG_NODES((startRule)(ifElseNormalRule)(ifElseContent))
    }

    qi::rule<Iterator, vector<someSeqNode>(), Skipper> startRule;
    qi::rule<Iterator, ifElseStruct(), Skipper> recursiveImpCpp;
    qi::rule<Iterator, ifElseStruct(), Skipper> ifElseNormalRule;

    qi::rule<Iterator, string(), Skipper> condition;
    qi::rule<Iterator, vector<someSeqNode>(), Skipper> ifElseContent;
    qi::rule<Iterator, std::string(), Skipper> nestedSomething;
    qi::rule<Iterator, std::string(), Skipper> singleStatement;

    /*qi::rule<Iterator, Skipper> forRule;
    qi::rule<Iterator, Skipper> switchCaseBreakRule;
    qi::rule<Iterator, Skipper> whileRule;
    qi::rule<Iterator, Skipper> doWhileRule;*/
};
#pragma endregion GRAMMAR_STUFF

1 个答案:

答案 0 :(得分:2)

有很多问题。

  1. 与评论一样,不要使用using-directives;他们让你陷入困境
  2. 如果您只想在nestedSomething中连接所有源字符串,那么只需将其全部包含在raw[](或as_string[raw[...]]中,但这甚至不是必需的),例如

    nestedSomething = !recursiveImpCpp >> qi::raw[*~char_("(){}")
        >> -('(' >> nestedSomething >> ')')
        >> -('{' >> nestedSomething >> '}')
        >> !recursiveImpCpp >> *~char_("(){}")];
    
  3. 该规则在与空字符串匹配的意义上被破坏。这使得语法永远不会结束(它将匹配“无限”量的空nestedSomething)。您将不得不决定一些非可选部分。这是一个强力修复:

    qi::raw[...] [ qi::_pass = px::size(qi::_1) > 0 ];
    

    即使这样,语法也会陷入非平凡程序的无限循环中(尝试使用自己的源代码)。以下内容应该清楚一点:

    identifier_soup = !recursiveImpCpp >> +~qi::char_("(){}");
    parenthesized = '(' >> -nestedSomething >> ')';
    bracketed     = '{' >> -nestedSomething >> '}';
    nestedSomething %=  qi::raw[ -identifier_soup
        >> -parenthesized
        >> -bracketed
        >> -identifier_soup] [ qi::_pass = px::size(qi::_1) > 0 ];
    

    但是仍然无法解析,例如int main() { if(true) { std::cout << "Yes\n"; } else { std::cout << "No\n"; } })。原因是main(<parenthesized>){<bracketed>}只接受括号内的nestedSomething;明确禁止if-else构造......

    让我们将ifElseContent重命名为正确的内容(例如statement

    block     = '{' >> startRule >> '}';
    statement = block | singleStatement;
    

    并使用它代替bracketed

    nestedSomething %= qi::raw[ -identifier_soup
        >> -parenthesized
        >> -block
        >> -identifier_soup] [ qi::_pass = boost::phoenix::size(qi::_1) > 0 ];
    
  4. 一般各种笔记

    • 您可以简化包含,而不是将它们包装在区域中以隐藏它们
    • 你也可以简化其余部分(参见我的演示)
    • 语法在所有负面预测中都会非常低效。考虑使用标记化或使用更精细的关键字检测方案(使用期望点和/或来自Qi存储库的distinct()[]

    部分演示

    应用上述说明:

    <强> Live On Coliru

    #define BOOST_SPIRIT_DEBUG
    #define BOOST_SPIRIT_USE_PHOENIX_V3
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <boost/fusion/include/adapted.hpp>
    #include <boost/optional/optional_io.hpp>
    
    #ifdef BOOST_SPIRIT_DEBUG
        namespace std {
            template <typename... T, typename... V>
            auto& operator<<(basic_ostream<T...>& os, vector<V...> const& v) {
                os << "{";
                for (auto& el : v) os << el << " ";
                return os;
            }
        }
    #endif
    
    namespace qi  = boost::spirit::qi;
    
    /* later make this variant with all impStatementVariants -> either make this a
     * vector to have sequences on all levels or make imperativeCpp derive from
     * this
    
        -> typedef variant<
            recursive_wrapper<ifElseStruct>,
            recursive_wrapper<switchStruct>,
            recursive_wrapper<forStruct>,
            recursive_wrapper<whileStruct>,
            recursive_wrapper<doWhileStruct>
    
     *
     */
    struct ifElseStruct;
    typedef boost::variant<ifElseStruct, std::string> someSeqNode;
    
    struct ifElseStruct
    {
        std::string ifCond;
        std::vector<someSeqNode> ifContent;
        boost::optional<std::vector<someSeqNode>> elseContent;
    
        friend std::ostream& operator<< (std::ostream& stream, const ifElseStruct& var) {
            stream << "ifCond: " << var.ifCond << " ifContent: " << var.ifContent << std::endl << "elseContent:" << var.elseContent;
            return stream;
        }
    };
    
    BOOST_FUSION_ADAPT_STRUCT(ifElseStruct, ifCond, ifContent, elseContent)
    
    //GRAMMAR for flowcontrol (branching and looping)
    template<typename Iterator, typename Skipper> struct imperativeGrammar :qi::grammar<Iterator, std::vector<someSeqNode>(), Skipper>
    {
        imperativeGrammar() : imperativeGrammar::base_type(startRule)
        {
            startRule = *(recursiveImpCpp | nestedSomething); //vector<variant<ifElseStruct(), string>>
            recursiveImpCpp = ifElseNormalRule.alias() /*| switchRule | whileRule | forRule ...*/;
    
            //attr: ifElseStruct containing-> string, vector<someSeqNode>, optional<vector<someSeqNode>>
            ifElseNormalRule = qi::lit("if") >> '(' >> condition >> ')' >> statement >> -("else" >> statement);
    
            condition = *~qi::char_(")");//TODO: replace with nestedSomething rule
            block     = '{' >> startRule >> '}';
            statement = block | singleStatement;
    
            identifier_soup = !recursiveImpCpp >> +~qi::char_("(){}");
            parenthesized = '(' >> -nestedSomething >> ')';
            bracketed     = '{' >> -nestedSomething >> '}';
            nestedSomething %= qi::raw[ -identifier_soup
                >> -parenthesized
                >> -block
                >> -identifier_soup] [ qi::_pass = boost::phoenix::size(qi::_1) > 0 ];
            singleStatement = !recursiveImpCpp >> qi::raw[*~qi::char_(';') >> ';'];
    
            BOOST_SPIRIT_DEBUG_NODES((startRule)(ifElseNormalRule)(statement)(block)(nestedSomething)(identifier_soup)(parenthesized)(bracketed)(singleStatement))
        }
    
        qi::rule<Iterator, std::vector<someSeqNode>(), Skipper> startRule;
        qi::rule<Iterator, ifElseStruct(), Skipper> recursiveImpCpp;
        qi::rule<Iterator, ifElseStruct(), Skipper> ifElseNormalRule;
    
        qi::rule<Iterator, std::string(), Skipper> condition;
        qi::rule<Iterator, std::vector<someSeqNode>(), Skipper> block, statement;
        qi::rule<Iterator, std::string(), Skipper> nestedSomething;
        qi::rule<Iterator, std::string(), Skipper> singleStatement;
        qi::rule<Iterator, Skipper> identifier_soup, parenthesized, bracketed;
    
        /*qi::rule<Iterator, Skipper> forRule;
        qi::rule<Iterator, Skipper> switchCaseBreakRule;
        qi::rule<Iterator, Skipper> whileRule;
        qi::rule<Iterator, Skipper> doWhileRule;*/
    };
    
    #include <fstream>
    
    int main() {
        //std::string const input = { std::istreambuf_iterator<char>(std::ifstream("main.cpp").rdbuf()), {} };
        std::string const input = "int main() { if(true) { std::cout << \"Yes\\n\"; } else { std::cout << \"No\\n\"; } }";
    
        using It = std::string::const_iterator;
        It f(input.begin()), l(input.end());
    
        imperativeGrammar<It, qi::space_type> p;
        std::vector<someSeqNode> rep;
        bool ok = phrase_parse(f, l, p, qi::space, rep);
        if (ok) {
            std::cout << "Parse success: " << rep << "\n";
        }
        else
            std::cout << "Parse failure\n";
    
        if (f!=l)
            std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
    }
    

    打印:

    Parse success: {int main() { if(true) { std::cout << "Yes\n"; } else { std::cout << "No\n"; } } 
    

    使用调试信息

    <startRule>
      <try>int main() { if(true</try>
      <ifElseNormalRule>
        <try>int main() { if(true</try>
        <fail/>
      </ifElseNormalRule>
      <nestedSomething>
        <try>int main() { if(true</try>
        <identifier_soup>
          <try>int main() { if(true</try>
          <ifElseNormalRule>
            <try>int main() { if(true</try>
            <fail/>
          </ifElseNormalRule>
          <success>() { if(true) { std:</success>
          <attributes>[]</attributes>
        </identifier_soup>
        <parenthesized>
          <try>() { if(true) { std:</try>
          <nestedSomething>
            <try>) { if(true) { std::</try>
            <identifier_soup>
              <try>) { if(true) { std::</try>
              <ifElseNormalRule>
                <try>) { if(true) { std::</try>
                <fail/>
              </ifElseNormalRule>
              <fail/>
            </identifier_soup>
            <parenthesized>
              <try>) { if(true) { std::</try>
              <fail/>
            </parenthesized>
            <block>
              <try>) { if(true) { std::</try>
              <fail/>
            </block>
            <identifier_soup>
              <try>) { if(true) { std::</try>
              <ifElseNormalRule>
                <try>) { if(true) { std::</try>
                <fail/>
              </ifElseNormalRule>
              <fail/>
            </identifier_soup>
            <fail/>
          </nestedSomething>
          <success> { if(true) { std::c</success>
          <attributes>[]</attributes>
        </parenthesized>
        <block>
          <try> { if(true) { std::c</try>
          <startRule>
            <try> if(true) { std::cou</try>
            <ifElseNormalRule>
              <try> if(true) { std::cou</try>
              <statement>
                <try> { std::cout << "Yes</try>
                <block>
                  <try> { std::cout << "Yes</try>
                  <startRule>
                    <try> std::cout << "Yes\n</try>
                    <ifElseNormalRule>
                      <try> std::cout << "Yes\n</try>
                      <fail/>
                    </ifElseNormalRule>
                    <nestedSomething>
                      <try> std::cout << "Yes\n</try>
                      <identifier_soup>
                        <try>std::cout << "Yes\n"</try>
                        <ifElseNormalRule>
                          <try>std::cout << "Yes\n"</try>
                          <fail/>
                        </ifElseNormalRule>
                        <success>} else { std::cout <</success>
                        <attributes>[]</attributes>
                      </identifier_soup>
                      <parenthesized>
                        <try>} else { std::cout <</try>
                        <fail/>
                      </parenthesized>
                      <block>
                        <try>} else { std::cout <</try>
                        <fail/>
                      </block>
                      <identifier_soup>
                        <try>} else { std::cout <</try>
                        <ifElseNormalRule>
                          <try>} else { std::cout <</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <success>} else { std::cout <</success>
                      <attributes>[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]]</attributes>
                    </nestedSomething>
                    <ifElseNormalRule>
                      <try>} else { std::cout <</try>
                      <fail/>
                    </ifElseNormalRule>
                    <nestedSomething>
                      <try>} else { std::cout <</try>
                      <identifier_soup>
                        <try>} else { std::cout <</try>
                        <ifElseNormalRule>
                          <try>} else { std::cout <</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <parenthesized>
                        <try>} else { std::cout <</try>
                        <fail/>
                      </parenthesized>
                      <block>
                        <try>} else { std::cout <</try>
                        <fail/>
                      </block>
                      <identifier_soup>
                        <try>} else { std::cout <</try>
                        <ifElseNormalRule>
                          <try>} else { std::cout <</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <fail/>
                    </nestedSomething>
                    <success>} else { std::cout <</success>
                    <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]]]</attributes>
                  </startRule>
                  <success> else { std::cout <<</success>
                  <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]]]</attributes>
                </block>
                <success> else { std::cout <<</success>
                <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]]]</attributes>
              </statement>
              <statement>
                <try> { std::cout << "No\</try>
                <block>
                  <try> { std::cout << "No\</try>
                  <startRule>
                    <try> std::cout << "No\n"</try>
                    <ifElseNormalRule>
                      <try> std::cout << "No\n"</try>
                      <fail/>
                    </ifElseNormalRule>
                    <nestedSomething>
                      <try> std::cout << "No\n"</try>
                      <identifier_soup>
                        <try>std::cout << "No\n";</try>
                        <ifElseNormalRule>
                          <try>std::cout << "No\n";</try>
                          <fail/>
                        </ifElseNormalRule>
                        <success>} }</success>
                        <attributes>[]</attributes>
                      </identifier_soup>
                      <parenthesized>
                        <try>} }</try>
                        <fail/>
                      </parenthesized>
                      <block>
                        <try>} }</try>
                        <fail/>
                      </block>
                      <identifier_soup>
                        <try>} }</try>
                        <ifElseNormalRule>
                          <try>} }</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <success>} }</success>
                      <attributes>[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]</attributes>
                    </nestedSomething>
                    <ifElseNormalRule>
                      <try>} }</try>
                      <fail/>
                    </ifElseNormalRule>
                    <nestedSomething>
                      <try>} }</try>
                      <identifier_soup>
                        <try>} }</try>
                        <ifElseNormalRule>
                          <try>} }</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <parenthesized>
                        <try>} }</try>
                        <fail/>
                      </parenthesized>
                      <block>
                        <try>} }</try>
                        <fail/>
                      </block>
                      <identifier_soup>
                        <try>} }</try>
                        <ifElseNormalRule>
                          <try>} }</try>
                          <fail/>
                        </ifElseNormalRule>
                        <fail/>
                      </identifier_soup>
                      <fail/>
                    </nestedSomething>
                    <success>} }</success>
                    <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]</attributes>
                  </startRule>
                  <success> }</success>
                  <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]</attributes>
                </block>
                <success> }</success>
                <attributes>[[[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]</attributes>
              </statement>
              <success> }</success>
              <attributes>[[[t, r, u, e], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]]</attributes>
            </ifElseNormalRule>
            <ifElseNormalRule>
              <try> }</try>
              <fail/>
            </ifElseNormalRule>
            <nestedSomething>
              <try> }</try>
              <identifier_soup>
                <try>}</try>
                <ifElseNormalRule>
                  <try>}</try>
                  <fail/>
                </ifElseNormalRule>
                <fail/>
              </identifier_soup>
              <parenthesized>
                <try>}</try>
                <fail/>
              </parenthesized>
              <block>
                <try>}</try>
                <fail/>
              </block>
              <identifier_soup>
                <try>}</try>
                <ifElseNormalRule>
                  <try>}</try>
                  <fail/>
                </ifElseNormalRule>
                <fail/>
              </identifier_soup>
              <fail/>
            </nestedSomething>
            <success> }</success>
            <attributes>[[[[t, r, u, e], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]]]</attributes>
          </startRule>
          <success></success>
          <attributes>[[[[t, r, u, e], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  ]], [[s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  ]]]]]</attributes>
        </block>
        <identifier_soup>
          <try></try>
          <ifElseNormalRule>
            <try></try>
            <fail/>
          </ifElseNormalRule>
          <fail/>
        </identifier_soup>
        <success></success>
        <attributes>[[i, n, t,  , m, a, i, n, (, ),  , {,  , i, f, (, t, r, u, e, ),  , {,  , s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  , },  , e, l, s, e,  , {,  , s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  , },  , }]]</attributes>
      </nestedSomething>
      <ifElseNormalRule>
        <try></try>
        <fail/>
      </ifElseNormalRule>
      <nestedSomething>
        <try></try>
        <identifier_soup>
          <try></try>
          <ifElseNormalRule>
            <try></try>
            <fail/>
          </ifElseNormalRule>
          <fail/>
        </identifier_soup>
        <parenthesized>
          <try></try>
          <fail/>
        </parenthesized>
        <block>
          <try></try>
          <fail/>
        </block>
        <identifier_soup>
          <try></try>
          <ifElseNormalRule>
            <try></try>
            <fail/>
          </ifElseNormalRule>
          <fail/>
        </identifier_soup>
        <fail/>
      </nestedSomething>
      <success></success>
      <attributes>[[[i, n, t,  , m, a, i, n, (, ),  , {,  , i, f, (, t, r, u, e, ),  , {,  , s, t, d, :, :, c, o, u, t,  , <, <,  , ", Y, e, s, \, n, ", ;,  , },  , e, l, s, e,  , {,  , s, t, d, :, :, c, o, u, t,  , <, <,  , ", N, o, \, n, ", ;,  , },  , }]]]</attributes>
    </startRule>
    

    概要/忠告

    如果您运行上面的示例on its own source,您会注意到它在第9行的命名空间上出现了问题。虽然程序完成而不是崩溃很好,但这并不令人鼓舞。

    你需要一个合适的语法。您需要了解什么是语句,什么是块,什么是关键字以及它们之间的关系。您的部分困惑似乎来自于将表达式语句混为一谈。

    我非常考虑提出一个你可以工作的语法2.你知道为什么它会起作用而不是......看起来只是试图通过解析编程语言来欺骗你的方式。

    您是否考虑过如何解析std::cout << "int main() { return 0; }";

    您是否考虑过具有续行的宏?