12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- #include "Parser.h"
- #include <string>
- using namespace zp;
- using namespace std;
- Parser::Parser(istream& in) :
- in{in}
- {
- }
- unique_ptr<Block> Parser::parse(void)
- {
- return parseBlock(false);
- }
- unique_ptr<Block> Parser::parseBlock(bool isLoop)
- {
- unique_ptr<UnionBlock> wrapper = nullptr;
- unique_ptr<InstructionBlock> block = make_unique<InstructionBlock>();
- char chr;
- while (in >> chr) {
- switch(chr) {
- case '+':
- block->addInstruction(Instruction::PLUS);
- break;
- case '-':
- block->addInstruction(Instruction::MINUS);
- break;
- case '<':
- block->addInstruction(Instruction::LEFT);
- break;
- case '>':
- block->addInstruction(Instruction::RIGHT);
- break;
- case '.':
- block->addInstruction(Instruction::DOT);
- break;
- case ',':
- block->addInstruction(Instruction::COMMA);
- break;
- case '[':
- if (wrapper == nullptr) {
- wrapper = isLoop ? make_unique<Loop>() : make_unique<UnionBlock>();
- }
- if (!block->isEmpty()) {
- wrapper->addBlock(move(block));
- block = make_unique<InstructionBlock>();
- }
- wrapper->addBlock(parseBlock(true));
- break;
- case ']':
- if (isLoop) {
- if (wrapper == nullptr)
- return block;
- else
- return wrapper;
- }
- else
- throw ParserException("encountered unexpected ']'");
- default:;
- }
- }
- if (isLoop)
- throw ParserException("number of '['s and ']'s not matching");
- else if (wrapper == nullptr)
- return block;
- else
- return wrapper;
- }
|