編輯:我已經撕掉了詞法分析器,因爲它不能與Qi完全整合,只是混淆了語法(請參閱here)。助力精神lex和qi。集成一個跳過語法分析器
我想在精神lex框架之上增長一個語法。當我嘗試將一個跳過解析器移入語法時,我開始出現錯誤。
因此,將qi::grammar<>
和qi::rule<> event
簽名從<Iterator>
更改爲<Iterator,void(),ascii::space_type>
。在語法結構中。我需要做什麼?
此外,我已設置token_def
以省略其屬性optional
令牌和其他一些。爲什麼它仍然爲詞法分析器中的可選語義動作提供有效的_val
?我想問的原因是因爲我認爲問題必須與qi中的事件規則的rhs上的可選標記的字符串屬性無關,而與規則的屬性簽名不一致。
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>
namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
tokens()
: left_paranthesis("\"{\""),
right_paranthesis("\"}\""),
colon(":"),
namespace_("(?i:namespace)"),
event("(?i:event)"),
optional("(?i:optional)"),
required("(?i:required)"),
ordinal("\\d+"),
identifier("\\w+")
{
using boost::spirit::lex::_val;
this->self
= " "
| left_paranthesis [ std::cout << px::val("lpar") << std::endl]
| right_paranthesis [ std::cout << px::val("rpar") << std::endl]
| colon [ std::cout << px::val("colon") << std::endl]
| namespace_ [ std::cout << px::val("kw namesapce") << std::endl]
| event [ std::cout << px::val("kw event") << std::endl]
| optional [ std::cout << px::val("optional ") << "-->" << _val << "<--" << std::endl]
| required [ std::cout << px::val("required") << std::endl]
| ordinal [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
| identifier [std::cout << px::val("val identifier(") << _val << ")" << std::endl];
}
lex::token_def<> left_paranthesis, right_paranthesis, colon;
lex::token_def<lex::omit> namespace_, event, optional, required;
lex::token_def<boost::uint32_t> ordinal;
lex::token_def<> identifier;
};
template <typename Iterator>
struct grammar : qi::grammar<Iterator>
{
template <typename TokenDef>
grammar(TokenDef const& tok)
: grammar::base_type(event)
{
//start = event;
event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
}
qi::rule<Iterator> start;
qi::rule<Iterator> event;
};
// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";
std::string test = "OPTIONAL";
int main()
{
typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
typedef tokens<lexer_type>::iterator_type iterator_type;
tokens<lexer_type> token_lexer;
grammar<iterator_type> grammar(token_lexer);
std::string::iterator first = test.begin();
std::string::iterator last = test.end();
bool r;
r = lex::tokenize_and_parse(first, last, token_lexer, grammar);
if(r)
;
else
{
std::cout << "parsing failed" << std::endl;
}
/*
lexer_type::iterator_type iter;
try
{
iter = token_lexer.begin(first,last);
}
catch(std::exception & e)
{
std::cout << e.what() << std::endl;
}
lexer_type::iterator_type end = token_lexer.end();
while (iter != end && token_is_valid(*iter))
++iter;
*/
}
此語法失敗:
template <typename Iterator>
struct grammar : qi::grammar<Iterator,void(),ascii::space_type>
{
template <typename TokenDef>
grammar(TokenDef const& tok)
: grammar::base_type(event)
{
//start = event;
event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
}
qi::rule<Iterator> start;
qi::rule<Iterator,void(),ascii::space_type> event;
};
但是,'lex :: pass_flags :: pass_ignore'完全記錄符合法案。問題是,你不需要傳統的船長。 – sehe
是的,說實話,這種做事方式讓語法比以前更乾淨。如果我使用'pass_ignore',我想我甚至不必跳過語法中的'qi :: in_state_skipper <>'圈,詞法分析器會默默地跳過WS令牌? –
尋找[由sehe](http://stackoverflow.com/search?q=user:85371+ [boost-spirit])提供的大量優秀(和可悲的低估)精神相關答案總是一個好主意。這個網站。 [這個特別](http://stackoverflow.com/search?q=user%3A85371+ [boost-spirit] + lex +隊長)似乎是合適的。 – llonesmiz