115 |
// block: - - - 14 - - - - - |
// block: - - - 14 - - - - - |
116 |
// assignment: - 15 - - - - - - - |
// assignment: - 15 - - - - - - - |
117 |
// |
// |
118 |
|
|
119 |
#ifndef __MPAK__PARSER_TCC__ |
#ifndef __MPAK__PARSER_TCC__ |
120 |
#define __MPAK__PARSER_TCC__ |
#define __MPAK__PARSER_TCC__ |
121 |
|
|
123 |
|
|
124 |
#include <stdexcept> |
#include <stdexcept> |
125 |
#include <stack> |
#include <stack> |
126 |
|
#include <iostream> |
127 |
|
|
128 |
#include <ecstacy/util/macros.hh> |
#include <ecstacy/util/macros.hh> |
129 |
|
|
136 |
basic_parser<char_type_, traits_type_>::do_parse_ (basic_parser<char_type_,traits_type_>::lexer_type &lexer) |
basic_parser<char_type_, traits_type_>::do_parse_ (basic_parser<char_type_,traits_type_>::lexer_type &lexer) |
137 |
ECSTACY_THROW_SPEC ((basic_parser<char_type_, traits_type_>::failure)) |
ECSTACY_THROW_SPEC ((basic_parser<char_type_, traits_type_>::failure)) |
138 |
{ |
{ |
139 |
|
using namespace ecstacy::mem; |
140 |
|
|
141 |
|
shared_ptr<tree> ret (new tree); |
142 |
|
ret->start.reset (new start_node); |
143 |
|
|
144 |
std::stack<symbol> symbol_stack; |
std::stack<symbol> symbol_stack; |
145 |
symbol_stack.push (symbol (token_type (token_type::type_eof))); |
shared_ptr<token_node> eof_node (new token_node (token_type (token_type::type_eof))); |
146 |
symbol_stack.push (symbol (symbol::type_start)); |
symbol_stack.push (symbol (symbol::type_token, eof_node)); |
147 |
|
symbol_stack.push (symbol (symbol::type_start, ret->start)); |
148 |
token_type token (lexer.next_token ()); |
token_type token (lexer.next_token ()); |
149 |
|
|
150 |
do { |
while (!symbol_stack.empty ()) { |
151 |
symbol top = symbol_stack.top (); |
symbol top = symbol_stack.top (); |
152 |
|
|
153 |
switch (top.type) { |
switch (top.type) { |
154 |
case symbol::type_token: |
case symbol::type_token: |
155 |
if (top.token.type == token.type) { |
{ |
156 |
symbol_stack.pop (); |
shared_ptr<token_node> token_n = dynamic_pointer_cast<token_node> (top.node); |
157 |
token = lexer.next_token (); |
if (token_n->type == token.type) { |
158 |
} else { |
*token_n = token; |
159 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
symbol_stack.pop (); |
160 |
|
token = lexer.next_token (); |
161 |
|
} else { |
162 |
|
ecstacy::util::throw_exception (failure ("unrecognized token")); |
163 |
|
} |
164 |
} |
} |
165 |
break; |
break; |
166 |
|
|
171 |
case token_type::type_semicolon: |
case token_type::type_semicolon: |
172 |
case token_type::type_endl: |
case token_type::type_endl: |
173 |
case token_type::type_eof: |
case token_type::type_eof: |
174 |
// start -> statement_list |
{ |
175 |
symbol_stack.pop (); |
// 1. start -> statement_list |
176 |
symbol_stack.push (symbol::type_statement_list); |
shared_ptr<start_node> start = dynamic_pointer_cast<start_node> (top.node); |
177 |
|
start->production = 1; |
178 |
|
start->statement_list.reset (new statement_list_node ()); |
179 |
|
symbol_stack.pop (); |
180 |
|
symbol_stack.push (symbol (symbol::type_statement_list, start->statement_list)); |
181 |
|
} |
182 |
break; |
break; |
183 |
default: |
default: |
184 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
191 |
case token_type::type_identifier: |
case token_type::type_identifier: |
192 |
case token_type::type_semicolon: |
case token_type::type_semicolon: |
193 |
case token_type::type_endl: |
case token_type::type_endl: |
194 |
// statement_list -> statement statement_list |
{ |
195 |
symbol_stack.pop (); |
// 2. statement_list -> statement statement_list |
196 |
symbol_stack.push (symbol (symbol::type_statement_list)); |
shared_ptr<statement_list_node> statement_list = |
197 |
symbol_stack.push (symbol (symbol::type_statement)); |
dynamic_pointer_cast<statement_list_node> (top.node); |
198 |
|
statement_list->production = 2; |
199 |
|
statement_list->statement.reset (new statement_node ()); |
200 |
|
statement_list->statement_list.reset (new statement_list_node ()); |
201 |
|
symbol_stack.pop (); |
202 |
|
symbol_stack.push (symbol (symbol::type_statement_list, statement_list->statement_list)); |
203 |
|
symbol_stack.push (symbol (symbol::type_statement, statement_list->statement)); |
204 |
|
} |
205 |
break; |
break; |
206 |
case token_type::type_block_end: |
case token_type::type_block_end: |
207 |
case token_type::type_eof: |
case token_type::type_eof: |
208 |
// statement_list -> EMPTY |
{ |
209 |
symbol_stack.pop (); |
// 3. statement_list -> EMPTY |
210 |
|
shared_ptr<statement_list_node> statement_list = |
211 |
|
dynamic_pointer_cast<statement_list_node> (top.node); |
212 |
|
statement_list->production = 3; |
213 |
|
statement_list->statement.reset (); |
214 |
|
statement_list->statement_list.reset (); |
215 |
|
symbol_stack.pop (); |
216 |
|
} |
217 |
break; |
break; |
218 |
default: |
default: |
219 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
223 |
case symbol::type_statement: |
case symbol::type_statement: |
224 |
switch (token.type) { |
switch (token.type) { |
225 |
case token_type::type_command_begin: |
case token_type::type_command_begin: |
226 |
// statement -> command statement_end |
{ |
227 |
symbol_stack.pop (); |
// 4. statement -> command statement_end |
228 |
symbol_stack.push (symbol (symbol::type_statement_end)); |
shared_ptr<statement_node> statement = dynamic_pointer_cast<statement_node> (top.node); |
229 |
symbol_stack.push (symbol (symbol::type_command)); |
statement->production = 4; |
230 |
|
statement->command.reset (new command_node ()); |
231 |
|
statement->assignment.reset (); |
232 |
|
statement->statement_end.reset (new statement_end_node ()); |
233 |
|
symbol_stack.pop (); |
234 |
|
symbol_stack.push (symbol (symbol::type_statement_end, statement->statement_end)); |
235 |
|
symbol_stack.push (symbol (symbol::type_command, statement->command)); |
236 |
|
} |
237 |
break; |
break; |
238 |
case token_type::type_identifier: |
case token_type::type_identifier: |
239 |
// statement -> assignment statement_end |
{ |
240 |
symbol_stack.pop (); |
// 5. statement -> assignment statement_end |
241 |
symbol_stack.push (symbol (symbol::type_statement_end)); |
shared_ptr<statement_node> statement = dynamic_pointer_cast<statement_node> (top.node); |
242 |
symbol_stack.push (symbol (symbol::type_assignment)); |
statement->production = 5; |
243 |
|
statement->command.reset (); |
244 |
|
statement->assignment.reset (new assignment_node ()); |
245 |
|
statement->statement_end.reset (new statement_end_node ()); |
246 |
|
symbol_stack.pop (); |
247 |
|
symbol_stack.push (symbol (symbol::type_statement_end, statement->statement_end)); |
248 |
|
symbol_stack.push (symbol (symbol::type_assignment, statement->assignment)); |
249 |
|
} |
250 |
break; |
break; |
251 |
case token_type::type_semicolon: |
case token_type::type_semicolon: |
252 |
case token_type::type_endl: |
case token_type::type_endl: |
253 |
// statement -> statement_end |
{ |
254 |
symbol_stack.pop (); |
// 6. statement -> statement_end |
255 |
symbol_stack.push (symbol (symbol::type_statement_end)); |
shared_ptr<statement_node> statement = dynamic_pointer_cast<statement_node> (top.node); |
256 |
|
statement->production = 6; |
257 |
|
statement->command.reset (); |
258 |
|
statement->assignment.reset (); |
259 |
|
statement->statement_end.reset (new statement_end_node ()); |
260 |
|
symbol_stack.pop (); |
261 |
|
symbol_stack.push (symbol (symbol::type_statement_end, statement->statement_end)); |
262 |
|
} |
263 |
break; |
break; |
264 |
default: |
default: |
265 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
269 |
case symbol::type_statement_end: |
case symbol::type_statement_end: |
270 |
switch (token.type) { |
switch (token.type) { |
271 |
case token_type::type_semicolon: |
case token_type::type_semicolon: |
272 |
// statement_end -> SEMICOLON |
{ |
273 |
symbol_stack.pop (); |
// 7. statement_end -> SEMICOLON |
274 |
symbol_stack.push (symbol (token_type (token_type::type_semicolon))); |
shared_ptr<statement_end_node> statement_end = |
275 |
|
dynamic_pointer_cast<statement_end_node> (top.node); |
276 |
|
statement_end->production = 7; |
277 |
|
statement_end->semicolon.reset (new token_node (token_type (token_type::type_semicolon))); |
278 |
|
statement_end->endl.reset (); |
279 |
|
symbol_stack.pop (); |
280 |
|
symbol_stack.push (symbol (symbol::type_token, statement_end->semicolon)); |
281 |
|
} |
282 |
break; |
break; |
283 |
case token_type::type_endl: |
case token_type::type_endl: |
284 |
// statement_end -> ENDL |
{ |
285 |
symbol_stack.pop (); |
// 8. statement_end -> ENDL |
286 |
symbol_stack.push (symbol (token_type (token_type::type_endl))); |
shared_ptr<statement_end_node> statement_end = |
287 |
|
dynamic_pointer_cast<statement_end_node> (top.node); |
288 |
|
statement_end->production = 7; |
289 |
|
statement_end->semicolon.reset (); |
290 |
|
statement_end->endl.reset (new token_node (token_type (token_type::type_endl))); |
291 |
|
symbol_stack.pop (); |
292 |
|
symbol_stack.push (symbol (symbol::type_token, statement_end->endl)); |
293 |
|
} |
294 |
break; |
break; |
295 |
default: |
default: |
296 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
297 |
} |
} |
298 |
|
break; |
299 |
|
|
300 |
case symbol::type_command: |
case symbol::type_command: |
301 |
switch (token.type) { |
switch (token.type) { |
302 |
case token_type::type_command_begin: |
case token_type::type_command_begin: |
303 |
// command -> COMMAND_BEGIN IDENTIFIER argument_list |
{ |
304 |
symbol_stack.pop (); |
// 9. command -> COMMAND_BEGIN IDENTIFIER argument_list |
305 |
symbol_stack.push (symbol (symbol::type_argument_list)); |
shared_ptr<command_node> command = dynamic_pointer_cast<command_node> (top.node); |
306 |
symbol_stack.push (symbol (token_type (token_type::type_identifier))); |
command->production = 9; |
307 |
symbol_stack.push (symbol (token_type (token_type::type_command_begin))); |
command->command_begin.reset (new token_node (token_type (token_type::type_command_begin))); |
308 |
|
command->identifier.reset (new token_node (token_type (token_type::type_identifier))); |
309 |
|
command->argument_list.reset (new argument_list_node ()); |
310 |
|
symbol_stack.pop (); |
311 |
|
symbol_stack.push (symbol (symbol::type_argument_list, command->argument_list)); |
312 |
|
symbol_stack.push (symbol (symbol::type_token, command->identifier)); |
313 |
|
symbol_stack.push (symbol (symbol::type_token, command->command_begin)); |
314 |
|
} |
315 |
break; |
break; |
316 |
default: |
default: |
317 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
322 |
switch (token.type) { |
switch (token.type) { |
323 |
case token_type::type_string: |
case token_type::type_string: |
324 |
case token_type::type_block_begin: |
case token_type::type_block_begin: |
325 |
// argument_list -> argument argument_list |
{ |
326 |
symbol_stack.pop (); |
// 10. argument_list -> argument argument_list |
327 |
symbol_stack.push (symbol (symbol::type_argument_list)); |
shared_ptr<argument_list_node> argument_list = dynamic_pointer_cast<argument_list_node> (top.node); |
328 |
symbol_stack.push (symbol (symbol::type_argument)); |
argument_list->production = 10; |
329 |
|
argument_list->argument.reset (new argument_node ()); |
330 |
|
argument_list->argument_list.reset (new argument_list_node ()); |
331 |
|
symbol_stack.pop (); |
332 |
|
symbol_stack.push (symbol (symbol::type_argument_list, argument_list->argument_list)); |
333 |
|
symbol_stack.push (symbol (symbol::type_argument, argument_list->argument)); |
334 |
|
} |
335 |
break; |
break; |
336 |
case token_type::type_semicolon: |
case token_type::type_semicolon: |
337 |
case token_type::type_endl: |
case token_type::type_endl: |
338 |
// argument_list -> EMPTY |
{ |
339 |
symbol_stack.pop (); |
// 11. argument_list -> EMPTY |
340 |
|
shared_ptr<argument_list_node> argument_list = dynamic_pointer_cast<argument_list_node> (top.node); |
341 |
|
argument_list->production = 11; |
342 |
|
argument_list->argument.reset (); |
343 |
|
argument_list->argument_list.reset (); |
344 |
|
symbol_stack.pop (); |
345 |
|
} |
346 |
break; |
break; |
347 |
default: |
default: |
348 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
352 |
case symbol::type_argument: |
case symbol::type_argument: |
353 |
switch (token.type) { |
switch (token.type) { |
354 |
case token_type::type_string: |
case token_type::type_string: |
355 |
// argument -> STRING |
{ |
356 |
symbol_stack.pop (); |
// 12. argument -> STRING |
357 |
symbol_stack.push (symbol (token_type (token_type::type_string))); |
shared_ptr<argument_node> argument = dynamic_pointer_cast<argument_node> (top.node); |
358 |
|
argument->production = 12; |
359 |
|
argument->string.reset (new token_node (token_type (token_type::type_string))); |
360 |
|
argument->block.reset (); |
361 |
|
symbol_stack.pop (); |
362 |
|
symbol_stack.push (symbol (symbol::type_token, argument->string)); |
363 |
|
} |
364 |
break; |
break; |
365 |
case token_type::type_block_begin: |
case token_type::type_block_begin: |
366 |
// argument -> block |
{ |
367 |
symbol_stack.pop (); |
// 13. argument -> block |
368 |
symbol_stack.push (symbol (symbol::type_block)); |
shared_ptr<argument_node> argument = dynamic_pointer_cast<argument_node> (top.node); |
369 |
|
argument->production = 13; |
370 |
|
argument->string.reset (); |
371 |
|
argument->block.reset (new block_node ()); |
372 |
|
symbol_stack.pop (); |
373 |
|
symbol_stack.push (symbol (symbol::type_block, argument->block)); |
374 |
|
} |
375 |
break; |
break; |
376 |
default: |
default: |
377 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
381 |
case symbol::type_block: |
case symbol::type_block: |
382 |
switch (token.type) { |
switch (token.type) { |
383 |
case token_type::type_block_begin: |
case token_type::type_block_begin: |
384 |
// block -> BLOCK_BEGIN statement_list BLOCK_END |
{ |
385 |
symbol_stack.pop (); |
// 14. block -> BLOCK_BEGIN statement_list BLOCK_END |
386 |
symbol_stack.push (symbol (token_type (token_type::type_block_end))); |
shared_ptr<block_node> block = dynamic_pointer_cast<block_node> (top.node); |
387 |
symbol_stack.push (symbol (symbol::type_start)); |
block->production = 14; |
388 |
symbol_stack.push (symbol (token_type (token_type::type_block_begin))); |
block->block_begin.reset (new token_node (token_type (token_type::type_block_begin))); |
389 |
|
block->statement_list.reset (new statement_list_node ()); |
390 |
|
block->block_end.reset (new token_node (token_type (token_type::type_block_end))); |
391 |
|
symbol_stack.pop (); |
392 |
|
symbol_stack.push (symbol (symbol::type_token, block->block_end)); |
393 |
|
symbol_stack.push (symbol (symbol::type_statement_list, block->statement_list)); |
394 |
|
symbol_stack.push (symbol (symbol::type_token, block->block_begin)); |
395 |
|
} |
396 |
|
break; |
397 |
default: |
default: |
398 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
399 |
} |
} |
402 |
case symbol::type_assignment: |
case symbol::type_assignment: |
403 |
switch (token.type) { |
switch (token.type) { |
404 |
case token_type::type_identifier: |
case token_type::type_identifier: |
405 |
// assignment -> IDENTIFIER EQUALS STRING |
{ |
406 |
symbol_stack.pop (); |
// 15. assignment -> IDENTIFIER EQUALS STRING |
407 |
symbol_stack.push (symbol (token_type (token_type::type_string))); |
shared_ptr<assignment_node> assignment = dynamic_pointer_cast<assignment_node> (top.node); |
408 |
symbol_stack.push (symbol (token_type (token_type::type_equals))); |
assignment->production = 15; |
409 |
symbol_stack.push (symbol (token_type (token_type::type_identifier))); |
assignment->identifier.reset (new token_node (token_type (token_type::type_identifier))); |
410 |
|
assignment->equals.reset (new token_node (token_type (token_type::type_equals))); |
411 |
|
assignment->string.reset (new token_node (token_type (token_type::type_string))); |
412 |
|
symbol_stack.pop (); |
413 |
|
symbol_stack.push (symbol (symbol::type_token, assignment->string)); |
414 |
|
symbol_stack.push (symbol (symbol::type_token, assignment->equals)); |
415 |
|
symbol_stack.push (symbol (symbol::type_token, assignment->identifier)); |
416 |
|
} |
417 |
|
break; |
418 |
default: |
default: |
419 |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
ecstacy::util::throw_exception (failure ("unrecognized token")); |
420 |
} |
} |
421 |
|
break; |
422 |
|
|
423 |
default: |
default: |
424 |
ecstacy::util::throw_exception (std::logic_error ("what the fuck?")); |
ecstacy::util::throw_exception (std::logic_error ("invalid parser token")); |
425 |
} |
} |
426 |
} while (1); |
} |
427 |
return ecstacy::mem::shared_ptr<tree> (new tree ()); |
return ret; |
428 |
} |
} |
429 |
} |
} |
430 |
} |
} |