#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 );}
这是运行它的输出(读入字符串的文件首先在main中转出)
********************{ 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解决方法 问题是您将标记定义添加到词法分析器的顺序.你的代码
this->self += IDentifIEr | number | if_ | else_;
首先添加标识符标记,它将与’if'(和任何其他关键字)完全匹配.如果你改变它
this->self += if_ | else_ | IDentifIEr | number;
每一件事都应该开始发挥作用.
这对Spirit.Lex来说并不具体.任何标记化器都遵循定义标记的顺序以确定匹配的优先级.
总结以上是内存溢出为你收集整理的c – 提升精神和Lex解析器问题全部内容,希望文章能够帮你解决c – 提升精神和Lex解析器问题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)