/*

cls_2: Curl Like Syntax
Yauheni A. Akhotnikau (C) 2001-2003
eao197@yahoo.com
-------------------------------------------------

Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:

1. This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2. The origin of this software must not be misrepresented, either by
   explicit claim or by omission.

3. Altered versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

-------------------------------------------------

*/
/*!
	\file
	\brief Лексический анализатор.
*/

#if !defined( _CLS__LEX_HPP_ )
#define _CLS__LEX_HPP_

namespace cls_2 {

class	input_stream_t;
class	parser_context_t;

//
// Tokens
//
const int	c_tok_space = 1; // ' ', '\n', '\t', ...
const int	c_tok_nonspace = 2;
const int	c_tok_dquote = 3; // '\"'
const int	c_tok_open_block = 4; // '{'
const int	c_tok_close_block = 5; // '}'
const int	c_tok_eof = 6;
const int	c_tok_error = 7;
const int	c_tok_any = 8;

//
// lex_t
//

/*!
	\brief Лексический анализатор.
	
	Осуществляет лексический разбор входного потока на
	токены.
*/
class	lex_t
{
	public :
		//! Инициализирующий конструктор.
		lex_t( input_stream_t & stream );
		~lex_t();

		//! Взять следующий токен.
		/*
			\return c_ok, если следующий токен успешно извлечен.
		*/
		int
		get_tok(
			//! Контекст в котором осуществляется работа.
			parser_context_t & context,
			//! Приемник очередного токена.
			int & tok,
			//! Значение символа, который привел к появлению
			//! токена c_tok_nonspace.
			char & ch );

	protected :
		//! Входной поток.
		input_stream_t &	m_stream;

		//! Разбор последовательности, начинающейся с
		//! обратного слеша.
		/*!
			Допускаются последовательности:
			\\n \\r \\t \\\\ \\{ \\} \\| \\"
			\\xDD \\XDD \\oDDD \\ODDD
			\\bDDDDDDDD \\BDDDDDDDD.

			\return c_ok, если следующий токен успешно извлечен.
		*/
		int
		parse_back_slash_seq(
			//! Контекст в котором осуществляется работа.
			parser_context_t & context,
			//! Приемник очередного токена.
			int & tok,
			//! Значение символа, который привел к появлению
			//! токена c_tok_nonspace.
			char & ch );

		//! Разбор последовательности, начинающиейся с
		//! вертикальной черты.
		/*!
			Допускаются однострочный и многострочные комментарии.

			\return c_ok, если следующий токен успешно извлечен.
		*/
		int
		parse_vert_bar(
			parser_context_t & context,
			int & tok,
			char & ch );

		//! Пропустить однострочный комментарий.
		/*!
			\return c_ok, если следующий токен успешно извлечен.
		*/
		int
		skip_single_line_comment(
			parser_context_t & context );

		//! Пропустить многострочный комментарий.
		/*!
			\return c_ok, если следующий токен успешно извлечен.
		*/
		int
		skip_start_stop_comment(
			parser_context_t & context );

		//! Разбор специального представления символа.
		/*!
			\since v.2.6

			Выделяет из входного потока указанное количество
			символов, формирует представление, понятное для
			parse_digits. Осуществляет разбор с помощью
			parse_digits. Проверяет диапазон получившегося
			значения.

			\return c_ok, если разбор прошел успешно.
		*/
		int
		parse_spec_char_representation(
			//! Контекст в котором осуществляется работа.
			parser_context_t & context,
			//! Приемник очередного токена.
			int & tok,
			//! Значение символа, который привел к появлению
			//! токена c_tok_nonspace.
			char & ch,
			//! Символ, который означает систему счисления.
			char base_mark,
			//! Количество символов, которые нужно извлечь
			//! из входного потока.
			unsigned int char_count );
};

} /* namespace cls_2 */

#endif
