Advertisement
kknndd_

Untitled

May 14th, 2021
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.14 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include "lexer.h"
  6. #include "generator.h"
  7.  
  8. #define MAX_INPUT_SIZE 160
  9.  
  10. /*** Syntakticky analyzator a interpretator ***/
  11.  
  12. /* Overenie symbolu na vstupe a precitanie dalsieho.
  13.  * Vracia atribut overeneho symbolu. */
  14. int match(const Symbol expected)
  15. {
  16.     if (lex_symbol == expected) {
  17.         int attr = lex_attr;
  18.         next_symbol();
  19.         return attr;
  20.     } else {
  21.         fprintf(stderr,
  22.                 "CHYBA: Chyba symbol %s, namiesto toho sa vyskytol %s.\n",
  23.                 symbol_name(expected), symbol_name(lex_symbol));
  24.         exit(1);
  25.     }
  26. }
  27.  
  28. /* Tabulka premennych:
  29.  * index -- index identifikatora, hodnota -- hodnota premennej */
  30. int variables[LEX_IDS_MAX];
  31.  
  32. void read_variable(int id_idx)
  33. {
  34.     int value;
  35.     printf("%s = ", lex_ids[id_idx]);
  36.     scanf("%d", &value);
  37.     variables[id_idx] = value;
  38. }
  39.  
  40. /* Gramatika:
  41.  *
  42.  * Expr -> Term {("+"|"-") Term}
  43.  * Term -> VALUE | "(" Expr ")"
  44.  */
  45.  
  46. int expr(), term(), print(), read(), mul(), power(), equal(), let(), assign(), condition(), program();
  47.  
  48. int print(){
  49.  
  50.     if(lex_symbol == PRINT){
  51.         // sicko ok
  52.     } else {
  53.         fprintf(stderr,"Chyba prikaz PRINT ! objavil sa : %s", symbol_name(lex_symbol));
  54.     }
  55.  
  56.     next_symbol();
  57.     return equal();
  58.  
  59. }
  60.  
  61. int condition(){
  62.  
  63.     // let a; let b; if a < b ? print 1 : print 0;
  64.  
  65.     int res = -1;
  66.  
  67.     if(lex_symbol == IF){
  68.         next_symbol();
  69.  
  70.         if(equal()) {
  71.  
  72.             while( lex_symbol != ELSE ){
  73.  
  74.                 switch (lex_symbol) {
  75.                     case PRINT: res = print(); break;
  76.                     case ASSIGN: assign(); break;
  77.                 }
  78.                 if(lex_symbol == ELSE){
  79.                     break;
  80.                 }
  81.                 next_symbol();
  82.             }
  83.  
  84.             while(lex_symbol != SEMICOLON && lex_symbol != SEOF){
  85.                 next_symbol();
  86.             }
  87.  
  88.             next_symbol();
  89.  
  90.         } else {
  91.             while (lex_symbol != ELSE){
  92.                 next_symbol();
  93.             }
  94.  
  95.             while( lex_symbol != SEMICOLON ){
  96.  
  97.                 switch (lex_symbol) {
  98.                     case PRINT: res = print(); break;
  99.                     case ASSIGN: assign(); break;
  100.                 }
  101.                 if(lex_symbol == ELSE){
  102.                     break;
  103.                 }
  104.                 next_symbol();
  105.             }
  106.  
  107.             next_symbol();
  108.  
  109.         }
  110.  
  111.     }
  112.  
  113.     return res;
  114. }
  115.  
  116. int let(){
  117.  
  118.     int pocet_premennych = 0;
  119.  
  120.     if( lex_symbol == LET ){
  121.  
  122.         while( lex_symbol != SEMICOLON) {
  123.  
  124.             next_symbol();
  125.  
  126.             if(lex_symbol == SEMICOLON){
  127.                 break;
  128.             }
  129.  
  130.             if(lex_symbol == COMMA){
  131.                 next_symbol();
  132.             }
  133.  
  134.             if(lex_symbol == SEMICOLON){
  135.                 break;
  136.             }
  137.  
  138.             if(lex_symbol == ID){
  139.                 read_variable(lex_attr);
  140.             }
  141.  
  142.             pocet_premennych++;
  143.  
  144.             next_symbol();
  145.  
  146.         }
  147.  
  148.     }
  149.  
  150.     return pocet_premennych;
  151.  
  152. }
  153.  
  154. int read(){
  155.  
  156.     int pocet_premennych = 0;
  157.  
  158.     if(lex_symbol == READ){
  159.  
  160.         do {
  161.  
  162.             next_symbol();
  163.  
  164.             if(lex_symbol != ID){
  165.                 fprintf(stderr,"Chyba ID !");
  166.             } else {
  167.                 read_variable(lex_attr);
  168.             }
  169.  
  170.             next_symbol();
  171.             pocet_premennych++;
  172.  
  173.         } while (lex_symbol == COMMA);
  174.  
  175.     } else {
  176.         fprintf(stderr,"Chyba prikaz READ !");
  177.     }
  178.  
  179.     return pocet_premennych;
  180.  
  181. }
  182.  
  183. int assign(){
  184.  
  185.     int variables_count = 0;
  186.     // let a; a:=10; print a; -> 10
  187.     // let a,b; print a*b+5; let a,b; print (a*b)+5;
  188.     // let a,b; a:=b*b; print a;
  189.     // let a,b; print a*b;
  190.  
  191.     do {
  192.  
  193.         if(lex_symbol == COMMA){
  194.             next_symbol();
  195.         }
  196.  
  197.         int position = lex_attr;
  198.  
  199.         next_symbol();
  200.  
  201.         if(lex_symbol == SEMICOLON || lex_symbol == SEOF || lex_symbol != ASSIGN){
  202.             next_symbol();
  203.             break;
  204.         }
  205.  
  206.         next_symbol();
  207.  
  208.         // if assign
  209.         variables[position] = equal();
  210.         variables_count++;
  211.  
  212.     } while(lex_symbol != SEOF && lex_symbol != SEMICOLON);
  213.  
  214.     next_symbol();
  215.  
  216.     return variables_count;
  217.  
  218. }
  219.  
  220. int program (){
  221.  
  222.  
  223.     int j = 0;
  224.     int res = 0;
  225.  
  226.     while(lex_symbol != SEOF){
  227.         switch (lex_symbol) {
  228.             case LET: j = let(); break;
  229.             case READ: read(); break;
  230.             case ID: assign(); break;
  231.             case PRINT: res = print(); break;
  232.             case SEMICOLON: next_symbol(); break;
  233.             case IF: condition(); break;
  234.             case SEOF: break;
  235.         }
  236.  
  237.     }
  238.  
  239.     return res;
  240. }
  241.  
  242. /* Term -> VALUE | "(" Expr ")" */
  243. int term()
  244. {
  245.     int value;
  246.  
  247.     switch (lex_symbol) {
  248.         case VALUE:
  249.             value = lex_attr;
  250.             write_number(value);
  251.             next_symbol();
  252.             break;
  253.         case LPAR:
  254.             next_symbol();
  255.             value = expr();
  256.             match(RPAR);
  257.             break;
  258.         case ID:
  259.             write_var(lex_attr);
  260.             value = variables[lex_attr];
  261.             next_symbol();
  262.             break;
  263.         case SEOF: break;
  264. //        default:
  265. //        default:
  266.             //fprintf(stderr, "CHYBA: Chyba operand, namiesto toho sa vyskytol %s\n.",
  267. //                    symbol_name(lex_symbol));
  268. //            exit(1);
  269.     }
  270.  
  271.     return value;
  272. }
  273.  
  274. /* Expr -> Term {("+"|"-") Term} */
  275. int expr()
  276. {
  277.     int leftOp, rightOp;
  278.  
  279.     Symbol operator;
  280.     leftOp = mul();
  281.  
  282.     while (lex_symbol == PLUS || lex_symbol == MINUS) {
  283.  
  284.         operator = lex_symbol;
  285.  
  286.         next_symbol();
  287.  
  288.         rightOp = mul();
  289.  
  290.         switch (operator) {
  291.             case PLUS:
  292.                 write_add();
  293.                 leftOp = leftOp + rightOp;
  294.                 break;
  295.             case MINUS:
  296.                 write_sub();
  297.                 leftOp = leftOp - rightOp;
  298.                 break;
  299.             case SEOF:
  300.  
  301.                 break;
  302.             default:
  303.                 assert("Neocakavany operator v expr()");
  304.         }
  305.     }
  306.  
  307.  
  308.     return leftOp;
  309. }
  310.  
  311. int power(){
  312.     int leftOp, rightOp;
  313.  
  314.     leftOp = term();
  315.     Symbol operator = lex_symbol;
  316.  
  317.     while(operator == POWER){
  318.  
  319.         operator = lex_symbol;
  320.  
  321.         next_symbol();
  322.         rightOp = power();
  323.  
  324.         if(operator == POWER){
  325.             write_power(leftOp, rightOp);
  326.             leftOp = (int)pow(leftOp, rightOp);
  327.         }
  328.  
  329.     }
  330.  
  331.     return leftOp;
  332.  
  333. }
  334.  
  335. int mul(){
  336.  
  337.     int leftOp, rightOp;
  338.     Symbol operator;
  339.  
  340.     leftOp = power();
  341.  
  342.     operator = lex_symbol;
  343.  
  344.     while( operator == MUL || operator == DIV ) {
  345.  
  346.         operator = lex_symbol;
  347.  
  348.         if( operator == SEOF || operator == SEMICOLON ){
  349.             break;
  350.         }
  351.  
  352.         next_symbol();
  353.  
  354.         rightOp = power();
  355.  
  356.         switch ( operator ) {
  357.             case MUL:
  358.                 write_mul();
  359.                 leftOp = leftOp * rightOp;
  360.                 break;
  361.             case DIV:
  362.                 write_div();
  363.                 leftOp = leftOp / rightOp;
  364.                 break;
  365.             default:
  366.                 break;
  367.                     //fprintf(stderr, "CHYBA: Neocakavany  ('%s') operator pri deleni a nasobeni", symbol_name(operator));
  368.         }
  369.  
  370.     }
  371.  
  372.     return leftOp;
  373.  
  374. }
  375.  
  376. int equal(){
  377.  
  378.     int leftOp = expr(), rightOp;
  379.     Symbol operator = lex_symbol;
  380.  
  381.     while(
  382.             operator == EQUAL ||
  383.             operator == GREATER_THAN ||
  384.             operator == GREATER_THAN_EQUAL ||
  385.             operator == LESS_THAN_EQUAL ||
  386.             operator == LESS_THAN
  387.             ){
  388.  
  389.         operator = lex_symbol;
  390.         next_symbol();
  391.  
  392.         rightOp = expr();
  393.  
  394.         switch ( operator ) {
  395.             case EQUAL: leftOp = leftOp == rightOp; break;
  396.             case GREATER_THAN_EQUAL: leftOp = leftOp >= rightOp; break;
  397.             case GREATER_THAN: leftOp = leftOp > rightOp; break;
  398.             case LESS_THAN_EQUAL: leftOp = leftOp <= rightOp; break;
  399.             case LESS_THAN: leftOp = leftOp < rightOp; break;
  400.             case SEOF: break;
  401.             //default: fprintf(stderr ,"CHYBA: ockava sa operator porovnania nie : ('%s') ", symbol_name(lex_symbol)); break;
  402.         }
  403.  
  404.     }
  405.  
  406.     return leftOp;
  407.  
  408. }
  409.  
  410. int main(int argc, char** argv)
  411. {
  412.  
  413.     // otvorenie suboru pre Computron VM
  414.     FILE *output_file = fopen("program.bin", "wb");
  415.     init_generator(output_file);
  416.  
  417.     printf("Vstupny retazec: ");
  418.     // Citanie vstupneho retazca
  419.     char source[MAX_INPUT_SIZE];
  420.     fgets(source, MAX_INPUT_SIZE, stdin);
  421.  
  422.     init_lexer(source);
  423.     print_tokens();
  424.  
  425.     printf("\nZaciatok syntaxou riadenej interpretacie\n\n");
  426.     init_lexer(source);
  427.     next_symbol();
  428.  
  429.     // volanie programu
  430.     int result = program();
  431.     printf("Vysledok: %d\n", result);
  432.  
  433.  
  434.     write_result();
  435.     // ukoncenie prace s binarnym suborom pre Computron VM
  436.     generate_output();
  437.     fclose(output_file);
  438.     printf("Program vygenerovany v program.bin\n");
  439.  
  440.     getchar();
  441.     return 0;
  442. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement