#ifndef ARGUMENT_SEPARATOR_HPP__ #define ARGUMENT_SEPARATOR_HPP__ /** * \file argument_separator.hpp * contains the argument_separator class, which serves as the tokenizer function * for parsing instructions and execution signals */ namespace BMD { /** * Tokenizes instruction and execution signals. * argument_separator recognizes two major token types: * - symbols, any combination of characters except quotes, spaces, and commas * - quoted strings, which use '\' as an escape character * Tokens are separated by any number of spaces and commas, except obviously * for quoted characters of that type. */ class argument_separator { public: argument_separator() { } /** * retrieves the next token, moving the token iterator forward. */ template bool operator()(InputIterator& next,InputIterator end,Token& tok) { // move past any spaces tok = Token(); // move up until we get something that's not a space or comma while ((*next == ' ' || *next == ',') && next != end) ++next; if (next == end) return false; // if the first element isn't a quote, we should just read until we hit a // space or a comma if (*next != '"') { while (*next != ' ' && *next != ',') { tok += *next; if (++next == end) return true; } return true; } // if it is a quotation, keep reading in until we hit a quote, while // taking always munching the character after the escape character tok += *next; ++next; while (next != end && *next != '"') { // if it's not an escape character, read it if (*next != '\\') { tok += *next; ++next; continue; } // if it is an escape character, read it and the next character, being // sure to avoid going over tok += *next; ++next; if (next == end) throw instruction_parse_error("last token is string with no end-quote"); tok += *next; ++next; } // if we get here, our next character should be a quote // otherwise, we didn't finish the string if (next == end) throw instruction_parse_error("last token is string with no end-quote"); tok += *next; ++next; return true; } void reset() { } }; } #endif