137 lines
3.0 KiB
C++

// tokeniser_state.hpp
// Copyright (c) 2005-2018 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LEXERTL_RE_TOKENISER_STATE_HPP
#define LEXERTL_RE_TOKENISER_STATE_HPP
#include "../../char_traits.hpp"
#include "../../enums.hpp"
#include <locale>
#include "../../narrow.hpp"
#include <stack>
namespace lexertl
{
namespace detail
{
template<typename ch_type, typename id_type>
struct basic_re_tokeniser_state
{
using char_type = ch_type;
using index_type = typename basic_char_traits<char_type>::index_type;
const char_type * const _start;
const char_type * const _end;
const char_type *_curr;
id_type _id;
std::size_t _flags;
std::stack<std::size_t> _flags_stack;
std::locale _locale;
const char_type *_macro_name;
long _paren_count;
bool _in_string;
id_type _nl_id;
basic_re_tokeniser_state(const char_type *start_,
const char_type * const end_, id_type id_, const std::size_t flags_,
const std::locale locale_, const char_type *macro_name_) :
_start(start_),
_end(end_),
_curr(start_),
_id(id_),
_flags(flags_),
_flags_stack(),
_locale(locale_),
_macro_name(macro_name_),
_paren_count(0),
_in_string(false),
_nl_id(static_cast<id_type>(~0))
{
}
basic_re_tokeniser_state(const basic_re_tokeniser_state &rhs_)
{
assign(rhs_);
}
// prevent VC++ 7.1 warning:
const basic_re_tokeniser_state &operator =
(const basic_re_tokeniser_state &rhs_)
{
return assign(rhs_);
}
basic_re_tokeniser_state &assign(const basic_re_tokeniser_state &rhs_)
{
_start = rhs_._start;
_end = rhs_._end;
_curr = rhs_._curr;
_id = rhs_._id;
_flags = rhs_._flags;
_flags_stack = rhs_._flags_stack;
_locale = rhs_._locale;
_macro_name = rhs_._macro_name;
_paren_count = rhs_._paren_count;
_in_string = rhs_._in_string;
_nl_id = rhs_._nl_id;
return *this;
}
inline bool next(char_type &ch_)
{
if (_curr >= _end)
{
ch_ = 0;
return true;
}
else
{
ch_ = *_curr;
increment();
return false;
}
}
inline void increment()
{
++_curr;
}
inline std::size_t index()
{
return _curr - _start;
}
inline bool eos()
{
return _curr >= _end;
}
inline void unexpected_end(std::ostringstream &ss_)
{
ss_ << "Unexpected end of regex";
}
inline void error(std::ostringstream &ss_)
{
ss_ << " in ";
if (_macro_name)
{
ss_ << "MACRO '";
narrow(_macro_name, ss_);
ss_ << "'.";
}
else
{
ss_ << "rule id " << _id << '.';
}
}
};
}
}
#endif