Advertisement
andruhovski

SysProg-01-2017

Oct 2nd, 2017
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.50 KB | None | 0 0
  1. // SysProg01.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #define DELIMITER   1
  6. #define VARIABLE    2
  7. #define NUMBER      3
  8. #define COMMAND     4
  9. #define STRING      5
  10. #define QUOTE       6
  11. #define PRINT       7
  12. #define INPUT       8
  13. #define IF          9
  14. #define THEN        10
  15. #define FOR         11
  16. #define NEXT        12
  17. #define TO          13
  18. #define GOTO        14
  19. #define EOL         15
  20. #define FINISHED    16
  21. #define GOSUB       17
  22. #define RETURN      18
  23. #define END         19
  24. #define NUM_LAB     100
  25. #define LAB_LEN     10
  26. #define FOR_NEST    25
  27. #define SUB_NEST    25
  28. #define PROG_SIZE   10240
  29.  
  30. struct for_stack {
  31.     int var;    //поточний стан
  32.     int target; //кінцеве значення
  33.     int step;   // крок
  34.     char* loc;  //точка входу в цикл
  35. };
  36. struct for_stack fstack[FOR_NEST];
  37.  
  38. int variables[26] = {
  39.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  40.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  41.     0, 0, 0, 0, 0, 0 };
  42. int token_type;                     //тип лексеми    
  43. int tok;                            //уточнення типу
  44. #if _DEBUG
  45. char *prog = "10 PRINT \"TEST\"\r\n20 PRINT \"TEST2\"\r\n30 GOSUB 100\r\n40 PRINT \"TEST3\"\r\n50 END\r\n100 PRINT \"ABC\"\r\n110 RETURN";
  46. #else
  47. char *prog;
  48. #error Реалізуйте завантаження програми
  49. #endif
  50.  
  51. char token[256];                    //для збереження значень лексем
  52.  
  53. int get_token(void);
  54. int isdelim(char c);
  55. int look_up(char *s);
  56. struct commands
  57. {
  58.     char command[20];
  59.     char tok;
  60. }
  61. table[] = {
  62.     "print", PRINT,
  63.     "input", INPUT,
  64.     "if", IF,
  65.     "then", THEN,
  66.     "goto", GOTO,
  67.     "for", FOR,
  68.     "next", NEXT,
  69.     "to", TO,
  70.     "gosub", GOSUB,
  71.     "return", RETURN,
  72.     "end", END,
  73.     "", END
  74. };
  75. struct label
  76. {
  77.     char name[LAB_LEN];
  78.     char *p;
  79. };
  80. struct label label_table[NUM_LAB];
  81.  
  82. void print(void);
  83. void scan_label(void);
  84. void find_eol(void);
  85. void exec_if(void);
  86. void exec_for(void);
  87. void next(void);
  88. void fpush(struct for_stack i);
  89. struct for_stack fpop(void);
  90. int ftos;
  91. int gtos;
  92. void input(void);
  93. void gosub(void);
  94. void putback(void);
  95. void greturn(void);
  96. void label_init(void);
  97. char *find_label(char *s);
  98. int find_var(char *s);
  99. int load_program(char *p, char *fname);
  100. int assignment(void);
  101. void serror(int error);
  102. void gpush(char *s);
  103. char *gpop(void);
  104. int get_next_label(char *s);
  105. int look_up(char *s);
  106. int isdelim(char c);
  107. int is_space(char s);
  108. void get_exp(int *result);
  109. void level2(int *result);
  110. void level3(int *result);
  111. void level4(int *result);
  112. void level5(int *result);
  113. void level6(int *result);
  114. void primitive(int *result);
  115. void arith(char o, int *r, int *h);
  116. void unary(char o, int *r);
  117. void putback();
  118. char *gstack[SUB_NEST];
  119.  
  120.  
  121. int _tmain(int argc, _TCHAR* argv[])
  122. {
  123.     scan_label();
  124.     ftos = 0;
  125.     gtos = 0;
  126.     do
  127.     {
  128.         token_type = get_token();
  129.         if (token_type == VARIABLE)
  130.         {
  131.             putback();
  132.             assignment();
  133.         }
  134.         switch (tok)
  135.         {
  136.         case PRINT:
  137.             print();
  138.             break;
  139.         case IF:
  140.             exec_if();
  141.             break;
  142.         case FOR:
  143.             exec_for();
  144.             break;
  145.         case NEXT:
  146.             next();
  147.             break;
  148.         case INPUT:
  149.             input();
  150.             break;
  151.         case GOSUB:
  152.             gosub();
  153.             break;
  154.         case RETURN:
  155.             greturn();
  156.             break;
  157.         case END:
  158.             exit(0);
  159.         }
  160.     } while (tok != FINISHED);
  161.     return 0;
  162. }
  163.  
  164. int get_token(void)
  165. {
  166.     char *temp;
  167.     token_type = 0;
  168.     tok = 0;
  169.     temp = token;
  170.     if (*prog == '\0')
  171.     {
  172.         *token = 0;
  173.         tok = FINISHED;
  174.         return (token_type = DELIMITER);
  175.     }
  176.  
  177.     while (is_space(*prog)) prog++;
  178.     if (*prog == '\r')
  179.     {
  180.         prog += 2;
  181.         tok = EOL;
  182.         token[0] = '\r';
  183.         token[1] = '\n';
  184.         token[2] = 0;
  185.         return (token_type = DELIMITER);
  186.     }
  187.  
  188.     if (strchr("*+-^/%=;(),><", *prog) != NULL)
  189.     {
  190.         *temp = *prog;
  191.         prog++;
  192.         temp++;
  193.         *temp = 0;
  194.         return (token_type = DELIMITER);
  195.     }
  196.  
  197.     if (*prog == '"')
  198.     {
  199.         prog++;
  200.         while (*prog != '"' && *prog != '\r')
  201.             *temp++ = *prog++;
  202.         *temp = 0; prog++;
  203.         return (token_type = QUOTE);
  204.     }
  205.  
  206.     if (isdigit(*prog))
  207.     {
  208.         while (!isdelim(*prog))
  209.             *temp++ = *prog++;
  210.         *temp = '\0';
  211.         return (token_type = NUMBER);
  212.     }
  213.  
  214.     if (isalpha(*prog))
  215.     {
  216.         while (!isdelim(*prog))
  217.             *temp++ = *prog++;
  218.         token_type = STRING;
  219.     }
  220.     *temp = '\0';
  221.     if (token_type == STRING)
  222.     {
  223.         tok = look_up(token);
  224.         if (!tok)
  225.             token_type = VARIABLE;
  226.         else
  227.             token_type = COMMAND;
  228.     }
  229.     return token_type;
  230. }
  231.  
  232. int look_up(char *s)
  233. {
  234.     register int i;
  235.     char *p;
  236.     p = s;
  237.     while (*p)
  238.     {
  239.         *p = tolower(*p);
  240.         p++;
  241.     }
  242.  
  243.     for (i = 0; *table[i].command; i++)
  244.         if (!strcmp(table[i].command, s))
  245.             return table[i].tok;
  246.     return 0;
  247. }
  248.  
  249. int isdelim(char c)
  250. {
  251.     if ((strchr(" ;,+-<>/*%^=()", c) != NULL) || c == 9 || c == '\r' || c == 0)
  252.         return 1;
  253.     return 0;
  254. }
  255.  
  256. int is_space(char c)
  257. {
  258.     if (c == ' ' || c == '\t')
  259.         return 1;
  260.     return 0;
  261. }
  262.  
  263. int load_program(char *p, char *fname)
  264. {
  265.     FILE *fp;
  266.     int prg_size;
  267.     int err = fopen_s(&fp, fname, "rb");
  268.     if (err != 0)
  269.     {
  270.         fprintf(stderr, "The file was not opened\n");
  271.         exit(0);
  272.     }
  273.  
  274.     prg_size = fread(p, PROG_SIZE, sizeof(char), fp);
  275.     *(p - prg_size - 2) = '\0';
  276.     fclose(fp);
  277.     return 1;
  278. }
  279.  
  280. int assignment(void)
  281. {
  282.     int var, value;
  283.     get_token();
  284.     if (!isalpha(*token))
  285.     {
  286.         serror(4);
  287.         return 0;
  288.     }
  289.     var = toupper(*token) - 'A';
  290.     get_token();
  291.     if (*token != '=')
  292.     {
  293.         serror(3);
  294.         return 0;
  295.     }
  296.     get_exp(&value);
  297.     variables[var] = value;
  298.     return 0;
  299. }
  300.  
  301. void putback()
  302. {
  303.     char *t;
  304.     t = token;
  305.     for (; *t; t++)
  306.         prog--;
  307. }
  308.  
  309. void scan_label()
  310. {
  311.     int addr;
  312.     char *temp;
  313.     label_init();
  314.     temp = prog;
  315.     get_token();
  316.     if (token_type == NUMBER)
  317.     {
  318.         strcpy_s(label_table[0].name, LAB_LEN, token);
  319.         label_table[0].p = prog;
  320.     }
  321.     find_eol();
  322.     do
  323.     {
  324.         get_token();
  325.         if (token_type == NUMBER)
  326.         {
  327.             addr = get_next_label(token);
  328.             if (addr == -1 || addr == -2)
  329.             {
  330.                 (addr == -1) ? serror(5) : serror(6);
  331.             }
  332.             strncpy_s(label_table[addr].name, LAB_LEN, token, LAB_LEN-1);
  333.             label_table[addr].p = prog;
  334.         }
  335.         if (tok != EOL)
  336.             find_eol();
  337.     } while (tok != FINISHED);
  338.     prog = temp;
  339. }
  340.  
  341. void find_eol()
  342. {
  343.     while (*prog != '\n' && *prog != '\0')
  344.         ++prog;
  345.     if (*prog)
  346.         prog++;
  347. }
  348.  
  349. int get_next_label(char *s)
  350. {
  351.     register int t;
  352.     for (t = 0; t<NUM_LAB; ++t)
  353.     {
  354.         if (label_table[t].name[0] == 0)
  355.             return t;
  356.         if (!strcmp(label_table[t].name, s))
  357.             return -2;
  358.     }
  359.     return -1;
  360. }
  361.  
  362. char *find_label(char *s)
  363. {
  364.     register int t;
  365.     for (t = 0; t<NUM_LAB; t++)
  366.         if (!strcmp(label_table[t].name, s))
  367.             return label_table[t].p;
  368.     return'\0';
  369. }
  370.  
  371. void exec_goto()
  372. {
  373.     char *loc;
  374.     get_token();
  375.     loc = find_label(token);
  376.     if (loc == '\0')
  377.         serror(7);
  378.     else
  379.         prog = loc;
  380. }
  381.  
  382. void label_init()
  383. {
  384.     memset(label_table, 0, sizeof(label_table));
  385. }
  386.  
  387. void print()
  388. {
  389.     int answer;
  390.     int len = 0, spaces;
  391.     char last_delim = '\0';
  392.     do
  393.     {
  394.         get_token();
  395.         if (tok == EOL || tok == FINISHED)
  396.             break;
  397.         if (token_type == QUOTE)
  398.         {
  399.             printf("%s", token);
  400.             len += strlen(token);
  401.             get_token();
  402.         }
  403.         else
  404.         {
  405.             putback();
  406.             get_exp(&answer);
  407.             get_token();
  408.             len += printf("%d", answer);
  409.         }
  410.  
  411.         last_delim = *token;
  412.         if (*token == ',')
  413.         {
  414.             spaces = 8 - (len % 8);
  415.             len += spaces;
  416.             while (spaces)
  417.             {
  418.                 putchar(' ');
  419.                 spaces--;
  420.             }
  421.         }
  422.         else{
  423.             if ((*token != ';')
  424.                 && (tok != EOL)
  425.                 && (tok != FINISHED))
  426.                 serror(0);
  427.         }
  428.            
  429.     } while (*token == ';' || *token == ',');
  430.  
  431.     if (tok == EOL || tok == FINISHED)
  432.     {
  433.         if (last_delim != ';' || last_delim != ',')
  434.             putchar('\n');
  435.     }
  436.     else
  437.         serror(0);
  438. }
  439.  
  440. void input()
  441. {
  442.     char var;
  443.     int i;
  444.     get_token();
  445.     if (token_type == QUOTE)
  446.     {
  447.         printf(token);
  448.         get_token();
  449.         if (*token != ',')
  450.             serror(1);
  451.         get_token();
  452.     }
  453.     else
  454.         printf("? ");
  455.     var = toupper(*token) - 'A'; //toupper - перетворити до вел. літери tolower - перетворити до мал. літ.
  456.     if (var >= 0 && var <= 25)
  457.     {
  458.         scanf_s("%d", &i);
  459.         variables[var] = i;
  460.     }
  461.     else
  462.     {
  463.         serror(99);
  464.     }
  465. }
  466.  
  467. void gosub()
  468. {
  469.     char *loc;
  470.     get_token();
  471.     if (token_type != NUMBER) {
  472.         //....
  473.     }
  474.     loc = find_label(token);
  475.     if (loc == '\0')
  476.         serror(7);
  477.     else
  478.     {
  479.         gpush(prog);
  480.         prog = loc;
  481.     }
  482. }
  483.  
  484. void gpush(char *s)
  485. {
  486.     gtos++;
  487.     if (gtos == SUB_NEST)
  488.     {
  489.         serror(12);
  490.         return;
  491.     }
  492.     gstack[gtos] = s;
  493. }
  494.  
  495. void greturn()
  496. {
  497.     prog = gpop();
  498. }
  499.  
  500. char *gpop(void)
  501. {
  502.     if (gtos == 0)
  503.     {
  504.         serror(13);
  505.         return 0;
  506.     }
  507.     return gstack[gtos--];
  508. }
  509.  
  510. void goto_operator()
  511. {
  512.     char *loc;
  513.     get_token();
  514.     loc = find_label(token);
  515.     if (loc == '\0')
  516.         serror(7);
  517.     else
  518.         prog = loc;
  519. }
  520.  
  521. void get_exp(int *result)
  522. {
  523.     get_token();
  524.     if (!(*token))
  525.     {
  526.         serror(2);
  527.         return;
  528.     }
  529.     level2(result);
  530.     putback();
  531. }
  532.  
  533. void level2(int *result)
  534. {
  535.     char op;
  536.     int hold;
  537.     level3(result);
  538.     while (((op = *token) == '+') || (op == '-'))
  539.     {
  540.         get_token();
  541.         level3(&hold);
  542.         arith(op, result, &hold);
  543.     }
  544. }
  545.  
  546. void level3(int *result)
  547. {
  548.     char op;
  549.     int hold;
  550.     level4(result); //P1
  551.     while (((op = *token) == '*') || (op == '/') || (op == '%'))
  552.     {
  553.         get_token();
  554.         level4(&hold); //P2
  555.         arith(op, result, &hold);
  556.     }
  557. }
  558.  
  559. void level4(int *result)
  560. {
  561.     char op = '\0';
  562.     int hold;
  563.     level5(result);
  564.     if (*token == '^')
  565.     {
  566.         get_token();
  567.         level5(&hold);
  568.         arith('^', result, &hold);
  569.     }
  570.     //get_token();
  571. }
  572.  
  573. void level5(int *result)
  574. {
  575.     char op = 0;
  576.     if ((token_type == DELIMITER) && (*token == '+') || (*token == '-'))
  577.     {
  578.         op = *token;
  579.         get_token();
  580.     }
  581.     level6(result);
  582.     if (op)
  583.         unary(op, result);
  584. }
  585.  
  586. void level6(int *result)
  587. {
  588.     if ((*token == '(') && (token_type == DELIMITER))
  589.     {
  590.         get_token();
  591.         level2(result);
  592.         if (*token != ')') serror(1);
  593.         get_token();
  594.     }
  595.     else
  596.         primitive(result);
  597. }
  598.  
  599. void primitive(int *result)
  600. {
  601.     switch (token_type)
  602.     {
  603.     case VARIABLE: *result = find_var(token);
  604.         get_token();
  605.         return;
  606.     case NUMBER: *result = atoi(token);
  607.         get_token();
  608.         return;
  609.     default: serror(0);
  610.     }
  611. }
  612.  
  613. void arith(char o, int *r, int *h)
  614. {
  615.     int t = 0, ex = 0;
  616.     switch (o)
  617.     {
  618.     case '-': *r = *r - *h;
  619.         break;
  620.     case '*': *r = *r * *h;
  621.         break;
  622.     case '/': *r = *r / *h;
  623.         break;
  624.     case '%': *r = *r % *h;
  625.         break;
  626.     case '+': *r = *r + *h;
  627.         break;
  628.     case '^': ex = *r;
  629.         if (*h == 0) { *r = 1; break; }
  630.         for (int t = 1; t<*h; t++)
  631.             *r = (*r) * ex;
  632.         break;
  633.     }
  634. }
  635.  
  636. void exec_if(void)
  637. {
  638.     int x, y, cond;
  639.     char op;
  640.     get_exp(&x);
  641.     //prog--;
  642.     get_token();
  643.     if (!strchr("=<>", *token))
  644.     {
  645.         serror(0);
  646.     }
  647.     op = *token;
  648.     get_exp(&y);
  649.     prog--;
  650.     cond = 0;
  651.     switch (op)
  652.     {
  653.     case '=': if (x == y) cond = 1; break;
  654.     case '<': if (x < y) cond = 1; break;
  655.     case '>': if (x > y) cond = 1; break;
  656.     }
  657.     if (cond)
  658.     {
  659.         get_token();
  660.         if (tok != THEN)
  661.         {
  662.             serror(8);
  663.         }
  664.     }
  665.     else
  666.     {
  667.         find_eol();
  668.     }
  669. }
  670. void unary(char o, int *r)
  671. {
  672.     if (o == '-') *r = -*r;
  673. }
  674. void exec_for(void)
  675. {
  676.     struct for_stack i;
  677.     int value;
  678.     get_token();
  679.     if (token_type != VARIABLE)
  680.     {
  681.         serror(4);
  682.         return;
  683.     }
  684.     i.var = toupper(*token) - 'A';
  685.     get_token();
  686.     if (*token != '=')
  687.     {
  688.         serror(3);
  689.         return;
  690.     }
  691.     get_exp(&value);
  692.     variables[i.var] = value;
  693.     get_token();
  694.     if (tok != TO)
  695.     {
  696.         serror(9);
  697.         return;
  698.     }
  699.     get_exp(&i.target);
  700.     get_token();
  701.     /*if (tok != STEP)
  702.     {
  703.     serror(19);
  704.     return;
  705.     }
  706.     get_exp(&i.?????);*/
  707.  
  708.     if (value >= variables[i.var])
  709.     {
  710.         i.loc = prog;
  711.         fpush(i);
  712.     }
  713.     else
  714.         while (tok != NEXT)
  715.             get_token();
  716. }
  717.  
  718. void next()
  719. {
  720.     struct for_stack i;
  721.     i = fpop();
  722.     //variables[i.var] += i.step; //+1
  723.     variables[i.var] ++;
  724.     if (variables[i.var] > i.target) return;
  725.     prog = i.loc;
  726.     fpush(i);
  727. }
  728.  
  729. void fpush(struct for_stack i)
  730. {
  731.     if (ftos > FOR_NEST)
  732.     {
  733.         serror(10);
  734.         return;
  735.     }
  736.     fstack[ftos++] = i;
  737. }
  738.  
  739. struct for_stack fpop()
  740. {
  741.     ftos--;
  742.     if (ftos < 0) { serror(11); }
  743.     return (fstack[ftos]);
  744. }
  745.  
  746. void serror(int k)
  747. {
  748.     switch (k)
  749.     {
  750.     case 0: printf("Syntaksychna pomylka.\n"); break;
  751.     case 1: printf("Neparni krugli duzhky.\n"); break;
  752.     case 2: printf("Pomylka u vyrazi, propuschenyy znak.\n"); break;
  753.     case 3: printf("Ochikuet'sya znak dorivnue.\n"); break;
  754.     case 4: printf("Ochikuet'sya zminna.\n"); break;
  755.     case 5: printf("Tablycyu mitok perepovneno.\n"); break;
  756.     case 6: printf("Dubluut'sya mitky.\n"); break;
  757.     case 7: printf("Nevyznachena mitka.\n"); break;
  758.     case 8: printf("Ochikuet'sya THEN.\n"); break;
  759.     case 9: printf("Ochikuet'sya TO.\n"); break;
  760.     case 10: printf("Perevyscheno riven' vkladenosti FOR.\n"); break;
  761.     case 11: printf("NEXT bez FOR.\n"); break;
  762.     case 12: printf("Perevyscheno riven' vkladenosti GO SUB.\n"); break;
  763.     case 13: printf("RETURN bez GO SUB.\n"); break;
  764.     }
  765.     exit(1);
  766. }
  767. int find_var(char *s)
  768. {
  769.     char i = toupper(*s) - 'A';
  770.     if (i<0 || i>25) serror(2);
  771.     return variables[i];
  772.  
  773. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement