Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #define N 1024
- #define DIVBYZERO 777
- #define MEM_SYMBOL '$'
- //For char
- struct stack_char {
- char data[N];
- int size;
- };
- int _pow(int b, int q) {
- int res = 1;
- int i = 0;
- for (; i < q; ++i) {
- res *= b;
- }
- return res;
- }
- int leftAssoc(char op) {
- if (op == '+' || op == '-' || op == '/' || op == '*') return 1;
- else return 0;
- }
- void pushChar(struct stack_char* p, char value) {
- if (p->size < N) {
- p->data[p->size] = value;
- p->size++;
- }
- else {
- }
- }
- char peekChar(struct stack_char* p) {
- if (p->size > 0) {
- return p->data[p->size - 1];
- }
- else {
- return 0;
- }
- }
- void popChar(struct stack_char* p) {
- if (p->size > 0) {
- p->size--;
- }
- else {
- }
- }
- char extractChar(struct stack_char* p) {
- if (p->size > 0) {
- return p->data[p->size-- - 1];
- }
- else {
- return -1;
- }
- }
- int isEmptyChar(struct stack_char* p) {
- if (p == NULL) {
- return 0;
- }
- if (p->size == 0) {
- return 1;
- }
- else {
- return 0;
- }
- }
- //For int
- struct stack_int {
- int data[N];
- int size;
- };
- void pushInt(struct stack_int* p, int value) {
- if (p->size < N) {
- p->data[p->size] = value;
- p->size++;
- }
- else {
- }
- }
- int peekInt(struct stack_int* p) {
- if (p->size > 0) {
- return p->data[p->size - 1];
- }
- else {
- return 0;
- }
- }
- void popInt(struct stack_int* p) {
- if (p->size > 0) {
- p->size--;
- }
- else {
- }
- }
- bool isOp(char c) {
- if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
- return 1;
- }
- else {
- return 0;
- }
- }
- int priority(char op) {
- if (op == '+' || op == '-') return 1;
- if (op == '*' || op == '/') return 2;
- if (op == '^') return 3;
- return -1;
- }
- int simpleOperation(struct stack_int* p, char oper) {
- int right = peekInt(p);
- popInt(p);
- int left = peekInt(p);
- popInt(p);
- switch (oper) {
- case '^': pushInt(p, _pow(left, right)); break;
- case '+': pushInt(p, left + right); break;
- case '-': pushInt(p, left - right); break;
- case '*': pushInt(p, left * right); break;
- case '/': {
- if (right == 0) {
- return DIVBYZERO;
- }
- else {
- pushInt(p, left / right);
- }
- break;
- }
- default:
- break;
- }
- return 0;
- }
- int calc(const char* s, int* pFlag) {
- struct stack_char opers;
- opers.size = 0;
- struct stack_int vault;
- vault.size = 0;
- int flag = 0;
- for (int i = 0; s[i] != '\0' && s[i] != '\n'; ++i) {
- if (s[i] == '(') {
- pushChar(&opers, '(');
- }
- else if (s[i] == ')') {
- while (peekChar(&opers) != '(') {
- flag = simpleOperation(&vault, extractChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- }
- popChar(&opers);
- }
- else if (isOp(s[i])) {
- char currentOp = s[i];
- while ((!isEmptyChar(&opers)) && (
- (leftAssoc(currentOp) == 1 && priority(peekChar(&opers)) >= priority(s[i]))
- || (leftAssoc(currentOp) == 0 && priority(peekChar(&opers)) > priority(s[i])))
- ) {
- flag = simpleOperation(&vault, extractChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- }
- pushChar(&opers, currentOp);
- }
- else {
- char* endPtr = NULL;
- int value = strtol(s + i, &endPtr, 10);
- pushInt(&vault, value);
- i = endPtr - s - 1;
- }
- }
- while (!isEmptyChar(&opers)) {
- flag = simpleOperation(&vault, peekChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- popChar(&opers);
- }
- int finalResult = peekInt(&vault);
- return finalResult;
- }
- int calc_with_mem(const char* s, int* pFlag, int* memP) {
- struct stack_char opers;
- opers.size = 0;
- struct stack_int vault;
- vault.size = 0;
- int flag = 0;
- for (int i = 0; s[i] != '\0' && s[i] != '\n'; ++i) {
- if (s[i] == '(') {
- pushChar(&opers, '(');
- }
- else if (s[i] == ')') {
- while (peekChar(&opers) != '(') {
- flag = simpleOperation(&vault, extractChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- }
- popChar(&opers);
- }
- else if (isOp(s[i])) {
- char currentOp = s[i];
- while (!isEmptyChar(&opers) && (
- (leftAssoc(currentOp) == 1 && priority(peekChar(&opers)) >= priority(s[i]))
- || (leftAssoc(currentOp) == 0 && priority(peekChar(&opers)) > priority(s[i])))
- ) {
- flag = simpleOperation(&vault, extractChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- }
- pushChar(&opers, currentOp);
- }
- else {
- if (s[i] == MEM_SYMBOL) {
- pushInt(&vault, *memP);
- }
- else {
- char* endPtr = NULL;
- int value = strtol(s + i, &endPtr, 10);
- pushInt(&vault, value);
- i = endPtr - s - 1;
- }
- }
- }
- while (!isEmptyChar(&opers)) {
- flag = simpleOperation(&vault, peekChar(&opers));
- if (flag == DIVBYZERO) {
- *pFlag = DIVBYZERO;
- return 0;
- }
- popChar(&opers);
- }
- int finalResult = peekInt(&vault);
- return finalResult;
- }
- int checkString(const char* s) {
- int openParsCnt = 0;
- int closParsCnt = 0;
- int digitsCnt = 0;
- size_t i = 0;
- for (; s[i] != '\0' && s[i] != '\n'; ++i) {
- char c = s[i];
- if ('0' <= c && c <= '9') {
- digitsCnt += 1;
- continue;
- }
- if (c == '(') {
- openParsCnt += 1;
- continue;
- }
- if (c == ')') {
- if (i > 0 && s[i - 1] == '(') {
- return 0;
- }
- closParsCnt += 1;
- if (closParsCnt > openParsCnt) {
- return 0;
- }
- continue;
- }
- if (isOp(c)) {
- if (i > 0 && isOp(s[i - 1])) {
- return 0;
- }
- continue;
- }
- return 0;
- }
- if (i > 0 && isOp(s[i - 1]))return 0;
- if (openParsCnt != closParsCnt) return 0;
- if (digitsCnt == 0) fprintf(stdout, "syntax error");
- return 1;
- }
- int checkString_with_mem(const char* s) {
- int openParsCnt = 0;
- int closParsCnt = 0;
- int digitsCnt = 0;
- int memCnt = 0;
- size_t i = 0;
- for (; s[i] != '\0' && s[i] != '\n'; ++i) {
- char c = s[i];
- if ('0' <= c && c <= '9') {
- digitsCnt += 1;
- continue;
- }
- if (c == '(') {
- openParsCnt += 1;
- continue;
- }
- if (c == ')') {
- if (i > 0 && s[i - 1] == '(') {
- return 0;
- }
- closParsCnt += 1;
- if (closParsCnt > openParsCnt) {
- return 0;
- }
- continue;
- }
- if (isOp(c)) {
- if (i > 0 && isOp(s[i - 1])) {
- return 0;
- }
- continue;
- }
- if (s[i] == MEM_SYMBOL) {
- memCnt++;
- continue;
- }
- return 0;
- }
- if (i > 0 && isOp(s[i - 1]))return 0;
- if (openParsCnt != closParsCnt) return 0;
- if (digitsCnt == 0 && memCnt == 0) fprintf(stdout, "syntax error\n");
- return 1;
- }
- int main(int argc, char** argv) {
- char str[N] = { 0 };
- if (argc == 1) {
- if (fgets(str, N, stdin) == NULL) {
- fprintf(stdout, "syntax error");
- return 0;
- }
- if (checkString(str) == 0) {
- fprintf(stdout, "syntax error");
- return 0;
- }
- int erFlag = 0;
- int result = calc(str, &erFlag);
- if (erFlag == DIVBYZERO) {
- fprintf(stdout, "division by zero");
- return 0;
- }
- fprintf(stdout, "%d", result);
- return 0;
- }
- if (argc > 1 && !((argv[1][0] == '-' && argv[1][1] == 'i'))) {
- return 0;
- }
- if (argv[1][0] == '-' && argv[1][1] == 'i') {
- int x = 0;
- fprintf(stdout, ">Welcome! Use the symbol $ to use the previous value, and enter exit to finish the job<\n");
- while (1) {
- fprintf(stdout, "Input: ");
- if (!fgets(str, N, stdin)) {
- fprintf(stdout, "systax error");
- }
- if (strncmp(str, "exit", 4) == 0) {
- break;
- }
- if (checkString_with_mem(str) == 0) {
- fprintf(stdout, "syntax error\n");
- continue;
- }
- int erFlag = 0;
- int result = calc_with_mem(str, &erFlag, &x);
- x = result;
- if (erFlag == DIVBYZERO) {
- fprintf(stdout, "division by zero\n");
- }
- else {
- fprintf(stdout, "%d\n", result);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement