c – 提升精神和Lex解析器问题

c – 提升精神和Lex解析器问题,第1张

概述我一直在努力尝试(逐步)修改文档中的示例代码,但没有太大的不同,我没有得到我期望的行为.具体来说,“if”语句在(我的意图是)它应该传递时失败(有一个“else”但是在调试期间删除了部分解析器).赋值语句工作正常.我有一个“while”语句,它与“if”语句有同样的问题,所以我相信如果我能得到帮助来弄清楚为什么一个不工作它应该很容易让另一个去.它必须是一种微妙的,因为这几乎是逐字逐句的,其中一个例 我一直在努力尝试(逐步)修改文档中的示例代码,但没有太大的不同,我没有得到我期望的行为.具体来说,“if”语句在(我的意图是)它应该传递时失败(有一个“else”但是在调试期间删除了部分解析器).赋值语句工作正常.我有一个“while”语句,它与“if”语句有同样的问题,所以我相信如果我能得到帮助来弄清楚为什么一个不工作它应该很容易让另一个去.它必须是一种微妙的,因为这几乎是逐字逐句的,其中一个例子.
#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解析器问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1234582.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存