Guest User

Untitled

a guest
Mar 31st, 2020
71
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #define N 1024
  6. #define DIVBYZERO 777
  7. #define MEM_SYMBOL '$'
  8.  
  9.  
  10. //For char
  11. struct stack_char {
  12.  
  13. char data[N];
  14. int size;
  15. };
  16. int _pow(int b, int q) {
  17.  
  18. int res = 1;
  19. int i = 0;
  20.  
  21. for (; i < q; ++i) {
  22.  
  23. res *= b;
  24. }
  25. return res;
  26. }
  27.  
  28. int leftAssoc(char op) {
  29.  
  30. if (op == '+' || op == '-' || op == '/' || op == '*') return 1;
  31. else return 0;
  32. }
  33.  
  34. void pushChar(struct stack_char* p, char value) {
  35.  
  36. if (p->size < N) {
  37.  
  38. p->data[p->size] = value;
  39. p->size++;
  40. }
  41. else {
  42. }
  43. }
  44.  
  45. char peekChar(struct stack_char* p) {
  46.  
  47. if (p->size > 0) {
  48. return p->data[p->size - 1];
  49. }
  50. else {
  51. return 0;
  52. }
  53. }
  54.  
  55. void popChar(struct stack_char* p) {
  56.  
  57. if (p->size > 0) {
  58.  
  59. p->size--;
  60. }
  61. else {
  62.  
  63. }
  64. }
  65. char extractChar(struct stack_char* p) {
  66. if (p->size > 0) {
  67. return p->data[p->size-- - 1];
  68. }
  69. else {
  70. return -1;
  71. }
  72. }
  73.  
  74. int isEmptyChar(struct stack_char* p) {
  75.  
  76. if (p == NULL) {
  77. return 0;
  78. }
  79.  
  80. if (p->size == 0) {
  81. return 1;
  82. }
  83. else {
  84. return 0;
  85. }
  86. }
  87.  
  88. //For int
  89.  
  90. struct stack_int {
  91.  
  92. int data[N];
  93. int size;
  94. };
  95.  
  96. void pushInt(struct stack_int* p, int value) {
  97.  
  98. if (p->size < N) {
  99.  
  100. p->data[p->size] = value;
  101. p->size++;
  102. }
  103. else {
  104. }
  105. }
  106.  
  107. int peekInt(struct stack_int* p) {
  108.  
  109. if (p->size > 0) {
  110. return p->data[p->size - 1];
  111. }
  112. else {
  113. return 0;
  114. }
  115. }
  116.  
  117. void popInt(struct stack_int* p) {
  118.  
  119. if (p->size > 0) {
  120.  
  121. p->size--;
  122. }
  123. else {
  124.  
  125. }
  126. }
  127.  
  128. bool isOp(char c) {
  129.  
  130. if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
  131. return 1;
  132. }
  133. else {
  134. return 0;
  135. }
  136. }
  137.  
  138. int priority(char op) {
  139.  
  140.  
  141. if (op == '+' || op == '-') return 1;
  142. if (op == '*' || op == '/') return 2;
  143. if (op == '^') return 3;
  144. return -1;
  145. }
  146.  
  147. int simpleOperation(struct stack_int* p, char oper) {
  148.  
  149.  
  150. int right = peekInt(p);
  151. popInt(p);
  152. int left = peekInt(p);
  153. popInt(p);
  154.  
  155. switch (oper) {
  156.  
  157. case '^': pushInt(p, _pow(left, right)); break;
  158. case '+': pushInt(p, left + right); break;
  159. case '-': pushInt(p, left - right); break;
  160. case '*': pushInt(p, left * right); break;
  161. case '/': {
  162.  
  163. if (right == 0) {
  164. return DIVBYZERO;
  165. }
  166. else {
  167. pushInt(p, left / right);
  168. }
  169. break;
  170. }
  171. default:
  172. break;
  173. }
  174.  
  175. return 0;
  176. }
  177.  
  178. int calc(const char* s, int* pFlag) {
  179. struct stack_char opers;
  180. opers.size = 0;
  181. struct stack_int vault;
  182. vault.size = 0;
  183.  
  184. int flag = 0;
  185.  
  186. for (int i = 0; s[i] != '\0' && s[i] != '\n'; ++i) {
  187.  
  188.  
  189. if (s[i] == '(') {
  190.  
  191. pushChar(&opers, '(');
  192. }
  193. else if (s[i] == ')') {
  194.  
  195. while (peekChar(&opers) != '(') {
  196.  
  197. flag = simpleOperation(&vault, extractChar(&opers));
  198. if (flag == DIVBYZERO) {
  199.  
  200. *pFlag = DIVBYZERO;
  201. return 0;
  202. }
  203. }
  204. popChar(&opers);
  205. }
  206. else if (isOp(s[i])) {
  207. char currentOp = s[i];
  208. while ((!isEmptyChar(&opers)) && (
  209. (leftAssoc(currentOp) == 1 && priority(peekChar(&opers)) >= priority(s[i]))
  210. || (leftAssoc(currentOp) == 0 && priority(peekChar(&opers)) > priority(s[i])))
  211. ) {
  212.  
  213. flag = simpleOperation(&vault, extractChar(&opers));
  214. if (flag == DIVBYZERO) {
  215.  
  216. *pFlag = DIVBYZERO;
  217. return 0;
  218. }
  219. }
  220. pushChar(&opers, currentOp);
  221. }
  222. else {
  223.  
  224. char* endPtr = NULL;
  225. int value = strtol(s + i, &endPtr, 10);
  226. pushInt(&vault, value);
  227.  
  228. i = endPtr - s - 1;
  229.  
  230. }
  231. }
  232.  
  233.  
  234. while (!isEmptyChar(&opers)) {
  235.  
  236. flag = simpleOperation(&vault, peekChar(&opers));
  237. if (flag == DIVBYZERO) {
  238.  
  239. *pFlag = DIVBYZERO;
  240. return 0;
  241. }
  242. popChar(&opers);
  243. }
  244.  
  245.  
  246. int finalResult = peekInt(&vault);
  247. return finalResult;
  248. }
  249.  
  250.  
  251. int calc_with_mem(const char* s, int* pFlag, int* memP) {
  252. struct stack_char opers;
  253. opers.size = 0;
  254. struct stack_int vault;
  255. vault.size = 0;
  256.  
  257. int flag = 0;
  258.  
  259. for (int i = 0; s[i] != '\0' && s[i] != '\n'; ++i) {
  260. if (s[i] == '(') {
  261. pushChar(&opers, '(');
  262. }
  263. else if (s[i] == ')') {
  264.  
  265. while (peekChar(&opers) != '(') {
  266.  
  267. flag = simpleOperation(&vault, extractChar(&opers));
  268. if (flag == DIVBYZERO) {
  269.  
  270. *pFlag = DIVBYZERO;
  271. return 0;
  272. }
  273. }
  274. popChar(&opers);
  275. }
  276. else if (isOp(s[i])) {
  277. char currentOp = s[i];
  278. while (!isEmptyChar(&opers) && (
  279. (leftAssoc(currentOp) == 1 && priority(peekChar(&opers)) >= priority(s[i]))
  280. || (leftAssoc(currentOp) == 0 && priority(peekChar(&opers)) > priority(s[i])))
  281. ) {
  282.  
  283. flag = simpleOperation(&vault, extractChar(&opers));
  284. if (flag == DIVBYZERO) {
  285.  
  286. *pFlag = DIVBYZERO;
  287. return 0;
  288. }
  289. }
  290. pushChar(&opers, currentOp);
  291. }
  292. else {
  293. if (s[i] == MEM_SYMBOL) {
  294.  
  295. pushInt(&vault, *memP);
  296. }
  297. else {
  298. char* endPtr = NULL;
  299. int value = strtol(s + i, &endPtr, 10);
  300. pushInt(&vault, value);
  301.  
  302. i = endPtr - s - 1;
  303. }
  304. }
  305. }
  306. while (!isEmptyChar(&opers)) {
  307.  
  308. flag = simpleOperation(&vault, peekChar(&opers));
  309. if (flag == DIVBYZERO) {
  310.  
  311. *pFlag = DIVBYZERO;
  312. return 0;
  313. }
  314. popChar(&opers);
  315. }
  316. int finalResult = peekInt(&vault);
  317. return finalResult;
  318. }
  319.  
  320.  
  321.  
  322. int checkString(const char* s) {
  323.  
  324. int openParsCnt = 0;
  325. int closParsCnt = 0;
  326. int digitsCnt = 0;
  327.  
  328. size_t i = 0;
  329. for (; s[i] != '\0' && s[i] != '\n'; ++i) {
  330.  
  331. char c = s[i];
  332.  
  333. if ('0' <= c && c <= '9') {
  334. digitsCnt += 1;
  335. continue;
  336. }
  337. if (c == '(') {
  338. openParsCnt += 1;
  339. continue;
  340. }
  341. if (c == ')') {
  342. if (i > 0 && s[i - 1] == '(') {
  343. return 0;
  344. }
  345. closParsCnt += 1;
  346.  
  347. if (closParsCnt > openParsCnt) {
  348. return 0;
  349. }
  350.  
  351. continue;
  352. }
  353.  
  354.  
  355. if (isOp(c)) {
  356.  
  357. if (i > 0 && isOp(s[i - 1])) {
  358.  
  359. return 0;
  360. }
  361.  
  362. continue;
  363. }
  364.  
  365.  
  366. return 0;
  367. }
  368. if (i > 0 && isOp(s[i - 1]))return 0;
  369.  
  370. if (openParsCnt != closParsCnt) return 0;
  371.  
  372.  
  373. if (digitsCnt == 0) fprintf(stdout, "syntax error");
  374.  
  375. return 1;
  376. }
  377.  
  378. int checkString_with_mem(const char* s) {
  379.  
  380. int openParsCnt = 0;
  381. int closParsCnt = 0;
  382. int digitsCnt = 0;
  383. int memCnt = 0;
  384.  
  385. size_t i = 0;
  386. for (; s[i] != '\0' && s[i] != '\n'; ++i) {
  387.  
  388. char c = s[i];
  389.  
  390. if ('0' <= c && c <= '9') {
  391. digitsCnt += 1;
  392. continue;
  393. }
  394. if (c == '(') {
  395. openParsCnt += 1;
  396. continue;
  397. }
  398. if (c == ')') {
  399. if (i > 0 && s[i - 1] == '(') {
  400. return 0;
  401. }
  402. closParsCnt += 1;
  403.  
  404. if (closParsCnt > openParsCnt) {
  405. return 0;
  406. }
  407.  
  408. continue;
  409. }
  410.  
  411.  
  412. if (isOp(c)) {
  413.  
  414. if (i > 0 && isOp(s[i - 1])) {
  415.  
  416. return 0;
  417. }
  418.  
  419. continue;
  420. }
  421.  
  422. if (s[i] == MEM_SYMBOL) {
  423. memCnt++;
  424. continue;
  425. }
  426.  
  427. return 0;
  428. }
  429. if (i > 0 && isOp(s[i - 1]))return 0;
  430.  
  431. if (openParsCnt != closParsCnt) return 0;
  432.  
  433.  
  434. if (digitsCnt == 0 && memCnt == 0) fprintf(stdout, "syntax error\n");
  435.  
  436. return 1;
  437. }
  438.  
  439. int main(int argc, char** argv) {
  440.  
  441. char str[N] = { 0 };
  442. if (argc == 1) {
  443.  
  444. if (fgets(str, N, stdin) == NULL) {
  445. fprintf(stdout, "syntax error");
  446. return 0;
  447. }
  448. if (checkString(str) == 0) {
  449.  
  450. fprintf(stdout, "syntax error");
  451. return 0;
  452. }
  453. int erFlag = 0;
  454. int result = calc(str, &erFlag);
  455.  
  456. if (erFlag == DIVBYZERO) {
  457. fprintf(stdout, "division by zero");
  458. return 0;
  459. }
  460. fprintf(stdout, "%d", result);
  461. return 0;
  462. }
  463. if (argc > 1 && !((argv[1][0] == '-' && argv[1][1] == 'i'))) {
  464. return 0;
  465. }
  466.  
  467. if (argv[1][0] == '-' && argv[1][1] == 'i') {
  468.  
  469. int x = 0;
  470. fprintf(stdout, ">Welcome! Use the symbol $ to use the previous value, and enter exit to finish the job<\n");
  471. while (1) {
  472.  
  473. fprintf(stdout, "Input: ");
  474. if (!fgets(str, N, stdin)) {
  475. fprintf(stdout, "systax error");
  476. }
  477. if (strncmp(str, "exit", 4) == 0) {
  478.  
  479. break;
  480. }
  481. if (checkString_with_mem(str) == 0) {
  482.  
  483. fprintf(stdout, "syntax error\n");
  484. continue;
  485. }
  486.  
  487. int erFlag = 0;
  488. int result = calc_with_mem(str, &erFlag, &x);
  489. x = result;
  490. if (erFlag == DIVBYZERO) {
  491. fprintf(stdout, "division by zero\n");
  492. }
  493. else {
  494. fprintf(stdout, "%d\n", result);
  495. }
  496. }
  497. }
  498. }
RAW Paste Data