id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 12497,Errors with QI and Karma rules managing 64 bit integers,Gilles Brunet ,Joel de Guzman,"MSVC++ 14 used to build the following source code enclosing a trio of spirit components (Lex, QI and Karma) performing three steps: 1. Uses “Spirit Lex” to make tokens from input text; 1. Uses “Spirit QI” for parsing tokens to generate an AST; and 1. Uses “Spirit Karma” for generating back the original text. The “QI” and “Karma” grammars are compiling and running fine with tokens enclosing 32 bit integers. However, the compiler generates thousands of errors with tokens enclosing 64 bit integers. For reproducing the problem, we move comments in front of the alias type named “int_lit_type” for defining it as a 64-bit integer. The code compiles and runs fine with 32 bit integers, and do not compile with 64 bit ones. The same result carried out whenever the compiler is configured for targeting “x86” or “x64”. Here is the source code: {{{ #include #include #include #include #include #include #include #include #include #include namespace spirit = boost::spirit; namespace phoenix = boost::phoenix; namespace lex = spirit::lex; namespace qi = spirit::qi; namespace karma = spirit::karma; /////////////////////////////////// // Lexer using real_lit_type = long double; //using int_lit_type = long; using int_lit_type = std::int32_t; //using int_lit_type = long long; //using int_lit_type = std::int64_t; template struct lexer_grammar : lex::lexer { lexer_grammar() : int_lit{""[0-9]+""} , real_lit{""[0-9]+\\.([0-9]+([Ee][\\-\\+]?[0-9]*)?)?""} , identifier{""[_a-zA-Z][_a-zA-Z0-9]*""} { this->self = lex::token_def<>(""[ \\t\\n\\r]+"")[lex::_pass = lex::pass_flags::pass_ignore] | real_lit | int_lit | identifier | lex::token_def<>('(') | ')' | '=' | ';'; } lex::token_def real_lit; lex::token_def int_lit; lex::token_def identifier; }; template struct tokens_factory { using iterator_type = Iterator; using value_type = boost::mpl::vector; using token_type = lex::lexertl::token; using lexer_type = lexer_grammar>; }; /////////////////////////////////// // AST namespace ast { using literal_type = boost::variant; using identifier_type = std::string; using expr_type = boost::variant; struct assign_stmt_type { assign_stmt_type() {} template explicit assign_stmt_type(const Stmt& stmt); identifier_type var_ref; expr_type expr; }; using stmt_type = boost::variant; using stmt_list_type = std::vector; template <> inline assign_stmt_type::assign_stmt_type(const stmt_type& stmt) { *this = boost::get(stmt); } } BOOST_FUSION_ADAPT_STRUCT( ast::assign_stmt_type, var_ref, expr ) template struct parser_grammar : qi::grammar { explicit parser_grammar(const Lexer& tokens) : parser_grammar::base_type{stmt_list} { stmt_list = *(stmt >> ';'); stmt = assign_stmt; assign_stmt = var_ref_expr >> '=' >> expr; expr = ('(' >> expr >> ')') | var_ref_expr | literal_expr; var_ref_expr = tokens.identifier; literal_expr = tokens.int_lit | tokens.real_lit; } qi::rule stmt_list; qi::rule stmt; qi::rule assign_stmt; qi::rule expr; qi::rule var_ref_expr; qi::rule literal_expr; }; /////////////////////////////////// // Generator template struct generator_grammar : karma::grammar { generator_grammar() : generator_grammar::base_type(stmt_list) { stmt_list = *(stmt << karma::lit(';') << karma::eol); stmt = assign_stmt; assign_stmt = var_ref_expr << karma::lit("" = "") << expr; expr = var_ref_expr | literal_expr; var_ref_expr = karma::string; literal_expr = int_literal_expr | real_literal_expr; int_literal_expr = karma::long_long | karma::long_; real_literal_expr = karma::long_double; } karma::rule stmt_list; karma::rule stmt; karma::rule assign_stmt; karma::rule expr; karma::rule var_ref_expr; karma::rule literal_expr; karma::rule int_literal_expr; karma::rule real_literal_expr; }; /////////////////////////////////// // main int main() { static const auto text = std::string{ ""var1 = 25.3;\n"" ""var2 = 455;\n"" ""var3 = var2;"" }; using lexer_type = tokens_factory::lexer_type; lexer_type lexer{}; auto tokens = std::vector{}; parser_grammar parser{lexer}; auto it = text.begin(); auto lex_it = lexer.begin(it, text.end()); auto lex_end = lexer.end(); auto stmt_list = ast::stmt_list_type{}; auto parser_success = qi::parse(lex_it, lex_end, parser, stmt_list); if (parser_success) { std::cout << ""parser success. Then, generates back the source."" << std::endl << std::endl; using output_iterator_type = std::back_insert_iterator; using generator_type = generator_grammar; std::string generated; output_iterator_type outit(generated); generator_type generator{}; auto generator_success = karma::generate(outit, generator, stmt_list); if (generator_success) { std::cout << ""generator success:"" << std::endl << generated << std::endl; } else std::cout << ""generator failure"" << std::endl; } else std::cout << ""parser failure"" << std::endl; return 0; } }}} ",Bugs,closed,To Be Determined,spirit,Boost 1.61.0,Showstopper,fixed,,