Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h> // 3 ЛАБА
- #include<malloc.h>
- #include<stdlib.h>
- #include<ctype.h>
- #include<math.h>
- #include<string.h>
- const char *ERRORS[] = {
- "File '%s' doesn`t exist or can`t be open!\n",
- "Memory error! %s\n",
- "Empty stack! %s\n",
- "Can`t divide by zero! %s\n",
- "Empty file! %s\n",
- "Base hasn`t this number! %s\n",
- "`}` was found, but comment hasn`t yet been closed! %s\n"
- } ;
- void push(struct stack**, int);
- int top(struct stack*);
- void pop(struct stack**);
- int prioritet(char);
- void Error(int, char*);
- void intToStr(int, int, char*);
- int strToInt(char*, int);
- int calc(int, int, char);
- struct stack {
- int data;
- struct stack *next;
- };
- FILE *fIn = NULL, *fOut = NULL;
- void main(int argc, char *argv[]) {
- struct stack *st = NULL, *stNum = NULL;
- char c, c_ = ' ', mbuf[BUFSIZ], *mb = mbuf, buf[33], *b = buf, *sIn = "data.in", *ssIn = sIn, *sOut = "data.out";
- int base = 10, i, num1, num2, reg[26], tr = 1, comment = 0, k;
- for (i = 0; i < argc; i++)
- if (strstr(argv[i], "tr="))
- if (strstr(argv[i], "false"))
- tr = 0;
- /*if(strstr(argv[i], "if="))
- strcpy(sIn, argv[i] + 3) ;
- if(strstr(argv[i], "of="))
- strcpy(sOut, argv[i] + 3) ;*/
- if (!(fIn = fopen(sIn, "r")))
- Error(0, sIn);
- if (!(fOut = fopen(sOut, "w")))
- fclose(fIn), Error(0, sOut);
- push(&st, '(');
- while (!feof(fIn)) {
- fgets(mb, BUFSIZ, fIn);
- if ((int)*mb == -52)
- Error(4, "");
- if (strstr(mb, "#"))
- *strstr(mb, "#") = 0;
- if (strstr(mb, "{"))
- *strstr(mb, "{") = 0, comment = 1;
- if (strstr(mb, "}")) {
- if(comment)
- mb = strstr(mb, "}") + 1, comment = 0;
- else
- Error(6, "") ;
- } ;
- if (!strcmp(mb, "\n") || !strcmp(mb, ""))
- continue;
- if (comment == 1)
- continue;
- if (strstr(mb, "sys")) {
- mb[strlen(mb) - 1] = 0; //убираем символ конца строки
- base = strToInt(mb + 4, 10);
- continue;
- }
- else if (toupper(*mb) >= 'A' && toupper(*mb) <= 'Z' && *(mb + 1) == '=') {
- mb[strlen(mb) - 1] = 0; // убираем символ конца строки
- reg[toupper(*mb) - 'A'] = strToInt(mb + 2, base); // заносим в массив регистров число
- continue;
- };
- if (strstr(mb, "\n"))
- *strstr(mb, "\n") = 0;
- fprintf(fOut, "%s = ", mb);
- for (i = 0; i < strlen(mb); i++) {
- c = mb[i];
- if (isalpha(c)) {
- push(&stNum, reg[toupper(c) - 'A']);
- if (tr)
- fprintf(fOut, "%d ", reg[toupper(c) - 'A']);
- }
- else if (isdigit(c) || c == '~')
- *b++ = c;
- else if (isdigit(c_)) {
- *b = 0;
- b = buf; //ставим на начало указатель
- push(&stNum, strToInt(b, base));
- if (tr)
- fprintf(fOut, "%s ", b);
- };
- if (c == '(')
- push(&st, '(');
- else if (c == ')') {
- while (top(st) != '(') {
- if (tr)
- fprintf(fOut, "%c ", top(st));
- num2 = top(stNum);
- pop(&stNum);
- num1 = top(stNum);
- pop(&stNum);
- push(&stNum, calc(num1, num2, top(st)));
- pop(&st);
- };
- pop(&st);
- }
- else if (prioritet(c)) {
- while (prioritet(c) <= prioritet(top(st))) {
- if (tr)
- fprintf(fOut, "%c ", top(st));
- num2 = top(stNum);
- pop(&stNum);
- num1 = top(stNum);
- pop(&stNum);
- push(&stNum, calc(num1, num2, top(st)));
- pop(&st);
- };
- push(&st, c);
- };
- c_ = c;
- };
- if (isdigit(c_)) {
- *b = 0;
- b = buf;
- push(&stNum, strToInt(b, base));
- if (tr)
- fprintf(fOut, "%s ", b);
- };
- while (top(st) != '(') {
- if (tr)
- fprintf(fOut, "%c ", top(st));
- num2 = top(stNum);
- pop(&stNum);
- num1 = top(stNum);
- pop(&stNum);
- push(&stNum, calc(num1, num2, top(st)));
- pop(&st);
- };
- intToStr(top(stNum), base, b);
- if (tr)
- fprintf(fOut, "= ");
- fprintf(fOut, "%s\n", b);
- pop(&stNum);
- };
- pop(&st) ;
- fclose(fIn) ;
- fclose(fOut) ;
- }
- void push(struct stack **st, int c) {
- struct stack *newS;
- newS = (struct stack*) malloc(sizeof(struct stack));
- if (!newS)
- Error(1, "");
- newS->data = c;
- newS->next = *st;
- *st = newS;
- }
- void pop(struct stack **st) {
- struct stack *oldS = *st;
- if (!oldS)
- Error(2, "");
- *st = (*st)->next;
- free(oldS);
- }
- int top(struct stack *st) {
- return st->data;
- }
- int prioritet(char op) {
- return (op == '^') ? 3 : (op == '+' || op == '-') ? 1 : (op == '*' || op == '/') ? 2 : 0;
- }
- void Error(int nErr, char *s) {
- printf("Error #%d! ", nErr + 1);
- printf(ERRORS[nErr], s);
- if (nErr != 1)
- fclose(fIn), fclose(fOut);
- exit(nErr + 1);
- }
- void intToStr(int num, int base, char *convertNum) {
- int rest, k = 0, addMinus = 0;
- unsigned number;
- char n[BUFSIZ], *nu = n + BUFSIZ - 1;
- *nu-- = 0;
- if (num < 0) {
- number = -num;
- addMinus = 1;
- }
- else
- number = num;
- while (number)
- *nu-- = ((rest = number % base) < 10) ? rest + '0' : rest + 'A' - 10, number /= base;
- if (addMinus)
- *convertNum++ = '-';
- while (*nu++)
- *convertNum++ = *nu;
- }
- int strToInt(char *num, int base) {
- int res = 0, addMinus = 0;
- char *s = num;
- if (*s == '~')
- s++;
- while (*s)
- if (*s++ - '0' >= base)
- Error(5, "");
- if (*num == '~')
- addMinus = 1;
- else
- num--;
- while (*++num)
- res = res * base + (isdigit(*num) ? *num - '0' : toupper(*num) - 'A' + 10);
- return addMinus ? -res : res;
- }
- int calc(int a, int b, char op) {
- switch (op) {
- case '+': return a + b;
- case '-': return a - b;
- case '*': return a * b;
- case '/': {
- if (b != 0)
- return a / b;
- else
- Error(3, "");
- };
- case '^': return pow((double)a, b);
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement