处理语义动作中的异常

时间:2013-10-28 08:34:15

标签: boost boost-spirit boost-spirit-qi

考虑以下解析器:

class test
{
public:
  static test from_string(const string &str); //throws!
};

template <typename Iterator = string::const_iterator>
struct test_parser : grammar<Iterator, test(), blank_type>
{
  test_parser() : test_parser::base_type(query)
  {
    query = id[_val = phx::bind(&test::from_string, qi::_1)];
    id = lexeme[*char_("a-zA-Z_0-9")];
  }
  rule<Iterator, test(), blank_type> query;
  rule<Iterator, string(), blank_type> id;
};

我想捕获test::from_string可能抛出的异常以及异常时的匹配失败。我找不到直接的方法来做到这一点,所以我试图使用一个“适配器”函数来明确接受上下文。但是如何访问上下文以及如何将这样的操作附加到语法?请查看代码中的问题:

template<class Context>
void match_test(const string &attr, Context &context, bool &mFlag)
{
  try
  {
    test t = test::from_string(attr);
    // how do I access the context to put t into _val?
  }
  catch(...)
  {
    mFlag = false;
  }
}

//...
test_parser() : test_parser::base_type(query)
{
  query = id[?match_test<?>? /*how to instantiate and use the above semantic action?*/];
  id = lexeme[*char_("a-zA-Z_0-9")];
}

1 个答案:

答案 0 :(得分:2)

就像评论者说的那样,使用

    query = id[
            phx::try_ [
                qi::_val = phx::bind(&test::from_string, qi::_1)
            ].catch_all [ 
                qi::_pass = false 
            ]
        ];

查看 Live on Coliru

即使使用BOOST_SPIRIT_USE_PHOENIX_V3进行编译的版本: Live on Coliru

    query = id[
            phx::try_ [
                qi::_val = phx::bind(&test::from_string, qi::_1)
            ].catch_all [ 
                qi::_pass = false 
            ],
            qi::_pass = qi::_pass // to appease the spirit expression compilation gods
        ];