Advertisement
spartanPAGE

Untitled

Jun 25th, 2019
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.13 KB | None | 0 0
  1. #include "stack.h"
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <stdbool.h>
  7.  
  8. enum ERROR
  9. {
  10. INCORRECT_INPUT = 1,
  11. INCORRECT_EXPRESSION = 2,
  12. MEMORY_OVERFLOW = 3
  13. };
  14.  
  15. const char* ERRORS[] =
  16. {
  17. "",
  18. "Incorrect input",
  19. "Incorrect expression",
  20. "Failed to allocate memory",
  21. };
  22.  
  23. char* read_token(FILE* fp, size_t size, char *ch, int *error_code)
  24. {
  25. char* str = realloc(NULL, sizeof(char) * size);
  26. size_t len = 0;
  27. if (!str)
  28. {
  29. *error_code = 8;
  30. return NULL;
  31. }
  32.  
  33. while ((*ch = getchar()) != '\n' && *ch != ' ' && *ch != EOF)
  34. {
  35. str[len++] = *ch;
  36. if (len == size)
  37. {
  38. char* last_block = str;
  39. str = realloc(str, sizeof(char) * (size += 16));
  40. if (!str)
  41. {
  42. free(last_block);
  43. *error_code = 8;
  44. return NULL;
  45. }
  46. }
  47. }
  48. str[len++] = 0;
  49.  
  50. char *result = realloc(str, sizeof(char) * len);
  51. if (!result)
  52. {
  53. free(str);
  54. *error_code = 8;
  55. return NULL;
  56. }
  57. return result;
  58. }
  59.  
  60. int consume_token(struct stack_t* stack, const char* token)
  61. {
  62. #define HANDLE_OPERATOR(_op_) do { \
  63. if (!strcmp(token, #_op_)) { \
  64. if (stack_size(stack) < 2) { \
  65. return INCORRECT_EXPRESSION; \
  66. } \
  67. double d1 = stack_pop(stack, NULL); \
  68. double d2 = stack_pop(stack, NULL); \
  69. switch(stack_push(stack, d2 _op_ d1)) \
  70. { \
  71. case 0: \
  72. return 0; \
  73. case 2: \
  74. return MEMORY_OVERFLOW; \
  75. } \
  76. return 0; \
  77. } } while (0)
  78.  
  79. HANDLE_OPERATOR(+);
  80. HANDLE_OPERATOR(-);
  81. HANDLE_OPERATOR(/);
  82. HANDLE_OPERATOR(*);
  83.  
  84. double d = strtod(token, NULL);
  85. size_t len = strlen(token);
  86. if (d == 0.0 && (!len || token[0] != '0')) {
  87. return INCORRECT_INPUT;
  88. }
  89.  
  90. int stack_size_result = stack_size(stack);
  91. if (stack_push(stack, d)) {
  92. return MEMORY_OVERFLOW;
  93. }
  94. return 0;
  95. #undef HANDLE_OPERATOR
  96. }
  97.  
  98. int main(void)
  99. {
  100. struct stack_t* stack = NULL;
  101. char* padding = malloc(sizeof(char) * 4);
  102. if (stack_init(&stack) == 2)
  103. {
  104. printf(ERRORS[MEMORY_OVERFLOW]);
  105. return 8;
  106. }
  107. free(padding);
  108.  
  109. printf("Enter expression: ");
  110. char last_char = 0;
  111. char* token = NULL;
  112. int error_code = 0;
  113. while (token = read_token(stdin, 1, &last_char, &error_code))
  114. {
  115. if (error_code == 8)
  116. {
  117. printf(ERRORS[MEMORY_OVERFLOW]);
  118. return 8;
  119. }
  120.  
  121. int err = consume_token(stack, token);
  122. switch (err)
  123. {
  124. case 3:
  125. printf(ERRORS[MEMORY_OVERFLOW]);
  126. return 8;
  127. case 2:
  128. printf(ERRORS[INCORRECT_EXPRESSION]);
  129. return INCORRECT_EXPRESSION;
  130. case 1:
  131. printf(ERRORS[INCORRECT_INPUT]);
  132. return INCORRECT_INPUT;
  133. }
  134. free(token);
  135. if (last_char == '\n')
  136. {
  137. break;
  138. }
  139. }
  140.  
  141. if (error_code == 8)
  142. {
  143. printf(ERRORS[MEMORY_OVERFLOW]);
  144. return 8;
  145. }
  146.  
  147. if (stack_size(stack) != 1)
  148. {
  149. printf(ERRORS[INCORRECT_EXPRESSION]);
  150. return INCORRECT_EXPRESSION;
  151. }
  152. printf("%f", stack_pop(stack, NULL));
  153. stack_destroy(&stack);
  154. return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement