parameters.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 217 行
CPP
217 行
/*============================================================================= Copyright (c) 2001-2003 Hartmut Kaiser http://spirit.sourceforge.net/ Use, modification and distribution is subject to 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 sample show the usage of parser parameters.//// Parser parameters are used to pass some values from the outer parsing scope// to the next inner scope. They can be imagined as the opposite to the return// value paradigm, which returns some value from the inner to the next outer// scope. See the "Closures" chapter in the User's Guide.#include <string>#include <iostream>#include <cassert>#if defined(_MSC_VER) /*&& !defined(__COMO__)*/#pragma warning(disable: 4244)#pragma warning(disable: 4355)#endif // defined(_MSC_VER) && !defined(__COMO__)#include <boost/spirit/include/classic_core.hpp>#include <boost/spirit/include/classic_symbols.hpp>#include <boost/spirit/include/classic_closure.hpp>#include <boost/spirit/include/phoenix1_tuples.hpp>#include <boost/spirit/include/phoenix1_tuple_helpers.hpp>#include <boost/spirit/include/phoenix1_primitives.hpp>///////////////////////////////////////////////////////////////////////////////// used namespacesusing namespace BOOST_SPIRIT_CLASSIC_NS;using namespace phoenix;using namespace std;///////////////////////////////////////////////////////////////////////////////// Helper class for encapsulation of the type for the parsed variable namesclass declaration_type{public: enum vartype { vartype_unknown = 0, // unknown variable type vartype_int = 1, // 'int' vartype_real = 2 // 'real' }; declaration_type() : type(vartype_unknown) { } template <typename ItT> declaration_type(ItT const &first, ItT const &last) { init(string(first, last-first-1)); } declaration_type(declaration_type const &type_) : type(type_.type) { } declaration_type(string const &type_) : type(vartype_unknown) { init(type_); }// access to the variable type operator vartype const &() const { return type; } operator string () { switch(type) { default: case vartype_unknown: break; case vartype_int: return string("int"); case vartype_real: return string("real"); } return string ("unknown"); } void swap(declaration_type &s) { std::swap(type, s.type); }protected: void init (string const &type_) { if (type_ == "int") type = vartype_int; else if (type_ == "real") type = vartype_real; else type = vartype_unknown; }private: vartype type;};/////////////////////////////////////////////////////////////////////////////////// used closure type/////////////////////////////////////////////////////////////////////////////////struct var_decl_closure : BOOST_SPIRIT_CLASSIC_NS::closure<var_decl_closure, declaration_type>{ member1 val;};/////////////////////////////////////////////////////////////////////////////////// symbols_with_data//// Helper class for inserting an item with data into a symbol table/////////////////////////////////////////////////////////////////////////////////template <typename T, typename InitT>class symbols_with_data{public: typedef symbol_inserter<T, BOOST_SPIRIT_CLASSIC_NS::impl::tst<T, char> > symbol_inserter_t; symbols_with_data(symbol_inserter_t const &add_, InitT const &data_) : add(add_), data(as_actor<InitT>::convert(data_)) { } template <typename IteratorT> symbol_inserter_t const & operator()(IteratorT const &first_, IteratorT const &last) const { IteratorT first = first_; return add(first, last, data()); }private: symbol_inserter_t const &add; typename as_actor<InitT>::type data;};template <typename T, typename CharT, typename InitT>inlinesymbols_with_data<T, InitT>symbols_gen(symbol_inserter<T, BOOST_SPIRIT_CLASSIC_NS::impl::tst<T, CharT> > const &add_, InitT const &data_){ return symbols_with_data<T, InitT>(add_, data_);}///////////////////////////////////////////////////////////////////////////////// The var_decl_list grammar parses variable declaration liststruct var_decl_list : public grammar<var_decl_list, var_decl_closure::context_t>{ template <typename ScannerT> struct definition { definition(var_decl_list const &self) { // pass variable type returned from 'type' to list closure member 0 decl = type[self.val = arg1] >> +space_p >> list(self.val); // m0 to access arg 0 of list --> passing variable type down to ident list = ident(list.val) >> *(',' >> ident(list.val)); // store identifier and type into the symbol table ident = (*alnum_p)[symbols_gen(symtab.add, ident.val)]; // the type of the decl is returned in type's closure member 0 type = str_p("int")[type.val = construct_<string>(arg1, arg2)] | str_p("real")[type.val = construct_<string>(arg1, arg2)] ; BOOST_SPIRIT_DEBUG_RULE(decl); BOOST_SPIRIT_DEBUG_RULE(list); BOOST_SPIRIT_DEBUG_RULE(ident); BOOST_SPIRIT_DEBUG_RULE(type); } rule<ScannerT> const& start() const { return decl; } private: typedef rule<ScannerT, var_decl_closure::context_t> rule_t; rule_t type; rule_t list; rule_t ident; symbols<declaration_type> symtab; rule<ScannerT> decl; // start rule };};///////////////////////////////////////////////////////////////////////////////// main entry pointint main(){var_decl_list decl;declaration_type type;char const *pbegin = "int var1"; if (parse (pbegin, decl[assign(type)]).full) { cout << endl << "Parsed variable declarations successfully!" << endl << "Detected type: " << declaration_type::vartype(type) << " (" << string(type) << ")" << endl; } else { cout << endl << "Parsing the input stream failed!" << endl; } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?