Parser.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include "Parser.h"
  2. #include <string>
  3. using namespace zp;
  4. using namespace std;
  5. Parser::Parser(istream& in) :
  6. in{in}
  7. {
  8. }
  9. unique_ptr<Block> Parser::parse(void)
  10. {
  11. return parseBlock(false);
  12. }
  13. unique_ptr<Block> Parser::parseBlock(bool isLoop)
  14. {
  15. unique_ptr<UnionBlock> wrapper = nullptr;
  16. unique_ptr<InstructionBlock> block = make_unique<InstructionBlock>();
  17. char chr;
  18. while (in >> chr) {
  19. switch(chr) {
  20. case '+':
  21. block->addInstruction(Instruction::PLUS);
  22. break;
  23. case '-':
  24. block->addInstruction(Instruction::MINUS);
  25. break;
  26. case '<':
  27. block->addInstruction(Instruction::LEFT);
  28. break;
  29. case '>':
  30. block->addInstruction(Instruction::RIGHT);
  31. break;
  32. case '.':
  33. block->addInstruction(Instruction::DOT);
  34. break;
  35. case ',':
  36. block->addInstruction(Instruction::COMMA);
  37. break;
  38. case '[':
  39. if (wrapper == nullptr) {
  40. wrapper = isLoop ? make_unique<Loop>() : make_unique<UnionBlock>();
  41. }
  42. if (!block->isEmpty()) {
  43. wrapper->addBlock(move(block));
  44. block = make_unique<InstructionBlock>();
  45. }
  46. wrapper->addBlock(parseBlock(true));
  47. break;
  48. case ']':
  49. if (isLoop) {
  50. if (wrapper == nullptr)
  51. return block;
  52. else
  53. return wrapper;
  54. }
  55. else
  56. throw ParserException("encountered unexpected ']'");
  57. default:;
  58. }
  59. }
  60. if (isLoop)
  61. throw ParserException("number of '['s and ']'s not matching");
  62. else if (wrapper == nullptr)
  63. return block;
  64. else
  65. return wrapper;
  66. }