| 23 |
|
|
| 24 |
#include <ecstacy/util/exception.hh> |
#include <ecstacy/util/exception.hh> |
| 25 |
#include <ecstacy/util/macros.hh> |
#include <ecstacy/util/macros.hh> |
| 26 |
|
#include <ecstacy/mem/shared_ptr.hh> |
| 27 |
|
|
| 28 |
#include <mpak/defs.hh> |
#include <mpak/defs.hh> |
| 29 |
|
#include <mpak/spec/lexer.hh> |
| 30 |
|
|
| 31 |
#include <list> |
#include <list> |
| 32 |
|
|
| 34 |
{ |
{ |
| 35 |
namespace spec |
namespace spec |
| 36 |
{ |
{ |
| 37 |
template<typename char_type_, typename traits_type_ = std::char_traits<_char_type> > |
template<typename char_type_, typename traits_type_ = std::char_traits<char_type_> > |
| 38 |
class basic_parser |
class basic_parser |
| 39 |
{ |
{ |
| 40 |
public: |
public: |
| 42 |
: public std::runtime_error |
: public std::runtime_error |
| 43 |
{ |
{ |
| 44 |
public: |
public: |
| 45 |
inline failure (void) |
inline failure (const std::string &what) |
| 46 |
throw ECSTACY_THROW_SPEC (()) |
ECSTACY_THROW_SPEC (()) |
| 47 |
|
: std::runtime_error (what) |
| 48 |
{ |
{ |
| 49 |
} |
} |
| 50 |
}; |
}; |
| 54 |
typedef typename traits_type_::int_type int_type; |
typedef typename traits_type_::int_type int_type; |
| 55 |
typedef traits_type_ traits_type; |
typedef traits_type_ traits_type; |
| 56 |
typedef std::basic_streambuf<char_type, traits_type> streambuf_type; |
typedef std::basic_streambuf<char_type, traits_type> streambuf_type; |
| 57 |
|
typedef mpak::spec::basic_lexer<char_type, traits_type> lexer_type; |
| 58 |
|
typedef typename lexer_type::token token_type; |
| 59 |
|
|
| 60 |
protected: |
struct parse_tree |
| 61 |
// whether the we are parsing a subfile or not. |
{ |
| 62 |
std::string filename_; |
}; |
| 63 |
mutable bool initialized_; |
|
| 64 |
|
private: |
| 65 |
|
struct symbol |
| 66 |
|
{ |
| 67 |
|
enum type_t { |
| 68 |
|
type_token, |
| 69 |
|
type_start, |
| 70 |
|
type_statement_list, |
| 71 |
|
type_statement, |
| 72 |
|
type_statement_end, |
| 73 |
|
type_command, |
| 74 |
|
type_assignment, |
| 75 |
|
type_argument_list, |
| 76 |
|
type_argument, |
| 77 |
|
type_block, |
| 78 |
|
}; |
| 79 |
|
|
| 80 |
|
type_t type; |
| 81 |
|
token_type token; |
| 82 |
|
|
| 83 |
|
symbol (const token_type &token) |
| 84 |
|
: type (type_token), |
| 85 |
|
token (token) |
| 86 |
|
{ |
| 87 |
|
} |
| 88 |
|
|
| 89 |
|
symbol (type_t type) |
| 90 |
|
: type (type), |
| 91 |
|
token () |
| 92 |
|
{ |
| 93 |
|
} |
| 94 |
|
}; |
| 95 |
|
|
| 96 |
protected: |
public: |
| 97 |
inline |
inline |
| 98 |
basic_parser (void) |
basic_parser (void) |
|
ECSTACY_THROW_SPEC (()) |
|
|
: initialized_ (false), |
|
| 99 |
{ |
{ |
| 100 |
} |
} |
| 101 |
|
|
| 102 |
inline |
inline ~basic_parser (void) |
|
basic_parser (const basic_parser &parser) |
|
| 103 |
ECSTACY_THROW_SPEC (()) |
ECSTACY_THROW_SPEC (()) |
|
: initialized_ (parser.initialized_) |
|
| 104 |
{ |
{ |
| 105 |
} |
} |
| 106 |
|
|
| 107 |
inline |
inline |
| 108 |
basic_parser (streambuf_type *buf, |
parse_tree parse (const std::string &filename) |
| 109 |
std::string filename) |
ECSTACY_THROW_SPEC ((failure)) |
|
: buf_ (buf), |
|
|
initialized_ (false), |
|
| 110 |
{ |
{ |
| 111 |
this->init (); |
lexer_type lexer (filename); |
| 112 |
|
return this->do_parse_ (lexer); |
| 113 |
} |
} |
| 114 |
|
|
| 115 |
inline |
inline |
| 116 |
basic_parser (std::string filename) |
parse_tree parse (const std::string &filename, |
| 117 |
: initialized_ (false), |
streambuf_type *buf) |
| 118 |
|
ECSTACY_THROW_SPEC ((failure)) |
| 119 |
{ |
{ |
| 120 |
|
lexer_type lexer (filename, buf); |
| 121 |
|
return this->do_parse_ (lexer); |
| 122 |
} |
} |
| 123 |
|
|
| 124 |
virtual ~basic_parser (void) ECSTACY_THROW_SPEC (()); |
private: |
| 125 |
|
basic_parser (const basic_parser &) |
|
inline basic_parser & |
|
|
operator= (const basic_parser &parser) |
|
|
ECSTACY_THROW_SPEC (()) |
|
| 126 |
{ |
{ |
|
this->filename_ = parser.filename_; |
|
|
return *this; |
|
| 127 |
} |
} |
| 128 |
|
|
| 129 |
void parse (void) |
basic_parser &operator = (const basic_parser &) |
| 130 |
ECSTACY_THROW_SPEC ((basic_parser::failure)); |
{ |
| 131 |
|
return *this; |
|
inline void |
|
|
init () |
|
|
const |
|
|
{ |
|
|
if (this->initialized_) |
|
|
return; |
|
|
if (this->buf_ == 0) { |
|
|
streambuf_type buf (this->filename_.c_str ()); |
|
|
this->buf_ = &file; |
|
|
this->parse (); |
|
|
thus->buf_ = 0; |
|
|
} else { |
|
|
this->parse (); |
|
|
} |
|
| 132 |
} |
} |
| 133 |
|
|
| 134 |
|
parse_tree do_parse_ (lexer_type &lexer) ECSTACY_THROW_SPEC ((failure)); |
| 135 |
}; |
}; |
| 136 |
|
|
| 137 |
typedef basic_parser<char, std::char_traits<char> > parser; |
typedef basic_parser<char, std::char_traits<char> > parser; |
| 138 |
typedef basic_parser<ecstacy::wchar_type, std::char_traits<wchar_type> >; |
typedef basic_parser<wchar_t, std::char_traits<wchar_t> > wparser; |
| 139 |
|
|
| 140 |
|
extern template class basic_parser<char>; |
| 141 |
|
extern template class basic_parser<wchar_t>; |
| 142 |
} |
} |
| 143 |
} |
} |
| 144 |
|
|
| 145 |
|
#include <mpak/spec/parser.tcc> |
| 146 |
|
|
| 147 |
#endif // ifndef __MPAK__PARSER_HH__ |
#endif // ifndef __MPAK__PARSER_HH__ |