From 102992da75edfcb671eb408bd801703a3f9137d0 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Wed, 5 Jan 2011 00:23:40 +0100 Subject: Replaced regex parser in telnet::Connection::parse_args() with a spirit-based parser. --- telnet_connection.cpp | 43 +++++++++++++++++-------------------------- telnet_connection.h | 2 +- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/telnet_connection.cpp b/telnet_connection.cpp index 8d6675d..9eeecdf 100644 --- a/telnet_connection.cpp +++ b/telnet_connection.cpp @@ -3,11 +3,12 @@ #include #include -#include -#include +#include #include +namespace qi = boost::spirit::qi; + telnet::Connection::Connection(boost::asio::io_service& io_service) : socket(io_service) { } @@ -25,9 +26,10 @@ void telnet::Connection::handle_read(const boost::system::error_code& error, siz return; } - std::vector args = parse_args(line); - // no arguments, i.e. empty line - if(!args.size()) { + std::vector args; + + // failed to parse or no arguments, i.e. empty line + if(!parse_args(line, args) || !args.size()) { start(); return; } @@ -54,27 +56,16 @@ void telnet::Connection::handle_read(const boost::system::error_code& error, siz /** Parse a given line and return a vector with its arguments. * Arguments which are surrounded by "quotes" are interpreted as a single argument. */ -std::vector telnet::Connection::parse_args(std::string& line) { - std::string::const_iterator begin = line.begin(); - std::string::const_iterator end = line.end(); - - boost::regex re("(\")?((?(1)[^\"]|[^ ])+)(?(1)\")"); - boost::match_results what; - boost::match_flag_type flags = boost::match_default; - - std::vector args; - - while(boost::regex_search(begin, end, what, re, flags)) { - std::string s = std::string(what[2].first, what[2].second); - boost::algorithm::trim(s); - // avoid empty strings when parsing multi-word arguments (a "b c") - if(s.size()) { - args.push_back(s); - } - begin = what[0].second; - } - - return args; +bool telnet::Connection::parse_args(std::string& line, std::vector& args) { + std::string::const_iterator begin = line.begin(), end = line.end(); + + return qi::parse(begin, end, + // find "words in quotes" + (('"' >> *(qi::char_ - '"') >> '"') | + // single words + *(qi::char_ - ' ')) % + // skip spaces between arguments + +qi::char_(' '), args); } void telnet::Connection::start() { diff --git a/telnet_connection.h b/telnet_connection.h index 68d652e..2109b05 100644 --- a/telnet_connection.h +++ b/telnet_connection.h @@ -16,7 +16,7 @@ namespace telnet { private: Connection(boost::asio::io_service& io_service); void handle_read(const boost::system::error_code& error, size_t bytes_transferred); - std::vector parse_args(std::string& line); + bool parse_args(std::string& line, std::vector& args); tcp::socket socket; boost::asio::streambuf buf; -- cgit v1.2.3