c++ - 振奋 spirit : how to instruct the parser to read whole input and then report the result

标签 c++ boost

我有一个表达式语法的最小示例(仅限算术表达式),只有当完整的输入是一个有效的算术表达式时,它才会成功。在我看来,即使子序列导致解析器的开始符号,解析器也会报告成功。

  template <typename Iterator>
    struct expparser : qi::grammar<Iterator, expression_ast(),ascii::space_type>
    {
        expparser() : expparser::base_type(aexp)
        {
            using qi::_val;
            using qi::_1;
            using qi::_2;
            using qi::_3;
            using qi::uint_;
            using qi::lit;
            using qi::alnum;


            aexp = tm >> +((lit("+") >> aexp))
                | (tm >> +(lit("-") >> aexp))
                | (tm >> +(lit("*") >> aexp))
                | (tm >> +(lit("/") >> aexp))
                | tm;

            tm = (uint_)[_val=_1];
        }

        qi::rule<Iterator, expression_ast(),ascii::space_type  >
        aexp,tm;
    };
}


int main()
{
     std::string input("3+5*}{%%");
//initial part is good but some junk at the end


 using boost::spirit::ascii::space;
         typedef client::expparser<std::string::const_iterator> parser;
         parser par; // Our grammar
         std::string::const_iterator beg = input.begin();
         std::string::const_iterator end = input.end();
//       std::cout<<"About to parse the expression "<<input;
         bool r = phrase_parse(beg, end, par, space, ast);
         if(!r)
         {
             BOOST_ASSERT_MSG(false,"NOt a valid expression to parse");
         }else
         {
             std::cout<<"Parsed successfully"<<std::endl;
         }
    }

当我运行这个程序时,它成功了,因为 3 与 tm 匹配并给出了初始符号 aexp。如何保证完整表达式的良构性?

最佳答案

如果找到匹配项,

phrase_parse 返回 true,即使该匹配项不包含整个字符串。它还修改了给它的前端迭代器指向它找到的匹配项的末尾,这意味着如果整个字符串都匹配,则当 phrase_parse 是时,前端迭代器将等于末尾迭代器完成的。

如果要测试是否找到匹配项并包含整个字符串,请使用

     if(!r || beg != end)
     {
         BOOST_ASSERT_MSG(false,"NOt a valid expression to parse");
     }else
     {
         std::cout<<"Parsed successfully"<<std::endl;
     }

关于c++ - 振奋 spirit : how to instruct the parser to read whole input and then report the result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30817787/

相关文章:

c++ - MSVC2017 上的 SFINAE 与 numeric_limits<T>::max()

boost - 使用 clang-tidy 处理大量与 boost 单元测试相关的警告

c++ - 哪些编译器支持 std::filesystem?

c++ - 如何使用 C++11 标准使 g++ 永久编译?

c++ - 引用 vector

C++ 相当于 Python getattr

c++ - 没有得到 boost::bad_get 的 boost::get 异常

c++ - Boost模板派生类的序列化

c++ - 获取基类指针的派生类

c++ - 指针递增递减语法差异