我一直在努力尝试和(增量)从文档,但没有太大的不同,我没有得到我预期的行为修改示例代码。特别是,当if(我的意图是)它应该传递时(有一个“else”但解析器的那部分在调试期间被移除)时,“if”语句失败。赋值语句正常工作。我有一个“while”语句,它与“if”语句具有相同的问题,所以我相信如果我能找到帮助来弄清楚为什么一个人不工作,应该很容易让其他人去做。它必须有点微妙,因为这几乎是逐字的例子之一。升压精神和Lex解析器问题
#include <iostream>
#include <fstream>
#include <string>
#define BOOST_SPIRIT_DEBUG
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
namespace qi = boost::spirit::qi;
namespace lex = boost::spirit::lex;
inline std::string read_from_file(const char* infile)
{
std::ifstream instream(infile);
if(!instream.is_open())
{
std::cerr << "Could not open file: \"" << infile << "\"" << std::endl;
exit(-1);
}
instream.unsetf(std::ios::skipws);
return(std::string(
std::istreambuf_iterator<char>(instream.rdbuf()),
std::istreambuf_iterator<char>()
));
}
template< typename Lexer >
struct LangLexer : lex::lexer<Lexer>
{
LangLexer()
{
identifier = "[a-zA-Z][a-zA-Z0-9_]*";
number = "[-+]?(\\d*\\.)?\\d+([eE][-+]?\\d+)?";
if_ = "if";
else_ = "else";
this->self = lex::token_def<> ('(') | ')' | '{' | '}' | '=' | ';';
this->self += identifier | number | if_ | else_;
this->self("WS") = lex::token_def<>("[ \\t\\n]+");
}
lex::token_def<> if_, else_;
lex::token_def<std::string> identifier;
lex::token_def<double> number;
};
template< typename Iterator, typename Lexer >
struct LangGrammar : qi::grammar< Iterator, qi::in_state_skipper<Lexer> >
{
template< typename TokenDef >
LangGrammar(const TokenDef& tok) : LangGrammar::base_type(program)
{
using boost::phoenix::val;
using boost::phoenix::ref;
using boost::phoenix::size;
program = +block;
block = '{' >> *statement >> '}';
statement = assignment | if_stmt;
assignment = (tok.identifier >> '=' >> expression >> ';');
if_stmt = (tok.if_ >> '(' >> expression >> ')' >> block);
expression = (tok.identifier[ qi::_val = qi::_1 ] | tok.number[ qi::_val = qi::_1 ]);
BOOST_SPIRIT_DEBUG_NODE(program);
BOOST_SPIRIT_DEBUG_NODE(block);
BOOST_SPIRIT_DEBUG_NODE(statement);
BOOST_SPIRIT_DEBUG_NODE(assignment);
BOOST_SPIRIT_DEBUG_NODE(if_stmt);
BOOST_SPIRIT_DEBUG_NODE(expression);
}
qi::rule< Iterator, qi::in_state_skipper<Lexer> > program, block, statement;
qi::rule< Iterator, qi::in_state_skipper<Lexer> > assignment, if_stmt;
typedef boost::variant< double, std::string > expression_type;
qi::rule< Iterator, expression_type(), qi::in_state_skipper<Lexer> > expression;
};
int main(int argc, char** argv)
{
typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token< base_iterator_type, boost::mpl::vector< double, std::string > > token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;
typedef LangLexer<lexer_type> LangLexer;
typedef LangLexer::iterator_type iterator_type;
typedef LangGrammar< iterator_type, LangLexer::lexer_def > LangGrammar;
LangLexer lexer;
LangGrammar grammar(lexer);
std::string str(read_from_file(1 == argc ? "boostLexTest.dat" : argv[1]));
base_iterator_type strBegin = str.begin();
iterator_type tokenItor = lexer.begin(strBegin, str.end());
iterator_type tokenItorEnd = lexer.end();
std::cout << std::setfill('*') << std::setw(20) << '*' << std::endl <<
str
<< std::endl << std::setfill('*') << std::setw(20) << '*' << std::endl;
bool result = qi::phrase_parse(tokenItor, tokenItorEnd, grammar, qi::in_state("WS")[ lexer.self ]);
if(result)
{
std::cout << "Parsing successful" << std::endl;
}
else
{
std::cout << "Parsing error" << std::endl;
}
return(0);
}
这里是运行这个输出(读入字符串的文件是在主首先倾倒出来)
********************
{
a = 5;
if(a){ b = 2; }
}
********************
<program>
<try>{</try>
<block>
<try>{</try>
<statement>
<try></try>
<assignment>
<try></try>
<expression>
<try></try>
<success>;</success>
<attributes>(5)</attributes>
</expression>
<success></success>
<attributes>()</attributes>
</assignment>
<success></success>
<attributes>()</attributes>
</statement>
<statement>
<try></try>
<assignment>
<try></try>
<fail/>
</assignment>
<if_stmt>
<try>
if(</try>
<fail/>
</if_stmt>
<fail/>
</statement>
<fail/>
</block>
<fail/>
</program>
Parsing error
你的男人哈特穆特!我希望你或乔尔能够做到这一点。我没有意识到它们的添加顺序与令牌解析的优先顺序有关。顺便说一句,您是否知道使用版本2语法的任何全新解决方案?我在Spirit Applications Repository中看到的大多数示例都使用旧的语法。另外,是否有直接链接到您的“示例”文件(例如,http://www.boost.org/doc/libs/1_42_0/libs/spirit/example/lex/example#.cpp)? – bpw1621 2010-05-04 18:22:24
您的意思是:http://svn.boost.org/svn/boost/trunk/libs/spirit/example/? – hkaiser 2010-05-05 00:18:25