C ++ carbon copy istream?

For my own small parser structure, I am trying to define (something like) the following function:

template <class T>
// with operator>>( std::istream&, T& )
void tryParse( std::istream& is, T& tgt )
{
    is >> tgt /* , *BUT* store every character that is consumed by this operation
    in some string. If afterwards, is.fail() (which should indicate a parsing
    error for now), put all the characters read back into the 'is' stream so that
    we can try a different parser. */
}

Then I could write something like this: (maybe not the best example)

/* grammar: MyData     = <IntTriple> | <DoublePair>
            DoublePair = <double> <double>
            IntTriple  = <int> <int> <int> */
class MyData
{ public:
    union { DoublePair dp; IntTriple it; } data;
    bool isDoublePair;
};

istream& operator>>( istream& is, MyData& md )
{
    /* If I used just "is >> md.data.it" here instead, the
       operator>>( ..., IntTriple ) might consume two ints, then hit an
       unexpected character, and fail, making it impossible to read these two
       numbers as doubles in the "else" branch below. */
    tryParse( is, md.data.it );
    if ( !is.fail() )
        md.isDoublePair = false;
    else
    {
        md.isDoublePair = true;
        is.clear();
        is >> md.data.dp;
    }
    return is;
}

Any help is greatly appreciated.

+5
source share
4 answers

Unfortunately, threads have only very minimal and rudimentary support.

, , , , , , . , .
, , , , . ( , .) :

class parse_buffer {
    friend class parse_state;
public:
    typedef std::string::size_type index_type;

    parse_buffer(std::istream& str);

    index_type get_current_index() const;
    void set_current_index(index_type) const;

    std::string get_next_string(bool skip_ws = true) const;
    char get_next_char(bool skip_ws = true);
    char peek_next_char(bool skip_ws = true); 

    std::string get_error_string() const; // returns string starting at error idx
    index_type get_error_index() const;
    void set_error_index(index_type);

    bool eof() const;

    // ...
};

class parse_state {
public:
    parse_state(parse_buffer&);
    ~parse_state();

    void commit();
    void rollback();

    // ...
};

. , . , , , , , , , , .

, , , . . parse_state , , - , ( get_error_string()).

, , . OTOH, , - , XPath, DOM, 3D-. XPath , . :)

+3

, . , , ( ) , . :

template <class T, class U>
bool tryParse( U & begin, U & end, T & target ) {
    // return true if parse was successful, false otherwise
}

istream , istream_iterator:

 std::vector< char > buffer(std::istream_iterator<char>(is), std::istream_iterator<char>());

.

+3

. unget() putback(somechar), , ( ).

, , .

+2

streambuf . , .

.

+1

All Articles