I want to parse this line and storing all hex values in functor
<005F> <0061> [<00660066> <00660069> <00660066006C>]
this values in txt file and m reading this fill line by line
like
005F 0061 00660066 00660069 00660066006C
all values should be in vector but its not working
the spirit rule is to parse this line is
rule<> blanks = *blank_p;
rule<> parse_int = blanks >> "<" >> int_p [AddEntry] >> ">";
rule<> parse_ints = *parse_int ;
rule<> parse_range = *parse_int >>"[" >> blanks >> *parse_int >> "]";
int status = parse (line.c_str(),
*(
parse_range
)
).full;
and my functor is this
struct AddEntry
{
vector<int> list;
void operator()( int integer)
{
list.push_back(integer);
}
};
Here's a sample doing this using Spirit V2
Live On Coliru
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
typedef std::string::const_iterator It;
std::string const line = "<005F> <0061> [<00660066> <00660069> <00660066006C>]";
It f = line.begin(), l = line.end();
qi::int_parser<uintmax_t, 16> hex_int;
qi::rule<It, uintmax_t()> braced_hex = '<' >> hex_int >> '>';
BOOST_SPIRIT_DEBUG_NODE(braced_hex);
std::vector<uintmax_t> list;
bool result = qi::phrase_parse(f, l, *braced_hex >> '[' >> *braced_hex >> ']', qi::space, list);
if (result) {
std::cout << "Parse success: " << list.size() << "\n";
for (auto& v : list)
std::cout << v << " ";
}
else {
std::cout << "Parse failed\n";
}
if (f!=l) {
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
Output:
Parse success: 5
95 97 6684774 6684777 438093348972
Debug output (if enabled):
<braced_hex>
<try><005F> <0061> [<0066</try>
<success> <0061> [<00660066> </success>
<attributes>[95]</attributes>
</braced_hex>
<braced_hex>
<try><0061> [<00660066> <</try>
<success> [<00660066> <006600</success>
<attributes>[97]</attributes>
</braced_hex>
<braced_hex>
<try>[<00660066> <0066006</try>
<fail/>
</braced_hex>
<braced_hex>
<try><00660066> <00660069</try>
<success> <00660069> <0066006</success>
<attributes>[6684774]</attributes>
</braced_hex>
<braced_hex>
<try><00660069> <00660066</try>
<success> <00660066006C>]</success>
<attributes>[6684777]</attributes>
</braced_hex>
<braced_hex>
<try><00660066006C>]</try>
<success>]</success>
<attributes>[438093348972]</attributes>
</braced_hex>
<braced_hex>
<try>]</try>
<fail/>
</braced_hex>
Note that on my system int
wasn't big enough to hold those numbers, so parse would fail. For maximum range I used intmax_t
but you can use other types, including arbitrary precision types:
- 128 bit string to array using boost::spirit::*
Also note I prefer not to use semantic actions, using automatic attribute propagation. This is really prevalent in Spirit V2. See also
- Boost Spirit: "Semantic actions are evil"?