Advertisement
phyrrus9

Parser

Jan 1st, 2017
339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.36 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <vector>
  5. #include <cstring>
  6. #include <string>
  7. #include <algorithm>
  8. #include <functional>
  9.  
  10. typedef struct variable
  11. {
  12.     char name[32];
  13.     int value;
  14. } variable;
  15.  
  16. char buffer[512];
  17. char raw[512];
  18. std::vector<variable *> variables;
  19. bool error;
  20. bool ret;
  21.  
  22. int E();
  23. int T(const char *);
  24. void parseCode(FILE *f = stdin, const char *prefix = NULL);
  25.  
  26. void removeCharacter(char c)
  27. {
  28.     std::string str = buffer;
  29.     str.erase(std::remove_if(str.begin(), str.end(), std::bind2nd(std::equal_to<char>(), c)), str.end());
  30.     strcpy(buffer, str.c_str());
  31. }
  32.  
  33. void readInput(FILE *f)
  34. {
  35.     if (f == stdin)
  36.     {
  37.         printf("> ");
  38.         fflush(stdout);
  39.     }
  40.     fgets(buffer, 512, f);
  41.     //trim all whitespace
  42.     removeCharacter('\n');
  43.     strcpy(raw, buffer);
  44.     removeCharacter(' ');
  45.     removeCharacter('\t');
  46. }
  47.  
  48. void printVariables()
  49. {
  50.     for (int i = 0; i < variables.size(); i++)
  51.     {
  52.         variable *v = variables.at(i);
  53.         printf("%s\t=\t%d\n", v->name, v->value);
  54.     }
  55. }
  56. variable *findVariable(const char *name)
  57. {
  58.     for (int i = 0; i < variables.size(); i++)
  59.     {
  60.         variable *v = variables.at(i);
  61.         if (!strcmp(name, v->name))
  62.             return v;
  63.     }
  64.     return NULL;
  65. }
  66.  
  67. bool deleteVariable(const char *name)
  68. {
  69.     for (int i = 0; i < variables.size(); i++)
  70.     {
  71.         variable *v = variables.at(i);
  72.         if (!strcmp(name, v->name))
  73.         {
  74.             variables.erase(variables.begin() + i);
  75.             return true;
  76.         }
  77.     }
  78.     return false;
  79. }
  80.  
  81. bool S()
  82. {
  83.     char *pch;
  84.     if (!strcmp(buffer, ".done"))
  85.     {
  86.         ret = true;
  87.         return true;
  88.     }
  89.     else if (!strcmp(buffer, ".print"))
  90.     {
  91.         printVariables();
  92.         return true;
  93.     }
  94.     else if (strstr(buffer, ".echo(") == buffer)
  95.     {
  96.         char *tmp = strdup(raw + strlen(".echo("));
  97.         if ((pch = strtok(tmp, ")")) != NULL)
  98.         {
  99.             printf("%s\n", pch);
  100.             free(tmp);
  101.             return true;
  102.         }
  103.         free(tmp);
  104.         return false;
  105.     }
  106.     else if (strstr(buffer, ".print(") == buffer)
  107.     {
  108.         char *tmp = strdup(buffer + strlen(".print("));
  109.         if ((pch = strtok(tmp, ")")) != NULL)
  110.         {
  111.             variable *v = findVariable(pch);
  112.             if (v != NULL)
  113.             {
  114.                 printf("%s\t=\t%d\n", v->name, v->value);
  115.                 free(tmp);
  116.                 return true;
  117.             }
  118.         }
  119.         free(tmp);
  120.         return false;
  121.     }
  122.     else if (strstr(buffer, ".input(") == buffer)
  123.     {
  124.         char *tmp = strdup(buffer + strlen(".input("));
  125.         if ((pch = strtok(tmp, ")")) != NULL)
  126.         {
  127.             int val;
  128.             printf("? ");
  129.             fflush(stdout);
  130.             if (scanf("%d", &val) > 0)
  131.             {
  132.                 char *t = strdup(pch);
  133.                 variable *var = findVariable(t);
  134.                 if (var == NULL)
  135.                 {
  136.                     var = new variable;
  137.                     strcpy(var->name, t);
  138.                     variables.push_back(var);
  139.                 }
  140.                 var->value = val;
  141.                 free(tmp);
  142.                 free(t);
  143.                 return true;
  144.             }
  145.         }
  146.         free(tmp);
  147.         return false;
  148.     }
  149.     else if (strstr(buffer, ".call(") == buffer)
  150.     {
  151.         char *tmp = strdup(buffer + strlen(".call("));
  152.         if ((pch = strtok(tmp, ")")) != NULL)
  153.         {
  154.             FILE *f = fopen(pch, "r");
  155.             if (f == NULL)
  156.                 return false;
  157.             parseCode(f, pch);
  158.             return true;
  159.         }
  160.         return false;
  161.     }
  162.     else if (strstr(buffer, ".ifcall(") == buffer)
  163.     {
  164.         char *proc;
  165.         char *tmp = strdup(buffer + strlen(".ifcall("));
  166.         if ((pch = strtok(tmp, ",")) != NULL)
  167.         {
  168.             proc = strdup(pch);
  169.             if ((pch = strtok(NULL, ")")) != NULL)
  170.             {
  171.                 strcpy(buffer, pch);
  172.                 int val = E();
  173.                 if (!error)
  174.                 {
  175.                     if (!val)
  176.                     {
  177.                         FILE *f = fopen(proc, "r");
  178.                         if (f == NULL)
  179.                             goto ifcallsynerr;
  180.                         parseCode(f, proc);
  181.                     }
  182.                     goto ifcallgood;
  183.                 }
  184.             }
  185.         ifcallsynerr:
  186.             free(proc);
  187.             free(tmp);
  188.             return false;
  189.         }
  190.     ifcallgood:
  191.         free(proc);
  192.         free(tmp);
  193.         return true;
  194.     }
  195.     else if (strstr(buffer, ".delete(") == buffer)
  196.     {
  197.         char *tmp = strdup(buffer + strlen(".delete("));
  198.         if ((pch = strtok(tmp, ")")) != NULL)
  199.         {
  200.             if (deleteVariable(pch))
  201.             {
  202.                 free(tmp);
  203.                 return true;
  204.             }
  205.         }
  206.         free(tmp);
  207.         return false;
  208.     }
  209.     pch = strtok(buffer, "=");
  210.     bool newvar = false;
  211.     variable *var = findVariable(pch);
  212.     if (var == NULL)
  213.     {
  214.         var = new variable;
  215.         strcpy(var->name, pch);
  216.         newvar = true;
  217.     }
  218.     if ((pch = strtok(NULL, "\0")) == NULL)
  219.     {
  220.         if (newvar)
  221.             delete var;
  222.         return false;
  223.     }
  224.     strcpy(buffer, pch);
  225.     int val = E();
  226.     if (!error)
  227.     {
  228.         var->value = val;
  229.         if (newvar)
  230.             variables.push_back(var);
  231.         return true;
  232.     }
  233.     return false;
  234. }
  235.  
  236. bool isConstant(const char *buf, int *v)
  237. {
  238.     return sscanf(buf, "%d", v) > 0;
  239. }
  240.  
  241. #define ERR() free(tmp); error = true; return 0;
  242. int E()
  243. {
  244.     int val;
  245.     char *pch;
  246.     char *tmp, *t1, *t2;
  247.     error = false;
  248.     //T
  249.     val = T(buffer);
  250.     if (!error)
  251.         return val;
  252.     //T + T
  253.     tmp = strdup(buffer);
  254.     if ((pch = strtok(tmp, "+")) != NULL)
  255.     {
  256.         val = T(pch);
  257.         if (error)
  258.         {
  259.             free(tmp);
  260.             goto minus;
  261.         }
  262.         if ((pch = strtok(NULL, "\0")) != NULL)
  263.         {
  264.             val += T(pch);
  265.             if (error) { ERR() }
  266.             free(tmp);
  267.             return val;
  268.         }
  269.     }
  270.     //T - T
  271. minus:
  272.     tmp = strdup(buffer);
  273.     if ((pch = strtok(tmp, "-")) != NULL)
  274.     {
  275.         val = T(pch);
  276.         if (error)
  277.         {
  278.             free(tmp);
  279.             goto multiply;
  280.         }
  281.         if ((pch = strtok(NULL, "\0")) != NULL)
  282.         {
  283.             val -= T(pch);
  284.             if (error) { ERR() }
  285.             free(tmp);
  286.             return val;
  287.         }
  288.     }
  289.     //T * T
  290. multiply:
  291.     tmp = strdup(buffer);
  292.     if ((pch = strtok(tmp, "*")) != NULL)
  293.     {
  294.         val = T(pch);
  295.         if (error)
  296.         {
  297.             free(tmp);
  298.             goto divide;
  299.         }
  300.         if ((pch = strtok(NULL, "\0")) != NULL)
  301.         {
  302.             val *= T(pch);
  303.             if (error) { ERR() }
  304.             free(tmp);
  305.             return val;
  306.         }
  307.     }
  308.     //T / T
  309. divide:
  310.     tmp = strdup(buffer);
  311.     if ((pch = strtok(tmp, "/")) != NULL)
  312.     {
  313.         val = T(pch);
  314.         if (error)
  315.         {
  316.             free(tmp);
  317.             goto modulo;
  318.         }
  319.         if ((pch = strtok(NULL, "\0")) != NULL)
  320.         {
  321.             val /= T(pch);
  322.             if (error) { ERR() }
  323.             free(tmp);
  324.             return val;
  325.         }
  326.     }
  327.     //T % T
  328. modulo:
  329.     tmp = strdup(buffer);
  330.     if ((pch = strtok(tmp, "%")) != NULL)
  331.     {
  332.         val = T(pch);
  333.         if (error)
  334.         {
  335.             ERR()
  336.         }
  337.         if ((pch = strtok(NULL, "\0")) != NULL)
  338.         {
  339.             val %= T(pch);
  340.             if (error) { ERR() }
  341.             free(tmp);
  342.             return val;
  343.         }
  344.     }
  345.     error = true;
  346.     return 0;
  347. }
  348. #undef ERR
  349.  
  350. int T(const char *buf)
  351. {
  352.     int val = 0;
  353.     variable *v = findVariable(buf);
  354.     error = false;
  355.     if (v != NULL)
  356.     {
  357.         return v->value;
  358.     }
  359.     else
  360.     {
  361.         if (isConstant(buf, &val))
  362.             return val;
  363.     }
  364.     error = true;
  365. }
  366.  
  367. void transferVariables(const std::vector<variable *> l, const char *_p)
  368. {
  369.     char *p = new char[strlen(_p) + 3];
  370.     sprintf(p, "%s.", _p);
  371.     for (int i = 0; i < l.size(); i++)
  372.     {
  373.         variable *v = l.at(i);
  374.         if (strstr(v->name, p) == v->name)
  375.         {
  376.             variable *tv;
  377.             if ((tv = findVariable(v->name)) != NULL)
  378.                 tv->value = v->value;
  379.             else
  380.                 variables.push_back(v);
  381.         }
  382.     }
  383.     delete[] p;
  384. }
  385.  
  386. void parseCode(FILE *f, const char *prefix)
  387. {
  388.     std::vector<variable *> save;
  389.     ret = false;
  390.     if (f != stdin)
  391.     {
  392.         save = variables;
  393.         variables.clear();
  394.         transferVariables(save, prefix);
  395.     }
  396.     for (; !ret;)
  397.     {
  398.         readInput(f);
  399.         if (strlen(buffer) == 0)
  400.         {
  401.             printf("\r                                                              \r");
  402.             continue;
  403.         }
  404.         if (!S())
  405.         {
  406.             printf("ERROR!\t%s\n", raw);
  407.         }
  408.     }
  409.     if (f != stdin)
  410.     {
  411.         std::vector<variable *> save2 = variables;
  412.         variables.clear();
  413.         variables = save;
  414.         transferVariables(save2, prefix);
  415.     }
  416.     fclose(f);
  417.     ret = false;
  418. }
  419.  
  420. int main(int argc, char ** argv)
  421. {
  422.     if (argc > 1)
  423.     {
  424.         FILE *f = fopen(argv[1], "r");
  425.         parseCode(f);
  426.     }
  427.     else
  428.         parseCode();
  429.     return 0;
  430. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement