rule.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 228 行

CPP
228
字号
/*=============================================================================    Copyright (c) 2001-2007 Joel de Guzman    Distributed under the Boost Software License, Version 1.0. (See accompanying    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#include <boost/detail/lightweight_test.hpp>#include <boost/spirit/include/qi_operator.hpp>#include <boost/spirit/include/qi_char.hpp>#include <boost/spirit/include/qi_string.hpp>#include <boost/spirit/include/qi_numeric.hpp>#include <boost/spirit/include/qi_nonterminal.hpp>#include <boost/spirit/include/qi_action.hpp>#include <boost/spirit/include/phoenix_core.hpp>#include <boost/spirit/include/phoenix_operator.hpp>#include <boost/spirit/include/phoenix_object.hpp>#include <string>#include <iostream>#include "test.hpp"using namespace spirit_test;intmain(){    using namespace boost::spirit::qi;    using namespace boost::spirit::ascii;    { // basic tests        rule<char const*> a, b, c, start;        a = 'a';        b = 'b';        c = 'c';        start = *(a | b | c);        BOOST_TEST(test("abcabcacb", start));        start = (a | b) >> (start | b);        BOOST_TEST(test("aaaabababaaabbb", start));        BOOST_TEST(test("aaaabababaaabba", start, false));    }    { // basic tests w/ skipper        rule<char const*, space_type> a, b, c, start;        a = 'a';        b = 'b';        c = 'c';        start = *(a | b | c);        BOOST_TEST(test(" a b c a b c a c b", start, space));        // allow no skipping too:        BOOST_TEST(test("abcabcacb", start));        start = (a | b) >> (start | b);        BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));        BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));    }    { // alias tests        rule<char const*> a, b, c, d, start;        a = 'a';        b = 'b';        c = 'c';        d = start.alias(); // d will always track start        start = *(a | b | c);        BOOST_TEST(test("abcabcacb", d));        start = (a | b) >> (start | b);        BOOST_TEST(test("aaaabababaaabbb", d));    }    { // copy tests        rule<char const*> a, b, c, start;        a = 'a';        b = 'b';        c = 'c';        // The FF is the dynamic equivalent of start = *(a | b | c);        start = a;        start = start.copy() | b;        start = start.copy() | c;        start = *(start.copy());        BOOST_TEST(test("abcabcacb", start));        // The FF is the dynamic equivalent of start = (a | b) >> (start | b);        start = b;        start = a | start.copy();        start = start.copy() >> (start | b);        BOOST_TEST(test("aaaabababaaabbb", start));        BOOST_TEST(test("aaaabababaaabba", start, false));    }    { // context tests        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::spirit::arg_names::_1;        using boost::spirit::arg_names::_val;        char ch;        rule<char const*, char()> a;        a = alpha[_val = _1];        BOOST_TEST(test("x", a[ref(ch) = _1]));        BOOST_TEST(ch == 'x');        BOOST_TEST(test_attr("z", a, ch)); // attribute is given.        BOOST_TEST(ch == 'z');    }    { // context (w/arg) tests        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::spirit::arg_names::_1;        using boost::spirit::arg_names::_r1;        using boost::spirit::arg_names::_r2;        using boost::spirit::arg_names::_val;        char ch;        rule<char const*, char(int)> a; // 1 arg        a = alpha[_val = _1 + _r1];        BOOST_TEST(test("x", a(val(1))[ref(ch) = _1]));        BOOST_TEST(ch == 'x' + 1);        BOOST_TEST(test_attr("a", a(1), ch)); // allow scalars as rule args too.        BOOST_TEST(ch == 'a' + 1);        rule<char const*, char(int, int)> b; // 2 args        b = alpha[_val = _1 + _r1 + _r2];        BOOST_TEST(test_attr("a", b(1, 2), ch));        BOOST_TEST(ch == 'a' + 1 + 2);    }    { // context (w/locals) tests        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::spirit::arg_names::_1;        using boost::spirit::arg_names::_a;        using boost::spirit::char_;        using boost::spirit::locals;        rule<char const*, locals<char> > a; // 1 local        a = alpha[_a = _1] >> char_(_a);        BOOST_TEST(test("aa", a));        BOOST_TEST(!test("ax", a));    }    { // context (w/args and locals) tests        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::spirit::arg_names::_1;        using boost::spirit::arg_names::_r1;        using boost::spirit::arg_names::_a;        using boost::spirit::char_;        using boost::spirit::locals;        rule<char const*, void(int), locals<char> > a; // 1 arg + 1 local        a = alpha[_a = _1 + _r1] >> char_(_a);        BOOST_TEST(test("ab", a(val(1))));        BOOST_TEST(test("xy", a(val(1))));        BOOST_TEST(!test("ax", a(val(1))));    }    { // bug: test that injected attributes are ok        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::spirit::arg_names::_1;        using boost::spirit::arg_names::_r1;        using boost::spirit::arg_names::_val;        using boost::spirit::char_;        rule<char const*, char(int) > r;        // problem code:        r = char_(_r1)[_val = _1];    }    { // error handling        using namespace boost::phoenix;        using namespace boost::spirit::ascii;        using boost::phoenix::val;        using boost::spirit::int_;        using boost::spirit::arg_names::_4; // what        using boost::spirit::arg_names::_3; // error pos        using boost::spirit::arg_names::_2; // end        using boost::spirit::qi::fail;        rule<char const*> r;        r = '(' > int_ > ',' > int_ > ')';        on_error<fail>        (            r, std::cout                << val("Error! Expecting: ")                << _4                << val(" Here: \"")                << construct<std::string>(_3, _2)                << val("\"")                << std::endl        );        BOOST_TEST(test("(123,456)", r));        BOOST_TEST(!test("(abc,def)", r));        BOOST_TEST(!test("(123,456]", r));        BOOST_TEST(!test("(123;456)", r));        BOOST_TEST(!test("[123,456]", r));    }    return boost::report_errors();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?