Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| SHA1 Hash: | ca08e3a704640f5ad6dac399b36c97df70952dc7 |
|---|---|
| Date: | 2008-06-21 10:57:43 |
| User: | stephan |
| Comment: | added missing include |
Tags And Properties
- branch=trunk inherited from [d45e7467f2]
- sym-trunk inherited from [d45e7467f2]
Changes
[hide diffs]Changes to parsepp.hpp
@@ -4,10 +4,11 @@
#include <map>
#include <string>
#include <cassert>
#include <iostream>
#include <sstream>
+#include <stdexcept>
#include <vector>
#include <list>
#include <set>
#include "parsepp_typelist.hpp"
@@ -189,26 +190,28 @@
- parse_iterators are read-only iterators. They cannot be used
to change their input.
*/
class parse_iterator : public std::iterator<std::input_iterator_tag,const std::string::value_type>
{
+ private:
+ static const int start_column = 1;
public:
typedef std::string::const_iterator iterator;
/**
Constructs an empty iterator, useful only as the target
of an assignment.
*/
- parse_iterator() : m_beg(), m_pos(), m_end(m_pos)
+ parse_iterator() : m_beg(), m_pos(), m_end(m_pos), m_line(1), m_col(start_column)
{}
/**
Constructs an iterator for the range [it,end). The string
pointed-to by (it,end) must not change (or otherwise
invalid the iterators) for the life of this object, or
undefined behaviour results.
*/
parse_iterator( iterator it, iterator end )
- : m_beg(it), m_pos(it), m_end(end)
+ : m_beg(it), m_pos(it), m_end(end), m_line(1), m_col(start_column)
{}
/**
Equivalent to the parse_iterator(in.begin(),in.end()).
Note that the input string must outlive this
@@ -215,11 +218,12 @@
iterator. Also, the string MUST NOT change for the life of
this iterator (and any copies of this iterator). Changing
the string invalidates all iterators.
*/
explicit parse_iterator( std::string const & in )
- : m_beg(in.begin()),m_pos(m_beg), m_end(in.end())
+ : m_beg(in.begin()),m_pos(m_beg), m_end(in.end()),
+ m_line(1), m_col(start_column)
{}
/**
Returns true if this object has been advanced
to its end iterator or if the current
@@ -273,13 +277,28 @@
input (i.e., ++iterator becomes a no-op once iterator.eof()
is true).
*/
parse_iterator & operator++()
{
- if( this->m_pos != this->m_end )
- {
- ++this->m_pos;
+ if( m_pos != m_end )
+ {
+ if( ++m_pos != m_end )
+ {
+ if('\n' == *m_pos)
+ {
+ m_line += 1;
+ m_col = 0;
+ }
+ else
+ {
+ ++m_col;
+ }
+ }
+ else
+ {
+ ++m_col; // for symmetry with op--
+ }
}
return *this;
}
/**
@@ -289,12 +308,12 @@
See the Prefix form for notes about advancing past the end
of the input.
*/
parse_iterator operator++(int)
{
- return ( this->m_pos != this->m_end )
- ? parse_iterator(this->m_pos++, this->m_end)
+ return (this->m_pos != this->m_end )
+ ? (++(parse_iterator(*this)))
: *this;
}
/**
Prefix decrement. Decrements the iternal iterator. It will
@@ -303,11 +322,33 @@
*/
parse_iterator & operator--()
{
if( this->m_pos != this->m_beg )
{
- --this->m_pos;
+ if( m_beg != --m_pos )
+ {
+ if('\n' == *m_pos)
+ {
+ m_line -= 1;
+ m_col = 0;
+ iterator it = m_pos;
+ --it;
+ for( ; it != m_beg; --it )
+ {
+ ++m_col;
+ if( '\n' == *it ) break;
+ }
+ }
+ else
+ {
+ --m_col;
+ }
+ }
+ else
+ {
+ m_col = 0;
+ }
}
return *this;
}
/** Postfix decrement. It will not decrement to a point
@@ -314,11 +355,11 @@
before begin().
*/
parse_iterator operator--(int)
{
return ( this->m_pos != this->m_beg )
- ? parse_iterator(this->m_pos--, this->m_end)
+ ? (--(parse_iterator(*this)))
: *this;
}
/**
Returns a copy of the pointed-to char, or 0 if
@@ -355,14 +396,33 @@
bool operator<( parse_iterator const & rhs ) const
{
return this->m_pos < rhs.m_pos;
}
+ /**
+ Returns the 1-based line number of this iterator. Counting starts
+ only at the begin iterator this object was initialized with, and is
+ updated via the ++/-- operators. If an itertor is used on a partial
+ range of input, the line/col numbers won't reflect those of the
+ whole input.
+ */
+ int line() const { return m_line; }
+ /**
+ Returns the 1-base column number of the input. When (*this == '\n')
+ then col() actually returns 0, as doing so simplifies the implementation
+ a good deal and seems to coincide with text editors which use row 1/col 1
+ as a starting point (as opposed to emacs, which uses row 1/col 0).
+ See line() for important caveats.
+ */
+ int col() const { return m_col; }
+
private:
iterator m_beg;
iterator m_pos;
iterator m_end;
+ int m_line;
+ int m_col;
};
/***
parser_state stores the "significant" information about a
parsing run, where "significant" means significant to the
@@ -597,12 +657,18 @@
class parse_error : public std::exception
{
private:
void calcWhere()
{
+ // these two options actually provide different column numbers:
+#if 0
int line = 1, col = 0;
calc_line_col( m_pos, line, col );
+#else
+ int line = m_pos.line();
+ int col = m_pos.col();
+#endif
std::ostringstream os;
os << "[line "<<line<<" col "<<col<<']';
m_where = (os.str());
}