Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.62 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. namespace FifthLab
  5.  
  6. {
  7.  
  8.     enum words { BEGINL = 257, ENDL, READL, PRITL, RETRL, IFL, THENL, WHILEL, DOL, INTL, CONSTL, NUMB, IDEN };
  9.     struct odc
  10.     {
  11.         public string name;
  12.         public int what;
  13.         public int val;
  14.     }
  15.     struct fnd
  16.     {
  17.         public string name; //імя функції
  18.         public int isd;     //описана (isd=1) чи ні (isd=0)
  19.         public int cpt;     //кількість параметрів
  20.         public int start;   // точка входу в таблиі команд
  21.     }
  22.     class Program
  23.     {
  24.         StreamReader sr;
  25.         StreamWriter sw;
  26.         char nch = '\n';
  27.         int lex = 0;
  28.         string[] TNM = new string[400];
  29.         int ptn = 0;
  30.         int lval;
  31.         int nst = 0;
  32.  
  33.         int cgv = 0;
  34.         int clv = 0;
  35.         odc[] TOB = new odc[30];
  36.         int pto = 0;
  37.         int ptol = 0;
  38.         int ut = 1;
  39.         fnd[] TFN = new fnd[30];
  40.         int ptf = 0;
  41.         public Program(string nm1, string nm2)
  42.         {
  43.             try
  44.             {
  45.                 sr = new StreamReader(nm1);
  46.                 sw = new StreamWriter(nm2);
  47.             }
  48.             catch (Exception e)
  49.             {
  50.                 Console.WriteLine("Ошибка чтения файла:");
  51.                 Console.WriteLine(e.Message);
  52.             }
  53.         }
  54.  
  55.         public char getc()
  56.         {
  57.             return (char)sr.Read();
  58.         }
  59.  
  60.         public void get()
  61.         {
  62.             bool flg;
  63.             while (!sr.EndOfStream)
  64.             {
  65.                 nch = getc();
  66.                 flg = false;
  67.                 if (char.IsLetter(nch))
  68.                 {
  69.                     flg = true;
  70.                     word();
  71.                 }
  72.                 if (char.IsDigit(nch))
  73.                 {
  74.                     flg = true;
  75.                     number();
  76.                     Console.WriteLine("number lval={0} lex={1}", lval, lex);
  77.                     sw.WriteLine("number lval={0} lex={1}", lval, lex);
  78.                 }
  79.                 if (nch == ')' || nch == '(')
  80.                 {
  81.                     flg = true;
  82.                     lex = nch;
  83.                     Console.WriteLine(nch + " - скобка");
  84.                     sw.WriteLine(nch + " - скобка");
  85.                 }
  86.                 if (nch == ',')
  87.                 {
  88.                     flg = true;
  89.                     lex = nch;
  90.                     Console.WriteLine(nch + " - запятая");
  91.                     sw.WriteLine(nch + " - запятая");
  92.                 }
  93.                 if (nch == ';')
  94.                 {
  95.                     flg = true;
  96.                     lex = nch;
  97.                     Console.WriteLine(nch + " - точка с запятой");
  98.                     sw.WriteLine(nch + " - точка с запятой");
  99.                 }
  100.                 if (nch == '=')
  101.                 {
  102.                     flg = true;
  103.                     lex = nch;
  104.                     Console.WriteLine(nch + " - знак равно");
  105.                     sw.WriteLine(nch + " - знак равно");
  106.                 }
  107.  
  108.                 if (char.IsWhiteSpace(nch) || nch == '@')
  109.                 {
  110.                     flg = true;
  111.                     lex = nch;
  112.                     if (nch == '\n')
  113.                     {
  114.                         nst++;
  115.                     }
  116.                 }
  117.                 if (!flg)
  118.                 {
  119.                     Console.WriteLine(nch + " - недопустимый символ");
  120.                     sw.WriteLine(nch + " - недопустимый символ");
  121.                 }
  122.             }
  123.             //Console.WriteLine(nst);
  124.             sw.Close();
  125.         }
  126.  
  127.         public void word()
  128.         {
  129.             string tx = "";
  130.             string[] serv = { "begin", "end", "read", "print", "return", "if", "then", "while", "do", "int", "const", "numb", "iden" };
  131.             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 };
  132.             while (char.IsLetterOrDigit(nch))
  133.             {
  134.                 tx += nch;
  135.                 nch = getc();
  136.             }
  137.             tx += " ";
  138.             Console.WriteLine(tx);
  139.             bool idenFlg = false;
  140.             for (int i = 0; i < serv.Length; i++)
  141.             {
  142.                 if (tx.Contains(serv[i]))
  143.                 {
  144.                     sw.WriteLine(serv[i] + " = " + cdl[i]);
  145.                     this.lex = cdl[i];
  146.                     idenFlg = true;
  147.                 }
  148.             }
  149.             if (!idenFlg)
  150.             {
  151.                 lval = add(tx);
  152.                 lex = (int)words.IDEN;
  153.                 sw.WriteLine("{0} идентификатор lex={1} lval={2}", tx, lex, lval);
  154.             }
  155.         }
  156.  
  157.         public void number()
  158.         {
  159.             for (lval = 0; char.IsDigit(nch); nch = getc())
  160.             {
  161.                 lval = lval * 10 + nch - '0';
  162.             }
  163.             lex = (int)words.NUMB;
  164.         }
  165.  
  166.         public int add(string nm)
  167.         {
  168.             for (int i = 0; i < TNM.Length; i++)
  169.             {
  170.                 if (nm.CompareTo(TNM[i]) == 0) return i;
  171.             }
  172.             try
  173.             {
  174.                 TNM[ptn] = nm;
  175.                 ptn++;
  176.             }
  177.             catch (IndexOutOfRangeException)
  178.             {
  179.                 Console.WriteLine("Таблица TNM переполнена");
  180.             }
  181.             return ptn - 1;
  182.         }
  183.  
  184.         public void prog()
  185.         {
  186.             Console.WriteLine("PROG");
  187.             sr.BaseStream.Position = 0;
  188.             while (!sr.EndOfStream)
  189.             {
  190.                 switch (lex)
  191.                 {
  192.                     case (int)words.IDEN: dfunc(); break;
  193.                     case (int)words.INTL: dvarb(); break;
  194.                     case (int)words.CONSTL: dconst(); break;
  195.                     default: Console.WriteLine("Синтаксическая ошибка в строке № {0}. Лексема {1}.", nst, lex); break;
  196.                 }
  197.             }
  198.         }
  199.  
  200.         public void dconst()
  201.         {
  202.             Console.WriteLine("DCONST");
  203.             do
  204.             {
  205.                 get();
  206.                 cons();
  207.             } while (lex == ',');
  208.             exam(';');
  209.         }
  210.  
  211.         public void cons()
  212.         {
  213.             string nm = TNM[lval];
  214.             int s;
  215.             exam((int)words.IDEN);
  216.             exam('=');
  217.             s = (lex == '-' ? -1 : 1);
  218.             if (lex == '+' || lex == '-')
  219.             {
  220.                 get();
  221.             }
  222.             newob(nm, 1, s * lval);
  223.             exam((int)words.NUMB);
  224.         }
  225.  
  226.         public void dvarb()
  227.         {
  228.             Console.WriteLine("DVARB");
  229.             do
  230.             {
  231.                 get();
  232.                 newob(TNM[lval], (ut == 1 ? 2 : 3), (ut == 1 ? cgv++ : ++clv));
  233.                 exam((int)words.IDEN);
  234.  
  235.             } while (lex == ',');
  236.  
  237.             exam(';');
  238.         }
  239.  
  240.         public void dfunc()
  241.         {
  242.             int cp; // Количество параметров функции
  243.             int st; // Точка входа в функцию
  244.             string nm = TNM[lval]; //Идентификатор функции
  245.             get();
  246.             ut = 0; //Признак того, что будет локальная переменная
  247.             cp = param(); // вернет количество параметров
  248.             st = body(); // вернет точку входа в функцию,
  249.             ut = 1; // Восстановили признак out.
  250.             ptol = pto; //заполняется указатель, откуда можно заносить локальные переменные
  251.             defin(nm, cp, st); //Определение функции
  252.             return;
  253.         }
  254.  
  255.         public int param()
  256.         {
  257.             Console.WriteLine("PARAM");
  258.             int p;
  259.             int cp = 0;
  260.             exam('(');
  261.             if (lex != ')')
  262.             {
  263.                 newob(TNM[lval], 3, ++cp);
  264.                 exam((int)words.IDEN);
  265.                 while (lex == ',')
  266.                 {
  267.                     get();
  268.                     newob(TNM[lval], 3, ++cp);
  269.                     exam((int)words.IDEN);
  270.                 }
  271.             }
  272.             exam(')');
  273.             for (p = ptol; p < pto; p++)
  274.             {
  275.                 TOB[p].val -= cp + 3;
  276.             }
  277.             return cp;
  278.         }
  279.  
  280.         public void body()
  281.         {
  282.             Console.WriteLine("BODY");
  283.             exam((int)words.BEGINL);
  284.             while (lex == (int)words.INTL || lex == (int)words.CONSTL)
  285.             {
  286.                 if (lex == (int)words.INTL) dvarb();
  287.                 else dconst();
  288.                 stml();
  289.             }
  290.             exam((int)words.ENDL);
  291.         }
  292.  
  293.         public void stml()
  294.         {
  295.             Console.WriteLine("STML");
  296.             stat();
  297.             while (lex == ';')
  298.             {
  299.                 get();
  300.                 stat();
  301.             }
  302.         }
  303.  
  304.         public void stat()
  305.         {
  306.             Console.WriteLine("STAT");
  307.             switch (lex)
  308.             {
  309.                 case (int)words.IDEN: get(); exam('='); expr(); break;
  310.                 case (int)words.READL: get(); exam((int)words.IDEN); break;
  311.                 case (int)words.PRITL: get(); expr(); break;
  312.                 case (int)words.RETRL: get(); expr(); break;
  313.                 case (int)words.IFL: get(); expr(); exam((int)words.THENL); stml(); exam((int)words.ENDL); break;
  314.                 case (int)words.WHILEL: get(); expr(); exam((int)words.DOL); stml(); exam((int)words.ENDL); break;
  315.                 default: Console.WriteLine("Синтаксична помилка у рядку № {0}.", nst); break;
  316.             }
  317.         }
  318.  
  319.         public void expr()
  320.         {
  321.             Console.WriteLine("EXPR");
  322.             if (lex == '+' || lex == '-')
  323.                 get();
  324.             term();
  325.             while (lex == '+' || lex == '-')
  326.             {
  327.                 get();
  328.                 term();
  329.             }
  330.         }
  331.  
  332.         public void term()
  333.         {
  334.             Console.WriteLine("TERM");
  335.             fact();
  336.             while (lex == '*' || lex == '/' || lex == '%')
  337.             {
  338.                 get();
  339.                 fact();
  340.             }
  341.         }
  342.  
  343.         public void fact()
  344.         {
  345.             Console.WriteLine("FACT");
  346.             switch (lex)
  347.             {
  348.                 case '(': get(); expr(); exam(')'); break;
  349.                 case (int)words.NUMB: get(); break;
  350.                 case (int)words.IDEN:
  351.                     get();
  352.                     if (lex == '(')
  353.                     {
  354.                         get();
  355.                         if (lex != ')')
  356.                             fctl();
  357.                         exam(')');
  358.                     }
  359.                     break;
  360.                 default: Console.WriteLine("Синтаксична помилка {0} у рядку № {1}.", lex, nst); break;
  361.             }
  362.         }
  363.  
  364.         public void fctl()
  365.         {
  366.             Console.WriteLine("FCTL");
  367.             expr();
  368.             while (lex == ',')
  369.             {
  370.                 get();
  371.                 expr();
  372.             }
  373.         }
  374.  
  375.         public void exam(int lx)
  376.         {
  377.             Console.WriteLine("EXAM");
  378.             if (lex != lx)
  379.             {
  380.                 Console.WriteLine("Не співпадають лексеми lex = {0} та ls = {1} в рядку № {2}", lex, lx, nst);
  381.             }
  382.             get();
  383.         }
  384.  
  385.         public void newob(string nm, int wt, int vl)
  386.         {
  387.             int p, pe;
  388.             pe = ut == 1 ? TOB.Length : ptol;
  389.             for (p = pto - 1; p >= pe; p--)
  390.                 if (nm.CompareTo(TOB[p].name) == 0)
  391.                 {
  392.                     Console.WriteLine("Функция описана дважды!");
  393.                     System.Environment.Exit(1);
  394.                 }
  395.             if (pto >= TOB.Length + 100)
  396.             {
  397.                 Console.WriteLine("Таблица ТОВ переполнена!");
  398.                 System.Environment.Exit(1);
  399.             }
  400.             TOB[p].name = nm;
  401.             TOB[p].what = wt;
  402.             TOB[p].val = vl;
  403.             pto++;
  404.         }
  405.  
  406.         public int findob(string nm)
  407.         {
  408.             int p;
  409.             for (p = pto - 1; p >= TOB.Length; p--)
  410.                 if (nm.CompareTo(TOB[p].name) == 0)
  411.                     return p;
  412.             Console.WriteLine("Об'єкт {0} не описан!", nm);
  413.             System.Environment.Exit(1);
  414.             return p;
  415.         }
  416.  
  417.         public void newfn(string name, int isd, int cpt, int start)
  418.         {
  419.             if (findfn(name) == 0)
  420.             {
  421.                 TFN[ptf].name = name;
  422.                 TFN[ptf].isd = isd;
  423.                 TFN[ptf].cpt = cpt;
  424.                 TFN[ptf].start = start;
  425.                 ptf++;
  426.             }
  427.             else
  428.             {
  429.                 Console.WriteLine("Функция уже описана!");
  430.             }
  431.         }
  432.  
  433.         public int findfn(string namefn)
  434.         {
  435.             for (int i = 0; i < ptf; i++)
  436.                 if (namefn.CompareTo(TFN[i].name) == 0)
  437.                     return i;
  438.             Console.WriteLine("Функция {0} не описана!", namefn);
  439.  
  440.             return 0;
  441.         }
  442.  
  443.         void defin(string nm, int cp, int ad)
  444.         {
  445.             int p;
  446.             p = findfn(nm);
  447.             if (p != -1)
  448.             {
  449.                 if (TFN[p].isd != 0)
  450.                 {
  451.                     Console.WriteLine("функция {0} уже описана!", nm);
  452.                     Console.ReadKey();
  453.                     Environment.Exit(0);
  454.                 }
  455.                 if (TFN[p].cpt != cp)
  456.                 {
  457.                     Console.WriteLine("У функции {0} не совпадает количество параметров \n", nm);
  458.                     Console.ReadKey();
  459.                     Environment.Exit(0);
  460.                 }
  461.                 TFN[p].isd = 1;
  462.                 TFN[p].start = ad;
  463.             }
  464.             else
  465.                 newfn(nm, 1, cp, ad);
  466.             return;
  467.  
  468.         }
  469.         static void Main(string[] args)
  470.         {
  471.             string name1 = "/Users/danilmaleev/Desktop/SystemProgramming/input.txt";
  472.             string name2 = "/Users/danilmaleev/Desktop/SystemProgramming/output.txt";
  473.             Program ob = new Program(name1, name2);
  474.             ob.get();
  475.             ob.prog();
  476.         }
  477.     }
  478.  
  479. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement