diff --git a/parserMinimalExample/parserMinimalExample4.cpp b/parserMinimalExample/parserMinimalExample4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d335331cb3b2204961976064e3dfec84af0940c --- /dev/null +++ b/parserMinimalExample/parserMinimalExample4.cpp @@ -0,0 +1,90 @@ +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/qi_lit.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_fusion.hpp> +#include <boost/spirit/include/phoenix_stl.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/fusion/include/io.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> +#include <iostream> +#include <string> + +namespace qi = boost::spirit::qi; +namespace px = boost::phoenix; +namespace ascii = boost::spirit::ascii; + + +void +print (const std::string &s) +{ + std::cout << s << std::endl; +} + +typedef qi::rule<std::string::const_iterator,std::string(),qi::ascii::space_type> RuleType; +typedef RuleType* RuleTypePtr; + +template <typename Iterator> +struct dynamicParser : qi::grammar<Iterator,std::string(), boost::spirit::ascii::space_type> { + dynamicParser (std::vector<qi::rule<Iterator,std::string(), qi::ascii::space_type>* > rules) : dynamicParser::base_type(startRule) { + rulestack = rules; + startRule = *(rulestack.at(0)); + for (unsigned long int i=0; i < rulestack.size();i++) + qi::debug(*rulestack.at(i)); + qi::debug(startRule); + qi::on_error<qi::fail> + ( + startRule + , std::cout + << px::val("Error! Expecting ") + << qi::_4 // what failed? + << px::val(" here: \"") + << px::construct<std::string>(qi::_3, qi::_2) // iterators to error-pos, end + << px::val("\"") + << std::endl + ); + } + std::vector<qi::rule<Iterator,std::string(),qi::ascii::space_type>* > rulestack; + qi::rule<Iterator,std::string(), qi::ascii::space_type> startRule; +}; + +int +main (int argc, char** argv) { + std::vector<RuleTypePtr> myRuleVector; + myRuleVector.push_back (new RuleType(qi::eps));//This rule is going to get replaced + myRuleVector.push_back (new RuleType(qi::string("Hello")[print])); + myRuleVector.back()->name("Hello"); + myRuleVector.push_back (new RuleType(qi::string("Hi")[print])); + myRuleVector.back()->name("Hi"); + myRuleVector.push_back (new RuleType(qi::string("Whats up")[print])); + myRuleVector.back()->name("WU"); + + //Now magically compose a rule *with arbitrary vectorsize* + //I have no clue how to do this + //But it should result in: + + myRuleVector.at(0) = new RuleType (*myRuleVector.at(1)); + + for (int i=2; i < 4; i++) + (*myRuleVector.at(0)) = myRuleVector.at(0)->copy() > (*myRuleVector.at(i)); + myRuleVector.at(0)->name("startrule"); + dynamicParser<std::string::const_iterator> myDynamicParser(myRuleVector); + + std::string s ("Hello Hi Whats up"); + std::string attr; + + if (qi::phrase_parse ((std::string::const_iterator)s.begin(),(std::string::const_iterator)s.end(),myDynamicParser,ascii::space,attr)) + std::cout << "Parse success" << std::endl; + else + std::cout << "Parse failed" << std::endl; + // std::cout << "Result: "; + // for (std::vector<std::string>::const_iterator it=attr.begin(); it != attr.end(); it++) + // std::cout << "[" << (*it) << "] "; + // std::cout << std::endl; + return 0; +} + + diff --git a/pocketsphinxAdapter/src/JsgfParser.h b/pocketsphinxAdapter/src/JsgfParser.h index 7806c0bdba9d72c77179378123342dfa427d5cff..003313f9f3ea21a8e20bc1e8fa26642287884290 100644 --- a/pocketsphinxAdapter/src/JsgfParser.h +++ b/pocketsphinxAdapter/src/JsgfParser.h @@ -15,10 +15,12 @@ #include <boost/spirit/include/phoenix_object.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/spirit/include/phoenix_stl.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/io.hpp> #include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp> +#include <boost/bind.hpp> #include <iostream> #include <string> #include <map> @@ -27,7 +29,17 @@ namespace qi = boost::spirit::qi; namespace px = boost::phoenix; namespace ascii = boost::spirit::ascii; +void +print (const std::string &s) +{ + std::cout << s << std::endl; +} +void +printNonterminal (const std::string s1,const std::string s2) +{ + std::cout <<" s1='" << s1 << "' s2 = '" << s2 << "'" << std::endl; +} namespace jsgfParserTypes { @@ -284,7 +296,7 @@ namespace jsgfParserTypes { { if (0 == tl.symbols.at(i).type) { - myRules.push_back (new ruleT (qi::string(trim(tl.symbols.at(i).name))[qi::_val = px::val('<') + px::val(myNonterminal) + px::val('>') + px::val(trim(tl.symbols.at(i).name)) + px::val("</") + px::val(myNonterminal) + px::val('>')])); + myRules.push_back (new ruleT (qi::string(trim(tl.symbols.at(i).name))[print /*qi::_val = px::val('<') + px::val(myNonterminal) + px::val('>') + px::val(trim(tl.symbols.at(i).name)) + px::val("</") + px::val(myNonterminal) + px::val('>')*/])); (*myRules.back()).name(std::string("T:").append(trim(tl.symbols.at(i).name))); //std::cout << "Added qi::lexeme[" << trim(tl.symbols.at(i).name) << "][" << myNonterminal << "]"<< std::endl; } @@ -294,7 +306,7 @@ namespace jsgfParserTypes { if (pos != myNamesToRules.end()) { //std::cout << "Adding nonterminal '" << trim(tl.symbols.at(i).name) <<"' link to rule " << pos->second << std::endl; - myRules.push_back (new ruleT ((*myRules.at(pos->second))[qi::_val = px::val('<') + px::val(myNonterminal) + px::val('>') + qi::_1 + px::val("</") + px::val(myNonterminal) + px::val('>')])); + myRules.push_back (new ruleT ((*myRules.at(pos->second))[px::bind(&printNonterminal,trim(tl.symbols.at(i).name),qi::_1) /*qi::_val = px::val('<') + px::val(myNonterminal) + px::val('>') + qi::_1 + px::val("</") + px::val(myNonterminal) + px::val('>')*/])); (*myRules.back()).name(std::string("N:").append(trim(tl.symbols.at(i).name))); //std::cout << "done" << std::endl; } @@ -305,7 +317,7 @@ namespace jsgfParserTypes { } } } - ruleTPtr r = new ruleT ((*myRules.at(myRulesLocalStart))[qi::_val = qi::_1]/*[px::insert(qi::_val,px::end(qi::_val), px::begin(qi::_1), px::end(qi::_1))]*/); + ruleTPtr r = new ruleT ((*myRules.at(myRulesLocalStart))/*[px::insert(qi::_val,px::end(qi::_val), px::begin(qi::_1), px::end(qi::_1))]*/); r->name(myRules.at(myRulesLocalStart)->name()); for (std::vector<SymbolT>::size_type i=(myRulesLocalStart+1); i < myRules.size();i++) {