Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- /*
- 1) S -> I:=E;
- 2) E -> T|E
- E -> T
- T -> M&T | M
- M -> !M | (E) | I | C
- 3) I -> AK | A
- K -> DK | D
- 4) C -> DC | D
- 5) A -> a | .. | z
- 6) D -> 0|1
- */
- using namespace std;
- #define MAX_ID_LEN 50
- #define MAX_VARS 50
- #define MAX_BITS 20
- typedef struct number
- {
- long value;
- int digits;
- } number;
- typedef struct var
- {
- char name[MAX_ID_LEN + 1];
- number num;
- } var;
- var vars[MAX_VARS];
- FILE * f = NULL;
- FILE *out = NULL;
- int c = EOF;
- int var_count = 0;
- int last_assigned = -1;
- int index = 0;
- int line = 1;
- void ProcS(void);
- number ProcE(void);
- number ProcT(void);
- number ProcM(void);
- number *ProcL(void);
- number ProcI(void);
- number ProcC(void);
- int power(int x, int y)
- {
- int res = 1;
- if(y == 0) return 1;
- else
- for(int i = 0; i < y; i++)
- res *= x;
- return res;
- }
- void get(void)
- {
- c = getc(f);
- }
- void space_skip(void)
- {
- while(isspace(c))
- get();
- }
- bool isletter(char c)
- {
- return c >= 'a' && c <= 'z';
- }
- void error(const char * msg)
- {
- puts(msg);
- printf("Last symbol: %c\n", c);
- exit(1);
- }
- void to_binary(number x)
- {
- char res[MAX_BITS];
- for(int i = 0; i < x.digits; i++)
- {
- res[i] = x.value % 2 + '0';
- x.value = x.value/2;
- }
- for(int i = x.digits - 1; i >= 0; i--)
- {
- cout<<res[i];
- }
- }
- void to_bin_to_file(number x)
- {
- char res[MAX_BITS];
- for(int i = 0; i < x.digits; i++)
- {
- res[i] = x.value % 2 + '0';
- x.value = x.value/2;
- }
- for(int i = x.digits - 1; i >= 0; i--)
- {
- fprintf(out,"%c",res[i]);
- }
- }
- long to_decimal(char byte_arr[MAX_BITS], int num)
- {
- int i,j;
- long res = 0;
- for(i = num - 1, j = 0; i >= 0; i--, j++)
- {
- if(byte_arr[j] == '1')
- {
- res += power(2,i);
- }
- else if (byte_arr[j] != '0')
- {
- error("Error: Wrong number!");
- }
- }
- return res;
- }
- void print_var(int n)
- {
- if(n >= 0 && n < MAX_VARS)
- {
- cout<<vars[n].name<<" = ";
- to_binary(vars[n].num);
- cout<<endl;
- }
- else
- error("Not found variable!");
- }
- void print_all(void)
- {
- cout<<"Defined: "<<var_count<<" variables"<<endl;
- for(int i = 0; i < var_count; i++)
- {
- print_var(i);
- }
- }
- int ProcC(void) /*считывание константы и переведение
- ее в десятичный код а также сохранение количества цифр в константе*/
- {
- number N;
- int i = 0;
- char res[MAX_BITS];
- int digits = 0;
- while(c == '0' || c == '1')
- {
- res[i++] = c;
- digits++;
- get();
- }
- N.digits = digits;
- N.value = to_decimal(res,digits);
- fprintf(out,"%d:\tC(",line);
- to_bin_to_file(N);
- fprintf(out,",@)\n");
- return line++;
- //return N;
- }
- int ProcI(void) /*возвращаем значение переменной если нашел идентификатор и значение константы
- если нашел константу и ошибка если встретилась переменная */
- {
- int i = 0;
- int len;
- char buf[MAX_ID_LEN+1] = {0};
- if(!isletter(c)) //первой должна быть буква
- {
- error("Error: Not a alpha!");
- }
- buf[i++] = c;
- get();
- while((c == '0' || c == '1') && i < MAX_ID_LEN) /*дальнейшее чтение идентификатора при условии того
- что все остальные символы должны быть либо 0 либо 1*/
- {
- buf[i] = c;
- ++i;
- get();
- }
- len = i;
- buf[len] = '\0';
- if(len == MAX_ID_LEN && (c == '0' || c == '1')) //проверка на идентификатор большей длины чем задано
- {
- error("Too long identifier!");
- }
- for(i = 0; i < var_count; i++) /* возвращаем значение по уже существующему идентификатору
- если он есть в списке переменных*/
- {
- if(strcmp(buf,vars[i].name) == 0)
- {
- break;
- }
- }
- if(i == var_count) // неопределенный идентификатор
- {
- error("Error: Undefined identifier!");
- }
- fprintf(out,"%d:\tV(%s,@)\n",line,buf);;
- return line++;
- //return vars[i].num;
- }
- int ProcL() // взятие адреса переменной и создание переменной если ее нет
- {
- char buf[MAX_ID_LEN+1] = { 0 };
- int i = 0;
- int len = 0;
- if(!isletter(c))
- {
- error("In the begining of variable name must be alpha!");
- }
- buf[i++] = c;
- get();
- while((c == '0' || c == '1') && i < MAX_ID_LEN)
- {
- buf[i] = c;
- ++i;
- get();
- }
- len = i;
- buf[len] = '\0';
- if(len == MAX_ID_LEN && (c == '0' || c == '1'))
- {
- error("Too long identifier!");
- }
- for(i = 0; i < var_count; i++) // берем адрес переменной
- {
- if(strcmp(buf,vars[i].name) == 0)
- {
- last_assigned = i; // индекс последней присвоенной переменной
- return &vars[i].num; // возврат этой переменной
- }
- }
- strncpy(vars[i].name, buf, len); // если переменной нет создаем переменную с данным именем
- vars[i].name[len] = '\0';
- last_assigned = i; // последняя присвоенная
- fprintf(out,"%d:\tV(%s,@)\n",line,buf);;
- return line++;
- //return &vars[var_count++].num; // возвращаем адрес ячейки где потом будет храниться эта переменная
- }
- int ProcM(void) // обработка выражений в скобках и инвертирование выражений в скобках
- {
- number res;
- //int l = line - 1;
- int op;
- if(c == '~') // если отрицание то инвертируем все цифры в числе
- {
- get();
- //res = ProcM();
- op = ProcM();
- for(int i = 0; i < res.digits; i++)
- {
- res.value ^= 1 << i;
- }
- fprintf(out, "%d:\t~(^%d,@)\n", line, op);
- op = line++;
- }
- else if(c == '(') // обработка выражений в скобках
- {
- get();
- space_skip();
- //res = ProcE(); // содержимое скобок
- op = ProcE();
- space_skip();
- if(c != ')')
- {
- error("Syntax Error: ')' is missing!");
- }
- get();
- }
- else if(isletter(c)) // если первая буква то считываем идентификатор
- {
- //res = ProcI();
- op = ProcI();
- }
- else if(c == '0' || c == '1') // если 0 или 1 то считывается константа
- {
- //res = ProcC();
- op = ProcC();
- }
- else
- error("Syntax Error: Unexpected symbol!");
- //return res;
- return op;
- }
- int ProcT(void)// поразрядное И
- {
- number res1, res2;
- //int l = line - 1;
- //res1 = ProcM(); // считываем первое выражение
- int op1 = ProcM();
- space_skip();
- if(c != '&')
- //return res1;
- return op1;
- get();
- space_skip();
- //res2 = ProcT(); // считываем второе выражение
- int op2 = ProcT();
- res1.value &= res2.value; // выполняем поразрядное умножение
- if(res1.digits < res2.digits)
- res1.digits = res2.digits; // возвращаем количество цифр в полученном числе
- //fprintf(out,"%d:\t&(^%d,^%d)\n", line, l + 1, line - 1);
- fprintf(out,"%d:\t&(^%d,^%d)\n", line, op1, op2);
- return line++;
- //return res1;
- }
- int ProcE(void)// поразрядное ИЛИ
- {
- number res1,res2;
- //int l = line - 1;
- //res1 = ProcT(); // считываем первое выражение
- int op1 = ProcT();
- space_skip();
- if(c != '|') // если не встретиили поразрядное или
- //return res1;
- return op1;
- get();
- space_skip();
- //res2 = ProcE(); // считываем второе выражение
- int op2 = ProcE();
- res1.value |= res2.value; // применяем поразрядное или
- if(res1.digits < res2.digits)
- res1.digits = res2.digits; // возвращаем количество цифр в полученном числе
- //fprintf(out,"%d:\t|(^%d,^%d)\n", line, l + 1, line - 1);
- fprintf(out,"%d:\t|(^%d,^%d)\n", line, op1, op2);
- return line++;
- //return res1;
- }
- void ProcS(void)
- {
- //int l = line - 1;
- //number* var = ProcL(); // для хранения адреса на значение переменной
- int op1 = ProcL();
- space_skip();
- if(c != ':') /*согласно синтаксису присваивание
- происходит после считывания символов := */
- {
- error("Syntax error: Expected ':=' ");
- }
- get();
- if(c != '=')
- {
- error("Syntax error: Expected ':=' ");
- }
- get();
- space_skip();
- //*var = ProcE();
- int op2 = ProcE();
- space_skip();
- if(c != ';')
- {
- error("Syntax error: Expected ';' ");
- }
- get();
- //fprintf(out,"%d:\t:=(^%d,^%d)\n",line, l + 1, line - 1);
- fprintf(out,"%d:\t:=(^%d,^%d)\n",line, op1, op2);
- line++;
- }
- void Run(void)
- {
- get();
- int i = 0;
- for(i = 1; ; i++)
- {
- space_skip();
- if(c == EOF)
- break;
- //printf("Operator %2d: ", i);
- ProcS();
- //print_var(last_assigned);
- }
- print_all();
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- //char filename[100], output[100];
- //cout<<"Input filename for parse: ";
- //cin>>filename;
- //f = fopen("err.txt","rb");
- f = fopen("in.txt","rb");
- out = fopen("out.txt","wb");
- if(!f)
- {
- cout<<"Input File Error!"<<endl;
- return -1;
- }
- if(!out)
- {
- cout<<"Output File Error!"<<endl;
- return -1;
- }
- Run();
- fclose(f);
- fclose(out);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement