2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00
Files
spirit/example/application/cpp_lexer/cpp_lexer.hpp
2003-01-31 11:11:39 +00:00

115 lines
3.0 KiB
C++

//
// C++ Lexer implemented with Spirit (http://spirit.sourceforge.net/)
//
// Copyright© 2002 Juan Carlos Arevalo-Baeza, All rights reserved
// email: jcab@JCABs-Rumblings.com
// Created: 8-Nov-2002
//
// The basics:
// The lexer is an iterator that iterates over tokens generated on the fly
// from a text input.
// In order to use it, you create a "lex_iterator" object, and initialize it
// with the beginning and end iterators of the text input, and a string that
// represents the name of the input file (for inclusion into the tokens).
// This purposefully doesn't export any Spirit parser definitions, so access
// to the input sequence must be done through a generic run-time interface
// (virtual functions). The multi_pass iterator adapter helps handle this
// very well.
//
#ifndef cpp_lexer_hpp_included
#define cpp_lexer_hpp_included
#include "cpp_lexer_token.hpp"
#include <boost/spirit/iterator/multi_pass.hpp>
///////////////////////////////////////////////////////////////////////////////
// Lexer proper.
struct lex_input_interface {
protected:
virtual ~lex_input_interface() {}
public:
virtual void add_ref() = 0;
virtual void dec_ref() = 0;
virtual Token get() = 0;
virtual boost::spirit::file_position get_position() = 0;
Token const& eof();
};
lex_input_interface*
NewLexer(char const* first,
char const* last,
char const* fname = "<filename>");
struct lex_input_policy {
public:
typedef Token result_type;
lex_input_interface* interf;
lex_input_policy(lex_input_policy const& other):
interf(other.interf)
{
interf->add_ref();
}
lex_input_policy& operator=(lex_input_policy const& other)
{
if (other.interf != interf) {
other.interf->add_ref();
interf->dec_ref();
interf = other.interf;
}
return *this;
}
template < typename IteratorT >
lex_input_policy(IteratorT const& first,
IteratorT const& last,
char const* fname = "<filename>"):
interf(NewLexer(first, last, fname))
{
}
~lex_input_policy() {
interf->dec_ref();
}
result_type operator()() {
return interf->get();
}
static Token const eof;
};
struct lex_iterator:
boost::spirit::multi_pass<
lex_input_policy,
boost::spirit::multi_pass_policies::functor_input
/* ,
multi_pass_policies::first_owner,
multi_pass_policies::no_check,
multi_pass_policies::std_deque
*/
>
{
typedef boost::spirit::multi_pass<
lex_input_policy,
boost::spirit::multi_pass_policies::functor_input
> base_t;
typedef lex_iterator self_t;
lex_iterator() {}
template < typename IteratorT >
lex_iterator(IteratorT const& first,
IteratorT const& last,
char const* fname = "<filename>"):
base_t(lex_input_policy(first, last, fname))
{}
};
#endif