diff options
Diffstat (limited to 'src/boost/libs/spirit/example/x3/minimal')
7 files changed, 250 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/example/x3/minimal/ast.hpp b/src/boost/libs/spirit/example/x3/minimal/ast.hpp new file mode 100644 index 00000000..b66bb072 --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/ast.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2002-2018 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_MINIMAL_AST_HPP) +#define BOOST_SPIRIT_X3_MINIMAL_AST_HPP + +#include <boost/fusion/include/io.hpp> + +#include <iostream> +#include <string> + +namespace client { namespace ast +{ + /////////////////////////////////////////////////////////////////////////// + // Our employee AST struct + /////////////////////////////////////////////////////////////////////////// + struct employee + { + int age; + std::string forename; + std::string surname; + double salary; + }; + + using boost::fusion::operator<<; +}} + +#endif
\ No newline at end of file diff --git a/src/boost/libs/spirit/example/x3/minimal/ast_adapted.hpp b/src/boost/libs/spirit/example/x3/minimal/ast_adapted.hpp new file mode 100644 index 00000000..9d6c6fe9 --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/ast_adapted.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2002-2018 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_MINIMAL_AST_ADAPTED_HPP) +#define BOOST_SPIRIT_X3_MINIMAL_AST_ADAPTED_HPP + +#include <boost/fusion/include/adapt_struct.hpp> +#include "ast.hpp" + +// We need to tell fusion about our employee struct +// to make it a first-class fusion citizen. This has to +// be in global scope. + +BOOST_FUSION_ADAPT_STRUCT(client::ast::employee, + age, forename, surname, salary +) + +#endif diff --git a/src/boost/libs/spirit/example/x3/minimal/config.hpp b/src/boost/libs/spirit/example/x3/minimal/config.hpp new file mode 100644 index 00000000..3787346a --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/config.hpp @@ -0,0 +1,20 @@ +/*============================================================================= + Copyright (c) 2001-2018 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_MINIMAL_CONFIG_HPP) +#define BOOST_SPIRIT_X3_MINIMAL_CONFIG_HPP + +#include <boost/spirit/home/x3.hpp> + +namespace client { namespace parser +{ + namespace x3 = boost::spirit::x3; + + using iterator_type = std::string::const_iterator; + using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type; +}} + +#endif diff --git a/src/boost/libs/spirit/example/x3/minimal/employee.cpp b/src/boost/libs/spirit/example/x3/minimal/employee.cpp new file mode 100644 index 00000000..8b2fa6c1 --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/employee.cpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2001-2018 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 "employee_def.hpp" +#include "config.hpp" + +namespace client { namespace parser +{ + BOOST_SPIRIT_INSTANTIATE(employee_type, iterator_type, context_type); +}} diff --git a/src/boost/libs/spirit/example/x3/minimal/employee.hpp b/src/boost/libs/spirit/example/x3/minimal/employee.hpp new file mode 100644 index 00000000..a4475ec2 --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/employee.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2002-2018 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_MINIMAL_EMPLOYEE_HPP) +#define BOOST_SPIRIT_X3_MINIMAL_EMPLOYEE_HPP + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/home/x3.hpp> + +#include "ast.hpp" + +namespace client +{ + /////////////////////////////////////////////////////////////////////////////// + // Our employee parser declaration + /////////////////////////////////////////////////////////////////////////////// + namespace parser + { + namespace x3 = boost::spirit::x3; + using employee_type = x3::rule<class employee, ast::employee>; + BOOST_SPIRIT_DECLARE(employee_type); + } + + parser::employee_type employee(); +} + +#endif diff --git a/src/boost/libs/spirit/example/x3/minimal/employee_def.hpp b/src/boost/libs/spirit/example/x3/minimal/employee_def.hpp new file mode 100644 index 00000000..227b2f7f --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/employee_def.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2002-2018 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_MINIMAL_EMPLOYEE_DEF_HPP) +#define BOOST_SPIRIT_X3_MINIMAL_EMPLOYEE_DEF_HPP + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/home/x3.hpp> + +#include "ast.hpp" +#include "ast_adapted.hpp" +#include "employee.hpp" + +namespace client +{ + /////////////////////////////////////////////////////////////////////////////// + // Our employee parser definition + /////////////////////////////////////////////////////////////////////////////// + namespace parser + { + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + + using x3::int_; + using x3::lit; + using x3::double_; + using x3::lexeme; + using ascii::char_; + + x3::rule<class employee, ast::employee> const employee = "employee"; + + auto const quoted_string = lexeme['"' >> +(char_ - '"') >> '"']; + + auto const employee_def = + lit("employee") + >> '{' + >> int_ >> ',' + >> quoted_string >> ',' + >> quoted_string >> ',' + >> double_ + >> '}' + ; + + BOOST_SPIRIT_DEFINE(employee); + } + + parser::employee_type employee() + { + return parser::employee; + } +} + +#endif diff --git a/src/boost/libs/spirit/example/x3/minimal/main.cpp b/src/boost/libs/spirit/example/x3/minimal/main.cpp new file mode 100644 index 00000000..aeb3bc51 --- /dev/null +++ b/src/boost/libs/spirit/example/x3/minimal/main.cpp @@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2002-2018 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) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// This is the same employee parser (see employee.cpp) but structured to +// allow separate compilation of the actual parser in its own definition +// file (employee_def.hpp) and cpp file (employee.cpp). This main cpp file +// sees only the header file (employee.hpp). This is a good example on how +// parsers are structured in a C++ application. +// +// [ JDG May 9, 2007 ] +// [ JDG May 13, 2015 ] spirit X3 +// [ JDG Feb 20, 2018 ] Minimal "best practice" example +// +// I would like to thank Rainbowverse, llc (https://primeorbial.com/) +// for sponsoring this work and donating it to the community. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ast.hpp" +#include "ast_adapted.hpp" +#include "employee.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// Main program +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + std::cout << "/////////////////////////////////////////////////////////\n\n"; + std::cout << "\t\tAn employee parser for Spirit...\n\n"; + std::cout << "/////////////////////////////////////////////////////////\n\n"; + + std::cout + << "Give me an employee of the form :" + << "employee{age, \"forename\", \"surname\", salary } \n"; + std::cout << "Type [q or Q] to quit\n\n"; + + using boost::spirit::x3::ascii::space; + using iterator_type = std::string::const_iterator; + using client::employee; + + std::string str; + while (getline(std::cin, str)) + { + if (str.empty() || str[0] == 'q' || str[0] == 'Q') + break; + + client::ast::employee emp; + iterator_type iter = str.begin(); + iterator_type const end = str.end(); + bool r = phrase_parse(iter, end, employee(), space, emp); + + if (r && iter == end) + { + std::cout << boost::fusion::tuple_open('['); + std::cout << boost::fusion::tuple_close(']'); + std::cout << boost::fusion::tuple_delimiter(", "); + + std::cout << "-------------------------\n"; + std::cout << "Parsing succeeded\n"; + std::cout << "got: " << emp << std::endl; + std::cout << "\n-------------------------\n"; + } + else + { + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "-------------------------\n"; + } + } + + std::cout << "Bye... :-) \n\n"; + return 0; +} |