Gistrec

CatPlusPlus bkp

Apr 3rd, 2019
333
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.91 KB | None | 0 0
  1. #pragma once
  2. #include <string>
  3.  
  4. using std::string;
  5.  
  6. /**
  7.  * Типы лексем
  8.  * Keyword   - ключевое слово
  9.  * Delimiter - разделитель
  10.  * Sign  - арифметический знак
  11.  * Const - константа
  12.  * Var   - переменная
  13.  */
  14. enum LexemeType : int { Keyword = 0, Sign = 1, Delimiter = 2, Var = 3, Const = 4};
  15. struct Lexeme {
  16.     int type;
  17.     int subtype; // Одно из KeywordType::, SignType::, DelimiterType::
  18.  
  19.     string name; // Название лексемы
  20.  
  21.     Lexeme(int type, int subtype, string name) :
  22.         type(type),
  23.         subtype(subtype),
  24.         name(name)
  25.     {};
  26.  
  27.     int    getType()    { return type;    }
  28.     int    getSubtype() { return subtype; }
  29.     string getName()    { return name;    }
  30. };
  31.  
  32.  
  33.  
  34. enum KeywordType   : int { If, Else, For, While };
  35. enum SignType      : int { Add, Sub, Mul, Div, Equal, isEqual };
  36. enum DelimiterType : int { OpenBracket, CloseBracket, Space, Semicolon };
  37.  
  38. enum VariableType  : int { Undefined, Int, Float };
  39.  
  40.  
  41.  
  42. /**
  43.  * Переменная
  44.  * @constructor name - название переменной
  45.  * @constructor vartype - тип значения        ?? Знаем ли мы тип во время лексического анализа
  46.  */
  47. struct Variable : public Lexeme {
  48.     VariableType vartype;  // Тип переменной
  49.  
  50.     bool init;   // Инициализированна ли переменная
  51.     size_t data; // Данные переменной
  52.  
  53.     Variable(string name, VariableType vartype = VariableType::Undefined) :
  54.         Lexeme(LexemeType::Var, 0, name),
  55.         vartype(vartype),
  56.         init(false),
  57.         data(0)
  58.     {};
  59.  
  60.     /** Геттеры */
  61.     bool         isInit()     {  return init;     }
  62.  
  63.     VariableType getVarType() {  return vartype;  }
  64.     string       getName()    {  return name;     }
  65.     size_t       getData()    {  return data;     }
  66.  
  67.     /** Сеттеры */
  68.     void setVarType(VariableType new_vartype) {
  69.         vartype = new_vartype;
  70.     }
  71.  
  72.     void setData(size_t new_data) {
  73.         init = true;
  74.         data = new_data;
  75.     }
  76. };
  77.  
  78. /**
  79.  * Константа
  80.  * @constructor name - название константы
  81.  * @constructor vartype - тип значения       ?? Знаем ли мы тип во время лексического анализа
  82.  * @constructor data - данные константы      ?? Знаем ли мы данные во время лексического анализа
  83.  */
  84. struct Constant : public Lexeme {
  85.     VariableType vartype;
  86.  
  87.     size_t data;  // Данные переменной
  88.  
  89.     Constant(string name, VariableType vartype = VariableType::Undefined, size_t data = 0) :
  90.         Lexeme(LexemeType::Const, 0, name),
  91.         vartype(vartype),
  92.         data(data)
  93.     {};
  94.  
  95.     /** Геттеры */
  96.     VariableType getVarType() {  return vartype;  }
  97.     string       getName()    {  return name;     }
  98.     size_t       getData()    {  return data;     }
  99.  
  100.     /** Сеттеры */
  101. };
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. #pragma once
  122. #include <cassert>
  123. #include <string>
  124. #include <vector>
  125. #include <map>
  126.  
  127. #include "Lexemes.hpp"
  128.  
  129. using std::string;
  130. using std::vector;
  131. using std::pair;
  132. using std::map;
  133.  
  134.  
  135. class LexemesTables {
  136. public:
  137.     vector<Lexeme> keywords;   // Ключевые слова
  138.     vector<Lexeme> delimiters; // Разделители
  139.     vector<Lexeme> signs;      // Арифметические знаки
  140.  
  141.     vector<Variable> variables; // Переменные
  142.     vector<Constant> constants; // Константы
  143.  
  144.     LexemesTables();
  145.  
  146.     /**
  147.      * Поиск лексемы среди константных таблиц
  148.      * По строке или номеру таблицы и позиции в таблице
  149.      */
  150.     Lexeme* getLexeme(const string& name);
  151.     Lexeme* getLexeme(int type, int subtype);
  152.  
  153.     /**
  154.      * Добавляем/получаем переменную в таблице переменных
  155.      * int - позиция в таблице
  156.      */
  157.     int addVariable(Variable &variable);
  158.     Variable* getVariable(int position);
  159.     Variable* getVariable(string name);
  160.  
  161.     int addConstant(Constant &constant);
  162.     Constant* getConstant(int position);
  163.     Constant* getConstant(string name);
  164. };
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189. #include "LexemesTables.hpp"
  190.  
  191. LexemesTables::LexemesTables() {
  192.     // Добавляем ключевые слова
  193.     keywords = {
  194.         {Lexeme(LexemeType::Keyword, KeywordType::If,    "if"   )},
  195.         {Lexeme(LexemeType::Keyword, KeywordType::Else,  "else" )},
  196.         {Lexeme(LexemeType::Keyword, KeywordType::For,   "for"  )},
  197.         {Lexeme(LexemeType::Keyword, KeywordType::While, "while")},
  198.     };
  199.  
  200.     // Добавляем знаки
  201.     signs = {
  202.         {Lexeme(LexemeType::Sign, SignType::Add,     "+" )},
  203.         {Lexeme(LexemeType::Sign, SignType::Sub,     "-" )},
  204.         {Lexeme(LexemeType::Sign, SignType::Mul,     "*" )},
  205.         {Lexeme(LexemeType::Sign, SignType::Div,     "/" )},
  206.         {Lexeme(LexemeType::Sign, SignType::isEqual, "==")},
  207.         {Lexeme(LexemeType::Sign, SignType::Equal,   "=" )},
  208.     };
  209.  
  210.     // Добавляем разделители
  211.     delimiters = {
  212.         {Lexeme(LexemeType::Delimiter, DelimiterType::OpenBracket,  "(")},
  213.         {Lexeme(LexemeType::Delimiter, DelimiterType::CloseBracket, ")")},
  214.         {Lexeme(LexemeType::Delimiter, DelimiterType::Space,        " ")},
  215.         {Lexeme(LexemeType::Delimiter, DelimiterType::Semicolon,    ";")},
  216.     };
  217. }
  218.  
  219. Lexeme* LexemesTables::getLexeme(const string& name) {
  220.     for (auto& keyword : keywords) {
  221.         if (keyword.getName() == name) return &keyword;
  222.     }
  223.     for (auto& sign : signs) {
  224.         if (sign.getName() == name) return &sign;
  225.     }
  226.     for (auto& delimiter : delimiters) {
  227.         if (delimiter.getName() == name) return &delimiter;
  228.     }
  229.  
  230.     return nullptr;
  231. }
  232. Lexeme* LexemesTables::getLexeme(int type, int subtype) {
  233.     switch (type) {
  234.         case LexemeType::Keyword:   return &keywords.at(subtype);
  235.         case LexemeType::Delimiter: return &delimiters.at(subtype);
  236.         case LexemeType::Sign:      return &signs.at(subtype);
  237.     }
  238.     return nullptr;
  239. }
  240.  
  241.  
  242. int LexemesTables::addVariable(Variable &variable) {
  243.     // TODO: нельзя добавлять существующую переменную
  244.     variables.push_back(variable);
  245.     return variables.size() - 1;
  246. }
  247.  
  248. Variable* LexemesTables::getVariable(int position) {
  249.     if (variables.size() < position) return nullptr;
  250.  
  251.     return &(variables[position]);
  252. }
  253. Variable* LexemesTables::getVariable(string name)  {
  254.     for (auto &variable : variables) {
  255.         if (variable.getName() == name) return &variable;
  256.     }
  257.     return nullptr;
  258. };
  259.  
  260. int LexemesTables::addConstant(Constant &constant) {
  261.     constants.push_back(constant);
  262.     return constants.size() - 1;
  263. }
  264.  
  265. Constant* LexemesTables::getConstant(int position)  {
  266.     if (constants.size() < position) return nullptr;
  267.  
  268.     return &constants[position];
  269. }
  270. Constant* LexemesTables::getConstant(string name) {
  271.     for (auto &constant : constants) {
  272.         if (constant.getName() == name) return &constant;
  273.     }
  274.     return nullptr;
  275. }
  276.  
  277.  
  278.  
  279.  
  280. int main() {
  281.     return 0;
  282. }
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319. #pragma once
  320. #include "stdafx.hpp"
  321.  
  322. #include "../src/LexemesTables.hpp"
  323.  
  324.  
  325. TEST_CLASS(LexemesTest) {
  326. public:
  327.     /** Проверка функций, которые возвращают table_id и position*/
  328.     TEST_METHOD(SimpleLexemeTest) {
  329.         string word = "if";
  330.         Lexeme lexeme(LexemeType::Keyword, KeywordType::If, word);
  331.  
  332.         Assert::AreEqual(lexeme.getType(),    (int)LexemeType::Keyword);
  333.         Assert::AreEqual(lexeme.getSubtype(), (int)KeywordType::If);
  334.         Assert::AreEqual(lexeme.getName(),    word);
  335.     }
  336.    
  337.     TEST_METHOD(LexemeTest) {
  338.         string word;
  339.         Lexeme sign_lexeme(LexemeType::Sign, SignType::Add, word);
  340.  
  341.         Assert::AreEqual(sign_lexeme.getType(),    (int)LexemeType::Sign);
  342.         Assert::AreEqual(sign_lexeme.getSubtype(), (int)SignType::Add);
  343.  
  344.         word = " ";
  345.         Lexeme delim_lexeme(LexemeType::Delimiter, DelimiterType::Space, word);
  346.         Assert::AreEqual(delim_lexeme.getType(),    (int)LexemeType::Delimiter);
  347.         Assert::AreEqual(delim_lexeme.getSubtype(), (int)DelimiterType::Space);
  348.     }
  349.  
  350.     TEST_METHOD(VariableLexemeTest) {
  351.         string name = "my_variable";
  352.         Variable var(name);
  353.  
  354.         Assert::AreEqual(var.getName(),    name);
  355.         Assert::AreEqual(var.getType(),    (int)LexemeType::Var);
  356.         Assert::AreEqual(var.getVarType(), VariableType::Undefined);
  357.         Assert::AreEqual(var.isInit(),     false);
  358.         Assert::AreEqual(var.getData(),    (size_t) 0);
  359.        
  360.         var.setVarType(VariableType::Int);
  361.         var.setData(12);
  362.  
  363.         Assert::AreEqual(var.getVarType(), VariableType::Int);
  364.         Assert::AreEqual(var.getData(),    (size_t) 12);
  365.     }
  366.  
  367.     TEST_METHOD(ConstantLexemeTest) {
  368.         string name = "my_constant";
  369.         Constant constant(name, VariableType::Int, 5);
  370.  
  371.         Assert::AreEqual(constant.getName(),    name);
  372.         Assert::AreEqual(constant.getType(),    (int)LexemeType::Const);
  373.         Assert::AreEqual(constant.getVarType(), VariableType::Int);
  374.         Assert::AreEqual(constant.getData(),    (size_t) 5);
  375.     }
  376. };
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400. #pragma once
  401. #include "stdafx.hpp"
  402.  
  403. #include "../src/LexemesTables.cpp"
  404.  
  405.  
  406. using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  407.  
  408.  
  409. TEST_CLASS(LexemesTablesTest) {
  410. public:
  411.  
  412.     /** Поиск в константных таблицах */
  413.     TEST_METHOD(GetConstantLexemeByName) {
  414.         LexemesTables tables;
  415.  
  416.         Lexeme* lexeme = tables.getLexeme("NOT FOUND LEXEME");
  417.         Assert::IsNull(lexeme);
  418.  
  419.         lexeme = tables.getLexeme("if");
  420.         Assert::AreEqual(lexeme->getType(),    (int)LexemeType::Keyword);
  421.         Assert::AreEqual(lexeme->getSubtype(), (int)KeywordType::If);
  422.  
  423.         lexeme = tables.getLexeme(" ");
  424.         Assert::AreEqual(lexeme->getType(),    (int)LexemeType::Delimiter);
  425.         Assert::AreEqual(lexeme->getSubtype(), (int) DelimiterType::Space);
  426.     }
  427.  
  428.     /** Поиск в константных таблицах по id:position */
  429.     TEST_METHOD(GetConstantLexemeById) {
  430.         LexemesTables tables;
  431.  
  432.         Lexeme* lexeme = tables.getLexeme("if");
  433.         Assert::IsNotNull(lexeme);
  434.         Assert::AreEqual(lexeme->getType(),    (int)LexemeType::Keyword);
  435.         Assert::AreEqual(lexeme->getSubtype(), (int)KeywordType::If);
  436.  
  437.         Lexeme* second = tables.getLexeme(lexeme->getType(), lexeme->getSubtype());
  438.         Assert::IsNotNull(second);
  439.     }
  440.  
  441.     /** Тесты переменной */
  442.     TEST_METHOD(VariableLexemesTablesTest) {
  443.         LexemesTables tables;
  444.         string name = "my_variable";
  445.  
  446.         // Переменной не существует
  447.         Variable* var_ptr = tables.getVariable(name);
  448.         Assert::IsNull(var_ptr);
  449.  
  450.         // Добавили переменную и получили её позицию в таблице переменных
  451.         Variable var(name);
  452.         int position = tables.addVariable(var);
  453.  
  454.         // Переменная существует
  455.         var_ptr = tables.getVariable(name);
  456.         Assert::IsNotNull(var_ptr);
  457.         Assert::AreEqual(var_ptr->getName(), name);
  458.  
  459.         // Получаем переменную по её позиции в таблице переменных
  460.         var_ptr = tables.getVariable(position);
  461.         Assert::IsNotNull(var_ptr);
  462.         Assert::AreEqual(var_ptr->getName(), name);
  463.     }
  464. };
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment