//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(_ATF_CXX_PARSER_HPP_)
#define _ATF_CXX_PARSER_HPP_
#include <istream>
#include <map>
#include <ostream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace atf {
namespace parser {
// ------------------------------------------------------------------------
// The "parse_error" class.
// ------------------------------------------------------------------------
public:
~parse_error(void) throw();
const char* what(void) const throw();
};
// ------------------------------------------------------------------------
// The "parse_errors" class.
// ------------------------------------------------------------------------
public:
parse_errors(void);
~parse_errors(void) throw();
const char* what(void) const throw();
};
// ------------------------------------------------------------------------
// The "format_error" class.
// ------------------------------------------------------------------------
public:
};
// ------------------------------------------------------------------------
// The "token" class.
// ------------------------------------------------------------------------
typedef int token_type;
//!
//! \brief Representation of a read token.
//!
//! A pair that contains the information of a token read from a stream.
//! It contains the token's type and its associated data, if any.
//!
struct token {
bool m_inited;
public:
token(void);
const token_type& type(void) const;
operator bool(void) const;
bool operator!(void) const;
};
// ------------------------------------------------------------------------
// The "tokenizer" class.
// ------------------------------------------------------------------------
//!
//! \brief A stream tokenizer.
//!
//! This template implements an extremely simple, line-oriented stream
//! tokenizer. It is only able to recognize one character-long delimiters,
//! random-length keywords, skip whitespace and, anything that does not
//! match these rules is supposed to be a word.
//!
//! Parameter IS: The input stream's type.
//!
template< class IS >
class tokenizer {
bool m_skipws;
char m_quotech;
token_type alloc_type(void);
template< class TKZ >
friend
class parser;
public:
void add_delim(char, const token_type&);
void add_quote(char, const token_type&);
};
template< class IS >
bool p_skipws,
const token_type& p_eof_type,
const token_type& p_nl_type,
const token_type& p_text_type,
m_quotech(-1)
{
}
template< class IS >
const
{
return m_lineno;
}
template< class IS >
void
{
m_delims_str += delim;
}
template< class IS >
void
const token_type& type)
{
}
template< class IS >
void
{
m_quotetype = type;
}
template< class IS >
{
if (m_la) {
m_lineno++;
return t;
}
char ch;
bool escaped = false;
if (!escaped) {
if (ch == '\\')
escaped = true;
else if (ch == '\n') {
throw parse_error(t.lineno(),
"Missing double quotes before "
"end of line");
done = true;
else
} else {
escaped = false;
}
}
throw parse_error(t.lineno(),
"Missing double quotes before "
"end of file");
quoted = true;
} else {
done = true;
}
} else {
done = true;
else
} else if (ch == '\n') {
done = true;
else
done = true;
} else
}
}
else
}
m_lineno++;
return t;
}
template< class IS >
{
return str;
}
// ------------------------------------------------------------------------
// The "parser" class.
// ------------------------------------------------------------------------
template< class TKZ >
class parser {
bool m_thrown;
public:
~parser(void);
bool good(void) const;
void add_error(const parse_error&);
bool has_errors(void) const;
expect(const token_type&,
expect(const token_type&,
const token_type&,
expect(const token_type&,
const token_type&,
const token_type&,
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
expect(const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
const token_type&,
};
template< class TKZ >
m_thrown(false)
{
}
template< class TKZ >
{
throw m_errors;
}
template< class TKZ >
bool
const
{
}
template< class TKZ >
void
{
}
template< class TKZ >
bool
const
{
}
template< class TKZ >
{
m_last = t;
m_thrown = true;
throw m_errors;
}
}
return t;
}
template< class TKZ >
{
return m_tkz.rest_of_line();
}
template< class TKZ >
{
t = next();
return t;
}
template< class TKZ >
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
const token_type& t2,
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
const token_type& t2,
const token_type& t3,
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
const token_type& t2,
const token_type& t3,
const token_type& t4,
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
const token_type& t2,
const token_type& t3,
const token_type& t4,
const token_type& t5,
const token_type& t6,
const token_type& t7,
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
template< class TKZ >
const token_type& t2,
const token_type& t3,
const token_type& t4,
const token_type& t5,
const token_type& t6,
const token_type& t7,
const token_type& t8,
{
throw parse_error(t.lineno(),
"Unexpected token `" + t.text() +
"'; expected " + textual);
return t;
}
do { \
if (!(parser).has_errors()) \
func; \
} while (false)
// ------------------------------------------------------------------------
// Header parsing.
// ------------------------------------------------------------------------
class header_entry {
public:
header_entry(void);
};
} // namespace parser
} // namespace atf
#endif // !defined(_ATF_CXX_PARSER_HPP_)