Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.IO;
- using System.Linq;
- namespace FifthLab
- {
- enum words { BEGINL = 257, ENDL, READL, PRITL, RETRL, IFL, THENL, WHILEL, DOL, INTL, CONSTL, NUMB, IDEN };
- struct odc
- {
- public string name;
- public int what;
- public int val;
- }
- struct fnd
- {
- public string name; //імя функції
- public int isd; //описана (isd=1) чи ні (isd=0)
- public int cpt; //кількість параметрів
- public int start; // точка входу в таблиі команд
- }
- class Program
- {
- StreamReader sr;
- StreamWriter sw;
- char nch = '\n';
- int lex = 0;
- string[] TNM = new string[400];
- int ptn = 0;
- int lval;
- int nst = 0;
- int cgv = 0;
- int clv = 0;
- odc[] TOB = new odc[30];
- int pto = 0;
- int ptol = 0;
- int ut = 1;
- fnd[] TFN = new fnd[30];
- int ptf = 0;
- public Program(string nm1, string nm2)
- {
- try
- {
- sr = new StreamReader(nm1);
- sw = new StreamWriter(nm2);
- }
- catch (Exception e)
- {
- Console.WriteLine("Ошибка чтения файла:");
- Console.WriteLine(e.Message);
- }
- }
- public char getc()
- {
- return (char)sr.Read();
- }
- public void get()
- {
- bool flg;
- while (!sr.EndOfStream)
- {
- nch = getc();
- flg = false;
- if (char.IsLetter(nch))
- {
- flg = true;
- word();
- }
- if (char.IsDigit(nch))
- {
- flg = true;
- number();
- Console.WriteLine("number lval={0} lex={1}", lval, lex);
- sw.WriteLine("number lval={0} lex={1}", lval, lex);
- }
- if (nch == ')' || nch == '(')
- {
- flg = true;
- lex = nch;
- Console.WriteLine(nch + " - скобка");
- sw.WriteLine(nch + " - скобка");
- }
- if (nch == ',')
- {
- flg = true;
- lex = nch;
- Console.WriteLine(nch + " - запятая");
- sw.WriteLine(nch + " - запятая");
- }
- if (nch == ';')
- {
- flg = true;
- lex = nch;
- Console.WriteLine(nch + " - точка с запятой");
- sw.WriteLine(nch + " - точка с запятой");
- }
- if (nch == '=')
- {
- flg = true;
- lex = nch;
- Console.WriteLine(nch + " - знак равно");
- sw.WriteLine(nch + " - знак равно");
- }
- if (char.IsWhiteSpace(nch) || nch == '@')
- {
- flg = true;
- lex = nch;
- if (nch == '\n')
- {
- nst++;
- }
- }
- if (!flg)
- {
- Console.WriteLine(nch + " - недопустимый символ");
- sw.WriteLine(nch + " - недопустимый символ");
- }
- }
- //Console.WriteLine(nst);
- sw.Close();
- }
- public void word()
- {
- string tx = "";
- string[] serv = { "begin", "end", "read", "print", "return", "if", "then", "while", "do", "int", "const", "numb", "iden" };
- int[] cdl = { (int)words.BEGINL, (int)words.ENDL, (int)words.READL, (int)words.PRITL, (int)words.RETRL, (int)words.IFL, (int)words.THENL, (int)words.WHILEL, (int)words.DOL, (int)words.INTL, (int)words.CONSTL, (int)words.NUMB, (int)words.IDEN };
- while (char.IsLetterOrDigit(nch))
- {
- tx += nch;
- nch = getc();
- }
- tx += " ";
- Console.WriteLine(tx);
- bool idenFlg = false;
- for (int i = 0; i < serv.Length; i++)
- {
- if (tx.Contains(serv[i]))
- {
- sw.WriteLine(serv[i] + " = " + cdl[i]);
- this.lex = cdl[i];
- idenFlg = true;
- }
- }
- if (!idenFlg)
- {
- lval = add(tx);
- lex = (int)words.IDEN;
- sw.WriteLine("{0} идентификатор lex={1} lval={2}", tx, lex, lval);
- }
- }
- public void number()
- {
- for (lval = 0; char.IsDigit(nch); nch = getc())
- {
- lval = lval * 10 + nch - '0';
- }
- lex = (int)words.NUMB;
- }
- public int add(string nm)
- {
- for (int i = 0; i < TNM.Length; i++)
- {
- if (nm.CompareTo(TNM[i]) == 0) return i;
- }
- try
- {
- TNM[ptn] = nm;
- ptn++;
- }
- catch (IndexOutOfRangeException)
- {
- Console.WriteLine("Таблица TNM переполнена");
- }
- return ptn - 1;
- }
- public void prog()
- {
- Console.WriteLine("PROG");
- sr.BaseStream.Position = 0;
- while (!sr.EndOfStream)
- {
- switch (lex)
- {
- case (int)words.IDEN: dfunc(); break;
- case (int)words.INTL: dvarb(); break;
- case (int)words.CONSTL: dconst(); break;
- default: Console.WriteLine("Синтаксическая ошибка в строке № {0}. Лексема {1}.", nst, lex); break;
- }
- }
- }
- public void dconst()
- {
- Console.WriteLine("DCONST");
- do
- {
- get();
- cons();
- } while (lex == ',');
- exam(';');
- }
- public void cons()
- {
- string nm = TNM[lval];
- int s;
- exam((int)words.IDEN);
- exam('=');
- s = (lex == '-' ? -1 : 1);
- if (lex == '+' || lex == '-')
- {
- get();
- }
- newob(nm, 1, s * lval);
- exam((int)words.NUMB);
- }
- public void dvarb()
- {
- Console.WriteLine("DVARB");
- do
- {
- get();
- newob(TNM[lval], (ut == 1 ? 2 : 3), (ut == 1 ? cgv++ : ++clv));
- exam((int)words.IDEN);
- } while (lex == ',');
- exam(';');
- }
- public void dfunc()
- {
- int cp; // Количество параметров функции
- int st; // Точка входа в функцию
- string nm = TNM[lval]; //Идентификатор функции
- get();
- ut = 0; //Признак того, что будет локальная переменная
- cp = param(); // вернет количество параметров
- st = body(); // вернет точку входа в функцию,
- ut = 1; // Восстановили признак out.
- ptol = pto; //заполняется указатель, откуда можно заносить локальные переменные
- defin(nm, cp, st); //Определение функции
- return;
- }
- public int param()
- {
- Console.WriteLine("PARAM");
- int p;
- int cp = 0;
- exam('(');
- if (lex != ')')
- {
- newob(TNM[lval], 3, ++cp);
- exam((int)words.IDEN);
- while (lex == ',')
- {
- get();
- newob(TNM[lval], 3, ++cp);
- exam((int)words.IDEN);
- }
- }
- exam(')');
- for (p = ptol; p < pto; p++)
- {
- TOB[p].val -= cp + 3;
- }
- return cp;
- }
- public void body()
- {
- Console.WriteLine("BODY");
- exam((int)words.BEGINL);
- while (lex == (int)words.INTL || lex == (int)words.CONSTL)
- {
- if (lex == (int)words.INTL) dvarb();
- else dconst();
- stml();
- }
- exam((int)words.ENDL);
- }
- public void stml()
- {
- Console.WriteLine("STML");
- stat();
- while (lex == ';')
- {
- get();
- stat();
- }
- }
- public void stat()
- {
- Console.WriteLine("STAT");
- switch (lex)
- {
- case (int)words.IDEN: get(); exam('='); expr(); break;
- case (int)words.READL: get(); exam((int)words.IDEN); break;
- case (int)words.PRITL: get(); expr(); break;
- case (int)words.RETRL: get(); expr(); break;
- case (int)words.IFL: get(); expr(); exam((int)words.THENL); stml(); exam((int)words.ENDL); break;
- case (int)words.WHILEL: get(); expr(); exam((int)words.DOL); stml(); exam((int)words.ENDL); break;
- default: Console.WriteLine("Синтаксична помилка у рядку № {0}.", nst); break;
- }
- }
- public void expr()
- {
- Console.WriteLine("EXPR");
- if (lex == '+' || lex == '-')
- get();
- term();
- while (lex == '+' || lex == '-')
- {
- get();
- term();
- }
- }
- public void term()
- {
- Console.WriteLine("TERM");
- fact();
- while (lex == '*' || lex == '/' || lex == '%')
- {
- get();
- fact();
- }
- }
- public void fact()
- {
- Console.WriteLine("FACT");
- switch (lex)
- {
- case '(': get(); expr(); exam(')'); break;
- case (int)words.NUMB: get(); break;
- case (int)words.IDEN:
- get();
- if (lex == '(')
- {
- get();
- if (lex != ')')
- fctl();
- exam(')');
- }
- break;
- default: Console.WriteLine("Синтаксична помилка {0} у рядку № {1}.", lex, nst); break;
- }
- }
- public void fctl()
- {
- Console.WriteLine("FCTL");
- expr();
- while (lex == ',')
- {
- get();
- expr();
- }
- }
- public void exam(int lx)
- {
- Console.WriteLine("EXAM");
- if (lex != lx)
- {
- Console.WriteLine("Не співпадають лексеми lex = {0} та ls = {1} в рядку № {2}", lex, lx, nst);
- }
- get();
- }
- public void newob(string nm, int wt, int vl)
- {
- int p, pe;
- pe = ut == 1 ? TOB.Length : ptol;
- for (p = pto - 1; p >= pe; p--)
- if (nm.CompareTo(TOB[p].name) == 0)
- {
- Console.WriteLine("Функция описана дважды!");
- System.Environment.Exit(1);
- }
- if (pto >= TOB.Length + 100)
- {
- Console.WriteLine("Таблица ТОВ переполнена!");
- System.Environment.Exit(1);
- }
- TOB[p].name = nm;
- TOB[p].what = wt;
- TOB[p].val = vl;
- pto++;
- }
- public int findob(string nm)
- {
- int p;
- for (p = pto - 1; p >= TOB.Length; p--)
- if (nm.CompareTo(TOB[p].name) == 0)
- return p;
- Console.WriteLine("Об'єкт {0} не описан!", nm);
- System.Environment.Exit(1);
- return p;
- }
- public void newfn(string name, int isd, int cpt, int start)
- {
- if (findfn(name) == 0)
- {
- TFN[ptf].name = name;
- TFN[ptf].isd = isd;
- TFN[ptf].cpt = cpt;
- TFN[ptf].start = start;
- ptf++;
- }
- else
- {
- Console.WriteLine("Функция уже описана!");
- }
- }
- public int findfn(string namefn)
- {
- for (int i = 0; i < ptf; i++)
- if (namefn.CompareTo(TFN[i].name) == 0)
- return i;
- Console.WriteLine("Функция {0} не описана!", namefn);
- return 0;
- }
- void defin(string nm, int cp, int ad)
- {
- int p;
- p = findfn(nm);
- if (p != -1)
- {
- if (TFN[p].isd != 0)
- {
- Console.WriteLine("функция {0} уже описана!", nm);
- Console.ReadKey();
- Environment.Exit(0);
- }
- if (TFN[p].cpt != cp)
- {
- Console.WriteLine("У функции {0} не совпадает количество параметров \n", nm);
- Console.ReadKey();
- Environment.Exit(0);
- }
- TFN[p].isd = 1;
- TFN[p].start = ad;
- }
- else
- newfn(nm, 1, cp, ad);
- return;
- }
- static void Main(string[] args)
- {
- string name1 = "/Users/danilmaleev/Desktop/SystemProgramming/input.txt";
- string name2 = "/Users/danilmaleev/Desktop/SystemProgramming/output.txt";
- Program ob = new Program(name1, name2);
- ob.get();
- ob.prog();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement