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__ |