Advertisement
Guest User

Untitled

a guest
May 26th, 2017
525
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.68 KB | None | 0 0
  1. /** @file
  2. Implementacja kaltulatora
  3.  
  4. @author Krzysztof Olejnik <ko361240@students.mimuw.edu.pl>
  5. */
  6.  
  7. #include <stdbool.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <memory.h>
  11. #include <ctype.h>
  12. #include <limits.h>
  13.  
  14. #include "poly.h"
  15. #include "check_poly.h"
  16. #include "stack.h"
  17.  
  18. #define WRONG_COMMAND -2
  19. #define STACK_UNDERFLOW -3
  20. #define WRONG_VALUE -4
  21. #define WRONG_VARIABLE -5
  22.  
  23. Poly ParseOnePoly(char *poly, unsigned *pos);
  24.  
  25. Mono ParseOneMono(char *poly, unsigned *pos)
  26. {
  27. Poly poly_coeff;
  28. *pos = *pos + 1;
  29.  
  30. if (poly[*pos] == '(')
  31. {
  32. poly_coeff = ParseOnePoly(poly, pos);
  33. }
  34. else
  35. {
  36. Mono *next;
  37. poly_coeff_t coeff = strtol(&poly[*pos], &next, 10);
  38.  
  39. while (&poly[*pos] != next)
  40. {
  41. *pos = *pos + 1;
  42. }
  43.  
  44. poly_coeff = PolyFromCoeff(coeff);
  45. }
  46.  
  47. Mono *next;
  48. poly_exp_t exp = (poly_exp_t)strtol(&poly[*pos], next, 10);
  49.  
  50. while (&poly[*pos] != next)
  51. {
  52. *pos = *pos + 1;
  53. }
  54.  
  55. return MonoFromPoly(&poly_coeff, exp);
  56. }
  57.  
  58. Poly ParseOnePoly(char *poly, unsigned *pos)
  59. {
  60. if (poly[*pos] != '(')
  61. {
  62. Mono *next;
  63. Poly PolyCoeff = PolyFromCoeff(strtol(&poly[*pos], &next, 10));
  64.  
  65. while (&poly[*pos] != next)
  66. {
  67. *pos = *pos + 1;
  68. }
  69.  
  70. return PolyCoeff;
  71. }
  72.  
  73. Mono *monos = (Mono *)malloc(sizeof(Mono));
  74. unsigned size = 1;
  75. unsigned first_free = 0;
  76. bool end_of_list = false;
  77.  
  78. while (!end_of_list)
  79. {
  80. if (size == first_free)
  81. {
  82. size = size * 2;
  83. monos = realloc(monos, size * sizeof(Mono));
  84. }
  85.  
  86. monos[first_free] = ParseOneMono(poly, pos);
  87.  
  88. if (poly[*pos] != '+')
  89. {
  90. end_of_list = true;
  91. }
  92. else
  93. {
  94. *pos = *pos + 1;
  95. first_free++;
  96. }
  97. }
  98.  
  99. monos = realloc(monos, first_free * sizeof(Mono));
  100.  
  101. Poly result = PolyAddMonos(first_free, monos);
  102. free(monos);
  103.  
  104. return result;
  105. }
  106.  
  107. Poly ParsePoly(char *poly)
  108. {
  109. unsigned pos = 0;
  110. return ParseOnePoly(poly, &pos);
  111. }
  112.  
  113. char *DoubleTheSize(char *array, unsigned size)
  114. {
  115. char *new_array = (char *)malloc(2 * size);
  116. strncpy(new_array, array, size);
  117. free(array);
  118. return new_array;
  119. }
  120.  
  121. char *ReadOneLine()
  122. {
  123. char *line = (char *)malloc(sizeof(char));
  124. unsigned first_free = 0;
  125. unsigned current_size = 1;
  126.  
  127. do
  128. {
  129. if (first_free == current_size)
  130. {
  131. current_size = current_size * 2;
  132. line = realloc(line, current_size * sizeof(char));//DoubleTheSize(line, current_size);
  133. }
  134.  
  135. int temp = (char)getchar();
  136.  
  137. if (temp == EOF)
  138. {
  139. free(line);
  140. return NULL;
  141. }
  142.  
  143. line[first_free] = (char)temp;
  144. first_free++;
  145. } while (line[first_free - 1] != '\n');
  146.  
  147. line[first_free - 1] = '\0';
  148.  
  149. line = realloc(line, first_free);
  150.  
  151. return line;
  152. }
  153.  
  154. long Choose(long a, long b)
  155. {
  156. if (a == CORRECT || b == CORRECT)
  157. {
  158. return CORRECT;
  159. }
  160. else
  161. {
  162. return a > b ? a : b;
  163. }
  164. }
  165.  
  166. long CheckSizeOfNumber(char *str, long pos, int type)
  167. {
  168. bool empty = true;
  169. long long number = 0;
  170. long i = pos;
  171. long long max = 0;
  172. long long min = 0;
  173.  
  174. if (type == EXP)
  175. {
  176. max = INT_MAX;
  177. min = 0;
  178. }
  179. else if (type == IDX)
  180. {
  181. max = UINT_MAX;
  182. min = 0;
  183. }
  184. else if (type == POINT)
  185. {
  186. max = LONG_MAX;
  187. min = LONG_MIN;
  188. }
  189.  
  190. if (str[i] == '-')
  191. {
  192. empty = false;
  193. int value = str[i + 1] - '0';
  194. number = value * (-1);
  195.  
  196. if (number > max || number < min)
  197. {
  198. return i + 1;
  199. }
  200.  
  201. i = i + 2;
  202. }
  203.  
  204. while (isdigit(str[i]))
  205. {
  206. empty = false;
  207. number *= 10;
  208. int value = str[i] - '0';
  209.  
  210. if (str[pos] == '-')
  211. {
  212. number -= value;
  213. }
  214. else
  215. {
  216. number += value;
  217. }
  218.  
  219. if (number > max || number < min)
  220. {
  221. return i + 1;
  222. }
  223.  
  224. i++;
  225. }
  226.  
  227. if (empty)
  228. {
  229. return pos + 1;
  230. }
  231.  
  232. return CORRECT;
  233. }
  234.  
  235. void PrintPoly(Poly *p);
  236.  
  237. void PrintMono(Mono *m)
  238. {
  239. printf("(");
  240. PrintPoly(&m->p);
  241. printf(",%d)", m->exp);
  242. }
  243.  
  244. void PrintPoly(Poly *p)
  245. {
  246. if (PolyIsCoeff(p))
  247. {
  248. printf("%li", p->coeff);
  249. }
  250. else
  251. {
  252. for (unsigned i = 0; i < p->size; i++)
  253. {
  254. PrintMono(&(p->arr[i]));
  255.  
  256. if (i != p->size - 1)
  257. {
  258. printf("+");
  259. }
  260. }
  261. }
  262. }
  263.  
  264. //sprawdza czy to co znajduje się w command[pos] - command[strlen(command) - 1] jest liczbą
  265. bool CheckNumber(char *command, unsigned pos)
  266. {
  267. unsigned size = strlen(command);
  268.  
  269. if (pos == size)
  270. {
  271. return false;
  272. }
  273.  
  274. for (unsigned i = pos; i < size; i++)
  275. {
  276. if (!isdigit(command[i]) && command[i] != '-')
  277. {
  278. return false;
  279. }
  280. }
  281.  
  282. return true;
  283. }
  284.  
  285. long CalculateComand(char *command, Stack *stack)
  286. {
  287. if (strcmp(command, "ZERO") == 0)
  288. {
  289. Poly p = PolyZero();
  290. Push(stack, p);
  291.  
  292. return CORRECT;
  293. }
  294. else if(strcmp(command, "IS_COEFF") == 0)
  295. {
  296. if (IsEmpty(stack))
  297. {
  298. return STACK_UNDERFLOW;
  299. }
  300.  
  301. Poly p = Top(stack);
  302.  
  303. if (PolyIsCoeff(&p))
  304. {
  305. printf("%d\n", 1);
  306. }
  307. else
  308. {
  309. printf("%d\n", 0);
  310. }
  311.  
  312. return CORRECT;
  313. }
  314. else if(strcmp(command, "IS_ZERO") == 0)
  315. {
  316. if (IsEmpty(stack))
  317. {
  318. return STACK_UNDERFLOW;
  319. }
  320.  
  321. Poly p = Top(stack);
  322.  
  323. if (PolyIsZero(&p))
  324. {
  325. printf("%d\n", 1);
  326. }
  327. else
  328. {
  329. printf("%d\n", 0);
  330. }
  331.  
  332. return CORRECT;
  333. }
  334. else if(strcmp(command, "CLONE") == 0)
  335. {
  336. if (IsEmpty(stack))
  337. {
  338. return STACK_UNDERFLOW;
  339. }
  340.  
  341. Poly p = Top(stack);
  342. Poly new_p = PolyClone(&p);
  343. Push(stack, new_p);
  344.  
  345. return CORRECT;
  346. }
  347. else if(strcmp(command, "ADD") == 0)
  348. {
  349. if (IsEmpty(stack) || stack->top->next == NULL)
  350. {
  351. return STACK_UNDERFLOW;
  352. }
  353.  
  354. Poly p = PopAndReturn(stack);
  355. Poly q = PopAndReturn(stack);
  356. Poly new_poly = PolyAdd(&p, &q);
  357. Push(stack, new_poly);
  358. PolyDestroy(&p);
  359. PolyDestroy(&q);
  360.  
  361. return CORRECT;
  362. }
  363. else if(strcmp(command, "MUL") == 0)
  364. {
  365. if (IsEmpty(stack) || stack->top->next == NULL)
  366. {
  367. return STACK_UNDERFLOW;
  368. }
  369.  
  370. Poly p = PopAndReturn(stack);
  371. Poly q = PopAndReturn(stack);
  372. Poly new_poly = PolyMul(&p, &q);
  373. Push(stack, new_poly);
  374. PolyDestroy(&p);
  375. PolyDestroy(&q);
  376.  
  377. return CORRECT;
  378. }
  379. else if(strcmp(command, "NEG") == 0)
  380. {
  381. if (IsEmpty(stack))
  382. {
  383. return STACK_UNDERFLOW;
  384. }
  385.  
  386. Poly p = PopAndReturn(stack);
  387. Poly new_poly = PolyNeg(&p);
  388. Push(stack, new_poly);
  389. PolyDestroy(&p);
  390.  
  391. return CORRECT;
  392. }
  393. else if(strcmp(command, "SUB") == 0)
  394. {
  395. if (IsEmpty(stack) || stack->top->next == NULL)
  396. {
  397. return STACK_UNDERFLOW;
  398. }
  399.  
  400. Poly p = PopAndReturn(stack);
  401. Poly q = PopAndReturn(stack);
  402. Poly new_poly = PolySub(&p, &q);
  403. Push(stack, new_poly);
  404. PolyDestroy(&p);
  405. PolyDestroy(&q);
  406.  
  407. return CORRECT;
  408. }
  409. else if(strcmp(command, "IS_EQ") == 0)
  410. {
  411. if (IsEmpty(stack) || stack->top->next == NULL)
  412. {
  413. return STACK_UNDERFLOW;
  414. }
  415.  
  416. Poly p = Top(stack);
  417. Poly q = Secound(stack);
  418.  
  419. if (PolyIsEq(&p, &q))
  420. {
  421. printf("%d\n", 1);
  422. }
  423. else
  424. {
  425. printf("%d\n", 0);
  426. }
  427.  
  428. return CORRECT;
  429. }
  430. else if(strncmp(command, "DEG_BY ", 7) == 0)
  431. {
  432. if (!CheckNumber(command, 7))
  433. {
  434. return WRONG_VARIABLE;
  435. }
  436.  
  437. if (CheckSizeOfNumber(command, 7, IDX) != CORRECT)
  438. {
  439. return WRONG_VARIABLE;
  440. }
  441.  
  442. if (IsEmpty(stack))
  443. {
  444. return STACK_UNDERFLOW;
  445. }
  446.  
  447. Poly p = Top(stack);
  448. unsigned idx = (unsigned)strtol(&(command[7]), NULL, 10);
  449. printf("%d\n", PolyDegBy(&p, idx));
  450.  
  451. return CORRECT;
  452. }
  453. else if(strcmp(command, "DEG") == 0)
  454. {
  455. if (IsEmpty(stack))
  456. {
  457. return STACK_UNDERFLOW;
  458. }
  459.  
  460. Poly p = Top(stack);
  461. printf("%d\n", PolyDeg(&p));
  462.  
  463. return CORRECT;
  464. }
  465. else if(strncmp(command, "AT ", 3) == 0)
  466. {
  467. if (!CheckNumber(command, 3))
  468. {
  469. return WRONG_VALUE;
  470. }
  471.  
  472. if (CheckSizeOfNumber(command, 3, POINT) != CORRECT)
  473. {
  474. return WRONG_VALUE;
  475. }
  476.  
  477. if (IsEmpty(stack))
  478. {
  479. return STACK_UNDERFLOW;
  480. }
  481.  
  482. Poly p = PopAndReturn(stack);
  483. poly_coeff_t x = strtol(&(command[3]), NULL, 10);
  484. Push(stack, PolyAt(&p, x));
  485. PolyDestroy(&p);
  486.  
  487. return CORRECT;
  488. }
  489. else if(strcmp(command, "PRINT") == 0)
  490. {
  491. if (IsEmpty(stack))
  492. {
  493. return STACK_UNDERFLOW;
  494. }
  495.  
  496. Poly p = Top(stack);
  497. PrintPoly(&p);
  498. printf("\n");
  499.  
  500. return CORRECT;
  501. }
  502. else if(strcmp(command, "POP") == 0)
  503. {
  504. if (IsEmpty(stack))
  505. {
  506. return STACK_UNDERFLOW;
  507. }
  508.  
  509. Pop(stack);
  510.  
  511. return CORRECT;
  512. }
  513. else
  514. {
  515. return WRONG_COMMAND;
  516. }
  517. }
  518.  
  519. void PrintError(long error_type, unsigned curr_line)
  520. {
  521. if (error_type != CORRECT)
  522. {
  523. if (error_type >= 0)
  524. {
  525. fprintf(stderr, "ERROR %u %li\n", curr_line, error_type);
  526. }
  527. else if (error_type == STACK_UNDERFLOW)
  528. {
  529. fprintf(stderr, "ERROR %u STACK UNDERFLOW\n", curr_line);
  530. }
  531. else if (error_type == WRONG_COMMAND)
  532. {
  533. fprintf(stderr, "ERROR %u WRONG COMMAND\n", curr_line);
  534. }
  535. else if (error_type == WRONG_VALUE)
  536. {
  537. fprintf(stderr, "ERROR %u WRONG VALUE\n", curr_line);
  538. }
  539. else if (error_type == WRONG_VARIABLE)
  540. {
  541. fprintf(stderr, "ERROR %u WRONG VARIABLE\n", curr_line);
  542. }
  543. }
  544. }
  545.  
  546. int Calculate()
  547. {
  548. Stack *stack = (Stack *)malloc(sizeof(Stack));
  549. Initialize(stack);
  550. unsigned row_number = 1;
  551. bool koniec = false;
  552.  
  553. while (!koniec)
  554. {
  555. char *line = ReadOneLine();
  556.  
  557. if (line == NULL)
  558. {
  559. koniec = true;
  560. }
  561. else if (isalpha(line[0]))
  562. {
  563. PrintError(CalculateComand(line, stack), row_number);
  564. }
  565. else
  566. {
  567. long err_col = CheckLine(line);
  568. PrintError(err_col, row_number);
  569.  
  570. if (err_col == CORRECT)
  571. {
  572. Poly p = ParsePoly(line);
  573. Push(stack, p);
  574. }
  575. }
  576.  
  577. free(line);
  578. row_number++;
  579. }
  580.  
  581. Clear(stack);
  582. free(stack);
  583.  
  584. return 0;
  585. }
  586.  
  587. int main() {
  588. Calculate();
  589.  
  590. return 0;
  591. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement