Advertisement
andrei_gavrila

LFC-T4-AFD

Nov 3rd, 2019
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.87 KB | None | 0 0
  1. //
  2. //  main.cpp
  3. //  T4-AFD
  4. //
  5. //  Created by Andrei Gavrila on 21/10/2019.
  6. //  Copyright © 2019 Andrei Gavrila. All rights reserved.
  7. //
  8.  
  9. #include <iostream>
  10. #include <iomanip>
  11. #include <set>
  12. #include <map>
  13. #include <string>
  14. #include <fstream>
  15. #include <regex>
  16.  
  17. #define LOG_DEBUG(x)
  18. //#define LOG_DEBUG(x) std::cout << "DEBUG: " << x << std::endl
  19. #define LOG_WARNING(x) std::cout << "WARNING: " << x << std::endl
  20. #define LOG_ERROR(x) std::cout << "ERROR: " << x << std::endl
  21.  
  22. #define OS "[\\s]*"
  23. #define STARE "[a-zA-Z0-9]+"
  24. #define STARI OS "Stari" OS "=" OS "\\{((" OS STARE OS "[,]{1}" OS ")*(" OS STARE OS "){1})\\}"
  25.  
  26. class AFD
  27. {
  28. private:
  29.     std::set<std::string> Stari;
  30.     std::set<std::string> Sigma;
  31.     std::map<std::string, std::map<std::string, std::string>> Delta;
  32.     std::string StareInit;
  33.     std::set<std::string> Finale;
  34.  
  35.     bool attempt_to_read_stari(const std::string &line)
  36.     {
  37.         std::match_results<std::string::const_iterator> mr;
  38.  
  39. //        std::regex r("[\\s]*Stari[\\s]*=[\\s]*\\{(([\\s]*[a-zA-Z0-9]+[\\s]*[,]{1}[\\s]*)*([\\s]*[a-zA-Z0-9]+[\\s]*){1})\\}");
  40.         std::regex r(STARI);
  41.  
  42.         if (std::regex_match(line, mr, r))
  43.         {
  44.             LOG_DEBUG("Detected Stari line: " << line);
  45.  
  46. //            std::regex ri("[a-zA-Z0-9]+");
  47.             std::regex ri(STARE);
  48.             std::match_results<std::string::const_iterator> mri;
  49.  
  50.             std::string haystack = mr[1].str();
  51.  
  52.             while (regex_search(haystack, mri, ri))
  53.             {
  54.                 LOG_DEBUG("Adding Stari item: " << mri.str());
  55.  
  56.                 Stari.insert(mri.str());
  57.  
  58.                 haystack = mri.suffix();
  59.             }
  60.  
  61.             return true;
  62.         }
  63.  
  64.         return false;
  65.     }
  66.  
  67.     bool attempt_to_read_sigma(const std::string &line)
  68.     {
  69.         std::match_results<std::string::const_iterator> mr;
  70.  
  71.         std::regex r("[\\s]*Sigma[\\s]*=[\\s]*\\{(([\\s]*[a-zA-Z0-9\\+=]+[\\s]*[,]{1}[\\s]*)*([\\s]*[a-zA-Z0-9\\+=]+[\\s]*){1})\\}");
  72.  
  73.         if (std::regex_match(line, mr, r))
  74.         {
  75.             LOG_DEBUG("Detected Sigma line: " << line);
  76.  
  77.             std::regex ri("[a-zA-Z0-9\\+=]+");
  78.             std::match_results<std::string::const_iterator> mri;
  79.  
  80.             std::string haystack = mr[1].str();
  81.  
  82.             while (regex_search(haystack, mri, ri))
  83.             {
  84.                 LOG_DEBUG("Adding Sigma item: " << mri.str());
  85.  
  86.                 Sigma.insert(mri.str());
  87.  
  88.                 haystack = mri.suffix();
  89.             }
  90.  
  91.             return true;
  92.         }
  93.  
  94.         return false;
  95.     }
  96.  
  97.     bool attempt_to_read_delta(const std::string &line)
  98.     {
  99.         std::match_results<std::string::const_iterator> mr;
  100.  
  101.         std::regex r("[\\s]*Delta[\\s]*\\([\\s]*([a-zA-Z0-9]+)[\\s]*,[\\s]*([a-zA-Z0-9\\+=]+)[\\s]*\\)[\\s]*=[\\s]*([a-zA-Z0-9]+)[\\s]*");
  102.  
  103.         if (std::regex_match(line, mr, r))
  104.         {
  105.             LOG_DEBUG("Detected Delta line: " << line);
  106.  
  107.             if ((Delta.find(mr[1].str()) != Delta.end()) && (Delta[mr[1].str()].find(mr[2].str()) != Delta[mr[1].str()].end()))
  108.             {
  109.                 LOG_WARNING("Replacing Delta item (" + mr[1].str() + ", " + mr[2].str() + ", " + Delta[mr[1].str()][mr[2].str()] + ") with: " << mr[1].str() << ", " << mr[2].str() << ", " << mr[3].str());
  110.             }
  111.             else
  112.             {
  113.                 LOG_DEBUG("Adding Delta item with: " << mr[1].str() << ", " << mr[2].str() << ", " << mr[3].str());
  114.             }
  115.  
  116.             Delta[mr[1].str()][mr[2].str()] = mr[3].str();
  117.  
  118.             return true;
  119.         }
  120.  
  121.         return false;
  122.     }
  123.  
  124.     bool attempt_to_read_stare_init(const std::string &line)
  125.     {
  126.         std::match_results<std::string::const_iterator> mr;
  127.  
  128.         std::regex r("[\\s]*StareInit[\\s]*\\=[\\s]*([a-zA-Z0-9]+)[\\s]*");
  129.  
  130.         if (std::regex_match(line, mr, r))
  131.         {
  132.             LOG_DEBUG("Detected StareInit line: " << line);
  133.  
  134.             LOG_DEBUG("Adding StareInit item: " << mr[1].str());
  135.  
  136.             StareInit = mr[1].str();
  137.  
  138.             return true;
  139.         }
  140.  
  141.         return false;
  142.     }
  143.  
  144.     bool attempt_to_read_finale(const std::string &line)
  145.     {
  146.         std::match_results<std::string::const_iterator> mr;
  147.  
  148.         std::regex r("[\\s]*Finale[\\s]*=[\\s]*\\{(([\\s]*[a-zA-Z0-9]+[\\s]*[,]{1}[\\s]*)*([\\s]*[a-zA-Z0-9]+[\\s]*){1})\\}");
  149.  
  150.         if (std::regex_match(line, mr, r))
  151.         {
  152.             LOG_DEBUG("Detected Finale line: " << line);
  153.  
  154.             std::regex ri("[a-zA-Z0-9]+");
  155.             std::match_results<std::string::const_iterator> mri;
  156.  
  157.             std::string haystack = mr[1].str();
  158.  
  159.             while (regex_search(haystack, mri, ri))
  160.             {
  161.                 LOG_DEBUG("Adding Finale item: " << mri.str());
  162.  
  163.                 Finale.insert(mri.str());
  164.  
  165.                 haystack = mri.suffix();
  166.             }
  167.  
  168.             return true;
  169.         }
  170.  
  171.         return false;
  172.     }
  173.  
  174. public:
  175.     void citire(const std::string filename)
  176.     {
  177.         std::ifstream file(filename);
  178.         std::string line;
  179.  
  180.         while (std::getline(file, line))
  181.         {
  182.             if (!line.length() || line[0] == '#')
  183.             {
  184.                 continue;
  185.             }
  186.  
  187.             if (attempt_to_read_stari(line))
  188.             {
  189.                 continue;
  190.             }
  191.  
  192.             if (attempt_to_read_sigma(line))
  193.             {
  194.                 continue;
  195.             }
  196.  
  197.             if (attempt_to_read_delta(line))
  198.             {
  199.                 continue;
  200.             }
  201.  
  202.             if (attempt_to_read_stare_init(line))
  203.             {
  204.                 continue;
  205.             }
  206.  
  207.             if (attempt_to_read_finale(line))
  208.             {
  209.                 continue;
  210.             }
  211.  
  212.             LOG_WARNING("Invalid line: " << line);
  213.         }
  214.     }
  215.  
  216.     bool isValid() const
  217.     {
  218.         if (Stari.size() == 0)
  219.         {
  220.             LOG_ERROR("Multimea de stari este nedefinita!");
  221.  
  222.             return false;
  223.         }
  224.  
  225.         if (Sigma.size() == 0)
  226.         {
  227.             LOG_ERROR("Alfabetul de intrare este nedefinit!");
  228.  
  229.             return false;
  230.         }
  231.  
  232.         if (Delta.size() == 0)
  233.         {
  234.             LOG_ERROR("Functia de tranzitie este nedefinita!");
  235.  
  236.             return false;
  237.         }
  238.  
  239.         for (auto &e0: Delta)
  240.         {
  241.             for (auto &e1: e0.second)
  242.             {
  243.                 if (Stari.find(e0.first) == Stari.end())
  244.                 {
  245.                     LOG_ERROR("Delta(" << e0.first << ", " << e1.first << ") = " << e1.second << ": " << e0.first << " nu se afla in multimea de stari!");
  246.  
  247.                     return false;
  248.                 }
  249.  
  250.                 if (Sigma.find(e1.first) == Sigma.end())
  251.                 {
  252.                     LOG_ERROR("Delta(" << e0.first << ", " << e1.first << ") = " << e1.second << ": " << e1.first << " nu se afla in alfabetul de intrare!");
  253.  
  254.                     return false;
  255.                 }
  256.  
  257.                 if (Stari.find(e1.second) == Stari.end())
  258.                 {
  259.                     LOG_ERROR("Delta(" << e0.first << ", " << e1.first << ") = " << e1.second << ": " << e1.second << " nu se afla in multimea de stari!");
  260.  
  261.                     return false;
  262.                 }
  263.             }
  264.         }
  265.  
  266.         if (StareInit.length() == 0)
  267.         {
  268.             LOG_ERROR("Starea initiala este nedefinita!");
  269.  
  270.             return false;
  271.         }
  272.  
  273.         if (Stari.find(StareInit) == Stari.end())
  274.         {
  275.             LOG_ERROR("Starea initiala " << StareInit << " nu se afla in multimea de stari!");
  276.  
  277.             return false;
  278.         }
  279.  
  280.         if (Finale.size() == 0)
  281.         {
  282.             LOG_ERROR("Multimea starilor finale este nedefinita!");
  283.  
  284.             return false;
  285.         }
  286.  
  287.         for (auto &e: Finale)
  288.         {
  289.             if (Stari.find(e) == Stari.end())
  290.             {
  291.                 LOG_ERROR("Starea finale " << e << " nu se afla in multimea de stari!");
  292.  
  293.                 return false;
  294.             }
  295.         }
  296.  
  297.         return true;
  298.     }
  299.  
  300.     void afisareDetaliata() const
  301.     {
  302.         if (!isValid())
  303.         {
  304.             return;
  305.         }
  306.  
  307.         std::string prefix;
  308.  
  309.         prefix = "";
  310.         std::cout << "Stari = {";
  311.         for (auto &e: Stari)
  312.         {
  313.             std::cout << prefix << e;
  314.  
  315.             prefix = ", ";
  316.         }
  317.         std::cout << "}" << std::endl;
  318.  
  319.         prefix = "";
  320.         std::cout << "Sigma = {";
  321.         for (auto &e: Sigma)
  322.         {
  323.             std::cout << prefix << e;
  324.  
  325.             prefix = ", ";
  326.         }
  327.         std::cout << "}" << std::endl;
  328.  
  329.         for (auto &e0: Delta)
  330.         {
  331.             for (auto &e1: e0.second)
  332.             {
  333.                 std::cout << "Delta(" << e0.first << ", " << e1.first << ") = " << e1.second << std::endl;
  334.             }
  335.         }
  336.  
  337.         std::cout << "StareInit = " << StareInit << std::endl;
  338.  
  339.         prefix = "";
  340.         std::cout << "Finale = {";
  341.         for (auto &e: Finale)
  342.         {
  343.             std::cout << prefix << e;
  344.  
  345.             prefix = ", ";
  346.         }
  347.         std::cout << "}" << std::endl;
  348.     }
  349.  
  350.     void afisareScurta()
  351.     {
  352.         if (!isValid())
  353.         {
  354.             return;
  355.         }
  356.  
  357.         std::string prefix;
  358.  
  359.         std::cout << "M = (";
  360.  
  361.         prefix = "";
  362.         std::cout << "{";
  363.         for (auto &e: Stari)
  364.         {
  365.             std::cout << prefix << e;
  366.  
  367.             prefix = ", ";
  368.         }
  369.         std::cout << "}, ";
  370.  
  371.         prefix = "";
  372.         std::cout << "{";
  373.         for (auto &e: Sigma)
  374.         {
  375.             std::cout << prefix << e;
  376.  
  377.             prefix = ", ";
  378.         }
  379.         std::cout << "}, ";
  380.  
  381.         std::cout << "Delta, ";
  382.        
  383.         std::cout <<  StareInit << ", ";
  384.        
  385.         prefix = "";
  386.         std::cout << "{";
  387.         for (auto &e: Finale)
  388.         {
  389.             std::cout << prefix << e;
  390.            
  391.             prefix = ", ";
  392.         }
  393.         std::cout << "})" << std::endl;
  394.  
  395.         std::cout << std::endl;
  396.  
  397.         size_t StariMaxLen = 0;
  398.  
  399.         std::for_each(Stari.begin(), Stari.end(), [&] (auto &e) {
  400.             StariMaxLen = (e.size() > StariMaxLen ? e.size() : StariMaxLen);
  401.         });
  402.  
  403.         size_t SigmaMaxLen = 0;
  404.  
  405.         std::for_each(Sigma.begin(), Sigma.end(), [&] (auto &e) {
  406.             SigmaMaxLen = (e.size() > SigmaMaxLen ? e.size() : SigmaMaxLen);
  407.         });
  408.  
  409.         std::cout << std::setw(static_cast<int>(SigmaMaxLen) + 1) << " " << " |";
  410.         std::for_each(Stari.begin(), Stari.end(), [&] (auto &e) {
  411.             std::cout << std::setw(static_cast<int>(StariMaxLen) + 2) << e;
  412.         });
  413.  
  414.         std::cout << std::endl;
  415.  
  416.         std::cout << std::setw(static_cast<int>(SigmaMaxLen) + 1) << std::setfill('-') << "-" << "-+" << std::setw(static_cast<int>(Stari.size())*(static_cast<int>(StariMaxLen) + 2)) << std::setfill('-') << "-" << std::endl;
  417.  
  418.         std::for_each(Sigma.begin(), Sigma.end(), [&] (auto &e1) {
  419.             std::cout << std::setw(static_cast<int>(SigmaMaxLen) + 1) << std::setfill(' ') << e1 << " |";
  420.  
  421.             std::for_each(Stari.begin(), Stari.end(), [&] (auto &e2) {
  422.                 if (Delta.find(e2) != Delta.end() && Delta[e2].find(e1) != Delta[e2].end())
  423.                 {
  424.                     std::cout << std::setw(static_cast<int>(StariMaxLen) + 2) << Delta[e2][e1];
  425.                 }
  426.                 else
  427.                 {
  428.                     std::cout << std::setw(static_cast<int>(StariMaxLen) + 2) << "MV";
  429.                 }
  430.             });
  431.  
  432.             std::cout << std::endl;
  433.         });
  434.  
  435.         std::cout << std::endl;
  436.     }
  437.  
  438.     uint8_t verificare(const std::string cuvant)
  439.     {
  440.         std::cout << "Verificare: " << cuvant << std::endl;
  441.  
  442.         std::string stare = StareInit;
  443.        
  444.         std::regex r("[a-zA-Z0-9\\+=]+");
  445.         std::match_results<std::string::const_iterator> mr;
  446.  
  447.         std::string haystack = cuvant;
  448.  
  449.         while (regex_search(haystack, mr, r))
  450.         {
  451.             if (Sigma.find(mr.str()) == Sigma.end())
  452.             {
  453.                 std::cout << "Simbolul " << mr.str() << " nu se afla in alfabetul de intrare!" << std::endl;
  454.  
  455.                 return 0;
  456.             }
  457.  
  458.             haystack = mr.suffix();
  459.         }
  460.  
  461.         haystack = cuvant;
  462.  
  463.         while (regex_search(haystack, mr, r))
  464.         {
  465.             std::cout << "Delta(" << stare << ", \"";
  466.  
  467.             bool begin = true;
  468.             for (auto &e: haystack)
  469.             {
  470.                 if (e != ' ' || !begin)
  471.                 {
  472.                     std::cout << e;
  473.  
  474.                     begin = false;
  475.                 }
  476.                 else if (e != ' ')
  477.                 {
  478.                     begin = false;
  479.                 }
  480.             }
  481.             std::cout << "\") = ";
  482.  
  483.             if (Delta.find(stare) != Delta.end() && Delta[stare].find(mr.str()) != Delta[stare].end())
  484.             {
  485.                 stare = Delta[stare][mr.str()];
  486.             }
  487.             else
  488.             {
  489.                 std::cout << "Multimea Vida - blocaj" << std::endl;
  490.  
  491.                 return 1;
  492.             }
  493.  
  494.             haystack = mr.suffix();
  495.         }
  496.  
  497.         std::cout << stare;
  498.  
  499.         if (Finale.find(stare) == Finale.end())
  500.         {
  501.             std::cout << ", nu apartine Finale - neacceptat" << std::endl;
  502.  
  503.             return 2;
  504.         }
  505.  
  506.         std::cout << ", apartine Finale - acceptat" << std::endl;
  507.  
  508.         return 3;
  509.     }
  510. };
  511.  
  512. int main(int argc, const char **argv)
  513. {
  514.     AFD afd;
  515.  
  516.     afd.citire("/Users/andreig/Documents/Xcode/LimbajeFormale/T4-AFD/T4-AFD/input.txt");
  517.  
  518.     std::cout << std::endl;
  519.  
  520.     afd.afisareDetaliata();
  521.  
  522.     std::cout << std::endl;
  523.  
  524.     afd.afisareScurta();
  525.  
  526. /*
  527.     if (afd.isValid())
  528.     {
  529.         std::cout << std::endl;
  530.  
  531.         afd.verificare("a b b a");
  532.  
  533.         std::cout << std::endl;
  534.  
  535.         afd.verificare("a a b b a");
  536.  
  537.         std::cout << std::endl;
  538.  
  539.         afd.verificare("a b");
  540.     }
  541. */
  542.  
  543.     if (afd.isValid())
  544.     {
  545.         while (true)
  546.         {
  547.             std::string cuvant;
  548.  
  549.             std::cout << std::endl << "Cuvant: ";
  550.  
  551.             std::getline(std::cin, cuvant);
  552.  
  553.             afd.verificare(cuvant);
  554.         }
  555.     }
  556.  
  557.     return 0;
  558. }
  559.  
  560.  
  561. /*
  562. # input.txt
  563. #
  564. Stari = {q0, q1, q2}
  565. Sigma = {a, b}
  566. Delta(q0, a) = q1
  567. Delta(q1, b) = q2
  568. Delta(q2, a) = q2
  569. Delta(q2, b) = q2
  570. StareInit = q0
  571. Finale = {q2}
  572.  
  573. #Stari = {q0, q1, q2, q3, q4, q5}
  574. #Sigma = {1, +, =}
  575. #Delta(q0, 1) = q1
  576. #Delta(q1, 1) = q1
  577. #Delta(q1, +) = q2
  578. #Delta(q2, 1) = q3
  579. #Delta(q3, 1) = q3
  580. #Delta(q3, =) = q4
  581. #Delta(q4, 1) = q5
  582. #Delta(q5, 1) = q5
  583. #StareInit = q0
  584. #Finale = {q5}
  585.  
  586. # example: 1 1 1 + 1 1 = 1 1 1 1 1
  587.  
  588. #Stari = {q0, q1, q2, q3, q4, q5, q6, q7}
  589. #Sigma = {if, 0, 1, a, b, ==, then, print, exit, else}
  590. #Delta(q0, if) = q1
  591. #Delta(q1, 0) = q2
  592. #Delta(q1, 1) = q2
  593. #Delta(q1, a) = q2
  594. #Delta(q1, b) = q2
  595. #Delta(q2, ==) = q3
  596. #Delta(q3, 0) = q4
  597. #Delta(q3, 1) = q4
  598. #Delta(q3, a) = q4
  599. #Delta(q3, b) = q4
  600. #Delta(q4, then) = q5
  601. #Delta(q5, print) = q6
  602. #Delta(q6, 0) = q7
  603. #Delta(q6, 1) = q7
  604. #Delta(q6, a) = q7
  605. #Delta(q6, b) = q7
  606. #Delta(q5, exit) = q7
  607. #Delta(q7, else) = q5
  608. #StareInit = q0
  609. #Finale = {q7}
  610.  
  611. # example: if b == 0 then print 1
  612. # example: if a == 1 then print a else exit
  613. */
  614.  
  615. /*
  616. Output:
  617.  
  618.  
  619. Stari = {q0, q1, q2}
  620. Sigma = {a, b}
  621. Delta(q0, a) = q1
  622. Delta(q1, b) = q2
  623. Delta(q2, a) = q2
  624. Delta(q2, b) = q2
  625. StareInit = q0
  626. Finale = {q2}
  627.  
  628. M = ({q0, q1, q2}, {a, b}, Delta, q0, {q2})
  629.  
  630.    |  q0  q1  q2
  631. ---+------------
  632.  a |  q1  MV  q2
  633.  b |  MV  q2  q2
  634.  
  635.  
  636. Cuvant: a b a a
  637. Verificare: a b a a
  638. Delta(q0, "a b a a") = Delta(q1, "b a a") = Delta(q2, "a a") = Delta(q2, "a") = q2, apartine Finale - acceptat
  639.  
  640. Cuvant: a a b a
  641. Verificare: a a b a
  642. Delta(q0, "a a b a") = Delta(q1, "a b a") = Multimea Vida - blocaj
  643.  
  644. Cuvant: a
  645. Verificare: a
  646. Delta(q0, "a") = q1, nu apartine Finale - neacceptat
  647.  
  648. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement