Frage

Ich habe Probleme bekommen einen kleinen Geist / Qi Grammatik zu kompilieren. Der Build-Stack-Trace ist fugly genug, um keinen Sinn für mich (trotz einiger ASSERTION_FAILED ich dort feststellen konnte, aber das hat nicht viele Informationen gebracht)

die Eingabegrammatik-Header:

inputGrammar.h

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;
//using namespace boost::spirit::arg_names;

namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;

using phoenix::at_c;
using phoenix::push_back;


template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {

    InputGrammar() : InputGrammar::base_type( block ) {
        tag = sp::lexeme[+(alpha)        [sp::_val += sp::_1]];//[+(char_ - '<')        [_val += _1]];

        block = sp::lit("block") [ at_c<0>(sp::_val) = sp::_1]
                >> "(" >> *instruction[ push_back( at_c<1>(sp::_val) , sp::_1 ) ]
                >> ")";

        command = tag   [ at_c<0>(sp::_val) = sp::_1]
                                >> "(" >> *instruction [ push_back( at_c<1>(sp::_val) , sp::_1 )]
                                >> ")";

        instruction = ( command | tag ) [sp::_val = sp::_1];
    }
    qi::rule< Iterator , std::string() , space_type > tag;
    qi::rule< Iterator , ExpressionAST() , space_type > block;
    qi::rule< Iterator , ExpressionAST() , space_type > function_def;
    qi::rule< Iterator , ExpressionAST() , space_type > command;
    qi::rule< Iterator , ExpressionAST() , space_type > instruction;
};

Sie den Test Build-Programm: i scheint die Build bei Qi :: phrase_parse ausfällt, ich bin mit Boost 1,43 und g ++ 4.4.1

#include <iostream>
#include <string>
#include <vector>
using namespace std;

//my grammar
#include <InputGrammar.h>

struct MockExpressionNode {
    std::string name;
    std::vector< MockExpressionNode > operands;

    typedef std::vector< MockExpressionNode >::iterator iterator;
    typedef std::vector< MockExpressionNode >::const_iterator const_iterator;

    iterator begin() { return operands.begin(); }
    const_iterator begin() const { return operands.begin(); }
    iterator end() { return operands.end(); }
    const_iterator end() const { return operands.end(); }

    bool is_leaf() const {
        return ( operands.begin() == operands.end() );
    }
};


BOOST_FUSION_ADAPT_STRUCT(
    MockExpressionNode,
    (std::string, name)
    (std::vector<MockExpressionNode>, operands)
)

int const tabsize = 4;

void tab(int indent)
{
    for (int i = 0; i < indent; ++i)
        std::cout << ' ';
}

template< typename ExpressionNode >
struct ExpressionNodePrinter
{
    ExpressionNodePrinter(int indent = 0)
      : indent(indent)
    {
    }

    void operator()(ExpressionNode const& node) const {
        cout << " tag: " << node.name << endl;
        for (int i=0 ; i < node.operands.size() ; i++ ) {
            tab( indent ); cout << " arg "<<i<<": "; ExpressionNodePrinter(indent + 2)( node.operands[i]); cout << endl;
        }
    }

    int indent;
};

int test() {
 MockExpressionNode root;
    InputGrammar< string::const_iterator , MockExpressionNode > g();
    std::string litA = "litA";
    std::string litB = "litB";
    std::string litC = "litC";
    std::string litD = "litD";
    std::string litE = "litE";
    std::string litF = "litF";
    std::string source = litA+"( "+litB+" ,"+litC+" , "+ litD+" ( "+litE+", "+litF+" ) "+ " )";
    string::const_iterator iter = source.begin();
    string::const_iterator end = source.end();
    bool r = qi::phrase_parse( iter , end , g , root , space );
    ExpressionNodePrinter< MockExpressionNode > np;
    np( root );
};

int main() {
   test();
}

schließlich der Build-Fehler ist die folgende:

/usr/bin/make -f nbproject/Makefile-linux_amd64_devel.mk SUBPROJECTS= .build-conf
make[1]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
/usr/bin/make  -f nbproject/Makefile-linux_amd64_devel.mk dist/linux_amd64_devel/GNU-Linux-x86/vpuinputparsertests
make[2]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
mkdir -p build/linux_amd64_devel/GNU-Linux-x86
rm -f build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d
g++ `llvm-config --cxxflags` `pkg-config --cflags unittest-cpp` `pkg-config --cflags boost-1.43` `pkg-config --cflags boost-coroutines`    -c -g -I../InputParser -MMD -MP -MF build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d -o build/linux_amd64_devel/GNU-Linux-x86/tests_main.o tests_main.cpp
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/auto.hpp:16,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi.hpp:15,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/qi.hpp:16,
                 from ../InputParser/InputGrammar.h:12,
                 from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp: In function ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/detail/parse_auto.hpp:14,
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:125:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::spirit::ascii::space_type]’
tests_main.cpp:206:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:99: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]::error_invalid_expression::************)(InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode> (*)()))’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:125:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::spirit::ascii::space_type]’
tests_main.cpp:206:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:100: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]::error_invalid_expression::************)(MockExpressionNode))’
                 from /home/mineq/third_party/boost_1_43_0/boost/proto/proto.hpp:12,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/support/meta_compiler.hpp:17,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/action/action.hpp:14,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/action.hpp:14,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi.hpp:14,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/qi.hpp:16,
                 from ../InputParser/InputGrammar.h:12,
                 from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/proto/detail/expr0.hpp: At global scope:
/home/mineq/third_party/boost_1_43_0/boost/proto/proto_fwd.hpp: In instantiation of ‘boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>()>, 0l>’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/proto/core.hpp:13,
/home/mineq/third_party/boost_1_43_0/boost/utility/enable_if.hpp:59:   instantiated from ‘boost::disable_if<boost::proto::result_of::is_expr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>()>, 0l>, void>, void>’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/support/meta_compiler.hpp:200:   instantiated from ‘boost::spirit::result_of::compile<boost::spirit::qi::domain, InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), boost::fusion::unused_type, void>’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:107:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:125:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::spirit::ascii::space_type]’
tests_main.cpp:206:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/proto/detail/expr0.hpp:64: error: field ‘boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>()>, 0l>::child0’ invalidly declared function type
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/auto.hpp:16,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi.hpp:15,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/qi.hpp:16,
                 from ../InputParser/InputGrammar.h:12,
                 from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp: In function ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/detail/parse_auto.hpp:14,
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:125:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::spirit::ascii::space_type]’
tests_main.cpp:206:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:107: error: request for member ‘parse’ in ‘boost::spirit::compile [with Domain = boost::spirit::qi::domain, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>()](((InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode> (&)())((InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode> (*)())expr)))’, which is of non-class type ‘InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>()’
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/auto.hpp:15,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi.hpp:15,
                 from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/qi.hpp:16,
                 from ../InputParser/InputGrammar.h:12,
                 from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/skip_over.hpp: In function ‘void boost::spirit::qi::skip_over(Iterator&, const Iterator&, const T&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, T = boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]::skipper_type]’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/auto/auto.hpp:19,
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:112:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag::enum_type, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/parse.hpp:125:   instantiated from ‘bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Expr = InputGrammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode>(), Skipper = MockExpressionNode, Attr = const boost::spirit::ascii::space_type]’
tests_main.cpp:206:   instantiated from here
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/skip_over.hpp:27: error: ‘const struct MockExpressionNode’ has no member named ‘parse’
make[2]: *** [build/linux_amd64_devel/GNU-Linux-x86/tests_main.o] Error 1
make[2]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make[1]: *** [.build-conf] Error 2
make[1]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1m 48s)
War es hilfreich?

Lösung

Das Attribut (e) immer als letzter Parameter übergeben werden muß (s) zu den Parse / phrase_parse Funktionen. So Sie schreiben müssen:

bool r = qi::phrase_parse( iter , end , g , space, root );

Darüber hinaus können Sie alle semantischen aus Ihrer Grammatik entfernen, wenn Sie auf den Typ ExpressionAST zusätzliche Konstrukteuren hinzufügen:

template< typename Iterator , typename ExpressionAST > 
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> { 

    InputGrammar() : InputGrammar::base_type( block ) { 
        tag = sp::lexeme[+(alpha)]; 
        block = sp::lit("block") >> "(" >> *instruction >> ")"; 
        command = tag >> "(" >> *instruction >> ")"; 
        instruction = ( command | tag ); 
    } 
    qi::rule< Iterator , std::string() , space_type > tag; 
    qi::rule< Iterator , ExpressionAST() , space_type > block; 
    qi::rule< Iterator , ExpressionAST() , space_type > function_def; 
    qi::rule< Iterator , ExpressionAST() , space_type > command; 
    qi::rule< Iterator , ExpressionAST() , space_type > instruction; 
};

und

struct MockExpressionNode { 
    // ...
    MockExpressionNode() {}
    MockExpressionNode(std::string name) : name(name) {}
    // ...
}; 

Aber selbst dann wird es nicht kompilieren, weil die MockExpressionNode Datenstruktur selbst rekursiv ist. Dies kann dadurch fixiert werden, um entweder einen Vektor von Zeigern zu speichern (die changethe Grammatik erfordert) oder durch Verwendung von boost :: recursive_wrapper .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top