diff --git a/Module1/Lexer.cs b/Module1/Lexer.cs
index af2b9ee3546dd4b83f81005077e1b3f57c0eeace..cb01e375d77fe72abc6aa0ca7594d98680f3d80c 100644
--- a/Module1/Lexer.cs
+++ b/Module1/Lexer.cs
@@ -1,7 +1,8 @@
 using System;
+using System.Text;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
-using System.Text;
 
 namespace Lexer
 {
@@ -42,7 +43,7 @@ namespace Lexer
         protected void NextCh()
         {
             this.currentCharValue = this.inputReader.Read();
-            this.currentCh = (char)currentCharValue;
+            this.currentCh = (char) currentCharValue;
             this.position += 1;
         }
 
@@ -50,6 +51,11 @@ namespace Lexer
         {
             return true;
         }
+
+        protected int currentDigit()
+        {
+            return currentCharValue - '0';
+        }
     }
 
     public class IntLexer : Lexer
@@ -66,19 +72,17 @@ namespace Lexer
 
         public override bool Parse()
         {
-            int sign = 1;
+            bool isNeg = false;
             NextCh();
             if (currentCh == '+' || currentCh == '-')
             {
-                if (currentCh == '-')
-                    sign = -1;
-
+                if (currentCh == '-') isNeg = true;
                 NextCh();
             }
-
+        
             if (char.IsDigit(currentCh))
             {
-                parseResult = currentCh - '0';
+                parseResult = currentDigit();
                 NextCh();
             }
             else
@@ -88,65 +92,67 @@ namespace Lexer
 
             while (char.IsDigit(currentCh))
             {
-                parseResult = parseResult * 10 + currentCh - '0';
+                parseResult = parseResult * 10 + currentDigit();
                 NextCh();
             }
-            parseResult *= sign;
 
+            // если есть еще что прочитать => не число
             if (currentCharValue != -1)
             {
                 Error();
             }
 
+            if (isNeg)
+            {
+                parseResult = -parseResult;
+            }
+
             return true;
 
         }
     }
-
+    
     public class IdentLexer : Lexer
     {
         private string parseResult;
         protected StringBuilder builder;
-
+    
         public string ParseResult
         {
             get { return parseResult; }
         }
-
+    
         public IdentLexer(string input) : base(input)
         {
             builder = new StringBuilder();
         }
-        bool checkChar(char ch)
-        {
-            return char.IsDigit(ch) ||
-                (ch >= 'A' && ch <= 'Z') ||
-                (ch >= 'a' && ch <= 'z') ||
-                ch == '_';
-        }
 
         public override bool Parse()
         {
             NextCh();
-
-            if (!checkChar(currentCh))
+            if (currentCharValue == -1)
+            {
                 Error();
+            }
 
-            while (checkChar(currentCh))
+            while (currentCharValue != -1)
             {
-                parseResult += currentCh;
-                NextCh();
+                if (char.IsLetterOrDigit(currentCh) || currentCh == '_')
+                {
+                    builder.Append(currentCh);
+                    NextCh();
+                }
+                else
+                {
+                    Error();
+                }
             }
 
-            if (currentCharValue != -1)
-                Error();
+            parseResult = builder.ToString();
 
             return true;
-
-            //throw new NotImplementedException();
         }
 
-
     }
 
     public class IntNoZeroLexer : IntLexer
@@ -158,20 +164,17 @@ namespace Lexer
 
         public override bool Parse()
         {
-
-            int sign = 1;
+            bool isNeg = false;
             NextCh();
             if (currentCh == '+' || currentCh == '-')
             {
-                if (currentCh == '-')
-                    sign = -1;
-
+                if (currentCh == '-') isNeg = true;
                 NextCh();
             }
 
             if (char.IsDigit(currentCh) && currentCh != '0')
             {
-                parseResult = currentCh - '0';
+                parseResult = currentDigit();
                 NextCh();
             }
             else
@@ -181,19 +184,22 @@ namespace Lexer
 
             while (char.IsDigit(currentCh))
             {
-                parseResult = parseResult * 10 + currentCh - '0';
+                parseResult = parseResult * 10 + currentDigit();
                 NextCh();
             }
-            parseResult *= sign;
 
+            // если есть еще что прочитать => не число
             if (currentCharValue != -1)
             {
                 Error();
             }
 
-            return true;
+            if (isNeg)
+            {
+                parseResult = -parseResult;
+            }
 
-            throw new NotImplementedException();
+            return true;
         }
     }
 
@@ -202,6 +208,8 @@ namespace Lexer
         protected StringBuilder builder;
         protected string parseResult;
 
+        private bool passChar = true; 
+
         public string ParseResult
         {
             get { return parseResult; }
@@ -212,21 +220,44 @@ namespace Lexer
         {
             builder = new StringBuilder();
         }
-        public override bool Parse()
+
+        private void parse()
         {
-            bool isDigit = false;
+            if (passChar)
+            {
+                if (char.IsLetter(currentCh))
+                {
+                    builder.Append(currentCh);
+                }
+                else
+                {
+                    Error();
+                }
+            }
+            else
+            {
+                if (char.IsDigit(currentCh))
+                {
+                    builder.Append(currentCh);
+                }
+                else
+                {
+                    Error();
+                }
+            }
+            passChar = !passChar;
+        }
 
-            NextCh();
 
+        public override bool Parse()
+        {
+            NextCh();
             while (currentCharValue != -1)
             {
-                if (char.IsDigit(currentCh) ^ isDigit || currentCh == ' ')
-                    Error();
-
-                isDigit = !isDigit;
+                parse();
                 NextCh();
             }
-
+            parseResult = builder.ToString();
             return true;
         }
 
@@ -236,6 +267,11 @@ namespace Lexer
     {
         protected List<char> parseResult;
 
+        private bool passChar = true; // true for letter, false for sign
+
+        private List<char> delimeters = new List<char> { ',', ';' };
+
+
         public List<char> ParseResult
         {
             get { return parseResult; }
@@ -247,28 +283,44 @@ namespace Lexer
             parseResult = new List<char>();
         }
 
-        public override bool Parse()
+        private void parse()
         {
-            bool isChar = false;
-
-            NextCh();
-            while (currentCharValue != -1)
+            if (passChar)
             {
-                if ((currentCh == ',' || currentCh == ';') ^ isChar
-                    || char.IsDigit(currentCh))
+                if (char.IsLetter(currentCh))
+                {
+                    parseResult.Add(currentCh);
+                }
+                else
+                {
+                    Error();
+                }
+            }
+            else
+            {
+                if (!delimeters.Contains(currentCh))
+                {
                     Error();
+                }
+            }
+            passChar = !passChar;
+        }
 
-                if (!(currentCh == ',' || currentCh == ';') && !isChar)
-                    parseResult.Add(currentCh);
 
-                isChar = !isChar;
+        public override bool Parse()
+        {
+            NextCh();
+            while (currentCharValue != -1)
+            {
+                parse();
                 NextCh();
             }
-
-            if (!isChar)
+            if (passChar)
+            {
                 Error();
-
+            }
             return true;
+
         }
     }
 
@@ -289,38 +341,34 @@ namespace Lexer
 
         public override bool Parse()
         {
-            bool flag = true;
-
             NextCh();
-            if (currentCh == ' ' || !char.IsDigit(currentCh))
+            if (!char.IsDigit(currentCh))
             {
                 Error();
             }
-
-            parseResult.Add(currentCh - '0');
-
-            NextCh();
-            while (currentCharValue != -1)
+            while (true)
             {
-                if (currentCh == ' ')
-                {
-                    flag = false;
-                }
-                else
+                if (char.IsDigit(currentCh))
                 {
-                    if (!flag)
+                    parseResult.Add(currentCharValue - '0');
+                    NextCh();
+                    if (char.IsDigit(currentCh))
+                    {
+                        Error();
+                    }
+                    if (currentCharValue == -1)
                     {
-                        flag = true;
-                        parseResult.Add(currentCh - '0');
+                        return true;
                     }
-                    else Error();
+                }
+                // скипаем пробелы
+                // если попалась вторая цифра(буква) => ошибка
+                if (!char.IsWhiteSpace(currentCh))
+                {
+                    Error();
                 }
                 NextCh();
             }
-            if (!flag)
-                Error();
-
-            return true;
         }
     }
 
@@ -333,7 +381,7 @@ namespace Lexer
         {
             get { return parseResult; }
         }
-
+        
         public LetterDigitGroupLexer(string input)
             : base(input)
         {
@@ -342,58 +390,44 @@ namespace Lexer
 
         public override bool Parse()
         {
-            bool lastIsDigit = true;
-            bool isDigit;
-            int countCurrentChar = 0;
-
+            int lettersInRow = 0;
+            int digitsInRow = 0;
             NextCh();
-            if (currentCh == ' ' || currentCh == '\uffff')//'\uffff' - non-char
+            if (currentCharValue == -1 || !char.IsLetter(currentCh))
             {
                 Error();
             }
-            else
+
+            builder.Append(currentCh);
+            lettersInRow += 1;
+
+            NextCh();
+            while (currentCharValue != -1)
             {
-                if (char.IsDigit(currentCh) || currentCh == '_')
+                if (lettersInRow > 2 || digitsInRow > 2)
                 {
                     Error();
                 }
-                else
+                if (char.IsDigit(currentCh))
                 {
-                    isDigit = false;
-                    lastIsDigit = isDigit;
+                    builder.Append(currentCh);
+                    digitsInRow += 1;
+                    lettersInRow = 0;
                 }
-                builder.Append(currentCh);
-                countCurrentChar++;
-            }
-            NextCh();
-            while (currentCharValue != -1)
-            {
-                if (currentCh == ' ' || currentCh == '_')
+                else if (char.IsLetter(currentCh))
                 {
-                    Error();
+                    builder.Append(currentCh);
+                    lettersInRow += 1;
+                    digitsInRow = 0;
                 }
                 else
                 {
-                    isDigit = char.IsDigit(currentCh);
-
-                    if (lastIsDigit != isDigit)
-                    {
-                        countCurrentChar = 0;
-                        lastIsDigit = isDigit;
-                    }
-
-                    builder.Append(currentCh);
-                    countCurrentChar++;
-
-                    if (countCurrentChar == 3)
-                        Error();
-
-                    NextCh();
+                    Error();
                 }
+                NextCh();
             }
 
             parseResult = builder.ToString();
-
             return true;
         }
 
@@ -407,6 +441,7 @@ namespace Lexer
         public double ParseResult
         {
             get { return parseResult; }
+
         }
 
         public DoubleLexer(string input)
@@ -417,36 +452,47 @@ namespace Lexer
 
         public override bool Parse()
         {
-            bool havePoint = false;
             NextCh();
-            if (char.IsDigit(currentCh))
+            if (!char.IsDigit(currentCh))
             {
-                builder.Append(currentCh);
+                Error();
             }
-            else
+            while (char.IsDigit(currentCh))
             {
-                Error();
+                parseResult = parseResult * 10 + currentDigit();
+                NextCh();
             }
-            NextCh();
-            while (currentCharValue != -1)
+
+            if (currentCharValue == -1)
             {
-                if (currentCh == '.')
-                {
-                    if (havePoint == true)
-                        Error();
+                return true;
+            }
 
-                    havePoint = true;
-                }
-                builder.Append(currentCh);
-                NextCh();
+            if (currentCh != '.')
+            {
+                Error();
             }
 
-            if (builder.ToString().Last() == '.')
+            NextCh();
+            if (!char.IsDigit(currentCh))
+            {
                 Error();
+            }
 
-            parseResult = double.Parse(builder.ToString());
 
+            double power = 1;
+            while (char.IsDigit(currentCh))
+            {
+                power /= 10;
+                parseResult += currentDigit() * power;
+                NextCh();
+            }
+            if (currentCharValue != -1)
+            {
+                Error();
+            }
             return true;
+
         }
 
     }
@@ -470,40 +516,34 @@ namespace Lexer
 
         public override bool Parse()
         {
-            int count = 0;
-
             NextCh();
-
-            if (currentCh == ' ')
-                Error();
-
-            if (currentCh == '\'')
+            // первая кавычка
+            if (currentCh != '\'')
             {
-                count++;
+                Error();
             }
 
-            builder.Append(currentCh);
             NextCh();
-
-            while (currentCharValue != -1)
+            while (currentCh != '\'' && currentCharValue != -1)
             {
-                if (currentCh == ' ' && count % 2 == 0)
-                    Error();
-
-                if (currentCh == '\'')
-                {
-                    count++;
-                }
                 builder.Append(currentCh);
                 NextCh();
             }
 
-            if (count % 2 == 1)
+            // вторая кавычка
+            if (currentCh != '\'')
+            {
                 Error();
+            }
 
+            NextCh();
+            if (currentCharValue != -1)
+            {
+                Error();
+            }
             parseResult = builder.ToString();
-
             return true;
+
         }
     }
 
@@ -526,68 +566,54 @@ namespace Lexer
 
         public override bool Parse()
         {
-            int flag_before = 0;//0 - не было, 1 - было, 2 - завершено
-            bool flag_before_final = false;//открывающая /*
-
-            int flag_after = 0;//закрывающая */
-            bool flag_after_final = false;
-
             NextCh();
-            if (currentCh == ' ')
+            if (currentCh == '/')
+            {
+                NextCh();
+            }
+            else
+            {
                 Error();
-            else if (currentCh == '/')
+            }
+
+            if (currentCh == '*')
             {
-                flag_before = 1;
+                NextCh();
             }
-            builder.Append(currentCh);
-            NextCh();
+            else
+            {
+                Error();
+            }
+            // конец начала комментария
 
             while (currentCharValue != -1)
             {
-                if (flag_after_final == true)//Если зашли в цикл после комментариев
-                    Error();
-
-                if (currentCh == '/')//Для открывающей
-                {
-                    flag_before = 1;
-                }
-
-                if (currentCh == '*' && flag_before_final == true)//Для закрывающей
-                {
-                    flag_after = 1;
-                }
-
-                if (currentCh == '*')//Для открывающей
+                // проверка на конец комментария
+                if (currentCh == '*')
                 {
-                    if (flag_before == 1)
+                    NextCh();
+                    if (currentCh == '/')
                     {
-                        flag_before = 2;
-                        flag_before_final = true;
+                        NextCh();
+                        if (currentCharValue == -1)
+                        {
+                            return true;
+                        }
+                        else
+                        {
+                            Error();
+                        }
                     }
-                    else flag_before = 0;
-                }
-
-                if (currentCh == '/')//Для закрывающей
-                {
-                    if (flag_after == 1)
+                    else
                     {
-                        flag_after = 2;
-                        flag_after_final = true;
+                        continue;
                     }
-                    else flag_after = 0;
                 }
-
-
-                builder.Append(currentCh);
                 NextCh();
             }
+            Error();
+            return false;
 
-            if (!flag_after_final)
-                Error();
-
-            parseResult = builder.ToString();
-
-            return true;
         }
     }
 
@@ -611,49 +637,34 @@ namespace Lexer
 
         public override bool Parse()
         {
-            string temp = "";
-            bool dot_flag = true;//0 - всё хорошо. 1 - id1.id2.
-
+            int lastSymbol = 0;
             NextCh();
 
-            if (currentCharValue == -1)
-            {
-                Error();
-            }
-
             while (currentCharValue != -1)
             {
-                dot_flag = false;
-                if (currentCh == '$' || currentCh == ' ' || currentCh == ',')
+                // если первый символ число - ошибка
+                if (char.IsDigit(currentCh))
                 {
                     Error();
                 }
-                if (currentCh == '.')
+                // читаем до точки, потом делаем IdentLexer
+                while (currentCh != '.'
+                    && currentCharValue != -1)
                 {
-                    temp = builder.ToString();
-                    if (temp.Length == 0 || char.IsDigit(temp[0]))
-                        Error();
-
-                    parseResult.Add(temp);
-                    builder.Clear();
-                    dot_flag = true;
+                    builder.Append(currentCh);
+                    NextCh();
                 }
-                else
-                    builder.Append(currentCh.ToString());
-
+                lastSymbol = currentCharValue;
+                IdentLexer id = new IdentLexer(builder.ToString());
+                id.Parse();
+                parseResult.Add(id.ParseResult);
+                builder.Clear();
                 NextCh();
             }
-
-            if (dot_flag == true || currentCharValue != -1)
-                Error();
-
-            temp = builder.ToString();
-
-            if (char.IsDigit(temp[0]))
+            if (lastSymbol != -1)
+            {
                 Error();
-
-            parseResult.Add(temp);
-
+            }
             return true;
         }
     }
diff --git a/Module1/Lexer.csproj b/Module1/Lexer.csproj
index 6bfb931e8088586215e4e4d5694f2c923f9d5f73..7592ce676a25ba786975f4818e6108e64a851be1 100644
--- a/Module1/Lexer.csproj
+++ b/Module1/Lexer.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -13,6 +15,8 @@
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -42,6 +46,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -55,8 +62,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module1/packages.config b/Module1/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module1/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module2/SimpleLangLexer/SimpleLexer.cs b/Module2/SimpleLangLexer/SimpleLexer.cs
index 7bd0af4e65a57a95a208e01d8242bf4f0d50d410..87e0cd809edd0203e5b7f0f157b0fad1fe10719c 100644
--- a/Module2/SimpleLangLexer/SimpleLexer.cs
+++ b/Module2/SimpleLangLexer/SimpleLexer.cs
@@ -100,6 +100,19 @@ namespace SimpleLexer
             keywordsMap["begin"] = Tok.BEGIN;
             keywordsMap["end"] = Tok.END;
             keywordsMap["cycle"] = Tok.CYCLE;
+            keywordsMap["div"] = Tok.DIV;
+            keywordsMap["mod"] = Tok.MOD;
+            keywordsMap["and"] = Tok.AND;
+            keywordsMap["or"] = Tok.OR;
+            keywordsMap["not"] = Tok.NOT;
+            keywordsMap["while"] = Tok.WHILE;
+            keywordsMap["for"] = Tok.FOR;
+            keywordsMap["if"] = Tok.IF;
+            keywordsMap["to"] = Tok.TO;
+            keywordsMap["do"] = Tok.DO;
+            keywordsMap["then"] = Tok.THEN;
+            keywordsMap["else"] = Tok.ELSE;
+
         }
 
         public string FinishCurrentLine()
@@ -166,12 +179,16 @@ namespace SimpleLexer
             else if (currentCh == ':')
             {
                 NextCh();
-                if (currentCh != '=')
+                if (currentCh == '=')
                 {
-                    LexError("= was expected");
+                    LexKind = Tok.ASSIGN;
+                    NextCh();
                 }
-                NextCh();
-                LexKind = Tok.ASSIGN;
+                else
+                {
+                    LexKind = Tok.COLON;
+                }
+
             }
             else if (char.IsLetter(currentCh))
             {
@@ -201,6 +218,145 @@ namespace SimpleLexer
             {
                 LexKind = Tok.EOF;
             }
+            else if (currentCh == ',')
+            {
+                LexKind = Tok.COMMA;
+                NextCh();
+            }
+            else if (currentCh == '+')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.PLUSASSIGN;
+                    NextCh();
+                }
+                else
+                {
+                    LexKind = Tok.PLUS;
+                }
+
+            }
+            else if (currentCh == '-')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.MINUSASSIGN;
+                    NextCh();
+                }
+                else
+                {
+                    LexKind = Tok.MINUS;
+                }
+            }
+            else if (currentCh == '*')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.MULTASSIGN;
+                    NextCh();
+                }
+                else
+                {
+                    LexKind = Tok.MULT;
+                }
+            }
+            else if (currentCh == '/')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.DIVASSIGN;
+                    NextCh();
+                }
+                else if (currentCh == '/')
+                {
+                    NextCh();
+                    while ((int)currentCh != 0 && (currentCh != '\n'))
+                    {
+                        NextCh();
+                    }
+                    if (currentCh == '\n')
+                    {
+                        NextCh();
+                        NextLexem();
+                    }
+                    else
+                    {
+                        LexKind = Tok.EOF;
+                    }
+                }
+                else
+                {
+                    LexKind = Tok.DIVISION;
+                }
+            }
+            else if (currentCh == '=')
+            {
+                LexKind = Tok.EQ;
+                NextCh();
+            }
+            else if (currentCh == '>')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.GEQ;
+                    NextCh();
+                }
+                else
+                {
+                    LexKind = Tok.GT;
+                }
+            }
+            else if (currentCh == '<')
+            {
+                NextCh();
+                if (currentCh == '=')
+                {
+                    LexKind = Tok.LEQ;
+                    NextCh();
+                }
+                else if (currentCh == '>')
+                {
+                    LexKind = Tok.NEQ;
+                    NextCh();
+                }
+                else
+                {
+                    LexKind = Tok.LT;
+                }
+            }
+            else if (currentCh == '{')
+            {
+                NextCh();
+                while ((int)currentCh != 0 && (currentCh != '}'))
+                {
+                    NextCh();
+                }
+                if (currentCh == '}')
+                {
+                    NextCh();
+                    NextLexem();
+                }
+                else
+                {
+                    LexError("No closing bracket");
+                }
+            }
+            else if (currentCh == '(')
+            {
+                LexKind = Tok.LEFT_BRACKET;
+                NextCh();
+            }
+            else if (currentCh == ')')
+            {
+                LexKind = Tok.RIGHT_BRACKET;
+                NextCh();
+            }
+
             else
             {
                 LexError("Incorrect symbol " + currentCh);
diff --git a/Module2/SimpleLangLexer/SimpleLexer.csproj b/Module2/SimpleLangLexer/SimpleLexer.csproj
index 10cf9bdd2d1b7e84ed927e720a2269652432bbcd..97c1aa272cc755cebd1887210e6c5fc20f2e1f44 100644
--- a/Module2/SimpleLangLexer/SimpleLexer.csproj
+++ b/Module2/SimpleLangLexer/SimpleLexer.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -12,6 +14,8 @@
     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -41,6 +45,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -52,7 +59,17 @@
     <Compile Include="SimpleLexer.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module2/SimpleLangLexer/packages.config b/Module2/SimpleLangLexer/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module2/SimpleLangLexer/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module2/SimpleLexerDemo/SimpleLexerDemo.csproj b/Module2/SimpleLexerDemo/SimpleLexerDemo.csproj
index c1cae769b8f90c06b2c36d5a8f567a82011d8fc4..e4201b4bcfd58f9fe74bb03ca76b9fd8926ffdad 100644
--- a/Module2/SimpleLexerDemo/SimpleLexerDemo.csproj
+++ b/Module2/SimpleLexerDemo/SimpleLexerDemo.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -12,6 +14,8 @@
     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -38,6 +42,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -57,8 +64,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module2/SimpleLexerDemo/packages.config b/Module2/SimpleLexerDemo/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module2/SimpleLexerDemo/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module3/GeneratedLexer.csproj b/Module3/GeneratedLexer.csproj
index d424603f2cfb3ad42c1ef37ba301b041ec3801e4..33a17c2799a1b05df72f40a334035800c3c429e3 100644
--- a/Module3/GeneratedLexer.csproj
+++ b/Module3/GeneratedLexer.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -34,6 +36,8 @@
     <BootstrapperEnabled>true</BootstrapperEnabled>
     <LangVersion>5</LangVersion>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -54,6 +58,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
@@ -94,10 +101,18 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
     <None Include="SimpleLex.lex" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
   <ProjectExtensions>
     <VisualStudio AllowExistingFolder="true" />
   </ProjectExtensions>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
 </Project>
\ No newline at end of file
diff --git a/Module3/Gplex.exe b/Module3/Gplex.exe
new file mode 100644
index 0000000000000000000000000000000000000000..51a522e221f5ca52cc934933e08745f1653a98b5
Binary files /dev/null and b/Module3/Gplex.exe differ
diff --git a/Module3/LexerAddon.cs b/Module3/LexerAddon.cs
index c2467796d99e34b2906c362b66cf925504fe57e5..da6df4ccf1d2aa908ff8c093dec6dd7b37c30a03 100644
--- a/Module3/LexerAddon.cs
+++ b/Module3/LexerAddon.cs
@@ -19,7 +19,10 @@ namespace  GeneratedLexer
         public int sumInt = 0;
         public double sumDouble = 0.0;
         public List<string> idsInComment = new List<string>();
-        
+
+        public string apostrophe = "";
+
+
 
         public LexerAddon(string programText)
         {
@@ -37,6 +40,8 @@ namespace  GeneratedLexer
 
         public void Lex()
         {
+            int sum_id_len = 0; //sum длина идентификатора
+
             // Чтобы вещественные числа распознавались и отображались в формате 3.14 (а не 3,14 как в русской Culture)
             System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
 
@@ -46,8 +51,35 @@ namespace  GeneratedLexer
 
                 if (tok == (int)Tok.EOF)
                 {
+                    avgIdLength = idCount != 0 ? (double)sum_id_len / idCount : 0;           
                     break;
                 }
+                else if (tok == (int)Tok.ID)
+                {
+                    idCount++;
+                    int length = myScanner.yytext.Length;
+                    sum_id_len += length;
+                    minIdLength = length < minIdLength ? length : minIdLength;
+                    maxIdLength = length > maxIdLength ? length : maxIdLength;
+                }
+                else if (tok == (int)Tok.INUM)
+                {
+                    sumInt += myScanner.LexValueInt;
+                }
+                else if (tok == (int)Tok.RNUM)
+                {
+                    sumDouble += myScanner.LexValueDouble;
+                }
+                else if (tok == (int)Tok.STRINGAP)
+                {
+                    apostrophe = myScanner.yytext;
+                }
+                else if (tok == (int)Tok.LONGCOMMENT)
+                {
+                    idsInComment.Add(myScanner.yytext);
+                }
+
+
             } while (true);
         }
     }
diff --git a/Module3/SimpleLex.cs b/Module3/SimpleLex.cs
index d8f9df81a5460e11bf2e732ea49905ce52e6f7fa..169af759a67f3c028b4b9886315eee5779eac8e4 100644
--- a/Module3/SimpleLex.cs
+++ b/Module3/SimpleLex.cs
@@ -1,14 +1,10 @@
 //
 //  This CSharp output file generated by Gardens Point LEX
-//  Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
-//  Output produced by GPLEX is the property of the user.
-//  See accompanying file GPLEXcopyright.rtf.
-//
-//  GPLEX Version:  1.2.2
-//  Machine:  MAINHOMEPC2
-//  DateTime: 30.09.2018 17:57:38
-//  UserName: someone
-//  GPLEX input file <SimpleLex.lex - 30.09.2018 17:56:56>
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 27.11.2022 17:31:31
+//  UserName: ?????????????
+//  GPLEX input file <SimpleLex.lex>
 //  GPLEX frame file <embedded resource>
 //
 //  Option settings: noParser, minimize
@@ -16,8 +12,8 @@
 //
 
 //
-// Revised backup code
-// Version 1.2.1 of 24-June-2013
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
 //
 //
 #define BACKUP
@@ -126,15 +122,17 @@ namespace SimpleScanner
         
         enum Result {accept, noMatch, contextFound};
 
-        const int maxAccept = 20;
-        const int initial = 21;
+        const int maxAccept = 35;
+        const int initial = 36;
         const int eofNum = 0;
         const int goStart = -1;
         const int INITIAL = 0;
+        const int COMMENT = 1;
 
 #region user code
 public int LexValueInt;
   public double LexValueDouble;
+  public string idsInComment = "";
 #endregion user code
 
         int state;
@@ -166,112 +164,178 @@ public int LexValueInt;
         }
     };
 
-    static int[] startState = new int[] {21, 0};
+    static int[] startState = new int[] {36, 39, 0};
 
-    static Table[] NxS = new Table[23] {
+    static Table[] NxS = new Table[40] {
 /* NxS[   0] */ new Table(0, 0, 0, null),
 /* NxS[   1] */ new Table(0, 0, -1, null),
-/* NxS[   2] */ new Table(46, 12, -1, new sbyte[] {22, -1, 2, 2, 2, 2, 
-          2, 2, 2, 2, 2, 2}),
-/* NxS[   3] */ new Table(61, 1, -1, new sbyte[] {19}),
-/* NxS[   4] */ new Table(0, 0, -1, null),
-/* NxS[   5] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[   6] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 15, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[   7] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 11, 5}),
-/* NxS[   8] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[   9] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 10, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  10] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  11] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 12, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  12] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  13] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 14, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  14] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  15] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  16] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  17] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  18] */ new Table(48, 75, -1, new sbyte[] {5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, -1, -1, -1, -1, 5, -1, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5}),
-/* NxS[  19] */ new Table(0, 0, -1, null),
-/* NxS[  20] */ new Table(48, 10, -1, new sbyte[] {20, 20, 20, 20, 20, 20, 
-          20, 20, 20, 20}),
-/* NxS[  21] */ new Table(10, 113, 1, new sbyte[] {-1, 1, 1, -1, 1, 1, 
+/* NxS[   2] */ new Table(39, 1, 38, new sbyte[] {25}),
+/* NxS[   3] */ new Table(47, 1, -1, new sbyte[] {24}),
+/* NxS[   4] */ new Table(46, 12, -1, new sbyte[] {37, -1, 4, 4, 4, 4, 
+          4, 4, 4, 4, 4, 4}),
+/* NxS[   5] */ new Table(61, 1, -1, new sbyte[] {22}),
+/* NxS[   6] */ new Table(0, 0, -1, null),
+/* NxS[   7] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[   8] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 18, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[   9] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 14, 7}),
+/* NxS[  10] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 12, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  11] */ new Table(0, 0, -1, null),
+/* NxS[  12] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 13, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  13] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  14] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 15, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  15] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 16, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  16] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 17, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  17] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  18] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 19, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  19] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 20, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  20] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 21, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  21] */ new Table(48, 75, -1, new sbyte[] {7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, -1, -1, -1, -1, 7, -1, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7}),
+/* NxS[  22] */ new Table(0, 0, -1, null),
+/* NxS[  23] */ new Table(48, 10, -1, new sbyte[] {23, 23, 23, 23, 23, 23, 
+          23, 23, 23, 23}),
+/* NxS[  24] */ new Table(10, 4, 24, new sbyte[] {-1, 24, 24, -1}),
+/* NxS[  25] */ new Table(0, 0, -1, null),
+/* NxS[  26] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  27] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 32, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  28] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  29] */ new Table(0, 0, -1, null),
+/* NxS[  30] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 31, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  31] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  32] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 33, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  33] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 34, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  34] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 35, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  35] */ new Table(48, 75, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, -1, -1, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26}),
+/* NxS[  36] */ new Table(10, 114, 1, new sbyte[] {-1, 1, 1, -1, 1, 1, 
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-          -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 1, 1, 1, 1, 
-          1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 5, 
-          1, 5, 6, 7, 5, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}),
-/* NxS[  22] */ new Table(48, 10, -1, new sbyte[] {20, 20, 20, 20, 20, 20, 
-          20, 20, 20, 20}),
+          -1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 3, 
+          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 1, 1, 1, 1, 
+          1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 
+          1, 7, 8, 9, 7, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 11}),
+/* NxS[  37] */ new Table(48, 10, -1, new sbyte[] {23, 23, 23, 23, 23, 23, 
+          23, 23, 23, 23}),
+/* NxS[  38] */ new Table(39, 1, 38, new sbyte[] {25}),
+/* NxS[  39] */ new Table(65, 61, -1, new sbyte[] {26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, -1, -1, 26, -1, 26, 27, 26, 26, 28, 26, 
+          26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
+          26, 26, 26, 26, -1, -1, 29}),
     };
 
 int NextState() {
@@ -356,7 +420,8 @@ int NextState() {
 #if !NOFILES
      public Scanner(Stream file) {
             SetSource(file); // no unicode option
-        }   
+        }
+        
 #endif // !NOFILES
 
      public Scanner() { }
@@ -384,7 +449,7 @@ int NextState() {
                     if (next < 0xDC00 || next > 0xDFFF)
                         code = ScanBuff.UnicodeReplacementChar;
                     else
-                        code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
                 }
 #endif
                 cCol++;
@@ -437,7 +502,9 @@ int NextState() {
             GetCode();
         }
 
+#if !NOFILES        
         // ================ LineBuffer Initialization ===================
+
         /// <summary>
         /// Create and initialize a LineBuff buffer object for this scanner
         /// </summary>
@@ -451,7 +518,6 @@ int NextState() {
             GetCode();
         }
 
-#if !NOFILES        
         // =============== StreamBuffer Initialization ==================
 
         /// <summary>
@@ -553,12 +619,6 @@ int NextState() {
             }
         }
 
-        /// <summary>
-        /// Discards all but the first "n" codepoints in the recognized pattern.
-        /// Resets the buffer position so that only n codepoints have been consumed;
-        /// yytext is also re-evaluated. 
-        /// </summary>
-        /// <param name="n">The number of codepoints to consume</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void yyless(int n)
         {
@@ -578,10 +638,6 @@ int NextState() {
         //  but it does not seem possible to re-establish
         //  the correct column counts except by going forward.
         //
-        /// <summary>
-        /// Removes the last "n" code points from the pattern.
-        /// </summary>
-        /// <param name="n">The number to remove</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void _yytrunc(int n) { yyless(yyleng - n); }
         
@@ -594,23 +650,18 @@ int NextState() {
         // can't use (tokEPos - tokPos) because of the
         // possibility of surrogate pairs in the token.
         //
-        /// <summary>
-        /// The length of the pattern in codepoints (not the same as 
-        /// string-length if the pattern contains any surrogate pairs).
-        /// </summary>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
         public int yyleng
         {
             get {
+#if BYTEMODE
+                return tokEPos - tokPos;
+#else   
                 if (tokELin == tokLin)
                     return tokECol - tokCol;
-                else
-#if BYTEMODE
-                    return tokEPos - tokPos;
-#else
-                {
+                else {
                     int ch;
                     int count = 0;
                     int save = buffer.Pos;
@@ -619,7 +670,7 @@ int NextState() {
                         ch = buffer.Read();
                         if (!char.IsHighSurrogate((char)ch)) count++;
                     } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
-                    buffer.Pos = save;
+                    buffer.Pos = save; 
                     return count;
                 }
 #endif // BYTEMODE
@@ -644,55 +695,64 @@ int NextState() {
 
         // ============== The main tokenizer code =================
 
-        int Scan() {
-                for (; ; ) {
-                    int next;              // next state to enter
+        int Scan()
+        {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
 #if LEFTANCHORS
-                    for (;;) {
+                    for (;;)
+                    {
                         // Discard characters that do not start any pattern.
                         // Must check the left anchor condition after *every* GetCode!
                         state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
-                        if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
+                        if ((next = NextState()) != goStart) 
+                            break; // LOOP EXIT HERE...
                         GetCode();
                     }
                     
 #else // !LEFTANCHORS
                     state = currentStart;
-                    while ((next = NextState()) == goStart) {
+                    while ((next = NextState()) == goStart)
                         // At this point, the current character has no
                         // transition from the current state.  We discard 
                         // the "no-match" char.   In traditional LEX such 
                         // characters are echoed to the console.
                         GetCode();
-                    }
 #endif // LEFTANCHORS                    
                     // At last, a valid transition ...    
                     MarkToken();
                     state = next;
-                    GetCode();                    
+                    GetCode();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
 #if BACKUP
-                    bool contextSaved = false;
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                        if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
-                            // Store data for the *latest* accept state that was found.
-                            SaveStateAndPos( ref ctx );
-                            contextSaved = true;
+                        if (state <= maxAccept && next > maxAccept) // need to prepare backup data
+                        {
+                            // ctx is an object. The fields may be 
+                            // mutated by the call to Recurse2.
+                            // On return the data in ctx is the
+                            // *latest* accept state that was found.
+                            
+                            rslt = Recurse2(ref ctx, next);
+                            if (rslt == Result.noMatch) 
+                                RestoreStateAndPos(ref ctx);
+                            break;
                         }
-                        state = next;
-                        GetCode();
-                    }
-                    if (state > maxAccept && contextSaved)
-                        RestoreStateAndPos( ref ctx );
-#else  // BACKUP
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                         state = next;
-                         GetCode();
-                    }
+                        else
 #endif // BACKUP
-                    if (state <= maxAccept) {
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
                         MarkEnd();
 #region ActionSwitch
-#pragma warning disable 162, 1522
+#pragma warning disable 162
     switch (state)
     {
         case eofNum:
@@ -700,59 +760,111 @@ int NextState() {
                 return (int)Tokens.EOF;
             break;
         case 1:
+        case 2:
+        case 3:
 LexError();
 	return 0;
             break;
-        case 2:
+        case 4:
 LexValueInt = int.Parse(yytext);
   return (int)Tok.INUM;
             break;
-        case 3:
+        case 5:
 return (int)Tok.COLON;
             break;
-        case 4:
+        case 6:
 return (int)Tok.SEMICOLON;
             break;
-        case 5:
-        case 6:
         case 7:
         case 8:
         case 9:
-        case 11:
+        case 10:
         case 12:
-        case 13:
+        case 14:
         case 15:
         case 16:
-        case 17:
+        case 18:
+        case 19:
+        case 20:
 return (int)Tok.ID;
             break;
-        case 10:
+        case 11:
+BEGIN(COMMENT);
+            break;
+        case 13:
 return (int)Tok.END;
             break;
-        case 14:
+        case 17:
 return (int)Tok.CYCLE;
             break;
-        case 18:
+        case 21:
 return (int)Tok.BEGIN;
             break;
-        case 19:
+        case 22:
 return (int)Tok.ASSIGN;
             break;
-        case 20:
+        case 23:
 LexValueDouble = double.Parse(yytext);
   return (int)Tok.RNUM;
             break;
+        case 24:
+return (int)Tok.COMMENT;
+            break;
+        case 25:
+return (int)Tok.STRINGAP;
+            break;
+        case 26:
+        case 27:
+        case 28:
+        case 30:
+        case 32:
+        case 33:
+        case 34:
+idsInComment = yytext;
+  return (int)Tok.LONGCOMMENT;
+            break;
+        case 29:
+BEGIN(INITIAL);
+            break;
+        case 31:
+return (int)Tok.END;
+            break;
+        case 35:
+return (int)Tok.BEGIN;
+            break;
         default:
             break;
     }
-#pragma warning restore 162, 1522
+#pragma warning restore 162
 #endregion
                     }
                 }
         }
 
 #if BACKUP
-        void SaveStateAndPos(ref Context ctx) {
+        Result Recurse2(ref Context ctx, int next)
+        {
+            // Assert: at entry "state" is an accept state AND
+            //         NextState(state, code) != goStart AND
+            //         NextState(state, code) is not an accept state.
+            //
+            SaveStateAndPos(ref ctx);
+            state = next;
+            GetCode();
+
+            while ((next = NextState()) > eofNum)
+            {
+                if (state <= maxAccept && next > maxAccept) // need to update backup data
+                    SaveStateAndPos(ref ctx);
+                state = next;
+                if (state == eofNum) return Result.accept;
+                GetCode(); 
+            }
+            return (state <= maxAccept ? Result.accept : Result.noMatch);
+        }
+
+        void SaveStateAndPos(ref Context ctx)
+        {
             ctx.bPos  = buffer.Pos;
             ctx.rPos  = readPos;
             ctx.cCol  = cCol;
@@ -761,7 +873,8 @@ LexValueDouble = double.Parse(yytext);
             ctx.cChr  = code;
         }
 
-        void RestoreStateAndPos(ref Context ctx) {
+        void RestoreStateAndPos(ref Context ctx)
+        {
             buffer.Pos = ctx.bPos;
             readPos = ctx.rPos;
             cCol  = ctx.cCol;
@@ -769,7 +882,8 @@ LexValueDouble = double.Parse(yytext);
             state = ctx.state;
             code  = ctx.cChr;
         }
-#endif  // BACKUP
+
+#endif // BACKUP
 
         // ============= End of the tokenizer code ================
 
@@ -803,7 +917,7 @@ LexValueDouble = double.Parse(yytext);
 
 public void LexError()
 {
-	Console.WriteLine("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
+	Console.WriteLine("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
 }
 
 public string TokToString(Tok tok)
@@ -870,7 +984,6 @@ public string TokToString(Tok tok)
             return new LineBuffer(source);
         }
 
-#if (!NOFILES)
         public static ScanBuff GetBuffer(Stream source)
         {
             return new BuildBuffer(source);
@@ -881,8 +994,7 @@ public string TokToString(Tok tok)
         {
             return new BuildBuffer(source, fallbackCodePage);
         }
-#endif // !BYTEMODE
-#endif // !NOFILES
+#endif
     }
 
     #region Buffer classes
@@ -1005,7 +1117,7 @@ public string TokToString(Tok tok)
             {
                 ix = lstart = 0;
             }
-            while (ix < numLines)
+            for (; ; )
             {
                 int len = line[ix].Length + 1;
                 if (pos < lstart + len) break;
@@ -1063,8 +1175,7 @@ public string TokToString(Tok tok)
             {
                 cPos = value;
                 findIndex(cPos, out cLine, out curLineStart);
-                // cLine should be the *next* line after curLine.
-                curLine = (cLine < numLines ? line[cLine++] : "");
+                curLine = line[cLine];
                 curLineEnd = curLineStart + curLine.Length;
             }
         }
@@ -1072,7 +1183,7 @@ public string TokToString(Tok tok)
         public override string ToString() { return "LineBuffer"; }
     }
 
-#if (!NOFILES)
+
     // ==============================================================
     // =====     class BuildBuff : for unicode text files    ========
     // ==============================================================
@@ -1313,13 +1424,12 @@ public string TokToString(Tok tok)
         }
 #endif // !BYTEMODE
     }
-#endif // !NOFILES
     #endregion Buffer classes
 
     // ==============================================================
     // ============      class CodePageHandling         =============
     // ==============================================================
-#if (!NOFILES)
+
     public static class CodePageHandling
     {
         public static int GetCodePage(string option)
@@ -1530,7 +1640,6 @@ public string TokToString(Tok tok)
     
 #endif // !BYTEMODE
 #endregion
-#endif // !NOFILES
 
 // End of code copied from embedded resource
 
diff --git a/Module3/SimpleLex.lex b/Module3/SimpleLex.lex
index c0434f09b6e8ca1adf55cd70f9ae3e4b18e41e45..4b3285398bf87c428a8e99f16e20392ada84c7fa 100644
--- a/Module3/SimpleLex.lex
+++ b/Module3/SimpleLex.lex
@@ -7,14 +7,50 @@ AlphaDigit {Alpha}|{Digit}
 INTNUM  {Digit}+
 REALNUM {INTNUM}\.{INTNUM}
 ID {Alpha}{AlphaDigit}* 
+DotChr [^\r\n]
+OneLineCmnt  \/\/{DotChr}*
+Apostrophe \'[^']*\'
+
+
+
+%x COMMENT
 
 // Здесь можно делать описания типов, переменных и методов - они попадают в класс Scanner
 %{
   public int LexValueInt;
   public double LexValueDouble;
+  public string idsInComment = "";
 %}
 
+
+
 %%
+
+"{" { 
+  //    COMMENT
+  BEGIN(COMMENT);
+}
+
+<COMMENT> "}" { 
+  // переход в состояние INITIAL (исходное)
+  BEGIN(INITIAL);
+}
+
+<COMMENT>begin { 
+  return (int)Tok.BEGIN;
+}
+
+<COMMENT>end { 
+  return (int)Tok.END;
+}
+
+<COMMENT>{ID} {
+  idsInComment = yytext;
+  return (int)Tok.LONGCOMMENT;
+}
+
+
+
 {INTNUM} { 
   LexValueInt = int.Parse(yytext);
   return (int)Tok.INUM;
@@ -41,6 +77,16 @@ cycle {
   return (int)Tok.ID;
 }
 
+{OneLineCmnt} { 
+	return (int)Tok.COMMENT;
+}
+
+{Apostrophe} {
+	return (int)Tok.STRINGAP;
+}
+
+
+
 ":" { 
   return (int)Tok.COLON;
 }
@@ -58,6 +104,7 @@ cycle {
 	return 0; // конец разбора
 }
 
+
 %%
 
 // Здесь можно делать описания переменных и методов - они тоже попадают в класс Scanner
diff --git a/Module3/SimpleLex.lst b/Module3/SimpleLex.lst
new file mode 100644
index 0000000000000000000000000000000000000000..e6ee40106e72e0721576229f819d826664ca7752
--- /dev/null
+++ b/Module3/SimpleLex.lst
@@ -0,0 +1,141 @@
+
+// ==========================================================================
+//  GPLEX error listing for lex source file <SimpleLex.lex>
+// ==========================================================================
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 27.11.2022 17:27:41
+//  UserName: ?????????????
+// ==========================================================================
+
+
+%using ScannerHelper;
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+DotChr [^\r\n]
+OneLineCmnt  \/\/{DotChr}*
+Apostrophe \'[^']*\'
+
+
+
+%x COMMENT
+
+// Здесь можно делать описания типов, переменных и методов - они попадают в класс Scanner
+%{
+  public int LexValueInt;
+  public double LexValueDouble;
+  public List<string> commentedIDs = new List<string>();
+%}
+
+
+
+%%
+{INTNUM} { 
+  LexValueInt = int.Parse(yytext);
+  return (int)Tok.INUM;
+}
+
+{REALNUM} { 
+  LexValueDouble = double.Parse(yytext);
+  return (int)Tok.RNUM;
+}
+
+begin { 
+  return (int)Tok.BEGIN;
+}
+
+end { 
+  return (int)Tok.END;
+}
+
+cycle { 
+  return (int)Tok.CYCLE;
+}
+
+{ID}  { 
+  return (int)Tok.ID;
+}
+
+{OneLineCmnt} { 
+	return (int)Tok.COMMENT;
+}
+
+{Apostrophe} {
+	return (int)Tok.STRINGAP;
+}
+
+
+
+":" { 
+  return (int)Tok.COLON;
+}
+
+":=" { 
+  return (int)Tok.ASSIGN;
+}
+
+";" { 
+  return (int)Tok.SEMICOLON;
+}
+
+[^ \r\n] {
+//^^^^^^
+// Warning: This pattern always overrides ""{"" 
+// ---------------------------------------------
+	LexError();
+	return 0; // конец разбора
+}
+
+"{" { 
+// Warning: This pattern always overridden by "[^ \r\n]" 
+// ------------------------------------------------------
+  // переход в состояние COMMENT
+  BEGIN(COMMENT);
+}
+
+<COMMENT> "}" { 
+  // переход в состояние INITIAL (исходное)
+  BEGIN(INITIAL);
+}
+
+<COMMENT>{ID} {
+  if (yytext != "begin" && yytext != "end" && yytext != "cycle") {
+		commentedIDs.Add(yytext);
+  }
+
+  return (int)Tok.LONGCOMMENT;
+}
+
+
+%%
+
+// Здесь можно делать описания переменных и методов - они тоже попадают в класс Scanner
+
+public void LexError()
+{
+	Console.WriteLine("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+}
+
+public string TokToString(Tok tok)
+{
+	switch (tok)
+	{
+		case Tok.ID:
+			return tok + " " + yytext;
+		case Tok.INUM:
+			return tok + " " + LexValueInt;
+		case Tok.RNUM:
+			return tok + " " + LexValueDouble;
+		default:
+			return tok + "";
+	}
+}
+
+// ==========================================================================
+
diff --git a/Module3/a.txt b/Module3/a.txt
index cda64314589386e33d85b530880ee7a9b74b7e00..9db1d29f9bfc4947b9df7acb5e2e3daa745705a5 100644
--- a/Module3/a.txt
+++ b/Module3/a.txt
@@ -1,3 +1,3 @@
-begin ggg : ; :+= 7 99.9 5 
-1 
+begin gggggg ppp : ; : 7 99.9 5 
+1 2
 ppp end
diff --git a/Module3/mymain.cs b/Module3/mymain.cs
index 9a33c597556eaecf3a6908bf931d847f7ed6c273..d9f67b196cf393510a325492b088872833813d64 100644
--- a/Module3/mymain.cs
+++ b/Module3/mymain.cs
@@ -12,7 +12,8 @@ namespace GeneratedLexer
         {
             int cnt_id = 0;//кол-во идентификаторов
             int min_id_len = Int32.MaxValue, max_id_len = 0; //минимальная, максимальная длины идентификаторов
-            double avg_id_len = 0; //средняя длина идентификатора
+   
+            int sum_id_len = 0; //sum длина идентификатора
 
             int sum_int = 0; //сумма всех целых
             double sum_d = 0; //сумма всех вещественных
@@ -34,9 +35,9 @@ namespace GeneratedLexer
                 {
                     Console.WriteLine();
                     Console.WriteLine("number of id: {0:D}", cnt_id);
-                    Console.WriteLine("average length of the id: {0:N}", avg_id_len / cnt_id);
+                    Console.WriteLine("average length of the id: {0:N}", sum_id_len / cnt_id);
                     Console.WriteLine("min length of the id: {0:D}", min_id_len);
-                    Console.WriteLine("min length of the id: {0:D}", max_id_len);
+                    Console.WriteLine("max length of the id: {0:D}", max_id_len);
 
                     Console.WriteLine();
                     Console.WriteLine("sum of int: {0:D}", sum_int);
@@ -46,6 +47,23 @@ namespace GeneratedLexer
 
                     break;
                 }
+                else if (tok == (int)Tok.ID)
+                {
+                    cnt_id++; 
+                    int length = scanner.yytext.Length;
+                    sum_id_len += length;
+                    min_id_len = length < min_id_len ? length : min_id_len;
+                    max_id_len = length > max_id_len ? length : max_id_len;
+                } 
+                else if (tok == (int)Tok.INUM)
+                {
+                    sum_int += scanner.LexValueInt;
+                }
+                else if (tok == (int)Tok.RNUM)
+                {
+                    sum_d += scanner.LexValueDouble;
+                }
+
 
                 Console.WriteLine(scanner.TokToString((Tok)tok));
             } while (true);
diff --git a/Module3/packages.config b/Module3/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module3/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module4/SimpleLangParser/RecursiveDescentParser.csproj b/Module4/SimpleLangParser/RecursiveDescentParser.csproj
index 62fc7818a91b3f1e20c354c41d9a8c683e3f2de5..7375ec7eaf0efd8acf3f8dd0bfee462872e5749b 100644
--- a/Module4/SimpleLangParser/RecursiveDescentParser.csproj
+++ b/Module4/SimpleLangParser/RecursiveDescentParser.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -12,6 +14,8 @@
     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -41,6 +45,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -58,7 +65,17 @@
       <Name>SimpleLexer</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module4/SimpleLangParser/SimpleLangParser.cs b/Module4/SimpleLangParser/SimpleLangParser.cs
index 246db0b398caf6b3e0ecd83364d3832a912b8882..06387d3bdcb931abe3b1bcb591f898d843c8c63e 100644
--- a/Module4/SimpleLangParser/SimpleLangParser.cs
+++ b/Module4/SimpleLangParser/SimpleLangParser.cs
@@ -27,7 +27,7 @@ namespace SimpleLangParser
             Block();
         }
 
-        public void Expr() 
+        public void Expr2() 
         {
             if (l.LexKind == Tok.ID || l.LexKind == Tok.INUM)
             {
@@ -39,6 +39,66 @@ namespace SimpleLangParser
             }
         }
 
+        // ==== другая грамматика ====
+
+        public void Expr()
+        {
+            T();
+            A();
+        }
+
+        public void T()
+        {
+            M();
+            B();
+        }
+
+        public void A()
+        {
+            if (l.LexKind == Tok.PLUS || l.LexKind == Tok.MINUS)
+            {
+                l.NextLexem(); // РїСЂРѕРїСѓСЃРє sign
+                T();
+                A();
+            }
+        }
+
+        public void B()
+        {
+            if (l.LexKind == Tok.MULT || l.LexKind == Tok.DIVISION)
+            {
+                l.NextLexem();
+                M();
+                B();
+            }
+        }
+        public void M()
+        {
+            if (l.LexKind == Tok.ID || l.LexKind == Tok.INUM)
+            {
+                l.NextLexem();
+            }
+            else if (l.LexKind == Tok.LEFT_BRACKET)
+            {
+                l.NextLexem(); // РїСЂРѕРїСѓСЃРє (
+                Expr();
+                if (l.LexKind != Tok.RIGHT_BRACKET)
+                {
+                    SyntaxError(") expected");
+                }
+                l.NextLexem(); 
+            }
+            else
+            {
+                SyntaxError("ID, number or (expr) expected");
+            }
+        }
+
+
+
+        // ==== другая грамматика ====
+
+
         public void Assign() 
         {
             l.NextLexem();  // РїСЂРѕРїСѓСЃРє id
@@ -81,6 +141,22 @@ namespace SimpleLangParser
                         Assign();
                         break;
                     }
+                case Tok.WHILE:
+                    {
+                        While();
+                        break;
+                    }
+                case Tok.FOR:
+                    {
+                        For();
+                        break;
+                    }
+                case Tok.IF:
+                    {
+                        If();
+                        break;
+                    }
+
                 default:
                     {
                         SyntaxError("Operator expected");
@@ -111,6 +187,66 @@ namespace SimpleLangParser
             Statement();
         }
 
+        public void While()
+        {
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє while
+            Expr();
+            if (l.LexKind != Tok.DO)
+            {
+                SyntaxError("do expected");
+            }
+
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє do
+            Statement();
+        }
+
+        public void For()
+        {
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє for
+            if (l.LexKind != Tok.ID)
+            {
+                SyntaxError("id expected");
+            }
+            Assign();
+
+            if (l.LexKind != Tok.TO)
+            {
+                SyntaxError("to expected");
+            }
+
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє TO
+            Expr();
+            if (l.LexKind != Tok.DO)
+            {
+                SyntaxError("do expected");
+            }
+
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє DO
+            Statement();
+        }
+
+        public void If()
+        {
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє if
+            Expr();
+
+            if (l.LexKind != Tok.THEN)
+            {
+                SyntaxError("then expected");
+            }
+
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє then
+            Statement();
+            if (l.LexKind != Tok.ELSE)
+            {
+                return; // если неполная форма всё ок - не выкидываем SyntaxError
+            }
+            l.NextLexem(); // РїСЂРѕРїСѓСЃРє else
+            Statement();
+        }
+
+
+
         public void SyntaxError(string message) 
         {
             var errorMessage = "Syntax error in line " + l.LexRow.ToString() + ":\n";
diff --git a/Module4/SimpleLangParser/packages.config b/Module4/SimpleLangParser/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module4/SimpleLangParser/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module4/SimpleLangParserTest/RecursiveDescentParserDemo.csproj b/Module4/SimpleLangParserTest/RecursiveDescentParserDemo.csproj
index ff254b89bced368398aef650c9983b7d71de8b7d..fd91524b8d692958dcbca1476042dd3d1e085dfd 100644
--- a/Module4/SimpleLangParserTest/RecursiveDescentParserDemo.csproj
+++ b/Module4/SimpleLangParserTest/RecursiveDescentParserDemo.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -12,6 +14,8 @@
     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -41,6 +45,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -64,8 +71,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module4/SimpleLangParserTest/packages.config b/Module4/SimpleLangParserTest/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module4/SimpleLangParserTest/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module5/GeneratedParser.csproj b/Module5/GeneratedParser.csproj
index 6928965c0f6a926b9e0237d904f9ede6ddaa47c9..ecefaf8e456ecdb1e20d9daf54f8347ab1fedd5e 100644
--- a/Module5/GeneratedParser.csproj
+++ b/Module5/GeneratedParser.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -14,6 +16,8 @@
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <PlatformTarget>x86</PlatformTarget>
@@ -60,6 +64,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -83,8 +90,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module5/SimpleLex.cs b/Module5/SimpleLex.cs
index af473da5e86ca6d0a581b5a1a65f18662ef3ba88..dc2b032302cdf0e867a18c868cf2c8e051c3c87d 100644
--- a/Module5/SimpleLex.cs
+++ b/Module5/SimpleLex.cs
@@ -1,14 +1,10 @@
 //
 //  This CSharp output file generated by Gardens Point LEX
-//  Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
-//  Output produced by GPLEX is the property of the user.
-//  See accompanying file GPLEXcopyright.rtf.
-//
-//  GPLEX Version:  1.2.2
-//  Machine:  MAINHOMEPC2
-//  DateTime: 30.09.2018 18:11:00
-//  UserName: someone
-//  GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:02>
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 28.11.2022 22:08:30
+//  UserName: ?????????????
+//  GPLEX input file <SimpleLex.lex>
 //  GPLEX frame file <embedded resource>
 //
 //  Option settings: unicode, parser, minimize
@@ -17,8 +13,8 @@
 //
 
 //
-// Revised backup code
-// Version 1.2.1 of 24-June-2013
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
 //
 //
 #define BACKUP
@@ -127,8 +123,8 @@ namespace SimpleScanner
         
         enum Result {accept, noMatch, contextFound};
 
-        const int maxAccept = 7;
-        const int initial = 8;
+        const int maxAccept = 14;
+        const int initial = 15;
         const int eofNum = 0;
         const int goStart = -1;
         const int INITIAL = 0;
@@ -165,24 +161,24 @@ namespace SimpleScanner
         }
     };
 
-    static int[] startState = new int[] {8, 0};
+    static int[] startState = new int[] {15, 0};
 
 #region CompressedCharacterMap
     //
-    // There are 8 equivalence classes
+    // There are 15 equivalence classes
     // There are 2 character sequence regions
     // There are 1 tables, 123 entries
     // There are 1 runs, 0 singletons
     // Decision tree depth is 1
     //
     static sbyte[] mapC0 = new sbyte[123] {
-/*     '\0' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7, 
-/*   '\x10' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-/*   '\x20' */ 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 
-/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 7, 5, 7, 7, 
-/*      '@' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
-/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 3, 
-/*      '`' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*     '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14, 
+/*   '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+/*   '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 7, 8, 12, 10, 9, 11, 2, 13, 
+/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14, 
+/*      '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 
+/*      '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
 /*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
 
     static sbyte MapC(int code)
@@ -190,22 +186,29 @@ namespace SimpleScanner
       if (code < 123) // '\0' <= code <= 'z'
         return mapC0[code - 0];
       else // '{' <= code <= '\U0010FFFF'
-        return (sbyte)7;
+        return (sbyte)14;
     }
 #endregion
 
-    static Table[] NxS = new Table[10] {
+    static Table[] NxS = new Table[17] {
 /* NxS[   0] */ new Table(0, 0, 0, null),
-/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 16}),
 /* NxS[   2] */ new Table(0, 0, -1, null),
 /* NxS[   3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
-/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {6}),
+/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {13}),
 /* NxS[   5] */ new Table(0, 0, -1, null),
 /* NxS[   6] */ new Table(0, 0, -1, null),
-/* NxS[   7] */ new Table(1, 1, -1, new sbyte[] {7}),
-/* NxS[   8] */ new Table(1, 7, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
-          2}),
-/* NxS[   9] */ new Table(1, 1, -1, new sbyte[] {7}),
+/* NxS[   7] */ new Table(0, 0, -1, null),
+/* NxS[   8] */ new Table(0, 0, -1, null),
+/* NxS[   9] */ new Table(0, 0, -1, null),
+/* NxS[  10] */ new Table(0, 0, -1, null),
+/* NxS[  11] */ new Table(0, 0, -1, null),
+/* NxS[  12] */ new Table(0, 0, -1, null),
+/* NxS[  13] */ new Table(0, 0, -1, null),
+/* NxS[  14] */ new Table(1, 1, -1, new sbyte[] {14}),
+/* NxS[  15] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
+          6, 7, 8, 9, 10, 11, 12, 2}),
+/* NxS[  16] */ new Table(1, 1, -1, new sbyte[] {14}),
     };
 
 int NextState() {
@@ -215,7 +218,7 @@ int NextState() {
         unchecked {
             int rslt;
             int idx = MapC(code) - NxS[state].min;
-            if (idx < 0) idx += 8;
+            if (idx < 0) idx += 15;
             if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
             else rslt = NxS[state].nxt[idx];
             return rslt;
@@ -295,7 +298,8 @@ int NextState() {
 
         public Scanner(Stream file, string codepage) {
             SetSource(file, CodePageHandling.GetCodePage(codepage));
-        }   
+        }
+        
 #endif // !NOFILES
 
      public Scanner() { }
@@ -323,7 +327,7 @@ int NextState() {
                     if (next < 0xDC00 || next > 0xDFFF)
                         code = ScanBuff.UnicodeReplacementChar;
                     else
-                        code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
                 }
 #endif
                 cCol++;
@@ -376,7 +380,9 @@ int NextState() {
             GetCode();
         }
 
+#if !NOFILES        
         // ================ LineBuffer Initialization ===================
+
         /// <summary>
         /// Create and initialize a LineBuff buffer object for this scanner
         /// </summary>
@@ -390,7 +396,6 @@ int NextState() {
             GetCode();
         }
 
-#if !NOFILES        
         // =============== StreamBuffer Initialization ==================
 
         /// <summary>
@@ -492,12 +497,6 @@ int NextState() {
             }
         }
 
-        /// <summary>
-        /// Discards all but the first "n" codepoints in the recognized pattern.
-        /// Resets the buffer position so that only n codepoints have been consumed;
-        /// yytext is also re-evaluated. 
-        /// </summary>
-        /// <param name="n">The number of codepoints to consume</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void yyless(int n)
         {
@@ -517,10 +516,6 @@ int NextState() {
         //  but it does not seem possible to re-establish
         //  the correct column counts except by going forward.
         //
-        /// <summary>
-        /// Removes the last "n" code points from the pattern.
-        /// </summary>
-        /// <param name="n">The number to remove</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void _yytrunc(int n) { yyless(yyleng - n); }
         
@@ -533,23 +528,18 @@ int NextState() {
         // can't use (tokEPos - tokPos) because of the
         // possibility of surrogate pairs in the token.
         //
-        /// <summary>
-        /// The length of the pattern in codepoints (not the same as 
-        /// string-length if the pattern contains any surrogate pairs).
-        /// </summary>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
         public int yyleng
         {
             get {
+#if BYTEMODE
+                return tokEPos - tokPos;
+#else   
                 if (tokELin == tokLin)
                     return tokECol - tokCol;
-                else
-#if BYTEMODE
-                    return tokEPos - tokPos;
-#else
-                {
+                else {
                     int ch;
                     int count = 0;
                     int save = buffer.Pos;
@@ -558,7 +548,7 @@ int NextState() {
                         ch = buffer.Read();
                         if (!char.IsHighSurrogate((char)ch)) count++;
                     } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
-                    buffer.Pos = save;
+                    buffer.Pos = save; 
                     return count;
                 }
 #endif // BYTEMODE
@@ -583,56 +573,65 @@ int NextState() {
 
         // ============== The main tokenizer code =================
 
-        int Scan() {
+        int Scan()
+        {
             try {
-                for (; ; ) {
-                    int next;              // next state to enter
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
 #if LEFTANCHORS
-                    for (;;) {
+                    for (;;)
+                    {
                         // Discard characters that do not start any pattern.
                         // Must check the left anchor condition after *every* GetCode!
                         state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
-                        if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
+                        if ((next = NextState()) != goStart) 
+                            break; // LOOP EXIT HERE...
                         GetCode();
                     }
                     
 #else // !LEFTANCHORS
                     state = currentStart;
-                    while ((next = NextState()) == goStart) {
+                    while ((next = NextState()) == goStart)
                         // At this point, the current character has no
                         // transition from the current state.  We discard 
                         // the "no-match" char.   In traditional LEX such 
                         // characters are echoed to the console.
                         GetCode();
-                    }
 #endif // LEFTANCHORS                    
                     // At last, a valid transition ...    
                     MarkToken();
                     state = next;
-                    GetCode();                    
+                    GetCode();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
 #if BACKUP
-                    bool contextSaved = false;
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                        if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
-                            // Store data for the *latest* accept state that was found.
-                            SaveStateAndPos( ref ctx );
-                            contextSaved = true;
+                        if (state <= maxAccept && next > maxAccept) // need to prepare backup data
+                        {
+                            // ctx is an object. The fields may be 
+                            // mutated by the call to Recurse2.
+                            // On return the data in ctx is the
+                            // *latest* accept state that was found.
+                            
+                            rslt = Recurse2(ref ctx, next);
+                            if (rslt == Result.noMatch) 
+                                RestoreStateAndPos(ref ctx);
+                            break;
                         }
-                        state = next;
-                        GetCode();
-                    }
-                    if (state > maxAccept && contextSaved)
-                        RestoreStateAndPos( ref ctx );
-#else  // BACKUP
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                         state = next;
-                         GetCode();
-                    }
+                        else
 #endif // BACKUP
-                    if (state <= maxAccept) {
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
                         MarkEnd();
 #region ActionSwitch
-#pragma warning disable 162, 1522
+#pragma warning disable 162
     switch (state)
     {
         case eofNum:
@@ -655,15 +654,36 @@ int res = ScannerHelper.GetIDToken(yytext);
 return (int)Tokens.SEMICOLON;
             break;
         case 6:
-return (int)Tokens.ASSIGN;
+return (int)Tokens.LEFT_BRACKET;
             break;
         case 7:
+return (int)Tokens.RIGHT_BRACKET;
+            break;
+        case 8:
+return (int)Tokens.COMMA;
+            break;
+        case 9:
+return (int)Tokens.PLUS;
+            break;
+        case 10:
+return (int)Tokens.MINUS;
+            break;
+        case 11:
+return (int)Tokens.MULT;
+            break;
+        case 12:
+return (int)Tokens.DIV;
+            break;
+        case 13:
+return (int)Tokens.ASSIGN;
+            break;
+        case 14:
 return (int)Tokens.RNUM;
             break;
         default:
             break;
     }
-#pragma warning restore 162, 1522
+#pragma warning restore 162
 #endregion
                     }
                 }
@@ -676,7 +696,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         }
 
 #if BACKUP
-        void SaveStateAndPos(ref Context ctx) {
+        Result Recurse2(ref Context ctx, int next)
+        {
+            // Assert: at entry "state" is an accept state AND
+            //         NextState(state, code) != goStart AND
+            //         NextState(state, code) is not an accept state.
+            //
+            SaveStateAndPos(ref ctx);
+            state = next;
+            GetCode();
+
+            while ((next = NextState()) > eofNum)
+            {
+                if (state <= maxAccept && next > maxAccept) // need to update backup data
+                    SaveStateAndPos(ref ctx);
+                state = next;
+                if (state == eofNum) return Result.accept;
+                GetCode(); 
+            }
+            return (state <= maxAccept ? Result.accept : Result.noMatch);
+        }
+
+        void SaveStateAndPos(ref Context ctx)
+        {
             ctx.bPos  = buffer.Pos;
             ctx.rPos  = readPos;
             ctx.cCol  = cCol;
@@ -685,7 +727,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             ctx.cChr  = code;
         }
 
-        void RestoreStateAndPos(ref Context ctx) {
+        void RestoreStateAndPos(ref Context ctx)
+        {
             buffer.Pos = ctx.bPos;
             readPos = ctx.rPos;
             cCol  = ctx.cCol;
@@ -693,7 +736,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             state = ctx.state;
             code  = ctx.cChr;
         }
-#endif  // BACKUP
+
+#endif // BACKUP
 
         // ============= End of the tokenizer code ================
 
@@ -725,16 +769,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         
 #region UserCodeSection
 
-public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
+public override void yyerror(string format, params object[] args) // обработка синтаксических ошибок
 {
   var ww = args.Skip(1).Cast<string>().ToArray();
-  string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
+  string errorMsg = string.Format("({0},{1}): Встречено {2}, а ожидалось {3}", yyline, yycol, args[0], string.Join(" или ", ww));
   throw new SyntaxException(errorMsg);
 }
 
 public void LexError()
 {
-	string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
+	string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
     throw new LexException(errorMsg);
 }
 
@@ -748,10 +792,23 @@ class ScannerHelper
     keywords.Add("begin",(int)Tokens.BEGIN);
     keywords.Add("end",(int)Tokens.END);
     keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("while",(int)Tokens.WHILE);
+    keywords.Add("do",(int)Tokens.DO);
+    keywords.Add("repeat",(int)Tokens.REPEAT);
+    keywords.Add("until",(int)Tokens.UNTIL);
+    keywords.Add("for", (int)Tokens.FOR);
+    keywords.Add("to", (int)Tokens.TO);
+    keywords.Add("write", (int)Tokens.WRITE);
+    keywords.Add("if", (int)Tokens.IF);
+    keywords.Add("then", (int)Tokens.THEN);
+    keywords.Add("else", (int)Tokens.ELSE);
+    keywords.Add("var",(int)Tokens.VAR);
+
+
   }
   public static int GetIDToken(string s)
   {
-    if (keywords.ContainsKey(s.ToLower())) // ÿçûê íå÷óâñòâèòåëåí ê ðåãèñòðó
+    if (keywords.ContainsKey(s.ToLower())) // язык нечувствителен к регистру
       return keywords[s];
     else
       return (int)Tokens.ID;
@@ -807,7 +864,6 @@ class ScannerHelper
             return new LineBuffer(source);
         }
 
-#if (!NOFILES)
         public static ScanBuff GetBuffer(Stream source)
         {
             return new BuildBuffer(source);
@@ -818,8 +874,7 @@ class ScannerHelper
         {
             return new BuildBuffer(source, fallbackCodePage);
         }
-#endif // !BYTEMODE
-#endif // !NOFILES
+#endif
     }
 
     #region Buffer classes
@@ -942,7 +997,7 @@ class ScannerHelper
             {
                 ix = lstart = 0;
             }
-            while (ix < numLines)
+            for (; ; )
             {
                 int len = line[ix].Length + 1;
                 if (pos < lstart + len) break;
@@ -1000,8 +1055,7 @@ class ScannerHelper
             {
                 cPos = value;
                 findIndex(cPos, out cLine, out curLineStart);
-                // cLine should be the *next* line after curLine.
-                curLine = (cLine < numLines ? line[cLine++] : "");
+                curLine = line[cLine];
                 curLineEnd = curLineStart + curLine.Length;
             }
         }
@@ -1009,7 +1063,7 @@ class ScannerHelper
         public override string ToString() { return "LineBuffer"; }
     }
 
-#if (!NOFILES)
+
     // ==============================================================
     // =====     class BuildBuff : for unicode text files    ========
     // ==============================================================
@@ -1250,13 +1304,12 @@ class ScannerHelper
         }
 #endif // !BYTEMODE
     }
-#endif // !NOFILES
     #endregion Buffer classes
 
     // ==============================================================
     // ============      class CodePageHandling         =============
     // ==============================================================
-#if (!NOFILES)
+
     public static class CodePageHandling
     {
         public static int GetCodePage(string option)
@@ -1467,7 +1520,6 @@ class ScannerHelper
     
 #endif // !BYTEMODE
 #endregion
-#endif // !NOFILES
 
 // End of code copied from embedded resource
 
diff --git a/Module5/SimpleLex.lex b/Module5/SimpleLex.lex
index 10547e9b9695423ba9e54065df5945d19fd597a9..486ba0271b809fd52717379e642552a000b53fee 100644
--- a/Module5/SimpleLex.lex
+++ b/Module5/SimpleLex.lex
@@ -28,6 +28,15 @@ ID {Alpha}{AlphaDigit}*
 
 ":=" { return (int)Tokens.ASSIGN; }
 ";"  { return (int)Tokens.SEMICOLON; }
+"(" { return (int)Tokens.LEFT_BRACKET; }
+")"  { return (int)Tokens.RIGHT_BRACKET; }
+","  { return (int)Tokens.COMMA; }
+"+"  { return (int)Tokens.PLUS; }
+"-" { return (int)Tokens.MINUS; }
+"*"  { return (int)Tokens.MULT; }
+"/"  { return (int)Tokens.DIV; }
+
+
 
 [^ \r\n] {
 	LexError();
@@ -63,6 +72,19 @@ class ScannerHelper
     keywords.Add("begin",(int)Tokens.BEGIN);
     keywords.Add("end",(int)Tokens.END);
     keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("while",(int)Tokens.WHILE);
+    keywords.Add("do",(int)Tokens.DO);
+    keywords.Add("repeat",(int)Tokens.REPEAT);
+    keywords.Add("until",(int)Tokens.UNTIL);
+    keywords.Add("for", (int)Tokens.FOR);
+    keywords.Add("to", (int)Tokens.TO);
+    keywords.Add("write", (int)Tokens.WRITE);
+    keywords.Add("if", (int)Tokens.IF);
+    keywords.Add("then", (int)Tokens.THEN);
+    keywords.Add("else", (int)Tokens.ELSE);
+    keywords.Add("var",(int)Tokens.VAR);
+
+
   }
   public static int GetIDToken(string s)
   {
diff --git a/Module5/SimpleYacc.cs b/Module5/SimpleYacc.cs
index 0be791437a683b1c6147f0ca5e9e36fc68941431..d90f58e3e01a216d1dceae7feb88e0636ba4ba14 100644
--- a/Module5/SimpleYacc.cs
+++ b/Module5/SimpleYacc.cs
@@ -1,102 +1,161 @@
 // This code was generated by the Gardens Point Parser Generator
-// Copyright (c) Wayne Kelly, John Gough, QUT 2005-2014
+// Copyright (c) Wayne Kelly, QUT 2005-2010
 // (see accompanying GPPGcopyright.rtf)
 
-// GPPG version 1.5.2
-// Machine:  MAINHOMEPC2
-// DateTime: 30.09.2018 18:11:19
-// UserName: someone
-// Input file <SimpleYacc.y - 24.09.2018 23:47:02>
+// GPPG version 1.3.6
+// Machine:  WIN-51KGPO1PTR9
+// DateTime: 28.11.2022 22:08:30
+// UserName: ?????????????
+// Input file <SimpleYacc.y>
 
 // options: no-lines gplex
 
 using System;
 using System.Collections.Generic;
-using System.CodeDom.Compiler;
 using System.Globalization;
 using System.Text;
 using QUT.Gppg;
 
 namespace SimpleParser
 {
-public enum Tokens {error=2,EOF=3,BEGIN=4,END=5,CYCLE=6,
-    INUM=7,RNUM=8,ID=9,ASSIGN=10,SEMICOLON=11};
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,INUM=6,
+    RNUM=7,ID=8,ASSIGN=9,SEMICOLON=10,WHILE=11,DO=12,
+    REPEAT=13,UNTIL=14,FOR=15,TO=16,WRITE=17,LEFT_BRACKET=18,
+    RIGHT_BRACKET=19,IF=20,THEN=21,ELSE=22,VAR=23,COMMA=24,
+    PLUS=25,MINUS=26,MULT=27,DIV=28};
 
 // Abstract base class for GPLEX scanners
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public abstract class ScanBase : AbstractScanner<int,LexLocation> {
   private LexLocation __yylloc = new LexLocation();
   public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } }
   protected virtual bool yywrap() { return true; }
 }
 
-// Utility class for encapsulating token information
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
-public class ScanObj {
-  public int token;
-  public int yylval;
-  public LexLocation yylloc;
-  public ScanObj( int t, int val, LexLocation loc ) {
-    this.token = t; this.yylval = val; this.yylloc = loc;
-  }
-}
-
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public class Parser: ShiftReduceParser<int, LexLocation>
 {
-  // Verbatim content from SimpleYacc.y - 24.09.2018 23:47:02
-// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
     public Parser(AbstractScanner<int, LexLocation> scanner) : base(scanner) { }
-  // End verbatim content from SimpleYacc.y - 24.09.2018 23:47:02
+  // End verbatim content from SimpleYacc.y
 
 #pragma warning disable 649
-  private static Dictionary<int, string> aliases;
+  private static Dictionary<int, string> aliasses;
 #pragma warning restore 649
-  private static Rule[] rules = new Rule[14];
-  private static State[] states = new State[22];
+  private static Rule[] rules = new Rule[36];
+  private static State[] states = new State[70];
   private static string[] nonTerms = new string[] {
       "progr", "$accept", "block", "stlist", "statement", "assign", "cycle", 
-      "ident", "expr", };
+      "while", "repeat", "for", "write", "if", "var", "ident", "expr", "t", "f", 
+      "id_list", };
 
   static Parser() {
-    states[0] = new State(new int[]{4,4},new int[]{-1,1,-3,3});
-    states[1] = new State(new int[]{3,2});
+    states[0] = new State(new int[]{3,4},new int[]{-1,1,-3,3});
+    states[1] = new State(new int[]{2,2});
     states[2] = new State(-1);
     states[3] = new State(-2);
-    states[4] = new State(new int[]{9,14,4,4,6,18},new int[]{-4,5,-5,21,-6,9,-8,10,-3,16,-7,17});
-    states[5] = new State(new int[]{5,6,11,7});
-    states[6] = new State(-12);
-    states[7] = new State(new int[]{9,14,4,4,6,18},new int[]{-5,8,-6,9,-8,10,-3,16,-7,17});
+    states[4] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-4,5,-5,44,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[5] = new State(new int[]{4,6,10,7});
+    states[6] = new State(-25);
+    states[7] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,8,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
     states[8] = new State(-4);
     states[9] = new State(-5);
-    states[10] = new State(new int[]{10,11});
-    states[11] = new State(new int[]{9,14,7,15},new int[]{-9,12,-8,13});
-    states[12] = new State(-9);
-    states[13] = new State(-10);
-    states[14] = new State(-8);
-    states[15] = new State(-11);
-    states[16] = new State(-6);
-    states[17] = new State(-7);
-    states[18] = new State(new int[]{9,14,7,15},new int[]{-9,19,-8,13});
-    states[19] = new State(new int[]{9,14,4,4,6,18},new int[]{-5,20,-6,9,-8,10,-3,16,-7,17});
-    states[20] = new State(-13);
-    states[21] = new State(-3);
-
-    for (int sNo = 0; sNo < states.Length; sNo++) states[sNo].number = sNo;
+    states[10] = new State(new int[]{9,11});
+    states[11] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,12,-16,28,-17,27,-14,17});
+    states[12] = new State(new int[]{25,13,26,23,4,-15,10,-15,14,-15,22,-15,16,-15});
+    states[13] = new State(new int[]{8,18,6,19,18,20},new int[]{-16,14,-17,27,-14,17});
+    states[14] = new State(new int[]{27,15,28,25,25,-17,26,-17,4,-17,10,-17,14,-17,22,-17,16,-17,19,-17,8,-17,3,-17,5,-17,11,-17,13,-17,15,-17,17,-17,20,-17,23,-17,12,-17,21,-17});
+    states[15] = new State(new int[]{8,18,6,19,18,20},new int[]{-17,16,-14,17});
+    states[16] = new State(-20);
+    states[17] = new State(-22);
+    states[18] = new State(-14);
+    states[19] = new State(-23);
+    states[20] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,21,-16,28,-17,27,-14,17});
+    states[21] = new State(new int[]{19,22,25,13,26,23});
+    states[22] = new State(-24);
+    states[23] = new State(new int[]{8,18,6,19,18,20},new int[]{-16,24,-17,27,-14,17});
+    states[24] = new State(new int[]{27,15,28,25,25,-18,26,-18,4,-18,10,-18,14,-18,22,-18,16,-18,19,-18,8,-18,3,-18,5,-18,11,-18,13,-18,15,-18,17,-18,20,-18,23,-18,12,-18,21,-18});
+    states[25] = new State(new int[]{8,18,6,19,18,20},new int[]{-17,26,-14,17});
+    states[26] = new State(-21);
+    states[27] = new State(-19);
+    states[28] = new State(new int[]{27,15,28,25,25,-16,26,-16,4,-16,10,-16,14,-16,22,-16,16,-16,19,-16,8,-16,3,-16,5,-16,11,-16,13,-16,15,-16,17,-16,20,-16,23,-16,12,-16,21,-16});
+    states[29] = new State(-6);
+    states[30] = new State(-7);
+    states[31] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,32,-16,28,-17,27,-14,17});
+    states[32] = new State(new int[]{25,13,26,23,8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,33,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[33] = new State(-26);
+    states[34] = new State(-8);
+    states[35] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,36,-16,28,-17,27,-14,17});
+    states[36] = new State(new int[]{12,37,25,13,26,23});
+    states[37] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,38,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[38] = new State(-27);
+    states[39] = new State(-9);
+    states[40] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-4,41,-5,44,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[41] = new State(new int[]{14,42,10,7});
+    states[42] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,43,-16,28,-17,27,-14,17});
+    states[43] = new State(new int[]{25,13,26,23,4,-28,10,-28,14,-28,22,-28});
+    states[44] = new State(-3);
+    states[45] = new State(-10);
+    states[46] = new State(new int[]{8,18},new int[]{-6,47,-14,10});
+    states[47] = new State(new int[]{16,48});
+    states[48] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,49,-16,28,-17,27,-14,17});
+    states[49] = new State(new int[]{12,50,25,13,26,23});
+    states[50] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,51,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[51] = new State(-29);
+    states[52] = new State(-11);
+    states[53] = new State(new int[]{18,54});
+    states[54] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,55,-16,28,-17,27,-14,17});
+    states[55] = new State(new int[]{19,56,25,13,26,23});
+    states[56] = new State(-30);
+    states[57] = new State(-12);
+    states[58] = new State(new int[]{8,18,6,19,18,20},new int[]{-15,59,-16,28,-17,27,-14,17});
+    states[59] = new State(new int[]{21,60,25,13,26,23});
+    states[60] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,61,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[61] = new State(new int[]{22,62,4,-32,10,-32,14,-32});
+    states[62] = new State(new int[]{8,18,3,4,5,31,11,35,13,40,15,46,17,53,20,58,23,65},new int[]{-5,63,-6,9,-14,10,-3,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[63] = new State(-31);
+    states[64] = new State(-13);
+    states[65] = new State(new int[]{8,18},new int[]{-18,66,-14,69});
+    states[66] = new State(new int[]{24,67,4,-33,10,-33,14,-33,22,-33});
+    states[67] = new State(new int[]{8,18},new int[]{-14,68});
+    states[68] = new State(-34);
+    states[69] = new State(-35);
 
-    rules[1] = new Rule(-2, new int[]{-1,3});
+    rules[1] = new Rule(-2, new int[]{-1,2});
     rules[2] = new Rule(-1, new int[]{-3});
     rules[3] = new Rule(-4, new int[]{-5});
-    rules[4] = new Rule(-4, new int[]{-4,11,-5});
+    rules[4] = new Rule(-4, new int[]{-4,10,-5});
     rules[5] = new Rule(-5, new int[]{-6});
     rules[6] = new Rule(-5, new int[]{-3});
     rules[7] = new Rule(-5, new int[]{-7});
-    rules[8] = new Rule(-8, new int[]{9});
-    rules[9] = new Rule(-6, new int[]{-8,10,-9});
-    rules[10] = new Rule(-9, new int[]{-8});
-    rules[11] = new Rule(-9, new int[]{7});
-    rules[12] = new Rule(-3, new int[]{4,-4,5});
-    rules[13] = new Rule(-7, new int[]{6,-9,-5});
+    rules[8] = new Rule(-5, new int[]{-8});
+    rules[9] = new Rule(-5, new int[]{-9});
+    rules[10] = new Rule(-5, new int[]{-10});
+    rules[11] = new Rule(-5, new int[]{-11});
+    rules[12] = new Rule(-5, new int[]{-12});
+    rules[13] = new Rule(-5, new int[]{-13});
+    rules[14] = new Rule(-14, new int[]{8});
+    rules[15] = new Rule(-6, new int[]{-14,9,-15});
+    rules[16] = new Rule(-15, new int[]{-16});
+    rules[17] = new Rule(-15, new int[]{-15,25,-16});
+    rules[18] = new Rule(-15, new int[]{-15,26,-16});
+    rules[19] = new Rule(-16, new int[]{-17});
+    rules[20] = new Rule(-16, new int[]{-16,27,-17});
+    rules[21] = new Rule(-16, new int[]{-16,28,-17});
+    rules[22] = new Rule(-17, new int[]{-14});
+    rules[23] = new Rule(-17, new int[]{6});
+    rules[24] = new Rule(-17, new int[]{18,-15,19});
+    rules[25] = new Rule(-3, new int[]{3,-4,4});
+    rules[26] = new Rule(-7, new int[]{5,-15,-5});
+    rules[27] = new Rule(-8, new int[]{11,-15,12,-5});
+    rules[28] = new Rule(-9, new int[]{13,-4,14,-15});
+    rules[29] = new Rule(-10, new int[]{15,-6,16,-15,12,-5});
+    rules[30] = new Rule(-11, new int[]{17,18,-15,19});
+    rules[31] = new Rule(-12, new int[]{20,-15,21,-5,22,-5});
+    rules[32] = new Rule(-12, new int[]{20,-15,21,-5});
+    rules[33] = new Rule(-13, new int[]{23,-18});
+    rules[34] = new Rule(-18, new int[]{-18,24,-14});
+    rules[35] = new Rule(-18, new int[]{-14});
   }
 
   protected override void Initialize() {
@@ -108,17 +167,15 @@ public class Parser: ShiftReduceParser<int, LexLocation>
 
   protected override void DoAction(int action)
   {
-#pragma warning disable 162, 1522
     switch (action)
     {
     }
-#pragma warning restore 162, 1522
   }
 
   protected override string TerminalToString(int terminal)
   {
-    if (aliases != null && aliases.ContainsKey(terminal))
-        return aliases[terminal];
+    if (aliasses != null && aliasses.ContainsKey(terminal))
+        return aliasses[terminal];
     else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture))
         return ((Tokens)terminal).ToString();
     else
diff --git a/Module5/SimpleYacc.lst b/Module5/SimpleYacc.lst
index 6a40f2d376fe60dec695a3f3c5f547d9b46f6bf6..0a56bd519115531867f617a15d0c0ce8bad09e27 100644
--- a/Module5/SimpleYacc.lst
+++ b/Module5/SimpleYacc.lst
@@ -3,9 +3,9 @@
 //  GPPG error listing for yacc source file <SimpleYacc.y>
 // ==========================================================================
 //  Version:  1.3.6
-//  Machine:  SSM
-//  DateTime: 17.08.2014 10:25:15
-//  UserName: Станислав
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 28.11.2022 21:40:09
+//  UserName: Администратор
 // ==========================================================================
 
 
@@ -16,19 +16,17 @@
 
 %output = SimpleYacc.cs
 
-%using System.IO;
-
 %namespace SimpleParser
 
-%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON  
+%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE
 
 %%
-// Error: NonTerminal symbol "st" has no productions
-// Warning: Terminating st fixes the following size-2 NonTerminal set
-   // {cycle, st}
-// Error: There are 2 non-terminating NonTerminal Symbols
-   //  {cycle, st}
-// ------------------------------------------------------------------
+// Error: NonTerminal symbol "write" has no productions
+// Warning: Terminating write fixes the following size-1 NonTerminal set
+   // {write}
+// Error: There are 1 non-terminating NonTerminal Symbols
+   //  {write}
+// ---------------------------------------------------------------------
 
 progr   : block
 		;
@@ -39,7 +37,11 @@ stlist	: statement
 
 statement: assign
 		| block  
-		| cycle  
+		| cycle
+		| while
+		| repeat
+		| for
+		| write
 		;
 
 ident 	: ID 
@@ -55,10 +57,21 @@ expr	: ident
 block	: BEGIN stlist END 
 		;
 
-cycle	: CYCLE expr st 
+cycle	: CYCLE expr statement 
+		;
+
+while	: WHILE expr DO statement 
 		;
+
+repeat	: REPEAT stlist UNTIL expr
+		;
+
+for		: FOR ID ASSIGN expr TO expr DO statement
+		;
+
+
+
 	
 %%
-
 // ==========================================================================
 
diff --git a/Module5/SimpleYacc.y b/Module5/SimpleYacc.y
index 95947328e21b95b7a66c1d8f5fbd6990cff9fae3..ea88b7df46e2017c8ec5d5e8820a26616c32dfb9 100644
--- a/Module5/SimpleYacc.y
+++ b/Module5/SimpleYacc.y
@@ -7,7 +7,7 @@
 
 %namespace SimpleParser
 
-%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON  
+%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE LEFT_BRACKET RIGHT_BRACKET IF THEN ELSE VAR COMMA PLUS MINUS MULT DIV
 
 %%
 
@@ -20,7 +20,13 @@ stlist	: statement
 
 statement: assign
 		| block  
-		| cycle  
+		| cycle
+		| while
+		| repeat
+		| for
+		| write
+		| if
+		| var
 		;
 
 ident 	: ID 
@@ -29,14 +35,51 @@ ident 	: ID
 assign 	: ident ASSIGN expr 
 		;
 
-expr	: ident  
-		| INUM 
-		;
+// дополнение грамматики
+expr : t
+     | expr PLUS t
+     | expr MINUS t
+     ;
+
+t    : f
+     | t MULT f
+     | t DIV f
+     ;
+
+f    : ident
+     | INUM 
+     | LEFT_BRACKET expr RIGHT_BRACKET
+     ;
+// дополнение грамматики
+
 
 block	: BEGIN stlist END 
 		;
 
 cycle	: CYCLE expr statement 
 		;
-	
+
+while	: WHILE expr DO statement 
+		;
+
+repeat	: REPEAT stlist UNTIL expr
+		;
+
+for		: FOR assign TO expr DO statement
+		;
+
+write   : WRITE LEFT_BRACKET expr RIGHT_BRACKET
+		;
+
+if		: IF expr THEN statement ELSE statement
+		| IF expr THEN statement
+		;
+
+var		: VAR id_list
+		;
+
+id_list	: id_list COMMA ident
+		| ident
+		;
+
 %%
diff --git a/Module5/packages.config b/Module5/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module5/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module6/ParserAST.csproj b/Module6/ParserAST.csproj
index b6c10a75acc1c95ed305a9ab4b0eaf6efa624066..b5dfa80fbe6ab5eefa25e7f62d326cca89c21f01 100644
--- a/Module6/ParserAST.csproj
+++ b/Module6/ParserAST.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -14,6 +16,8 @@
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <PlatformTarget>x86</PlatformTarget>
@@ -64,6 +68,9 @@
       <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net35\Newtonsoft.Json.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -90,6 +97,13 @@
     <Content Include="SimpleYacc.y" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module6/ProgramTree.cs b/Module6/ProgramTree.cs
index ade12f7bf2514b8b52857a88840f4f94faa39839..2def4a9bb72494f9fbebbfa9154cc9470367867b 100644
--- a/Module6/ProgramTree.cs
+++ b/Module6/ProgramTree.cs
@@ -4,6 +4,8 @@ namespace ProgramTree
 {
     public enum AssignType { Assign, AssignPlus, AssignMinus, AssignMult, AssignDivide };
 
+    public enum BinOpType { ADD, SUB, MUL, DIV };
+
     public class Node // базовый класс для всех узлов    
     {
     }
@@ -65,4 +67,94 @@ namespace ProgramTree
         }
     }
 
+    public class WhileNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode Stat { get; set; }
+        public WhileNode(ExprNode expr, StatementNode stat)
+        {
+            Expr = expr;
+            Stat = stat;
+        }
+    }
+
+    public class RepeatNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public BlockNode StList { get; set; }
+        public RepeatNode(BlockNode stlist, ExprNode expr)
+        {
+            Expr = expr;
+            StList = stlist;
+        }
+    }
+
+    public class ForNode : StatementNode
+    {
+        public AssignNode Assign { get; set; }
+        public ExprNode Expr { get; set; }
+        public StatementNode Statement { get; set; }
+        public ForNode(AssignNode assi, ExprNode expr, StatementNode st)
+        {
+            Assign = assi;
+            Expr = expr;
+            Statement = st;
+        }
+    }
+
+    public class WriteNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public WriteNode(ExprNode expr)
+        {
+            Expr = expr;
+        }
+    }
+
+    public class IfNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode IfStat { get; set; }
+        public StatementNode ElseStat { get; set; }
+        public IfNode(ExprNode expr, StatementNode ifStat, StatementNode elseStat)
+        {
+            Expr = expr;
+            IfStat = ifStat;
+            ElseStat = elseStat;
+        }
+
+        public IfNode(ExprNode expr, StatementNode ifStat)
+        {
+            Expr = expr;
+            IfStat = ifStat;
+            ElseStat = null;
+        }
+    }
+
+    public class VarNode : StatementNode
+    {
+        public List<IdNode> IDList = new List<IdNode>();
+        public VarNode(IdNode id)
+        {
+            Add(id);
+        }
+        public void Add(IdNode id)
+        {
+            IDList.Add(id);
+        }
+    }
+
+    public class BinNode : ExprNode
+    {
+        public ExprNode Left { get; set; }
+        public ExprNode Right { get; set; }
+        public BinOpType Operation { get; set; }
+        public BinNode(ExprNode left, ExprNode right, BinOpType operation)
+        {
+            Left = left;
+            Right = right;
+            Operation = operation;
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/Module6/SimpleLex.cs b/Module6/SimpleLex.cs
index c518c8b3443fd6ed15300f8e5f3eea6733bd0974..06b6f635250cbbdae67a6c55bc6eb48784069b31 100644
--- a/Module6/SimpleLex.cs
+++ b/Module6/SimpleLex.cs
@@ -1,14 +1,10 @@
 //
 //  This CSharp output file generated by Gardens Point LEX
-//  Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
-//  Output produced by GPLEX is the property of the user.
-//  See accompanying file GPLEXcopyright.rtf.
-//
-//  GPLEX Version:  1.2.2
-//  Machine:  MAINHOMEPC2
-//  DateTime: 30.09.2018 18:14:30
-//  UserName: someone
-//  GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:03>
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 29.11.2022 12:28:16
+//  UserName: ?????????????
+//  GPLEX input file <SimpleLex.lex>
 //  GPLEX frame file <embedded resource>
 //
 //  Option settings: unicode, parser, minimize
@@ -17,8 +13,8 @@
 //
 
 //
-// Revised backup code
-// Version 1.2.1 of 24-June-2013
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
 //
 //
 #define BACKUP
@@ -127,8 +123,8 @@ namespace SimpleScanner
         
         enum Result {accept, noMatch, contextFound};
 
-        const int maxAccept = 7;
-        const int initial = 8;
+        const int maxAccept = 14;
+        const int initial = 15;
         const int eofNum = 0;
         const int goStart = -1;
         const int INITIAL = 0;
@@ -165,24 +161,24 @@ namespace SimpleScanner
         }
     };
 
-    static int[] startState = new int[] {8, 0};
+    static int[] startState = new int[] {15, 0};
 
 #region CompressedCharacterMap
     //
-    // There are 8 equivalence classes
+    // There are 15 equivalence classes
     // There are 2 character sequence regions
     // There are 1 tables, 123 entries
     // There are 1 runs, 0 singletons
     // Decision tree depth is 1
     //
     static sbyte[] mapC0 = new sbyte[123] {
-/*     '\0' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7, 
-/*   '\x10' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-/*   '\x20' */ 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 
-/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 7, 5, 7, 7, 
-/*      '@' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
-/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 3, 
-/*      '`' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*     '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14, 
+/*   '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+/*   '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 7, 8, 13, 10, 9, 11, 2, 12, 
+/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14, 
+/*      '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 
+/*      '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
 /*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
 
     static sbyte MapC(int code)
@@ -190,22 +186,29 @@ namespace SimpleScanner
       if (code < 123) // '\0' <= code <= 'z'
         return mapC0[code - 0];
       else // '{' <= code <= '\U0010FFFF'
-        return (sbyte)7;
+        return (sbyte)14;
     }
 #endregion
 
-    static Table[] NxS = new Table[10] {
+    static Table[] NxS = new Table[17] {
 /* NxS[   0] */ new Table(0, 0, 0, null),
-/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 16}),
 /* NxS[   2] */ new Table(0, 0, -1, null),
 /* NxS[   3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
-/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {6}),
+/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {13}),
 /* NxS[   5] */ new Table(0, 0, -1, null),
 /* NxS[   6] */ new Table(0, 0, -1, null),
-/* NxS[   7] */ new Table(1, 1, -1, new sbyte[] {7}),
-/* NxS[   8] */ new Table(1, 7, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
-          2}),
-/* NxS[   9] */ new Table(1, 1, -1, new sbyte[] {7}),
+/* NxS[   7] */ new Table(0, 0, -1, null),
+/* NxS[   8] */ new Table(0, 0, -1, null),
+/* NxS[   9] */ new Table(0, 0, -1, null),
+/* NxS[  10] */ new Table(0, 0, -1, null),
+/* NxS[  11] */ new Table(0, 0, -1, null),
+/* NxS[  12] */ new Table(0, 0, -1, null),
+/* NxS[  13] */ new Table(0, 0, -1, null),
+/* NxS[  14] */ new Table(1, 1, -1, new sbyte[] {14}),
+/* NxS[  15] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
+          6, 7, 8, 9, 10, 11, 12, 2}),
+/* NxS[  16] */ new Table(1, 1, -1, new sbyte[] {14}),
     };
 
 int NextState() {
@@ -215,7 +218,7 @@ int NextState() {
         unchecked {
             int rslt;
             int idx = MapC(code) - NxS[state].min;
-            if (idx < 0) idx += 8;
+            if (idx < 0) idx += 15;
             if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
             else rslt = NxS[state].nxt[idx];
             return rslt;
@@ -295,7 +298,8 @@ int NextState() {
 
         public Scanner(Stream file, string codepage) {
             SetSource(file, CodePageHandling.GetCodePage(codepage));
-        }   
+        }
+        
 #endif // !NOFILES
 
      public Scanner() { }
@@ -323,7 +327,7 @@ int NextState() {
                     if (next < 0xDC00 || next > 0xDFFF)
                         code = ScanBuff.UnicodeReplacementChar;
                     else
-                        code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
                 }
 #endif
                 cCol++;
@@ -376,7 +380,9 @@ int NextState() {
             GetCode();
         }
 
+#if !NOFILES        
         // ================ LineBuffer Initialization ===================
+
         /// <summary>
         /// Create and initialize a LineBuff buffer object for this scanner
         /// </summary>
@@ -390,7 +396,6 @@ int NextState() {
             GetCode();
         }
 
-#if !NOFILES        
         // =============== StreamBuffer Initialization ==================
 
         /// <summary>
@@ -492,12 +497,6 @@ int NextState() {
             }
         }
 
-        /// <summary>
-        /// Discards all but the first "n" codepoints in the recognized pattern.
-        /// Resets the buffer position so that only n codepoints have been consumed;
-        /// yytext is also re-evaluated. 
-        /// </summary>
-        /// <param name="n">The number of codepoints to consume</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void yyless(int n)
         {
@@ -517,10 +516,6 @@ int NextState() {
         //  but it does not seem possible to re-establish
         //  the correct column counts except by going forward.
         //
-        /// <summary>
-        /// Removes the last "n" code points from the pattern.
-        /// </summary>
-        /// <param name="n">The number to remove</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void _yytrunc(int n) { yyless(yyleng - n); }
         
@@ -533,23 +528,18 @@ int NextState() {
         // can't use (tokEPos - tokPos) because of the
         // possibility of surrogate pairs in the token.
         //
-        /// <summary>
-        /// The length of the pattern in codepoints (not the same as 
-        /// string-length if the pattern contains any surrogate pairs).
-        /// </summary>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
         public int yyleng
         {
             get {
+#if BYTEMODE
+                return tokEPos - tokPos;
+#else   
                 if (tokELin == tokLin)
                     return tokECol - tokCol;
-                else
-#if BYTEMODE
-                    return tokEPos - tokPos;
-#else
-                {
+                else {
                     int ch;
                     int count = 0;
                     int save = buffer.Pos;
@@ -558,7 +548,7 @@ int NextState() {
                         ch = buffer.Read();
                         if (!char.IsHighSurrogate((char)ch)) count++;
                     } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
-                    buffer.Pos = save;
+                    buffer.Pos = save; 
                     return count;
                 }
 #endif // BYTEMODE
@@ -583,56 +573,65 @@ int NextState() {
 
         // ============== The main tokenizer code =================
 
-        int Scan() {
+        int Scan()
+        {
             try {
-                for (; ; ) {
-                    int next;              // next state to enter
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
 #if LEFTANCHORS
-                    for (;;) {
+                    for (;;)
+                    {
                         // Discard characters that do not start any pattern.
                         // Must check the left anchor condition after *every* GetCode!
                         state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
-                        if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
+                        if ((next = NextState()) != goStart) 
+                            break; // LOOP EXIT HERE...
                         GetCode();
                     }
                     
 #else // !LEFTANCHORS
                     state = currentStart;
-                    while ((next = NextState()) == goStart) {
+                    while ((next = NextState()) == goStart)
                         // At this point, the current character has no
                         // transition from the current state.  We discard 
                         // the "no-match" char.   In traditional LEX such 
                         // characters are echoed to the console.
                         GetCode();
-                    }
 #endif // LEFTANCHORS                    
                     // At last, a valid transition ...    
                     MarkToken();
                     state = next;
-                    GetCode();                    
+                    GetCode();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
 #if BACKUP
-                    bool contextSaved = false;
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                        if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
-                            // Store data for the *latest* accept state that was found.
-                            SaveStateAndPos( ref ctx );
-                            contextSaved = true;
+                        if (state <= maxAccept && next > maxAccept) // need to prepare backup data
+                        {
+                            // ctx is an object. The fields may be 
+                            // mutated by the call to Recurse2.
+                            // On return the data in ctx is the
+                            // *latest* accept state that was found.
+                            
+                            rslt = Recurse2(ref ctx, next);
+                            if (rslt == Result.noMatch) 
+                                RestoreStateAndPos(ref ctx);
+                            break;
                         }
-                        state = next;
-                        GetCode();
-                    }
-                    if (state > maxAccept && contextSaved)
-                        RestoreStateAndPos( ref ctx );
-#else  // BACKUP
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                         state = next;
-                         GetCode();
-                    }
+                        else
 #endif // BACKUP
-                    if (state <= maxAccept) {
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
                         MarkEnd();
 #region ActionSwitch
-#pragma warning disable 162, 1522
+#pragma warning disable 162
     switch (state)
     {
         case eofNum:
@@ -657,16 +656,37 @@ int res = ScannerHelper.GetIDToken(yytext);
 return (int)Tokens.SEMICOLON;
             break;
         case 6:
-return (int)Tokens.ASSIGN;
+return (int)Tokens.LBRACKET;
             break;
         case 7:
+return (int)Tokens.RBRACKET;
+            break;
+        case 8:
+return (int)Tokens.COMMA;
+            break;
+        case 9:
+return (int)Tokens.ADD;
+            break;
+        case 10:
+return (int)Tokens.SUB;
+            break;
+        case 11:
+return (int)Tokens.DIV;
+            break;
+        case 12:
+return (int)Tokens.MUL;
+            break;
+        case 13:
+return (int)Tokens.ASSIGN;
+            break;
+        case 14:
 yylval.dVal = double.Parse(yytext); 
   return (int)Tokens.RNUM;
             break;
         default:
             break;
     }
-#pragma warning restore 162, 1522
+#pragma warning restore 162
 #endregion
                     }
                 }
@@ -679,7 +699,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         }
 
 #if BACKUP
-        void SaveStateAndPos(ref Context ctx) {
+        Result Recurse2(ref Context ctx, int next)
+        {
+            // Assert: at entry "state" is an accept state AND
+            //         NextState(state, code) != goStart AND
+            //         NextState(state, code) is not an accept state.
+            //
+            SaveStateAndPos(ref ctx);
+            state = next;
+            GetCode();
+
+            while ((next = NextState()) > eofNum)
+            {
+                if (state <= maxAccept && next > maxAccept) // need to update backup data
+                    SaveStateAndPos(ref ctx);
+                state = next;
+                if (state == eofNum) return Result.accept;
+                GetCode(); 
+            }
+            return (state <= maxAccept ? Result.accept : Result.noMatch);
+        }
+
+        void SaveStateAndPos(ref Context ctx)
+        {
             ctx.bPos  = buffer.Pos;
             ctx.rPos  = readPos;
             ctx.cCol  = cCol;
@@ -688,7 +730,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             ctx.cChr  = code;
         }
 
-        void RestoreStateAndPos(ref Context ctx) {
+        void RestoreStateAndPos(ref Context ctx)
+        {
             buffer.Pos = ctx.bPos;
             readPos = ctx.rPos;
             cCol  = ctx.cCol;
@@ -696,7 +739,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             state = ctx.state;
             code  = ctx.cChr;
         }
-#endif  // BACKUP
+
+#endif // BACKUP
 
         // ============= End of the tokenizer code ================
 
@@ -728,16 +772,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         
 #region UserCodeSection
 
-public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
+public override void yyerror(string format, params object[] args) // обработка синтаксических ошибок
 {
   var ww = args.Skip(1).Cast<string>().ToArray();
-  string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
+  string errorMsg = string.Format("({0},{1}): Встречено {2}, а ожидалось {3}", yyline, yycol, args[0], string.Join(" или ", ww));
   throw new SyntaxException(errorMsg);
 }
 
 public void LexError()
 {
-  string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
   throw new LexException(errorMsg);
 }
 
@@ -751,6 +795,18 @@ class ScannerHelper
     keywords.Add("begin",(int)Tokens.BEGIN);
     keywords.Add("end",(int)Tokens.END);
     keywords.Add("cycle",(int)Tokens.CYCLE);
+	keywords.Add("while",(int)Tokens.WHILE);
+	keywords.Add("do",(int)Tokens.DO);
+	keywords.Add("repeat",(int)Tokens.REPEAT);
+	keywords.Add("until",(int)Tokens.UNTIL);
+	keywords.Add("for",(int)Tokens.FOR);
+	keywords.Add("to",(int)Tokens.TO);
+	keywords.Add("write",(int)Tokens.WRITE);
+	keywords.Add("if",(int)Tokens.IF);
+	keywords.Add("then",(int)Tokens.THEN);
+	keywords.Add("else",(int)Tokens.ELSE);
+	keywords.Add("var",(int)Tokens.VAR);
+
   }
   public static int GetIDToken(string s)
   {
@@ -811,7 +867,6 @@ class ScannerHelper
             return new LineBuffer(source);
         }
 
-#if (!NOFILES)
         public static ScanBuff GetBuffer(Stream source)
         {
             return new BuildBuffer(source);
@@ -822,8 +877,7 @@ class ScannerHelper
         {
             return new BuildBuffer(source, fallbackCodePage);
         }
-#endif // !BYTEMODE
-#endif // !NOFILES
+#endif
     }
 
     #region Buffer classes
@@ -946,7 +1000,7 @@ class ScannerHelper
             {
                 ix = lstart = 0;
             }
-            while (ix < numLines)
+            for (; ; )
             {
                 int len = line[ix].Length + 1;
                 if (pos < lstart + len) break;
@@ -1004,8 +1058,7 @@ class ScannerHelper
             {
                 cPos = value;
                 findIndex(cPos, out cLine, out curLineStart);
-                // cLine should be the *next* line after curLine.
-                curLine = (cLine < numLines ? line[cLine++] : "");
+                curLine = line[cLine];
                 curLineEnd = curLineStart + curLine.Length;
             }
         }
@@ -1013,7 +1066,7 @@ class ScannerHelper
         public override string ToString() { return "LineBuffer"; }
     }
 
-#if (!NOFILES)
+
     // ==============================================================
     // =====     class BuildBuff : for unicode text files    ========
     // ==============================================================
@@ -1254,13 +1307,12 @@ class ScannerHelper
         }
 #endif // !BYTEMODE
     }
-#endif // !NOFILES
     #endregion Buffer classes
 
     // ==============================================================
     // ============      class CodePageHandling         =============
     // ==============================================================
-#if (!NOFILES)
+
     public static class CodePageHandling
     {
         public static int GetCodePage(string option)
@@ -1471,7 +1523,6 @@ class ScannerHelper
     
 #endif // !BYTEMODE
 #endregion
-#endif // !NOFILES
 
 // End of code copied from embedded resource
 
diff --git a/Module6/SimpleLex.lex b/Module6/SimpleLex.lex
index 20b364f4bf657ae535567648661456eec4a82d52..ec6e6f5a0d4c9f28490dd1d6da5a3eeb135cc6c4 100644
--- a/Module6/SimpleLex.lex
+++ b/Module6/SimpleLex.lex
@@ -32,6 +32,15 @@ ID {Alpha}{AlphaDigit}*
 
 ":=" { return (int)Tokens.ASSIGN; }
 ";" { return (int)Tokens.SEMICOLON; }
+"(" { return (int)Tokens.LBRACKET; }
+")" { return (int)Tokens.RBRACKET; }
+"," { return (int)Tokens.COMMA; }
+"+" { return (int)Tokens.ADD; }
+"-" { return (int)Tokens.SUB; }
+"/" { return (int)Tokens.DIV; }
+"*" { return (int)Tokens.MUL; }
+
+
 
 [^ \r\n] {
 	LexError();
@@ -66,6 +75,18 @@ class ScannerHelper
     keywords.Add("begin",(int)Tokens.BEGIN);
     keywords.Add("end",(int)Tokens.END);
     keywords.Add("cycle",(int)Tokens.CYCLE);
+	keywords.Add("while",(int)Tokens.WHILE);
+	keywords.Add("do",(int)Tokens.DO);
+	keywords.Add("repeat",(int)Tokens.REPEAT);
+	keywords.Add("until",(int)Tokens.UNTIL);
+	keywords.Add("for",(int)Tokens.FOR);
+	keywords.Add("to",(int)Tokens.TO);
+	keywords.Add("write",(int)Tokens.WRITE);
+	keywords.Add("if",(int)Tokens.IF);
+	keywords.Add("then",(int)Tokens.THEN);
+	keywords.Add("else",(int)Tokens.ELSE);
+	keywords.Add("var",(int)Tokens.VAR);
+
   }
   public static int GetIDToken(string s)
   {
diff --git a/Module6/SimpleYacc.cs b/Module6/SimpleYacc.cs
index b13b1e9abfb58162aa20d280d3fec11345fdc298..be9e5428a85154864d2044b68e7237252f09cfa0 100644
--- a/Module6/SimpleYacc.cs
+++ b/Module6/SimpleYacc.cs
@@ -1,18 +1,17 @@
 // This code was generated by the Gardens Point Parser Generator
-// Copyright (c) Wayne Kelly, John Gough, QUT 2005-2014
+// Copyright (c) Wayne Kelly, QUT 2005-2010
 // (see accompanying GPPGcopyright.rtf)
 
-// GPPG version 1.5.2
-// Machine:  MAINHOMEPC2
-// DateTime: 30.09.2018 18:14:41
-// UserName: someone
-// Input file <SimpleYacc.y - 24.09.2018 23:47:03>
+// GPPG version 1.3.6
+// Machine:  WIN-51KGPO1PTR9
+// DateTime: 29.11.2022 12:28:17
+// UserName: ?????????????
+// Input file <SimpleYacc.y>
 
 // options: no-lines gplex
 
 using System;
 using System.Collections.Generic;
-using System.CodeDom.Compiler;
 using System.Globalization;
 using System.Text;
 using QUT.Gppg;
@@ -20,8 +19,12 @@ using ProgramTree;
 
 namespace SimpleParser
 {
-public enum Tokens {error=2,EOF=3,BEGIN=4,END=5,CYCLE=6,
-    ASSIGN=7,SEMICOLON=8,INUM=9,RNUM=10,ID=11};
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,ASSIGN=6,
+    SEMICOLON=7,WHILE=8,DO=9,REPEAT=10,UNTIL=11,FOR=12,
+    TO=13,WRITE=14,LBRACKET=15,RBRACKET=16,IF=17,THEN=18,
+    ELSE=19,VAR=20,COMMA=21,ADD=22,SUB=23,MUL=24,
+    DIV=25,INUM=26,RNUM=27,ID=28};
 
 public struct ValueType
 { 
@@ -34,81 +37,134 @@ public struct ValueType
 			public BlockNode blVal;
        }
 // Abstract base class for GPLEX scanners
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public abstract class ScanBase : AbstractScanner<ValueType,LexLocation> {
   private LexLocation __yylloc = new LexLocation();
   public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } }
   protected virtual bool yywrap() { return true; }
 }
 
-// Utility class for encapsulating token information
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
-public class ScanObj {
-  public int token;
-  public ValueType yylval;
-  public LexLocation yylloc;
-  public ScanObj( int t, ValueType val, LexLocation loc ) {
-    this.token = t; this.yylval = val; this.yylloc = loc;
-  }
-}
-
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public class Parser: ShiftReduceParser<ValueType, LexLocation>
 {
-  // Verbatim content from SimpleYacc.y - 24.09.2018 23:47:03
-// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
-    public BlockNode root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà 
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
     public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
-  // End verbatim content from SimpleYacc.y - 24.09.2018 23:47:03
+  // End verbatim content from SimpleYacc.y
 
 #pragma warning disable 649
-  private static Dictionary<int, string> aliases;
+  private static Dictionary<int, string> aliasses;
 #pragma warning restore 649
-  private static Rule[] rules = new Rule[14];
-  private static State[] states = new State[22];
+  private static Rule[] rules = new Rule[35];
+  private static State[] states = new State[69];
   private static string[] nonTerms = new string[] {
-      "expr", "ident", "assign", "statement", "cycle", "stlist", "block", "progr", 
-      "$accept", };
+      "expr", "ident", "T", "F", "assign", "statement", "cycle", "while", "repeat", 
+      "for", "write", "if", "var", "stlist", "block", "progr", "$accept", };
 
   static Parser() {
-    states[0] = new State(new int[]{4,4},new int[]{-8,1,-7,3});
-    states[1] = new State(new int[]{3,2});
+    states[0] = new State(new int[]{3,4},new int[]{-16,1,-15,3});
+    states[1] = new State(new int[]{2,2});
     states[2] = new State(-1);
     states[3] = new State(-2);
-    states[4] = new State(new int[]{11,14,4,4,6,18},new int[]{-6,5,-4,21,-3,9,-2,10,-7,16,-5,17});
-    states[5] = new State(new int[]{5,6,8,7});
-    states[6] = new State(-12);
-    states[7] = new State(new int[]{11,14,4,4,6,18},new int[]{-4,8,-3,9,-2,10,-7,16,-5,17});
+    states[4] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-14,5,-6,44,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[5] = new State(new int[]{4,6,7,7});
+    states[6] = new State(-25);
+    states[7] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,8,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
     states[8] = new State(-4);
     states[9] = new State(-5);
-    states[10] = new State(new int[]{7,11});
-    states[11] = new State(new int[]{11,14,9,15},new int[]{-1,12,-2,13});
-    states[12] = new State(-9);
-    states[13] = new State(-10);
-    states[14] = new State(-8);
-    states[15] = new State(-11);
-    states[16] = new State(-6);
-    states[17] = new State(-7);
-    states[18] = new State(new int[]{11,14,9,15},new int[]{-1,19,-2,13});
-    states[19] = new State(new int[]{11,14,4,4,6,18},new int[]{-4,20,-3,9,-2,10,-7,16,-5,17});
-    states[20] = new State(-13);
-    states[21] = new State(-3);
-
-    for (int sNo = 0; sNo < states.Length; sNo++) states[sNo].number = sNo;
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,12,-3,28,-4,27,-2,17});
+    states[12] = new State(new int[]{22,13,23,23,4,-15,7,-15,11,-15,19,-15,13,-15});
+    states[13] = new State(new int[]{28,18,26,19,15,20},new int[]{-3,14,-4,27,-2,17});
+    states[14] = new State(new int[]{24,15,25,25,22,-17,23,-17,4,-17,7,-17,11,-17,19,-17,13,-17,16,-17,28,-17,3,-17,5,-17,8,-17,10,-17,12,-17,14,-17,17,-17,20,-17,9,-17,18,-17});
+    states[15] = new State(new int[]{28,18,26,19,15,20},new int[]{-4,16,-2,17});
+    states[16] = new State(-20);
+    states[17] = new State(-22);
+    states[18] = new State(-14);
+    states[19] = new State(-23);
+    states[20] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,21,-3,28,-4,27,-2,17});
+    states[21] = new State(new int[]{16,22,22,13,23,23});
+    states[22] = new State(-24);
+    states[23] = new State(new int[]{28,18,26,19,15,20},new int[]{-3,24,-4,27,-2,17});
+    states[24] = new State(new int[]{24,15,25,25,22,-18,23,-18,4,-18,7,-18,11,-18,19,-18,13,-18,16,-18,28,-18,3,-18,5,-18,8,-18,10,-18,12,-18,14,-18,17,-18,20,-18,9,-18,18,-18});
+    states[25] = new State(new int[]{28,18,26,19,15,20},new int[]{-4,26,-2,17});
+    states[26] = new State(-21);
+    states[27] = new State(-19);
+    states[28] = new State(new int[]{24,15,25,25,22,-16,23,-16,4,-16,7,-16,11,-16,19,-16,13,-16,16,-16,28,-16,3,-16,5,-16,8,-16,10,-16,12,-16,14,-16,17,-16,20,-16,9,-16,18,-16});
+    states[29] = new State(-6);
+    states[30] = new State(-7);
+    states[31] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,32,-3,28,-4,27,-2,17});
+    states[32] = new State(new int[]{22,13,23,23,28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,33,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[33] = new State(-26);
+    states[34] = new State(-8);
+    states[35] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,36,-3,28,-4,27,-2,17});
+    states[36] = new State(new int[]{9,37,22,13,23,23});
+    states[37] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,38,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[38] = new State(-27);
+    states[39] = new State(-9);
+    states[40] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-14,41,-6,44,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[41] = new State(new int[]{11,42,7,7});
+    states[42] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,43,-3,28,-4,27,-2,17});
+    states[43] = new State(new int[]{22,13,23,23,4,-28,7,-28,11,-28,19,-28});
+    states[44] = new State(-3);
+    states[45] = new State(-10);
+    states[46] = new State(new int[]{28,18},new int[]{-5,47,-2,10});
+    states[47] = new State(new int[]{13,48});
+    states[48] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,49,-3,28,-4,27,-2,17});
+    states[49] = new State(new int[]{9,50,22,13,23,23});
+    states[50] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,51,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[51] = new State(-29);
+    states[52] = new State(-11);
+    states[53] = new State(new int[]{15,54});
+    states[54] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,55,-3,28,-4,27,-2,17});
+    states[55] = new State(new int[]{16,56,22,13,23,23});
+    states[56] = new State(-30);
+    states[57] = new State(-12);
+    states[58] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,59,-3,28,-4,27,-2,17});
+    states[59] = new State(new int[]{18,60,22,13,23,23});
+    states[60] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,61,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[61] = new State(new int[]{19,62,4,-31,7,-31,11,-31});
+    states[62] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,20,67},new int[]{-6,63,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64});
+    states[63] = new State(-32);
+    states[64] = new State(new int[]{21,65,4,-13,7,-13,11,-13,19,-13});
+    states[65] = new State(new int[]{28,18},new int[]{-2,66});
+    states[66] = new State(-34);
+    states[67] = new State(new int[]{28,18},new int[]{-2,68});
+    states[68] = new State(-33);
 
-    rules[1] = new Rule(-9, new int[]{-8,3});
-    rules[2] = new Rule(-8, new int[]{-7});
-    rules[3] = new Rule(-6, new int[]{-4});
-    rules[4] = new Rule(-6, new int[]{-6,8,-4});
-    rules[5] = new Rule(-4, new int[]{-3});
-    rules[6] = new Rule(-4, new int[]{-7});
-    rules[7] = new Rule(-4, new int[]{-5});
-    rules[8] = new Rule(-2, new int[]{11});
-    rules[9] = new Rule(-3, new int[]{-2,7,-1});
-    rules[10] = new Rule(-1, new int[]{-2});
-    rules[11] = new Rule(-1, new int[]{9});
-    rules[12] = new Rule(-7, new int[]{4,-6,5});
-    rules[13] = new Rule(-5, new int[]{6,-1,-4});
+    rules[1] = new Rule(-17, new int[]{-16,2});
+    rules[2] = new Rule(-16, new int[]{-15});
+    rules[3] = new Rule(-14, new int[]{-6});
+    rules[4] = new Rule(-14, new int[]{-14,7,-6});
+    rules[5] = new Rule(-6, new int[]{-5});
+    rules[6] = new Rule(-6, new int[]{-15});
+    rules[7] = new Rule(-6, new int[]{-7});
+    rules[8] = new Rule(-6, new int[]{-8});
+    rules[9] = new Rule(-6, new int[]{-9});
+    rules[10] = new Rule(-6, new int[]{-10});
+    rules[11] = new Rule(-6, new int[]{-11});
+    rules[12] = new Rule(-6, new int[]{-12});
+    rules[13] = new Rule(-6, new int[]{-13});
+    rules[14] = new Rule(-2, new int[]{28});
+    rules[15] = new Rule(-5, new int[]{-2,6,-1});
+    rules[16] = new Rule(-1, new int[]{-3});
+    rules[17] = new Rule(-1, new int[]{-1,22,-3});
+    rules[18] = new Rule(-1, new int[]{-1,23,-3});
+    rules[19] = new Rule(-3, new int[]{-4});
+    rules[20] = new Rule(-3, new int[]{-3,24,-4});
+    rules[21] = new Rule(-3, new int[]{-3,25,-4});
+    rules[22] = new Rule(-4, new int[]{-2});
+    rules[23] = new Rule(-4, new int[]{26});
+    rules[24] = new Rule(-4, new int[]{15,-1,16});
+    rules[25] = new Rule(-15, new int[]{3,-14,4});
+    rules[26] = new Rule(-7, new int[]{5,-1,-6});
+    rules[27] = new Rule(-8, new int[]{8,-1,9,-6});
+    rules[28] = new Rule(-9, new int[]{10,-14,11,-1});
+    rules[29] = new Rule(-10, new int[]{12,-5,13,-1,9,-6});
+    rules[30] = new Rule(-11, new int[]{14,15,-1,16});
+    rules[31] = new Rule(-12, new int[]{17,-1,18,-6});
+    rules[32] = new Rule(-12, new int[]{17,-1,18,-6,19,-6});
+    rules[33] = new Rule(-13, new int[]{20,-2});
+    rules[34] = new Rule(-13, new int[]{-13,21,-2});
   }
 
   protected override void Initialize() {
@@ -120,7 +176,6 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
 
   protected override void DoAction(int action)
   {
-#pragma warning disable 162, 1522
     switch (action)
     {
       case 2: // progr -> block
@@ -146,32 +201,91 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
       case 7: // statement -> cycle
 { CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
         break;
-      case 8: // ident -> ID
+      case 8: // statement -> while
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 9: // statement -> repeat
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 10: // statement -> for
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 11: // statement -> write
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 12: // statement -> if
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 13: // statement -> var
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 14: // ident -> ID
 { CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); }
         break;
-      case 9: // assign -> ident, ASSIGN, expr
+      case 15: // assign -> ident, ASSIGN, expr
 { CurrentSemanticValue.stVal = new AssignNode(ValueStack[ValueStack.Depth-3].eVal as IdNode, ValueStack[ValueStack.Depth-1].eVal); }
         break;
-      case 10: // expr -> ident
+      case 17: // expr -> expr, ADD, T
+{CurrentSemanticValue.eVal = new BinNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,BinOpType.ADD);}
+        break;
+      case 18: // expr -> expr, SUB, T
+{CurrentSemanticValue.eVal = new BinNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,BinOpType.SUB);}
+        break;
+      case 20: // T -> T, MUL, F
+{CurrentSemanticValue.eVal = new BinNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,BinOpType.MUL);}
+        break;
+      case 21: // T -> T, DIV, F
+{CurrentSemanticValue.eVal = new BinNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,BinOpType.DIV);}
+        break;
+      case 22: // F -> ident
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
         break;
-      case 11: // expr -> INUM
+      case 23: // F -> INUM
 { CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
         break;
-      case 12: // block -> BEGIN, stlist, END
+      case 24: // F -> LBRACKET, expr, RBRACKET
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; }
+        break;
+      case 25: // block -> BEGIN, stlist, END
 { CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
         break;
-      case 13: // cycle -> CYCLE, expr, statement
+      case 26: // cycle -> CYCLE, expr, statement
 { CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal, ValueStack[ValueStack.Depth-1].stVal); }
         break;
+      case 27: // while -> WHILE, expr, DO, statement
+{ CurrentSemanticValue.stVal  = new WhileNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal);}
+        break;
+      case 28: // repeat -> REPEAT, stlist, UNTIL, expr
+{ CurrentSemanticValue.stVal = new RepeatNode(ValueStack[ValueStack.Depth-3].blVal, ValueStack[ValueStack.Depth-1].eVal);}
+        break;
+      case 29: // for -> FOR, assign, TO, expr, DO, statement
+{ CurrentSemanticValue.stVal = new ForNode(ValueStack[ValueStack.Depth-5].stVal as AssignNode, ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 30: // write -> WRITE, LBRACKET, expr, RBRACKET
+{ CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal);}
+        break;
+      case 31: // if -> IF, expr, THEN, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal);}
+        break;
+      case 32: // if -> IF, expr, THEN, statement, ELSE, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-5].eVal, ValueStack[ValueStack.Depth-3].stVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 33: // var -> VAR, ident
+{ CurrentSemanticValue.stVal = new VarNode(ValueStack[ValueStack.Depth-1].eVal as IdNode);}
+        break;
+      case 34: // var -> var, COMMA, ident
+{ 
+				(ValueStack[ValueStack.Depth-3].stVal as VarNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); 
+				CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; 
+			}
+        break;
     }
-#pragma warning restore 162, 1522
   }
 
   protected override string TerminalToString(int terminal)
   {
-    if (aliases != null && aliases.ContainsKey(terminal))
-        return aliases[terminal];
+    if (aliasses != null && aliasses.ContainsKey(terminal))
+        return aliasses[terminal];
     else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture))
         return ((Tokens)terminal).ToString();
     else
diff --git a/Module6/SimpleYacc.y b/Module6/SimpleYacc.y
index b9899b4c1edf1a54720d7dac60d5962c0e8a8c0e..c8c22f064a10b65c764ece9a920f1a49b1182fda 100644
--- a/Module6/SimpleYacc.y
+++ b/Module6/SimpleYacc.y
@@ -20,13 +20,13 @@
 
 %namespace SimpleParser
 
-%token BEGIN END CYCLE ASSIGN SEMICOLON
+%token BEGIN END CYCLE ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE LBRACKET RBRACKET IF THEN ELSE VAR COMMA ADD SUB MUL DIV
 %token <iVal> INUM 
 %token <dVal> RNUM 
 %token <sVal> ID
 
-%type <eVal> expr ident 
-%type <stVal> assign statement cycle 
+%type <eVal> expr ident T F
+%type <stVal> assign statement cycle while repeat for write if var
 %type <blVal> stlist block
 
 %%
@@ -48,6 +48,12 @@ stlist	: statement
 statement: assign { $$ = $1; }
 		| block   { $$ = $1; }
 		| cycle   { $$ = $1; }
+		| while	  { $$ = $1; }
+		| repeat  { $$ = $1; }
+		| for  { $$ = $1; }
+		| write   { $$ = $1; }
+		| if	  { $$ = $1; }
+		| var     { $$ = $1; }
 	;
 
 ident 	: ID { $$ = new IdNode($1); }	
@@ -56,15 +62,53 @@ ident 	: ID { $$ = new IdNode($1); }
 assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
 		;
 
-expr	: ident  { $$ = $1 as IdNode; }
+expr	: T
+		| expr ADD T {$$ = new BinNode($1,$3,BinOpType.ADD);}
+		| expr SUB T {$$ = new BinNode($1,$3,BinOpType.SUB);}
+		;
+
+T		: F
+		| T MUL F {$$ = new BinNode($1,$3,BinOpType.MUL);}
+		| T DIV F {$$ = new BinNode($1,$3,BinOpType.DIV);}
+		;
+
+F		: ident  { $$ = $1 as IdNode; }
 		| INUM { $$ = new IntNumNode($1); }
+		| LBRACKET expr RBRACKET { $$ = $2; }
 		;
 
+     
+
+
 block	: BEGIN stlist END { $$ = $2; }
 		;
 
 cycle	: CYCLE expr statement { $$ = new CycleNode($2, $3); }
 		;
-	
+
+while	: WHILE expr DO statement{ $$  = new WhileNode($2, $4);}
+		;
+
+repeat	: REPEAT stlist UNTIL expr { $$ = new RepeatNode($2, $4);}
+		;
+
+for		: FOR assign TO expr DO statement { $$ = new ForNode($2 as AssignNode, $4, $6); }
+		;
+
+write	: WRITE LBRACKET expr RBRACKET { $$ = new WriteNode($3);}
+		;
+
+if		: IF expr THEN statement { $$ = new IfNode($2, $4);}
+		| IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); }
+		;
+
+var		: VAR ident { $$ = new VarNode($2 as IdNode);}
+		| var COMMA ident 
+			{ 
+				($1 as VarNode).Add($3 as IdNode); 
+				$$ = $1; 
+			}
+		;
+
 %%
 
diff --git a/Module6/generateParserScanner.bat b/Module6/generateParserScanner.bat
index 7ca5476d806c30e141372064805b2aaef2c5ce91..06c5897913890b9834610fa8316dc2513492b5cd 100644
--- a/Module6/generateParserScanner.bat
+++ b/Module6/generateParserScanner.bat
@@ -1,3 +1,4 @@
 cls
 gplex.exe /unicode SimpleLex.lex
 gppg.exe /no-lines /gplex SimpleYacc.y
+pause
diff --git a/Module6/packages.config b/Module6/packages.config
index 7a0d545fef78dffb45e66ad6c4bf9598a681c3bf..cad472ab4a4c7db4015b20d3c5b92b589e689b30 100644
--- a/Module6/packages.config
+++ b/Module6/packages.config
@@ -1,4 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net35-client" />
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
 </packages>
\ No newline at end of file
diff --git a/Module7/ParserVistors.csproj b/Module7/ParserVistors.csproj
index 21e6a21eb29fc16fe29ad72054c273d6810bff6f..e9c89366d33df926e80363c6b922c3a00490ba75 100644
--- a/Module7/ParserVistors.csproj
+++ b/Module7/ParserVistors.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -14,6 +16,8 @@
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <PlatformTarget>x86</PlatformTarget>
@@ -60,6 +64,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -93,8 +100,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module7/ProgramTree.cs b/Module7/ProgramTree.cs
index e48dcb56fcb811d4b2e7f37bbf71e935306aedc6..f2a07d3ddffae6efe08107d510a9e331f7c23502 100644
--- a/Module7/ProgramTree.cs
+++ b/Module7/ProgramTree.cs
@@ -142,4 +142,32 @@ namespace ProgramTree
             v.VisitVarDefNode(this);
         }
     }
+
+    public class IfNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+
+        public StatementNode ThenStat { get; set; }
+
+        public StatementNode ElseStat { get; set; }
+
+        // полная форма
+        public IfNode(ExprNode expr, StatementNode thenNode, StatementNode elseNode)
+        {
+            Expr = expr;
+            ThenStat = thenNode;
+            ElseStat = elseNode;
+        }
+
+        // неполная форма
+        public IfNode(ExprNode expr, StatementNode thenNode) : this(expr, thenNode, null)
+        {
+        }
+
+        public override void Visit(Visitor v)
+        {
+            v.VisitIfNode(this);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/Module7/SimpleLex.cs b/Module7/SimpleLex.cs
index 98388ef125489f1e1cc850a1341825c4971cf640..640275d584e20d9cc8e0bfd2317320b7262ffb46 100644
--- a/Module7/SimpleLex.cs
+++ b/Module7/SimpleLex.cs
@@ -1,14 +1,10 @@
 //
 //  This CSharp output file generated by Gardens Point LEX
-//  Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
-//  Output produced by GPLEX is the property of the user.
-//  See accompanying file GPLEXcopyright.rtf.
-//
-//  GPLEX Version:  1.2.2
-//  Machine:  MAINHOMEPC2
-//  DateTime: 30.09.2018 18:17:27
-//  UserName: someone
-//  GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:03>
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 04.12.2022 15:32:10
+//  UserName: ?????????????
+//  GPLEX input file <SimpleLex.lex>
 //  GPLEX frame file <embedded resource>
 //
 //  Option settings: unicode, parser, minimize
@@ -17,8 +13,8 @@
 //
 
 //
-// Revised backup code
-// Version 1.2.1 of 24-June-2013
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
 //
 //
 #define BACKUP
@@ -305,7 +301,8 @@ int NextState() {
 
         public Scanner(Stream file, string codepage) {
             SetSource(file, CodePageHandling.GetCodePage(codepage));
-        }   
+        }
+        
 #endif // !NOFILES
 
      public Scanner() { }
@@ -333,7 +330,7 @@ int NextState() {
                     if (next < 0xDC00 || next > 0xDFFF)
                         code = ScanBuff.UnicodeReplacementChar;
                     else
-                        code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
                 }
 #endif
                 cCol++;
@@ -386,7 +383,9 @@ int NextState() {
             GetCode();
         }
 
+#if !NOFILES        
         // ================ LineBuffer Initialization ===================
+
         /// <summary>
         /// Create and initialize a LineBuff buffer object for this scanner
         /// </summary>
@@ -400,7 +399,6 @@ int NextState() {
             GetCode();
         }
 
-#if !NOFILES        
         // =============== StreamBuffer Initialization ==================
 
         /// <summary>
@@ -502,12 +500,6 @@ int NextState() {
             }
         }
 
-        /// <summary>
-        /// Discards all but the first "n" codepoints in the recognized pattern.
-        /// Resets the buffer position so that only n codepoints have been consumed;
-        /// yytext is also re-evaluated. 
-        /// </summary>
-        /// <param name="n">The number of codepoints to consume</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void yyless(int n)
         {
@@ -527,10 +519,6 @@ int NextState() {
         //  but it does not seem possible to re-establish
         //  the correct column counts except by going forward.
         //
-        /// <summary>
-        /// Removes the last "n" code points from the pattern.
-        /// </summary>
-        /// <param name="n">The number to remove</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void _yytrunc(int n) { yyless(yyleng - n); }
         
@@ -543,23 +531,18 @@ int NextState() {
         // can't use (tokEPos - tokPos) because of the
         // possibility of surrogate pairs in the token.
         //
-        /// <summary>
-        /// The length of the pattern in codepoints (not the same as 
-        /// string-length if the pattern contains any surrogate pairs).
-        /// </summary>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
         public int yyleng
         {
             get {
+#if BYTEMODE
+                return tokEPos - tokPos;
+#else   
                 if (tokELin == tokLin)
                     return tokECol - tokCol;
-                else
-#if BYTEMODE
-                    return tokEPos - tokPos;
-#else
-                {
+                else {
                     int ch;
                     int count = 0;
                     int save = buffer.Pos;
@@ -568,7 +551,7 @@ int NextState() {
                         ch = buffer.Read();
                         if (!char.IsHighSurrogate((char)ch)) count++;
                     } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
-                    buffer.Pos = save;
+                    buffer.Pos = save; 
                     return count;
                 }
 #endif // BYTEMODE
@@ -593,56 +576,65 @@ int NextState() {
 
         // ============== The main tokenizer code =================
 
-        int Scan() {
+        int Scan()
+        {
             try {
-                for (; ; ) {
-                    int next;              // next state to enter
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
 #if LEFTANCHORS
-                    for (;;) {
+                    for (;;)
+                    {
                         // Discard characters that do not start any pattern.
                         // Must check the left anchor condition after *every* GetCode!
                         state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
-                        if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
+                        if ((next = NextState()) != goStart) 
+                            break; // LOOP EXIT HERE...
                         GetCode();
                     }
                     
 #else // !LEFTANCHORS
                     state = currentStart;
-                    while ((next = NextState()) == goStart) {
+                    while ((next = NextState()) == goStart)
                         // At this point, the current character has no
                         // transition from the current state.  We discard 
                         // the "no-match" char.   In traditional LEX such 
                         // characters are echoed to the console.
                         GetCode();
-                    }
 #endif // LEFTANCHORS                    
                     // At last, a valid transition ...    
                     MarkToken();
                     state = next;
-                    GetCode();                    
+                    GetCode();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
 #if BACKUP
-                    bool contextSaved = false;
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                        if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
-                            // Store data for the *latest* accept state that was found.
-                            SaveStateAndPos( ref ctx );
-                            contextSaved = true;
+                        if (state <= maxAccept && next > maxAccept) // need to prepare backup data
+                        {
+                            // ctx is an object. The fields may be 
+                            // mutated by the call to Recurse2.
+                            // On return the data in ctx is the
+                            // *latest* accept state that was found.
+                            
+                            rslt = Recurse2(ref ctx, next);
+                            if (rslt == Result.noMatch) 
+                                RestoreStateAndPos(ref ctx);
+                            break;
                         }
-                        state = next;
-                        GetCode();
-                    }
-                    if (state > maxAccept && contextSaved)
-                        RestoreStateAndPos( ref ctx );
-#else  // BACKUP
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                         state = next;
-                         GetCode();
-                    }
+                        else
 #endif // BACKUP
-                    if (state <= maxAccept) {
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
                         MarkEnd();
 #region ActionSwitch
-#pragma warning disable 162, 1522
+#pragma warning disable 162
     switch (state)
     {
         case eofNum:
@@ -706,7 +698,7 @@ yylval.dVal = double.Parse(yytext);
         default:
             break;
     }
-#pragma warning restore 162, 1522
+#pragma warning restore 162
 #endregion
                     }
                 }
@@ -719,7 +711,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         }
 
 #if BACKUP
-        void SaveStateAndPos(ref Context ctx) {
+        Result Recurse2(ref Context ctx, int next)
+        {
+            // Assert: at entry "state" is an accept state AND
+            //         NextState(state, code) != goStart AND
+            //         NextState(state, code) is not an accept state.
+            //
+            SaveStateAndPos(ref ctx);
+            state = next;
+            GetCode();
+
+            while ((next = NextState()) > eofNum)
+            {
+                if (state <= maxAccept && next > maxAccept) // need to update backup data
+                    SaveStateAndPos(ref ctx);
+                state = next;
+                if (state == eofNum) return Result.accept;
+                GetCode(); 
+            }
+            return (state <= maxAccept ? Result.accept : Result.noMatch);
+        }
+
+        void SaveStateAndPos(ref Context ctx)
+        {
             ctx.bPos  = buffer.Pos;
             ctx.rPos  = readPos;
             ctx.cCol  = cCol;
@@ -728,7 +742,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             ctx.cChr  = code;
         }
 
-        void RestoreStateAndPos(ref Context ctx) {
+        void RestoreStateAndPos(ref Context ctx)
+        {
             buffer.Pos = ctx.bPos;
             readPos = ctx.rPos;
             cCol  = ctx.cCol;
@@ -736,7 +751,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             state = ctx.state;
             code  = ctx.cChr;
         }
-#endif  // BACKUP
+
+#endif // BACKUP
 
         // ============= End of the tokenizer code ================
 
@@ -768,16 +784,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         
 #region UserCodeSection
 
-public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
+public override void yyerror(string format, params object[] args) // обработка синтаксических ошибок
 {
   var ww = args.Skip(1).Cast<string>().ToArray();
-  string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
+  string errorMsg = string.Format("({0},{1}): Встречено {2}, а ожидалось {3}", yyline, yycol, args[0], string.Join(" или ", ww));
   throw new SyntaxException(errorMsg);
 }
 
 public void LexError()
 {
-  string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
   throw new LexException(errorMsg);
 }
 
@@ -793,6 +809,10 @@ class ScannerHelper
     keywords.Add("cycle",(int)Tokens.CYCLE);
     keywords.Add("write",(int)Tokens.WRITE);
     keywords.Add("var",(int)Tokens.VAR);
+    keywords.Add("if",(int)Tokens.IF);
+    keywords.Add("then",(int)Tokens.THEN);
+    keywords.Add("else",(int)Tokens.ELSE);
+
   }
   public static int GetIDToken(string s)
   {
@@ -853,7 +873,6 @@ class ScannerHelper
             return new LineBuffer(source);
         }
 
-#if (!NOFILES)
         public static ScanBuff GetBuffer(Stream source)
         {
             return new BuildBuffer(source);
@@ -864,8 +883,7 @@ class ScannerHelper
         {
             return new BuildBuffer(source, fallbackCodePage);
         }
-#endif // !BYTEMODE
-#endif // !NOFILES
+#endif
     }
 
     #region Buffer classes
@@ -988,7 +1006,7 @@ class ScannerHelper
             {
                 ix = lstart = 0;
             }
-            while (ix < numLines)
+            for (; ; )
             {
                 int len = line[ix].Length + 1;
                 if (pos < lstart + len) break;
@@ -1046,8 +1064,7 @@ class ScannerHelper
             {
                 cPos = value;
                 findIndex(cPos, out cLine, out curLineStart);
-                // cLine should be the *next* line after curLine.
-                curLine = (cLine < numLines ? line[cLine++] : "");
+                curLine = line[cLine];
                 curLineEnd = curLineStart + curLine.Length;
             }
         }
@@ -1055,7 +1072,7 @@ class ScannerHelper
         public override string ToString() { return "LineBuffer"; }
     }
 
-#if (!NOFILES)
+
     // ==============================================================
     // =====     class BuildBuff : for unicode text files    ========
     // ==============================================================
@@ -1296,13 +1313,12 @@ class ScannerHelper
         }
 #endif // !BYTEMODE
     }
-#endif // !NOFILES
     #endregion Buffer classes
 
     // ==============================================================
     // ============      class CodePageHandling         =============
     // ==============================================================
-#if (!NOFILES)
+
     public static class CodePageHandling
     {
         public static int GetCodePage(string option)
@@ -1513,7 +1529,6 @@ class ScannerHelper
     
 #endif // !BYTEMODE
 #endregion
-#endif // !NOFILES
 
 // End of code copied from embedded resource
 
diff --git a/Module7/SimpleLex.lex b/Module7/SimpleLex.lex
index 00dfa1249dd0572b3061e40d49d86058b4e1baee..c0e8f5a4d7459f1bcadc66d3c113140b2edd8e57 100644
--- a/Module7/SimpleLex.lex
+++ b/Module7/SimpleLex.lex
@@ -78,6 +78,10 @@ class ScannerHelper
     keywords.Add("cycle",(int)Tokens.CYCLE);
     keywords.Add("write",(int)Tokens.WRITE);
     keywords.Add("var",(int)Tokens.VAR);
+    keywords.Add("if",(int)Tokens.IF);
+    keywords.Add("then",(int)Tokens.THEN);
+    keywords.Add("else",(int)Tokens.ELSE);
+
   }
   public static int GetIDToken(string s)
   {
diff --git a/Module7/SimpleYacc.cs b/Module7/SimpleYacc.cs
index e0ec2ad6ff794b912c8c7509d7cc14a3103253c0..844a50c92e2b6d06e70437a1d5829815853aadd5 100644
--- a/Module7/SimpleYacc.cs
+++ b/Module7/SimpleYacc.cs
@@ -1,18 +1,17 @@
 // This code was generated by the Gardens Point Parser Generator
-// Copyright (c) Wayne Kelly, John Gough, QUT 2005-2014
+// Copyright (c) Wayne Kelly, QUT 2005-2010
 // (see accompanying GPPGcopyright.rtf)
 
-// GPPG version 1.5.2
-// Machine:  MAINHOMEPC2
-// DateTime: 30.09.2018 18:17:29
-// UserName: someone
-// Input file <SimpleYacc.y - 24.09.2018 23:47:03>
+// GPPG version 1.3.6
+// Machine:  WIN-51KGPO1PTR9
+// DateTime: 04.12.2022 15:32:11
+// UserName: ?????????????
+// Input file <SimpleYacc.y>
 
 // options: no-lines gplex
 
 using System;
 using System.Collections.Generic;
-using System.CodeDom.Compiler;
 using System.Globalization;
 using System.Text;
 using QUT.Gppg;
@@ -21,10 +20,12 @@ using ProgramTree;
 
 namespace SimpleParser
 {
-public enum Tokens {error=2,EOF=3,BEGIN=4,END=5,CYCLE=6,
-    ASSIGN=7,ASSIGNPLUS=8,ASSIGNMINUS=9,ASSIGNMULT=10,SEMICOLON=11,WRITE=12,
-    VAR=13,PLUS=14,MINUS=15,MULT=16,DIV=17,LPAREN=18,
-    RPAREN=19,COLUMN=20,INUM=21,RNUM=22,ID=23};
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,ASSIGN=6,
+    ASSIGNPLUS=7,ASSIGNMINUS=8,ASSIGNMULT=9,SEMICOLON=10,WRITE=11,VAR=12,
+    PLUS=13,MINUS=14,MULT=15,DIV=16,LPAREN=17,RPAREN=18,
+    COLUMN=19,IF=20,THEN=21,ELSE=22,INUM=23,RNUM=24,
+    ID=25};
 
 public struct ValueType
 { 
@@ -37,124 +38,120 @@ public struct ValueType
 			public BlockNode blVal;
        }
 // Abstract base class for GPLEX scanners
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public abstract class ScanBase : AbstractScanner<ValueType,LexLocation> {
   private LexLocation __yylloc = new LexLocation();
   public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } }
   protected virtual bool yywrap() { return true; }
 }
 
-// Utility class for encapsulating token information
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
-public class ScanObj {
-  public int token;
-  public ValueType yylval;
-  public LexLocation yylloc;
-  public ScanObj( int t, ValueType val, LexLocation loc ) {
-    this.token = t; this.yylval = val; this.yylloc = loc;
-  }
-}
-
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public class Parser: ShiftReduceParser<ValueType, LexLocation>
 {
-  // Verbatim content from SimpleYacc.y - 24.09.2018 23:47:03
-// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
-    public BlockNode root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà 
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
     public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
 	private bool InDefSect = false;
-  // End verbatim content from SimpleYacc.y - 24.09.2018 23:47:03
+  // End verbatim content from SimpleYacc.y
 
 #pragma warning disable 649
-  private static Dictionary<int, string> aliases;
+  private static Dictionary<int, string> aliasses;
 #pragma warning restore 649
-  private static Rule[] rules = new Rule[30];
-  private static State[] states = new State[48];
+  private static Rule[] rules = new Rule[33];
+  private static State[] states = new State[55];
   private static string[] nonTerms = new string[] {
       "progr", "expr", "ident", "T", "F", "statement", "assign", "block", "cycle", 
-      "write", "empty", "var", "varlist", "stlist", "$accept", "Anon@1", };
+      "write", "empty", "var", "varlist", "if", "stlist", "$accept", "Anon@1", 
+      };
 
   static Parser() {
-    states[0] = new State(new int[]{4,4},new int[]{-1,1,-8,3});
-    states[1] = new State(new int[]{3,2});
+    states[0] = new State(new int[]{3,4},new int[]{-1,1,-8,3});
+    states[1] = new State(new int[]{2,2});
     states[2] = new State(-1);
     states[3] = new State(-2);
-    states[4] = new State(new int[]{23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-14,5,-6,47,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
-    states[5] = new State(new int[]{5,6,11,7});
-    states[6] = new State(-23);
-    states[7] = new State(new int[]{23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-6,8,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
+    states[4] = new State(new int[]{25,18,3,4,5,31,11,35,12,40,20,48,4,-12,10,-12},new int[]{-15,5,-6,54,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46,-14,47});
+    states[5] = new State(new int[]{4,6,10,7});
+    states[6] = new State(-24);
+    states[7] = new State(new int[]{25,18,3,4,5,31,11,35,12,40,20,48,4,-12,10,-12},new int[]{-6,8,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46,-14,47});
     states[8] = new State(-4);
     states[9] = new State(-5);
-    states[10] = new State(new int[]{7,11});
-    states[11] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,12,-4,28,-5,27,-3,17});
-    states[12] = new State(new int[]{14,13,15,23,5,-13,11,-13});
-    states[13] = new State(new int[]{23,18,21,19,18,20},new int[]{-4,14,-5,27,-3,17});
-    states[14] = new State(new int[]{16,15,17,25,14,-14,15,-14,5,-14,11,-14,19,-14,23,-14,4,-14,6,-14,12,-14,13,-14});
-    states[15] = new State(new int[]{23,18,21,19,18,20},new int[]{-5,16,-3,17});
-    states[16] = new State(-17);
-    states[17] = new State(-20);
-    states[18] = new State(-12);
-    states[19] = new State(-21);
-    states[20] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,21,-4,28,-5,27,-3,17});
-    states[21] = new State(new int[]{19,22,14,13,15,23});
-    states[22] = new State(-22);
-    states[23] = new State(new int[]{23,18,21,19,18,20},new int[]{-4,24,-5,27,-3,17});
-    states[24] = new State(new int[]{16,15,17,25,14,-15,15,-15,5,-15,11,-15,19,-15,23,-15,4,-15,6,-15,12,-15,13,-15});
-    states[25] = new State(new int[]{23,18,21,19,18,20},new int[]{-5,26,-3,17});
-    states[26] = new State(-18);
-    states[27] = new State(-19);
-    states[28] = new State(new int[]{16,15,17,25,14,-16,15,-16,5,-16,11,-16,19,-16,23,-16,4,-16,6,-16,12,-16,13,-16});
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{25,18,23,19,17,20},new int[]{-2,12,-4,28,-5,27,-3,17});
+    states[12] = new State(new int[]{13,13,14,23,4,-14,10,-14,22,-14});
+    states[13] = new State(new int[]{25,18,23,19,17,20},new int[]{-4,14,-5,27,-3,17});
+    states[14] = new State(new int[]{15,15,16,25,13,-15,14,-15,4,-15,10,-15,22,-15,18,-15,25,-15,3,-15,5,-15,11,-15,12,-15,20,-15,21,-15});
+    states[15] = new State(new int[]{25,18,23,19,17,20},new int[]{-5,16,-3,17});
+    states[16] = new State(-18);
+    states[17] = new State(-21);
+    states[18] = new State(-13);
+    states[19] = new State(-22);
+    states[20] = new State(new int[]{25,18,23,19,17,20},new int[]{-2,21,-4,28,-5,27,-3,17});
+    states[21] = new State(new int[]{18,22,13,13,14,23});
+    states[22] = new State(-23);
+    states[23] = new State(new int[]{25,18,23,19,17,20},new int[]{-4,24,-5,27,-3,17});
+    states[24] = new State(new int[]{15,15,16,25,13,-16,14,-16,4,-16,10,-16,22,-16,18,-16,25,-16,3,-16,5,-16,11,-16,12,-16,20,-16,21,-16});
+    states[25] = new State(new int[]{25,18,23,19,17,20},new int[]{-5,26,-3,17});
+    states[26] = new State(-19);
+    states[27] = new State(-20);
+    states[28] = new State(new int[]{15,15,16,25,13,-17,14,-17,4,-17,10,-17,22,-17,18,-17,25,-17,3,-17,5,-17,11,-17,12,-17,20,-17,21,-17});
     states[29] = new State(-6);
     states[30] = new State(-7);
-    states[31] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,32,-4,28,-5,27,-3,17});
-    states[32] = new State(new int[]{14,13,15,23,23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-6,33,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
-    states[33] = new State(-24);
+    states[31] = new State(new int[]{25,18,23,19,17,20},new int[]{-2,32,-4,28,-5,27,-3,17});
+    states[32] = new State(new int[]{13,13,14,23,25,18,3,4,5,31,11,35,12,40,20,48,4,-12,10,-12,22,-12},new int[]{-6,33,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46,-14,47});
+    states[33] = new State(-25);
     states[34] = new State(-8);
-    states[35] = new State(new int[]{18,36});
-    states[36] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,37,-4,28,-5,27,-3,17});
-    states[37] = new State(new int[]{19,38,14,13,15,23});
-    states[38] = new State(-25);
+    states[35] = new State(new int[]{17,36});
+    states[36] = new State(new int[]{25,18,23,19,17,20},new int[]{-2,37,-4,28,-5,27,-3,17});
+    states[37] = new State(new int[]{18,38,13,13,14,23});
+    states[38] = new State(-26);
     states[39] = new State(-9);
-    states[40] = new State(-26,new int[]{-16,41});
-    states[41] = new State(new int[]{23,18},new int[]{-13,42,-3,45});
-    states[42] = new State(new int[]{20,43,5,-27,11,-27});
-    states[43] = new State(new int[]{23,18},new int[]{-3,44});
-    states[44] = new State(-29);
-    states[45] = new State(-28);
+    states[40] = new State(-27,new int[]{-17,41});
+    states[41] = new State(new int[]{25,18},new int[]{-13,42,-3,45});
+    states[42] = new State(new int[]{19,43,4,-28,10,-28,22,-28});
+    states[43] = new State(new int[]{25,18},new int[]{-3,44});
+    states[44] = new State(-30);
+    states[45] = new State(-29);
     states[46] = new State(-10);
-    states[47] = new State(-3);
-
-    for (int sNo = 0; sNo < states.Length; sNo++) states[sNo].number = sNo;
+    states[47] = new State(-11);
+    states[48] = new State(new int[]{25,18,23,19,17,20},new int[]{-2,49,-4,28,-5,27,-3,17});
+    states[49] = new State(new int[]{21,50,13,13,14,23});
+    states[50] = new State(new int[]{25,18,3,4,5,31,11,35,12,40,20,48,4,-12,10,-12,22,-12},new int[]{-6,51,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46,-14,47});
+    states[51] = new State(new int[]{22,52,4,-31,10,-31});
+    states[52] = new State(new int[]{25,18,3,4,5,31,11,35,12,40,20,48,4,-12,10,-12,22,-12},new int[]{-6,53,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46,-14,47});
+    states[53] = new State(-32);
+    states[54] = new State(-3);
 
-    rules[1] = new Rule(-15, new int[]{-1,3});
+    rules[1] = new Rule(-16, new int[]{-1,2});
     rules[2] = new Rule(-1, new int[]{-8});
-    rules[3] = new Rule(-14, new int[]{-6});
-    rules[4] = new Rule(-14, new int[]{-14,11,-6});
+    rules[3] = new Rule(-15, new int[]{-6});
+    rules[4] = new Rule(-15, new int[]{-15,10,-6});
     rules[5] = new Rule(-6, new int[]{-7});
     rules[6] = new Rule(-6, new int[]{-8});
     rules[7] = new Rule(-6, new int[]{-9});
     rules[8] = new Rule(-6, new int[]{-10});
     rules[9] = new Rule(-6, new int[]{-12});
     rules[10] = new Rule(-6, new int[]{-11});
-    rules[11] = new Rule(-11, new int[]{});
-    rules[12] = new Rule(-3, new int[]{23});
-    rules[13] = new Rule(-7, new int[]{-3,7,-2});
-    rules[14] = new Rule(-2, new int[]{-2,14,-4});
-    rules[15] = new Rule(-2, new int[]{-2,15,-4});
-    rules[16] = new Rule(-2, new int[]{-4});
-    rules[17] = new Rule(-4, new int[]{-4,16,-5});
-    rules[18] = new Rule(-4, new int[]{-4,17,-5});
-    rules[19] = new Rule(-4, new int[]{-5});
-    rules[20] = new Rule(-5, new int[]{-3});
-    rules[21] = new Rule(-5, new int[]{21});
-    rules[22] = new Rule(-5, new int[]{18,-2,19});
-    rules[23] = new Rule(-8, new int[]{4,-14,5});
-    rules[24] = new Rule(-9, new int[]{6,-2,-6});
-    rules[25] = new Rule(-10, new int[]{12,18,-2,19});
-    rules[26] = new Rule(-16, new int[]{});
-    rules[27] = new Rule(-12, new int[]{13,-16,-13});
-    rules[28] = new Rule(-13, new int[]{-3});
-    rules[29] = new Rule(-13, new int[]{-13,20,-3});
+    rules[11] = new Rule(-6, new int[]{-14});
+    rules[12] = new Rule(-11, new int[]{});
+    rules[13] = new Rule(-3, new int[]{25});
+    rules[14] = new Rule(-7, new int[]{-3,6,-2});
+    rules[15] = new Rule(-2, new int[]{-2,13,-4});
+    rules[16] = new Rule(-2, new int[]{-2,14,-4});
+    rules[17] = new Rule(-2, new int[]{-4});
+    rules[18] = new Rule(-4, new int[]{-4,15,-5});
+    rules[19] = new Rule(-4, new int[]{-4,16,-5});
+    rules[20] = new Rule(-4, new int[]{-5});
+    rules[21] = new Rule(-5, new int[]{-3});
+    rules[22] = new Rule(-5, new int[]{23});
+    rules[23] = new Rule(-5, new int[]{17,-2,18});
+    rules[24] = new Rule(-8, new int[]{3,-15,4});
+    rules[25] = new Rule(-9, new int[]{5,-2,-6});
+    rules[26] = new Rule(-10, new int[]{11,17,-2,18});
+    rules[27] = new Rule(-17, new int[]{});
+    rules[28] = new Rule(-12, new int[]{12,-17,-13});
+    rules[29] = new Rule(-13, new int[]{-3});
+    rules[30] = new Rule(-13, new int[]{-13,19,-3});
+    rules[31] = new Rule(-14, new int[]{20,-2,21,-6});
+    rules[32] = new Rule(-14, new int[]{20,-2,21,-6,22,-6});
   }
 
   protected override void Initialize() {
@@ -166,7 +163,6 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
 
   protected override void DoAction(int action)
   {
-#pragma warning disable 162, 1522
     switch (action)
     {
       case 2: // progr -> block
@@ -201,85 +197,93 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
       case 10: // statement -> empty
 { CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
         break;
-      case 11: // empty -> /* empty */
+      case 11: // statement -> if
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 12: // empty -> /* empty */
 { CurrentSemanticValue.stVal = new EmptyNode(); }
         break;
-      case 12: // ident -> ID
+      case 13: // ident -> ID
 {
 			if (!InDefSect)
 				if (!SymbolTable.vars.ContainsKey(ValueStack[ValueStack.Depth-1].sVal))
-					throw new Exception("("+LocationStack[LocationStack.Depth-1].StartLine+","+LocationStack[LocationStack.Depth-1].StartColumn+"): Ïåðåìåííàÿ "+ValueStack[ValueStack.Depth-1].sVal+" íå îïèñàíà");
+					throw new Exception("("+LocationStack[LocationStack.Depth-1].StartLine+","+LocationStack[LocationStack.Depth-1].StartColumn+"): Переменная "+ValueStack[ValueStack.Depth-1].sVal+" не описана");
 			CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); 
 		}
         break;
-      case 13: // assign -> ident, ASSIGN, expr
+      case 14: // assign -> ident, ASSIGN, expr
 { CurrentSemanticValue.stVal = new AssignNode(ValueStack[ValueStack.Depth-3].eVal as IdNode, ValueStack[ValueStack.Depth-1].eVal); }
         break;
-      case 14: // expr -> expr, PLUS, T
+      case 15: // expr -> expr, PLUS, T
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'+'); }
         break;
-      case 15: // expr -> expr, MINUS, T
+      case 16: // expr -> expr, MINUS, T
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'-'); }
         break;
-      case 16: // expr -> T
+      case 17: // expr -> T
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
         break;
-      case 17: // T -> T, MULT, F
+      case 18: // T -> T, MULT, F
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'*'); }
         break;
-      case 18: // T -> T, DIV, F
+      case 19: // T -> T, DIV, F
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'/'); }
         break;
-      case 19: // T -> F
+      case 20: // T -> F
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
         break;
-      case 20: // F -> ident
+      case 21: // F -> ident
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
         break;
-      case 21: // F -> INUM
+      case 22: // F -> INUM
 { CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
         break;
-      case 22: // F -> LPAREN, expr, RPAREN
+      case 23: // F -> LPAREN, expr, RPAREN
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; }
         break;
-      case 23: // block -> BEGIN, stlist, END
+      case 24: // block -> BEGIN, stlist, END
 { CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
         break;
-      case 24: // cycle -> CYCLE, expr, statement
+      case 25: // cycle -> CYCLE, expr, statement
 { CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal,ValueStack[ValueStack.Depth-1].stVal); }
         break;
-      case 25: // write -> WRITE, LPAREN, expr, RPAREN
+      case 26: // write -> WRITE, LPAREN, expr, RPAREN
 { CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); }
         break;
-      case 26: // Anon@1 -> /* empty */
+      case 27: // Anon@1 -> /* empty */
 { InDefSect = true; }
         break;
-      case 27: // var -> VAR, Anon@1, varlist
+      case 28: // var -> VAR, Anon@1, varlist
 { 
 			foreach (var v in (ValueStack[ValueStack.Depth-1].stVal as VarDefNode).vars)
 				SymbolTable.NewVarDef(v.Name, type.tint);
 			InDefSect = false;	
 		}
         break;
-      case 28: // varlist -> ident
+      case 29: // varlist -> ident
 { 
 			CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); 
 		}
         break;
-      case 29: // varlist -> varlist, COLUMN, ident
+      case 30: // varlist -> varlist, COLUMN, ident
 { 
 			(ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode);
 			CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal;
 		}
         break;
+      case 31: // if -> IF, expr, THEN, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 32: // if -> IF, expr, THEN, statement, ELSE, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-5].eVal, ValueStack[ValueStack.Depth-3].stVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
     }
-#pragma warning restore 162, 1522
   }
 
   protected override string TerminalToString(int terminal)
   {
-    if (aliases != null && aliases.ContainsKey(terminal))
-        return aliases[terminal];
+    if (aliasses != null && aliasses.ContainsKey(terminal))
+        return aliasses[terminal];
     else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture))
         return ((Tokens)terminal).ToString();
     else
diff --git a/Module7/SimpleYacc.y b/Module7/SimpleYacc.y
index 20087e00b11254a052c1bfcd87f137d81203b253..a9130fc9dea10a6bb91fdb5574b0f9b5f8a6e0a5 100644
--- a/Module7/SimpleYacc.y
+++ b/Module7/SimpleYacc.y
@@ -24,13 +24,13 @@
 
 %start progr
 
-%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN IF THEN ELSE
 %token <iVal> INUM 
 %token <dVal> RNUM 
 %token <sVal> ID
 
 %type <eVal> expr ident T F 
-%type <stVal> statement assign block cycle write empty var varlist 
+%type <stVal> statement assign block cycle write empty var varlist if
 %type <blVal> stlist block
 
 %%
@@ -55,6 +55,7 @@ statement: assign { $$ = $1; }
 		| write   { $$ = $1; }
 		| var     { $$ = $1; }
 		| empty   { $$ = $1; }
+		| if      { $$ = $1; }
 		;
 
 empty	: { $$ = new EmptyNode(); }
@@ -114,6 +115,11 @@ varlist	: ident
 			$$ = $1;
 		}
 		;
+
+if	    : IF expr THEN statement { $$ = new IfNode($2, $4); }
+		| IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); }
+		;
+
 	
 %%
 
diff --git a/Module7/Visitors/AutoVisitor.cs b/Module7/Visitors/AutoVisitor.cs
index 4bc07787c1c5f14bc9f05ff665e570994bd17e63..cb673eadb7709e824330167d345cf1d9b8da539c 100644
--- a/Module7/Visitors/AutoVisitor.cs
+++ b/Module7/Visitors/AutoVisitor.cs
@@ -41,5 +41,14 @@ namespace SimpleLang.Visitors
             foreach (var v in w.vars)
                 v.Visit(this);
         }
+
+        public override void VisitIfNode(IfNode ifn)
+        {
+            ifn.Expr.Visit(this);
+            ifn.ThenStat.Visit(this);
+            if (ifn.ElseStat != null)
+                ifn.ElseStat.Visit(this);
+        }
+
     }
 }
diff --git a/Module7/Visitors/ChangeVarIdVisitor.cs b/Module7/Visitors/ChangeVarIdVisitor.cs
index 7e8942df896a2c4f3d4539a1ae3012d3bb483cc4..b072be222fb3b1dc0f5b0abae04973de02ae8487 100644
--- a/Module7/Visitors/ChangeVarIdVisitor.cs
+++ b/Module7/Visitors/ChangeVarIdVisitor.cs
@@ -15,6 +15,13 @@ namespace SimpleLang.Visitors
             from = _from;
             to = _to;
         }
-       
+
+        public override void VisitIdNode(IdNode id)
+        {
+            if (id.Name == from)
+            {
+                id.Name = to;
+            }     
+        }
     }
 }
diff --git a/Module7/Visitors/CommonlyUsedVarVisitor.cs b/Module7/Visitors/CommonlyUsedVarVisitor.cs
index a73e3b6cfeb2662db626d3649d7cefc95e687c2d..2353d6f71c81aff94dc2ad3a78b62a9005947e73 100644
--- a/Module7/Visitors/CommonlyUsedVarVisitor.cs
+++ b/Module7/Visitors/CommonlyUsedVarVisitor.cs
@@ -8,9 +8,28 @@ namespace SimpleLang.Visitors
 {
     public class CommonlyUsedVarVisitor : AutoVisitor
     {
+        Dictionary<string, int> varUsages = new Dictionary<string, int>();
         public string mostCommonlyUsedVar()
         {
-            throw new NotImplementedException();
+            int maxCount = 0;
+            string maxVar = "";
+            foreach (var item in varUsages)
+            {
+                if (item.Value > maxCount)
+                {
+                    maxVar = item.Key;
+                    maxCount = item.Value;
+                }
+            }
+            return maxVar;
         }
+
+        public override void VisitIdNode(IdNode a)
+        {
+            if (!varUsages.ContainsKey(a.Name))
+                varUsages[a.Name] = 1;
+            varUsages[a.Name]++;
+        }
+
     }
 }
diff --git a/Module7/Visitors/CountCyclesOpVisitor.cs b/Module7/Visitors/CountCyclesOpVisitor.cs
index 5b5368b01bb2ece936bdcff542998c8c01009aa5..dcbaec8ff07bcbe340b803c337a5706a8610928c 100644
--- a/Module7/Visitors/CountCyclesOpVisitor.cs
+++ b/Module7/Visitors/CountCyclesOpVisitor.cs
@@ -8,9 +8,37 @@ namespace SimpleLang.Visitors
 {
     public class CountCyclesOpVisitor : AutoVisitor
     {
+        public int amountOps = 0;
+        public int amountCycles = 0;
+        public bool isInCycle = false;
         public int MidCount()
         {
-            throw new NotImplementedException();
+            return amountOps == 0 ? 0 : amountOps / amountCycles;
+        }
+        public override void VisitAssignNode(AssignNode a)
+        {
+            if (!isInCycle) return;
+            amountOps++;
+        }
+
+        public override void VisitVarDefNode(VarDefNode w)
+        {
+            if (!isInCycle) return;
+            amountOps++;
+        }
+
+        public override void VisitWriteNode(WriteNode w)
+        {
+            if (!isInCycle) return;
+            amountOps++;
+        }
+
+        public override void VisitCycleNode(CycleNode c)
+        {
+            amountCycles++;
+            isInCycle = true;
+            c.Stat.Visit(this);
+            isInCycle = false;
         }
     }
 }
diff --git a/Module7/Visitors/ExprComplexityVisitor.cs b/Module7/Visitors/ExprComplexityVisitor.cs
index ef9f0b2a9e8e6d76f0cb90d25515bea16760776e..7ca57684cfcdd297d7ec3e0eead37490e2cffc24 100644
--- a/Module7/Visitors/ExprComplexityVisitor.cs
+++ b/Module7/Visitors/ExprComplexityVisitor.cs
@@ -8,11 +8,48 @@ namespace SimpleLang.Visitors
 {
     public class ExprComplexityVisitor : AutoVisitor
     {
-        // список должен содержать сложность каждого выражения, встреченного при обычном порядке обхода AST
-        public List<int> getComplexityList()
+        List<int> complexity = new List<int>();
+        int lastExprComplexity = 0;
+
+        public override void VisitAssignNode(AssignNode a)
+        {
+            a.Expr.Visit(this);
+            complexity.Add(lastExprComplexity);
+            lastExprComplexity = 0;
+        }
+
+        public override void VisitCycleNode(CycleNode c)
+        {
+            c.Expr.Visit(this);
+            complexity.Add(lastExprComplexity);
+            lastExprComplexity = 0;
+            c.Stat.Visit(this);
+        }
+
+        public override void VisitWriteNode(WriteNode w)
+        {
+            w.Expr.Visit(this);
+            complexity.Add(lastExprComplexity);
+            lastExprComplexity = 0;
+        }
+
+        public override void VisitBinOpNode(BinOpNode binop)
         {
-            throw new NotImplementedException();
+            binop.Left.Visit(this);
+            if (binop.Op == '+' || binop.Op == '-')
+            {
+                lastExprComplexity += 1;
+            }
+            if (binop.Op == '*' || binop.Op == '/')
+            {
+                lastExprComplexity += 3;
+            }
+            binop.Right.Visit(this);
         }
 
-     }
+        public List<int> getComplexityList()
+        {
+            return complexity;
+        }
+    }
 }
diff --git a/Module7/Visitors/MaxIfCycleNestVisitor.cs b/Module7/Visitors/MaxIfCycleNestVisitor.cs
index c399a8ec4e3a067d99e207abc8e8e04f1f0baadb..349992bc906a4785b00fb3f782fa43e261916d37 100644
--- a/Module7/Visitors/MaxIfCycleNestVisitor.cs
+++ b/Module7/Visitors/MaxIfCycleNestVisitor.cs
@@ -10,5 +10,28 @@ namespace SimpleLang.Visitors
     public class MaxIfCycleNestVisitor : AutoVisitor
     {
         public int MaxNest = 0;
+
+        private int currentNestLevel = 0;
+
+        public override void VisitCycleNode(CycleNode c)
+        {
+            currentNestLevel++;
+            if (currentNestLevel > MaxNest)
+                MaxNest = currentNestLevel;
+            c.Stat.Visit(this);
+            currentNestLevel--;
+        }
+
+        public override void VisitIfNode(IfNode ifn)
+        {
+            currentNestLevel++;
+            if (currentNestLevel > MaxNest)
+                MaxNest = currentNestLevel;
+            ifn.ThenStat.Visit(this);
+            if (ifn.ElseStat != null)
+                ifn.ElseStat.Visit(this);
+            currentNestLevel--;
+        }
+
     }
 }
\ No newline at end of file
diff --git a/Module7/Visitors/MaxNestCyclesVisitor.cs b/Module7/Visitors/MaxNestCyclesVisitor.cs
index e5c768b4052dd05dd6eb58a87db533df5929cf0a..e41e9138f2a8817f3000cc3a1dea95af457fb1e1 100644
--- a/Module7/Visitors/MaxNestCyclesVisitor.cs
+++ b/Module7/Visitors/MaxNestCyclesVisitor.cs
@@ -9,5 +9,18 @@ namespace SimpleLang.Visitors
     public class MaxNestCyclesVisitor : AutoVisitor
     {
         public int MaxNest = 0;
+
+        private int currentNestLevel = 0;
+        public override void VisitCycleNode(CycleNode c)
+        {
+            currentNestLevel++;
+            if (currentNestLevel > MaxNest)
+            {
+                MaxNest = currentNestLevel;
+            }   
+            c.Stat.Visit(this);
+            currentNestLevel--;
+        }
+
     }
 }
diff --git a/Module7/Visitors/PrettyPrintVisitor.cs b/Module7/Visitors/PrettyPrintVisitor.cs
index 87892b1214d751d13640e7adf61bd276ef870904..9d899dd1bae74f2aaebbb6877fbbb9f7f100c832 100644
--- a/Module7/Visitors/PrettyPrintVisitor.cs
+++ b/Module7/Visitors/PrettyPrintVisitor.cs
@@ -84,5 +84,18 @@ namespace SimpleLang.Visitors
             for (int i = 1; i < w.vars.Count; i++)
                 Text += ',' + w.vars[i].Name;
         }
+        public override void VisitIfNode(IfNode ifn)
+        {
+            Text += IndentStr() + "if ";
+            ifn.Expr.Visit(this);
+            Text += Environment.NewLine;
+            ifn.ThenStat.Visit(this);
+
+            if (ifn.ElseStat == null)
+                return;
+            Text += Environment.NewLine;
+            ifn.ElseStat.Visit(this);
+        }
+
     }
 }
diff --git a/Module7/Visitors/Visitor.cs b/Module7/Visitors/Visitor.cs
index b9dcae028c1c74893e7bf551cd0feccf5bcbf0c9..5c50fc18302eadea13267f6a696c96f6dabfc821 100644
--- a/Module7/Visitors/Visitor.cs
+++ b/Module7/Visitors/Visitor.cs
@@ -17,5 +17,6 @@ namespace SimpleLang.Visitors
         public virtual void VisitWriteNode(WriteNode w) { }
         public virtual void VisitVarDefNode(VarDefNode w) { }
         public virtual void VisitEmptyNode(EmptyNode w) { }
+        public virtual void VisitIfNode(IfNode ifn) { }
     }
 }
diff --git a/Module7/packages.config b/Module7/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module7/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/Module8/ParserGenerator.csproj b/Module8/ParserGenerator.csproj
index a49c30ab3a17dd6d0928ccb6aac6692229a41383..fcf9adb7b4eeadd3269b2a1c4d6af428a95b603b 100644
--- a/Module8/ParserGenerator.csproj
+++ b/Module8/ParserGenerator.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@@ -14,6 +16,8 @@
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <PlatformTarget>x86</PlatformTarget>
@@ -60,6 +64,9 @@
     <Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.dll</HintPath>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -90,8 +97,16 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/Module8/ProgramTree.cs b/Module8/ProgramTree.cs
index 500e94046a9d2b86cf850b1525f5933157af86bc..8ffb89b250f73f64414bf7263131b4072193f5f6 100644
--- a/Module8/ProgramTree.cs
+++ b/Module8/ProgramTree.cs
@@ -160,4 +160,35 @@ namespace ProgramTree
             v.VisitIfNode(this);
         }
     }
+
+    public class WhileNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode Stat { get; set; }
+        public WhileNode(ExprNode expr, StatementNode stat)
+        {
+            Expr = expr;
+            Stat = stat;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitWhileNode(this);
+        }
+    }
+
+    public class RepeatNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public BlockNode StList { get; set; }
+        public RepeatNode(ExprNode expr, BlockNode stat)
+        {
+            Expr = expr;
+            StList = stat;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitRepeatNode(this);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/Module8/SimpleLex.cs b/Module8/SimpleLex.cs
index 124489e2d753e8ffee406427501b40410d8779db..09a5c3ce728b1aa91a9a2a6d16dde48c847ed12a 100644
--- a/Module8/SimpleLex.cs
+++ b/Module8/SimpleLex.cs
@@ -1,14 +1,10 @@
 //
 //  This CSharp output file generated by Gardens Point LEX
-//  Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
-//  Output produced by GPLEX is the property of the user.
-//  See accompanying file GPLEXcopyright.rtf.
-//
-//  GPLEX Version:  1.2.2
-//  Machine:  MAINHOMEPC2
-//  DateTime: 30.09.2018 18:23:21
-//  UserName: someone
-//  GPLEX input file <SimpleLex.lex - 30.09.2018 18:22:46>
+//  Version:  1.1.3.301
+//  Machine:  WIN-51KGPO1PTR9
+//  DateTime: 04.12.2022 17:28:51
+//  UserName: ?????????????
+//  GPLEX input file <SimpleLex.lex>
 //  GPLEX frame file <embedded resource>
 //
 //  Option settings: unicode, parser, minimize
@@ -17,8 +13,8 @@
 //
 
 //
-// Revised backup code
-// Version 1.2.1 of 24-June-2013
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
 //
 //
 #define BACKUP
@@ -127,8 +123,8 @@ namespace SimpleScanner
         
         enum Result {accept, noMatch, contextFound};
 
-        const int maxAccept = 17;
-        const int initial = 18;
+        const int maxAccept = 18;
+        const int initial = 19;
         const int eofNum = 0;
         const int goStart = -1;
         const int INITIAL = 0;
@@ -165,24 +161,24 @@ namespace SimpleScanner
         }
     };
 
-    static int[] startState = new int[] {18, 0};
+    static int[] startState = new int[] {19, 0};
 
 #region CompressedCharacterMap
     //
-    // There are 15 equivalence classes
+    // There are 16 equivalence classes
     // There are 2 character sequence regions
     // There are 1 tables, 123 entries
     // There are 1 runs, 0 singletons
     // Decision tree depth is 1
     //
     static sbyte[] mapC0 = new sbyte[123] {
-/*     '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14, 
-/*   '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-/*   '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 11, 12, 9, 8, 13, 7, 2, 10, 
-/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14, 
-/*      '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
-/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 
-/*      '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*     '\0' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 
+/*   '\x10' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+/*   '\x20' */ 0, 15, 15, 15, 15, 14, 15, 15, 11, 12, 9, 8, 13, 7, 2, 10, 
+/*      '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 15, 5, 15, 15, 
+/*      '@' */ 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*      'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 3, 
+/*      '`' */ 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
 /*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
 
     static sbyte MapC(int code)
@@ -190,20 +186,20 @@ namespace SimpleScanner
       if (code < 123) // '\0' <= code <= 'z'
         return mapC0[code - 0];
       else // '{' <= code <= '\U0010FFFF'
-        return (sbyte)14;
+        return (sbyte)15;
     }
 #endregion
 
-    static Table[] NxS = new Table[20] {
+    static Table[] NxS = new Table[21] {
 /* NxS[   0] */ new Table(0, 0, 0, null),
-/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 19}),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 20}),
 /* NxS[   2] */ new Table(0, 0, -1, null),
 /* NxS[   3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
-/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {16}),
+/* NxS[   4] */ new Table(5, 1, -1, new sbyte[] {17}),
 /* NxS[   5] */ new Table(0, 0, -1, null),
-/* NxS[   6] */ new Table(5, 1, -1, new sbyte[] {15}),
-/* NxS[   7] */ new Table(5, 1, -1, new sbyte[] {14}),
-/* NxS[   8] */ new Table(5, 1, -1, new sbyte[] {13}),
+/* NxS[   6] */ new Table(5, 1, -1, new sbyte[] {16}),
+/* NxS[   7] */ new Table(5, 1, -1, new sbyte[] {15}),
+/* NxS[   8] */ new Table(5, 1, -1, new sbyte[] {14}),
 /* NxS[   9] */ new Table(0, 0, -1, null),
 /* NxS[  10] */ new Table(0, 0, -1, null),
 /* NxS[  11] */ new Table(0, 0, -1, null),
@@ -212,10 +208,11 @@ namespace SimpleScanner
 /* NxS[  14] */ new Table(0, 0, -1, null),
 /* NxS[  15] */ new Table(0, 0, -1, null),
 /* NxS[  16] */ new Table(0, 0, -1, null),
-/* NxS[  17] */ new Table(1, 1, -1, new sbyte[] {17}),
-/* NxS[  18] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
-          6, 7, 8, 9, 10, 11, 12, 2}),
-/* NxS[  19] */ new Table(1, 1, -1, new sbyte[] {17}),
+/* NxS[  17] */ new Table(0, 0, -1, null),
+/* NxS[  18] */ new Table(1, 1, -1, new sbyte[] {18}),
+/* NxS[  19] */ new Table(1, 15, -1, new sbyte[] {1, 2, 3, 4, 2, 5, 
+          6, 7, 8, 9, 10, 11, 12, 13, 2}),
+/* NxS[  20] */ new Table(1, 1, -1, new sbyte[] {18}),
     };
 
 int NextState() {
@@ -225,7 +222,7 @@ int NextState() {
         unchecked {
             int rslt;
             int idx = MapC(code) - NxS[state].min;
-            if (idx < 0) idx += 15;
+            if (idx < 0) idx += 16;
             if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
             else rslt = NxS[state].nxt[idx];
             return rslt;
@@ -305,7 +302,8 @@ int NextState() {
 
         public Scanner(Stream file, string codepage) {
             SetSource(file, CodePageHandling.GetCodePage(codepage));
-        }   
+        }
+        
 #endif // !NOFILES
 
      public Scanner() { }
@@ -333,7 +331,7 @@ int NextState() {
                     if (next < 0xDC00 || next > 0xDFFF)
                         code = ScanBuff.UnicodeReplacementChar;
                     else
-                        code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
                 }
 #endif
                 cCol++;
@@ -386,7 +384,9 @@ int NextState() {
             GetCode();
         }
 
+#if !NOFILES        
         // ================ LineBuffer Initialization ===================
+
         /// <summary>
         /// Create and initialize a LineBuff buffer object for this scanner
         /// </summary>
@@ -400,7 +400,6 @@ int NextState() {
             GetCode();
         }
 
-#if !NOFILES        
         // =============== StreamBuffer Initialization ==================
 
         /// <summary>
@@ -502,12 +501,6 @@ int NextState() {
             }
         }
 
-        /// <summary>
-        /// Discards all but the first "n" codepoints in the recognized pattern.
-        /// Resets the buffer position so that only n codepoints have been consumed;
-        /// yytext is also re-evaluated. 
-        /// </summary>
-        /// <param name="n">The number of codepoints to consume</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void yyless(int n)
         {
@@ -527,10 +520,6 @@ int NextState() {
         //  but it does not seem possible to re-establish
         //  the correct column counts except by going forward.
         //
-        /// <summary>
-        /// Removes the last "n" code points from the pattern.
-        /// </summary>
-        /// <param name="n">The number to remove</param>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         void _yytrunc(int n) { yyless(yyleng - n); }
         
@@ -543,23 +532,18 @@ int NextState() {
         // can't use (tokEPos - tokPos) because of the
         // possibility of surrogate pairs in the token.
         //
-        /// <summary>
-        /// The length of the pattern in codepoints (not the same as 
-        /// string-length if the pattern contains any surrogate pairs).
-        /// </summary>
         [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
         [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
         public int yyleng
         {
             get {
+#if BYTEMODE
+                return tokEPos - tokPos;
+#else   
                 if (tokELin == tokLin)
                     return tokECol - tokCol;
-                else
-#if BYTEMODE
-                    return tokEPos - tokPos;
-#else
-                {
+                else {
                     int ch;
                     int count = 0;
                     int save = buffer.Pos;
@@ -568,7 +552,7 @@ int NextState() {
                         ch = buffer.Read();
                         if (!char.IsHighSurrogate((char)ch)) count++;
                     } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
-                    buffer.Pos = save;
+                    buffer.Pos = save; 
                     return count;
                 }
 #endif // BYTEMODE
@@ -593,56 +577,65 @@ int NextState() {
 
         // ============== The main tokenizer code =================
 
-        int Scan() {
+        int Scan()
+        {
             try {
-                for (; ; ) {
-                    int next;              // next state to enter
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
 #if LEFTANCHORS
-                    for (;;) {
+                    for (;;)
+                    {
                         // Discard characters that do not start any pattern.
                         // Must check the left anchor condition after *every* GetCode!
                         state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
-                        if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
+                        if ((next = NextState()) != goStart) 
+                            break; // LOOP EXIT HERE...
                         GetCode();
                     }
                     
 #else // !LEFTANCHORS
                     state = currentStart;
-                    while ((next = NextState()) == goStart) {
+                    while ((next = NextState()) == goStart)
                         // At this point, the current character has no
                         // transition from the current state.  We discard 
                         // the "no-match" char.   In traditional LEX such 
                         // characters are echoed to the console.
                         GetCode();
-                    }
 #endif // LEFTANCHORS                    
                     // At last, a valid transition ...    
                     MarkToken();
                     state = next;
-                    GetCode();                    
+                    GetCode();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
 #if BACKUP
-                    bool contextSaved = false;
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                        if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
-                            // Store data for the *latest* accept state that was found.
-                            SaveStateAndPos( ref ctx );
-                            contextSaved = true;
+                        if (state <= maxAccept && next > maxAccept) // need to prepare backup data
+                        {
+                            // ctx is an object. The fields may be 
+                            // mutated by the call to Recurse2.
+                            // On return the data in ctx is the
+                            // *latest* accept state that was found.
+                            
+                            rslt = Recurse2(ref ctx, next);
+                            if (rslt == Result.noMatch) 
+                                RestoreStateAndPos(ref ctx);
+                            break;
                         }
-                        state = next;
-                        GetCode();
-                    }
-                    if (state > maxAccept && contextSaved)
-                        RestoreStateAndPos( ref ctx );
-#else  // BACKUP
-                    while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
-                         state = next;
-                         GetCode();
-                    }
+                        else
 #endif // BACKUP
-                    if (state <= maxAccept) {
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
                         MarkEnd();
 #region ActionSwitch
-#pragma warning disable 162, 1522
+#pragma warning disable 162
     switch (state)
     {
         case eofNum:
@@ -688,25 +681,28 @@ return (int)Tokens.RPAREN;
 return (int)Tokens.COLUMN;
             break;
         case 13:
-return (int)Tokens.ASSIGNMULT;
+return (int)Tokens.MOD;
             break;
         case 14:
-return (int)Tokens.ASSIGNPLUS;
+return (int)Tokens.ASSIGNMULT;
             break;
         case 15:
-return (int)Tokens.ASSIGNMINUS;
+return (int)Tokens.ASSIGNPLUS;
             break;
         case 16:
-return (int)Tokens.ASSIGN;
+return (int)Tokens.ASSIGNMINUS;
             break;
         case 17:
+return (int)Tokens.ASSIGN;
+            break;
+        case 18:
 yylval.dVal = double.Parse(yytext); 
   return (int)Tokens.RNUM;
             break;
         default:
             break;
     }
-#pragma warning restore 162, 1522
+#pragma warning restore 162
 #endregion
                     }
                 }
@@ -719,7 +715,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         }
 
 #if BACKUP
-        void SaveStateAndPos(ref Context ctx) {
+        Result Recurse2(ref Context ctx, int next)
+        {
+            // Assert: at entry "state" is an accept state AND
+            //         NextState(state, code) != goStart AND
+            //         NextState(state, code) is not an accept state.
+            //
+            SaveStateAndPos(ref ctx);
+            state = next;
+            GetCode();
+
+            while ((next = NextState()) > eofNum)
+            {
+                if (state <= maxAccept && next > maxAccept) // need to update backup data
+                    SaveStateAndPos(ref ctx);
+                state = next;
+                if (state == eofNum) return Result.accept;
+                GetCode(); 
+            }
+            return (state <= maxAccept ? Result.accept : Result.noMatch);
+        }
+
+        void SaveStateAndPos(ref Context ctx)
+        {
             ctx.bPos  = buffer.Pos;
             ctx.rPos  = readPos;
             ctx.cCol  = cCol;
@@ -728,7 +746,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             ctx.cChr  = code;
         }
 
-        void RestoreStateAndPos(ref Context ctx) {
+        void RestoreStateAndPos(ref Context ctx)
+        {
             buffer.Pos = ctx.bPos;
             readPos = ctx.rPos;
             cCol  = ctx.cCol;
@@ -736,7 +755,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
             state = ctx.state;
             code  = ctx.cChr;
         }
-#endif  // BACKUP
+
+#endif // BACKUP
 
         // ============= End of the tokenizer code ================
 
@@ -768,16 +788,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
         
 #region UserCodeSection
 
-public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
+public override void yyerror(string format, params object[] args) // обработка синтаксических ошибок
 {
   var ww = args.Skip(1).Cast<string>().ToArray();
-  string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
+  string errorMsg = string.Format("({0},{1}): Встречено {2}, а ожидалось {3}", yyline, yycol, args[0], string.Join(" или ", ww));
   throw new SyntaxException(errorMsg);
 }
 
 public void LexError()
 {
-  string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
   throw new LexException(errorMsg);
 }
 
@@ -793,6 +813,15 @@ class ScannerHelper
     keywords.Add("cycle",(int)Tokens.CYCLE);
     keywords.Add("write",(int)Tokens.WRITE);
     keywords.Add("var",(int)Tokens.VAR);
+    keywords.Add("if", (int)Tokens.IF);
+    keywords.Add("then", (int)Tokens.THEN);
+    keywords.Add("else", (int)Tokens.ELSE);
+    keywords.Add("while", (int)Tokens.WHILE);
+    keywords.Add("do", (int)Tokens.DO);
+    keywords.Add("repeat", (int)Tokens.REPEAT);
+    keywords.Add("until", (int)Tokens.UNTIL);
+
+
   }
   public static int GetIDToken(string s)
   {
@@ -853,7 +882,6 @@ class ScannerHelper
             return new LineBuffer(source);
         }
 
-#if (!NOFILES)
         public static ScanBuff GetBuffer(Stream source)
         {
             return new BuildBuffer(source);
@@ -864,8 +892,7 @@ class ScannerHelper
         {
             return new BuildBuffer(source, fallbackCodePage);
         }
-#endif // !BYTEMODE
-#endif // !NOFILES
+#endif
     }
 
     #region Buffer classes
@@ -988,7 +1015,7 @@ class ScannerHelper
             {
                 ix = lstart = 0;
             }
-            while (ix < numLines)
+            for (; ; )
             {
                 int len = line[ix].Length + 1;
                 if (pos < lstart + len) break;
@@ -1046,8 +1073,7 @@ class ScannerHelper
             {
                 cPos = value;
                 findIndex(cPos, out cLine, out curLineStart);
-                // cLine should be the *next* line after curLine.
-                curLine = (cLine < numLines ? line[cLine++] : "");
+                curLine = line[cLine];
                 curLineEnd = curLineStart + curLine.Length;
             }
         }
@@ -1055,7 +1081,7 @@ class ScannerHelper
         public override string ToString() { return "LineBuffer"; }
     }
 
-#if (!NOFILES)
+
     // ==============================================================
     // =====     class BuildBuff : for unicode text files    ========
     // ==============================================================
@@ -1296,13 +1322,12 @@ class ScannerHelper
         }
 #endif // !BYTEMODE
     }
-#endif // !NOFILES
     #endregion Buffer classes
 
     // ==============================================================
     // ============      class CodePageHandling         =============
     // ==============================================================
-#if (!NOFILES)
+
     public static class CodePageHandling
     {
         public static int GetCodePage(string option)
@@ -1513,7 +1538,6 @@ class ScannerHelper
     
 #endif // !BYTEMODE
 #endregion
-#endif // !NOFILES
 
 // End of code copied from embedded resource
 
diff --git a/Module8/SimpleLex.lex b/Module8/SimpleLex.lex
index 00dfa1249dd0572b3061e40d49d86058b4e1baee..4a1d43049203888f7ebc0c01ea6f6d06d9742237 100644
--- a/Module8/SimpleLex.lex
+++ b/Module8/SimpleLex.lex
@@ -42,6 +42,7 @@ ID {Alpha}{AlphaDigit}*
 "(" { return (int)Tokens.LPAREN; }
 ")" { return (int)Tokens.RPAREN; }
 "," { return (int)Tokens.COLUMN; }
+"%" { return (int)Tokens.MOD; }
 
 [^ \r\n] {
 	LexError();
@@ -78,6 +79,15 @@ class ScannerHelper
     keywords.Add("cycle",(int)Tokens.CYCLE);
     keywords.Add("write",(int)Tokens.WRITE);
     keywords.Add("var",(int)Tokens.VAR);
+    keywords.Add("if", (int)Tokens.IF);
+    keywords.Add("then", (int)Tokens.THEN);
+    keywords.Add("else", (int)Tokens.ELSE);
+    keywords.Add("while", (int)Tokens.WHILE);
+    keywords.Add("do", (int)Tokens.DO);
+    keywords.Add("repeat", (int)Tokens.REPEAT);
+    keywords.Add("until", (int)Tokens.UNTIL);
+
+
   }
   public static int GetIDToken(string s)
   {
diff --git a/Module8/SimpleYacc.cs b/Module8/SimpleYacc.cs
index 41990d1991abc1e5c84a48ae96c6d9f5381c4264..b88992e2c9f7a34577a60ab13f32162be59ae537 100644
--- a/Module8/SimpleYacc.cs
+++ b/Module8/SimpleYacc.cs
@@ -1,18 +1,17 @@
 // This code was generated by the Gardens Point Parser Generator
-// Copyright (c) Wayne Kelly, John Gough, QUT 2005-2014
+// Copyright (c) Wayne Kelly, QUT 2005-2010
 // (see accompanying GPPGcopyright.rtf)
 
-// GPPG version 1.5.2
-// Machine:  MAINHOMEPC2
-// DateTime: 30.09.2018 18:23:23
-// UserName: someone
-// Input file <SimpleYacc.y - 30.09.2018 18:22:38>
+// GPPG version 1.3.6
+// Machine:  WIN-51KGPO1PTR9
+// DateTime: 04.12.2022 17:28:51
+// UserName: ?????????????
+// Input file <SimpleYacc.y>
 
 // options: no-lines gplex
 
 using System;
 using System.Collections.Generic;
-using System.CodeDom.Compiler;
 using System.Globalization;
 using System.Text;
 using QUT.Gppg;
@@ -21,10 +20,12 @@ using ProgramTree;
 
 namespace SimpleParser
 {
-public enum Tokens {error=2,EOF=3,BEGIN=4,END=5,CYCLE=6,
-    ASSIGN=7,ASSIGNPLUS=8,ASSIGNMINUS=9,ASSIGNMULT=10,SEMICOLON=11,WRITE=12,
-    VAR=13,PLUS=14,MINUS=15,MULT=16,DIV=17,LPAREN=18,
-    RPAREN=19,COLUMN=20,INUM=21,RNUM=22,ID=23};
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,ASSIGN=6,
+    ASSIGNPLUS=7,ASSIGNMINUS=8,ASSIGNMULT=9,SEMICOLON=10,WRITE=11,VAR=12,
+    PLUS=13,MINUS=14,MULT=15,DIV=16,LPAREN=17,RPAREN=18,
+    COLUMN=19,MOD=20,IF=21,THEN=22,ELSE=23,WHILE=24,
+    DO=25,REPEAT=26,UNTIL=27,INUM=28,RNUM=29,ID=30};
 
 public struct ValueType
 { 
@@ -37,124 +38,137 @@ public struct ValueType
 			public BlockNode blVal;
        }
 // Abstract base class for GPLEX scanners
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public abstract class ScanBase : AbstractScanner<ValueType,LexLocation> {
   private LexLocation __yylloc = new LexLocation();
   public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } }
   protected virtual bool yywrap() { return true; }
 }
 
-// Utility class for encapsulating token information
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
-public class ScanObj {
-  public int token;
-  public ValueType yylval;
-  public LexLocation yylloc;
-  public ScanObj( int t, ValueType val, LexLocation loc ) {
-    this.token = t; this.yylval = val; this.yylloc = loc;
-  }
-}
-
-[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
 public class Parser: ShiftReduceParser<ValueType, LexLocation>
 {
-  // Verbatim content from SimpleYacc.y - 30.09.2018 18:22:38
-// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
-    public BlockNode root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà 
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
     public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
 	private bool InDefSect = false;
-  // End verbatim content from SimpleYacc.y - 30.09.2018 18:22:38
+  // End verbatim content from SimpleYacc.y
 
 #pragma warning disable 649
-  private static Dictionary<int, string> aliases;
+  private static Dictionary<int, string> aliasses;
 #pragma warning restore 649
-  private static Rule[] rules = new Rule[30];
-  private static State[] states = new State[48];
+  private static Rule[] rules = new Rule[38];
+  private static State[] states = new State[67];
   private static string[] nonTerms = new string[] {
       "progr", "expr", "ident", "T", "F", "statement", "assign", "block", "cycle", 
-      "write", "empty", "var", "varlist", "stlist", "$accept", "Anon@1", };
+      "write", "empty", "var", "varlist", "if", "while", "repeat", "stlist", 
+      "$accept", "Anon@1", };
 
   static Parser() {
-    states[0] = new State(new int[]{4,4},new int[]{-1,1,-8,3});
-    states[1] = new State(new int[]{3,2});
+    states[0] = new State(new int[]{3,4},new int[]{-1,1,-8,3});
+    states[1] = new State(new int[]{2,2});
     states[2] = new State(-1);
     states[3] = new State(-2);
-    states[4] = new State(new int[]{23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-14,5,-6,47,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
-    states[5] = new State(new int[]{5,6,11,7});
-    states[6] = new State(-23);
-    states[7] = new State(new int[]{23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-6,8,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
+    states[4] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14},new int[]{-17,5,-6,66,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[5] = new State(new int[]{4,6,10,7});
+    states[6] = new State(-27);
+    states[7] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14},new int[]{-6,8,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
     states[8] = new State(-4);
     states[9] = new State(-5);
-    states[10] = new State(new int[]{7,11});
-    states[11] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,12,-4,28,-5,27,-3,17});
-    states[12] = new State(new int[]{14,13,15,23,5,-13,11,-13});
-    states[13] = new State(new int[]{23,18,21,19,18,20},new int[]{-4,14,-5,27,-3,17});
-    states[14] = new State(new int[]{16,15,17,25,14,-14,15,-14,5,-14,11,-14,19,-14,23,-14,4,-14,6,-14,12,-14,13,-14});
-    states[15] = new State(new int[]{23,18,21,19,18,20},new int[]{-5,16,-3,17});
-    states[16] = new State(-17);
-    states[17] = new State(-20);
-    states[18] = new State(-12);
-    states[19] = new State(-21);
-    states[20] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,21,-4,28,-5,27,-3,17});
-    states[21] = new State(new int[]{19,22,14,13,15,23});
-    states[22] = new State(-22);
-    states[23] = new State(new int[]{23,18,21,19,18,20},new int[]{-4,24,-5,27,-3,17});
-    states[24] = new State(new int[]{16,15,17,25,14,-15,15,-15,5,-15,11,-15,19,-15,23,-15,4,-15,6,-15,12,-15,13,-15});
-    states[25] = new State(new int[]{23,18,21,19,18,20},new int[]{-5,26,-3,17});
-    states[26] = new State(-18);
-    states[27] = new State(-19);
-    states[28] = new State(new int[]{16,15,17,25,14,-16,15,-16,5,-16,11,-16,19,-16,23,-16,4,-16,6,-16,12,-16,13,-16});
-    states[29] = new State(-6);
-    states[30] = new State(-7);
-    states[31] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,32,-4,28,-5,27,-3,17});
-    states[32] = new State(new int[]{14,13,15,23,23,18,4,4,6,31,12,35,13,40,5,-11,11,-11},new int[]{-6,33,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
-    states[33] = new State(-24);
-    states[34] = new State(-8);
-    states[35] = new State(new int[]{18,36});
-    states[36] = new State(new int[]{23,18,21,19,18,20},new int[]{-2,37,-4,28,-5,27,-3,17});
-    states[37] = new State(new int[]{19,38,14,13,15,23});
-    states[38] = new State(-25);
-    states[39] = new State(-9);
-    states[40] = new State(-26,new int[]{-16,41});
-    states[41] = new State(new int[]{23,18},new int[]{-13,42,-3,45});
-    states[42] = new State(new int[]{20,43,5,-27,11,-27});
-    states[43] = new State(new int[]{23,18},new int[]{-3,44});
-    states[44] = new State(-29);
-    states[45] = new State(-28);
-    states[46] = new State(-10);
-    states[47] = new State(-3);
-
-    for (int sNo = 0; sNo < states.Length; sNo++) states[sNo].number = sNo;
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,12,-4,30,-5,29,-3,17});
+    states[12] = new State(new int[]{13,13,14,23,4,-16,10,-16,27,-16,23,-16});
+    states[13] = new State(new int[]{30,18,28,19,17,20},new int[]{-4,14,-5,29,-3,17});
+    states[14] = new State(new int[]{15,15,16,25,20,27,13,-17,14,-17,4,-17,10,-17,27,-17,23,-17,18,-17,30,-17,3,-17,5,-17,11,-17,12,-17,21,-17,24,-17,26,-17,22,-17,25,-17});
+    states[15] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,16,-3,17});
+    states[16] = new State(-20);
+    states[17] = new State(-24);
+    states[18] = new State(-15);
+    states[19] = new State(-25);
+    states[20] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,21,-4,30,-5,29,-3,17});
+    states[21] = new State(new int[]{18,22,13,13,14,23});
+    states[22] = new State(-26);
+    states[23] = new State(new int[]{30,18,28,19,17,20},new int[]{-4,24,-5,29,-3,17});
+    states[24] = new State(new int[]{15,15,16,25,20,27,13,-18,14,-18,4,-18,10,-18,27,-18,23,-18,18,-18,30,-18,3,-18,5,-18,11,-18,12,-18,21,-18,24,-18,26,-18,22,-18,25,-18});
+    states[25] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,26,-3,17});
+    states[26] = new State(-21);
+    states[27] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,28,-3,17});
+    states[28] = new State(-22);
+    states[29] = new State(-23);
+    states[30] = new State(new int[]{15,15,16,25,20,27,13,-19,14,-19,4,-19,10,-19,27,-19,23,-19,18,-19,30,-19,3,-19,5,-19,11,-19,12,-19,21,-19,24,-19,26,-19,22,-19,25,-19});
+    states[31] = new State(-6);
+    states[32] = new State(-7);
+    states[33] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,34,-4,30,-5,29,-3,17});
+    states[34] = new State(new int[]{13,13,14,23,30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,35,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[35] = new State(-28);
+    states[36] = new State(-8);
+    states[37] = new State(new int[]{17,38});
+    states[38] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,39,-4,30,-5,29,-3,17});
+    states[39] = new State(new int[]{18,40,13,13,14,23});
+    states[40] = new State(-29);
+    states[41] = new State(-9);
+    states[42] = new State(-30,new int[]{-19,43});
+    states[43] = new State(new int[]{30,18},new int[]{-13,44,-3,47});
+    states[44] = new State(new int[]{19,45,4,-31,10,-31,27,-31,23,-31});
+    states[45] = new State(new int[]{30,18},new int[]{-3,46});
+    states[46] = new State(-33);
+    states[47] = new State(-32);
+    states[48] = new State(-10);
+    states[49] = new State(-11);
+    states[50] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,51,-4,30,-5,29,-3,17});
+    states[51] = new State(new int[]{22,52,13,13,14,23});
+    states[52] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,53,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[53] = new State(new int[]{23,54,4,-34,10,-34,27,-34});
+    states[54] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,55,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[55] = new State(-35);
+    states[56] = new State(-12);
+    states[57] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,58,-4,30,-5,29,-3,17});
+    states[58] = new State(new int[]{25,59,13,13,14,23});
+    states[59] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,60,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[60] = new State(-36);
+    states[61] = new State(-13);
+    states[62] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,27,-14,10,-14},new int[]{-17,63,-6,66,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61});
+    states[63] = new State(new int[]{27,64,10,7});
+    states[64] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,65,-4,30,-5,29,-3,17});
+    states[65] = new State(new int[]{13,13,14,23,4,-37,10,-37,27,-37,23,-37});
+    states[66] = new State(-3);
 
-    rules[1] = new Rule(-15, new int[]{-1,3});
+    rules[1] = new Rule(-18, new int[]{-1,2});
     rules[2] = new Rule(-1, new int[]{-8});
-    rules[3] = new Rule(-14, new int[]{-6});
-    rules[4] = new Rule(-14, new int[]{-14,11,-6});
+    rules[3] = new Rule(-17, new int[]{-6});
+    rules[4] = new Rule(-17, new int[]{-17,10,-6});
     rules[5] = new Rule(-6, new int[]{-7});
     rules[6] = new Rule(-6, new int[]{-8});
     rules[7] = new Rule(-6, new int[]{-9});
     rules[8] = new Rule(-6, new int[]{-10});
     rules[9] = new Rule(-6, new int[]{-12});
     rules[10] = new Rule(-6, new int[]{-11});
-    rules[11] = new Rule(-11, new int[]{});
-    rules[12] = new Rule(-3, new int[]{23});
-    rules[13] = new Rule(-7, new int[]{-3,7,-2});
-    rules[14] = new Rule(-2, new int[]{-2,14,-4});
-    rules[15] = new Rule(-2, new int[]{-2,15,-4});
-    rules[16] = new Rule(-2, new int[]{-4});
-    rules[17] = new Rule(-4, new int[]{-4,16,-5});
-    rules[18] = new Rule(-4, new int[]{-4,17,-5});
-    rules[19] = new Rule(-4, new int[]{-5});
-    rules[20] = new Rule(-5, new int[]{-3});
-    rules[21] = new Rule(-5, new int[]{21});
-    rules[22] = new Rule(-5, new int[]{18,-2,19});
-    rules[23] = new Rule(-8, new int[]{4,-14,5});
-    rules[24] = new Rule(-9, new int[]{6,-2,-6});
-    rules[25] = new Rule(-10, new int[]{12,18,-2,19});
-    rules[26] = new Rule(-16, new int[]{});
-    rules[27] = new Rule(-12, new int[]{13,-16,-13});
-    rules[28] = new Rule(-13, new int[]{-3});
-    rules[29] = new Rule(-13, new int[]{-13,20,-3});
+    rules[11] = new Rule(-6, new int[]{-14});
+    rules[12] = new Rule(-6, new int[]{-15});
+    rules[13] = new Rule(-6, new int[]{-16});
+    rules[14] = new Rule(-11, new int[]{});
+    rules[15] = new Rule(-3, new int[]{30});
+    rules[16] = new Rule(-7, new int[]{-3,6,-2});
+    rules[17] = new Rule(-2, new int[]{-2,13,-4});
+    rules[18] = new Rule(-2, new int[]{-2,14,-4});
+    rules[19] = new Rule(-2, new int[]{-4});
+    rules[20] = new Rule(-4, new int[]{-4,15,-5});
+    rules[21] = new Rule(-4, new int[]{-4,16,-5});
+    rules[22] = new Rule(-4, new int[]{-4,20,-5});
+    rules[23] = new Rule(-4, new int[]{-5});
+    rules[24] = new Rule(-5, new int[]{-3});
+    rules[25] = new Rule(-5, new int[]{28});
+    rules[26] = new Rule(-5, new int[]{17,-2,18});
+    rules[27] = new Rule(-8, new int[]{3,-17,4});
+    rules[28] = new Rule(-9, new int[]{5,-2,-6});
+    rules[29] = new Rule(-10, new int[]{11,17,-2,18});
+    rules[30] = new Rule(-19, new int[]{});
+    rules[31] = new Rule(-12, new int[]{12,-19,-13});
+    rules[32] = new Rule(-13, new int[]{-3});
+    rules[33] = new Rule(-13, new int[]{-13,19,-3});
+    rules[34] = new Rule(-14, new int[]{21,-2,22,-6});
+    rules[35] = new Rule(-14, new int[]{21,-2,22,-6,23,-6});
+    rules[36] = new Rule(-15, new int[]{24,-2,25,-6});
+    rules[37] = new Rule(-16, new int[]{26,-17,27,-2});
   }
 
   protected override void Initialize() {
@@ -166,7 +180,6 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
 
   protected override void DoAction(int action)
   {
-#pragma warning disable 162, 1522
     switch (action)
     {
       case 2: // progr -> block
@@ -201,90 +214,114 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation>
       case 10: // statement -> empty
 { CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
         break;
-      case 11: // empty -> /* empty */
+      case 11: // statement -> if
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 12: // statement -> while
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 13: // statement -> repeat
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 14: // empty -> /* empty */
 { CurrentSemanticValue.stVal = new EmptyNode(); }
         break;
-      case 12: // ident -> ID
+      case 15: // ident -> ID
 {
 			if (!InDefSect)
 				if (!SymbolTable.vars.ContainsKey(ValueStack[ValueStack.Depth-1].sVal))
-					throw new Exception("("+LocationStack[LocationStack.Depth-1].StartLine+","+LocationStack[LocationStack.Depth-1].StartColumn+"): Ïåðåìåííàÿ "+ValueStack[ValueStack.Depth-1].sVal+" íå îïèñàíà");
+					throw new Exception("("+LocationStack[LocationStack.Depth-1].StartLine+","+LocationStack[LocationStack.Depth-1].StartColumn+"): Переменная "+ValueStack[ValueStack.Depth-1].sVal+" не описана");
 			CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); 
 		}
         break;
-      case 13: // assign -> ident, ASSIGN, expr
+      case 16: // assign -> ident, ASSIGN, expr
 { CurrentSemanticValue.stVal = new AssignNode(ValueStack[ValueStack.Depth-3].eVal as IdNode, ValueStack[ValueStack.Depth-1].eVal); }
         break;
-      case 14: // expr -> expr, PLUS, T
+      case 17: // expr -> expr, PLUS, T
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'+'); }
         break;
-      case 15: // expr -> expr, MINUS, T
+      case 18: // expr -> expr, MINUS, T
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'-'); }
         break;
-      case 16: // expr -> T
+      case 19: // expr -> T
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
         break;
-      case 17: // T -> T, MULT, F
+      case 20: // T -> T, MULT, F
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'*'); }
         break;
-      case 18: // T -> T, DIV, F
+      case 21: // T -> T, DIV, F
 { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'/'); }
         break;
-      case 19: // T -> F
+      case 22: // T -> T, MOD, F
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'%'); }
+        break;
+      case 23: // T -> F
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
         break;
-      case 20: // F -> ident
+      case 24: // F -> ident
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
         break;
-      case 21: // F -> INUM
+      case 25: // F -> INUM
 { CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
         break;
-      case 22: // F -> LPAREN, expr, RPAREN
+      case 26: // F -> LPAREN, expr, RPAREN
 { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; }
         break;
-      case 23: // block -> BEGIN, stlist, END
+      case 27: // block -> BEGIN, stlist, END
 { CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
         break;
-      case 24: // cycle -> CYCLE, expr, statement
+      case 28: // cycle -> CYCLE, expr, statement
 { CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal,ValueStack[ValueStack.Depth-1].stVal); }
         break;
-      case 25: // write -> WRITE, LPAREN, expr, RPAREN
+      case 29: // write -> WRITE, LPAREN, expr, RPAREN
 { CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); }
         break;
-      case 26: // Anon@1 -> /* empty */
+      case 30: // Anon@1 -> /* empty */
 { InDefSect = true; }
         break;
-      case 27: // var -> VAR, Anon@1, varlist
+      case 31: // var -> VAR, Anon@1, varlist
 { 
 			foreach (var v in (ValueStack[ValueStack.Depth-1].stVal as VarDefNode).vars)
 				SymbolTable.NewVarDef(v.Name, type.tint);
 			InDefSect = false;	
 		}
         break;
-      case 28: // varlist -> ident
+      case 32: // varlist -> ident
 { 
 			CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); 
 		}
         break;
-      case 29: // varlist -> varlist, COLUMN, ident
+      case 33: // varlist -> varlist, COLUMN, ident
 { 
 			(ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode);
 			CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal;
 		}
         break;
+      case 34: // if -> IF, expr, THEN, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 35: // if -> IF, expr, THEN, statement, ELSE, statement
+{ CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-5].eVal, ValueStack[ValueStack.Depth-3].stVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 36: // while -> WHILE, expr, DO, statement
+{ CurrentSemanticValue.stVal = new WhileNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+      case 37: // repeat -> REPEAT, stlist, UNTIL, expr
+{ CurrentSemanticValue.stVal = new RepeatNode(ValueStack[ValueStack.Depth-1].eVal, ValueStack[ValueStack.Depth-3].blVal); }
+        break;
     }
-#pragma warning restore 162, 1522
   }
 
   protected override string TerminalToString(int terminal)
   {
-    if (aliases != null && aliases.ContainsKey(terminal))
-        return aliases[terminal];
+    if (aliasses != null && aliasses.ContainsKey(terminal))
+        return aliasses[terminal];
     else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture))
         return ((Tokens)terminal).ToString();
     else
         return CharToString((char)terminal);
   }
 
+
 }
 }
diff --git a/Module8/SimpleYacc.y b/Module8/SimpleYacc.y
index 20087e00b11254a052c1bfcd87f137d81203b253..1e4d1d0252376b245b3fadd5d08cdce6c8482771 100644
--- a/Module8/SimpleYacc.y
+++ b/Module8/SimpleYacc.y
@@ -24,13 +24,13 @@
 
 %start progr
 
-%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN MOD IF THEN ELSE WHILE DO REPEAT UNTIL
 %token <iVal> INUM 
 %token <dVal> RNUM 
 %token <sVal> ID
 
 %type <eVal> expr ident T F 
-%type <stVal> statement assign block cycle write empty var varlist 
+%type <stVal> statement assign block cycle write empty var varlist if while repeat
 %type <blVal> stlist block
 
 %%
@@ -55,6 +55,10 @@ statement: assign { $$ = $1; }
 		| write   { $$ = $1; }
 		| var     { $$ = $1; }
 		| empty   { $$ = $1; }
+		| if      { $$ = $1; }
+		| while   { $$ = $1; }
+		| repeat  { $$ = $1; }
+
 		;
 
 empty	: { $$ = new EmptyNode(); }
@@ -79,6 +83,7 @@ expr	: expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
 		
 T 		: T MULT F { $$ = new BinOpNode($1,$3,'*'); }
 		| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
+		| T MOD F { $$ = new BinOpNode($1,$3,'%'); }
 		| F { $$ = $1; }
 		;
 		
@@ -114,6 +119,18 @@ varlist	: ident
 			$$ = $1;
 		}
 		;
+
+if	    : IF expr THEN statement { $$ = new IfNode($2, $4); }
+		| IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); }
+		;
+
+while   : WHILE expr DO statement { $$ = new WhileNode($2, $4); }
+		;
+
+repeat  : REPEAT stlist UNTIL expr { $$ = new RepeatNode($4, $2); }
+		;
+
+
 	
 %%
 
diff --git a/Module8/Visitors/AutoVisitor.cs b/Module8/Visitors/AutoVisitor.cs
index 5d508770fc5449f20e1d15859b78725d4e64af48..23010f40e5009930dcbe2db45043a72dfebc9517 100644
--- a/Module8/Visitors/AutoVisitor.cs
+++ b/Module8/Visitors/AutoVisitor.cs
@@ -50,5 +50,18 @@ namespace SimpleLang.Visitors
                 cond.ifFalse.Visit(this);
             }
         }
+
+        public override void VisitWhileNode(WhileNode whileNode)
+        {
+            whileNode.Expr.Visit(this);
+            whileNode.Stat.Visit(this);
+        }
+
+        public override void VisitRepeatNode(RepeatNode repeatNode)
+        {
+            repeatNode.StList.Visit(this);
+            repeatNode.Expr.Visit(this);
+        }
+
     }
 }
diff --git a/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs b/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs
index 88891ad31e66280ab20cdf988e42cb6e1390af22..4ebe637e82acebbe02f608f66ddc9826ddf8f447 100644
--- a/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs
+++ b/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs
@@ -44,6 +44,10 @@ namespace SimpleLang.Visitors
                 case '/':
                     genc.Emit(OpCodes.Div);
                     break;
+                case '%':
+                    genc.Emit(OpCodes.Rem);
+                    break;
+
             }
         }
         public override void VisitAssignNode(AssignNode a) 
@@ -94,6 +98,55 @@ namespace SimpleLang.Visitors
                 vars[v.Name] = genc.DeclareLocal(typeof(int));
         }
 
+        public override void VisitIfNode(IfNode cond)
+        {
+            var elseLabel = genc.DefineLabel();
+            cond.expr.Visit(this);
+
+            genc.Emit(OpCodes.Ldc_I4_0); // положил 0 на стек
+            genc.Emit(OpCodes.Beq, elseLabel); // если if expr == 0 тогда переод к elseLabel
+            cond.ifTrue.Visit(this);
+
+            genc.MarkLabel(elseLabel);
+            if (cond.ifFalse != null)
+                cond.ifFalse.Visit(this);
+        }
+
+        public override void VisitWhileNode(WhileNode whileNode)
+        {
+            var loopLabel = genc.DefineLabel();
+            var endLabel = genc.DefineLabel();
+
+            genc.MarkLabel(loopLabel);
+
+            whileNode.Expr.Visit(this);
+            genc.Emit(OpCodes.Ldc_I4_0); // положил 0 на стек
+            genc.Emit(OpCodes.Beq, endLabel);  // если expr == 0 тогда переход к endLabel
+
+            whileNode.Stat.Visit(this);
+
+            genc.Emit(OpCodes.Br, loopLabel); // переход к loopLabel
+            genc.MarkLabel(endLabel);
+        }
+
+        public override void VisitRepeatNode(RepeatNode repeatNode)
+        {
+            var loopLabel = genc.DefineLabel();
+            var endLabel = genc.DefineLabel();
+
+            genc.MarkLabel(loopLabel);
+            repeatNode.StList.Visit(this);
+            repeatNode.Expr.Visit(this);
+
+            genc.Emit(OpCodes.Ldc_I4_0);
+            genc.Emit(OpCodes.Beq, endLabel); // если expr == 0 тогда переход к endLabel
+            genc.Emit(OpCodes.Br, loopLabel); // если expr != 0 тогда еще срабатывание
+
+            genc.MarkLabel(endLabel);
+        }
+
+
+
         public void EndProgram()
         {
             genc.EndProgram();
diff --git a/Module8/Visitors/Visitor.cs b/Module8/Visitors/Visitor.cs
index 5fc65fcae1f33553c60fe2590eba8e3f086a85ca..a7b6b4455eeedf70e9425a23dbc7a224f8959a7a 100644
--- a/Module8/Visitors/Visitor.cs
+++ b/Module8/Visitors/Visitor.cs
@@ -18,5 +18,8 @@ namespace SimpleLang.Visitors
         public virtual void VisitVarDefNode(VarDefNode w) { }
         public virtual void VisitEmptyNode(EmptyNode w) { }
         public virtual void VisitIfNode(IfNode cond) { }
+
+        public virtual void VisitWhileNode(WhileNode whileNode) { }
+        public virtual void VisitRepeatNode(RepeatNode repeatNodee) { }
     }
 }
diff --git a/Module8/packages.config b/Module8/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..e68db37317c37e2eba1b927e94d341683afbbba1
--- /dev/null
+++ b/Module8/packages.config
@@ -0,0 +1,6 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
+</packages>
\ No newline at end of file
diff --git a/NunitReportParser/NunitReport.csproj b/NunitReportParser/NunitReport.csproj
index 5ae8b060675ab04b55972eb2f8c1434cf520b95e..373d8a1663efcba76b0f64c9efd57b6f00d12220 100644
--- a/NunitReportParser/NunitReport.csproj
+++ b/NunitReportParser/NunitReport.csproj
@@ -1,5 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -13,6 +15,8 @@
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -38,6 +42,9 @@
       <HintPath>..\packages\Newtonsoft.Json.12.0.3-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -56,4 +63,11 @@
     <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
+  </Target>
 </Project>
\ No newline at end of file
diff --git a/NunitReportParser/packages.config b/NunitReportParser/packages.config
index 8a038e619a9975d1d6b0a92ff414d50168876926..8395e35165b040340e715c03a3bfa74c9a6dbc53 100644
--- a/NunitReportParser/packages.config
+++ b/NunitReportParser/packages.config
@@ -1,4 +1,7 @@
 п»ї<?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Newtonsoft.Json" version="12.0.3-beta1" targetFramework="net461" />
+  <package id="NUnit" version="3.12.0" targetFramework="net48" />
+  <package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net48" />
+  <package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net48" />
 </packages>
\ No newline at end of file
diff --git a/TestASTParser/Tests.cs b/TestASTParser/Tests.cs
index e5a67a2d471dc7735e0f61864402026de83c9415..21a2d837c8cb4e87224f1aea7b18e2d01059bb8d 100644
--- a/TestASTParser/Tests.cs
+++ b/TestASTParser/Tests.cs
@@ -58,7 +58,9 @@ namespace TestASTParser
         {
             var tree = ASTParserTests.Parse("begin repeat a:=2 until 2 end");
             Assert.AreEqual("ProgramTree.RepeatNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]);
-            // TODO: проверить узлы содержимого repeat
+            Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["$type"]);
+            Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Expr"]["Num"]).Trim());
+
         }
     }
     
@@ -71,12 +73,12 @@ namespace TestASTParser
         {
             var tree = ASTParserTests.Parse("begin for i:=2 to 10 do a:=2 end");
             Assert.AreEqual("ProgramTree.ForNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]);
-            // TODO: проверить узлы содержимого for
+            Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Assign"]["Expr"]["Num"]).Trim());
         }
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class WriteTests
     {
         
@@ -85,7 +87,7 @@ namespace TestASTParser
         {
             var tree = ASTParserTests.Parse("begin write(2) end");
             Assert.AreEqual("ProgramTree.WriteNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]);
-            // TODO: проверить содержимое write
+            Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Expr"]["Num"]).Trim());
         }
     }
     
@@ -94,26 +96,42 @@ namespace TestASTParser
     {
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestIf()
         {
-            Assert.Fail();
-            // TODO: дописать тест
+            var tree = ASTParserTests.Parse("begin if 2 then a:=12; if 5 then b:=666 else b:=777 end");
+            Assert.AreEqual("ProgramTree.IfNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]);
+            Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["$type"]);
+
+            Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Expr"]["Num"]).Trim());
+            Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][0]["IfStat"]["$type"]);
+
         }
-        
+
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestVarDef()
         {
-            Assert.Fail();
-            // TODO: дописать тест
+            var tree = ASTParserTests.Parse(@"begin var a,b,c end");
+            Assert.AreEqual("ProgramTree.VarNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]);
+            Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["IDList"]["$values"][0]["$type"]);
+            
+            Assert.AreEqual("a", (string)tree["StList"]["$values"][0]["IDList"]["$values"][0]["Name"]);
+            Assert.AreEqual("b", (string)tree["StList"]["$values"][0]["IDList"]["$values"][1]["Name"]);
+
         }
-        
+
         [Test]
         public void TestBinary()
         {
-            Assert.Fail();
-            // TODO: дописать тест
+            var tree = ASTParserTests.Parse("begin x:=y*z+1/(1-y) end");
+           
+            Assert.AreEqual("ProgramTree.BinNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["Right"]["$type"]);
+            Assert.AreEqual("1", ((string)tree["StList"]["$values"][0]["Expr"]["Right"]["Left"]["Num"]).Trim());
+            Assert.AreEqual(ProgramTree.BinOpType.SUB, ((ProgramTree.BinOpType)(int)tree["StList"]["$values"][0]["Expr"]["Right"]["Right"]["Operation"]));
+            Assert.AreEqual("1", ((string)tree["StList"]["$values"][0]["Expr"]["Right"]["Right"]["Left"]["Num"]).Trim());
+            Assert.AreEqual("y", ((string)tree["StList"]["$values"][0]["Expr"]["Right"]["Right"]["Right"]["Name"]).Trim());
+
         }
     }
 }
\ No newline at end of file
diff --git a/TestCodeGenerator/Tests.cs b/TestCodeGenerator/Tests.cs
index c8f33a03382f00a4a89fa590b3f75048a1b46a72..cb30d77ab6fddbb3fdb264e1fcc61794c22abc30 100644
--- a/TestCodeGenerator/Tests.cs
+++ b/TestCodeGenerator/Tests.cs
@@ -79,7 +79,7 @@ namespace TestCodeGenerator
         public void TestIf()
         {
             Assert.AreEqual("3", TestHelper.GenerateNRun(@"begin var a1; a1 := 0; if a1 then write(2) else write(3) end"));
-            
+
             Assert.AreEqual("3", TestHelper.GenerateNRun(@"begin var x,y; x := 1; y := x-1; if x then if y then write(2) else write(3) end"));
         }
         
diff --git a/TestDescentParser/Tests.cs b/TestDescentParser/Tests.cs
index 2d3de166342e860cdab066c290870eeded581a44..e523ebdcfd052b9918adee764cc2c2a39fc22587 100644
--- a/TestDescentParser/Tests.cs
+++ b/TestDescentParser/Tests.cs
@@ -26,7 +26,7 @@ namespace TestDescentParser
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestWhile()
         {
             Assert.IsTrue(Parse(@"begin while 5 do a:=2 end"));
@@ -75,7 +75,7 @@ namespace TestDescentParser
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestIf()
         {
             Assert.IsTrue(Parse(@"begin 
@@ -101,7 +101,7 @@ namespace TestDescentParser
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestExpr()
         {
             Assert.IsTrue(Parse(@"begin 
diff --git a/TestGeneratedLexer/Tests.cs b/TestGeneratedLexer/Tests.cs
index 57d7d4cfefec38b435448d0de4ad694d624d177e..1bd6906cd85c36190cfcb4979e0a22a289f8d493 100644
--- a/TestGeneratedLexer/Tests.cs
+++ b/TestGeneratedLexer/Tests.cs
@@ -40,17 +40,17 @@ namespace TestGeneratedLexer
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestString()
         {
             LexerAddon lexer = new LexerAddon(@"3 389 3 'ssfsf ' ");
             lexer.Lex();
-            
-            // TODO: checks in this test
+
+            Assert.AreEqual("'ssfsf '", lexer.apostrophe);
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestSingleLineCmt()
         {
             LexerAddon lexer = new LexerAddon(@"i22d1 5.6  // i 32 id3
@@ -63,7 +63,7 @@ namespace TestGeneratedLexer
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestMultiLineCmt()
         {
             LexerAddon lexer = new LexerAddon(@"i22d1 5.6  { i 32 id3
@@ -76,7 +76,7 @@ namespace TestGeneratedLexer
         }
         
         [Test]
-        [Ignore("This test is disabled")]
+        //[Ignore("This test is disabled")]
         public void TestMultiLineCmtIds()
         {
             LexerAddon lexer = new LexerAddon(@"i22d1 5.6  { i 32 id3
diff --git a/TestLexer/Tests.cs b/TestLexer/Tests.cs
index face58f1981fa5ee196cc514347c9ef013f55c84..81ee1ac23cb5ae6127b84561ca5dde9381f60257 100644
--- a/TestLexer/Tests.cs
+++ b/TestLexer/Tests.cs
@@ -1,5 +1,6 @@
-using Lexer;
+using System;
 using NUnit.Framework;
+using Lexer;
 
 namespace TestLexer
 {
@@ -459,7 +460,7 @@ namespace TestLexer
     }
 
     [TestFixture]
-    // [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestCommentLexer
     {
 
@@ -493,7 +494,7 @@ namespace TestLexer
         }
 
     }
-
+    
     //[Ignore("This test is disabled")]
     [TestFixture]
     public class TestIdChainLexer
@@ -503,35 +504,35 @@ namespace TestLexer
         {
             IdentChainLexer l = new IdentChainLexer("Id1");
             Assert.IsTrue(l.Parse(), "Не пропускает Id1");
-
+            
             l = new IdentChainLexer("Id1.Id2");
             Assert.IsTrue(l.Parse(), "Не пропускает Id1.Id2");
-
+            
             l = new IdentChainLexer("uUd.k_22.sa3");
             Assert.IsTrue(l.Parse(), "Не пропускает uUd.k_22.sa3");
         }
-
+        
         [Test]
         public void TestIdChainFail()
         {
             IdentChainLexer l = new IdentChainLexer("3Id1");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает 3Id1");
-
+            
             l = new IdentChainLexer(".Id2");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает .Id2");
-
+            
             l = new IdentChainLexer("uUd.");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает uUd.");
-
+            
             l = new IdentChainLexer("uUd.3sa");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает uUd.3sa");
-
+            
             l = new IdentChainLexer("uUd. _sa");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает uUd. _sa");
-
+            
             l = new IdentChainLexer("uUd,sa");
             Assert.Throws<LexerException>(() => { l.Parse(); }, "Пропускает uUd,sa");
-
+            
         }
     }
 }
\ No newline at end of file
diff --git a/TestSimpleLexer/Tests.cs b/TestSimpleLexer/Tests.cs
index 14165974a952d77ad4d72a746988f0904d4bc9e2..ea8d836f583459895bb9791e893d73e14544edd5 100644
--- a/TestSimpleLexer/Tests.cs
+++ b/TestSimpleLexer/Tests.cs
@@ -19,7 +19,7 @@ namespace TestSimpleLexer
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestSimpleLexer
     {
         public static List< KeyValuePair<Tok, string> > getLexerOutput(Lexer l)
@@ -56,7 +56,7 @@ namespace TestSimpleLexer
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestSimpleLexerOps
     {
         [Test]
@@ -126,7 +126,7 @@ namespace TestSimpleLexer
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestSimpleLexerAssigns
     {
         [Test]
@@ -218,7 +218,7 @@ namespace TestSimpleLexer
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestSimpleLexerLineCmt
     {
         [Test]
@@ -280,7 +280,7 @@ namespace TestSimpleLexer
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestSimpleLexerMultLineCmt
     {
         [Test]
diff --git a/TestVisitors/Tests.cs b/TestVisitors/Tests.cs
index a5d43a509bcc0eb6b91f8d6fc8d7853ee67b02f4..67c57473ee1080690515759c06892903de6d1552 100644
--- a/TestVisitors/Tests.cs
+++ b/TestVisitors/Tests.cs
@@ -20,7 +20,7 @@ namespace TestVisitors
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestAvgOpCount: ParserTest
     {
         [Test]
@@ -69,10 +69,37 @@ namespace TestVisitors
             p.root.Visit(avgCounter);
             Assert.AreEqual(4, avgCounter.MidCount());            
         }
+
+        [Test]
+        public void TwoLoopsWithWriteTest()
+        {
+            Parser p = Parse(@"begin
+       var c;
+       b := 2;
+       c := 3;
+       c := c * 4 + b;;;
+       cycle 3
+       begin
+         c := c + 1;
+         write(c)
+       end;
+       cycle 3
+       begin
+         d := 2;
+         write(c);
+         write(c);
+         write(c)
+       end
+     end");
+            Assert.IsTrue(p.Parse());
+            var avgCounter = new CountCyclesOpVisitor();
+            p.root.Visit(avgCounter);
+            Assert.AreEqual(3, avgCounter.MidCount());
+        }
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestCommonVariable: ParserTest
     {
         [Test]
@@ -97,7 +124,7 @@ namespace TestVisitors
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestExprComplexity: ParserTest
     {
         [Test]
@@ -202,7 +229,7 @@ namespace TestVisitors
     }
     
     [TestFixture]
-    [Ignore("This test is disabled")]
+    //[Ignore("This test is disabled")]
     public class TestIfCycleNest: ParserTest
     {
         [Test]