Guest User

Untitled

a guest
Jan 25th, 2015
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.83 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <ctype.h>
  4.  
  5. enum TOKEN_ID
  6. {
  7.     NUM,
  8.     LBRACKET,
  9.     RBRACKET,
  10.     LPAREN,
  11.     RPAREN,
  12.     COMMA,
  13.     PLUS,
  14.     MINUS,
  15.     MUL
  16. };
  17.  
  18. typedef struct input
  19. {
  20.     enum TOKEN_ID id;
  21.     char *s;
  22.     int eof;
  23.     int num;
  24. } input;
  25.  
  26. typedef struct result
  27. {
  28.     double val;
  29.  
  30.     int is_vector;
  31.     size_t n;
  32.     double *vals;
  33. } result;
  34.  
  35. void
  36. error(char *msg)
  37. {
  38.     fprintf(stderr, "%s\n", msg);
  39.     exit(1);
  40. }
  41.  
  42. void
  43. getsym(input *i)
  44. {
  45.     for (;;) {
  46.         if (*(i->s) == '\0') {
  47.             i->eof = 1;
  48.             return;
  49.         }
  50.         if (isspace(*(i->s))) {
  51.             i->s++;
  52.         } else {
  53.             break;
  54.         }
  55.     }
  56.  
  57.     if (isdigit(*(i->s))) {
  58.         size_t l = 0;
  59.         char snum[20];
  60.  
  61.         do {
  62.             snum[l] = *(i->s);
  63.             l++;
  64.             if (l > sizeof(snum)) {
  65.                 error("Number too big");
  66.             }
  67.             i->s++;
  68.             if (*(i->s) == '\0') {
  69.                 i->eof = 1;
  70.                 break;
  71.             }
  72.         } while (isdigit(*(i->s)));
  73.         snum[l] = '\0';
  74.         i->num = atoi(snum);
  75.         i->id = NUM;
  76.         return;
  77.     }
  78.  
  79. #define SINGLE_SYM_TOKEN(SYM, ID)\
  80.     if (*(i->s) == SYM) {\
  81.         i->id = ID;\
  82.         i->s++;\
  83.         return;\
  84.     }
  85.  
  86.     SINGLE_SYM_TOKEN('[', LBRACKET)
  87.     SINGLE_SYM_TOKEN(']', RBRACKET)
  88.     SINGLE_SYM_TOKEN('(', LPAREN)
  89.     SINGLE_SYM_TOKEN(')', RPAREN)
  90.     SINGLE_SYM_TOKEN('+', PLUS)
  91.     SINGLE_SYM_TOKEN('-', MINUS)
  92.     SINGLE_SYM_TOKEN('*', MUL)
  93.     SINGLE_SYM_TOKEN(',', COMMA)
  94.  
  95. #undef SINGLE_SYM_TOKEN
  96.     error("Unknown token");
  97. }
  98.  
  99. int
  100. accept(input *i, enum TOKEN_ID id)
  101. {
  102.     if (i->id == id) {
  103.         getsym(i);
  104.         return 1;
  105.     }
  106.     return 0;
  107. }
  108.  
  109. int
  110. expect(input *i, enum TOKEN_ID id)
  111. {
  112.     if (accept(i, id)) {
  113.         return 1;
  114.     }
  115.     error("Unexpected symbol");
  116.     return 0;
  117. }
  118.  
  119. void
  120. result_init(result *r)
  121. {
  122.     r->is_vector = 0;
  123.     r->n = 0;
  124.     r->val = 0.0;
  125.     r->vals = NULL;
  126. }
  127.  
  128. void
  129. result_free(result *r)
  130. {
  131.     if (r->vals) {
  132.         free(r->vals);
  133.         r->vals = NULL;
  134.     }
  135.     r->is_vector = 0;
  136. }
  137.  
  138. void
  139. result_dump(result *a)
  140. {
  141.     size_t i;
  142.  
  143.     if (!a->is_vector) {
  144.         printf("%f\n", a->val);
  145.         return;
  146.     }
  147.  
  148.     printf("[");
  149.     for (i=0; i<a->n; i++) {
  150.         printf("%f", a->vals[i]);
  151.         if (i < (a->n - 1)) {
  152.             printf(", ");
  153.         }
  154.     }
  155.     printf("]\n");
  156. }
  157.  
  158. void
  159. result_swap(result *a, result *b)
  160. {
  161.     result tmp;
  162.  
  163.     tmp = *a;
  164.     *a = *b;
  165.     *b = tmp;
  166. }
  167.  
  168. void
  169. vector_push(result *r, int v)
  170. {
  171.     r->is_vector = 1;
  172.     r->n++;
  173.     r->vals = realloc(r->vals, r->n * sizeof(r->val));
  174.     r->vals[r->n - 1] = v;
  175. }
  176.  
  177. void
  178. result_mul(result *a, result *b)
  179. {
  180.     size_t i;
  181.  
  182.     if (a->is_vector && b->is_vector) {
  183.         error("Can't mul vector by vector");
  184.     }
  185.  
  186.     if (!a->is_vector && !b->is_vector) {
  187.         a->val *= b->val;
  188.         return;
  189.     }
  190.  
  191.     if (b->is_vector) {
  192.         result_swap(a, b);
  193.     }
  194.  
  195.     for (i=0; i<a->n; i++) {
  196.         a->vals[i] *= b->val;
  197.     }
  198. }
  199.  
  200. void
  201. result_inv(result *a)
  202. {
  203.     if (!a->is_vector) {
  204.         a->val = -a->val;
  205.     } else {
  206.         size_t i;
  207.  
  208.         for (i=0; i<a->n; i++) {
  209.             a->vals[i] = -a->vals[i];
  210.         }
  211.     }
  212. }
  213.  
  214. void
  215. result_plus(result *a, result *b)
  216. {
  217.     size_t i;
  218.  
  219.     if (!a->is_vector && !b->is_vector) {
  220.         a->val += b->val;
  221.         return;
  222.     }
  223.  
  224.     if (a->is_vector && b->is_vector) {
  225.         if (a->n < b->n) {
  226.             result_swap(a, b);
  227.         }
  228.  
  229.         for (i=0; i<b->n; i++) {
  230.             a->vals[i] += b->vals[i];
  231.         }
  232.     } else {
  233.         error("Can't add scalar to vector");
  234.     }
  235. }
  236.  
  237. void
  238. result_minus(result *a, result *b)
  239. {
  240.     result_inv(b);
  241.     result_plus(a, b);
  242. }
  243.  
  244.  
  245. result expression(input *i);
  246.  
  247. result
  248. vector(input *i)
  249. {
  250.     result r, tmp;
  251.  
  252.     result_init(&r);
  253.  
  254.     tmp = expression(i);
  255.     if (tmp.is_vector) {
  256.         error("Subvectors not allowed");
  257.     }
  258.     vector_push(&r, tmp.val);
  259.  
  260.     while (i->id != RBRACKET) {
  261.         expect(i, COMMA);
  262.         tmp = expression(i);
  263.         if (tmp.is_vector) {
  264.             error("Subvectors not allowed");
  265.         }
  266.         vector_push(&r, tmp.val);
  267.     }
  268.  
  269.     return r;
  270. }
  271.  
  272. result
  273. factor(input *i)
  274. {
  275.     result r;
  276.  
  277.     result_init(&r);
  278.  
  279.     if (accept(i, NUM)) {
  280.         r.val = i->num;
  281.     } else if (accept(i, LBRACKET)) {
  282.         r = vector(i);
  283.         expect(i, RBRACKET);
  284.     } else if (accept(i, LPAREN)) {
  285.         r = expression(i);
  286.         expect(i, RPAREN);
  287.     } else {
  288.         error("Syntax error");
  289.     }
  290.  
  291.     return r;
  292. }
  293.  
  294. result
  295. term(input *i)
  296. {
  297.     result left, r;
  298.  
  299.     left = factor(i);
  300.     while (i->id == MUL) {
  301.         getsym(i);
  302.         r = factor(i);
  303.         result_mul(&left, &r);
  304.         result_free(&r);
  305.     }
  306.  
  307.     return left;
  308. }
  309.  
  310. result
  311. expression(input *i)
  312. {
  313.     int inv = 0;
  314.     result left, r;
  315.  
  316.     if (i->id == PLUS || i->id == MINUS) {
  317.         if (i->id == MINUS) inv = 1;
  318.         getsym(i);
  319.     }
  320.  
  321.     left = term(i);
  322.     if (inv) {
  323.         result_inv(&left);
  324.     }
  325.  
  326.     while (i->id == PLUS || i->id == MINUS) {
  327.         int sign = i->id;
  328.         getsym(i);
  329.         r = term(i);
  330.         if (sign == MINUS) {
  331.             result_minus(&left, &r);
  332.         } else {
  333.             result_plus(&left, &r);
  334.         }
  335.         result_free(&r);
  336.     }
  337.  
  338.     return left;
  339. }
  340.  
  341.  
  342. int
  343. main()
  344. {
  345.     input i;
  346.     result r;
  347.  
  348.     i.eof = 0;
  349.     i.s = "5 * [1,2,3] + ( 5 * [3,2,1] - [1,2]) + [1,2,3,4,5,6]";
  350.  
  351.     getsym(&i);
  352.     r = expression(&i);
  353.     if (!i.eof) {
  354.         error("Incorrect expression");
  355.     }
  356.     result_dump(&r);
  357.  
  358.     result_free(&r);
  359.  
  360.     return 0;
  361. }
Advertisement
Add Comment
Please, Sign In to add comment