From 3cfe91e3e38f72de99adb84fa957582639ca6ba8 Mon Sep 17 00:00:00 2001
From: AntonBagliy <taccessviolation@gmail.com>
Date: Thu, 21 Sep 2017 21:10:16 +0300
Subject: [PATCH] ADD: all materials for modules 1-8

---
 Module3/GPLexProject/Lex1.csproj              |   95 +
 Module3/GPLexProject/LexProjects.sln          |   22 +
 Module3/GPLexProject/ScannerHelper.cs         |    4 +
 Module3/GPLexProject/ShiftReduceParserCode.cs |  944 ++++++++++
 Module3/GPLexProject/SimpleLex.cs             | 1548 +++++++++++++++++
 Module3/GPLexProject/SimpleLex.lex            |   84 +
 Module3/GPLexProject/a.txt                    |    3 +
 Module3/GPLexProject/generateScanner.bat      |    1 +
 Module3/GPLexProject/mymain.cs                |   32 +
 Module5/SimpleLanguage0/Main.cs               |   45 +
 Module5/SimpleLanguage0/ParserHelper.cs       |   19 +
 .../Properties/AssemblyInfo.cs                |   36 +
 .../SimpleLanguage0/ShiftReduceParserCode.cs  |  944 ++++++++++
 Module5/SimpleLanguage0/SimpleLang.csproj     |   61 +
 Module5/SimpleLanguage0/SimpleLang.sln        |   20 +
 Module5/SimpleLanguage0/SimpleLex.cs          | 1485 ++++++++++++++++
 Module5/SimpleLanguage0/SimpleLex.lex         |   74 +
 Module5/SimpleLanguage0/SimpleYacc.cs         |  112 ++
 Module5/SimpleLanguage0/SimpleYacc.lst        |   64 +
 Module5/SimpleLanguage0/SimpleYacc.y          |   42 +
 Module5/SimpleLanguage0/a.txt                 |   10 +
 .../SimpleLanguage0/generateParserScanner.bat |    3 +
 Module6/SimpleLanguage1/Main.cs               |   50 +
 Module6/SimpleLanguage1/ParserHelper.cs       |   18 +
 Module6/SimpleLanguage1/ProgramTree.cs        |   68 +
 .../Properties/AssemblyInfo.cs                |   36 +
 .../SimpleLanguage1/ShiftReduceParserCode.cs  |  944 ++++++++++
 Module6/SimpleLanguage1/SimpleLang1.csproj    |   62 +
 Module6/SimpleLanguage1/SimpleLang1.sln       |   22 +
 Module6/SimpleLanguage1/SimpleLex.cs          | 1489 ++++++++++++++++
 Module6/SimpleLanguage1/SimpleLex.lex         |   78 +
 Module6/SimpleLanguage1/SimpleYacc.cs         |  166 ++
 Module6/SimpleLanguage1/SimpleYacc.y          |   70 +
 Module6/SimpleLanguage1/a.txt                 |   10 +
 .../SimpleLanguage1/generateParserScanner.bat |    3 +
 Module7/SimpleLanguage2/Main.cs               |   56 +
 Module7/SimpleLanguage2/ParserHelper.cs       |   33 +
 Module7/SimpleLanguage2/ProgramTree.cs        |  145 ++
 .../Properties/AssemblyInfo.cs                |   36 +
 .../SimpleLanguage2/ShiftReduceParserCode.cs  |  944 ++++++++++
 Module7/SimpleLanguage2/SimpleLang2.csproj    |   66 +
 Module7/SimpleLanguage2/SimpleLang2.sln       |   22 +
 Module7/SimpleLanguage2/SimpleLex.cs          | 1531 ++++++++++++++++
 Module7/SimpleLanguage2/SimpleLex.lex         |   90 +
 Module7/SimpleLanguage2/SimpleYacc.cs         |  274 +++
 Module7/SimpleLanguage2/SimpleYacc.lst        |  139 ++
 Module7/SimpleLanguage2/SimpleYacc.y          |  119 ++
 .../Visitors/AssignCountVisitor.cs            |   23 +
 .../SimpleLanguage2/Visitors/AutoVisitor.cs   |   45 +
 .../Visitors/PrettyPrintVisitor.cs            |   88 +
 Module7/SimpleLanguage2/Visitors/Visitor.cs   |   21 +
 Module7/SimpleLanguage2/a.txt                 |   11 +
 .../SimpleLanguage2/generateParserScanner.bat |    3 +
 Module8/SimpleLanguage3/Main.cs               |   65 +
 Module8/SimpleLanguage3/ParserHelper.cs       |   33 +
 Module8/SimpleLanguage3/ProgramTree.cs        |  145 ++
 .../Properties/AssemblyInfo.cs                |   36 +
 .../SimpleLanguage3/ShiftReduceParserCode.cs  |  944 ++++++++++
 Module8/SimpleLanguage3/SimpleLang3.csproj    |   68 +
 Module8/SimpleLanguage3/SimpleLang3.sln       |   22 +
 Module8/SimpleLanguage3/SimpleLex.cs          | 1531 ++++++++++++++++
 Module8/SimpleLanguage3/SimpleLex.lex         |   90 +
 Module8/SimpleLanguage3/SimpleYacc.cs         |  274 +++
 Module8/SimpleLanguage3/SimpleYacc.lst        |  139 ++
 Module8/SimpleLanguage3/SimpleYacc.y          |  119 ++
 .../Visitors/AssignCountVisitor.cs            |   23 +
 .../SimpleLanguage3/Visitors/AutoVisitor.cs   |   45 +
 .../GenCodeVisitors/GenCodeCreator.cs         |  104 ++
 .../GenCodeVisitors/GenCodeVisitor.cs         |  113 ++
 .../Visitors/PrettyPrintVisitor.cs            |   88 +
 Module8/SimpleLanguage3/Visitors/Visitor.cs   |   21 +
 Module8/SimpleLanguage3/a.txt                 |   11 +
 .../SimpleLanguage3/generateParserScanner.bat |    3 +
 73 files changed, 16184 insertions(+)
 create mode 100644 Module3/GPLexProject/Lex1.csproj
 create mode 100644 Module3/GPLexProject/LexProjects.sln
 create mode 100644 Module3/GPLexProject/ScannerHelper.cs
 create mode 100644 Module3/GPLexProject/ShiftReduceParserCode.cs
 create mode 100644 Module3/GPLexProject/SimpleLex.cs
 create mode 100644 Module3/GPLexProject/SimpleLex.lex
 create mode 100644 Module3/GPLexProject/a.txt
 create mode 100644 Module3/GPLexProject/generateScanner.bat
 create mode 100644 Module3/GPLexProject/mymain.cs
 create mode 100644 Module5/SimpleLanguage0/Main.cs
 create mode 100644 Module5/SimpleLanguage0/ParserHelper.cs
 create mode 100644 Module5/SimpleLanguage0/Properties/AssemblyInfo.cs
 create mode 100644 Module5/SimpleLanguage0/ShiftReduceParserCode.cs
 create mode 100644 Module5/SimpleLanguage0/SimpleLang.csproj
 create mode 100644 Module5/SimpleLanguage0/SimpleLang.sln
 create mode 100644 Module5/SimpleLanguage0/SimpleLex.cs
 create mode 100644 Module5/SimpleLanguage0/SimpleLex.lex
 create mode 100644 Module5/SimpleLanguage0/SimpleYacc.cs
 create mode 100644 Module5/SimpleLanguage0/SimpleYacc.lst
 create mode 100644 Module5/SimpleLanguage0/SimpleYacc.y
 create mode 100644 Module5/SimpleLanguage0/a.txt
 create mode 100644 Module5/SimpleLanguage0/generateParserScanner.bat
 create mode 100644 Module6/SimpleLanguage1/Main.cs
 create mode 100644 Module6/SimpleLanguage1/ParserHelper.cs
 create mode 100644 Module6/SimpleLanguage1/ProgramTree.cs
 create mode 100644 Module6/SimpleLanguage1/Properties/AssemblyInfo.cs
 create mode 100644 Module6/SimpleLanguage1/ShiftReduceParserCode.cs
 create mode 100644 Module6/SimpleLanguage1/SimpleLang1.csproj
 create mode 100644 Module6/SimpleLanguage1/SimpleLang1.sln
 create mode 100644 Module6/SimpleLanguage1/SimpleLex.cs
 create mode 100644 Module6/SimpleLanguage1/SimpleLex.lex
 create mode 100644 Module6/SimpleLanguage1/SimpleYacc.cs
 create mode 100644 Module6/SimpleLanguage1/SimpleYacc.y
 create mode 100644 Module6/SimpleLanguage1/a.txt
 create mode 100644 Module6/SimpleLanguage1/generateParserScanner.bat
 create mode 100644 Module7/SimpleLanguage2/Main.cs
 create mode 100644 Module7/SimpleLanguage2/ParserHelper.cs
 create mode 100644 Module7/SimpleLanguage2/ProgramTree.cs
 create mode 100644 Module7/SimpleLanguage2/Properties/AssemblyInfo.cs
 create mode 100644 Module7/SimpleLanguage2/ShiftReduceParserCode.cs
 create mode 100644 Module7/SimpleLanguage2/SimpleLang2.csproj
 create mode 100644 Module7/SimpleLanguage2/SimpleLang2.sln
 create mode 100644 Module7/SimpleLanguage2/SimpleLex.cs
 create mode 100644 Module7/SimpleLanguage2/SimpleLex.lex
 create mode 100644 Module7/SimpleLanguage2/SimpleYacc.cs
 create mode 100644 Module7/SimpleLanguage2/SimpleYacc.lst
 create mode 100644 Module7/SimpleLanguage2/SimpleYacc.y
 create mode 100644 Module7/SimpleLanguage2/Visitors/AssignCountVisitor.cs
 create mode 100644 Module7/SimpleLanguage2/Visitors/AutoVisitor.cs
 create mode 100644 Module7/SimpleLanguage2/Visitors/PrettyPrintVisitor.cs
 create mode 100644 Module7/SimpleLanguage2/Visitors/Visitor.cs
 create mode 100644 Module7/SimpleLanguage2/a.txt
 create mode 100644 Module7/SimpleLanguage2/generateParserScanner.bat
 create mode 100644 Module8/SimpleLanguage3/Main.cs
 create mode 100644 Module8/SimpleLanguage3/ParserHelper.cs
 create mode 100644 Module8/SimpleLanguage3/ProgramTree.cs
 create mode 100644 Module8/SimpleLanguage3/Properties/AssemblyInfo.cs
 create mode 100644 Module8/SimpleLanguage3/ShiftReduceParserCode.cs
 create mode 100644 Module8/SimpleLanguage3/SimpleLang3.csproj
 create mode 100644 Module8/SimpleLanguage3/SimpleLang3.sln
 create mode 100644 Module8/SimpleLanguage3/SimpleLex.cs
 create mode 100644 Module8/SimpleLanguage3/SimpleLex.lex
 create mode 100644 Module8/SimpleLanguage3/SimpleYacc.cs
 create mode 100644 Module8/SimpleLanguage3/SimpleYacc.lst
 create mode 100644 Module8/SimpleLanguage3/SimpleYacc.y
 create mode 100644 Module8/SimpleLanguage3/Visitors/AssignCountVisitor.cs
 create mode 100644 Module8/SimpleLanguage3/Visitors/AutoVisitor.cs
 create mode 100644 Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeCreator.cs
 create mode 100644 Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeVisitor.cs
 create mode 100644 Module8/SimpleLanguage3/Visitors/PrettyPrintVisitor.cs
 create mode 100644 Module8/SimpleLanguage3/Visitors/Visitor.cs
 create mode 100644 Module8/SimpleLanguage3/a.txt
 create mode 100644 Module8/SimpleLanguage3/generateParserScanner.bat

diff --git a/Module3/GPLexProject/Lex1.csproj b/Module3/GPLexProject/Lex1.csproj
new file mode 100644
index 0000000..208f5f9
--- /dev/null
+++ b/Module3/GPLexProject/Lex1.csproj
@@ -0,0 +1,95 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <NoStandardLibraries>false</NoStandardLibraries>
+    <AssemblyName>sss</AssemblyName>
+    <RootNamespace>sss</RootNamespace>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <PublishUrl>http://localhost/sss/</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Web</InstallFrom>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>.\bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>.\bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ScannerHelper.cs" />
+    <Compile Include="SimpleLex.cs" />
+    <Compile Include="mymain.cs" />
+    <Compile Include="ShiftReduceParserCode.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>Клиентский профиль .NET Framework 3.5 с пакетом обновления 1 %28SP1%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="SimpleLex.lex" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+  <ProjectExtensions>
+    <VisualStudio AllowExistingFolder="true" />
+  </ProjectExtensions>
+  <PropertyGroup>
+    <PreBuildEvent>dir</PreBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/Module3/GPLexProject/LexProjects.sln b/Module3/GPLexProject/LexProjects.sln
new file mode 100644
index 0000000..c1a2272
--- /dev/null
+++ b/Module3/GPLexProject/LexProjects.sln
@@ -0,0 +1,22 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lex1", "Lex1.csproj", "{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4DD13462-DCB4-4C3E-B777-7FEA90CEA9D1}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Module3/GPLexProject/ScannerHelper.cs b/Module3/GPLexProject/ScannerHelper.cs
new file mode 100644
index 0000000..37f5895
--- /dev/null
+++ b/Module3/GPLexProject/ScannerHelper.cs
@@ -0,0 +1,4 @@
+п»їnamespace ScannerHelper
+{
+    public enum Tok { EOF = 0, ID, INUM, RNUM, COLON, SEMICOLON, ASSIGN, BEGIN, END, CYCLE };
+}
\ No newline at end of file
diff --git a/Module3/GPLexProject/ShiftReduceParserCode.cs b/Module3/GPLexProject/ShiftReduceParserCode.cs
new file mode 100644
index 0000000..c110ba1
--- /dev/null
+++ b/Module3/GPLexProject/ShiftReduceParserCode.cs
@@ -0,0 +1,944 @@
+// Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2009
+// (see accompanying GPPGcopyright.rtf)
+#define EXPORT_GPPG
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+namespace QUT.Gppg
+{
+    /// <summary>
+    /// Abstract class for GPPG shift-reduce parsers.
+    /// Parsers generated by GPPG derive from this base
+    /// class, overriding the abstract Initialize() and
+    /// DoAction() methods.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type</typeparam>
+    /// <typeparam name="TSpan">Location type</typeparam>
+#if EXPORT_GPPG
+    public abstract class ShiftReduceParser<TValue, TSpan>
+#else
+    internal abstract class ShiftReduceParser<TValue, TSpan>
+#endif
+ where TSpan : IMerge<TSpan>, new()
+    {
+        public AbstractScanner<TValue, TSpan> scanner;
+        /// <summary>
+        /// The abstract scanner for this parser.
+        /// </summary>
+        protected AbstractScanner<TValue, TSpan> Scanner {
+            get { return scanner; }
+            set { scanner = value; }
+        }
+
+        /// <summary>
+        /// Constructor for base class
+        /// </summary>
+        /// <param name="scanner">Scanner instance for this parser</param>
+        protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
+        {
+            this.scanner = scanner;
+        }
+
+        // ==============================================================
+        //                    TECHNICAL EXPLANATION.
+        //   Why the next two fields are not exposed via properties.
+        // ==============================================================
+        // These fields are of the generic parameter types, and are
+        // frequently instantiated as struct types in derived classes.
+        // Semantic actions are defined in the derived classes and refer
+        // to instance fields of these structs.  Is such cases the code
+        // "get_CurrentSemanticValue().myField = blah;" will fail since
+        // the getter pushes the value of the field, not the reference.
+        // So, in the presence of properties, gppg would need to encode
+        // such field accesses as ... 
+        //  "tmp = get_CurrentSemanticValue(); // Fetch value
+        //   tmp.myField = blah;               // update
+        //   set_CurrentSemanticValue(tmp); "  // Write update back.
+        // There is no issue if TValue is restricted to be a ref type.
+        // The same explanation applies to scanner.yylval.
+        // ==============================================================
+        /// <summary>
+        /// The current value of the "$$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TValue CurrentSemanticValue;
+
+        /// <summary>
+        /// The current value of the "@$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TSpan CurrentLocationSpan;
+
+        private TSpan LastSpan;
+        private int NextToken;
+        private State FsaState;
+        private bool recovering;
+        private int tokensSinceLastError;
+
+        private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
+        private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
+        private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
+
+        /// <summary>
+        /// The stack of semantic value (YYSTYPE) values.
+        /// </summary>
+        protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
+
+        /// <summary>
+        /// The stack of location value (YYLTYPE) varlues.
+        /// </summary>
+        protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
+
+        private int errorToken;
+        private int endOfFileToken;
+        private string[] nonTerminals;
+        private State[] states;
+        private Rule[] rules;
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the rule list into this base class.
+        /// </summary>
+        /// <param name="rules">The array of Rule objects</param>
+        protected void InitRules(Rule[] rules) { this.rules = rules; }
+
+      /// <summary>
+      /// Initialization method to allow derived classes to
+      /// insert the states table into this base class.
+      /// </summary>
+      /// <param name="states">The pre-initialized states table</param>
+        protected void InitStates(State[] states) { this.states = states; }
+
+      /// <summary>
+      /// OBSOLETE FOR VERSION 1.4.0
+      /// </summary>
+      /// <param name="size"></param>
+        protected void InitStateTable(int size) { states = new State[size]; }
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the special value for the error and EOF tokens.
+        /// </summary>
+        /// <param name="err">The error state ordinal</param>
+        /// <param name="end">The EOF stat ordinal</param>
+        protected void InitSpecialTokens(int err, int end)
+        {
+            errorToken = err;
+            endOfFileToken = end;
+        }
+
+        /// <summary>
+        /// Initialization method to allow derived classes to
+        /// insert the non-terminal symbol names into this base class.
+        /// </summary>
+        /// <param name="names">Non-terminal symbol names</param>
+        protected void InitNonTerminals(string[] names) { nonTerminals = names; }
+
+        #region YYAbort, YYAccept etcetera.
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AcceptException : Exception
+        {
+            internal AcceptException() { }
+            protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AbortException : Exception
+        {
+            internal AbortException() { }
+            protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class ErrorException : Exception
+        {
+            internal ErrorException() { }
+            protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+
+        // The following methods are only called from within
+        // a semantic action. The thrown exceptions can never
+        // propagate outside the ShiftReduceParser class in 
+        // which they are nested.
+
+        /// <summary>
+        /// Force parser to terminate, returning "true"
+        /// </summary>
+        protected static void YYAccept() { throw new AcceptException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning "false"
+        /// </summary>
+        protected static void YYAbort() { throw new AbortException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning
+        /// "false" if error recovery fails.
+        /// </summary>
+        protected static void YYError() { throw new ErrorException(); }
+
+        /// <summary>
+        /// Check if parser in error recovery state.
+        /// </summary>
+        protected bool YYRecovering { get { return recovering; } }
+        #endregion
+
+        /// <summary>
+        /// Abstract base method. ShiftReduceParser calls this
+        /// to initialize the base class data structures.  Concrete
+        /// parser classes must override this method.
+        /// </summary>
+        protected abstract void Initialize();
+
+        /// <summary>
+        /// Main entry point of the Shift-Reduce Parser.
+        /// </summary>
+        /// <returns>True if parse succeeds, else false for
+        /// unrecoverable errors</returns>
+        public bool Parse()
+        {
+            Initialize();	// allow derived classes to instantiate rules, states and nonTerminals
+
+            NextToken = 0;
+            FsaState = states[0];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+
+            while (true)
+            {
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+                int action = FsaState.defaultAction;
+
+                if (FsaState.ParserTable != null)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif
+                        // We save the last token span, so that the location span
+                        // of production right hand sides that begin or end with a
+                        // nullable production will be correct.
+                        LastSpan = scanner.yylloc;
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+                }
+
+                if (action > 0)         // shift
+                {
+                    Shift(action);
+                }
+                else if (action < 0)   // reduce
+                {
+                    try
+                    {
+                        Reduce(-action);
+                        if (action == -1)	// accept
+                            return true;
+                    }
+                    catch (Exception x)
+                    {
+                        if (x is AbortException)
+                            return false;
+                        else if (x is AcceptException)
+                            return true;
+                        else if (x is ErrorException && !ErrorRecovery())
+                            return false;
+                        else
+                            throw;  // Rethrow x, preserving information.
+
+                    }
+                }
+                else if (action == 0)   // error
+                    if (!ErrorRecovery())
+                        return false;
+            }
+        }
+
+        private void Shift(int stateIndex)
+        {
+#if TRACE_ACTIONS
+				Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
+#endif
+            FsaState = states[stateIndex];
+
+            valueStack.Push(scanner.yylval);
+            StateStack.Push(FsaState);
+            LocationStack.Push(scanner.yylloc);
+
+            if (recovering)
+            {
+                if (NextToken != errorToken)
+                    tokensSinceLastError++;
+
+                if (tokensSinceLastError > 5)
+                    recovering = false;
+            }
+
+            if (NextToken != endOfFileToken)
+                NextToken = 0;
+        }
+
+        private void Reduce(int ruleNumber)
+        {
+#if TRACE_ACTIONS
+				DisplayRule(ruleNumber);
+#endif
+            Rule rule = rules[ruleNumber];
+            //
+            //  Default actions for unit productions.
+            //
+            if (rule.RightHandSide.Length == 1)
+            {
+                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
+                CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
+            }
+            else
+            {
+                if (rule.RightHandSide.Length == 0)
+                {
+                    // Create a new blank value.
+                    // Explicit semantic action may mutate this value
+                    CurrentSemanticValue = default(TValue);
+                    // The location span for an empty production will start with the
+                    // beginning of the next lexeme, and end with the finish of the
+                    // previous lexeme.  This gives the correct behaviour when this
+                    // nonsense value is used in later Merge operations.
+                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
+                        scanner.yylloc.Merge(LastSpan) :
+                        default(TSpan));
+                }
+                else
+                {
+                    // Default action: $$ = $1;
+                    CurrentSemanticValue = valueStack.TopElement();
+                    //  Default action "@$ = @1.Merge(@N)" for location info.
+                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
+                    TSpan atN = LocationStack[LocationStack.Depth - 1];
+                    CurrentLocationSpan = 
+                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
+                }
+            }
+
+            DoAction(ruleNumber);
+
+            for (int i = 0; i < rule.RightHandSide.Length; i++)
+            {
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+            }
+
+#if TRACE_ACTIONS
+				DisplayStack();
+#endif
+            FsaState = StateStack.TopElement();
+
+            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
+                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+        }
+
+        /// <summary>
+        /// Execute the selected action from array.
+        /// Must be overriden in derived classes.
+        /// </summary>
+        /// <param name="actionNumber">Index of the action to perform</param>
+        protected abstract void DoAction(int actionNumber);
+
+        private bool ErrorRecovery()
+        {
+            bool discard;
+
+            if (!recovering) // if not recovering from previous error
+                ReportError();
+
+            if (!FindErrorRecoveryState())
+                return false;
+            //
+            //  The interim fix for the "looping in error recovery"
+            //  artifact involved moving the setting of the recovering 
+            //  bool until after invalid tokens have been discarded.
+            //
+            ShiftErrorToken();
+            discard = DiscardInvalidTokens();
+            recovering = true;
+            tokensSinceLastError = 0;
+            return discard;
+        }
+
+        private void ReportError1()
+        {
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
+
+            if (FsaState.ParserTable.Count < 7)
+            {
+                bool first = true;
+                foreach (int terminal in FsaState.ParserTable.Keys)
+                {
+                    if (first)
+                        errorMsg.Append(", expecting ");
+                    else
+                        errorMsg.Append(", or ");
+
+                    errorMsg.Append(TerminalToString(terminal));
+                    first = false;
+                }
+            }
+            scanner.yyerror(errorMsg.ToString());
+        }
+
+        private void ReportError()
+        {
+            object[] args = new object[FsaState.ParserTable.Keys.Count+1];
+            args[0] = TerminalToString(NextToken);
+            int i=1;
+            foreach (int terminal in FsaState.ParserTable.Keys)
+            {
+                args[i] = TerminalToString(terminal);
+                i++;
+            }
+            scanner.yyerror("",args);
+        }
+
+        private void ShiftErrorToken()
+        {
+            int old_next = NextToken;
+            NextToken = errorToken;
+
+            Shift(FsaState.ParserTable[NextToken]);
+
+#if TRACE_ACTIONS
+				Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+            NextToken = old_next;
+        }
+
+        private bool FindErrorRecoveryState()
+        {
+            while (true)    // pop states until one found that accepts error token
+            {
+                if (FsaState.ParserTable != null &&
+                    FsaState.ParserTable.ContainsKey(errorToken) &&
+                    FsaState.ParserTable[errorToken] > 0) // shift
+                    return true;
+
+#if TRACE_ACTIONS
+					Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
+#endif
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+
+#if TRACE_ACTIONS
+					DisplayStack();
+#endif
+                if (StateStack.IsEmpty())
+                {
+#if TRACE_ACTIONS
+                        Console.Error.Write("Aborting: didn't find a state that accepts error token");
+#endif
+                    return false;
+                }
+                else
+                    FsaState = StateStack.TopElement();
+            }
+        }
+
+        private bool DiscardInvalidTokens()
+        {
+
+            int action = FsaState.defaultAction;
+
+            if (FsaState.ParserTable != null)
+            {
+                // Discard tokens until find one that works ...
+                while (true)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif                       
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (NextToken == endOfFileToken)
+                        return false;
+
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+
+                    if (action != 0)
+                        return true;
+                    else
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
+#endif
+                        NextToken = 0;
+                    }
+                }
+            }
+            else if (recovering && tokensSinceLastError == 0)
+            {
+                // 
+                //  Boolean recovering is not set until after the first
+                //  error token has been shifted.  Thus if we get back 
+                //  here with recovering set and no tokens read we are
+                //  looping on the same error recovery action.  This 
+                //  happens if current_state.ParserTable is null because
+                //  the state has an LR(0) reduction, but not all
+                //  lookahead tokens are valid.  This only occurs for
+                //  error productions that *end* on "error".
+                //
+                //  This action discards tokens one at a time until
+                //  the looping stops.  Another attack would be to always
+                //  use the LALR(1) table if a production ends on "error"
+                //
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
+#endif
+                if (NextToken == endOfFileToken)
+                    return false;
+                NextToken = 0;
+                return true;
+            }
+            else
+                return true;
+
+        }
+
+        /// <summary>
+        /// Traditional YACC method.  Discards the next input token.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyclearin() { NextToken = 0; }
+
+        /// <summary>
+        /// Tradional YACC method. Clear the "recovering" flag.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyerrok()
+        {
+            recovering = false;
+        }
+
+        /// <summary>
+        /// OBSOLETE FOR VERSION 1.4.0
+        /// Method used by derived types to insert new
+        /// state instances in the "states" array.
+        /// </summary>
+        /// <param name="stateNumber">index of the state</param>
+        /// <param name="state">data for the state</param>
+        protected void AddState(int stateNumber, State state)
+        {
+            states[stateNumber] = state;
+            state.number = stateNumber;
+        }
+
+        private void DisplayStack()
+        {
+            Console.Error.Write("State now");
+            for (int i = 0; i < StateStack.Depth; i++)
+                Console.Error.Write(" {0}", StateStack[i].number);
+            Console.Error.WriteLine();
+        }
+
+        private void DisplayRule(int ruleNumber)
+        {
+            Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
+            DisplayProduction(rules[ruleNumber]);
+        }
+
+        private void DisplayProduction(Rule rule)
+        {
+            if (rule.RightHandSide.Length == 0)
+                Console.Error.Write("/* empty */ ");
+            else
+                foreach (int symbol in rule.RightHandSide)
+                    Console.Error.Write("{0} ", SymbolToString(symbol));
+
+            Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
+        }
+
+        /// <summary>
+        /// Abstract state class naming terminal symbols.
+        /// This is overridden by derived classes with the
+        /// name (or alias) to be used in error messages.
+        /// </summary>
+        /// <param name="terminal">The terminal ordinal</param>
+        /// <returns></returns>
+        protected abstract string TerminalToString(int terminal);
+
+        private string SymbolToString(int symbol)
+        {
+            if (symbol < 0)
+                return nonTerminals[-symbol];
+            else
+                return TerminalToString(symbol);
+        }
+
+        /// <summary>
+        /// Return text representation of argument character
+        /// </summary>
+        /// <param name="input">The character to convert</param>
+        /// <returns>String representation of the character</returns>
+        protected static string CharToString(char input)
+        {
+            switch (input)
+            {
+                case '\a': return @"'\a'";
+                case '\b': return @"'\b'";
+                case '\f': return @"'\f'";
+                case '\n': return @"'\n'";
+                case '\r': return @"'\r'";
+                case '\t': return @"'\t'";
+                case '\v': return @"'\v'";
+                case '\0': return @"'\0'";
+                default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Classes implementing this interface must supply a
+    /// method that merges two location objects to return
+    /// a new object of the same type.
+    /// GPPG-generated parsers have the default location
+    /// action equivalent to "@$ = @1.Merge(@N);" where N
+    /// is the right-hand-side length of the production.
+    /// </summary>
+    /// <typeparam name="TSpan">The Location type</typeparam>
+#if EXPORT_GPPG
+    public interface IMerge<TSpan>
+#else
+    internal interface IMerge<TSpan>
+#endif
+    {
+        /// <summary>
+        /// Interface method that creates a location object from
+        /// the current and last object.  Typically used to create
+        /// a location object extending from the start of the @1
+        /// object to the end of the @N object.
+        /// </summary>
+        /// <param name="last">The lexically last object to merge</param>
+        /// <returns>The merged location object</returns>
+        TSpan Merge(TSpan last);
+    }
+
+    /// <summary>
+    /// This is the default class that carries location
+    /// information from the scanner to the parser.
+    /// If you don't declare "%YYLTYPE Foo" the parser
+    /// will expect to deal with this type.
+    /// </summary>
+#if EXPORT_GPPG
+    public class LexLocation : IMerge<LexLocation>
+#else
+    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
+    internal class LexLocation : IMerge<LexLocation>
+#endif
+    {
+        private int startLine;   // start line
+        private int startColumn; // start column
+        private int endLine;     // end line
+        private int endColumn;   // end column
+
+        /// <summary>
+        /// The line at which the text span starts.
+        /// </summary>
+        public int StartLine { get { return startLine; } }
+
+        /// <summary>
+        /// The column at which the text span starts.
+        /// </summary>
+        public int StartColumn { get { return startColumn; } }
+
+        /// <summary>
+        /// The line on which the text span ends.
+        /// </summary>
+        public int EndLine { get { return endLine; } }
+
+        /// <summary>
+        /// The column of the first character
+        /// beyond the end of the text span.
+        /// </summary>
+        public int EndColumn { get { return endColumn; } }
+
+        /// <summary>
+        /// Default no-arg constructor.
+        /// </summary>
+        public LexLocation()
+        { }
+
+        /// <summary>
+        /// Constructor for text-span with given start and end.
+        /// </summary>
+        /// <param name="sl">start line</param>
+        /// <param name="sc">start column</param>
+        /// <param name="el">end line </param>
+        /// <param name="ec">end column</param>
+        public LexLocation(int sl, int sc, int el, int ec)
+        { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
+
+        /// <summary>
+        /// Create a text location which spans from the 
+        /// start of "this" to the end of the argument "last"
+        /// </summary>
+        /// <param name="last">The last location in the result span</param>
+        /// <returns>The merged span</returns>
+        public LexLocation Merge(LexLocation last)
+        { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
+
+    }
+
+    /// <summary>
+    /// Abstract scanner class that GPPG expects its scanners to 
+    /// extend.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
+    /// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
+#if EXPORT_GPPG
+    public abstract class AbstractScanner<TValue, TSpan>
+#else
+    internal abstract class AbstractScanner<TValue, TSpan>
+#endif
+        where TSpan : IMerge<TSpan>
+    {
+        /// <summary>
+        /// Lexical value optionally set by the scanner. The value
+        /// is of the %YYSTYPE type declared in the parser spec.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        // A field must be declared for this value of parametric type,
+        // since it may be instantiated by a value struct.  If it were 
+        // implemented as a property, machine generated code in derived
+        // types would not be able to select on the returned value.
+        public TValue yylval;                     // Lexical value: set by scanner
+
+        /// <summary>
+        /// Current scanner location property. The value is of the
+        /// type declared by %YYLTYPE in the parser specification.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual TSpan yylloc
+        {
+            get { return default(TSpan); }       // Empty implementation allowing
+            set { /* skip */ }                   // yylloc to be ignored entirely.
+        }
+
+        /// <summary>
+        /// Main call point for LEX-like scanners.  Returns an int
+        /// corresponding to the token recognized by the scanner.
+        /// </summary>
+        /// <returns>An int corresponding to the token</returns>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public abstract int yylex();
+
+        /// <summary>
+        /// Traditional error reporting provided by LEX-like scanners
+        /// to their YACC-like clients.
+        /// </summary>
+        /// <param name="format">Message format string</param>
+        /// <param name="args">Optional array of args</param>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual void yyerror(string format, params object[] args) { }
+    }
+
+    /// <summary>
+    /// Encapsulated state for the parser.
+    /// Opaque to users, visible to the tool-generated code.
+    /// </summary>
+#if EXPORT_GPPG
+    public class State
+#else
+    internal class State
+#endif
+    {
+        internal int number;
+        internal Dictionary<int, int> ParserTable;   // Terminal -> ParseAction
+        internal Dictionary<int, int> Goto;          // NonTerminal -> State;
+        internal int defaultAction; // = 0;		     // ParseAction
+
+        /// <summary>
+        /// State transition data for this state. Pairs of elements of the 
+        /// goto array associate symbol ordinals with next state indices.
+        /// The actions array is passed to another constructor. 
+        /// </summary>
+        /// <param name="actions">The action list</param>
+        /// <param name="goToList">Next state data</param>
+        public State(int[] actions, int[] goToList)
+            : this(actions)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+
+        /// <summary>
+        /// Action data for this state. Pairs of elements of the 
+        /// action array associate action ordinals with each of
+        /// those symbols that have actions in the current state.
+        /// </summary>
+        /// <param name="actions">The action array</param>
+        public State(int[] actions)
+        {
+            ParserTable = new Dictionary<int, int>();
+            for (int i = 0; i < actions.Length; i += 2)
+                ParserTable.Add(actions[i], actions[i + 1]);
+        }
+
+        /// <summary>
+        /// Set the default action for this state.
+        /// </summary>
+        /// <param name="defaultAction">Ordinal of the default action</param>
+        public State(int defaultAction)
+        {
+            this.defaultAction = defaultAction;
+        }
+
+        /// <summary>
+        /// Set the default action and the state transition table.
+        /// </summary>
+        /// <param name="defaultAction">The default action</param>
+        /// <param name="goToList">Transitions from this state</param>
+        public State(int defaultAction, int[] goToList)
+            : this(defaultAction)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+    }
+
+    /// <summary>
+    /// Rule representation at runtime.
+    /// </summary>
+#if EXPORT_GPPG
+    public class Rule
+#else
+    internal class Rule
+#endif
+    {
+        internal int LeftHandSide; // symbol
+        internal int[] RightHandSide; // symbols
+
+        /// <summary>
+        /// Rule constructor.  This holds the ordinal of
+        /// the left hand side symbol, and the list of
+        /// right hand side symbols, in lexical order.
+        /// </summary>
+        /// <param name="left">The LHS non-terminal</param>
+        /// <param name="right">The RHS symbols, in lexical order</param>
+        public Rule(int left, int[] right)
+        {
+            this.LeftHandSide = left;
+            this.RightHandSide = right;
+        }
+    }
+
+    /// <summary>
+    /// Stack utility for the shift-reduce parser.
+    /// GPPG parsers have three instances:
+    /// (1) The parser state stack, T = QUT.Gppg.State,
+    /// (2) The semantic value stack, T = TValue,
+    /// (3) The location stack, T = TSpan.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if EXPORT_GPPG
+    public class PushdownPrefixState<T>
+#else
+    internal class PushdownPrefixState<T>
+#endif
+    {
+        //  Note that we cannot use the BCL Stack<T> class
+        //  here as derived types need to index into stacks.
+        //
+        private T[] array = new T[8];
+        private int tos = 0;
+
+        /// <summary>
+        /// Indexer for values of the stack below the top.
+        /// </summary>
+        /// <param name="index">index of the element, starting from the bottom</param>
+        /// <returns>the selected element</returns>
+        public T this[int index] { get { return array[index]; } }
+
+        /// <summary>
+        /// The current depth of the stack.
+        /// </summary>
+        public int Depth { get { return tos; } }
+
+        internal void Push(T value)
+        {
+            if (tos >= array.Length)
+            {
+                T[] newarray = new T[array.Length * 2];
+                System.Array.Copy(array, newarray, tos);
+                array = newarray;
+            }
+            array[tos++] = value;
+        }
+
+        internal T Pop()
+        {
+            T rslt = array[--tos];
+            array[tos] = default(T);
+            return rslt;
+        }
+
+        internal T TopElement() { return array[tos - 1]; }
+
+        internal bool IsEmpty() { return tos == 0; }
+    }
+}
\ No newline at end of file
diff --git a/Module3/GPLexProject/SimpleLex.cs b/Module3/GPLexProject/SimpleLex.cs
new file mode 100644
index 0000000..a5496f5
--- /dev/null
+++ b/Module3/GPLexProject/SimpleLex.cs
@@ -0,0 +1,1548 @@
+//
+//  This CSharp output file generated by Gardens Point LEX
+//  Version:  1.1.3.301
+//  Machine:  HUB
+//  DateTime: 21.09.2017 20:07:39
+//  UserName: someone
+//  GPLEX input file <SimpleLex.lex>
+//  GPLEX frame file <embedded resource>
+//
+//  Option settings: noParser, minimize
+//  Option settings: compressNext, persistBuffer, embedbuffers
+//
+
+//
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
+//
+//
+#define BACKUP
+#define STANDALONE
+#define PERSIST
+#define BYTEMODE
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+using ScannerHelper;
+
+namespace SimpleScanner
+{   
+    /// <summary>
+    /// Summary Canonical example of GPLEX automaton
+    /// </summary>
+    
+#if STANDALONE
+    //
+    // These are the dummy declarations for stand-alone GPLEX applications
+    // normally these declarations would come from the parser.
+    // If you declare /noparser, or %option noparser then you get this.
+    //
+
+     public enum Tokens
+    { 
+      EOF = 0, maxParseToken = int.MaxValue 
+      // must have at least these two, values are almost arbitrary
+    }
+
+     public abstract class ScanBase
+    {
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public abstract int yylex();
+
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
+        protected virtual bool yywrap() { return true; }
+
+#if BABEL
+        protected abstract int CurrentSc { get; set; }
+        // EolState is the 32-bit of state data persisted at 
+        // the end of each line for Visual Studio colorization.  
+        // The default is to return CurrentSc.  You must override
+        // this if you want more complicated behavior.
+        public virtual int EolState { 
+            get { return CurrentSc; }
+            set { CurrentSc = value; } 
+        }
+    }
+    
+     public interface IColorScan
+    {
+        void SetSource(string source, int offset);
+        int GetNext(ref int state, out int start, out int end);
+#endif // BABEL
+    }
+
+#endif // STANDALONE
+    
+    // If the compiler can't find the scanner base class maybe you
+    // need to run GPPG with the /gplex option, or GPLEX with /noparser
+#if BABEL
+     public sealed partial class Scanner : ScanBase, IColorScan
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+        
+        protected override int CurrentSc 
+        {
+             // The current start state is a property
+             // to try to avoid the user error of setting
+             // scState but forgetting to update the FSA
+             // start state "currentStart"
+             //
+             get { return currentScOrd; }  // i.e. return YY_START;
+             set { currentScOrd = value;   // i.e. BEGIN(value);
+                   currentStart = startState[value]; }
+        }
+#else  // BABEL
+     public sealed partial class Scanner : ScanBase
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+#endif // BABEL
+        
+        /// <summary>
+        /// The input buffer for this scanner.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public ScanBuff Buffer { get { return buffer; } }
+        
+        private static int GetMaxParseToken() {
+     System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken");
+            return (f == null ? int.MaxValue : (int)f.GetValue(null));
+        }
+        
+        static int parserMax = GetMaxParseToken();
+        
+        enum Result {accept, noMatch, contextFound};
+
+        const int maxAccept = 20;
+        const int initial = 21;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+
+#region user code
+public int LexValueInt;
+  public double LexValueDouble;
+#endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;      // last code read
+        int cCol;      // column number of code
+        int lNum;      // current line number
+        //
+        // The following instance variables are used, among other
+        // things, for constructing the yylloc location objects.
+        //
+        int tokPos;        // buffer position at start of token
+        int tokCol;        // zero-based column number at start of token
+        int tokLin;        // line number at start of token
+        int tokEPos;       // buffer position at end of token
+        int tokECol;       // column number at end of token
+        int tokELin;       // line number at end of token
+        string tokTxt;     // lazily constructed text of token
+#if STACK          
+        private Stack<int> scStack = new Stack<int>();
+#endif // STACK
+
+#region ScannerTables
+    struct Table {
+        public int min; public int rng; public int dflt;
+        public sbyte[] nxt;
+        public Table(int m, int x, int d, sbyte[] n) {
+            min = m; rng = x; dflt = d; nxt = n;
+        }
+    };
+
+    static int[] startState = new int[] {21, 0};
+
+    static Table[] NxS = new Table[23] {
+/* 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, 
+          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}),
+    };
+
+int NextState() {
+    if (code == ScanBuff.EndOfFile)
+        return eofNum;
+    else
+        unchecked {
+            int rslt;
+            int idx = (byte)(code - NxS[state].min);
+            if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
+            else rslt = NxS[state].nxt[idx];
+            return rslt;
+        }
+}
+
+#endregion
+
+
+#if BACKUP
+        // ==============================================================
+        // == Nested struct used for backup in automata that do backup ==
+        // ==============================================================
+
+        struct Context // class used for automaton backup.
+        {
+            public int bPos;
+            public int rPos; // scanner.readPos saved value
+            public int cCol;
+            public int lNum; // Need this in case of backup over EOL.
+            public int state;
+            public int cChr;
+        }
+        
+        private Context ctx = new Context();
+#endif // BACKUP
+
+        // ==============================================================
+        // ==== Nested struct to support input switching in scanners ====
+        // ==============================================================
+
+		struct BufferContext {
+            internal ScanBuff buffSv;
+			internal int chrSv;
+			internal int cColSv;
+			internal int lNumSv;
+		}
+
+        // ==============================================================
+        // ===== Private methods to save and restore buffer contexts ====
+        // ==============================================================
+
+        /// <summary>
+        /// This method creates a buffer context record from
+        /// the current buffer object, together with some
+        /// scanner state values. 
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        BufferContext MkBuffCtx()
+		{
+			BufferContext rslt;
+			rslt.buffSv = this.buffer;
+			rslt.chrSv = this.code;
+			rslt.cColSv = this.cCol;
+			rslt.lNumSv = this.lNum;
+			return rslt;
+		}
+
+        /// <summary>
+        /// This method restores the buffer value and allied
+        /// scanner state from the given context record value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void RestoreBuffCtx(BufferContext value)
+		{
+			this.buffer = value.buffSv;
+			this.code = value.chrSv;
+			this.cCol = value.cColSv;
+			this.lNum = value.lNumSv;
+        } 
+        // =================== End Nested classes =======================
+
+#if !NOFILES
+     public Scanner(Stream file) {
+            SetSource(file); // no unicode option
+        }
+        
+#endif // !NOFILES
+
+     public Scanner() { }
+
+        private int readPos;
+
+        void GetCode()
+        {
+            if (code == '\n')  // This needs to be fixed for other conventions
+                               // i.e. [\r\n\205\u2028\u2029]
+            { 
+                cCol = -1;
+                lNum++;
+            }
+            readPos = buffer.Pos;
+
+            // Now read new codepoint.
+            code = buffer.Read();
+            if (code > ScanBuff.EndOfFile)
+            {
+#if (!BYTEMODE)
+                if (code >= 0xD800 && code <= 0xDBFF)
+                {
+                    int next = buffer.Read();
+                    if (next < 0xDC00 || next > 0xDFFF)
+                        code = ScanBuff.UnicodeReplacementChar;
+                    else
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
+                }
+#endif
+                cCol++;
+            }
+        }
+
+        void MarkToken()
+        {
+#if (!PERSIST)
+            buffer.Mark();
+#endif
+            tokPos = readPos;
+            tokLin = lNum;
+            tokCol = cCol;
+        }
+        
+        void MarkEnd()
+        {
+            tokTxt = null;
+            tokEPos = readPos;
+            tokELin = lNum;
+            tokECol = cCol;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int Peek()
+        {
+            int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
+            GetCode(); rslt = code;
+            lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
+            return rslt;
+        }
+
+        // ==============================================================
+        // =====    Initialization of string-based input buffers     ====
+        // ==============================================================
+
+        /// <summary>
+        /// Create and initialize a StringBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the input string</param>
+        /// <param name="offset">starting offset in the string</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(string source, int offset)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.buffer.Pos = offset;
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+
+#if !NOFILES        
+        // ================ LineBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a LineBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the list of input strings</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(IList<string> source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            this.lNum = 0;
+            GetCode();
+        }
+
+        // =============== StreamBuffer Initialization ==================
+
+        /// <summary>
+        /// Create and initialize a StreamBuff buffer object for this scanner.
+        /// StreamBuff is buffer for 8-bit byte files.
+        /// </summary>
+        /// <param name="source">the input byte stream</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+        
+#if !BYTEMODE
+        // ================ TextBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a TextBuff buffer object for this scanner.
+        /// TextBuff is a buffer for encoded unicode files.
+        /// </summary>
+        /// <param name="source">the input text file</param>
+        /// <param name="fallbackCodePage">Code page to use if file has
+        /// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source, int fallbackCodePage)
+        {
+            this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+#endif // !BYTEMODE
+#endif // !NOFILES
+        
+        // ==============================================================
+
+#if BABEL
+        //
+        //  Get the next token for Visual Studio
+        //
+        //  "state" is the inout mode variable that maintains scanner
+        //  state between calls, using the EolState property. In principle,
+        //  if the calls of EolState are costly set could be called once
+        //  only per line, at the start; and get called only at the end
+        //  of the line. This needs more infrastructure ...
+        //
+        public int GetNext(ref int state, out int start, out int end)
+        {
+                Tokens next;
+            int s, e;
+            s = state;        // state at start
+            EolState = state;
+                next = (Tokens)Scan();
+            state = EolState;
+            e = state;       // state at end;
+            start = tokPos;
+            end = tokEPos - 1; // end is the index of last char.
+            return (int)next;
+        }        
+#endif // BABEL
+
+        // ======== AbstractScanner<> Implementation =========
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public override int yylex()
+        {
+            // parserMax is set by reflecting on the Tokens
+            // enumeration.  If maxParseToken is defined
+            // that is used, otherwise int.MaxValue is used.
+            int next;
+            do { next = Scan(); } while (next >= parserMax);
+            return next;
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yypos { get { return tokPos; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yyline { get { return tokLin; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yycol { get { return tokCol; } }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
+        public string yytext
+        {
+            get 
+            {
+                if (tokTxt == null) 
+                    tokTxt = buffer.GetString(tokPos, tokEPos);
+                return tokTxt;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void yyless(int n)
+        {
+            buffer.Pos = tokPos;
+            // Must read at least one char, so set before start.
+            cCol = tokCol - 1; 
+            GetCode();
+            // Now ensure that line counting is correct.
+            lNum = tokLin;
+            // And count the rest of the text.
+            for (int i = 0; i < n; i++) GetCode();
+            MarkEnd();
+        }
+       
+        //
+        //  It would be nice to count backward in the text
+        //  but it does not seem possible to re-establish
+        //  the correct column counts except by going forward.
+        //
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void _yytrunc(int n) { yyless(yyleng - n); }
+        
+        //
+        // This is painful, but we no longer count
+        // codepoints.  For the overwhelming majority 
+        // of cases the single line code is fast, for
+        // the others, well, at least it is all in the
+        // buffer so no files are touched. Note that we
+        // can't use (tokEPos - tokPos) because of the
+        // possibility of surrogate pairs in the token.
+        //
+        [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 {
+                    int ch;
+                    int count = 0;
+                    int save = buffer.Pos;
+                    buffer.Pos = tokPos;
+                    do {
+                        ch = buffer.Read();
+                        if (!char.IsHighSurrogate((char)ch)) count++;
+                    } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
+                    buffer.Pos = save; 
+                    return count;
+                }
+#endif // BYTEMODE
+            }
+        }
+        
+        // ============ methods available in actions ==============
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int YY_START {
+            get { return currentScOrd; }
+            set { currentScOrd = value; 
+                  currentStart = startState[value]; 
+            } 
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void BEGIN(int next) {
+            currentScOrd = next;
+            currentStart = startState[next];
+        }
+
+        // ============== The main tokenizer code =================
+
+        int Scan()
+        {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
+#if LEFTANCHORS
+                    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...
+                        GetCode();
+                    }
+                    
+#else // !LEFTANCHORS
+                    state = currentStart;
+                    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();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
+#if BACKUP
+                        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;
+                        }
+                        else
+#endif // BACKUP
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
+                        MarkEnd();
+#region ActionSwitch
+#pragma warning disable 162
+    switch (state)
+    {
+        case eofNum:
+            if (yywrap())
+                return (int)Tokens.EOF;
+            break;
+        case 1:
+LexError();
+	return 0;
+            break;
+        case 2:
+LexValueInt = int.Parse(yytext);
+  return (int)Tok.INUM;
+            break;
+        case 3:
+return (int)Tok.COLON;
+            break;
+        case 4:
+return (int)Tok.SEMICOLON;
+            break;
+        case 5:
+        case 6:
+        case 7:
+        case 8:
+        case 9:
+        case 11:
+        case 12:
+        case 13:
+        case 15:
+        case 16:
+        case 17:
+return (int)Tok.ID;
+            break;
+        case 10:
+return (int)Tok.END;
+            break;
+        case 14:
+return (int)Tok.CYCLE;
+            break;
+        case 18:
+return (int)Tok.BEGIN;
+            break;
+        case 19:
+return (int)Tok.ASSIGN;
+            break;
+        case 20:
+LexValueDouble = double.Parse(yytext);
+  return (int)Tok.RNUM;
+            break;
+        default:
+            break;
+    }
+#pragma warning restore 162
+#endregion
+                    }
+                }
+        }
+
+#if BACKUP
+        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;
+            ctx.lNum  = lNum;
+            ctx.state = state;
+            ctx.cChr  = code;
+        }
+
+        void RestoreStateAndPos(ref Context ctx)
+        {
+            buffer.Pos = ctx.bPos;
+            readPos = ctx.rPos;
+            cCol  = ctx.cCol;
+            lNum  = ctx.lNum;
+            state = ctx.state;
+            code  = ctx.cChr;
+        }
+
+#endif // BACKUP
+
+        // ============= End of the tokenizer code ================
+
+#if STACK        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void yy_clear_stack() { scStack.Clear(); }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int yy_top_state() { return scStack.Peek(); }
+        
+        internal void yy_push_state(int state)
+        {
+            scStack.Push(currentScOrd);
+            BEGIN(state);
+        }
+        
+        internal void yy_pop_state()
+        {
+            // Protect against input errors that pop too far ...
+            if (scStack.Count > 0) {
+				int newSc = scStack.Pop();
+				BEGIN(newSc);
+            } // Otherwise leave stack unchanged.
+        }
+ #endif // STACK
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void ECHO() { Console.Out.Write(yytext); }
+        
+#region UserCodeSection
+
+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 + "";
+	}
+}
+
+#endregion
+    } // end class $Scanner
+
+// ==============================================================
+// <auto-generated>
+// This code automatically produced from an embedded resource.
+// Do not edit this file, or it will become incompatible with 
+// the specification from which it was generated.
+// </auto-generated>
+// ==============================================================
+
+// Code copied from GPLEX embedded resource
+    [Serializable]
+    public class BufferException : Exception
+    {
+        public BufferException() { }
+        public BufferException(string message) : base(message) { }
+        public BufferException(string message, Exception innerException)
+            : base(message, innerException) { }
+        protected BufferException(SerializationInfo info, StreamingContext context)
+            : base(info, context) { }
+    }
+
+    public abstract class ScanBuff
+    {
+        private string fileNm;
+
+        public const int EndOfFile = -1;
+        public const int UnicodeReplacementChar = 0xFFFD;
+
+        public bool IsFile { get { return (fileNm != null); } }
+        public string FileName { get { return fileNm; } set { fileNm = value; } }
+
+        public abstract int Pos { get; set; }
+        public abstract int Read();
+        public virtual void Mark() { }
+
+        public abstract string GetString(int begin, int limit);
+
+        public static ScanBuff GetBuffer(string source)
+        {
+            return new StringBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(IList<string> source)
+        {
+            return new LineBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(Stream source)
+        {
+            return new BuildBuffer(source);
+        }
+
+#if (!BYTEMODE)
+        public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
+        {
+            return new BuildBuffer(source, fallbackCodePage);
+        }
+#endif
+    }
+
+    #region Buffer classes
+
+    // ==============================================================
+    // =====  Definitions for various ScanBuff derived classes   ====
+    // ==============================================================
+    // ===============         String input          ================
+    // ==============================================================
+
+    /// <summary>
+    /// This class reads characters from a single string as
+    /// required, for example, by Visual Studio language services
+    /// </summary>
+    sealed class StringBuffer : ScanBuff
+    {
+        string str;        // input buffer
+        int bPos;          // current position in buffer
+        int sLen;
+
+        public StringBuffer(string source)
+        {
+            this.str = source;
+            this.sLen = source.Length;
+            this.FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (bPos < sLen) return str[bPos++];
+            else if (bPos == sLen) { bPos++; return '\n'; }   // one strike, see new line
+            else { bPos++; return EndOfFile; }                // two strikes and you're out!
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            //  "limit" can be greater than sLen with the BABEL
+            //  option set.  Read returns a "virtual" EOL if
+            //  an attempt is made to read past the end of the
+            //  string buffer.  Without the guard any attempt 
+            //  to fetch yytext for a token that includes the 
+            //  EOL will throw an index exception.
+            if (limit > sLen) limit = sLen;
+            if (limit <= begin) return "";
+            else return str.Substring(begin, limit - begin);
+        }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+        public override string ToString() { return "StringBuffer"; }
+    }
+
+    // ==============================================================
+    //  The LineBuff class contributed by Nigel Horspool, 
+    //  nigelh@cs.uvic.cs
+    // ==============================================================
+
+    sealed class LineBuffer : ScanBuff
+    {
+        IList<string> line;    // list of source lines from a file
+        int numLines;          // number of strings in line list
+        string curLine;        // current line in that list
+        int cLine;             // index of current line in the list
+        int curLen;            // length of current line
+        int curLineStart;      // position of line start in whole file
+        int curLineEnd;        // position of line end in whole file
+        int maxPos;            // max position ever visited in whole file
+        int cPos;              // ordinal number of code in source
+
+        // Constructed from a list of strings, one per source line.
+        // The lines have had trailing '\n' characters removed.
+        public LineBuffer(IList<string> lineList)
+        {
+            line = lineList;
+            numLines = line.Count;
+            cPos = curLineStart = 0;
+            curLine = (numLines > 0 ? line[0] : "");
+            maxPos = curLineEnd = curLen = curLine.Length;
+            cLine = 1;
+            FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (cPos < curLineEnd)
+                return curLine[cPos++ - curLineStart];
+            if (cPos++ == curLineEnd)
+                return '\n';
+            if (cLine >= numLines)
+                return EndOfFile;
+            curLine = line[cLine];
+            curLen = curLine.Length;
+            curLineStart = curLineEnd + 1;
+            curLineEnd = curLineStart + curLen;
+            if (curLineEnd > maxPos)
+                maxPos = curLineEnd;
+            cLine++;
+            return curLen > 0 ? curLine[0] : '\n';
+        }
+
+        // To speed up searches for the line containing a position
+        private int cachedPosition;
+        private int cachedIxdex;
+        private int cachedLineStart;
+
+        // Given a position pos within the entire source, the results are
+        //   ix     -- the index of the containing line
+        //   lstart -- the position of the first character on that line
+        private void findIndex(int pos, out int ix, out int lstart)
+        {
+            if (pos >= cachedPosition)
+            {
+                ix = cachedIxdex; lstart = cachedLineStart;
+            }
+            else
+            {
+                ix = lstart = 0;
+            }
+            for (; ; )
+            {
+                int len = line[ix].Length + 1;
+                if (pos < lstart + len) break;
+                lstart += len;
+                ix++;
+            }
+            cachedPosition = pos;
+            cachedIxdex = ix;
+            cachedLineStart = lstart;
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            if (begin >= maxPos || limit <= begin) return "";
+            int endIx, begIx, endLineStart, begLineStart;
+            findIndex(begin, out begIx, out begLineStart);
+            int begCol = begin - begLineStart;
+            findIndex(limit, out endIx, out endLineStart);
+            int endCol = limit - endLineStart;
+            string s = line[begIx];
+            if (begIx == endIx)
+            {
+                // the usual case, substring all on one line
+                return (endCol <= s.Length) ?
+                    s.Substring(begCol, endCol - begCol)
+                    : s.Substring(begCol) + "\n";
+            }
+            // the string spans multiple lines, yuk!
+            StringBuilder sb = new StringBuilder();
+            if (begCol < s.Length)
+                sb.Append(s.Substring(begCol));
+            for (; ; )
+            {
+                sb.Append("\n");
+                s = line[++begIx];
+                if (begIx >= endIx) break;
+                sb.Append(s);
+            }
+            if (endCol <= s.Length)
+            {
+                sb.Append(s.Substring(0, endCol));
+            }
+            else
+            {
+                sb.Append(s);
+                sb.Append("\n");
+            }
+            return sb.ToString();
+        }
+
+        public override int Pos
+        {
+            get { return cPos; }
+            set
+            {
+                cPos = value;
+                findIndex(cPos, out cLine, out curLineStart);
+                curLine = line[cLine];
+                curLineEnd = curLineStart + curLine.Length;
+            }
+        }
+
+        public override string ToString() { return "LineBuffer"; }
+    }
+
+
+    // ==============================================================
+    // =====     class BuildBuff : for unicode text files    ========
+    // ==============================================================
+
+    class BuildBuffer : ScanBuff
+    {
+        // Double buffer for char stream.
+        class BufferElement
+        {
+            StringBuilder bldr = new StringBuilder();
+            StringBuilder next = new StringBuilder();
+            int minIx;
+            int maxIx;
+            int brkIx;
+            bool appendToNext;
+
+            internal BufferElement() { }
+
+            internal int MaxIndex { get { return maxIx; } }
+            // internal int MinIndex { get { return minIx; } }
+
+            internal char this[int index]
+            {
+                get
+                {
+                    if (index < minIx || index >= maxIx)
+                        throw new BufferException("Index was outside data buffer");
+                    else if (index < brkIx)
+                        return bldr[index - minIx];
+                    else
+                        return next[index - brkIx];
+                }
+            }
+
+            internal void Append(char[] block, int count)
+            {
+                maxIx += count;
+                if (appendToNext)
+                    this.next.Append(block, 0, count);
+                else
+                {
+                    this.bldr.Append(block, 0, count);
+                    brkIx = maxIx;
+                    appendToNext = true;
+                }
+            }
+
+            internal string GetString(int start, int limit)
+            {
+                if (limit <= start)
+                    return "";
+                if (start >= minIx && limit <= maxIx)
+                    if (limit < brkIx) // String entirely in bldr builder
+                        return bldr.ToString(start - minIx, limit - start);
+                    else if (start >= brkIx) // String entirely in next builder
+                        return next.ToString(start - brkIx, limit - start);
+                    else // Must do a string-concatenation
+                        return
+                            bldr.ToString(start - minIx, brkIx - start) +
+                            next.ToString(0, limit - brkIx);
+                else
+                    throw new BufferException("String was outside data buffer");
+            }
+
+            internal void Mark(int limit)
+            {
+                if (limit > brkIx + 16) // Rotate blocks
+                {
+                    StringBuilder temp = bldr;
+                    bldr = next;
+                    next = temp;
+                    next.Length = 0;
+                    minIx = brkIx;
+                    brkIx = maxIx;
+                }
+            }
+        }
+
+        BufferElement data = new BufferElement();
+
+        int bPos;            // Postion index in the StringBuilder
+        BlockReader NextBlk; // Delegate that serves char-arrays;
+
+        private string EncodingName
+        {
+            get
+            {
+                StreamReader rdr = NextBlk.Target as StreamReader;
+                return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
+            }
+        }
+
+        public BuildBuffer(Stream stream)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Raw(stream);
+        }
+
+#if (!BYTEMODE)
+        public BuildBuffer(Stream stream, int fallbackCodePage)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
+        }
+#endif
+
+        /// <summary>
+        /// Marks a conservative lower bound for the buffer,
+        /// allowing space to be reclaimed.  If an application 
+        /// needs to call GetString at arbitrary past locations 
+        /// in the input stream, Mark() is not called.
+        /// </summary>
+        public override void Mark() { data.Mark(bPos - 2); }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+
+        /// <summary>
+        /// Read returns the ordinal number of the next char, or 
+        /// EOF (-1) for an end of stream.  Note that the next
+        /// code point may require *two* calls of Read().
+        /// </summary>
+        /// <returns></returns>
+        public override int Read()
+        {
+            //
+            //  Characters at positions 
+            //  [data.offset, data.offset + data.bldr.Length)
+            //  are available in data.bldr.
+            //
+            if (bPos < data.MaxIndex)
+            {
+                // ch0 cannot be EOF
+                return (int)data[bPos++];
+            }
+            else // Read from underlying stream
+            {
+                // Experimental code, blocks of page size
+                char[] chrs = new char[4096];
+                int count = NextBlk(chrs, 0, 4096);
+                if (count == 0)
+                    return EndOfFile;
+                else
+                {
+                    data.Append(chrs, count);
+                    return (int)data[bPos++];
+                }
+            }
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            return data.GetString(begin, limit);
+        }
+
+        public override string ToString()
+        {
+            return "StringBuilder buffer, encoding: " + this.EncodingName;
+        }
+    }
+
+    // =============== End ScanBuff-derived classes ==================
+
+    public delegate int BlockReader(char[] block, int index, int number);
+
+    // A delegate factory, serving up a delegate that
+    // reads a block of characters from the underlying
+    // encoded stream, via a StreamReader object.
+    //
+    public static class BlockReaderFactory
+    {
+        public static BlockReader Raw(Stream stream)
+        {
+            return delegate(char[] block, int index, int number)
+            {
+                byte[] b = new byte[number];
+                int count = stream.Read(b, 0, number);
+                int i = 0;
+                int j = index;
+                for (; i < count; i++, j++)
+                    block[j] = (char)b[i];
+                return count;
+            };
+        }
+
+#if (!BYTEMODE)
+        public static BlockReader Get(Stream stream, int fallbackCodePage)
+        {
+            Encoding encoding;
+            int preamble = Preamble(stream);
+
+            if (preamble != 0)  // There is a valid BOM here!
+                encoding = Encoding.GetEncoding(preamble);
+            else if (fallbackCodePage == -1) // Fallback is "raw" bytes
+                return Raw(stream);
+            else if (fallbackCodePage != -2) // Anything but "guess"
+                encoding = Encoding.GetEncoding(fallbackCodePage);
+            else // This is the "guess" option
+            {
+                int guess = new Guesser(stream).GuessCodePage();
+                stream.Seek(0, SeekOrigin.Begin);
+                if (guess == -1) // ==> this is a 7-bit file
+                    encoding = Encoding.ASCII;
+                else if (guess == 65001)
+                    encoding = Encoding.UTF8;
+                else             // ==> use the machine default
+                    encoding = Encoding.Default;
+            }
+            StreamReader reader = new StreamReader(stream, encoding);
+            return reader.Read;
+        }
+
+        static int Preamble(Stream stream)
+        {
+            int b0 = stream.ReadByte();
+            int b1 = stream.ReadByte();
+
+            if (b0 == 0xfe && b1 == 0xff)
+                return 1201; // UTF16BE
+            if (b0 == 0xff && b1 == 0xfe)
+                return 1200; // UTF16LE
+
+            int b2 = stream.ReadByte();
+            if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
+                return 65001; // UTF8
+            //
+            // There is no unicode preamble, so we
+            // return denoter for the machine default.
+            //
+            stream.Seek(0, SeekOrigin.Begin);
+            return 0;
+        }
+#endif // !BYTEMODE
+    }
+    #endregion Buffer classes
+
+    // ==============================================================
+    // ============      class CodePageHandling         =============
+    // ==============================================================
+
+    public static class CodePageHandling
+    {
+        public static int GetCodePage(string option)
+        {
+            string command = option.ToUpperInvariant();
+            if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
+                command = command.Substring(9);
+            try
+            {
+                if (command.Equals("RAW"))
+                    return -1;
+                else if (command.Equals("GUESS"))
+                    return -2;
+                else if (command.Equals("DEFAULT"))
+                    return 0;
+                else if (char.IsDigit(command[0]))
+                    return int.Parse(command, CultureInfo.InvariantCulture);
+                else
+                {
+                    Encoding enc = Encoding.GetEncoding(command);
+                    return enc.CodePage;
+                }
+            }
+            catch (FormatException)
+            {
+                Console.Error.WriteLine(
+                    "Invalid format \"{0}\", using machine default", option);
+            }
+            catch (ArgumentException)
+            {
+                Console.Error.WriteLine(
+                    "Unknown code page \"{0}\", using machine default", option);
+            }
+            return 0;
+        }
+    }
+#region guesser
+#if (!BYTEMODE)
+    // ==============================================================
+    // ============          Encoding Guesser           =============
+    // ==============================================================
+
+    /// <summary>
+    /// This class provides a simple finite state automaton that
+    /// scans the file looking for (1) valid UTF-8 byte patterns,
+    /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
+    /// The method then guesses whether it is UTF-8 or maybe some 
+    /// local machine default encoding.  This works well for the
+    /// various Latin encodings.
+    /// </summary>
+    internal class Guesser
+    {
+        ScanBuff buffer;
+
+        public int GuessCodePage() { return Scan(); }
+
+        const int maxAccept = 10;
+        const int initial = 0;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+        const int EndToken = 0;
+
+        #region user code
+        /* 
+         *  Reads the bytes of a file to determine if it is 
+         *  UTF-8 or a single-byte code page file.
+         */
+        public long utfX;
+        public long uppr;
+        #endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;
+
+        #region ScannerTables
+        static int[] startState = new int[] { 11, 0 };
+
+        #region CharacterMap
+        static sbyte[] map = new sbyte[256] {
+/*     '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*   '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
+        #endregion
+
+        static sbyte[][] nextState = new sbyte[][] {
+            new sbyte[] {0, 0, 0, 0, 0, 0},
+            new sbyte[] {-1, -1, 10, -1, -1, -1},
+            new sbyte[] {-1, -1, -1, -1, -1, -1},
+            new sbyte[] {-1, -1, 8, -1, -1, -1},
+            new sbyte[] {-1, -1, 5, -1, -1, -1},
+            new sbyte[] {-1, -1, 6, -1, -1, -1},
+            new sbyte[] {-1, -1, 7, -1, -1, -1},
+            null,
+            new sbyte[] {-1, -1, 9, -1, -1, -1},
+            null,
+            null,
+            new sbyte[] {-1, 1, 2, 3, 4, 2}
+        };
+
+
+        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
+        // Reason for suppression: cannot have self-reference in array initializer.
+        static Guesser()
+        {
+            nextState[7] = nextState[2];
+            nextState[9] = nextState[2];
+            nextState[10] = nextState[2];
+        }
+
+        int NextState()
+        {
+            if (code == ScanBuff.EndOfFile)
+                return eofNum;
+            else
+                return nextState[state][map[code]];
+        }
+        #endregion
+
+        public Guesser(System.IO.Stream file) { SetSource(file); }
+
+        public void SetSource(System.IO.Stream source)
+        {
+            this.buffer = new BuildBuffer(source);
+            code = buffer.Read();
+        }
+
+        int Scan()
+        {
+            for (; ; )
+            {
+                int next;
+                state = currentStart;
+                while ((next = NextState()) == goStart)
+                    code = buffer.Read();
+
+                state = next;
+                code = buffer.Read();
+
+                while ((next = NextState()) > eofNum)
+                {
+                    state = next;
+                    code = buffer.Read();
+                }
+                if (state <= maxAccept)
+                {
+                    #region ActionSwitch
+#pragma warning disable 162
+                    switch (state)
+                    {
+                        case eofNum:
+                            switch (currentStart)
+                            {
+                                case 11:
+                                    if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
+                                    else if (uppr * 10 > utfX) return 0;   /* default code page */
+                                    else return 65001;                     /* UTF-8 encoding */
+                                    break;
+                            }
+                            return EndToken;
+                        case 1: // Recognized '{Upper128}',	Shortest string "\xC0"
+                        case 2: // Recognized '{Upper128}',	Shortest string "\x80"
+                        case 3: // Recognized '{Upper128}',	Shortest string "\xE0"
+                        case 4: // Recognized '{Upper128}',	Shortest string "\xF0"
+                            uppr++;
+                            break;
+                        case 5: // Recognized '{Utf8pfx4}{Utf8cont}',	Shortest string "\xF0\x80"
+                            uppr += 2;
+                            break;
+                        case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}',	Shortest string "\xF0\x80\x80"
+                            uppr += 3;
+                            break;
+                        case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}',	Shortest string "\xF0\x80\x80\x80"
+                            utfX += 3;
+                            break;
+                        case 8: // Recognized '{Utf8pfx3}{Utf8cont}',	Shortest string "\xE0\x80"
+                            uppr += 2;
+                            break;
+                        case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}',	Shortest string "\xE0\x80\x80"
+                            utfX += 2;
+                            break;
+                        case 10: // Recognized '{Utf8pfx2}{Utf8cont}',	Shortest string "\xC0\x80"
+                            utfX++;
+                            break;
+                        default:
+                            break;
+                    }
+#pragma warning restore 162
+                    #endregion
+                }
+            }
+        }
+    } // end class Guesser
+    
+#endif // !BYTEMODE
+#endregion
+
+// End of code copied from embedded resource
+
+} // end namespace
diff --git a/Module3/GPLexProject/SimpleLex.lex b/Module3/GPLexProject/SimpleLex.lex
new file mode 100644
index 0000000..c0434f0
--- /dev/null
+++ b/Module3/GPLexProject/SimpleLex.lex
@@ -0,0 +1,84 @@
+%using ScannerHelper;
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+
+// Здесь можно делать описания типов, переменных и методов - они попадают в класс Scanner
+%{
+  public int LexValueInt;
+  public double LexValueDouble;
+%}
+
+%%
+{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;
+}
+
+":" { 
+  return (int)Tok.COLON;
+}
+
+":=" { 
+  return (int)Tok.ASSIGN;
+}
+
+";" { 
+  return (int)Tok.SEMICOLON;
+}
+
+[^ \r\n] {
+	LexError();
+	return 0; // конец разбора
+}
+
+%%
+
+// Здесь можно делать описания переменных и методов - они тоже попадают в класс 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/GPLexProject/a.txt b/Module3/GPLexProject/a.txt
new file mode 100644
index 0000000..cda6431
--- /dev/null
+++ b/Module3/GPLexProject/a.txt
@@ -0,0 +1,3 @@
+begin ggg : ; :+= 7 99.9 5 
+1 
+ppp end
diff --git a/Module3/GPLexProject/generateScanner.bat b/Module3/GPLexProject/generateScanner.bat
new file mode 100644
index 0000000..e4f7d78
--- /dev/null
+++ b/Module3/GPLexProject/generateScanner.bat
@@ -0,0 +1 @@
+gplex.exe /noparser SimpleLex.lex 
\ No newline at end of file
diff --git a/Module3/GPLexProject/mymain.cs b/Module3/GPLexProject/mymain.cs
new file mode 100644
index 0000000..e00ca8b
--- /dev/null
+++ b/Module3/GPLexProject/mymain.cs
@@ -0,0 +1,32 @@
+using System;
+using System.IO;
+using SimpleScanner;
+using ScannerHelper;
+
+namespace Main
+{
+    class mymain
+    {
+        static void Main(string[] args)
+        {
+            // Чтобы вещественные числа распознавались и отображались в формате 3.14 (а не 3,14 как в русской Culture)
+            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
+
+            var fname = @"..\..\a.txt";
+            Console.WriteLine(File.ReadAllText(fname));
+            Console.WriteLine("-------------------------");
+
+            Scanner scanner = new Scanner(new FileStream(fname, FileMode.Open));
+
+            int tok = 0;
+            do {
+                tok = scanner.yylex();
+                if (tok == (int)Tok.EOF)
+                    break;
+                Console.WriteLine(scanner.TokToString((Tok)tok));
+            } while (true);
+
+            Console.ReadKey();
+        }
+    }
+}
diff --git a/Module5/SimpleLanguage0/Main.cs b/Module5/SimpleLanguage0/Main.cs
new file mode 100644
index 0000000..b00452b
--- /dev/null
+++ b/Module5/SimpleLanguage0/Main.cs
@@ -0,0 +1,45 @@
+п»їusing System;
+using System.IO;
+using System.Collections.Generic;
+using SimpleScanner;
+using SimpleParser;
+
+namespace SimpleCompiler
+{
+    public class SimpleCompilerMain
+    {
+        public static void Main()
+        {
+            string FileName = @"..\..\a.txt";
+            try
+            {
+                string Text = File.ReadAllText(FileName);
+
+                Scanner scanner = new Scanner();
+                scanner.SetSource(Text, 0);
+            
+                Parser parser = new Parser(scanner);
+                      
+                var b = parser.Parse();
+                if (!b)
+		            Console.WriteLine("Ошибка");
+                else Console.WriteLine("Программа распознана");
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("Файл {0} не найден", FileName);
+            }
+            catch (LexException e)
+            {
+                Console.WriteLine("Лексическая ошибка. " + e.Message);
+            }
+            catch (SyntaxException e)
+            {
+                Console.WriteLine("Синтаксическая ошибка. " + e.Message);
+            }
+
+            Console.ReadLine();
+        }
+
+    }
+}
diff --git a/Module5/SimpleLanguage0/ParserHelper.cs b/Module5/SimpleLanguage0/ParserHelper.cs
new file mode 100644
index 0000000..4c781de
--- /dev/null
+++ b/Module5/SimpleLanguage0/ParserHelper.cs
@@ -0,0 +1,19 @@
+п»їusing System;
+using System.Linq;
+
+namespace SimpleParser
+{
+    public class LexException : Exception
+    {
+        public LexException(string msg) : base(msg) { }
+    }
+    public class SyntaxException : Exception
+    {
+        public SyntaxException(string msg) : base(msg) { }
+    }
+    // Класс глобальных описаний и статических методов
+    // для использования различными подсистемами парсера и сканера
+    public static class ParserHelper 
+    {
+    }
+}
\ No newline at end of file
diff --git a/Module5/SimpleLanguage0/Properties/AssemblyInfo.cs b/Module5/SimpleLanguage0/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..896cc99
--- /dev/null
+++ b/Module5/SimpleLanguage0/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+п»їusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью 
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("SimpleLang")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SimpleLang")]
+[assembly: AssemblyCopyright("Copyright В©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми 
+// для COM-компонентов.  Если требуется обратиться к типу в этой сборке через 
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("06dba63f-4805-4cd3-8a93-b329b2c7e37b")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+//      Основной номер версии
+//      Дополнительный номер версии 
+//      Номер построения
+//      Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию, 
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Module5/SimpleLanguage0/ShiftReduceParserCode.cs b/Module5/SimpleLanguage0/ShiftReduceParserCode.cs
new file mode 100644
index 0000000..c110ba1
--- /dev/null
+++ b/Module5/SimpleLanguage0/ShiftReduceParserCode.cs
@@ -0,0 +1,944 @@
+// Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2009
+// (see accompanying GPPGcopyright.rtf)
+#define EXPORT_GPPG
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+namespace QUT.Gppg
+{
+    /// <summary>
+    /// Abstract class for GPPG shift-reduce parsers.
+    /// Parsers generated by GPPG derive from this base
+    /// class, overriding the abstract Initialize() and
+    /// DoAction() methods.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type</typeparam>
+    /// <typeparam name="TSpan">Location type</typeparam>
+#if EXPORT_GPPG
+    public abstract class ShiftReduceParser<TValue, TSpan>
+#else
+    internal abstract class ShiftReduceParser<TValue, TSpan>
+#endif
+ where TSpan : IMerge<TSpan>, new()
+    {
+        public AbstractScanner<TValue, TSpan> scanner;
+        /// <summary>
+        /// The abstract scanner for this parser.
+        /// </summary>
+        protected AbstractScanner<TValue, TSpan> Scanner {
+            get { return scanner; }
+            set { scanner = value; }
+        }
+
+        /// <summary>
+        /// Constructor for base class
+        /// </summary>
+        /// <param name="scanner">Scanner instance for this parser</param>
+        protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
+        {
+            this.scanner = scanner;
+        }
+
+        // ==============================================================
+        //                    TECHNICAL EXPLANATION.
+        //   Why the next two fields are not exposed via properties.
+        // ==============================================================
+        // These fields are of the generic parameter types, and are
+        // frequently instantiated as struct types in derived classes.
+        // Semantic actions are defined in the derived classes and refer
+        // to instance fields of these structs.  Is such cases the code
+        // "get_CurrentSemanticValue().myField = blah;" will fail since
+        // the getter pushes the value of the field, not the reference.
+        // So, in the presence of properties, gppg would need to encode
+        // such field accesses as ... 
+        //  "tmp = get_CurrentSemanticValue(); // Fetch value
+        //   tmp.myField = blah;               // update
+        //   set_CurrentSemanticValue(tmp); "  // Write update back.
+        // There is no issue if TValue is restricted to be a ref type.
+        // The same explanation applies to scanner.yylval.
+        // ==============================================================
+        /// <summary>
+        /// The current value of the "$$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TValue CurrentSemanticValue;
+
+        /// <summary>
+        /// The current value of the "@$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TSpan CurrentLocationSpan;
+
+        private TSpan LastSpan;
+        private int NextToken;
+        private State FsaState;
+        private bool recovering;
+        private int tokensSinceLastError;
+
+        private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
+        private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
+        private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
+
+        /// <summary>
+        /// The stack of semantic value (YYSTYPE) values.
+        /// </summary>
+        protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
+
+        /// <summary>
+        /// The stack of location value (YYLTYPE) varlues.
+        /// </summary>
+        protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
+
+        private int errorToken;
+        private int endOfFileToken;
+        private string[] nonTerminals;
+        private State[] states;
+        private Rule[] rules;
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the rule list into this base class.
+        /// </summary>
+        /// <param name="rules">The array of Rule objects</param>
+        protected void InitRules(Rule[] rules) { this.rules = rules; }
+
+      /// <summary>
+      /// Initialization method to allow derived classes to
+      /// insert the states table into this base class.
+      /// </summary>
+      /// <param name="states">The pre-initialized states table</param>
+        protected void InitStates(State[] states) { this.states = states; }
+
+      /// <summary>
+      /// OBSOLETE FOR VERSION 1.4.0
+      /// </summary>
+      /// <param name="size"></param>
+        protected void InitStateTable(int size) { states = new State[size]; }
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the special value for the error and EOF tokens.
+        /// </summary>
+        /// <param name="err">The error state ordinal</param>
+        /// <param name="end">The EOF stat ordinal</param>
+        protected void InitSpecialTokens(int err, int end)
+        {
+            errorToken = err;
+            endOfFileToken = end;
+        }
+
+        /// <summary>
+        /// Initialization method to allow derived classes to
+        /// insert the non-terminal symbol names into this base class.
+        /// </summary>
+        /// <param name="names">Non-terminal symbol names</param>
+        protected void InitNonTerminals(string[] names) { nonTerminals = names; }
+
+        #region YYAbort, YYAccept etcetera.
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AcceptException : Exception
+        {
+            internal AcceptException() { }
+            protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AbortException : Exception
+        {
+            internal AbortException() { }
+            protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class ErrorException : Exception
+        {
+            internal ErrorException() { }
+            protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+
+        // The following methods are only called from within
+        // a semantic action. The thrown exceptions can never
+        // propagate outside the ShiftReduceParser class in 
+        // which they are nested.
+
+        /// <summary>
+        /// Force parser to terminate, returning "true"
+        /// </summary>
+        protected static void YYAccept() { throw new AcceptException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning "false"
+        /// </summary>
+        protected static void YYAbort() { throw new AbortException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning
+        /// "false" if error recovery fails.
+        /// </summary>
+        protected static void YYError() { throw new ErrorException(); }
+
+        /// <summary>
+        /// Check if parser in error recovery state.
+        /// </summary>
+        protected bool YYRecovering { get { return recovering; } }
+        #endregion
+
+        /// <summary>
+        /// Abstract base method. ShiftReduceParser calls this
+        /// to initialize the base class data structures.  Concrete
+        /// parser classes must override this method.
+        /// </summary>
+        protected abstract void Initialize();
+
+        /// <summary>
+        /// Main entry point of the Shift-Reduce Parser.
+        /// </summary>
+        /// <returns>True if parse succeeds, else false for
+        /// unrecoverable errors</returns>
+        public bool Parse()
+        {
+            Initialize();	// allow derived classes to instantiate rules, states and nonTerminals
+
+            NextToken = 0;
+            FsaState = states[0];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+
+            while (true)
+            {
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+                int action = FsaState.defaultAction;
+
+                if (FsaState.ParserTable != null)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif
+                        // We save the last token span, so that the location span
+                        // of production right hand sides that begin or end with a
+                        // nullable production will be correct.
+                        LastSpan = scanner.yylloc;
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+                }
+
+                if (action > 0)         // shift
+                {
+                    Shift(action);
+                }
+                else if (action < 0)   // reduce
+                {
+                    try
+                    {
+                        Reduce(-action);
+                        if (action == -1)	// accept
+                            return true;
+                    }
+                    catch (Exception x)
+                    {
+                        if (x is AbortException)
+                            return false;
+                        else if (x is AcceptException)
+                            return true;
+                        else if (x is ErrorException && !ErrorRecovery())
+                            return false;
+                        else
+                            throw;  // Rethrow x, preserving information.
+
+                    }
+                }
+                else if (action == 0)   // error
+                    if (!ErrorRecovery())
+                        return false;
+            }
+        }
+
+        private void Shift(int stateIndex)
+        {
+#if TRACE_ACTIONS
+				Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
+#endif
+            FsaState = states[stateIndex];
+
+            valueStack.Push(scanner.yylval);
+            StateStack.Push(FsaState);
+            LocationStack.Push(scanner.yylloc);
+
+            if (recovering)
+            {
+                if (NextToken != errorToken)
+                    tokensSinceLastError++;
+
+                if (tokensSinceLastError > 5)
+                    recovering = false;
+            }
+
+            if (NextToken != endOfFileToken)
+                NextToken = 0;
+        }
+
+        private void Reduce(int ruleNumber)
+        {
+#if TRACE_ACTIONS
+				DisplayRule(ruleNumber);
+#endif
+            Rule rule = rules[ruleNumber];
+            //
+            //  Default actions for unit productions.
+            //
+            if (rule.RightHandSide.Length == 1)
+            {
+                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
+                CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
+            }
+            else
+            {
+                if (rule.RightHandSide.Length == 0)
+                {
+                    // Create a new blank value.
+                    // Explicit semantic action may mutate this value
+                    CurrentSemanticValue = default(TValue);
+                    // The location span for an empty production will start with the
+                    // beginning of the next lexeme, and end with the finish of the
+                    // previous lexeme.  This gives the correct behaviour when this
+                    // nonsense value is used in later Merge operations.
+                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
+                        scanner.yylloc.Merge(LastSpan) :
+                        default(TSpan));
+                }
+                else
+                {
+                    // Default action: $$ = $1;
+                    CurrentSemanticValue = valueStack.TopElement();
+                    //  Default action "@$ = @1.Merge(@N)" for location info.
+                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
+                    TSpan atN = LocationStack[LocationStack.Depth - 1];
+                    CurrentLocationSpan = 
+                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
+                }
+            }
+
+            DoAction(ruleNumber);
+
+            for (int i = 0; i < rule.RightHandSide.Length; i++)
+            {
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+            }
+
+#if TRACE_ACTIONS
+				DisplayStack();
+#endif
+            FsaState = StateStack.TopElement();
+
+            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
+                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+        }
+
+        /// <summary>
+        /// Execute the selected action from array.
+        /// Must be overriden in derived classes.
+        /// </summary>
+        /// <param name="actionNumber">Index of the action to perform</param>
+        protected abstract void DoAction(int actionNumber);
+
+        private bool ErrorRecovery()
+        {
+            bool discard;
+
+            if (!recovering) // if not recovering from previous error
+                ReportError();
+
+            if (!FindErrorRecoveryState())
+                return false;
+            //
+            //  The interim fix for the "looping in error recovery"
+            //  artifact involved moving the setting of the recovering 
+            //  bool until after invalid tokens have been discarded.
+            //
+            ShiftErrorToken();
+            discard = DiscardInvalidTokens();
+            recovering = true;
+            tokensSinceLastError = 0;
+            return discard;
+        }
+
+        private void ReportError1()
+        {
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
+
+            if (FsaState.ParserTable.Count < 7)
+            {
+                bool first = true;
+                foreach (int terminal in FsaState.ParserTable.Keys)
+                {
+                    if (first)
+                        errorMsg.Append(", expecting ");
+                    else
+                        errorMsg.Append(", or ");
+
+                    errorMsg.Append(TerminalToString(terminal));
+                    first = false;
+                }
+            }
+            scanner.yyerror(errorMsg.ToString());
+        }
+
+        private void ReportError()
+        {
+            object[] args = new object[FsaState.ParserTable.Keys.Count+1];
+            args[0] = TerminalToString(NextToken);
+            int i=1;
+            foreach (int terminal in FsaState.ParserTable.Keys)
+            {
+                args[i] = TerminalToString(terminal);
+                i++;
+            }
+            scanner.yyerror("",args);
+        }
+
+        private void ShiftErrorToken()
+        {
+            int old_next = NextToken;
+            NextToken = errorToken;
+
+            Shift(FsaState.ParserTable[NextToken]);
+
+#if TRACE_ACTIONS
+				Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+            NextToken = old_next;
+        }
+
+        private bool FindErrorRecoveryState()
+        {
+            while (true)    // pop states until one found that accepts error token
+            {
+                if (FsaState.ParserTable != null &&
+                    FsaState.ParserTable.ContainsKey(errorToken) &&
+                    FsaState.ParserTable[errorToken] > 0) // shift
+                    return true;
+
+#if TRACE_ACTIONS
+					Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
+#endif
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+
+#if TRACE_ACTIONS
+					DisplayStack();
+#endif
+                if (StateStack.IsEmpty())
+                {
+#if TRACE_ACTIONS
+                        Console.Error.Write("Aborting: didn't find a state that accepts error token");
+#endif
+                    return false;
+                }
+                else
+                    FsaState = StateStack.TopElement();
+            }
+        }
+
+        private bool DiscardInvalidTokens()
+        {
+
+            int action = FsaState.defaultAction;
+
+            if (FsaState.ParserTable != null)
+            {
+                // Discard tokens until find one that works ...
+                while (true)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif                       
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (NextToken == endOfFileToken)
+                        return false;
+
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+
+                    if (action != 0)
+                        return true;
+                    else
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
+#endif
+                        NextToken = 0;
+                    }
+                }
+            }
+            else if (recovering && tokensSinceLastError == 0)
+            {
+                // 
+                //  Boolean recovering is not set until after the first
+                //  error token has been shifted.  Thus if we get back 
+                //  here with recovering set and no tokens read we are
+                //  looping on the same error recovery action.  This 
+                //  happens if current_state.ParserTable is null because
+                //  the state has an LR(0) reduction, but not all
+                //  lookahead tokens are valid.  This only occurs for
+                //  error productions that *end* on "error".
+                //
+                //  This action discards tokens one at a time until
+                //  the looping stops.  Another attack would be to always
+                //  use the LALR(1) table if a production ends on "error"
+                //
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
+#endif
+                if (NextToken == endOfFileToken)
+                    return false;
+                NextToken = 0;
+                return true;
+            }
+            else
+                return true;
+
+        }
+
+        /// <summary>
+        /// Traditional YACC method.  Discards the next input token.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyclearin() { NextToken = 0; }
+
+        /// <summary>
+        /// Tradional YACC method. Clear the "recovering" flag.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyerrok()
+        {
+            recovering = false;
+        }
+
+        /// <summary>
+        /// OBSOLETE FOR VERSION 1.4.0
+        /// Method used by derived types to insert new
+        /// state instances in the "states" array.
+        /// </summary>
+        /// <param name="stateNumber">index of the state</param>
+        /// <param name="state">data for the state</param>
+        protected void AddState(int stateNumber, State state)
+        {
+            states[stateNumber] = state;
+            state.number = stateNumber;
+        }
+
+        private void DisplayStack()
+        {
+            Console.Error.Write("State now");
+            for (int i = 0; i < StateStack.Depth; i++)
+                Console.Error.Write(" {0}", StateStack[i].number);
+            Console.Error.WriteLine();
+        }
+
+        private void DisplayRule(int ruleNumber)
+        {
+            Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
+            DisplayProduction(rules[ruleNumber]);
+        }
+
+        private void DisplayProduction(Rule rule)
+        {
+            if (rule.RightHandSide.Length == 0)
+                Console.Error.Write("/* empty */ ");
+            else
+                foreach (int symbol in rule.RightHandSide)
+                    Console.Error.Write("{0} ", SymbolToString(symbol));
+
+            Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
+        }
+
+        /// <summary>
+        /// Abstract state class naming terminal symbols.
+        /// This is overridden by derived classes with the
+        /// name (or alias) to be used in error messages.
+        /// </summary>
+        /// <param name="terminal">The terminal ordinal</param>
+        /// <returns></returns>
+        protected abstract string TerminalToString(int terminal);
+
+        private string SymbolToString(int symbol)
+        {
+            if (symbol < 0)
+                return nonTerminals[-symbol];
+            else
+                return TerminalToString(symbol);
+        }
+
+        /// <summary>
+        /// Return text representation of argument character
+        /// </summary>
+        /// <param name="input">The character to convert</param>
+        /// <returns>String representation of the character</returns>
+        protected static string CharToString(char input)
+        {
+            switch (input)
+            {
+                case '\a': return @"'\a'";
+                case '\b': return @"'\b'";
+                case '\f': return @"'\f'";
+                case '\n': return @"'\n'";
+                case '\r': return @"'\r'";
+                case '\t': return @"'\t'";
+                case '\v': return @"'\v'";
+                case '\0': return @"'\0'";
+                default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Classes implementing this interface must supply a
+    /// method that merges two location objects to return
+    /// a new object of the same type.
+    /// GPPG-generated parsers have the default location
+    /// action equivalent to "@$ = @1.Merge(@N);" where N
+    /// is the right-hand-side length of the production.
+    /// </summary>
+    /// <typeparam name="TSpan">The Location type</typeparam>
+#if EXPORT_GPPG
+    public interface IMerge<TSpan>
+#else
+    internal interface IMerge<TSpan>
+#endif
+    {
+        /// <summary>
+        /// Interface method that creates a location object from
+        /// the current and last object.  Typically used to create
+        /// a location object extending from the start of the @1
+        /// object to the end of the @N object.
+        /// </summary>
+        /// <param name="last">The lexically last object to merge</param>
+        /// <returns>The merged location object</returns>
+        TSpan Merge(TSpan last);
+    }
+
+    /// <summary>
+    /// This is the default class that carries location
+    /// information from the scanner to the parser.
+    /// If you don't declare "%YYLTYPE Foo" the parser
+    /// will expect to deal with this type.
+    /// </summary>
+#if EXPORT_GPPG
+    public class LexLocation : IMerge<LexLocation>
+#else
+    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
+    internal class LexLocation : IMerge<LexLocation>
+#endif
+    {
+        private int startLine;   // start line
+        private int startColumn; // start column
+        private int endLine;     // end line
+        private int endColumn;   // end column
+
+        /// <summary>
+        /// The line at which the text span starts.
+        /// </summary>
+        public int StartLine { get { return startLine; } }
+
+        /// <summary>
+        /// The column at which the text span starts.
+        /// </summary>
+        public int StartColumn { get { return startColumn; } }
+
+        /// <summary>
+        /// The line on which the text span ends.
+        /// </summary>
+        public int EndLine { get { return endLine; } }
+
+        /// <summary>
+        /// The column of the first character
+        /// beyond the end of the text span.
+        /// </summary>
+        public int EndColumn { get { return endColumn; } }
+
+        /// <summary>
+        /// Default no-arg constructor.
+        /// </summary>
+        public LexLocation()
+        { }
+
+        /// <summary>
+        /// Constructor for text-span with given start and end.
+        /// </summary>
+        /// <param name="sl">start line</param>
+        /// <param name="sc">start column</param>
+        /// <param name="el">end line </param>
+        /// <param name="ec">end column</param>
+        public LexLocation(int sl, int sc, int el, int ec)
+        { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
+
+        /// <summary>
+        /// Create a text location which spans from the 
+        /// start of "this" to the end of the argument "last"
+        /// </summary>
+        /// <param name="last">The last location in the result span</param>
+        /// <returns>The merged span</returns>
+        public LexLocation Merge(LexLocation last)
+        { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
+
+    }
+
+    /// <summary>
+    /// Abstract scanner class that GPPG expects its scanners to 
+    /// extend.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
+    /// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
+#if EXPORT_GPPG
+    public abstract class AbstractScanner<TValue, TSpan>
+#else
+    internal abstract class AbstractScanner<TValue, TSpan>
+#endif
+        where TSpan : IMerge<TSpan>
+    {
+        /// <summary>
+        /// Lexical value optionally set by the scanner. The value
+        /// is of the %YYSTYPE type declared in the parser spec.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        // A field must be declared for this value of parametric type,
+        // since it may be instantiated by a value struct.  If it were 
+        // implemented as a property, machine generated code in derived
+        // types would not be able to select on the returned value.
+        public TValue yylval;                     // Lexical value: set by scanner
+
+        /// <summary>
+        /// Current scanner location property. The value is of the
+        /// type declared by %YYLTYPE in the parser specification.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual TSpan yylloc
+        {
+            get { return default(TSpan); }       // Empty implementation allowing
+            set { /* skip */ }                   // yylloc to be ignored entirely.
+        }
+
+        /// <summary>
+        /// Main call point for LEX-like scanners.  Returns an int
+        /// corresponding to the token recognized by the scanner.
+        /// </summary>
+        /// <returns>An int corresponding to the token</returns>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public abstract int yylex();
+
+        /// <summary>
+        /// Traditional error reporting provided by LEX-like scanners
+        /// to their YACC-like clients.
+        /// </summary>
+        /// <param name="format">Message format string</param>
+        /// <param name="args">Optional array of args</param>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual void yyerror(string format, params object[] args) { }
+    }
+
+    /// <summary>
+    /// Encapsulated state for the parser.
+    /// Opaque to users, visible to the tool-generated code.
+    /// </summary>
+#if EXPORT_GPPG
+    public class State
+#else
+    internal class State
+#endif
+    {
+        internal int number;
+        internal Dictionary<int, int> ParserTable;   // Terminal -> ParseAction
+        internal Dictionary<int, int> Goto;          // NonTerminal -> State;
+        internal int defaultAction; // = 0;		     // ParseAction
+
+        /// <summary>
+        /// State transition data for this state. Pairs of elements of the 
+        /// goto array associate symbol ordinals with next state indices.
+        /// The actions array is passed to another constructor. 
+        /// </summary>
+        /// <param name="actions">The action list</param>
+        /// <param name="goToList">Next state data</param>
+        public State(int[] actions, int[] goToList)
+            : this(actions)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+
+        /// <summary>
+        /// Action data for this state. Pairs of elements of the 
+        /// action array associate action ordinals with each of
+        /// those symbols that have actions in the current state.
+        /// </summary>
+        /// <param name="actions">The action array</param>
+        public State(int[] actions)
+        {
+            ParserTable = new Dictionary<int, int>();
+            for (int i = 0; i < actions.Length; i += 2)
+                ParserTable.Add(actions[i], actions[i + 1]);
+        }
+
+        /// <summary>
+        /// Set the default action for this state.
+        /// </summary>
+        /// <param name="defaultAction">Ordinal of the default action</param>
+        public State(int defaultAction)
+        {
+            this.defaultAction = defaultAction;
+        }
+
+        /// <summary>
+        /// Set the default action and the state transition table.
+        /// </summary>
+        /// <param name="defaultAction">The default action</param>
+        /// <param name="goToList">Transitions from this state</param>
+        public State(int defaultAction, int[] goToList)
+            : this(defaultAction)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+    }
+
+    /// <summary>
+    /// Rule representation at runtime.
+    /// </summary>
+#if EXPORT_GPPG
+    public class Rule
+#else
+    internal class Rule
+#endif
+    {
+        internal int LeftHandSide; // symbol
+        internal int[] RightHandSide; // symbols
+
+        /// <summary>
+        /// Rule constructor.  This holds the ordinal of
+        /// the left hand side symbol, and the list of
+        /// right hand side symbols, in lexical order.
+        /// </summary>
+        /// <param name="left">The LHS non-terminal</param>
+        /// <param name="right">The RHS symbols, in lexical order</param>
+        public Rule(int left, int[] right)
+        {
+            this.LeftHandSide = left;
+            this.RightHandSide = right;
+        }
+    }
+
+    /// <summary>
+    /// Stack utility for the shift-reduce parser.
+    /// GPPG parsers have three instances:
+    /// (1) The parser state stack, T = QUT.Gppg.State,
+    /// (2) The semantic value stack, T = TValue,
+    /// (3) The location stack, T = TSpan.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if EXPORT_GPPG
+    public class PushdownPrefixState<T>
+#else
+    internal class PushdownPrefixState<T>
+#endif
+    {
+        //  Note that we cannot use the BCL Stack<T> class
+        //  here as derived types need to index into stacks.
+        //
+        private T[] array = new T[8];
+        private int tos = 0;
+
+        /// <summary>
+        /// Indexer for values of the stack below the top.
+        /// </summary>
+        /// <param name="index">index of the element, starting from the bottom</param>
+        /// <returns>the selected element</returns>
+        public T this[int index] { get { return array[index]; } }
+
+        /// <summary>
+        /// The current depth of the stack.
+        /// </summary>
+        public int Depth { get { return tos; } }
+
+        internal void Push(T value)
+        {
+            if (tos >= array.Length)
+            {
+                T[] newarray = new T[array.Length * 2];
+                System.Array.Copy(array, newarray, tos);
+                array = newarray;
+            }
+            array[tos++] = value;
+        }
+
+        internal T Pop()
+        {
+            T rslt = array[--tos];
+            array[tos] = default(T);
+            return rslt;
+        }
+
+        internal T TopElement() { return array[tos - 1]; }
+
+        internal bool IsEmpty() { return tos == 0; }
+    }
+}
\ No newline at end of file
diff --git a/Module5/SimpleLanguage0/SimpleLang.csproj b/Module5/SimpleLanguage0/SimpleLang.csproj
new file mode 100644
index 0000000..a45c176
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleLang.csproj
@@ -0,0 +1,61 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SimpleLang</RootNamespace>
+    <AssemblyName>SimpleLang</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Main.cs" />
+    <Compile Include="ParserHelper.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShiftReduceParserCode.cs" />
+    <Compile Include="SimpleLex.cs" />
+    <Compile Include="SimpleYacc.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- 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">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/Module5/SimpleLanguage0/SimpleLang.sln b/Module5/SimpleLanguage0/SimpleLang.sln
new file mode 100644
index 0000000..0f586d1
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleLang.sln
@@ -0,0 +1,20 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLang", "SimpleLang.csproj", "{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.ActiveCfg = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.Build.0 = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.ActiveCfg = Release|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Module5/SimpleLanguage0/SimpleLex.cs b/Module5/SimpleLanguage0/SimpleLex.cs
new file mode 100644
index 0000000..7752281
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleLex.cs
@@ -0,0 +1,1485 @@
+//
+//  This CSharp output file generated by Gardens Point LEX
+//  Version:  1.1.3.301
+//  Machine:  HUB
+//  DateTime: 21.09.2017 20:15:13
+//  UserName: someone
+//  GPLEX input file <SimpleLex.lex>
+//  GPLEX frame file <embedded resource>
+//
+//  Option settings: unicode, parser, minimize
+//  Option settings: classes, compressMap, compressNext, persistBuffer, embedbuffers
+//  Fallback code page: Target machine default
+//
+
+//
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
+//
+//
+#define BACKUP
+#define PERSIST
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+using SimpleParser;
+using QUT.Gppg;
+using System.Linq;
+
+namespace SimpleScanner
+{   
+    /// <summary>
+    /// Summary Canonical example of GPLEX automaton
+    /// </summary>
+    
+#if STANDALONE
+    //
+    // These are the dummy declarations for stand-alone GPLEX applications
+    // normally these declarations would come from the parser.
+    // If you declare /noparser, or %option noparser then you get this.
+    //
+
+     public enum Tokens
+    { 
+      EOF = 0, maxParseToken = int.MaxValue 
+      // must have at least these two, values are almost arbitrary
+    }
+
+     public abstract class ScanBase
+    {
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public abstract int yylex();
+
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
+        protected virtual bool yywrap() { return true; }
+
+#if BABEL
+        protected abstract int CurrentSc { get; set; }
+        // EolState is the 32-bit of state data persisted at 
+        // the end of each line for Visual Studio colorization.  
+        // The default is to return CurrentSc.  You must override
+        // this if you want more complicated behavior.
+        public virtual int EolState { 
+            get { return CurrentSc; }
+            set { CurrentSc = value; } 
+        }
+    }
+    
+     public interface IColorScan
+    {
+        void SetSource(string source, int offset);
+        int GetNext(ref int state, out int start, out int end);
+#endif // BABEL
+    }
+
+#endif // STANDALONE
+    
+    // If the compiler can't find the scanner base class maybe you
+    // need to run GPPG with the /gplex option, or GPLEX with /noparser
+#if BABEL
+     public sealed partial class Scanner : ScanBase, IColorScan
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+        
+        protected override int CurrentSc 
+        {
+             // The current start state is a property
+             // to try to avoid the user error of setting
+             // scState but forgetting to update the FSA
+             // start state "currentStart"
+             //
+             get { return currentScOrd; }  // i.e. return YY_START;
+             set { currentScOrd = value;   // i.e. BEGIN(value);
+                   currentStart = startState[value]; }
+        }
+#else  // BABEL
+     public sealed partial class Scanner : ScanBase
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+#endif // BABEL
+        
+        /// <summary>
+        /// The input buffer for this scanner.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public ScanBuff Buffer { get { return buffer; } }
+        
+        private static int GetMaxParseToken() {
+     System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken");
+            return (f == null ? int.MaxValue : (int)f.GetValue(null));
+        }
+        
+        static int parserMax = GetMaxParseToken();
+        
+        enum Result {accept, noMatch, contextFound};
+
+        const int maxAccept = 7;
+        const int initial = 8;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+
+#region user code
+#endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;      // last code read
+        int cCol;      // column number of code
+        int lNum;      // current line number
+        //
+        // The following instance variables are used, among other
+        // things, for constructing the yylloc location objects.
+        //
+        int tokPos;        // buffer position at start of token
+        int tokCol;        // zero-based column number at start of token
+        int tokLin;        // line number at start of token
+        int tokEPos;       // buffer position at end of token
+        int tokECol;       // column number at end of token
+        int tokELin;       // line number at end of token
+        string tokTxt;     // lazily constructed text of token
+#if STACK          
+        private Stack<int> scStack = new Stack<int>();
+#endif // STACK
+
+#region ScannerTables
+    struct Table {
+        public int min; public int rng; public int dflt;
+        public sbyte[] nxt;
+        public Table(int m, int x, int d, sbyte[] n) {
+            min = m; rng = x; dflt = d; nxt = n;
+        }
+    };
+
+    static int[] startState = new int[] {8, 0};
+
+#region CompressedCharacterMap
+    //
+    // There are 8 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, 
+/*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+    static sbyte MapC(int code)
+    { // '\0' <= code <= '\U0010FFFF'
+      if (code < 123) // '\0' <= code <= 'z'
+        return mapC0[code - 0];
+      else // '{' <= code <= '\U0010FFFF'
+        return (sbyte)7;
+    }
+#endregion
+
+    static Table[] NxS = new Table[10] {
+/* NxS[   0] */ new Table(0, 0, 0, null),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
+/* 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[   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}),
+    };
+
+int NextState() {
+    if (code == ScanBuff.EndOfFile)
+        return eofNum;
+    else
+        unchecked {
+            int rslt;
+            int idx = MapC(code) - NxS[state].min;
+            if (idx < 0) idx += 8;
+            if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
+            else rslt = NxS[state].nxt[idx];
+            return rslt;
+        }
+}
+
+#endregion
+
+
+#if BACKUP
+        // ==============================================================
+        // == Nested struct used for backup in automata that do backup ==
+        // ==============================================================
+
+        struct Context // class used for automaton backup.
+        {
+            public int bPos;
+            public int rPos; // scanner.readPos saved value
+            public int cCol;
+            public int lNum; // Need this in case of backup over EOL.
+            public int state;
+            public int cChr;
+        }
+        
+        private Context ctx = new Context();
+#endif // BACKUP
+
+        // ==============================================================
+        // ==== Nested struct to support input switching in scanners ====
+        // ==============================================================
+
+		struct BufferContext {
+            internal ScanBuff buffSv;
+			internal int chrSv;
+			internal int cColSv;
+			internal int lNumSv;
+		}
+
+        // ==============================================================
+        // ===== Private methods to save and restore buffer contexts ====
+        // ==============================================================
+
+        /// <summary>
+        /// This method creates a buffer context record from
+        /// the current buffer object, together with some
+        /// scanner state values. 
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        BufferContext MkBuffCtx()
+		{
+			BufferContext rslt;
+			rslt.buffSv = this.buffer;
+			rslt.chrSv = this.code;
+			rslt.cColSv = this.cCol;
+			rslt.lNumSv = this.lNum;
+			return rslt;
+		}
+
+        /// <summary>
+        /// This method restores the buffer value and allied
+        /// scanner state from the given context record value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void RestoreBuffCtx(BufferContext value)
+		{
+			this.buffer = value.buffSv;
+			this.code = value.chrSv;
+			this.cCol = value.cColSv;
+			this.lNum = value.lNumSv;
+        } 
+        // =================== End Nested classes =======================
+
+#if !NOFILES
+     public Scanner(Stream file) {
+            SetSource(file, 0); // unicode option
+        }
+
+        public Scanner(Stream file, string codepage) {
+            SetSource(file, CodePageHandling.GetCodePage(codepage));
+        }
+        
+#endif // !NOFILES
+
+     public Scanner() { }
+
+        private int readPos;
+
+        void GetCode()
+        {
+            if (code == '\n')  // This needs to be fixed for other conventions
+                               // i.e. [\r\n\205\u2028\u2029]
+            { 
+                cCol = -1;
+                lNum++;
+            }
+            readPos = buffer.Pos;
+
+            // Now read new codepoint.
+            code = buffer.Read();
+            if (code > ScanBuff.EndOfFile)
+            {
+#if (!BYTEMODE)
+                if (code >= 0xD800 && code <= 0xDBFF)
+                {
+                    int next = buffer.Read();
+                    if (next < 0xDC00 || next > 0xDFFF)
+                        code = ScanBuff.UnicodeReplacementChar;
+                    else
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
+                }
+#endif
+                cCol++;
+            }
+        }
+
+        void MarkToken()
+        {
+#if (!PERSIST)
+            buffer.Mark();
+#endif
+            tokPos = readPos;
+            tokLin = lNum;
+            tokCol = cCol;
+        }
+        
+        void MarkEnd()
+        {
+            tokTxt = null;
+            tokEPos = readPos;
+            tokELin = lNum;
+            tokECol = cCol;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int Peek()
+        {
+            int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
+            GetCode(); rslt = code;
+            lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
+            return rslt;
+        }
+
+        // ==============================================================
+        // =====    Initialization of string-based input buffers     ====
+        // ==============================================================
+
+        /// <summary>
+        /// Create and initialize a StringBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the input string</param>
+        /// <param name="offset">starting offset in the string</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(string source, int offset)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.buffer.Pos = offset;
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+
+#if !NOFILES        
+        // ================ LineBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a LineBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the list of input strings</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(IList<string> source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            this.lNum = 0;
+            GetCode();
+        }
+
+        // =============== StreamBuffer Initialization ==================
+
+        /// <summary>
+        /// Create and initialize a StreamBuff buffer object for this scanner.
+        /// StreamBuff is buffer for 8-bit byte files.
+        /// </summary>
+        /// <param name="source">the input byte stream</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+        
+#if !BYTEMODE
+        // ================ TextBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a TextBuff buffer object for this scanner.
+        /// TextBuff is a buffer for encoded unicode files.
+        /// </summary>
+        /// <param name="source">the input text file</param>
+        /// <param name="fallbackCodePage">Code page to use if file has
+        /// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source, int fallbackCodePage)
+        {
+            this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+#endif // !BYTEMODE
+#endif // !NOFILES
+        
+        // ==============================================================
+
+#if BABEL
+        //
+        //  Get the next token for Visual Studio
+        //
+        //  "state" is the inout mode variable that maintains scanner
+        //  state between calls, using the EolState property. In principle,
+        //  if the calls of EolState are costly set could be called once
+        //  only per line, at the start; and get called only at the end
+        //  of the line. This needs more infrastructure ...
+        //
+        public int GetNext(ref int state, out int start, out int end)
+        {
+                Tokens next;
+            int s, e;
+            s = state;        // state at start
+            EolState = state;
+                next = (Tokens)Scan();
+            state = EolState;
+            e = state;       // state at end;
+            start = tokPos;
+            end = tokEPos - 1; // end is the index of last char.
+            return (int)next;
+        }        
+#endif // BABEL
+
+        // ======== AbstractScanner<> Implementation =========
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public override int yylex()
+        {
+            // parserMax is set by reflecting on the Tokens
+            // enumeration.  If maxParseToken is defined
+            // that is used, otherwise int.MaxValue is used.
+            int next;
+            do { next = Scan(); } while (next >= parserMax);
+            return next;
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yypos { get { return tokPos; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yyline { get { return tokLin; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yycol { get { return tokCol; } }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
+        public string yytext
+        {
+            get 
+            {
+                if (tokTxt == null) 
+                    tokTxt = buffer.GetString(tokPos, tokEPos);
+                return tokTxt;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void yyless(int n)
+        {
+            buffer.Pos = tokPos;
+            // Must read at least one char, so set before start.
+            cCol = tokCol - 1; 
+            GetCode();
+            // Now ensure that line counting is correct.
+            lNum = tokLin;
+            // And count the rest of the text.
+            for (int i = 0; i < n; i++) GetCode();
+            MarkEnd();
+        }
+       
+        //
+        //  It would be nice to count backward in the text
+        //  but it does not seem possible to re-establish
+        //  the correct column counts except by going forward.
+        //
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void _yytrunc(int n) { yyless(yyleng - n); }
+        
+        //
+        // This is painful, but we no longer count
+        // codepoints.  For the overwhelming majority 
+        // of cases the single line code is fast, for
+        // the others, well, at least it is all in the
+        // buffer so no files are touched. Note that we
+        // can't use (tokEPos - tokPos) because of the
+        // possibility of surrogate pairs in the token.
+        //
+        [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 {
+                    int ch;
+                    int count = 0;
+                    int save = buffer.Pos;
+                    buffer.Pos = tokPos;
+                    do {
+                        ch = buffer.Read();
+                        if (!char.IsHighSurrogate((char)ch)) count++;
+                    } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
+                    buffer.Pos = save; 
+                    return count;
+                }
+#endif // BYTEMODE
+            }
+        }
+        
+        // ============ methods available in actions ==============
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int YY_START {
+            get { return currentScOrd; }
+            set { currentScOrd = value; 
+                  currentStart = startState[value]; 
+            } 
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void BEGIN(int next) {
+            currentScOrd = next;
+            currentStart = startState[next];
+        }
+
+        // ============== The main tokenizer code =================
+
+        int Scan()
+        {
+            try {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
+#if LEFTANCHORS
+                    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...
+                        GetCode();
+                    }
+                    
+#else // !LEFTANCHORS
+                    state = currentStart;
+                    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();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
+#if BACKUP
+                        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;
+                        }
+                        else
+#endif // BACKUP
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
+                        MarkEnd();
+#region ActionSwitch
+#pragma warning disable 162
+    switch (state)
+    {
+        case eofNum:
+            if (yywrap())
+                return (int)Tokens.EOF;
+            break;
+        case 1:
+return (int)Tokens.INUM;
+            break;
+        case 2:
+        case 4:
+LexError();
+	return (int)Tokens.EOF;
+            break;
+        case 3:
+int res = ScannerHelper.GetIDToken(yytext);
+  return res;
+            break;
+        case 5:
+return (int)Tokens.SEMICOLON;
+            break;
+        case 6:
+return (int)Tokens.ASSIGN;
+            break;
+        case 7:
+return (int)Tokens.RNUM;
+            break;
+        default:
+            break;
+    }
+#pragma warning restore 162
+#endregion
+                    }
+                }
+            } // end try
+            finally {
+// User-specified epilog to scan()
+yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+// End, user-specified epilog
+            } // end finally
+        }
+
+#if BACKUP
+        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;
+            ctx.lNum  = lNum;
+            ctx.state = state;
+            ctx.cChr  = code;
+        }
+
+        void RestoreStateAndPos(ref Context ctx)
+        {
+            buffer.Pos = ctx.bPos;
+            readPos = ctx.rPos;
+            cCol  = ctx.cCol;
+            lNum  = ctx.lNum;
+            state = ctx.state;
+            code  = ctx.cChr;
+        }
+
+#endif // BACKUP
+
+        // ============= End of the tokenizer code ================
+
+#if STACK        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void yy_clear_stack() { scStack.Clear(); }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int yy_top_state() { return scStack.Peek(); }
+        
+        internal void yy_push_state(int state)
+        {
+            scStack.Push(currentScOrd);
+            BEGIN(state);
+        }
+        
+        internal void yy_pop_state()
+        {
+            // Protect against input errors that pop too far ...
+            if (scStack.Count > 0) {
+				int newSc = scStack.Pop();
+				BEGIN(newSc);
+            } // Otherwise leave stack unchanged.
+        }
+ #endif // STACK
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void ECHO() { Console.Out.Write(yytext); }
+        
+#region UserCodeSection
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+	string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+    throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+  }
+  public static int GetIDToken(string s)
+  {
+    if (keywords.ContainsKey(s.ToLower())) // язык нечувствителен к регистру
+      return keywords[s];
+    else
+      return (int)Tokens.ID;
+  }
+}
+
+#endregion
+    } // end class $Scanner
+
+// ==============================================================
+// <auto-generated>
+// This code automatically produced from an embedded resource.
+// Do not edit this file, or it will become incompatible with 
+// the specification from which it was generated.
+// </auto-generated>
+// ==============================================================
+
+// Code copied from GPLEX embedded resource
+    [Serializable]
+    public class BufferException : Exception
+    {
+        public BufferException() { }
+        public BufferException(string message) : base(message) { }
+        public BufferException(string message, Exception innerException)
+            : base(message, innerException) { }
+        protected BufferException(SerializationInfo info, StreamingContext context)
+            : base(info, context) { }
+    }
+
+    public abstract class ScanBuff
+    {
+        private string fileNm;
+
+        public const int EndOfFile = -1;
+        public const int UnicodeReplacementChar = 0xFFFD;
+
+        public bool IsFile { get { return (fileNm != null); } }
+        public string FileName { get { return fileNm; } set { fileNm = value; } }
+
+        public abstract int Pos { get; set; }
+        public abstract int Read();
+        public virtual void Mark() { }
+
+        public abstract string GetString(int begin, int limit);
+
+        public static ScanBuff GetBuffer(string source)
+        {
+            return new StringBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(IList<string> source)
+        {
+            return new LineBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(Stream source)
+        {
+            return new BuildBuffer(source);
+        }
+
+#if (!BYTEMODE)
+        public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
+        {
+            return new BuildBuffer(source, fallbackCodePage);
+        }
+#endif
+    }
+
+    #region Buffer classes
+
+    // ==============================================================
+    // =====  Definitions for various ScanBuff derived classes   ====
+    // ==============================================================
+    // ===============         String input          ================
+    // ==============================================================
+
+    /// <summary>
+    /// This class reads characters from a single string as
+    /// required, for example, by Visual Studio language services
+    /// </summary>
+    sealed class StringBuffer : ScanBuff
+    {
+        string str;        // input buffer
+        int bPos;          // current position in buffer
+        int sLen;
+
+        public StringBuffer(string source)
+        {
+            this.str = source;
+            this.sLen = source.Length;
+            this.FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (bPos < sLen) return str[bPos++];
+            else if (bPos == sLen) { bPos++; return '\n'; }   // one strike, see new line
+            else { bPos++; return EndOfFile; }                // two strikes and you're out!
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            //  "limit" can be greater than sLen with the BABEL
+            //  option set.  Read returns a "virtual" EOL if
+            //  an attempt is made to read past the end of the
+            //  string buffer.  Without the guard any attempt 
+            //  to fetch yytext for a token that includes the 
+            //  EOL will throw an index exception.
+            if (limit > sLen) limit = sLen;
+            if (limit <= begin) return "";
+            else return str.Substring(begin, limit - begin);
+        }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+        public override string ToString() { return "StringBuffer"; }
+    }
+
+    // ==============================================================
+    //  The LineBuff class contributed by Nigel Horspool, 
+    //  nigelh@cs.uvic.cs
+    // ==============================================================
+
+    sealed class LineBuffer : ScanBuff
+    {
+        IList<string> line;    // list of source lines from a file
+        int numLines;          // number of strings in line list
+        string curLine;        // current line in that list
+        int cLine;             // index of current line in the list
+        int curLen;            // length of current line
+        int curLineStart;      // position of line start in whole file
+        int curLineEnd;        // position of line end in whole file
+        int maxPos;            // max position ever visited in whole file
+        int cPos;              // ordinal number of code in source
+
+        // Constructed from a list of strings, one per source line.
+        // The lines have had trailing '\n' characters removed.
+        public LineBuffer(IList<string> lineList)
+        {
+            line = lineList;
+            numLines = line.Count;
+            cPos = curLineStart = 0;
+            curLine = (numLines > 0 ? line[0] : "");
+            maxPos = curLineEnd = curLen = curLine.Length;
+            cLine = 1;
+            FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (cPos < curLineEnd)
+                return curLine[cPos++ - curLineStart];
+            if (cPos++ == curLineEnd)
+                return '\n';
+            if (cLine >= numLines)
+                return EndOfFile;
+            curLine = line[cLine];
+            curLen = curLine.Length;
+            curLineStart = curLineEnd + 1;
+            curLineEnd = curLineStart + curLen;
+            if (curLineEnd > maxPos)
+                maxPos = curLineEnd;
+            cLine++;
+            return curLen > 0 ? curLine[0] : '\n';
+        }
+
+        // To speed up searches for the line containing a position
+        private int cachedPosition;
+        private int cachedIxdex;
+        private int cachedLineStart;
+
+        // Given a position pos within the entire source, the results are
+        //   ix     -- the index of the containing line
+        //   lstart -- the position of the first character on that line
+        private void findIndex(int pos, out int ix, out int lstart)
+        {
+            if (pos >= cachedPosition)
+            {
+                ix = cachedIxdex; lstart = cachedLineStart;
+            }
+            else
+            {
+                ix = lstart = 0;
+            }
+            for (; ; )
+            {
+                int len = line[ix].Length + 1;
+                if (pos < lstart + len) break;
+                lstart += len;
+                ix++;
+            }
+            cachedPosition = pos;
+            cachedIxdex = ix;
+            cachedLineStart = lstart;
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            if (begin >= maxPos || limit <= begin) return "";
+            int endIx, begIx, endLineStart, begLineStart;
+            findIndex(begin, out begIx, out begLineStart);
+            int begCol = begin - begLineStart;
+            findIndex(limit, out endIx, out endLineStart);
+            int endCol = limit - endLineStart;
+            string s = line[begIx];
+            if (begIx == endIx)
+            {
+                // the usual case, substring all on one line
+                return (endCol <= s.Length) ?
+                    s.Substring(begCol, endCol - begCol)
+                    : s.Substring(begCol) + "\n";
+            }
+            // the string spans multiple lines, yuk!
+            StringBuilder sb = new StringBuilder();
+            if (begCol < s.Length)
+                sb.Append(s.Substring(begCol));
+            for (; ; )
+            {
+                sb.Append("\n");
+                s = line[++begIx];
+                if (begIx >= endIx) break;
+                sb.Append(s);
+            }
+            if (endCol <= s.Length)
+            {
+                sb.Append(s.Substring(0, endCol));
+            }
+            else
+            {
+                sb.Append(s);
+                sb.Append("\n");
+            }
+            return sb.ToString();
+        }
+
+        public override int Pos
+        {
+            get { return cPos; }
+            set
+            {
+                cPos = value;
+                findIndex(cPos, out cLine, out curLineStart);
+                curLine = line[cLine];
+                curLineEnd = curLineStart + curLine.Length;
+            }
+        }
+
+        public override string ToString() { return "LineBuffer"; }
+    }
+
+
+    // ==============================================================
+    // =====     class BuildBuff : for unicode text files    ========
+    // ==============================================================
+
+    class BuildBuffer : ScanBuff
+    {
+        // Double buffer for char stream.
+        class BufferElement
+        {
+            StringBuilder bldr = new StringBuilder();
+            StringBuilder next = new StringBuilder();
+            int minIx;
+            int maxIx;
+            int brkIx;
+            bool appendToNext;
+
+            internal BufferElement() { }
+
+            internal int MaxIndex { get { return maxIx; } }
+            // internal int MinIndex { get { return minIx; } }
+
+            internal char this[int index]
+            {
+                get
+                {
+                    if (index < minIx || index >= maxIx)
+                        throw new BufferException("Index was outside data buffer");
+                    else if (index < brkIx)
+                        return bldr[index - minIx];
+                    else
+                        return next[index - brkIx];
+                }
+            }
+
+            internal void Append(char[] block, int count)
+            {
+                maxIx += count;
+                if (appendToNext)
+                    this.next.Append(block, 0, count);
+                else
+                {
+                    this.bldr.Append(block, 0, count);
+                    brkIx = maxIx;
+                    appendToNext = true;
+                }
+            }
+
+            internal string GetString(int start, int limit)
+            {
+                if (limit <= start)
+                    return "";
+                if (start >= minIx && limit <= maxIx)
+                    if (limit < brkIx) // String entirely in bldr builder
+                        return bldr.ToString(start - minIx, limit - start);
+                    else if (start >= brkIx) // String entirely in next builder
+                        return next.ToString(start - brkIx, limit - start);
+                    else // Must do a string-concatenation
+                        return
+                            bldr.ToString(start - minIx, brkIx - start) +
+                            next.ToString(0, limit - brkIx);
+                else
+                    throw new BufferException("String was outside data buffer");
+            }
+
+            internal void Mark(int limit)
+            {
+                if (limit > brkIx + 16) // Rotate blocks
+                {
+                    StringBuilder temp = bldr;
+                    bldr = next;
+                    next = temp;
+                    next.Length = 0;
+                    minIx = brkIx;
+                    brkIx = maxIx;
+                }
+            }
+        }
+
+        BufferElement data = new BufferElement();
+
+        int bPos;            // Postion index in the StringBuilder
+        BlockReader NextBlk; // Delegate that serves char-arrays;
+
+        private string EncodingName
+        {
+            get
+            {
+                StreamReader rdr = NextBlk.Target as StreamReader;
+                return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
+            }
+        }
+
+        public BuildBuffer(Stream stream)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Raw(stream);
+        }
+
+#if (!BYTEMODE)
+        public BuildBuffer(Stream stream, int fallbackCodePage)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
+        }
+#endif
+
+        /// <summary>
+        /// Marks a conservative lower bound for the buffer,
+        /// allowing space to be reclaimed.  If an application 
+        /// needs to call GetString at arbitrary past locations 
+        /// in the input stream, Mark() is not called.
+        /// </summary>
+        public override void Mark() { data.Mark(bPos - 2); }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+
+        /// <summary>
+        /// Read returns the ordinal number of the next char, or 
+        /// EOF (-1) for an end of stream.  Note that the next
+        /// code point may require *two* calls of Read().
+        /// </summary>
+        /// <returns></returns>
+        public override int Read()
+        {
+            //
+            //  Characters at positions 
+            //  [data.offset, data.offset + data.bldr.Length)
+            //  are available in data.bldr.
+            //
+            if (bPos < data.MaxIndex)
+            {
+                // ch0 cannot be EOF
+                return (int)data[bPos++];
+            }
+            else // Read from underlying stream
+            {
+                // Experimental code, blocks of page size
+                char[] chrs = new char[4096];
+                int count = NextBlk(chrs, 0, 4096);
+                if (count == 0)
+                    return EndOfFile;
+                else
+                {
+                    data.Append(chrs, count);
+                    return (int)data[bPos++];
+                }
+            }
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            return data.GetString(begin, limit);
+        }
+
+        public override string ToString()
+        {
+            return "StringBuilder buffer, encoding: " + this.EncodingName;
+        }
+    }
+
+    // =============== End ScanBuff-derived classes ==================
+
+    public delegate int BlockReader(char[] block, int index, int number);
+
+    // A delegate factory, serving up a delegate that
+    // reads a block of characters from the underlying
+    // encoded stream, via a StreamReader object.
+    //
+    public static class BlockReaderFactory
+    {
+        public static BlockReader Raw(Stream stream)
+        {
+            return delegate(char[] block, int index, int number)
+            {
+                byte[] b = new byte[number];
+                int count = stream.Read(b, 0, number);
+                int i = 0;
+                int j = index;
+                for (; i < count; i++, j++)
+                    block[j] = (char)b[i];
+                return count;
+            };
+        }
+
+#if (!BYTEMODE)
+        public static BlockReader Get(Stream stream, int fallbackCodePage)
+        {
+            Encoding encoding;
+            int preamble = Preamble(stream);
+
+            if (preamble != 0)  // There is a valid BOM here!
+                encoding = Encoding.GetEncoding(preamble);
+            else if (fallbackCodePage == -1) // Fallback is "raw" bytes
+                return Raw(stream);
+            else if (fallbackCodePage != -2) // Anything but "guess"
+                encoding = Encoding.GetEncoding(fallbackCodePage);
+            else // This is the "guess" option
+            {
+                int guess = new Guesser(stream).GuessCodePage();
+                stream.Seek(0, SeekOrigin.Begin);
+                if (guess == -1) // ==> this is a 7-bit file
+                    encoding = Encoding.ASCII;
+                else if (guess == 65001)
+                    encoding = Encoding.UTF8;
+                else             // ==> use the machine default
+                    encoding = Encoding.Default;
+            }
+            StreamReader reader = new StreamReader(stream, encoding);
+            return reader.Read;
+        }
+
+        static int Preamble(Stream stream)
+        {
+            int b0 = stream.ReadByte();
+            int b1 = stream.ReadByte();
+
+            if (b0 == 0xfe && b1 == 0xff)
+                return 1201; // UTF16BE
+            if (b0 == 0xff && b1 == 0xfe)
+                return 1200; // UTF16LE
+
+            int b2 = stream.ReadByte();
+            if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
+                return 65001; // UTF8
+            //
+            // There is no unicode preamble, so we
+            // return denoter for the machine default.
+            //
+            stream.Seek(0, SeekOrigin.Begin);
+            return 0;
+        }
+#endif // !BYTEMODE
+    }
+    #endregion Buffer classes
+
+    // ==============================================================
+    // ============      class CodePageHandling         =============
+    // ==============================================================
+
+    public static class CodePageHandling
+    {
+        public static int GetCodePage(string option)
+        {
+            string command = option.ToUpperInvariant();
+            if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
+                command = command.Substring(9);
+            try
+            {
+                if (command.Equals("RAW"))
+                    return -1;
+                else if (command.Equals("GUESS"))
+                    return -2;
+                else if (command.Equals("DEFAULT"))
+                    return 0;
+                else if (char.IsDigit(command[0]))
+                    return int.Parse(command, CultureInfo.InvariantCulture);
+                else
+                {
+                    Encoding enc = Encoding.GetEncoding(command);
+                    return enc.CodePage;
+                }
+            }
+            catch (FormatException)
+            {
+                Console.Error.WriteLine(
+                    "Invalid format \"{0}\", using machine default", option);
+            }
+            catch (ArgumentException)
+            {
+                Console.Error.WriteLine(
+                    "Unknown code page \"{0}\", using machine default", option);
+            }
+            return 0;
+        }
+    }
+#region guesser
+#if (!BYTEMODE)
+    // ==============================================================
+    // ============          Encoding Guesser           =============
+    // ==============================================================
+
+    /// <summary>
+    /// This class provides a simple finite state automaton that
+    /// scans the file looking for (1) valid UTF-8 byte patterns,
+    /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
+    /// The method then guesses whether it is UTF-8 or maybe some 
+    /// local machine default encoding.  This works well for the
+    /// various Latin encodings.
+    /// </summary>
+    internal class Guesser
+    {
+        ScanBuff buffer;
+
+        public int GuessCodePage() { return Scan(); }
+
+        const int maxAccept = 10;
+        const int initial = 0;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+        const int EndToken = 0;
+
+        #region user code
+        /* 
+         *  Reads the bytes of a file to determine if it is 
+         *  UTF-8 or a single-byte code page file.
+         */
+        public long utfX;
+        public long uppr;
+        #endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;
+
+        #region ScannerTables
+        static int[] startState = new int[] { 11, 0 };
+
+        #region CharacterMap
+        static sbyte[] map = new sbyte[256] {
+/*     '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*   '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
+        #endregion
+
+        static sbyte[][] nextState = new sbyte[][] {
+            new sbyte[] {0, 0, 0, 0, 0, 0},
+            new sbyte[] {-1, -1, 10, -1, -1, -1},
+            new sbyte[] {-1, -1, -1, -1, -1, -1},
+            new sbyte[] {-1, -1, 8, -1, -1, -1},
+            new sbyte[] {-1, -1, 5, -1, -1, -1},
+            new sbyte[] {-1, -1, 6, -1, -1, -1},
+            new sbyte[] {-1, -1, 7, -1, -1, -1},
+            null,
+            new sbyte[] {-1, -1, 9, -1, -1, -1},
+            null,
+            null,
+            new sbyte[] {-1, 1, 2, 3, 4, 2}
+        };
+
+
+        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
+        // Reason for suppression: cannot have self-reference in array initializer.
+        static Guesser()
+        {
+            nextState[7] = nextState[2];
+            nextState[9] = nextState[2];
+            nextState[10] = nextState[2];
+        }
+
+        int NextState()
+        {
+            if (code == ScanBuff.EndOfFile)
+                return eofNum;
+            else
+                return nextState[state][map[code]];
+        }
+        #endregion
+
+        public Guesser(System.IO.Stream file) { SetSource(file); }
+
+        public void SetSource(System.IO.Stream source)
+        {
+            this.buffer = new BuildBuffer(source);
+            code = buffer.Read();
+        }
+
+        int Scan()
+        {
+            for (; ; )
+            {
+                int next;
+                state = currentStart;
+                while ((next = NextState()) == goStart)
+                    code = buffer.Read();
+
+                state = next;
+                code = buffer.Read();
+
+                while ((next = NextState()) > eofNum)
+                {
+                    state = next;
+                    code = buffer.Read();
+                }
+                if (state <= maxAccept)
+                {
+                    #region ActionSwitch
+#pragma warning disable 162
+                    switch (state)
+                    {
+                        case eofNum:
+                            switch (currentStart)
+                            {
+                                case 11:
+                                    if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
+                                    else if (uppr * 10 > utfX) return 0;   /* default code page */
+                                    else return 65001;                     /* UTF-8 encoding */
+                                    break;
+                            }
+                            return EndToken;
+                        case 1: // Recognized '{Upper128}',	Shortest string "\xC0"
+                        case 2: // Recognized '{Upper128}',	Shortest string "\x80"
+                        case 3: // Recognized '{Upper128}',	Shortest string "\xE0"
+                        case 4: // Recognized '{Upper128}',	Shortest string "\xF0"
+                            uppr++;
+                            break;
+                        case 5: // Recognized '{Utf8pfx4}{Utf8cont}',	Shortest string "\xF0\x80"
+                            uppr += 2;
+                            break;
+                        case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}',	Shortest string "\xF0\x80\x80"
+                            uppr += 3;
+                            break;
+                        case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}',	Shortest string "\xF0\x80\x80\x80"
+                            utfX += 3;
+                            break;
+                        case 8: // Recognized '{Utf8pfx3}{Utf8cont}',	Shortest string "\xE0\x80"
+                            uppr += 2;
+                            break;
+                        case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}',	Shortest string "\xE0\x80\x80"
+                            utfX += 2;
+                            break;
+                        case 10: // Recognized '{Utf8pfx2}{Utf8cont}',	Shortest string "\xC0\x80"
+                            utfX++;
+                            break;
+                        default:
+                            break;
+                    }
+#pragma warning restore 162
+                    #endregion
+                }
+            }
+        }
+    } // end class Guesser
+    
+#endif // !BYTEMODE
+#endregion
+
+// End of code copied from embedded resource
+
+} // end namespace
diff --git a/Module5/SimpleLanguage0/SimpleLex.lex b/Module5/SimpleLanguage0/SimpleLex.lex
new file mode 100644
index 0000000..10547e9
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleLex.lex
@@ -0,0 +1,74 @@
+%using SimpleParser;
+%using QUT.Gppg;
+%using System.Linq;
+
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+
+%%
+
+{INTNUM} { 
+  return (int)Tokens.INUM; 
+}
+
+{REALNUM} { 
+  return (int)Tokens.RNUM;
+}
+
+{ID}  { 
+  int res = ScannerHelper.GetIDToken(yytext);
+  return res;
+}
+
+":=" { return (int)Tokens.ASSIGN; }
+";"  { return (int)Tokens.SEMICOLON; }
+
+[^ \r\n] {
+	LexError();
+	return (int)Tokens.EOF; // конец разбора
+}
+
+%{
+  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol); // позиция символа (терминального или нетерминального), возвращаемая @1 @2 и т.д.
+%}
+
+%%
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+	string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+    throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+  }
+  public static int GetIDToken(string s)
+  {
+    if (keywords.ContainsKey(s.ToLower())) // язык нечувствителен к регистру
+      return keywords[s];
+    else
+      return (int)Tokens.ID;
+  }
+}
diff --git a/Module5/SimpleLanguage0/SimpleYacc.cs b/Module5/SimpleLanguage0/SimpleYacc.cs
new file mode 100644
index 0000000..d5c2289
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleYacc.cs
@@ -0,0 +1,112 @@
+// This code was generated by the Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2010
+// (see accompanying GPPGcopyright.rtf)
+
+// GPPG version 1.3.6
+// Machine:  HUB
+// DateTime: 21.09.2017 20:15:14
+// UserName: someone
+// Input file <SimpleYacc.y>
+
+// options: no-lines gplex
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using QUT.Gppg;
+
+namespace SimpleParser
+{
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,INUM=6,
+    RNUM=7,ID=8,ASSIGN=9,SEMICOLON=10};
+
+// Abstract base class for GPLEX scanners
+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; }
+}
+
+public class Parser: ShiftReduceParser<int, LexLocation>
+{
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public Parser(AbstractScanner<int, LexLocation> scanner) : base(scanner) { }
+  // End verbatim content from SimpleYacc.y
+
+#pragma warning disable 649
+  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 string[] nonTerms = new string[] {
+      "progr", "$accept", "block", "stlist", "statement", "assign", "cycle", 
+      "ident", "expr", };
+
+  static Parser() {
+    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[]{8,14,3,4,5,18},new int[]{-4,5,-5,21,-6,9,-8,10,-3,16,-7,17});
+    states[5] = new State(new int[]{4,6,10,7});
+    states[6] = new State(-12);
+    states[7] = new State(new int[]{8,14,3,4,5,18},new int[]{-5,8,-6,9,-8,10,-3,16,-7,17});
+    states[8] = new State(-4);
+    states[9] = new State(-5);
+    states[10] = new State(new int[]{9,11});
+    states[11] = new State(new int[]{8,14,6,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[]{8,14,6,15},new int[]{-9,19,-8,13});
+    states[19] = new State(new int[]{8,14,3,4,5,18},new int[]{-5,20,-6,9,-8,10,-3,16,-7,17});
+    states[20] = new State(-13);
+    states[21] = new State(-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,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[]{8});
+    rules[9] = new Rule(-6, new int[]{-8,9,-9});
+    rules[10] = new Rule(-9, new int[]{-8});
+    rules[11] = new Rule(-9, new int[]{6});
+    rules[12] = new Rule(-3, new int[]{3,-4,4});
+    rules[13] = new Rule(-7, new int[]{5,-9,-5});
+  }
+
+  protected override void Initialize() {
+    this.InitSpecialTokens((int)Tokens.error, (int)Tokens.EOF);
+    this.InitStates(states);
+    this.InitRules(rules);
+    this.InitNonTerminals(nonTerms);
+  }
+
+  protected override void DoAction(int action)
+  {
+    switch (action)
+    {
+    }
+  }
+
+  protected override string TerminalToString(int 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/Module5/SimpleLanguage0/SimpleYacc.lst b/Module5/SimpleLanguage0/SimpleYacc.lst
new file mode 100644
index 0000000..6a40f2d
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleYacc.lst
@@ -0,0 +1,64 @@
+
+// ==========================================================================
+//  GPPG error listing for yacc source file <SimpleYacc.y>
+// ==========================================================================
+//  Version:  1.3.6
+//  Machine:  SSM
+//  DateTime: 17.08.2014 10:25:15
+//  UserName: Станислав
+// ==========================================================================
+
+
+%{
+// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
+    public Parser(AbstractScanner<int, LexLocation> scanner) : base(scanner) { }
+%}
+
+%output = SimpleYacc.cs
+
+%using System.IO;
+
+%namespace SimpleParser
+
+%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON  
+
+%%
+// 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}
+// ------------------------------------------------------------------
+
+progr   : block
+		;
+
+stlist	: statement 
+		| stlist SEMICOLON statement 
+		;
+
+statement: assign
+		| block  
+		| cycle  
+		;
+
+ident 	: ID 
+		;
+	
+assign 	: ident ASSIGN expr 
+		;
+
+expr	: ident  
+		| INUM 
+		;
+
+block	: BEGIN stlist END 
+		;
+
+cycle	: CYCLE expr st 
+		;
+	
+%%
+
+// ==========================================================================
+
diff --git a/Module5/SimpleLanguage0/SimpleYacc.y b/Module5/SimpleLanguage0/SimpleYacc.y
new file mode 100644
index 0000000..9594732
--- /dev/null
+++ b/Module5/SimpleLanguage0/SimpleYacc.y
@@ -0,0 +1,42 @@
+%{
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public Parser(AbstractScanner<int, LexLocation> scanner) : base(scanner) { }
+%}
+
+%output = SimpleYacc.cs
+
+%namespace SimpleParser
+
+%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON  
+
+%%
+
+progr   : block
+		;
+
+stlist	: statement 
+		| stlist SEMICOLON statement 
+		;
+
+statement: assign
+		| block  
+		| cycle  
+		;
+
+ident 	: ID 
+		;
+	
+assign 	: ident ASSIGN expr 
+		;
+
+expr	: ident  
+		| INUM 
+		;
+
+block	: BEGIN stlist END 
+		;
+
+cycle	: CYCLE expr statement 
+		;
+	
+%%
diff --git a/Module5/SimpleLanguage0/a.txt b/Module5/SimpleLanguage0/a.txt
new file mode 100644
index 0000000..52ea170
--- /dev/null
+++ b/Module5/SimpleLanguage0/a.txt
@@ -0,0 +1,10 @@
+begin
+  b := 2;
+  a := 3;
+  a := b;
+  cycle 3
+  begin
+    a := c;
+    c := 1
+  end
+end
diff --git a/Module5/SimpleLanguage0/generateParserScanner.bat b/Module5/SimpleLanguage0/generateParserScanner.bat
new file mode 100644
index 0000000..7ca5476
--- /dev/null
+++ b/Module5/SimpleLanguage0/generateParserScanner.bat
@@ -0,0 +1,3 @@
+cls
+gplex.exe /unicode SimpleLex.lex
+gppg.exe /no-lines /gplex SimpleYacc.y
diff --git a/Module6/SimpleLanguage1/Main.cs b/Module6/SimpleLanguage1/Main.cs
new file mode 100644
index 0000000..01f9c95
--- /dev/null
+++ b/Module6/SimpleLanguage1/Main.cs
@@ -0,0 +1,50 @@
+п»їusing System;
+using System.IO;
+using System.Collections.Generic;
+using SimpleScanner;
+using SimpleParser;
+
+namespace SimpleCompiler
+{
+    public class SimpleCompilerMain
+    {
+        public static void Main()
+        {
+            string FileName = @"..\..\a.txt";
+            try
+            {
+                string Text = File.ReadAllText(FileName);
+
+                Scanner scanner = new Scanner();
+                scanner.SetSource(Text, 0);
+
+                Parser parser = new Parser(scanner);
+
+                var b = parser.Parse();
+                if (!b)
+                    Console.WriteLine("Ошибка");
+                else
+                {
+                    Console.WriteLine("Синтаксическое дерево построено");
+                    //foreach (var st in parser.root.StList)
+                    //Console.WriteLine(st);
+                }
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("Файл {0} не найден", FileName);
+            }
+            catch (LexException e)
+            {
+                Console.WriteLine("Лексическая ошибка. " + e.Message);
+            }
+            catch (SyntaxException e)
+            {
+                Console.WriteLine("Синтаксическая ошибка. " + e.Message);
+            }
+
+            Console.ReadLine();
+        }
+
+    }
+}
diff --git a/Module6/SimpleLanguage1/ParserHelper.cs b/Module6/SimpleLanguage1/ParserHelper.cs
new file mode 100644
index 0000000..1e2138c
--- /dev/null
+++ b/Module6/SimpleLanguage1/ParserHelper.cs
@@ -0,0 +1,18 @@
+п»їusing System;
+
+namespace SimpleParser
+{
+    public class LexException : Exception
+    {
+        public LexException(string msg) : base(msg) { }
+    }
+    public class SyntaxException : Exception
+    {
+        public SyntaxException(string msg) : base(msg) { }
+    }
+    // Класс глобальных описаний и статических методов
+    // для использования различными подсистемами парсера и сканера
+    public static class ParserHelper
+    {
+    }
+}
\ No newline at end of file
diff --git a/Module6/SimpleLanguage1/ProgramTree.cs b/Module6/SimpleLanguage1/ProgramTree.cs
new file mode 100644
index 0000000..ade12f7
--- /dev/null
+++ b/Module6/SimpleLanguage1/ProgramTree.cs
@@ -0,0 +1,68 @@
+п»їusing System.Collections.Generic;
+
+namespace ProgramTree
+{
+    public enum AssignType { Assign, AssignPlus, AssignMinus, AssignMult, AssignDivide };
+
+    public class Node // базовый класс для всех узлов    
+    {
+    }
+
+    public class ExprNode : Node // базовый класс для всех выражений
+    {
+    }
+
+    public class IdNode : ExprNode
+    {
+        public string Name { get; set; }
+        public IdNode(string name) { Name = name; }
+    }
+
+    public class IntNumNode : ExprNode
+    {
+        public int Num { get; set; }
+        public IntNumNode(int num) { Num = num; }
+    }
+
+    public class StatementNode : Node // базовый класс для всех операторов
+    {
+    }
+
+    public class AssignNode : StatementNode
+    {
+        public IdNode Id { get; set; }
+        public ExprNode Expr { get; set; }
+        public AssignType AssOp { get; set; }
+        public AssignNode(IdNode id, ExprNode expr, AssignType assop = AssignType.Assign)
+        {
+            Id = id;
+            Expr = expr;
+            AssOp = assop;
+        }
+    }
+
+    public class CycleNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode Stat { get; set; }
+        public CycleNode(ExprNode expr, StatementNode stat)
+        {
+            Expr = expr;
+            Stat = stat;
+        }
+    }
+
+    public class BlockNode : StatementNode
+    {
+        public List<StatementNode> StList = new List<StatementNode>();
+        public BlockNode(StatementNode stat)
+        {
+            Add(stat);
+        }
+        public void Add(StatementNode stat)
+        {
+            StList.Add(stat);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/Module6/SimpleLanguage1/Properties/AssemblyInfo.cs b/Module6/SimpleLanguage1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..896cc99
--- /dev/null
+++ b/Module6/SimpleLanguage1/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+п»їusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью 
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("SimpleLang")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SimpleLang")]
+[assembly: AssemblyCopyright("Copyright В©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми 
+// для COM-компонентов.  Если требуется обратиться к типу в этой сборке через 
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("06dba63f-4805-4cd3-8a93-b329b2c7e37b")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+//      Основной номер версии
+//      Дополнительный номер версии 
+//      Номер построения
+//      Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию, 
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Module6/SimpleLanguage1/ShiftReduceParserCode.cs b/Module6/SimpleLanguage1/ShiftReduceParserCode.cs
new file mode 100644
index 0000000..c110ba1
--- /dev/null
+++ b/Module6/SimpleLanguage1/ShiftReduceParserCode.cs
@@ -0,0 +1,944 @@
+// Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2009
+// (see accompanying GPPGcopyright.rtf)
+#define EXPORT_GPPG
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+namespace QUT.Gppg
+{
+    /// <summary>
+    /// Abstract class for GPPG shift-reduce parsers.
+    /// Parsers generated by GPPG derive from this base
+    /// class, overriding the abstract Initialize() and
+    /// DoAction() methods.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type</typeparam>
+    /// <typeparam name="TSpan">Location type</typeparam>
+#if EXPORT_GPPG
+    public abstract class ShiftReduceParser<TValue, TSpan>
+#else
+    internal abstract class ShiftReduceParser<TValue, TSpan>
+#endif
+ where TSpan : IMerge<TSpan>, new()
+    {
+        public AbstractScanner<TValue, TSpan> scanner;
+        /// <summary>
+        /// The abstract scanner for this parser.
+        /// </summary>
+        protected AbstractScanner<TValue, TSpan> Scanner {
+            get { return scanner; }
+            set { scanner = value; }
+        }
+
+        /// <summary>
+        /// Constructor for base class
+        /// </summary>
+        /// <param name="scanner">Scanner instance for this parser</param>
+        protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
+        {
+            this.scanner = scanner;
+        }
+
+        // ==============================================================
+        //                    TECHNICAL EXPLANATION.
+        //   Why the next two fields are not exposed via properties.
+        // ==============================================================
+        // These fields are of the generic parameter types, and are
+        // frequently instantiated as struct types in derived classes.
+        // Semantic actions are defined in the derived classes and refer
+        // to instance fields of these structs.  Is such cases the code
+        // "get_CurrentSemanticValue().myField = blah;" will fail since
+        // the getter pushes the value of the field, not the reference.
+        // So, in the presence of properties, gppg would need to encode
+        // such field accesses as ... 
+        //  "tmp = get_CurrentSemanticValue(); // Fetch value
+        //   tmp.myField = blah;               // update
+        //   set_CurrentSemanticValue(tmp); "  // Write update back.
+        // There is no issue if TValue is restricted to be a ref type.
+        // The same explanation applies to scanner.yylval.
+        // ==============================================================
+        /// <summary>
+        /// The current value of the "$$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TValue CurrentSemanticValue;
+
+        /// <summary>
+        /// The current value of the "@$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TSpan CurrentLocationSpan;
+
+        private TSpan LastSpan;
+        private int NextToken;
+        private State FsaState;
+        private bool recovering;
+        private int tokensSinceLastError;
+
+        private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
+        private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
+        private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
+
+        /// <summary>
+        /// The stack of semantic value (YYSTYPE) values.
+        /// </summary>
+        protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
+
+        /// <summary>
+        /// The stack of location value (YYLTYPE) varlues.
+        /// </summary>
+        protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
+
+        private int errorToken;
+        private int endOfFileToken;
+        private string[] nonTerminals;
+        private State[] states;
+        private Rule[] rules;
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the rule list into this base class.
+        /// </summary>
+        /// <param name="rules">The array of Rule objects</param>
+        protected void InitRules(Rule[] rules) { this.rules = rules; }
+
+      /// <summary>
+      /// Initialization method to allow derived classes to
+      /// insert the states table into this base class.
+      /// </summary>
+      /// <param name="states">The pre-initialized states table</param>
+        protected void InitStates(State[] states) { this.states = states; }
+
+      /// <summary>
+      /// OBSOLETE FOR VERSION 1.4.0
+      /// </summary>
+      /// <param name="size"></param>
+        protected void InitStateTable(int size) { states = new State[size]; }
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the special value for the error and EOF tokens.
+        /// </summary>
+        /// <param name="err">The error state ordinal</param>
+        /// <param name="end">The EOF stat ordinal</param>
+        protected void InitSpecialTokens(int err, int end)
+        {
+            errorToken = err;
+            endOfFileToken = end;
+        }
+
+        /// <summary>
+        /// Initialization method to allow derived classes to
+        /// insert the non-terminal symbol names into this base class.
+        /// </summary>
+        /// <param name="names">Non-terminal symbol names</param>
+        protected void InitNonTerminals(string[] names) { nonTerminals = names; }
+
+        #region YYAbort, YYAccept etcetera.
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AcceptException : Exception
+        {
+            internal AcceptException() { }
+            protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AbortException : Exception
+        {
+            internal AbortException() { }
+            protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class ErrorException : Exception
+        {
+            internal ErrorException() { }
+            protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+
+        // The following methods are only called from within
+        // a semantic action. The thrown exceptions can never
+        // propagate outside the ShiftReduceParser class in 
+        // which they are nested.
+
+        /// <summary>
+        /// Force parser to terminate, returning "true"
+        /// </summary>
+        protected static void YYAccept() { throw new AcceptException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning "false"
+        /// </summary>
+        protected static void YYAbort() { throw new AbortException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning
+        /// "false" if error recovery fails.
+        /// </summary>
+        protected static void YYError() { throw new ErrorException(); }
+
+        /// <summary>
+        /// Check if parser in error recovery state.
+        /// </summary>
+        protected bool YYRecovering { get { return recovering; } }
+        #endregion
+
+        /// <summary>
+        /// Abstract base method. ShiftReduceParser calls this
+        /// to initialize the base class data structures.  Concrete
+        /// parser classes must override this method.
+        /// </summary>
+        protected abstract void Initialize();
+
+        /// <summary>
+        /// Main entry point of the Shift-Reduce Parser.
+        /// </summary>
+        /// <returns>True if parse succeeds, else false for
+        /// unrecoverable errors</returns>
+        public bool Parse()
+        {
+            Initialize();	// allow derived classes to instantiate rules, states and nonTerminals
+
+            NextToken = 0;
+            FsaState = states[0];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+
+            while (true)
+            {
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+                int action = FsaState.defaultAction;
+
+                if (FsaState.ParserTable != null)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif
+                        // We save the last token span, so that the location span
+                        // of production right hand sides that begin or end with a
+                        // nullable production will be correct.
+                        LastSpan = scanner.yylloc;
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+                }
+
+                if (action > 0)         // shift
+                {
+                    Shift(action);
+                }
+                else if (action < 0)   // reduce
+                {
+                    try
+                    {
+                        Reduce(-action);
+                        if (action == -1)	// accept
+                            return true;
+                    }
+                    catch (Exception x)
+                    {
+                        if (x is AbortException)
+                            return false;
+                        else if (x is AcceptException)
+                            return true;
+                        else if (x is ErrorException && !ErrorRecovery())
+                            return false;
+                        else
+                            throw;  // Rethrow x, preserving information.
+
+                    }
+                }
+                else if (action == 0)   // error
+                    if (!ErrorRecovery())
+                        return false;
+            }
+        }
+
+        private void Shift(int stateIndex)
+        {
+#if TRACE_ACTIONS
+				Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
+#endif
+            FsaState = states[stateIndex];
+
+            valueStack.Push(scanner.yylval);
+            StateStack.Push(FsaState);
+            LocationStack.Push(scanner.yylloc);
+
+            if (recovering)
+            {
+                if (NextToken != errorToken)
+                    tokensSinceLastError++;
+
+                if (tokensSinceLastError > 5)
+                    recovering = false;
+            }
+
+            if (NextToken != endOfFileToken)
+                NextToken = 0;
+        }
+
+        private void Reduce(int ruleNumber)
+        {
+#if TRACE_ACTIONS
+				DisplayRule(ruleNumber);
+#endif
+            Rule rule = rules[ruleNumber];
+            //
+            //  Default actions for unit productions.
+            //
+            if (rule.RightHandSide.Length == 1)
+            {
+                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
+                CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
+            }
+            else
+            {
+                if (rule.RightHandSide.Length == 0)
+                {
+                    // Create a new blank value.
+                    // Explicit semantic action may mutate this value
+                    CurrentSemanticValue = default(TValue);
+                    // The location span for an empty production will start with the
+                    // beginning of the next lexeme, and end with the finish of the
+                    // previous lexeme.  This gives the correct behaviour when this
+                    // nonsense value is used in later Merge operations.
+                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
+                        scanner.yylloc.Merge(LastSpan) :
+                        default(TSpan));
+                }
+                else
+                {
+                    // Default action: $$ = $1;
+                    CurrentSemanticValue = valueStack.TopElement();
+                    //  Default action "@$ = @1.Merge(@N)" for location info.
+                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
+                    TSpan atN = LocationStack[LocationStack.Depth - 1];
+                    CurrentLocationSpan = 
+                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
+                }
+            }
+
+            DoAction(ruleNumber);
+
+            for (int i = 0; i < rule.RightHandSide.Length; i++)
+            {
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+            }
+
+#if TRACE_ACTIONS
+				DisplayStack();
+#endif
+            FsaState = StateStack.TopElement();
+
+            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
+                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+        }
+
+        /// <summary>
+        /// Execute the selected action from array.
+        /// Must be overriden in derived classes.
+        /// </summary>
+        /// <param name="actionNumber">Index of the action to perform</param>
+        protected abstract void DoAction(int actionNumber);
+
+        private bool ErrorRecovery()
+        {
+            bool discard;
+
+            if (!recovering) // if not recovering from previous error
+                ReportError();
+
+            if (!FindErrorRecoveryState())
+                return false;
+            //
+            //  The interim fix for the "looping in error recovery"
+            //  artifact involved moving the setting of the recovering 
+            //  bool until after invalid tokens have been discarded.
+            //
+            ShiftErrorToken();
+            discard = DiscardInvalidTokens();
+            recovering = true;
+            tokensSinceLastError = 0;
+            return discard;
+        }
+
+        private void ReportError1()
+        {
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
+
+            if (FsaState.ParserTable.Count < 7)
+            {
+                bool first = true;
+                foreach (int terminal in FsaState.ParserTable.Keys)
+                {
+                    if (first)
+                        errorMsg.Append(", expecting ");
+                    else
+                        errorMsg.Append(", or ");
+
+                    errorMsg.Append(TerminalToString(terminal));
+                    first = false;
+                }
+            }
+            scanner.yyerror(errorMsg.ToString());
+        }
+
+        private void ReportError()
+        {
+            object[] args = new object[FsaState.ParserTable.Keys.Count+1];
+            args[0] = TerminalToString(NextToken);
+            int i=1;
+            foreach (int terminal in FsaState.ParserTable.Keys)
+            {
+                args[i] = TerminalToString(terminal);
+                i++;
+            }
+            scanner.yyerror("",args);
+        }
+
+        private void ShiftErrorToken()
+        {
+            int old_next = NextToken;
+            NextToken = errorToken;
+
+            Shift(FsaState.ParserTable[NextToken]);
+
+#if TRACE_ACTIONS
+				Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+            NextToken = old_next;
+        }
+
+        private bool FindErrorRecoveryState()
+        {
+            while (true)    // pop states until one found that accepts error token
+            {
+                if (FsaState.ParserTable != null &&
+                    FsaState.ParserTable.ContainsKey(errorToken) &&
+                    FsaState.ParserTable[errorToken] > 0) // shift
+                    return true;
+
+#if TRACE_ACTIONS
+					Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
+#endif
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+
+#if TRACE_ACTIONS
+					DisplayStack();
+#endif
+                if (StateStack.IsEmpty())
+                {
+#if TRACE_ACTIONS
+                        Console.Error.Write("Aborting: didn't find a state that accepts error token");
+#endif
+                    return false;
+                }
+                else
+                    FsaState = StateStack.TopElement();
+            }
+        }
+
+        private bool DiscardInvalidTokens()
+        {
+
+            int action = FsaState.defaultAction;
+
+            if (FsaState.ParserTable != null)
+            {
+                // Discard tokens until find one that works ...
+                while (true)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif                       
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (NextToken == endOfFileToken)
+                        return false;
+
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+
+                    if (action != 0)
+                        return true;
+                    else
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
+#endif
+                        NextToken = 0;
+                    }
+                }
+            }
+            else if (recovering && tokensSinceLastError == 0)
+            {
+                // 
+                //  Boolean recovering is not set until after the first
+                //  error token has been shifted.  Thus if we get back 
+                //  here with recovering set and no tokens read we are
+                //  looping on the same error recovery action.  This 
+                //  happens if current_state.ParserTable is null because
+                //  the state has an LR(0) reduction, but not all
+                //  lookahead tokens are valid.  This only occurs for
+                //  error productions that *end* on "error".
+                //
+                //  This action discards tokens one at a time until
+                //  the looping stops.  Another attack would be to always
+                //  use the LALR(1) table if a production ends on "error"
+                //
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
+#endif
+                if (NextToken == endOfFileToken)
+                    return false;
+                NextToken = 0;
+                return true;
+            }
+            else
+                return true;
+
+        }
+
+        /// <summary>
+        /// Traditional YACC method.  Discards the next input token.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyclearin() { NextToken = 0; }
+
+        /// <summary>
+        /// Tradional YACC method. Clear the "recovering" flag.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyerrok()
+        {
+            recovering = false;
+        }
+
+        /// <summary>
+        /// OBSOLETE FOR VERSION 1.4.0
+        /// Method used by derived types to insert new
+        /// state instances in the "states" array.
+        /// </summary>
+        /// <param name="stateNumber">index of the state</param>
+        /// <param name="state">data for the state</param>
+        protected void AddState(int stateNumber, State state)
+        {
+            states[stateNumber] = state;
+            state.number = stateNumber;
+        }
+
+        private void DisplayStack()
+        {
+            Console.Error.Write("State now");
+            for (int i = 0; i < StateStack.Depth; i++)
+                Console.Error.Write(" {0}", StateStack[i].number);
+            Console.Error.WriteLine();
+        }
+
+        private void DisplayRule(int ruleNumber)
+        {
+            Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
+            DisplayProduction(rules[ruleNumber]);
+        }
+
+        private void DisplayProduction(Rule rule)
+        {
+            if (rule.RightHandSide.Length == 0)
+                Console.Error.Write("/* empty */ ");
+            else
+                foreach (int symbol in rule.RightHandSide)
+                    Console.Error.Write("{0} ", SymbolToString(symbol));
+
+            Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
+        }
+
+        /// <summary>
+        /// Abstract state class naming terminal symbols.
+        /// This is overridden by derived classes with the
+        /// name (or alias) to be used in error messages.
+        /// </summary>
+        /// <param name="terminal">The terminal ordinal</param>
+        /// <returns></returns>
+        protected abstract string TerminalToString(int terminal);
+
+        private string SymbolToString(int symbol)
+        {
+            if (symbol < 0)
+                return nonTerminals[-symbol];
+            else
+                return TerminalToString(symbol);
+        }
+
+        /// <summary>
+        /// Return text representation of argument character
+        /// </summary>
+        /// <param name="input">The character to convert</param>
+        /// <returns>String representation of the character</returns>
+        protected static string CharToString(char input)
+        {
+            switch (input)
+            {
+                case '\a': return @"'\a'";
+                case '\b': return @"'\b'";
+                case '\f': return @"'\f'";
+                case '\n': return @"'\n'";
+                case '\r': return @"'\r'";
+                case '\t': return @"'\t'";
+                case '\v': return @"'\v'";
+                case '\0': return @"'\0'";
+                default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Classes implementing this interface must supply a
+    /// method that merges two location objects to return
+    /// a new object of the same type.
+    /// GPPG-generated parsers have the default location
+    /// action equivalent to "@$ = @1.Merge(@N);" where N
+    /// is the right-hand-side length of the production.
+    /// </summary>
+    /// <typeparam name="TSpan">The Location type</typeparam>
+#if EXPORT_GPPG
+    public interface IMerge<TSpan>
+#else
+    internal interface IMerge<TSpan>
+#endif
+    {
+        /// <summary>
+        /// Interface method that creates a location object from
+        /// the current and last object.  Typically used to create
+        /// a location object extending from the start of the @1
+        /// object to the end of the @N object.
+        /// </summary>
+        /// <param name="last">The lexically last object to merge</param>
+        /// <returns>The merged location object</returns>
+        TSpan Merge(TSpan last);
+    }
+
+    /// <summary>
+    /// This is the default class that carries location
+    /// information from the scanner to the parser.
+    /// If you don't declare "%YYLTYPE Foo" the parser
+    /// will expect to deal with this type.
+    /// </summary>
+#if EXPORT_GPPG
+    public class LexLocation : IMerge<LexLocation>
+#else
+    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
+    internal class LexLocation : IMerge<LexLocation>
+#endif
+    {
+        private int startLine;   // start line
+        private int startColumn; // start column
+        private int endLine;     // end line
+        private int endColumn;   // end column
+
+        /// <summary>
+        /// The line at which the text span starts.
+        /// </summary>
+        public int StartLine { get { return startLine; } }
+
+        /// <summary>
+        /// The column at which the text span starts.
+        /// </summary>
+        public int StartColumn { get { return startColumn; } }
+
+        /// <summary>
+        /// The line on which the text span ends.
+        /// </summary>
+        public int EndLine { get { return endLine; } }
+
+        /// <summary>
+        /// The column of the first character
+        /// beyond the end of the text span.
+        /// </summary>
+        public int EndColumn { get { return endColumn; } }
+
+        /// <summary>
+        /// Default no-arg constructor.
+        /// </summary>
+        public LexLocation()
+        { }
+
+        /// <summary>
+        /// Constructor for text-span with given start and end.
+        /// </summary>
+        /// <param name="sl">start line</param>
+        /// <param name="sc">start column</param>
+        /// <param name="el">end line </param>
+        /// <param name="ec">end column</param>
+        public LexLocation(int sl, int sc, int el, int ec)
+        { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
+
+        /// <summary>
+        /// Create a text location which spans from the 
+        /// start of "this" to the end of the argument "last"
+        /// </summary>
+        /// <param name="last">The last location in the result span</param>
+        /// <returns>The merged span</returns>
+        public LexLocation Merge(LexLocation last)
+        { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
+
+    }
+
+    /// <summary>
+    /// Abstract scanner class that GPPG expects its scanners to 
+    /// extend.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
+    /// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
+#if EXPORT_GPPG
+    public abstract class AbstractScanner<TValue, TSpan>
+#else
+    internal abstract class AbstractScanner<TValue, TSpan>
+#endif
+        where TSpan : IMerge<TSpan>
+    {
+        /// <summary>
+        /// Lexical value optionally set by the scanner. The value
+        /// is of the %YYSTYPE type declared in the parser spec.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        // A field must be declared for this value of parametric type,
+        // since it may be instantiated by a value struct.  If it were 
+        // implemented as a property, machine generated code in derived
+        // types would not be able to select on the returned value.
+        public TValue yylval;                     // Lexical value: set by scanner
+
+        /// <summary>
+        /// Current scanner location property. The value is of the
+        /// type declared by %YYLTYPE in the parser specification.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual TSpan yylloc
+        {
+            get { return default(TSpan); }       // Empty implementation allowing
+            set { /* skip */ }                   // yylloc to be ignored entirely.
+        }
+
+        /// <summary>
+        /// Main call point for LEX-like scanners.  Returns an int
+        /// corresponding to the token recognized by the scanner.
+        /// </summary>
+        /// <returns>An int corresponding to the token</returns>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public abstract int yylex();
+
+        /// <summary>
+        /// Traditional error reporting provided by LEX-like scanners
+        /// to their YACC-like clients.
+        /// </summary>
+        /// <param name="format">Message format string</param>
+        /// <param name="args">Optional array of args</param>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual void yyerror(string format, params object[] args) { }
+    }
+
+    /// <summary>
+    /// Encapsulated state for the parser.
+    /// Opaque to users, visible to the tool-generated code.
+    /// </summary>
+#if EXPORT_GPPG
+    public class State
+#else
+    internal class State
+#endif
+    {
+        internal int number;
+        internal Dictionary<int, int> ParserTable;   // Terminal -> ParseAction
+        internal Dictionary<int, int> Goto;          // NonTerminal -> State;
+        internal int defaultAction; // = 0;		     // ParseAction
+
+        /// <summary>
+        /// State transition data for this state. Pairs of elements of the 
+        /// goto array associate symbol ordinals with next state indices.
+        /// The actions array is passed to another constructor. 
+        /// </summary>
+        /// <param name="actions">The action list</param>
+        /// <param name="goToList">Next state data</param>
+        public State(int[] actions, int[] goToList)
+            : this(actions)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+
+        /// <summary>
+        /// Action data for this state. Pairs of elements of the 
+        /// action array associate action ordinals with each of
+        /// those symbols that have actions in the current state.
+        /// </summary>
+        /// <param name="actions">The action array</param>
+        public State(int[] actions)
+        {
+            ParserTable = new Dictionary<int, int>();
+            for (int i = 0; i < actions.Length; i += 2)
+                ParserTable.Add(actions[i], actions[i + 1]);
+        }
+
+        /// <summary>
+        /// Set the default action for this state.
+        /// </summary>
+        /// <param name="defaultAction">Ordinal of the default action</param>
+        public State(int defaultAction)
+        {
+            this.defaultAction = defaultAction;
+        }
+
+        /// <summary>
+        /// Set the default action and the state transition table.
+        /// </summary>
+        /// <param name="defaultAction">The default action</param>
+        /// <param name="goToList">Transitions from this state</param>
+        public State(int defaultAction, int[] goToList)
+            : this(defaultAction)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+    }
+
+    /// <summary>
+    /// Rule representation at runtime.
+    /// </summary>
+#if EXPORT_GPPG
+    public class Rule
+#else
+    internal class Rule
+#endif
+    {
+        internal int LeftHandSide; // symbol
+        internal int[] RightHandSide; // symbols
+
+        /// <summary>
+        /// Rule constructor.  This holds the ordinal of
+        /// the left hand side symbol, and the list of
+        /// right hand side symbols, in lexical order.
+        /// </summary>
+        /// <param name="left">The LHS non-terminal</param>
+        /// <param name="right">The RHS symbols, in lexical order</param>
+        public Rule(int left, int[] right)
+        {
+            this.LeftHandSide = left;
+            this.RightHandSide = right;
+        }
+    }
+
+    /// <summary>
+    /// Stack utility for the shift-reduce parser.
+    /// GPPG parsers have three instances:
+    /// (1) The parser state stack, T = QUT.Gppg.State,
+    /// (2) The semantic value stack, T = TValue,
+    /// (3) The location stack, T = TSpan.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if EXPORT_GPPG
+    public class PushdownPrefixState<T>
+#else
+    internal class PushdownPrefixState<T>
+#endif
+    {
+        //  Note that we cannot use the BCL Stack<T> class
+        //  here as derived types need to index into stacks.
+        //
+        private T[] array = new T[8];
+        private int tos = 0;
+
+        /// <summary>
+        /// Indexer for values of the stack below the top.
+        /// </summary>
+        /// <param name="index">index of the element, starting from the bottom</param>
+        /// <returns>the selected element</returns>
+        public T this[int index] { get { return array[index]; } }
+
+        /// <summary>
+        /// The current depth of the stack.
+        /// </summary>
+        public int Depth { get { return tos; } }
+
+        internal void Push(T value)
+        {
+            if (tos >= array.Length)
+            {
+                T[] newarray = new T[array.Length * 2];
+                System.Array.Copy(array, newarray, tos);
+                array = newarray;
+            }
+            array[tos++] = value;
+        }
+
+        internal T Pop()
+        {
+            T rslt = array[--tos];
+            array[tos] = default(T);
+            return rslt;
+        }
+
+        internal T TopElement() { return array[tos - 1]; }
+
+        internal bool IsEmpty() { return tos == 0; }
+    }
+}
\ No newline at end of file
diff --git a/Module6/SimpleLanguage1/SimpleLang1.csproj b/Module6/SimpleLanguage1/SimpleLang1.csproj
new file mode 100644
index 0000000..9443c7d
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleLang1.csproj
@@ -0,0 +1,62 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SimpleLang</RootNamespace>
+    <AssemblyName>SimpleLang</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Main.cs" />
+    <Compile Include="ParserHelper.cs" />
+    <Compile Include="ProgramTree.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShiftReduceParserCode.cs" />
+    <Compile Include="SimpleLex.cs" />
+    <Compile Include="SimpleYacc.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- 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">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/Module6/SimpleLanguage1/SimpleLang1.sln b/Module6/SimpleLanguage1/SimpleLang1.sln
new file mode 100644
index 0000000..adda773
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleLang1.sln
@@ -0,0 +1,22 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLang1", "SimpleLang1.csproj", "{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.ActiveCfg = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.Build.0 = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.ActiveCfg = Release|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Module6/SimpleLanguage1/SimpleLex.cs b/Module6/SimpleLanguage1/SimpleLex.cs
new file mode 100644
index 0000000..ceaf75d
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleLex.cs
@@ -0,0 +1,1489 @@
+//
+//  This CSharp output file generated by Gardens Point LEX
+//  Version:  1.1.3.301
+//  Machine:  HUB
+//  DateTime: 21.09.2017 20:37:24
+//  UserName: someone
+//  GPLEX input file <SimpleLex.lex>
+//  GPLEX frame file <embedded resource>
+//
+//  Option settings: unicode, parser, minimize
+//  Option settings: classes, compressMap, compressNext, persistBuffer, embedbuffers
+//  Fallback code page: Target machine default
+//
+
+//
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
+//
+//
+#define BACKUP
+#define PERSIST
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+using SimpleParser;
+using QUT.Gppg;
+using System.Linq;
+
+namespace SimpleScanner
+{   
+    /// <summary>
+    /// Summary Canonical example of GPLEX automaton
+    /// </summary>
+    
+#if STANDALONE
+    //
+    // These are the dummy declarations for stand-alone GPLEX applications
+    // normally these declarations would come from the parser.
+    // If you declare /noparser, or %option noparser then you get this.
+    //
+
+     public enum Tokens
+    { 
+      EOF = 0, maxParseToken = int.MaxValue 
+      // must have at least these two, values are almost arbitrary
+    }
+
+     public abstract class ScanBase
+    {
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public abstract int yylex();
+
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
+        protected virtual bool yywrap() { return true; }
+
+#if BABEL
+        protected abstract int CurrentSc { get; set; }
+        // EolState is the 32-bit of state data persisted at 
+        // the end of each line for Visual Studio colorization.  
+        // The default is to return CurrentSc.  You must override
+        // this if you want more complicated behavior.
+        public virtual int EolState { 
+            get { return CurrentSc; }
+            set { CurrentSc = value; } 
+        }
+    }
+    
+     public interface IColorScan
+    {
+        void SetSource(string source, int offset);
+        int GetNext(ref int state, out int start, out int end);
+#endif // BABEL
+    }
+
+#endif // STANDALONE
+    
+    // If the compiler can't find the scanner base class maybe you
+    // need to run GPPG with the /gplex option, or GPLEX with /noparser
+#if BABEL
+     public sealed partial class Scanner : ScanBase, IColorScan
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+        
+        protected override int CurrentSc 
+        {
+             // The current start state is a property
+             // to try to avoid the user error of setting
+             // scState but forgetting to update the FSA
+             // start state "currentStart"
+             //
+             get { return currentScOrd; }  // i.e. return YY_START;
+             set { currentScOrd = value;   // i.e. BEGIN(value);
+                   currentStart = startState[value]; }
+        }
+#else  // BABEL
+     public sealed partial class Scanner : ScanBase
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+#endif // BABEL
+        
+        /// <summary>
+        /// The input buffer for this scanner.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public ScanBuff Buffer { get { return buffer; } }
+        
+        private static int GetMaxParseToken() {
+     System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken");
+            return (f == null ? int.MaxValue : (int)f.GetValue(null));
+        }
+        
+        static int parserMax = GetMaxParseToken();
+        
+        enum Result {accept, noMatch, contextFound};
+
+        const int maxAccept = 7;
+        const int initial = 8;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+
+#region user code
+#endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;      // last code read
+        int cCol;      // column number of code
+        int lNum;      // current line number
+        //
+        // The following instance variables are used, among other
+        // things, for constructing the yylloc location objects.
+        //
+        int tokPos;        // buffer position at start of token
+        int tokCol;        // zero-based column number at start of token
+        int tokLin;        // line number at start of token
+        int tokEPos;       // buffer position at end of token
+        int tokECol;       // column number at end of token
+        int tokELin;       // line number at end of token
+        string tokTxt;     // lazily constructed text of token
+#if STACK          
+        private Stack<int> scStack = new Stack<int>();
+#endif // STACK
+
+#region ScannerTables
+    struct Table {
+        public int min; public int rng; public int dflt;
+        public sbyte[] nxt;
+        public Table(int m, int x, int d, sbyte[] n) {
+            min = m; rng = x; dflt = d; nxt = n;
+        }
+    };
+
+    static int[] startState = new int[] {8, 0};
+
+#region CompressedCharacterMap
+    //
+    // There are 8 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, 
+/*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+    static sbyte MapC(int code)
+    { // '\0' <= code <= '\U0010FFFF'
+      if (code < 123) // '\0' <= code <= 'z'
+        return mapC0[code - 0];
+      else // '{' <= code <= '\U0010FFFF'
+        return (sbyte)7;
+    }
+#endregion
+
+    static Table[] NxS = new Table[10] {
+/* NxS[   0] */ new Table(0, 0, 0, null),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
+/* 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[   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}),
+    };
+
+int NextState() {
+    if (code == ScanBuff.EndOfFile)
+        return eofNum;
+    else
+        unchecked {
+            int rslt;
+            int idx = MapC(code) - NxS[state].min;
+            if (idx < 0) idx += 8;
+            if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
+            else rslt = NxS[state].nxt[idx];
+            return rslt;
+        }
+}
+
+#endregion
+
+
+#if BACKUP
+        // ==============================================================
+        // == Nested struct used for backup in automata that do backup ==
+        // ==============================================================
+
+        struct Context // class used for automaton backup.
+        {
+            public int bPos;
+            public int rPos; // scanner.readPos saved value
+            public int cCol;
+            public int lNum; // Need this in case of backup over EOL.
+            public int state;
+            public int cChr;
+        }
+        
+        private Context ctx = new Context();
+#endif // BACKUP
+
+        // ==============================================================
+        // ==== Nested struct to support input switching in scanners ====
+        // ==============================================================
+
+		struct BufferContext {
+            internal ScanBuff buffSv;
+			internal int chrSv;
+			internal int cColSv;
+			internal int lNumSv;
+		}
+
+        // ==============================================================
+        // ===== Private methods to save and restore buffer contexts ====
+        // ==============================================================
+
+        /// <summary>
+        /// This method creates a buffer context record from
+        /// the current buffer object, together with some
+        /// scanner state values. 
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        BufferContext MkBuffCtx()
+		{
+			BufferContext rslt;
+			rslt.buffSv = this.buffer;
+			rslt.chrSv = this.code;
+			rslt.cColSv = this.cCol;
+			rslt.lNumSv = this.lNum;
+			return rslt;
+		}
+
+        /// <summary>
+        /// This method restores the buffer value and allied
+        /// scanner state from the given context record value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void RestoreBuffCtx(BufferContext value)
+		{
+			this.buffer = value.buffSv;
+			this.code = value.chrSv;
+			this.cCol = value.cColSv;
+			this.lNum = value.lNumSv;
+        } 
+        // =================== End Nested classes =======================
+
+#if !NOFILES
+     public Scanner(Stream file) {
+            SetSource(file, 0); // unicode option
+        }
+
+        public Scanner(Stream file, string codepage) {
+            SetSource(file, CodePageHandling.GetCodePage(codepage));
+        }
+        
+#endif // !NOFILES
+
+     public Scanner() { }
+
+        private int readPos;
+
+        void GetCode()
+        {
+            if (code == '\n')  // This needs to be fixed for other conventions
+                               // i.e. [\r\n\205\u2028\u2029]
+            { 
+                cCol = -1;
+                lNum++;
+            }
+            readPos = buffer.Pos;
+
+            // Now read new codepoint.
+            code = buffer.Read();
+            if (code > ScanBuff.EndOfFile)
+            {
+#if (!BYTEMODE)
+                if (code >= 0xD800 && code <= 0xDBFF)
+                {
+                    int next = buffer.Read();
+                    if (next < 0xDC00 || next > 0xDFFF)
+                        code = ScanBuff.UnicodeReplacementChar;
+                    else
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
+                }
+#endif
+                cCol++;
+            }
+        }
+
+        void MarkToken()
+        {
+#if (!PERSIST)
+            buffer.Mark();
+#endif
+            tokPos = readPos;
+            tokLin = lNum;
+            tokCol = cCol;
+        }
+        
+        void MarkEnd()
+        {
+            tokTxt = null;
+            tokEPos = readPos;
+            tokELin = lNum;
+            tokECol = cCol;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int Peek()
+        {
+            int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
+            GetCode(); rslt = code;
+            lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
+            return rslt;
+        }
+
+        // ==============================================================
+        // =====    Initialization of string-based input buffers     ====
+        // ==============================================================
+
+        /// <summary>
+        /// Create and initialize a StringBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the input string</param>
+        /// <param name="offset">starting offset in the string</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(string source, int offset)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.buffer.Pos = offset;
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+
+#if !NOFILES        
+        // ================ LineBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a LineBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the list of input strings</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(IList<string> source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            this.lNum = 0;
+            GetCode();
+        }
+
+        // =============== StreamBuffer Initialization ==================
+
+        /// <summary>
+        /// Create and initialize a StreamBuff buffer object for this scanner.
+        /// StreamBuff is buffer for 8-bit byte files.
+        /// </summary>
+        /// <param name="source">the input byte stream</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+        
+#if !BYTEMODE
+        // ================ TextBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a TextBuff buffer object for this scanner.
+        /// TextBuff is a buffer for encoded unicode files.
+        /// </summary>
+        /// <param name="source">the input text file</param>
+        /// <param name="fallbackCodePage">Code page to use if file has
+        /// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source, int fallbackCodePage)
+        {
+            this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+#endif // !BYTEMODE
+#endif // !NOFILES
+        
+        // ==============================================================
+
+#if BABEL
+        //
+        //  Get the next token for Visual Studio
+        //
+        //  "state" is the inout mode variable that maintains scanner
+        //  state between calls, using the EolState property. In principle,
+        //  if the calls of EolState are costly set could be called once
+        //  only per line, at the start; and get called only at the end
+        //  of the line. This needs more infrastructure ...
+        //
+        public int GetNext(ref int state, out int start, out int end)
+        {
+                Tokens next;
+            int s, e;
+            s = state;        // state at start
+            EolState = state;
+                next = (Tokens)Scan();
+            state = EolState;
+            e = state;       // state at end;
+            start = tokPos;
+            end = tokEPos - 1; // end is the index of last char.
+            return (int)next;
+        }        
+#endif // BABEL
+
+        // ======== AbstractScanner<> Implementation =========
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public override int yylex()
+        {
+            // parserMax is set by reflecting on the Tokens
+            // enumeration.  If maxParseToken is defined
+            // that is used, otherwise int.MaxValue is used.
+            int next;
+            do { next = Scan(); } while (next >= parserMax);
+            return next;
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yypos { get { return tokPos; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yyline { get { return tokLin; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yycol { get { return tokCol; } }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
+        public string yytext
+        {
+            get 
+            {
+                if (tokTxt == null) 
+                    tokTxt = buffer.GetString(tokPos, tokEPos);
+                return tokTxt;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void yyless(int n)
+        {
+            buffer.Pos = tokPos;
+            // Must read at least one char, so set before start.
+            cCol = tokCol - 1; 
+            GetCode();
+            // Now ensure that line counting is correct.
+            lNum = tokLin;
+            // And count the rest of the text.
+            for (int i = 0; i < n; i++) GetCode();
+            MarkEnd();
+        }
+       
+        //
+        //  It would be nice to count backward in the text
+        //  but it does not seem possible to re-establish
+        //  the correct column counts except by going forward.
+        //
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void _yytrunc(int n) { yyless(yyleng - n); }
+        
+        //
+        // This is painful, but we no longer count
+        // codepoints.  For the overwhelming majority 
+        // of cases the single line code is fast, for
+        // the others, well, at least it is all in the
+        // buffer so no files are touched. Note that we
+        // can't use (tokEPos - tokPos) because of the
+        // possibility of surrogate pairs in the token.
+        //
+        [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 {
+                    int ch;
+                    int count = 0;
+                    int save = buffer.Pos;
+                    buffer.Pos = tokPos;
+                    do {
+                        ch = buffer.Read();
+                        if (!char.IsHighSurrogate((char)ch)) count++;
+                    } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
+                    buffer.Pos = save; 
+                    return count;
+                }
+#endif // BYTEMODE
+            }
+        }
+        
+        // ============ methods available in actions ==============
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int YY_START {
+            get { return currentScOrd; }
+            set { currentScOrd = value; 
+                  currentStart = startState[value]; 
+            } 
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void BEGIN(int next) {
+            currentScOrd = next;
+            currentStart = startState[next];
+        }
+
+        // ============== The main tokenizer code =================
+
+        int Scan()
+        {
+            try {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
+#if LEFTANCHORS
+                    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...
+                        GetCode();
+                    }
+                    
+#else // !LEFTANCHORS
+                    state = currentStart;
+                    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();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
+#if BACKUP
+                        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;
+                        }
+                        else
+#endif // BACKUP
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
+                        MarkEnd();
+#region ActionSwitch
+#pragma warning disable 162
+    switch (state)
+    {
+        case eofNum:
+            if (yywrap())
+                return (int)Tokens.EOF;
+            break;
+        case 1:
+yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM;
+            break;
+        case 2:
+        case 4:
+LexError();
+            break;
+        case 3:
+int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+            break;
+        case 5:
+return (int)Tokens.SEMICOLON;
+            break;
+        case 6:
+return (int)Tokens.ASSIGN;
+            break;
+        case 7:
+yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+            break;
+        default:
+            break;
+    }
+#pragma warning restore 162
+#endregion
+                    }
+                }
+            } // end try
+            finally {
+// User-specified epilog to scan()
+yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+// End, user-specified epilog
+            } // end finally
+        }
+
+#if BACKUP
+        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;
+            ctx.lNum  = lNum;
+            ctx.state = state;
+            ctx.cChr  = code;
+        }
+
+        void RestoreStateAndPos(ref Context ctx)
+        {
+            buffer.Pos = ctx.bPos;
+            readPos = ctx.rPos;
+            cCol  = ctx.cCol;
+            lNum  = ctx.lNum;
+            state = ctx.state;
+            code  = ctx.cChr;
+        }
+
+#endif // BACKUP
+
+        // ============= End of the tokenizer code ================
+
+#if STACK        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void yy_clear_stack() { scStack.Clear(); }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int yy_top_state() { return scStack.Peek(); }
+        
+        internal void yy_push_state(int state)
+        {
+            scStack.Push(currentScOrd);
+            BEGIN(state);
+        }
+        
+        internal void yy_pop_state()
+        {
+            // Protect against input errors that pop too far ...
+            if (scStack.Count > 0) {
+				int newSc = scStack.Pop();
+				BEGIN(newSc);
+            } // Otherwise leave stack unchanged.
+        }
+ #endif // STACK
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void ECHO() { Console.Out.Write(yytext); }
+        
+#region UserCodeSection
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
+
+#endregion
+    } // end class $Scanner
+
+// ==============================================================
+// <auto-generated>
+// This code automatically produced from an embedded resource.
+// Do not edit this file, or it will become incompatible with 
+// the specification from which it was generated.
+// </auto-generated>
+// ==============================================================
+
+// Code copied from GPLEX embedded resource
+    [Serializable]
+    public class BufferException : Exception
+    {
+        public BufferException() { }
+        public BufferException(string message) : base(message) { }
+        public BufferException(string message, Exception innerException)
+            : base(message, innerException) { }
+        protected BufferException(SerializationInfo info, StreamingContext context)
+            : base(info, context) { }
+    }
+
+    public abstract class ScanBuff
+    {
+        private string fileNm;
+
+        public const int EndOfFile = -1;
+        public const int UnicodeReplacementChar = 0xFFFD;
+
+        public bool IsFile { get { return (fileNm != null); } }
+        public string FileName { get { return fileNm; } set { fileNm = value; } }
+
+        public abstract int Pos { get; set; }
+        public abstract int Read();
+        public virtual void Mark() { }
+
+        public abstract string GetString(int begin, int limit);
+
+        public static ScanBuff GetBuffer(string source)
+        {
+            return new StringBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(IList<string> source)
+        {
+            return new LineBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(Stream source)
+        {
+            return new BuildBuffer(source);
+        }
+
+#if (!BYTEMODE)
+        public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
+        {
+            return new BuildBuffer(source, fallbackCodePage);
+        }
+#endif
+    }
+
+    #region Buffer classes
+
+    // ==============================================================
+    // =====  Definitions for various ScanBuff derived classes   ====
+    // ==============================================================
+    // ===============         String input          ================
+    // ==============================================================
+
+    /// <summary>
+    /// This class reads characters from a single string as
+    /// required, for example, by Visual Studio language services
+    /// </summary>
+    sealed class StringBuffer : ScanBuff
+    {
+        string str;        // input buffer
+        int bPos;          // current position in buffer
+        int sLen;
+
+        public StringBuffer(string source)
+        {
+            this.str = source;
+            this.sLen = source.Length;
+            this.FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (bPos < sLen) return str[bPos++];
+            else if (bPos == sLen) { bPos++; return '\n'; }   // one strike, see new line
+            else { bPos++; return EndOfFile; }                // two strikes and you're out!
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            //  "limit" can be greater than sLen with the BABEL
+            //  option set.  Read returns a "virtual" EOL if
+            //  an attempt is made to read past the end of the
+            //  string buffer.  Without the guard any attempt 
+            //  to fetch yytext for a token that includes the 
+            //  EOL will throw an index exception.
+            if (limit > sLen) limit = sLen;
+            if (limit <= begin) return "";
+            else return str.Substring(begin, limit - begin);
+        }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+        public override string ToString() { return "StringBuffer"; }
+    }
+
+    // ==============================================================
+    //  The LineBuff class contributed by Nigel Horspool, 
+    //  nigelh@cs.uvic.cs
+    // ==============================================================
+
+    sealed class LineBuffer : ScanBuff
+    {
+        IList<string> line;    // list of source lines from a file
+        int numLines;          // number of strings in line list
+        string curLine;        // current line in that list
+        int cLine;             // index of current line in the list
+        int curLen;            // length of current line
+        int curLineStart;      // position of line start in whole file
+        int curLineEnd;        // position of line end in whole file
+        int maxPos;            // max position ever visited in whole file
+        int cPos;              // ordinal number of code in source
+
+        // Constructed from a list of strings, one per source line.
+        // The lines have had trailing '\n' characters removed.
+        public LineBuffer(IList<string> lineList)
+        {
+            line = lineList;
+            numLines = line.Count;
+            cPos = curLineStart = 0;
+            curLine = (numLines > 0 ? line[0] : "");
+            maxPos = curLineEnd = curLen = curLine.Length;
+            cLine = 1;
+            FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (cPos < curLineEnd)
+                return curLine[cPos++ - curLineStart];
+            if (cPos++ == curLineEnd)
+                return '\n';
+            if (cLine >= numLines)
+                return EndOfFile;
+            curLine = line[cLine];
+            curLen = curLine.Length;
+            curLineStart = curLineEnd + 1;
+            curLineEnd = curLineStart + curLen;
+            if (curLineEnd > maxPos)
+                maxPos = curLineEnd;
+            cLine++;
+            return curLen > 0 ? curLine[0] : '\n';
+        }
+
+        // To speed up searches for the line containing a position
+        private int cachedPosition;
+        private int cachedIxdex;
+        private int cachedLineStart;
+
+        // Given a position pos within the entire source, the results are
+        //   ix     -- the index of the containing line
+        //   lstart -- the position of the first character on that line
+        private void findIndex(int pos, out int ix, out int lstart)
+        {
+            if (pos >= cachedPosition)
+            {
+                ix = cachedIxdex; lstart = cachedLineStart;
+            }
+            else
+            {
+                ix = lstart = 0;
+            }
+            for (; ; )
+            {
+                int len = line[ix].Length + 1;
+                if (pos < lstart + len) break;
+                lstart += len;
+                ix++;
+            }
+            cachedPosition = pos;
+            cachedIxdex = ix;
+            cachedLineStart = lstart;
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            if (begin >= maxPos || limit <= begin) return "";
+            int endIx, begIx, endLineStart, begLineStart;
+            findIndex(begin, out begIx, out begLineStart);
+            int begCol = begin - begLineStart;
+            findIndex(limit, out endIx, out endLineStart);
+            int endCol = limit - endLineStart;
+            string s = line[begIx];
+            if (begIx == endIx)
+            {
+                // the usual case, substring all on one line
+                return (endCol <= s.Length) ?
+                    s.Substring(begCol, endCol - begCol)
+                    : s.Substring(begCol) + "\n";
+            }
+            // the string spans multiple lines, yuk!
+            StringBuilder sb = new StringBuilder();
+            if (begCol < s.Length)
+                sb.Append(s.Substring(begCol));
+            for (; ; )
+            {
+                sb.Append("\n");
+                s = line[++begIx];
+                if (begIx >= endIx) break;
+                sb.Append(s);
+            }
+            if (endCol <= s.Length)
+            {
+                sb.Append(s.Substring(0, endCol));
+            }
+            else
+            {
+                sb.Append(s);
+                sb.Append("\n");
+            }
+            return sb.ToString();
+        }
+
+        public override int Pos
+        {
+            get { return cPos; }
+            set
+            {
+                cPos = value;
+                findIndex(cPos, out cLine, out curLineStart);
+                curLine = line[cLine];
+                curLineEnd = curLineStart + curLine.Length;
+            }
+        }
+
+        public override string ToString() { return "LineBuffer"; }
+    }
+
+
+    // ==============================================================
+    // =====     class BuildBuff : for unicode text files    ========
+    // ==============================================================
+
+    class BuildBuffer : ScanBuff
+    {
+        // Double buffer for char stream.
+        class BufferElement
+        {
+            StringBuilder bldr = new StringBuilder();
+            StringBuilder next = new StringBuilder();
+            int minIx;
+            int maxIx;
+            int brkIx;
+            bool appendToNext;
+
+            internal BufferElement() { }
+
+            internal int MaxIndex { get { return maxIx; } }
+            // internal int MinIndex { get { return minIx; } }
+
+            internal char this[int index]
+            {
+                get
+                {
+                    if (index < minIx || index >= maxIx)
+                        throw new BufferException("Index was outside data buffer");
+                    else if (index < brkIx)
+                        return bldr[index - minIx];
+                    else
+                        return next[index - brkIx];
+                }
+            }
+
+            internal void Append(char[] block, int count)
+            {
+                maxIx += count;
+                if (appendToNext)
+                    this.next.Append(block, 0, count);
+                else
+                {
+                    this.bldr.Append(block, 0, count);
+                    brkIx = maxIx;
+                    appendToNext = true;
+                }
+            }
+
+            internal string GetString(int start, int limit)
+            {
+                if (limit <= start)
+                    return "";
+                if (start >= minIx && limit <= maxIx)
+                    if (limit < brkIx) // String entirely in bldr builder
+                        return bldr.ToString(start - minIx, limit - start);
+                    else if (start >= brkIx) // String entirely in next builder
+                        return next.ToString(start - brkIx, limit - start);
+                    else // Must do a string-concatenation
+                        return
+                            bldr.ToString(start - minIx, brkIx - start) +
+                            next.ToString(0, limit - brkIx);
+                else
+                    throw new BufferException("String was outside data buffer");
+            }
+
+            internal void Mark(int limit)
+            {
+                if (limit > brkIx + 16) // Rotate blocks
+                {
+                    StringBuilder temp = bldr;
+                    bldr = next;
+                    next = temp;
+                    next.Length = 0;
+                    minIx = brkIx;
+                    brkIx = maxIx;
+                }
+            }
+        }
+
+        BufferElement data = new BufferElement();
+
+        int bPos;            // Postion index in the StringBuilder
+        BlockReader NextBlk; // Delegate that serves char-arrays;
+
+        private string EncodingName
+        {
+            get
+            {
+                StreamReader rdr = NextBlk.Target as StreamReader;
+                return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
+            }
+        }
+
+        public BuildBuffer(Stream stream)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Raw(stream);
+        }
+
+#if (!BYTEMODE)
+        public BuildBuffer(Stream stream, int fallbackCodePage)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
+        }
+#endif
+
+        /// <summary>
+        /// Marks a conservative lower bound for the buffer,
+        /// allowing space to be reclaimed.  If an application 
+        /// needs to call GetString at arbitrary past locations 
+        /// in the input stream, Mark() is not called.
+        /// </summary>
+        public override void Mark() { data.Mark(bPos - 2); }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+
+        /// <summary>
+        /// Read returns the ordinal number of the next char, or 
+        /// EOF (-1) for an end of stream.  Note that the next
+        /// code point may require *two* calls of Read().
+        /// </summary>
+        /// <returns></returns>
+        public override int Read()
+        {
+            //
+            //  Characters at positions 
+            //  [data.offset, data.offset + data.bldr.Length)
+            //  are available in data.bldr.
+            //
+            if (bPos < data.MaxIndex)
+            {
+                // ch0 cannot be EOF
+                return (int)data[bPos++];
+            }
+            else // Read from underlying stream
+            {
+                // Experimental code, blocks of page size
+                char[] chrs = new char[4096];
+                int count = NextBlk(chrs, 0, 4096);
+                if (count == 0)
+                    return EndOfFile;
+                else
+                {
+                    data.Append(chrs, count);
+                    return (int)data[bPos++];
+                }
+            }
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            return data.GetString(begin, limit);
+        }
+
+        public override string ToString()
+        {
+            return "StringBuilder buffer, encoding: " + this.EncodingName;
+        }
+    }
+
+    // =============== End ScanBuff-derived classes ==================
+
+    public delegate int BlockReader(char[] block, int index, int number);
+
+    // A delegate factory, serving up a delegate that
+    // reads a block of characters from the underlying
+    // encoded stream, via a StreamReader object.
+    //
+    public static class BlockReaderFactory
+    {
+        public static BlockReader Raw(Stream stream)
+        {
+            return delegate(char[] block, int index, int number)
+            {
+                byte[] b = new byte[number];
+                int count = stream.Read(b, 0, number);
+                int i = 0;
+                int j = index;
+                for (; i < count; i++, j++)
+                    block[j] = (char)b[i];
+                return count;
+            };
+        }
+
+#if (!BYTEMODE)
+        public static BlockReader Get(Stream stream, int fallbackCodePage)
+        {
+            Encoding encoding;
+            int preamble = Preamble(stream);
+
+            if (preamble != 0)  // There is a valid BOM here!
+                encoding = Encoding.GetEncoding(preamble);
+            else if (fallbackCodePage == -1) // Fallback is "raw" bytes
+                return Raw(stream);
+            else if (fallbackCodePage != -2) // Anything but "guess"
+                encoding = Encoding.GetEncoding(fallbackCodePage);
+            else // This is the "guess" option
+            {
+                int guess = new Guesser(stream).GuessCodePage();
+                stream.Seek(0, SeekOrigin.Begin);
+                if (guess == -1) // ==> this is a 7-bit file
+                    encoding = Encoding.ASCII;
+                else if (guess == 65001)
+                    encoding = Encoding.UTF8;
+                else             // ==> use the machine default
+                    encoding = Encoding.Default;
+            }
+            StreamReader reader = new StreamReader(stream, encoding);
+            return reader.Read;
+        }
+
+        static int Preamble(Stream stream)
+        {
+            int b0 = stream.ReadByte();
+            int b1 = stream.ReadByte();
+
+            if (b0 == 0xfe && b1 == 0xff)
+                return 1201; // UTF16BE
+            if (b0 == 0xff && b1 == 0xfe)
+                return 1200; // UTF16LE
+
+            int b2 = stream.ReadByte();
+            if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
+                return 65001; // UTF8
+            //
+            // There is no unicode preamble, so we
+            // return denoter for the machine default.
+            //
+            stream.Seek(0, SeekOrigin.Begin);
+            return 0;
+        }
+#endif // !BYTEMODE
+    }
+    #endregion Buffer classes
+
+    // ==============================================================
+    // ============      class CodePageHandling         =============
+    // ==============================================================
+
+    public static class CodePageHandling
+    {
+        public static int GetCodePage(string option)
+        {
+            string command = option.ToUpperInvariant();
+            if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
+                command = command.Substring(9);
+            try
+            {
+                if (command.Equals("RAW"))
+                    return -1;
+                else if (command.Equals("GUESS"))
+                    return -2;
+                else if (command.Equals("DEFAULT"))
+                    return 0;
+                else if (char.IsDigit(command[0]))
+                    return int.Parse(command, CultureInfo.InvariantCulture);
+                else
+                {
+                    Encoding enc = Encoding.GetEncoding(command);
+                    return enc.CodePage;
+                }
+            }
+            catch (FormatException)
+            {
+                Console.Error.WriteLine(
+                    "Invalid format \"{0}\", using machine default", option);
+            }
+            catch (ArgumentException)
+            {
+                Console.Error.WriteLine(
+                    "Unknown code page \"{0}\", using machine default", option);
+            }
+            return 0;
+        }
+    }
+#region guesser
+#if (!BYTEMODE)
+    // ==============================================================
+    // ============          Encoding Guesser           =============
+    // ==============================================================
+
+    /// <summary>
+    /// This class provides a simple finite state automaton that
+    /// scans the file looking for (1) valid UTF-8 byte patterns,
+    /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
+    /// The method then guesses whether it is UTF-8 or maybe some 
+    /// local machine default encoding.  This works well for the
+    /// various Latin encodings.
+    /// </summary>
+    internal class Guesser
+    {
+        ScanBuff buffer;
+
+        public int GuessCodePage() { return Scan(); }
+
+        const int maxAccept = 10;
+        const int initial = 0;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+        const int EndToken = 0;
+
+        #region user code
+        /* 
+         *  Reads the bytes of a file to determine if it is 
+         *  UTF-8 or a single-byte code page file.
+         */
+        public long utfX;
+        public long uppr;
+        #endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;
+
+        #region ScannerTables
+        static int[] startState = new int[] { 11, 0 };
+
+        #region CharacterMap
+        static sbyte[] map = new sbyte[256] {
+/*     '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*   '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
+        #endregion
+
+        static sbyte[][] nextState = new sbyte[][] {
+            new sbyte[] {0, 0, 0, 0, 0, 0},
+            new sbyte[] {-1, -1, 10, -1, -1, -1},
+            new sbyte[] {-1, -1, -1, -1, -1, -1},
+            new sbyte[] {-1, -1, 8, -1, -1, -1},
+            new sbyte[] {-1, -1, 5, -1, -1, -1},
+            new sbyte[] {-1, -1, 6, -1, -1, -1},
+            new sbyte[] {-1, -1, 7, -1, -1, -1},
+            null,
+            new sbyte[] {-1, -1, 9, -1, -1, -1},
+            null,
+            null,
+            new sbyte[] {-1, 1, 2, 3, 4, 2}
+        };
+
+
+        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
+        // Reason for suppression: cannot have self-reference in array initializer.
+        static Guesser()
+        {
+            nextState[7] = nextState[2];
+            nextState[9] = nextState[2];
+            nextState[10] = nextState[2];
+        }
+
+        int NextState()
+        {
+            if (code == ScanBuff.EndOfFile)
+                return eofNum;
+            else
+                return nextState[state][map[code]];
+        }
+        #endregion
+
+        public Guesser(System.IO.Stream file) { SetSource(file); }
+
+        public void SetSource(System.IO.Stream source)
+        {
+            this.buffer = new BuildBuffer(source);
+            code = buffer.Read();
+        }
+
+        int Scan()
+        {
+            for (; ; )
+            {
+                int next;
+                state = currentStart;
+                while ((next = NextState()) == goStart)
+                    code = buffer.Read();
+
+                state = next;
+                code = buffer.Read();
+
+                while ((next = NextState()) > eofNum)
+                {
+                    state = next;
+                    code = buffer.Read();
+                }
+                if (state <= maxAccept)
+                {
+                    #region ActionSwitch
+#pragma warning disable 162
+                    switch (state)
+                    {
+                        case eofNum:
+                            switch (currentStart)
+                            {
+                                case 11:
+                                    if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
+                                    else if (uppr * 10 > utfX) return 0;   /* default code page */
+                                    else return 65001;                     /* UTF-8 encoding */
+                                    break;
+                            }
+                            return EndToken;
+                        case 1: // Recognized '{Upper128}',	Shortest string "\xC0"
+                        case 2: // Recognized '{Upper128}',	Shortest string "\x80"
+                        case 3: // Recognized '{Upper128}',	Shortest string "\xE0"
+                        case 4: // Recognized '{Upper128}',	Shortest string "\xF0"
+                            uppr++;
+                            break;
+                        case 5: // Recognized '{Utf8pfx4}{Utf8cont}',	Shortest string "\xF0\x80"
+                            uppr += 2;
+                            break;
+                        case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}',	Shortest string "\xF0\x80\x80"
+                            uppr += 3;
+                            break;
+                        case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}',	Shortest string "\xF0\x80\x80\x80"
+                            utfX += 3;
+                            break;
+                        case 8: // Recognized '{Utf8pfx3}{Utf8cont}',	Shortest string "\xE0\x80"
+                            uppr += 2;
+                            break;
+                        case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}',	Shortest string "\xE0\x80\x80"
+                            utfX += 2;
+                            break;
+                        case 10: // Recognized '{Utf8pfx2}{Utf8cont}',	Shortest string "\xC0\x80"
+                            utfX++;
+                            break;
+                        default:
+                            break;
+                    }
+#pragma warning restore 162
+                    #endregion
+                }
+            }
+        }
+    } // end class Guesser
+    
+#endif // !BYTEMODE
+#endregion
+
+// End of code copied from embedded resource
+
+} // end namespace
diff --git a/Module6/SimpleLanguage1/SimpleLex.lex b/Module6/SimpleLanguage1/SimpleLex.lex
new file mode 100644
index 0000000..20b364f
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleLex.lex
@@ -0,0 +1,78 @@
+%using SimpleParser;
+%using QUT.Gppg;
+%using System.Linq;
+
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+
+%%
+
+{INTNUM} { 
+  yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM; 
+}
+
+{REALNUM} { 
+  yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+}
+
+{ID}  { 
+  int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+}
+
+":=" { return (int)Tokens.ASSIGN; }
+";" { return (int)Tokens.SEMICOLON; }
+
+[^ \r\n] {
+	LexError();
+}
+
+%{
+  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+%}
+
+%%
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
diff --git a/Module6/SimpleLanguage1/SimpleYacc.cs b/Module6/SimpleLanguage1/SimpleYacc.cs
new file mode 100644
index 0000000..5666e24
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleYacc.cs
@@ -0,0 +1,166 @@
+// This code was generated by the Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2010
+// (see accompanying GPPGcopyright.rtf)
+
+// GPPG version 1.3.6
+// Machine:  HUB
+// DateTime: 21.09.2017 20:37:24
+// UserName: someone
+// Input file <SimpleYacc.y>
+
+// options: no-lines gplex
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using QUT.Gppg;
+using ProgramTree;
+
+namespace SimpleParser
+{
+public enum Tokens {
+    error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,ASSIGN=6,
+    SEMICOLON=7,INUM=8,RNUM=9,ID=10};
+
+public struct ValueType
+{ 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+// Abstract base class for GPLEX scanners
+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; }
+}
+
+public class Parser: ShiftReduceParser<ValueType, LexLocation>
+{
+  // Verbatim content from SimpleYacc.y
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+  // End verbatim content from SimpleYacc.y
+
+#pragma warning disable 649
+  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 string[] nonTerms = new string[] {
+      "expr", "ident", "assign", "statement", "cycle", "stlist", "block", "progr", 
+      "$accept", };
+
+  static Parser() {
+    states[0] = new State(new int[]{3,4},new int[]{-8,1,-7,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[]{10,14,3,4,5,18},new int[]{-6,5,-4,21,-3,9,-2,10,-7,16,-5,17});
+    states[5] = new State(new int[]{4,6,7,7});
+    states[6] = new State(-12);
+    states[7] = new State(new int[]{10,14,3,4,5,18},new int[]{-4,8,-3,9,-2,10,-7,16,-5,17});
+    states[8] = new State(-4);
+    states[9] = new State(-5);
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{10,14,8,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[]{10,14,8,15},new int[]{-1,19,-2,13});
+    states[19] = new State(new int[]{10,14,3,4,5,18},new int[]{-4,20,-3,9,-2,10,-7,16,-5,17});
+    states[20] = new State(-13);
+    states[21] = new State(-3);
+
+    rules[1] = new Rule(-9, new int[]{-8,2});
+    rules[2] = new Rule(-8, new int[]{-7});
+    rules[3] = new Rule(-6, new int[]{-4});
+    rules[4] = new Rule(-6, new int[]{-6,7,-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[]{10});
+    rules[9] = new Rule(-3, new int[]{-2,6,-1});
+    rules[10] = new Rule(-1, new int[]{-2});
+    rules[11] = new Rule(-1, new int[]{8});
+    rules[12] = new Rule(-7, new int[]{3,-6,4});
+    rules[13] = new Rule(-5, new int[]{5,-1,-4});
+  }
+
+  protected override void Initialize() {
+    this.InitSpecialTokens((int)Tokens.error, (int)Tokens.EOF);
+    this.InitStates(states);
+    this.InitRules(rules);
+    this.InitNonTerminals(nonTerms);
+  }
+
+  protected override void DoAction(int action)
+  {
+    switch (action)
+    {
+      case 2: // progr -> block
+{ root = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 3: // stlist -> statement
+{ 
+				CurrentSemanticValue.blVal = new BlockNode(ValueStack[ValueStack.Depth-1].stVal); 
+			}
+        break;
+      case 4: // stlist -> stlist, SEMICOLON, statement
+{ 
+				ValueStack[ValueStack.Depth-3].blVal.Add(ValueStack[ValueStack.Depth-1].stVal); 
+				CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-3].blVal; 
+			}
+        break;
+      case 5: // statement -> assign
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 6: // statement -> block
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 7: // statement -> cycle
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 8: // ident -> ID
+{ CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); }
+        break;
+      case 9: // 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
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
+        break;
+      case 11: // expr -> INUM
+{ CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
+        break;
+      case 12: // block -> BEGIN, stlist, END
+{ CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
+        break;
+      case 13: // cycle -> CYCLE, expr, statement
+{ CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal, ValueStack[ValueStack.Depth-1].stVal); }
+        break;
+    }
+  }
+
+  protected override string TerminalToString(int 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/Module6/SimpleLanguage1/SimpleYacc.y b/Module6/SimpleLanguage1/SimpleYacc.y
new file mode 100644
index 0000000..b9899b4
--- /dev/null
+++ b/Module6/SimpleLanguage1/SimpleYacc.y
@@ -0,0 +1,70 @@
+%{
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+%}
+
+%output = SimpleYacc.cs
+
+%union { 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+
+%using ProgramTree;
+
+%namespace SimpleParser
+
+%token BEGIN END CYCLE ASSIGN SEMICOLON
+%token <iVal> INUM 
+%token <dVal> RNUM 
+%token <sVal> ID
+
+%type <eVal> expr ident 
+%type <stVal> assign statement cycle 
+%type <blVal> stlist block
+
+%%
+
+progr   : block { root = $1; }
+		;
+
+stlist	: statement 
+			{ 
+				$$ = new BlockNode($1); 
+			}
+		| stlist SEMICOLON statement 
+			{ 
+				$1.Add($3); 
+				$$ = $1; 
+			}
+		;
+
+statement: assign { $$ = $1; }
+		| block   { $$ = $1; }
+		| cycle   { $$ = $1; }
+	;
+
+ident 	: ID { $$ = new IdNode($1); }	
+		;
+	
+assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
+		;
+
+expr	: ident  { $$ = $1 as IdNode; }
+		| INUM { $$ = new IntNumNode($1); }
+		;
+
+block	: BEGIN stlist END { $$ = $2; }
+		;
+
+cycle	: CYCLE expr statement { $$ = new CycleNode($2, $3); }
+		;
+	
+%%
+
diff --git a/Module6/SimpleLanguage1/a.txt b/Module6/SimpleLanguage1/a.txt
new file mode 100644
index 0000000..52ea170
--- /dev/null
+++ b/Module6/SimpleLanguage1/a.txt
@@ -0,0 +1,10 @@
+begin
+  b := 2;
+  a := 3;
+  a := b;
+  cycle 3
+  begin
+    a := c;
+    c := 1
+  end
+end
diff --git a/Module6/SimpleLanguage1/generateParserScanner.bat b/Module6/SimpleLanguage1/generateParserScanner.bat
new file mode 100644
index 0000000..7ca5476
--- /dev/null
+++ b/Module6/SimpleLanguage1/generateParserScanner.bat
@@ -0,0 +1,3 @@
+cls
+gplex.exe /unicode SimpleLex.lex
+gppg.exe /no-lines /gplex SimpleYacc.y
diff --git a/Module7/SimpleLanguage2/Main.cs b/Module7/SimpleLanguage2/Main.cs
new file mode 100644
index 0000000..3734ff4
--- /dev/null
+++ b/Module7/SimpleLanguage2/Main.cs
@@ -0,0 +1,56 @@
+п»їusing System;
+using System.IO;
+using System.Text;
+using System.Reflection;
+using System.Collections.Generic;
+using SimpleScanner;
+using SimpleParser;
+using SimpleLang.Visitors;
+
+namespace SimpleCompiler
+{
+    public class SimpleCompilerMain
+    {
+        public static void Main()
+        {
+            string FileName = @"..\..\a.txt";
+            try
+            {
+                string Text = File.ReadAllText(FileName);
+
+                Scanner scanner = new Scanner();
+                scanner.SetSource(Text, 0);
+
+                Parser parser = new Parser(scanner);
+
+                var b = parser.Parse();
+                if (!b)
+                    Console.WriteLine("Ошибка");
+                else
+                {
+                    Console.WriteLine("Синтаксическое дерево построено");
+
+                    var avis = new AssignCountVisitor();
+                    parser.root.Visit(avis);
+                    Console.WriteLine("Количество присваиваний = {0}", avis.Count);
+                    Console.WriteLine("-------------------------------");
+
+                    var pp = new PrettyPrintVisitor();
+                    parser.root.Visit(pp);
+                    Console.WriteLine(pp.Text);
+                }
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("Файл {0} не найден", FileName);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("{0}", e);
+            }
+
+            Console.ReadLine();
+        }
+
+    }
+}
diff --git a/Module7/SimpleLanguage2/ParserHelper.cs b/Module7/SimpleLanguage2/ParserHelper.cs
new file mode 100644
index 0000000..a085ecd
--- /dev/null
+++ b/Module7/SimpleLanguage2/ParserHelper.cs
@@ -0,0 +1,33 @@
+п»їusing System.Collections.Generic;
+using System;
+
+namespace SimpleParser
+{
+
+    public enum type { tint, tdouble };
+
+    public static class SymbolTable // Таблица символов
+    {
+        public static Dictionary<string, type> vars = new Dictionary<string, type>(); // таблица символов
+        public static void NewVarDef(string name, type t)
+        {
+            if (vars.ContainsKey(name))
+                throw new Exception("Переменная " + name + " уже определена");
+            else vars.Add(name, t);
+        }
+    }
+
+    public class LexException : Exception
+    {
+        public LexException(string msg) : base(msg) { }
+    }
+    
+    public class SyntaxException : Exception
+    {
+        public SyntaxException(string msg) : base(msg) { }
+    }
+
+    public static class ParserHelper
+    {
+    }
+}
\ No newline at end of file
diff --git a/Module7/SimpleLanguage2/ProgramTree.cs b/Module7/SimpleLanguage2/ProgramTree.cs
new file mode 100644
index 0000000..e48dcb5
--- /dev/null
+++ b/Module7/SimpleLanguage2/ProgramTree.cs
@@ -0,0 +1,145 @@
+п»їusing System.Collections.Generic;
+using SimpleLang.Visitors;
+
+namespace ProgramTree
+{
+    public enum AssignType { Assign, AssignPlus, AssignMinus, AssignMult, AssignDivide };
+
+    public abstract class Node // базовый класс для всех узлов    
+    {
+        public abstract void Visit(Visitor v);
+    }
+
+    public abstract class ExprNode : Node // базовый класс для всех выражений
+    {
+    }
+
+    public class IdNode : ExprNode
+    {
+        public string Name { get; set; }
+        public IdNode(string name) { Name = name; }
+        public override void Visit(Visitor v)
+        {
+            v.VisitIdNode(this);
+        }
+    }
+
+    public class IntNumNode : ExprNode
+    {
+        public int Num { get; set; }
+        public IntNumNode(int num) { Num = num; }
+        public override void Visit(Visitor v)
+        {
+            v.VisitIntNumNode(this);
+        }
+    }
+
+    public class BinOpNode : ExprNode
+    {
+        public ExprNode Left { get; set; }
+        public ExprNode Right { get; set; }
+        public char Op { get; set; }
+        public BinOpNode(ExprNode Left, ExprNode Right, char op) 
+        {
+            this.Left = Left;
+            this.Right = Right;
+            this.Op = op;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitBinOpNode(this);
+        }
+    }
+
+    public abstract class StatementNode : Node // базовый класс для всех операторов
+    {
+    }
+
+    public class AssignNode : StatementNode
+    {
+        public IdNode Id { get; set; }
+        public ExprNode Expr { get; set; }
+        public AssignType AssOp { get; set; }
+        public AssignNode(IdNode id, ExprNode expr, AssignType assop = AssignType.Assign)
+        {
+            Id = id;
+            Expr = expr;
+            AssOp = assop;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitAssignNode(this);
+        }
+    }
+
+    public class CycleNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode Stat { get; set; }
+        public CycleNode(ExprNode expr, StatementNode stat)
+        {
+            Expr = expr;
+            Stat = stat;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitCycleNode(this);
+        }
+    }
+
+    public class BlockNode : StatementNode
+    {
+        public List<StatementNode> StList = new List<StatementNode>();
+        public BlockNode(StatementNode stat)
+        {
+            Add(stat);
+        }
+        public void Add(StatementNode stat)
+        {
+            StList.Add(stat);
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitBlockNode(this);
+        }
+    }
+
+    public class WriteNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public WriteNode(ExprNode Expr)
+        {
+            this.Expr = Expr;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitWriteNode(this);
+        }
+    }
+
+    public class EmptyNode : StatementNode
+    {
+        public override void Visit(Visitor v)
+        {
+            v.VisitEmptyNode(this);
+        }
+    }
+
+    public class VarDefNode : StatementNode
+    {
+        public List<IdNode> vars = new List<IdNode>();
+        public VarDefNode(IdNode id)
+        {
+            Add(id);
+        }
+
+        public void Add(IdNode id)
+        {
+            vars.Add(id);
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitVarDefNode(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Module7/SimpleLanguage2/Properties/AssemblyInfo.cs b/Module7/SimpleLanguage2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..896cc99
--- /dev/null
+++ b/Module7/SimpleLanguage2/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+п»їusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью 
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("SimpleLang")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SimpleLang")]
+[assembly: AssemblyCopyright("Copyright В©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми 
+// для COM-компонентов.  Если требуется обратиться к типу в этой сборке через 
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("06dba63f-4805-4cd3-8a93-b329b2c7e37b")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+//      Основной номер версии
+//      Дополнительный номер версии 
+//      Номер построения
+//      Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию, 
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Module7/SimpleLanguage2/ShiftReduceParserCode.cs b/Module7/SimpleLanguage2/ShiftReduceParserCode.cs
new file mode 100644
index 0000000..c110ba1
--- /dev/null
+++ b/Module7/SimpleLanguage2/ShiftReduceParserCode.cs
@@ -0,0 +1,944 @@
+// Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2009
+// (see accompanying GPPGcopyright.rtf)
+#define EXPORT_GPPG
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+namespace QUT.Gppg
+{
+    /// <summary>
+    /// Abstract class for GPPG shift-reduce parsers.
+    /// Parsers generated by GPPG derive from this base
+    /// class, overriding the abstract Initialize() and
+    /// DoAction() methods.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type</typeparam>
+    /// <typeparam name="TSpan">Location type</typeparam>
+#if EXPORT_GPPG
+    public abstract class ShiftReduceParser<TValue, TSpan>
+#else
+    internal abstract class ShiftReduceParser<TValue, TSpan>
+#endif
+ where TSpan : IMerge<TSpan>, new()
+    {
+        public AbstractScanner<TValue, TSpan> scanner;
+        /// <summary>
+        /// The abstract scanner for this parser.
+        /// </summary>
+        protected AbstractScanner<TValue, TSpan> Scanner {
+            get { return scanner; }
+            set { scanner = value; }
+        }
+
+        /// <summary>
+        /// Constructor for base class
+        /// </summary>
+        /// <param name="scanner">Scanner instance for this parser</param>
+        protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
+        {
+            this.scanner = scanner;
+        }
+
+        // ==============================================================
+        //                    TECHNICAL EXPLANATION.
+        //   Why the next two fields are not exposed via properties.
+        // ==============================================================
+        // These fields are of the generic parameter types, and are
+        // frequently instantiated as struct types in derived classes.
+        // Semantic actions are defined in the derived classes and refer
+        // to instance fields of these structs.  Is such cases the code
+        // "get_CurrentSemanticValue().myField = blah;" will fail since
+        // the getter pushes the value of the field, not the reference.
+        // So, in the presence of properties, gppg would need to encode
+        // such field accesses as ... 
+        //  "tmp = get_CurrentSemanticValue(); // Fetch value
+        //   tmp.myField = blah;               // update
+        //   set_CurrentSemanticValue(tmp); "  // Write update back.
+        // There is no issue if TValue is restricted to be a ref type.
+        // The same explanation applies to scanner.yylval.
+        // ==============================================================
+        /// <summary>
+        /// The current value of the "$$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TValue CurrentSemanticValue;
+
+        /// <summary>
+        /// The current value of the "@$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TSpan CurrentLocationSpan;
+
+        private TSpan LastSpan;
+        private int NextToken;
+        private State FsaState;
+        private bool recovering;
+        private int tokensSinceLastError;
+
+        private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
+        private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
+        private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
+
+        /// <summary>
+        /// The stack of semantic value (YYSTYPE) values.
+        /// </summary>
+        protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
+
+        /// <summary>
+        /// The stack of location value (YYLTYPE) varlues.
+        /// </summary>
+        protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
+
+        private int errorToken;
+        private int endOfFileToken;
+        private string[] nonTerminals;
+        private State[] states;
+        private Rule[] rules;
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the rule list into this base class.
+        /// </summary>
+        /// <param name="rules">The array of Rule objects</param>
+        protected void InitRules(Rule[] rules) { this.rules = rules; }
+
+      /// <summary>
+      /// Initialization method to allow derived classes to
+      /// insert the states table into this base class.
+      /// </summary>
+      /// <param name="states">The pre-initialized states table</param>
+        protected void InitStates(State[] states) { this.states = states; }
+
+      /// <summary>
+      /// OBSOLETE FOR VERSION 1.4.0
+      /// </summary>
+      /// <param name="size"></param>
+        protected void InitStateTable(int size) { states = new State[size]; }
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the special value for the error and EOF tokens.
+        /// </summary>
+        /// <param name="err">The error state ordinal</param>
+        /// <param name="end">The EOF stat ordinal</param>
+        protected void InitSpecialTokens(int err, int end)
+        {
+            errorToken = err;
+            endOfFileToken = end;
+        }
+
+        /// <summary>
+        /// Initialization method to allow derived classes to
+        /// insert the non-terminal symbol names into this base class.
+        /// </summary>
+        /// <param name="names">Non-terminal symbol names</param>
+        protected void InitNonTerminals(string[] names) { nonTerminals = names; }
+
+        #region YYAbort, YYAccept etcetera.
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AcceptException : Exception
+        {
+            internal AcceptException() { }
+            protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AbortException : Exception
+        {
+            internal AbortException() { }
+            protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class ErrorException : Exception
+        {
+            internal ErrorException() { }
+            protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+
+        // The following methods are only called from within
+        // a semantic action. The thrown exceptions can never
+        // propagate outside the ShiftReduceParser class in 
+        // which they are nested.
+
+        /// <summary>
+        /// Force parser to terminate, returning "true"
+        /// </summary>
+        protected static void YYAccept() { throw new AcceptException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning "false"
+        /// </summary>
+        protected static void YYAbort() { throw new AbortException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning
+        /// "false" if error recovery fails.
+        /// </summary>
+        protected static void YYError() { throw new ErrorException(); }
+
+        /// <summary>
+        /// Check if parser in error recovery state.
+        /// </summary>
+        protected bool YYRecovering { get { return recovering; } }
+        #endregion
+
+        /// <summary>
+        /// Abstract base method. ShiftReduceParser calls this
+        /// to initialize the base class data structures.  Concrete
+        /// parser classes must override this method.
+        /// </summary>
+        protected abstract void Initialize();
+
+        /// <summary>
+        /// Main entry point of the Shift-Reduce Parser.
+        /// </summary>
+        /// <returns>True if parse succeeds, else false for
+        /// unrecoverable errors</returns>
+        public bool Parse()
+        {
+            Initialize();	// allow derived classes to instantiate rules, states and nonTerminals
+
+            NextToken = 0;
+            FsaState = states[0];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+
+            while (true)
+            {
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+                int action = FsaState.defaultAction;
+
+                if (FsaState.ParserTable != null)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif
+                        // We save the last token span, so that the location span
+                        // of production right hand sides that begin or end with a
+                        // nullable production will be correct.
+                        LastSpan = scanner.yylloc;
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+                }
+
+                if (action > 0)         // shift
+                {
+                    Shift(action);
+                }
+                else if (action < 0)   // reduce
+                {
+                    try
+                    {
+                        Reduce(-action);
+                        if (action == -1)	// accept
+                            return true;
+                    }
+                    catch (Exception x)
+                    {
+                        if (x is AbortException)
+                            return false;
+                        else if (x is AcceptException)
+                            return true;
+                        else if (x is ErrorException && !ErrorRecovery())
+                            return false;
+                        else
+                            throw;  // Rethrow x, preserving information.
+
+                    }
+                }
+                else if (action == 0)   // error
+                    if (!ErrorRecovery())
+                        return false;
+            }
+        }
+
+        private void Shift(int stateIndex)
+        {
+#if TRACE_ACTIONS
+				Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
+#endif
+            FsaState = states[stateIndex];
+
+            valueStack.Push(scanner.yylval);
+            StateStack.Push(FsaState);
+            LocationStack.Push(scanner.yylloc);
+
+            if (recovering)
+            {
+                if (NextToken != errorToken)
+                    tokensSinceLastError++;
+
+                if (tokensSinceLastError > 5)
+                    recovering = false;
+            }
+
+            if (NextToken != endOfFileToken)
+                NextToken = 0;
+        }
+
+        private void Reduce(int ruleNumber)
+        {
+#if TRACE_ACTIONS
+				DisplayRule(ruleNumber);
+#endif
+            Rule rule = rules[ruleNumber];
+            //
+            //  Default actions for unit productions.
+            //
+            if (rule.RightHandSide.Length == 1)
+            {
+                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
+                CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
+            }
+            else
+            {
+                if (rule.RightHandSide.Length == 0)
+                {
+                    // Create a new blank value.
+                    // Explicit semantic action may mutate this value
+                    CurrentSemanticValue = default(TValue);
+                    // The location span for an empty production will start with the
+                    // beginning of the next lexeme, and end with the finish of the
+                    // previous lexeme.  This gives the correct behaviour when this
+                    // nonsense value is used in later Merge operations.
+                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
+                        scanner.yylloc.Merge(LastSpan) :
+                        default(TSpan));
+                }
+                else
+                {
+                    // Default action: $$ = $1;
+                    CurrentSemanticValue = valueStack.TopElement();
+                    //  Default action "@$ = @1.Merge(@N)" for location info.
+                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
+                    TSpan atN = LocationStack[LocationStack.Depth - 1];
+                    CurrentLocationSpan = 
+                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
+                }
+            }
+
+            DoAction(ruleNumber);
+
+            for (int i = 0; i < rule.RightHandSide.Length; i++)
+            {
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+            }
+
+#if TRACE_ACTIONS
+				DisplayStack();
+#endif
+            FsaState = StateStack.TopElement();
+
+            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
+                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+        }
+
+        /// <summary>
+        /// Execute the selected action from array.
+        /// Must be overriden in derived classes.
+        /// </summary>
+        /// <param name="actionNumber">Index of the action to perform</param>
+        protected abstract void DoAction(int actionNumber);
+
+        private bool ErrorRecovery()
+        {
+            bool discard;
+
+            if (!recovering) // if not recovering from previous error
+                ReportError();
+
+            if (!FindErrorRecoveryState())
+                return false;
+            //
+            //  The interim fix for the "looping in error recovery"
+            //  artifact involved moving the setting of the recovering 
+            //  bool until after invalid tokens have been discarded.
+            //
+            ShiftErrorToken();
+            discard = DiscardInvalidTokens();
+            recovering = true;
+            tokensSinceLastError = 0;
+            return discard;
+        }
+
+        private void ReportError1()
+        {
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
+
+            if (FsaState.ParserTable.Count < 7)
+            {
+                bool first = true;
+                foreach (int terminal in FsaState.ParserTable.Keys)
+                {
+                    if (first)
+                        errorMsg.Append(", expecting ");
+                    else
+                        errorMsg.Append(", or ");
+
+                    errorMsg.Append(TerminalToString(terminal));
+                    first = false;
+                }
+            }
+            scanner.yyerror(errorMsg.ToString());
+        }
+
+        private void ReportError()
+        {
+            object[] args = new object[FsaState.ParserTable.Keys.Count+1];
+            args[0] = TerminalToString(NextToken);
+            int i=1;
+            foreach (int terminal in FsaState.ParserTable.Keys)
+            {
+                args[i] = TerminalToString(terminal);
+                i++;
+            }
+            scanner.yyerror("",args);
+        }
+
+        private void ShiftErrorToken()
+        {
+            int old_next = NextToken;
+            NextToken = errorToken;
+
+            Shift(FsaState.ParserTable[NextToken]);
+
+#if TRACE_ACTIONS
+				Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+            NextToken = old_next;
+        }
+
+        private bool FindErrorRecoveryState()
+        {
+            while (true)    // pop states until one found that accepts error token
+            {
+                if (FsaState.ParserTable != null &&
+                    FsaState.ParserTable.ContainsKey(errorToken) &&
+                    FsaState.ParserTable[errorToken] > 0) // shift
+                    return true;
+
+#if TRACE_ACTIONS
+					Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
+#endif
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+
+#if TRACE_ACTIONS
+					DisplayStack();
+#endif
+                if (StateStack.IsEmpty())
+                {
+#if TRACE_ACTIONS
+                        Console.Error.Write("Aborting: didn't find a state that accepts error token");
+#endif
+                    return false;
+                }
+                else
+                    FsaState = StateStack.TopElement();
+            }
+        }
+
+        private bool DiscardInvalidTokens()
+        {
+
+            int action = FsaState.defaultAction;
+
+            if (FsaState.ParserTable != null)
+            {
+                // Discard tokens until find one that works ...
+                while (true)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif                       
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (NextToken == endOfFileToken)
+                        return false;
+
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+
+                    if (action != 0)
+                        return true;
+                    else
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
+#endif
+                        NextToken = 0;
+                    }
+                }
+            }
+            else if (recovering && tokensSinceLastError == 0)
+            {
+                // 
+                //  Boolean recovering is not set until after the first
+                //  error token has been shifted.  Thus if we get back 
+                //  here with recovering set and no tokens read we are
+                //  looping on the same error recovery action.  This 
+                //  happens if current_state.ParserTable is null because
+                //  the state has an LR(0) reduction, but not all
+                //  lookahead tokens are valid.  This only occurs for
+                //  error productions that *end* on "error".
+                //
+                //  This action discards tokens one at a time until
+                //  the looping stops.  Another attack would be to always
+                //  use the LALR(1) table if a production ends on "error"
+                //
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
+#endif
+                if (NextToken == endOfFileToken)
+                    return false;
+                NextToken = 0;
+                return true;
+            }
+            else
+                return true;
+
+        }
+
+        /// <summary>
+        /// Traditional YACC method.  Discards the next input token.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyclearin() { NextToken = 0; }
+
+        /// <summary>
+        /// Tradional YACC method. Clear the "recovering" flag.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyerrok()
+        {
+            recovering = false;
+        }
+
+        /// <summary>
+        /// OBSOLETE FOR VERSION 1.4.0
+        /// Method used by derived types to insert new
+        /// state instances in the "states" array.
+        /// </summary>
+        /// <param name="stateNumber">index of the state</param>
+        /// <param name="state">data for the state</param>
+        protected void AddState(int stateNumber, State state)
+        {
+            states[stateNumber] = state;
+            state.number = stateNumber;
+        }
+
+        private void DisplayStack()
+        {
+            Console.Error.Write("State now");
+            for (int i = 0; i < StateStack.Depth; i++)
+                Console.Error.Write(" {0}", StateStack[i].number);
+            Console.Error.WriteLine();
+        }
+
+        private void DisplayRule(int ruleNumber)
+        {
+            Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
+            DisplayProduction(rules[ruleNumber]);
+        }
+
+        private void DisplayProduction(Rule rule)
+        {
+            if (rule.RightHandSide.Length == 0)
+                Console.Error.Write("/* empty */ ");
+            else
+                foreach (int symbol in rule.RightHandSide)
+                    Console.Error.Write("{0} ", SymbolToString(symbol));
+
+            Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
+        }
+
+        /// <summary>
+        /// Abstract state class naming terminal symbols.
+        /// This is overridden by derived classes with the
+        /// name (or alias) to be used in error messages.
+        /// </summary>
+        /// <param name="terminal">The terminal ordinal</param>
+        /// <returns></returns>
+        protected abstract string TerminalToString(int terminal);
+
+        private string SymbolToString(int symbol)
+        {
+            if (symbol < 0)
+                return nonTerminals[-symbol];
+            else
+                return TerminalToString(symbol);
+        }
+
+        /// <summary>
+        /// Return text representation of argument character
+        /// </summary>
+        /// <param name="input">The character to convert</param>
+        /// <returns>String representation of the character</returns>
+        protected static string CharToString(char input)
+        {
+            switch (input)
+            {
+                case '\a': return @"'\a'";
+                case '\b': return @"'\b'";
+                case '\f': return @"'\f'";
+                case '\n': return @"'\n'";
+                case '\r': return @"'\r'";
+                case '\t': return @"'\t'";
+                case '\v': return @"'\v'";
+                case '\0': return @"'\0'";
+                default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Classes implementing this interface must supply a
+    /// method that merges two location objects to return
+    /// a new object of the same type.
+    /// GPPG-generated parsers have the default location
+    /// action equivalent to "@$ = @1.Merge(@N);" where N
+    /// is the right-hand-side length of the production.
+    /// </summary>
+    /// <typeparam name="TSpan">The Location type</typeparam>
+#if EXPORT_GPPG
+    public interface IMerge<TSpan>
+#else
+    internal interface IMerge<TSpan>
+#endif
+    {
+        /// <summary>
+        /// Interface method that creates a location object from
+        /// the current and last object.  Typically used to create
+        /// a location object extending from the start of the @1
+        /// object to the end of the @N object.
+        /// </summary>
+        /// <param name="last">The lexically last object to merge</param>
+        /// <returns>The merged location object</returns>
+        TSpan Merge(TSpan last);
+    }
+
+    /// <summary>
+    /// This is the default class that carries location
+    /// information from the scanner to the parser.
+    /// If you don't declare "%YYLTYPE Foo" the parser
+    /// will expect to deal with this type.
+    /// </summary>
+#if EXPORT_GPPG
+    public class LexLocation : IMerge<LexLocation>
+#else
+    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
+    internal class LexLocation : IMerge<LexLocation>
+#endif
+    {
+        private int startLine;   // start line
+        private int startColumn; // start column
+        private int endLine;     // end line
+        private int endColumn;   // end column
+
+        /// <summary>
+        /// The line at which the text span starts.
+        /// </summary>
+        public int StartLine { get { return startLine; } }
+
+        /// <summary>
+        /// The column at which the text span starts.
+        /// </summary>
+        public int StartColumn { get { return startColumn; } }
+
+        /// <summary>
+        /// The line on which the text span ends.
+        /// </summary>
+        public int EndLine { get { return endLine; } }
+
+        /// <summary>
+        /// The column of the first character
+        /// beyond the end of the text span.
+        /// </summary>
+        public int EndColumn { get { return endColumn; } }
+
+        /// <summary>
+        /// Default no-arg constructor.
+        /// </summary>
+        public LexLocation()
+        { }
+
+        /// <summary>
+        /// Constructor for text-span with given start and end.
+        /// </summary>
+        /// <param name="sl">start line</param>
+        /// <param name="sc">start column</param>
+        /// <param name="el">end line </param>
+        /// <param name="ec">end column</param>
+        public LexLocation(int sl, int sc, int el, int ec)
+        { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
+
+        /// <summary>
+        /// Create a text location which spans from the 
+        /// start of "this" to the end of the argument "last"
+        /// </summary>
+        /// <param name="last">The last location in the result span</param>
+        /// <returns>The merged span</returns>
+        public LexLocation Merge(LexLocation last)
+        { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
+
+    }
+
+    /// <summary>
+    /// Abstract scanner class that GPPG expects its scanners to 
+    /// extend.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
+    /// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
+#if EXPORT_GPPG
+    public abstract class AbstractScanner<TValue, TSpan>
+#else
+    internal abstract class AbstractScanner<TValue, TSpan>
+#endif
+        where TSpan : IMerge<TSpan>
+    {
+        /// <summary>
+        /// Lexical value optionally set by the scanner. The value
+        /// is of the %YYSTYPE type declared in the parser spec.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        // A field must be declared for this value of parametric type,
+        // since it may be instantiated by a value struct.  If it were 
+        // implemented as a property, machine generated code in derived
+        // types would not be able to select on the returned value.
+        public TValue yylval;                     // Lexical value: set by scanner
+
+        /// <summary>
+        /// Current scanner location property. The value is of the
+        /// type declared by %YYLTYPE in the parser specification.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual TSpan yylloc
+        {
+            get { return default(TSpan); }       // Empty implementation allowing
+            set { /* skip */ }                   // yylloc to be ignored entirely.
+        }
+
+        /// <summary>
+        /// Main call point for LEX-like scanners.  Returns an int
+        /// corresponding to the token recognized by the scanner.
+        /// </summary>
+        /// <returns>An int corresponding to the token</returns>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public abstract int yylex();
+
+        /// <summary>
+        /// Traditional error reporting provided by LEX-like scanners
+        /// to their YACC-like clients.
+        /// </summary>
+        /// <param name="format">Message format string</param>
+        /// <param name="args">Optional array of args</param>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual void yyerror(string format, params object[] args) { }
+    }
+
+    /// <summary>
+    /// Encapsulated state for the parser.
+    /// Opaque to users, visible to the tool-generated code.
+    /// </summary>
+#if EXPORT_GPPG
+    public class State
+#else
+    internal class State
+#endif
+    {
+        internal int number;
+        internal Dictionary<int, int> ParserTable;   // Terminal -> ParseAction
+        internal Dictionary<int, int> Goto;          // NonTerminal -> State;
+        internal int defaultAction; // = 0;		     // ParseAction
+
+        /// <summary>
+        /// State transition data for this state. Pairs of elements of the 
+        /// goto array associate symbol ordinals with next state indices.
+        /// The actions array is passed to another constructor. 
+        /// </summary>
+        /// <param name="actions">The action list</param>
+        /// <param name="goToList">Next state data</param>
+        public State(int[] actions, int[] goToList)
+            : this(actions)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+
+        /// <summary>
+        /// Action data for this state. Pairs of elements of the 
+        /// action array associate action ordinals with each of
+        /// those symbols that have actions in the current state.
+        /// </summary>
+        /// <param name="actions">The action array</param>
+        public State(int[] actions)
+        {
+            ParserTable = new Dictionary<int, int>();
+            for (int i = 0; i < actions.Length; i += 2)
+                ParserTable.Add(actions[i], actions[i + 1]);
+        }
+
+        /// <summary>
+        /// Set the default action for this state.
+        /// </summary>
+        /// <param name="defaultAction">Ordinal of the default action</param>
+        public State(int defaultAction)
+        {
+            this.defaultAction = defaultAction;
+        }
+
+        /// <summary>
+        /// Set the default action and the state transition table.
+        /// </summary>
+        /// <param name="defaultAction">The default action</param>
+        /// <param name="goToList">Transitions from this state</param>
+        public State(int defaultAction, int[] goToList)
+            : this(defaultAction)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+    }
+
+    /// <summary>
+    /// Rule representation at runtime.
+    /// </summary>
+#if EXPORT_GPPG
+    public class Rule
+#else
+    internal class Rule
+#endif
+    {
+        internal int LeftHandSide; // symbol
+        internal int[] RightHandSide; // symbols
+
+        /// <summary>
+        /// Rule constructor.  This holds the ordinal of
+        /// the left hand side symbol, and the list of
+        /// right hand side symbols, in lexical order.
+        /// </summary>
+        /// <param name="left">The LHS non-terminal</param>
+        /// <param name="right">The RHS symbols, in lexical order</param>
+        public Rule(int left, int[] right)
+        {
+            this.LeftHandSide = left;
+            this.RightHandSide = right;
+        }
+    }
+
+    /// <summary>
+    /// Stack utility for the shift-reduce parser.
+    /// GPPG parsers have three instances:
+    /// (1) The parser state stack, T = QUT.Gppg.State,
+    /// (2) The semantic value stack, T = TValue,
+    /// (3) The location stack, T = TSpan.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if EXPORT_GPPG
+    public class PushdownPrefixState<T>
+#else
+    internal class PushdownPrefixState<T>
+#endif
+    {
+        //  Note that we cannot use the BCL Stack<T> class
+        //  here as derived types need to index into stacks.
+        //
+        private T[] array = new T[8];
+        private int tos = 0;
+
+        /// <summary>
+        /// Indexer for values of the stack below the top.
+        /// </summary>
+        /// <param name="index">index of the element, starting from the bottom</param>
+        /// <returns>the selected element</returns>
+        public T this[int index] { get { return array[index]; } }
+
+        /// <summary>
+        /// The current depth of the stack.
+        /// </summary>
+        public int Depth { get { return tos; } }
+
+        internal void Push(T value)
+        {
+            if (tos >= array.Length)
+            {
+                T[] newarray = new T[array.Length * 2];
+                System.Array.Copy(array, newarray, tos);
+                array = newarray;
+            }
+            array[tos++] = value;
+        }
+
+        internal T Pop()
+        {
+            T rslt = array[--tos];
+            array[tos] = default(T);
+            return rslt;
+        }
+
+        internal T TopElement() { return array[tos - 1]; }
+
+        internal bool IsEmpty() { return tos == 0; }
+    }
+}
\ No newline at end of file
diff --git a/Module7/SimpleLanguage2/SimpleLang2.csproj b/Module7/SimpleLanguage2/SimpleLang2.csproj
new file mode 100644
index 0000000..e83a899
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleLang2.csproj
@@ -0,0 +1,66 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SimpleLang</RootNamespace>
+    <AssemblyName>SimpleLang</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Visitors\AssignCountVisitor.cs" />
+    <Compile Include="Visitors\AutoVisitor.cs" />
+    <Compile Include="Visitors\PrettyPrintVisitor.cs" />
+    <Compile Include="Visitors\Visitor.cs" />
+    <Compile Include="Main.cs" />
+    <Compile Include="ParserHelper.cs" />
+    <Compile Include="ProgramTree.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShiftReduceParserCode.cs" />
+    <Compile Include="SimpleLex.cs" />
+    <Compile Include="SimpleYacc.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- 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">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/Module7/SimpleLanguage2/SimpleLang2.sln b/Module7/SimpleLanguage2/SimpleLang2.sln
new file mode 100644
index 0000000..6983d32
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleLang2.sln
@@ -0,0 +1,22 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLang2", "SimpleLang2.csproj", "{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.ActiveCfg = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.Build.0 = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.ActiveCfg = Release|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Module7/SimpleLanguage2/SimpleLex.cs b/Module7/SimpleLanguage2/SimpleLex.cs
new file mode 100644
index 0000000..3658b77
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleLex.cs
@@ -0,0 +1,1531 @@
+//
+//  This CSharp output file generated by Gardens Point LEX
+//  Version:  1.1.3.301
+//  Machine:  SSM
+//  DateTime: 19.08.2014 13:38:37
+//  UserName: ?????????
+//  GPLEX input file <SimpleLex.lex>
+//  GPLEX frame file <embedded resource>
+//
+//  Option settings: unicode, parser, minimize
+//  Option settings: classes, compressMap, compressNext, persistBuffer, embedbuffers
+//  Fallback code page: Target machine default
+//
+
+//
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
+//
+//
+#define BACKUP
+#define PERSIST
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+using SimpleParser;
+using QUT.Gppg;
+using System.Linq;
+
+namespace SimpleScanner
+{   
+    /// <summary>
+    /// Summary Canonical example of GPLEX automaton
+    /// </summary>
+    
+#if STANDALONE
+    //
+    // These are the dummy declarations for stand-alone GPLEX applications
+    // normally these declarations would come from the parser.
+    // If you declare /noparser, or %option noparser then you get this.
+    //
+
+     public enum Tokens
+    { 
+      EOF = 0, maxParseToken = int.MaxValue 
+      // must have at least these two, values are almost arbitrary
+    }
+
+     public abstract class ScanBase
+    {
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public abstract int yylex();
+
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
+        protected virtual bool yywrap() { return true; }
+
+#if BABEL
+        protected abstract int CurrentSc { get; set; }
+        // EolState is the 32-bit of state data persisted at 
+        // the end of each line for Visual Studio colorization.  
+        // The default is to return CurrentSc.  You must override
+        // this if you want more complicated behavior.
+        public virtual int EolState { 
+            get { return CurrentSc; }
+            set { CurrentSc = value; } 
+        }
+    }
+    
+     public interface IColorScan
+    {
+        void SetSource(string source, int offset);
+        int GetNext(ref int state, out int start, out int end);
+#endif // BABEL
+    }
+
+#endif // STANDALONE
+    
+    // If the compiler can't find the scanner base class maybe you
+    // need to run GPPG with the /gplex option, or GPLEX with /noparser
+#if BABEL
+     public sealed partial class Scanner : ScanBase, IColorScan
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+        
+        protected override int CurrentSc 
+        {
+             // The current start state is a property
+             // to try to avoid the user error of setting
+             // scState but forgetting to update the FSA
+             // start state "currentStart"
+             //
+             get { return currentScOrd; }  // i.e. return YY_START;
+             set { currentScOrd = value;   // i.e. BEGIN(value);
+                   currentStart = startState[value]; }
+        }
+#else  // BABEL
+     public sealed partial class Scanner : ScanBase
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+#endif // BABEL
+        
+        /// <summary>
+        /// The input buffer for this scanner.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public ScanBuff Buffer { get { return buffer; } }
+        
+        private static int GetMaxParseToken() {
+     System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken");
+            return (f == null ? int.MaxValue : (int)f.GetValue(null));
+        }
+        
+        static int parserMax = GetMaxParseToken();
+        
+        enum Result {accept, noMatch, contextFound};
+
+        const int maxAccept = 17;
+        const int initial = 18;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+
+#region user code
+#endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;      // last code read
+        int cCol;      // column number of code
+        int lNum;      // current line number
+        //
+        // The following instance variables are used, among other
+        // things, for constructing the yylloc location objects.
+        //
+        int tokPos;        // buffer position at start of token
+        int tokCol;        // zero-based column number at start of token
+        int tokLin;        // line number at start of token
+        int tokEPos;       // buffer position at end of token
+        int tokECol;       // column number at end of token
+        int tokELin;       // line number at end of token
+        string tokTxt;     // lazily constructed text of token
+#if STACK          
+        private Stack<int> scStack = new Stack<int>();
+#endif // STACK
+
+#region ScannerTables
+    struct Table {
+        public int min; public int rng; public int dflt;
+        public sbyte[] nxt;
+        public Table(int m, int x, int d, sbyte[] n) {
+            min = m; rng = x; dflt = d; nxt = n;
+        }
+    };
+
+    static int[] startState = new int[] {18, 0};
+
+#region CompressedCharacterMap
+    //
+    // 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' */ 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, 
+/*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+    static sbyte MapC(int code)
+    { // '\0' <= code <= '\U0010FFFF'
+      if (code < 123) // '\0' <= code <= 'z'
+        return mapC0[code - 0];
+      else // '{' <= code <= '\U0010FFFF'
+        return (sbyte)14;
+    }
+#endregion
+
+    static Table[] NxS = new Table[20] {
+/* NxS[   0] */ new Table(0, 0, 0, null),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 19}),
+/* 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[   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[   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(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}),
+    };
+
+int NextState() {
+    if (code == ScanBuff.EndOfFile)
+        return eofNum;
+    else
+        unchecked {
+            int rslt;
+            int idx = MapC(code) - NxS[state].min;
+            if (idx < 0) idx += 15;
+            if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
+            else rslt = NxS[state].nxt[idx];
+            return rslt;
+        }
+}
+
+#endregion
+
+
+#if BACKUP
+        // ==============================================================
+        // == Nested struct used for backup in automata that do backup ==
+        // ==============================================================
+
+        struct Context // class used for automaton backup.
+        {
+            public int bPos;
+            public int rPos; // scanner.readPos saved value
+            public int cCol;
+            public int lNum; // Need this in case of backup over EOL.
+            public int state;
+            public int cChr;
+        }
+        
+        private Context ctx = new Context();
+#endif // BACKUP
+
+        // ==============================================================
+        // ==== Nested struct to support input switching in scanners ====
+        // ==============================================================
+
+		struct BufferContext {
+            internal ScanBuff buffSv;
+			internal int chrSv;
+			internal int cColSv;
+			internal int lNumSv;
+		}
+
+        // ==============================================================
+        // ===== Private methods to save and restore buffer contexts ====
+        // ==============================================================
+
+        /// <summary>
+        /// This method creates a buffer context record from
+        /// the current buffer object, together with some
+        /// scanner state values. 
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        BufferContext MkBuffCtx()
+		{
+			BufferContext rslt;
+			rslt.buffSv = this.buffer;
+			rslt.chrSv = this.code;
+			rslt.cColSv = this.cCol;
+			rslt.lNumSv = this.lNum;
+			return rslt;
+		}
+
+        /// <summary>
+        /// This method restores the buffer value and allied
+        /// scanner state from the given context record value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void RestoreBuffCtx(BufferContext value)
+		{
+			this.buffer = value.buffSv;
+			this.code = value.chrSv;
+			this.cCol = value.cColSv;
+			this.lNum = value.lNumSv;
+        } 
+        // =================== End Nested classes =======================
+
+#if !NOFILES
+     public Scanner(Stream file) {
+            SetSource(file, 0); // unicode option
+        }
+
+        public Scanner(Stream file, string codepage) {
+            SetSource(file, CodePageHandling.GetCodePage(codepage));
+        }
+        
+#endif // !NOFILES
+
+     public Scanner() { }
+
+        private int readPos;
+
+        void GetCode()
+        {
+            if (code == '\n')  // This needs to be fixed for other conventions
+                               // i.e. [\r\n\205\u2028\u2029]
+            { 
+                cCol = -1;
+                lNum++;
+            }
+            readPos = buffer.Pos;
+
+            // Now read new codepoint.
+            code = buffer.Read();
+            if (code > ScanBuff.EndOfFile)
+            {
+#if (!BYTEMODE)
+                if (code >= 0xD800 && code <= 0xDBFF)
+                {
+                    int next = buffer.Read();
+                    if (next < 0xDC00 || next > 0xDFFF)
+                        code = ScanBuff.UnicodeReplacementChar;
+                    else
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
+                }
+#endif
+                cCol++;
+            }
+        }
+
+        void MarkToken()
+        {
+#if (!PERSIST)
+            buffer.Mark();
+#endif
+            tokPos = readPos;
+            tokLin = lNum;
+            tokCol = cCol;
+        }
+        
+        void MarkEnd()
+        {
+            tokTxt = null;
+            tokEPos = readPos;
+            tokELin = lNum;
+            tokECol = cCol;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int Peek()
+        {
+            int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
+            GetCode(); rslt = code;
+            lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
+            return rslt;
+        }
+
+        // ==============================================================
+        // =====    Initialization of string-based input buffers     ====
+        // ==============================================================
+
+        /// <summary>
+        /// Create and initialize a StringBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the input string</param>
+        /// <param name="offset">starting offset in the string</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(string source, int offset)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.buffer.Pos = offset;
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+
+#if !NOFILES        
+        // ================ LineBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a LineBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the list of input strings</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(IList<string> source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            this.lNum = 0;
+            GetCode();
+        }
+
+        // =============== StreamBuffer Initialization ==================
+
+        /// <summary>
+        /// Create and initialize a StreamBuff buffer object for this scanner.
+        /// StreamBuff is buffer for 8-bit byte files.
+        /// </summary>
+        /// <param name="source">the input byte stream</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+        
+#if !BYTEMODE
+        // ================ TextBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a TextBuff buffer object for this scanner.
+        /// TextBuff is a buffer for encoded unicode files.
+        /// </summary>
+        /// <param name="source">the input text file</param>
+        /// <param name="fallbackCodePage">Code page to use if file has
+        /// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source, int fallbackCodePage)
+        {
+            this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+#endif // !BYTEMODE
+#endif // !NOFILES
+        
+        // ==============================================================
+
+#if BABEL
+        //
+        //  Get the next token for Visual Studio
+        //
+        //  "state" is the inout mode variable that maintains scanner
+        //  state between calls, using the EolState property. In principle,
+        //  if the calls of EolState are costly set could be called once
+        //  only per line, at the start; and get called only at the end
+        //  of the line. This needs more infrastructure ...
+        //
+        public int GetNext(ref int state, out int start, out int end)
+        {
+                Tokens next;
+            int s, e;
+            s = state;        // state at start
+            EolState = state;
+                next = (Tokens)Scan();
+            state = EolState;
+            e = state;       // state at end;
+            start = tokPos;
+            end = tokEPos - 1; // end is the index of last char.
+            return (int)next;
+        }        
+#endif // BABEL
+
+        // ======== AbstractScanner<> Implementation =========
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public override int yylex()
+        {
+            // parserMax is set by reflecting on the Tokens
+            // enumeration.  If maxParseToken is defined
+            // that is used, otherwise int.MaxValue is used.
+            int next;
+            do { next = Scan(); } while (next >= parserMax);
+            return next;
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yypos { get { return tokPos; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yyline { get { return tokLin; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yycol { get { return tokCol; } }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
+        public string yytext
+        {
+            get 
+            {
+                if (tokTxt == null) 
+                    tokTxt = buffer.GetString(tokPos, tokEPos);
+                return tokTxt;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void yyless(int n)
+        {
+            buffer.Pos = tokPos;
+            // Must read at least one char, so set before start.
+            cCol = tokCol - 1; 
+            GetCode();
+            // Now ensure that line counting is correct.
+            lNum = tokLin;
+            // And count the rest of the text.
+            for (int i = 0; i < n; i++) GetCode();
+            MarkEnd();
+        }
+       
+        //
+        //  It would be nice to count backward in the text
+        //  but it does not seem possible to re-establish
+        //  the correct column counts except by going forward.
+        //
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void _yytrunc(int n) { yyless(yyleng - n); }
+        
+        //
+        // This is painful, but we no longer count
+        // codepoints.  For the overwhelming majority 
+        // of cases the single line code is fast, for
+        // the others, well, at least it is all in the
+        // buffer so no files are touched. Note that we
+        // can't use (tokEPos - tokPos) because of the
+        // possibility of surrogate pairs in the token.
+        //
+        [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 {
+                    int ch;
+                    int count = 0;
+                    int save = buffer.Pos;
+                    buffer.Pos = tokPos;
+                    do {
+                        ch = buffer.Read();
+                        if (!char.IsHighSurrogate((char)ch)) count++;
+                    } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
+                    buffer.Pos = save; 
+                    return count;
+                }
+#endif // BYTEMODE
+            }
+        }
+        
+        // ============ methods available in actions ==============
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int YY_START {
+            get { return currentScOrd; }
+            set { currentScOrd = value; 
+                  currentStart = startState[value]; 
+            } 
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void BEGIN(int next) {
+            currentScOrd = next;
+            currentStart = startState[next];
+        }
+
+        // ============== The main tokenizer code =================
+
+        int Scan()
+        {
+            try {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
+#if LEFTANCHORS
+                    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...
+                        GetCode();
+                    }
+                    
+#else // !LEFTANCHORS
+                    state = currentStart;
+                    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();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
+#if BACKUP
+                        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;
+                        }
+                        else
+#endif // BACKUP
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
+                        MarkEnd();
+#region ActionSwitch
+#pragma warning disable 162
+    switch (state)
+    {
+        case eofNum:
+            if (yywrap())
+                return (int)Tokens.EOF;
+            break;
+        case 1:
+yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM;
+            break;
+        case 2:
+        case 4:
+LexError();
+            break;
+        case 3:
+int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+            break;
+        case 5:
+return (int)Tokens.SEMICOLON;
+            break;
+        case 6:
+return (int)Tokens.MINUS;
+            break;
+        case 7:
+return (int)Tokens.PLUS;
+            break;
+        case 8:
+return (int)Tokens.MULT;
+            break;
+        case 9:
+return (int)Tokens.DIV;
+            break;
+        case 10:
+return (int)Tokens.LPAREN;
+            break;
+        case 11:
+return (int)Tokens.RPAREN;
+            break;
+        case 12:
+return (int)Tokens.COLUMN;
+            break;
+        case 13:
+return (int)Tokens.ASSIGNMULT;
+            break;
+        case 14:
+return (int)Tokens.ASSIGNPLUS;
+            break;
+        case 15:
+return (int)Tokens.ASSIGNMINUS;
+            break;
+        case 16:
+return (int)Tokens.ASSIGN;
+            break;
+        case 17:
+yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+            break;
+        default:
+            break;
+    }
+#pragma warning restore 162
+#endregion
+                    }
+                }
+            } // end try
+            finally {
+// User-specified epilog to scan()
+yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+// End, user-specified epilog
+            } // end finally
+        }
+
+#if BACKUP
+        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;
+            ctx.lNum  = lNum;
+            ctx.state = state;
+            ctx.cChr  = code;
+        }
+
+        void RestoreStateAndPos(ref Context ctx)
+        {
+            buffer.Pos = ctx.bPos;
+            readPos = ctx.rPos;
+            cCol  = ctx.cCol;
+            lNum  = ctx.lNum;
+            state = ctx.state;
+            code  = ctx.cChr;
+        }
+
+#endif // BACKUP
+
+        // ============= End of the tokenizer code ================
+
+#if STACK        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void yy_clear_stack() { scStack.Clear(); }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int yy_top_state() { return scStack.Peek(); }
+        
+        internal void yy_push_state(int state)
+        {
+            scStack.Push(currentScOrd);
+            BEGIN(state);
+        }
+        
+        internal void yy_pop_state()
+        {
+            // Protect against input errors that pop too far ...
+            if (scStack.Count > 0) {
+				int newSc = scStack.Pop();
+				BEGIN(newSc);
+            } // Otherwise leave stack unchanged.
+        }
+ #endif // STACK
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void ECHO() { Console.Out.Write(yytext); }
+        
+#region UserCodeSection
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("write",(int)Tokens.WRITE);
+    keywords.Add("var",(int)Tokens.VAR);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
+
+#endregion
+    } // end class $Scanner
+
+// ==============================================================
+// <auto-generated>
+// This code automatically produced from an embedded resource.
+// Do not edit this file, or it will become incompatible with 
+// the specification from which it was generated.
+// </auto-generated>
+// ==============================================================
+
+// Code copied from GPLEX embedded resource
+    [Serializable]
+    public class BufferException : Exception
+    {
+        public BufferException() { }
+        public BufferException(string message) : base(message) { }
+        public BufferException(string message, Exception innerException)
+            : base(message, innerException) { }
+        protected BufferException(SerializationInfo info, StreamingContext context)
+            : base(info, context) { }
+    }
+
+    public abstract class ScanBuff
+    {
+        private string fileNm;
+
+        public const int EndOfFile = -1;
+        public const int UnicodeReplacementChar = 0xFFFD;
+
+        public bool IsFile { get { return (fileNm != null); } }
+        public string FileName { get { return fileNm; } set { fileNm = value; } }
+
+        public abstract int Pos { get; set; }
+        public abstract int Read();
+        public virtual void Mark() { }
+
+        public abstract string GetString(int begin, int limit);
+
+        public static ScanBuff GetBuffer(string source)
+        {
+            return new StringBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(IList<string> source)
+        {
+            return new LineBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(Stream source)
+        {
+            return new BuildBuffer(source);
+        }
+
+#if (!BYTEMODE)
+        public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
+        {
+            return new BuildBuffer(source, fallbackCodePage);
+        }
+#endif
+    }
+
+    #region Buffer classes
+
+    // ==============================================================
+    // =====  Definitions for various ScanBuff derived classes   ====
+    // ==============================================================
+    // ===============         String input          ================
+    // ==============================================================
+
+    /// <summary>
+    /// This class reads characters from a single string as
+    /// required, for example, by Visual Studio language services
+    /// </summary>
+    sealed class StringBuffer : ScanBuff
+    {
+        string str;        // input buffer
+        int bPos;          // current position in buffer
+        int sLen;
+
+        public StringBuffer(string source)
+        {
+            this.str = source;
+            this.sLen = source.Length;
+            this.FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (bPos < sLen) return str[bPos++];
+            else if (bPos == sLen) { bPos++; return '\n'; }   // one strike, see new line
+            else { bPos++; return EndOfFile; }                // two strikes and you're out!
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            //  "limit" can be greater than sLen with the BABEL
+            //  option set.  Read returns a "virtual" EOL if
+            //  an attempt is made to read past the end of the
+            //  string buffer.  Without the guard any attempt 
+            //  to fetch yytext for a token that includes the 
+            //  EOL will throw an index exception.
+            if (limit > sLen) limit = sLen;
+            if (limit <= begin) return "";
+            else return str.Substring(begin, limit - begin);
+        }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+        public override string ToString() { return "StringBuffer"; }
+    }
+
+    // ==============================================================
+    //  The LineBuff class contributed by Nigel Horspool, 
+    //  nigelh@cs.uvic.cs
+    // ==============================================================
+
+    sealed class LineBuffer : ScanBuff
+    {
+        IList<string> line;    // list of source lines from a file
+        int numLines;          // number of strings in line list
+        string curLine;        // current line in that list
+        int cLine;             // index of current line in the list
+        int curLen;            // length of current line
+        int curLineStart;      // position of line start in whole file
+        int curLineEnd;        // position of line end in whole file
+        int maxPos;            // max position ever visited in whole file
+        int cPos;              // ordinal number of code in source
+
+        // Constructed from a list of strings, one per source line.
+        // The lines have had trailing '\n' characters removed.
+        public LineBuffer(IList<string> lineList)
+        {
+            line = lineList;
+            numLines = line.Count;
+            cPos = curLineStart = 0;
+            curLine = (numLines > 0 ? line[0] : "");
+            maxPos = curLineEnd = curLen = curLine.Length;
+            cLine = 1;
+            FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (cPos < curLineEnd)
+                return curLine[cPos++ - curLineStart];
+            if (cPos++ == curLineEnd)
+                return '\n';
+            if (cLine >= numLines)
+                return EndOfFile;
+            curLine = line[cLine];
+            curLen = curLine.Length;
+            curLineStart = curLineEnd + 1;
+            curLineEnd = curLineStart + curLen;
+            if (curLineEnd > maxPos)
+                maxPos = curLineEnd;
+            cLine++;
+            return curLen > 0 ? curLine[0] : '\n';
+        }
+
+        // To speed up searches for the line containing a position
+        private int cachedPosition;
+        private int cachedIxdex;
+        private int cachedLineStart;
+
+        // Given a position pos within the entire source, the results are
+        //   ix     -- the index of the containing line
+        //   lstart -- the position of the first character on that line
+        private void findIndex(int pos, out int ix, out int lstart)
+        {
+            if (pos >= cachedPosition)
+            {
+                ix = cachedIxdex; lstart = cachedLineStart;
+            }
+            else
+            {
+                ix = lstart = 0;
+            }
+            for (; ; )
+            {
+                int len = line[ix].Length + 1;
+                if (pos < lstart + len) break;
+                lstart += len;
+                ix++;
+            }
+            cachedPosition = pos;
+            cachedIxdex = ix;
+            cachedLineStart = lstart;
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            if (begin >= maxPos || limit <= begin) return "";
+            int endIx, begIx, endLineStart, begLineStart;
+            findIndex(begin, out begIx, out begLineStart);
+            int begCol = begin - begLineStart;
+            findIndex(limit, out endIx, out endLineStart);
+            int endCol = limit - endLineStart;
+            string s = line[begIx];
+            if (begIx == endIx)
+            {
+                // the usual case, substring all on one line
+                return (endCol <= s.Length) ?
+                    s.Substring(begCol, endCol - begCol)
+                    : s.Substring(begCol) + "\n";
+            }
+            // the string spans multiple lines, yuk!
+            StringBuilder sb = new StringBuilder();
+            if (begCol < s.Length)
+                sb.Append(s.Substring(begCol));
+            for (; ; )
+            {
+                sb.Append("\n");
+                s = line[++begIx];
+                if (begIx >= endIx) break;
+                sb.Append(s);
+            }
+            if (endCol <= s.Length)
+            {
+                sb.Append(s.Substring(0, endCol));
+            }
+            else
+            {
+                sb.Append(s);
+                sb.Append("\n");
+            }
+            return sb.ToString();
+        }
+
+        public override int Pos
+        {
+            get { return cPos; }
+            set
+            {
+                cPos = value;
+                findIndex(cPos, out cLine, out curLineStart);
+                curLine = line[cLine];
+                curLineEnd = curLineStart + curLine.Length;
+            }
+        }
+
+        public override string ToString() { return "LineBuffer"; }
+    }
+
+
+    // ==============================================================
+    // =====     class BuildBuff : for unicode text files    ========
+    // ==============================================================
+
+    class BuildBuffer : ScanBuff
+    {
+        // Double buffer for char stream.
+        class BufferElement
+        {
+            StringBuilder bldr = new StringBuilder();
+            StringBuilder next = new StringBuilder();
+            int minIx;
+            int maxIx;
+            int brkIx;
+            bool appendToNext;
+
+            internal BufferElement() { }
+
+            internal int MaxIndex { get { return maxIx; } }
+            // internal int MinIndex { get { return minIx; } }
+
+            internal char this[int index]
+            {
+                get
+                {
+                    if (index < minIx || index >= maxIx)
+                        throw new BufferException("Index was outside data buffer");
+                    else if (index < brkIx)
+                        return bldr[index - minIx];
+                    else
+                        return next[index - brkIx];
+                }
+            }
+
+            internal void Append(char[] block, int count)
+            {
+                maxIx += count;
+                if (appendToNext)
+                    this.next.Append(block, 0, count);
+                else
+                {
+                    this.bldr.Append(block, 0, count);
+                    brkIx = maxIx;
+                    appendToNext = true;
+                }
+            }
+
+            internal string GetString(int start, int limit)
+            {
+                if (limit <= start)
+                    return "";
+                if (start >= minIx && limit <= maxIx)
+                    if (limit < brkIx) // String entirely in bldr builder
+                        return bldr.ToString(start - minIx, limit - start);
+                    else if (start >= brkIx) // String entirely in next builder
+                        return next.ToString(start - brkIx, limit - start);
+                    else // Must do a string-concatenation
+                        return
+                            bldr.ToString(start - minIx, brkIx - start) +
+                            next.ToString(0, limit - brkIx);
+                else
+                    throw new BufferException("String was outside data buffer");
+            }
+
+            internal void Mark(int limit)
+            {
+                if (limit > brkIx + 16) // Rotate blocks
+                {
+                    StringBuilder temp = bldr;
+                    bldr = next;
+                    next = temp;
+                    next.Length = 0;
+                    minIx = brkIx;
+                    brkIx = maxIx;
+                }
+            }
+        }
+
+        BufferElement data = new BufferElement();
+
+        int bPos;            // Postion index in the StringBuilder
+        BlockReader NextBlk; // Delegate that serves char-arrays;
+
+        private string EncodingName
+        {
+            get
+            {
+                StreamReader rdr = NextBlk.Target as StreamReader;
+                return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
+            }
+        }
+
+        public BuildBuffer(Stream stream)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Raw(stream);
+        }
+
+#if (!BYTEMODE)
+        public BuildBuffer(Stream stream, int fallbackCodePage)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
+        }
+#endif
+
+        /// <summary>
+        /// Marks a conservative lower bound for the buffer,
+        /// allowing space to be reclaimed.  If an application 
+        /// needs to call GetString at arbitrary past locations 
+        /// in the input stream, Mark() is not called.
+        /// </summary>
+        public override void Mark() { data.Mark(bPos - 2); }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+
+        /// <summary>
+        /// Read returns the ordinal number of the next char, or 
+        /// EOF (-1) for an end of stream.  Note that the next
+        /// code point may require *two* calls of Read().
+        /// </summary>
+        /// <returns></returns>
+        public override int Read()
+        {
+            //
+            //  Characters at positions 
+            //  [data.offset, data.offset + data.bldr.Length)
+            //  are available in data.bldr.
+            //
+            if (bPos < data.MaxIndex)
+            {
+                // ch0 cannot be EOF
+                return (int)data[bPos++];
+            }
+            else // Read from underlying stream
+            {
+                // Experimental code, blocks of page size
+                char[] chrs = new char[4096];
+                int count = NextBlk(chrs, 0, 4096);
+                if (count == 0)
+                    return EndOfFile;
+                else
+                {
+                    data.Append(chrs, count);
+                    return (int)data[bPos++];
+                }
+            }
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            return data.GetString(begin, limit);
+        }
+
+        public override string ToString()
+        {
+            return "StringBuilder buffer, encoding: " + this.EncodingName;
+        }
+    }
+
+    // =============== End ScanBuff-derived classes ==================
+
+    public delegate int BlockReader(char[] block, int index, int number);
+
+    // A delegate factory, serving up a delegate that
+    // reads a block of characters from the underlying
+    // encoded stream, via a StreamReader object.
+    //
+    public static class BlockReaderFactory
+    {
+        public static BlockReader Raw(Stream stream)
+        {
+            return delegate(char[] block, int index, int number)
+            {
+                byte[] b = new byte[number];
+                int count = stream.Read(b, 0, number);
+                int i = 0;
+                int j = index;
+                for (; i < count; i++, j++)
+                    block[j] = (char)b[i];
+                return count;
+            };
+        }
+
+#if (!BYTEMODE)
+        public static BlockReader Get(Stream stream, int fallbackCodePage)
+        {
+            Encoding encoding;
+            int preamble = Preamble(stream);
+
+            if (preamble != 0)  // There is a valid BOM here!
+                encoding = Encoding.GetEncoding(preamble);
+            else if (fallbackCodePage == -1) // Fallback is "raw" bytes
+                return Raw(stream);
+            else if (fallbackCodePage != -2) // Anything but "guess"
+                encoding = Encoding.GetEncoding(fallbackCodePage);
+            else // This is the "guess" option
+            {
+                int guess = new Guesser(stream).GuessCodePage();
+                stream.Seek(0, SeekOrigin.Begin);
+                if (guess == -1) // ==> this is a 7-bit file
+                    encoding = Encoding.ASCII;
+                else if (guess == 65001)
+                    encoding = Encoding.UTF8;
+                else             // ==> use the machine default
+                    encoding = Encoding.Default;
+            }
+            StreamReader reader = new StreamReader(stream, encoding);
+            return reader.Read;
+        }
+
+        static int Preamble(Stream stream)
+        {
+            int b0 = stream.ReadByte();
+            int b1 = stream.ReadByte();
+
+            if (b0 == 0xfe && b1 == 0xff)
+                return 1201; // UTF16BE
+            if (b0 == 0xff && b1 == 0xfe)
+                return 1200; // UTF16LE
+
+            int b2 = stream.ReadByte();
+            if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
+                return 65001; // UTF8
+            //
+            // There is no unicode preamble, so we
+            // return denoter for the machine default.
+            //
+            stream.Seek(0, SeekOrigin.Begin);
+            return 0;
+        }
+#endif // !BYTEMODE
+    }
+    #endregion Buffer classes
+
+    // ==============================================================
+    // ============      class CodePageHandling         =============
+    // ==============================================================
+
+    public static class CodePageHandling
+    {
+        public static int GetCodePage(string option)
+        {
+            string command = option.ToUpperInvariant();
+            if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
+                command = command.Substring(9);
+            try
+            {
+                if (command.Equals("RAW"))
+                    return -1;
+                else if (command.Equals("GUESS"))
+                    return -2;
+                else if (command.Equals("DEFAULT"))
+                    return 0;
+                else if (char.IsDigit(command[0]))
+                    return int.Parse(command, CultureInfo.InvariantCulture);
+                else
+                {
+                    Encoding enc = Encoding.GetEncoding(command);
+                    return enc.CodePage;
+                }
+            }
+            catch (FormatException)
+            {
+                Console.Error.WriteLine(
+                    "Invalid format \"{0}\", using machine default", option);
+            }
+            catch (ArgumentException)
+            {
+                Console.Error.WriteLine(
+                    "Unknown code page \"{0}\", using machine default", option);
+            }
+            return 0;
+        }
+    }
+#region guesser
+#if (!BYTEMODE)
+    // ==============================================================
+    // ============          Encoding Guesser           =============
+    // ==============================================================
+
+    /// <summary>
+    /// This class provides a simple finite state automaton that
+    /// scans the file looking for (1) valid UTF-8 byte patterns,
+    /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
+    /// The method then guesses whether it is UTF-8 or maybe some 
+    /// local machine default encoding.  This works well for the
+    /// various Latin encodings.
+    /// </summary>
+    internal class Guesser
+    {
+        ScanBuff buffer;
+
+        public int GuessCodePage() { return Scan(); }
+
+        const int maxAccept = 10;
+        const int initial = 0;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+        const int EndToken = 0;
+
+        #region user code
+        /* 
+         *  Reads the bytes of a file to determine if it is 
+         *  UTF-8 or a single-byte code page file.
+         */
+        public long utfX;
+        public long uppr;
+        #endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;
+
+        #region ScannerTables
+        static int[] startState = new int[] { 11, 0 };
+
+        #region CharacterMap
+        static sbyte[] map = new sbyte[256] {
+/*     '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*   '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
+        #endregion
+
+        static sbyte[][] nextState = new sbyte[][] {
+            new sbyte[] {0, 0, 0, 0, 0, 0},
+            new sbyte[] {-1, -1, 10, -1, -1, -1},
+            new sbyte[] {-1, -1, -1, -1, -1, -1},
+            new sbyte[] {-1, -1, 8, -1, -1, -1},
+            new sbyte[] {-1, -1, 5, -1, -1, -1},
+            new sbyte[] {-1, -1, 6, -1, -1, -1},
+            new sbyte[] {-1, -1, 7, -1, -1, -1},
+            null,
+            new sbyte[] {-1, -1, 9, -1, -1, -1},
+            null,
+            null,
+            new sbyte[] {-1, 1, 2, 3, 4, 2}
+        };
+
+
+        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
+        // Reason for suppression: cannot have self-reference in array initializer.
+        static Guesser()
+        {
+            nextState[7] = nextState[2];
+            nextState[9] = nextState[2];
+            nextState[10] = nextState[2];
+        }
+
+        int NextState()
+        {
+            if (code == ScanBuff.EndOfFile)
+                return eofNum;
+            else
+                return nextState[state][map[code]];
+        }
+        #endregion
+
+        public Guesser(System.IO.Stream file) { SetSource(file); }
+
+        public void SetSource(System.IO.Stream source)
+        {
+            this.buffer = new BuildBuffer(source);
+            code = buffer.Read();
+        }
+
+        int Scan()
+        {
+            for (; ; )
+            {
+                int next;
+                state = currentStart;
+                while ((next = NextState()) == goStart)
+                    code = buffer.Read();
+
+                state = next;
+                code = buffer.Read();
+
+                while ((next = NextState()) > eofNum)
+                {
+                    state = next;
+                    code = buffer.Read();
+                }
+                if (state <= maxAccept)
+                {
+                    #region ActionSwitch
+#pragma warning disable 162
+                    switch (state)
+                    {
+                        case eofNum:
+                            switch (currentStart)
+                            {
+                                case 11:
+                                    if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
+                                    else if (uppr * 10 > utfX) return 0;   /* default code page */
+                                    else return 65001;                     /* UTF-8 encoding */
+                                    break;
+                            }
+                            return EndToken;
+                        case 1: // Recognized '{Upper128}',	Shortest string "\xC0"
+                        case 2: // Recognized '{Upper128}',	Shortest string "\x80"
+                        case 3: // Recognized '{Upper128}',	Shortest string "\xE0"
+                        case 4: // Recognized '{Upper128}',	Shortest string "\xF0"
+                            uppr++;
+                            break;
+                        case 5: // Recognized '{Utf8pfx4}{Utf8cont}',	Shortest string "\xF0\x80"
+                            uppr += 2;
+                            break;
+                        case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}',	Shortest string "\xF0\x80\x80"
+                            uppr += 3;
+                            break;
+                        case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}',	Shortest string "\xF0\x80\x80\x80"
+                            utfX += 3;
+                            break;
+                        case 8: // Recognized '{Utf8pfx3}{Utf8cont}',	Shortest string "\xE0\x80"
+                            uppr += 2;
+                            break;
+                        case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}',	Shortest string "\xE0\x80\x80"
+                            utfX += 2;
+                            break;
+                        case 10: // Recognized '{Utf8pfx2}{Utf8cont}',	Shortest string "\xC0\x80"
+                            utfX++;
+                            break;
+                        default:
+                            break;
+                    }
+#pragma warning restore 162
+                    #endregion
+                }
+            }
+        }
+    } // end class Guesser
+    
+#endif // !BYTEMODE
+#endregion
+
+// End of code copied from embedded resource
+
+} // end namespace
diff --git a/Module7/SimpleLanguage2/SimpleLex.lex b/Module7/SimpleLanguage2/SimpleLex.lex
new file mode 100644
index 0000000..00dfa12
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleLex.lex
@@ -0,0 +1,90 @@
+%using SimpleParser;
+%using QUT.Gppg;
+%using System.Linq;
+
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+
+%%
+
+{INTNUM} { 
+  yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM; 
+}
+
+{REALNUM} { 
+  yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+}
+
+{ID}  { 
+  int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+}
+
+":=" { return (int)Tokens.ASSIGN; }
+";" { return (int)Tokens.SEMICOLON; }
+"-=" { return (int)Tokens.ASSIGNMINUS; }
+"+=" { return (int)Tokens.ASSIGNPLUS; }
+"*=" { return (int)Tokens.ASSIGNMULT; }
+"+" { return (int)Tokens.PLUS; }
+"-" { return (int)Tokens.MINUS; }
+"*" { return (int)Tokens.MULT; }
+"/" { return (int)Tokens.DIV; }
+"(" { return (int)Tokens.LPAREN; }
+")" { return (int)Tokens.RPAREN; }
+"," { return (int)Tokens.COLUMN; }
+
+[^ \r\n] {
+	LexError();
+}
+
+%{
+  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+%}
+
+%%
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("write",(int)Tokens.WRITE);
+    keywords.Add("var",(int)Tokens.VAR);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
diff --git a/Module7/SimpleLanguage2/SimpleYacc.cs b/Module7/SimpleLanguage2/SimpleYacc.cs
new file mode 100644
index 0000000..10d52e6
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleYacc.cs
@@ -0,0 +1,274 @@
+// This code was generated by the Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2010
+// (see accompanying GPPGcopyright.rtf)
+
+// GPPG version 1.3.6
+// Machine:  SSM
+// DateTime: 19.08.2014 13:38:37
+// UserName: ?????????
+// Input file <SimpleYacc.y>
+
+// options: no-lines gplex
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using QUT.Gppg;
+using System.IO;
+using ProgramTree;
+
+namespace SimpleParser
+{
+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,INUM=20,RNUM=21,ID=22};
+
+public struct ValueType
+{ 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+// Abstract base class for GPLEX scanners
+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; }
+}
+
+public class Parser: ShiftReduceParser<ValueType, LexLocation>
+{
+  // 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
+
+#pragma warning disable 649
+  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 string[] nonTerms = new string[] {
+      "progr", "expr", "ident", "T", "F", "statement", "assign", "block", "cycle", 
+      "write", "empty", "var", "varlist", "stlist", "$accept", "Anon@1", };
+
+  static Parser() {
+    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[]{22,18,3,4,5,31,11,35,12,40,4,-11,10,-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[]{4,6,10,7});
+    states[6] = new State(-23);
+    states[7] = new State(new int[]{22,18,3,4,5,31,11,35,12,40,4,-11,10,-11},new int[]{-6,8,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
+    states[8] = new State(-4);
+    states[9] = new State(-5);
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{22,18,20,19,17,20},new int[]{-2,12,-4,28,-5,27,-3,17});
+    states[12] = new State(new int[]{13,13,14,23,4,-13,10,-13});
+    states[13] = new State(new int[]{22,18,20,19,17,20},new int[]{-4,14,-5,27,-3,17});
+    states[14] = new State(new int[]{15,15,16,25,13,-14,14,-14,4,-14,10,-14,18,-14,22,-14,3,-14,5,-14,11,-14,12,-14});
+    states[15] = new State(new int[]{22,18,20,19,17,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[]{22,18,20,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(-22);
+    states[23] = new State(new int[]{22,18,20,19,17,20},new int[]{-4,24,-5,27,-3,17});
+    states[24] = new State(new int[]{15,15,16,25,13,-15,14,-15,4,-15,10,-15,18,-15,22,-15,3,-15,5,-15,11,-15,12,-15});
+    states[25] = new State(new int[]{22,18,20,19,17,20},new int[]{-5,26,-3,17});
+    states[26] = new State(-18);
+    states[27] = new State(-19);
+    states[28] = new State(new int[]{15,15,16,25,13,-16,14,-16,4,-16,10,-16,18,-16,22,-16,3,-16,5,-16,11,-16,12,-16});
+    states[29] = new State(-6);
+    states[30] = new State(-7);
+    states[31] = new State(new int[]{22,18,20,19,17,20},new int[]{-2,32,-4,28,-5,27,-3,17});
+    states[32] = new State(new int[]{13,13,14,23,22,18,3,4,5,31,11,35,12,40,4,-11,10,-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[]{17,36});
+    states[36] = new State(new int[]{22,18,20,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(-25);
+    states[39] = new State(-9);
+    states[40] = new State(-26,new int[]{-16,41});
+    states[41] = new State(new int[]{22,18},new int[]{-13,42,-3,45});
+    states[42] = new State(new int[]{19,43,4,-27,10,-27});
+    states[43] = new State(new int[]{22,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);
+
+    rules[1] = new Rule(-15, 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,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[]{22});
+    rules[13] = new Rule(-7, new int[]{-3,6,-2});
+    rules[14] = new Rule(-2, new int[]{-2,13,-4});
+    rules[15] = new Rule(-2, new int[]{-2,14,-4});
+    rules[16] = new Rule(-2, new int[]{-4});
+    rules[17] = new Rule(-4, new int[]{-4,15,-5});
+    rules[18] = new Rule(-4, new int[]{-4,16,-5});
+    rules[19] = new Rule(-4, new int[]{-5});
+    rules[20] = new Rule(-5, new int[]{-3});
+    rules[21] = new Rule(-5, new int[]{20});
+    rules[22] = new Rule(-5, new int[]{17,-2,18});
+    rules[23] = new Rule(-8, new int[]{3,-14,4});
+    rules[24] = new Rule(-9, new int[]{5,-2,-6});
+    rules[25] = new Rule(-10, new int[]{11,17,-2,18});
+    rules[26] = new Rule(-16, new int[]{});
+    rules[27] = new Rule(-12, new int[]{12,-16,-13});
+    rules[28] = new Rule(-13, new int[]{-3});
+    rules[29] = new Rule(-13, new int[]{-13,19,-3});
+  }
+
+  protected override void Initialize() {
+    this.InitSpecialTokens((int)Tokens.error, (int)Tokens.EOF);
+    this.InitStates(states);
+    this.InitRules(rules);
+    this.InitNonTerminals(nonTerms);
+  }
+
+  protected override void DoAction(int action)
+  {
+    switch (action)
+    {
+      case 2: // progr -> block
+{ root = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 3: // stlist -> statement
+{ 
+				CurrentSemanticValue.blVal = new BlockNode(ValueStack[ValueStack.Depth-1].stVal); 
+			}
+        break;
+      case 4: // stlist -> stlist, SEMICOLON, statement
+{ 
+				ValueStack[ValueStack.Depth-3].blVal.Add(ValueStack[ValueStack.Depth-1].stVal); 
+				CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-3].blVal; 
+			}
+        break;
+      case 5: // statement -> assign
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 6: // statement -> block
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 7: // statement -> cycle
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 8: // statement -> write
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 9: // statement -> var
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 10: // statement -> empty
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 11: // empty -> /* empty */
+{ CurrentSemanticValue.stVal = new EmptyNode(); }
+        break;
+      case 12: // 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+" не описана");
+			CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); 
+		}
+        break;
+      case 13: // 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
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'+'); }
+        break;
+      case 15: // expr -> expr, MINUS, T
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'-'); }
+        break;
+      case 16: // expr -> T
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
+        break;
+      case 17: // 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
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'/'); }
+        break;
+      case 19: // T -> F
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
+        break;
+      case 20: // F -> ident
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
+        break;
+      case 21: // F -> INUM
+{ CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
+        break;
+      case 22: // F -> LPAREN, expr, RPAREN
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; }
+        break;
+      case 23: // block -> BEGIN, stlist, END
+{ CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
+        break;
+      case 24: // 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
+{ CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); }
+        break;
+      case 26: // Anon@1 -> /* empty */
+{ InDefSect = true; }
+        break;
+      case 27: // 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
+{ 
+			CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); 
+		}
+        break;
+      case 29: // 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;
+    }
+  }
+
+  protected override string TerminalToString(int 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/Module7/SimpleLanguage2/SimpleYacc.lst b/Module7/SimpleLanguage2/SimpleYacc.lst
new file mode 100644
index 0000000..2de6038
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleYacc.lst
@@ -0,0 +1,139 @@
+
+// ==========================================================================
+//  GPPG error listing for yacc source file <SimpleYacc.y>
+// ==========================================================================
+//  Version:  1.3.6
+//  Machine:  SSM
+//  DateTime: 19.08.2014 13:28:35
+//  UserName: Станислав
+// ==========================================================================
+
+
+%{
+// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
+    public BlockNode root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+	private bool InDefSect = false;
+%}
+
+%output = SimpleYacc.cs
+
+%union { 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+
+%using System.IO;
+%using ProgramTree;
+
+%namespace SimpleParser
+
+%start progr
+
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%token <iVal> INUM 
+%token <dVal> RNUM 
+%token <sVal> ID
+
+%type <nVal> varlist 
+%type <eVal> expr ident T F 
+%type <stVal> statement assign block cycle write empty var  
+%type <blVal> stlist block
+
+%%
+// 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}
+// ------------------------------------------------------------------
+
+progr   : block { root = $1; }
+		;
+
+stlist	: statement 
+			{ 
+				$$ = new BlockNode($1); 
+			}
+		| stlist SEMICOLON statement 
+			{ 
+				$1.Add($3); 
+				$$ = $1; 
+			}
+		;
+
+statement: assign { $$ = $1; }
+		| block   { $$ = $1; }
+		| cycle   { $$ = $1; }
+		| write   { $$ = $1; }
+		| var     { $$ = $1; }
+		| empty   { $$ = $1; }
+		;
+
+empty	: { $$ = new EmptyNode(); }
+		;
+	
+ident 	: ID 
+		{
+			if (!InDefSect)
+				if (!SymbolTable.vars.ContainsKey($1))
+					throw new Exception("("+@1.StartLine+","+@1.StartColumn+"): Ïåðåìåííàÿ "+$1+" íå îïèñàíà");
+			$$ = new IdNode($1); 
+		}	
+	;
+	
+assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
+		;
+
+expr	: expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
+		| expr MINUS T { $$ = new BinOpNode($1,$3,'-'); }
+		| T { $$ = $1; }
+		;
+		
+T 		: T MULT F { $$ = new BinOpNode($1,$3,'*'); }
+		| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
+		| F { $$ = $1; }
+		;
+		
+F 		: ident  { $$ = $1 as IdNode; }
+		| INUM { $$ = new IntNumNode($1); }
+		| LPAREN expr RPAREN { $$ = $2; }
+		;
+
+block	: BEGIN stlist END { $$ = $2; }
+		;
+
+cycle	: CYCLE expr st { $$ = new CycleNode($2,$3); }
+		;
+		
+write	: WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); }
+		;
+		
+var		: VAR { InDefSect = true; } varlist 
+		{ 
+			foreach (var v in ($3 as VarDefNode).vars)
+				SymbolTable.NewVarDef(v.Name, type.tint);
+			InDefSect = false;	
+		}
+		;
+
+varlist	: ident 
+		{ 
+			$$ = new VarDefNode($1 as IdNode); 
+		}
+		| varlist COLUMN ident 
+		{ 
+			($1 as VarDefNode).Add($3 as IdNode);
+			$$ = $1;
+		}
+		;
+	
+%%
+
+// ==========================================================================
+
diff --git a/Module7/SimpleLanguage2/SimpleYacc.y b/Module7/SimpleLanguage2/SimpleYacc.y
new file mode 100644
index 0000000..20087e0
--- /dev/null
+++ b/Module7/SimpleLanguage2/SimpleYacc.y
@@ -0,0 +1,119 @@
+%{
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+	private bool InDefSect = false;
+%}
+
+%output = SimpleYacc.cs
+
+%union { 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+
+%using System.IO;
+%using ProgramTree;
+
+%namespace SimpleParser
+
+%start progr
+
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%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 <blVal> stlist block
+
+%%
+
+progr   : block { root = $1; }
+		;
+
+stlist	: statement 
+			{ 
+				$$ = new BlockNode($1); 
+			}
+		| stlist SEMICOLON statement 
+			{ 
+				$1.Add($3); 
+				$$ = $1; 
+			}
+		;
+
+statement: assign { $$ = $1; }
+		| block   { $$ = $1; }
+		| cycle   { $$ = $1; }
+		| write   { $$ = $1; }
+		| var     { $$ = $1; }
+		| empty   { $$ = $1; }
+		;
+
+empty	: { $$ = new EmptyNode(); }
+		;
+	
+ident 	: ID 
+		{
+			if (!InDefSect)
+				if (!SymbolTable.vars.ContainsKey($1))
+					throw new Exception("("+@1.StartLine+","+@1.StartColumn+"): Переменная "+$1+" не описана");
+			$$ = new IdNode($1); 
+		}	
+	;
+	
+assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
+		;
+
+expr	: expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
+		| expr MINUS T { $$ = new BinOpNode($1,$3,'-'); }
+		| T { $$ = $1; }
+		;
+		
+T 		: T MULT F { $$ = new BinOpNode($1,$3,'*'); }
+		| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
+		| F { $$ = $1; }
+		;
+		
+F 		: ident  { $$ = $1 as IdNode; }
+		| INUM { $$ = new IntNumNode($1); }
+		| LPAREN expr RPAREN { $$ = $2; }
+		;
+
+block	: BEGIN stlist END { $$ = $2; }
+		;
+
+cycle	: CYCLE expr statement { $$ = new CycleNode($2,$3); }
+		;
+		
+write	: WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); }
+		;
+		
+var		: VAR { InDefSect = true; } varlist 
+		{ 
+			foreach (var v in ($3 as VarDefNode).vars)
+				SymbolTable.NewVarDef(v.Name, type.tint);
+			InDefSect = false;	
+		}
+		;
+
+varlist	: ident 
+		{ 
+			$$ = new VarDefNode($1 as IdNode); 
+		}
+		| varlist COLUMN ident 
+		{ 
+			($1 as VarDefNode).Add($3 as IdNode);
+			$$ = $1;
+		}
+		;
+	
+%%
+
diff --git a/Module7/SimpleLanguage2/Visitors/AssignCountVisitor.cs b/Module7/SimpleLanguage2/Visitors/AssignCountVisitor.cs
new file mode 100644
index 0000000..43d8554
--- /dev/null
+++ b/Module7/SimpleLanguage2/Visitors/AssignCountVisitor.cs
@@ -0,0 +1,23 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    class AssignCountVisitor : AutoVisitor
+    {
+        public int Count = 0;
+        public override void VisitAssignNode(AssignNode a)
+        {
+            Count += 1;
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+        }
+        public override void VisitVarDefNode(VarDefNode w)
+        { 
+        }
+    }
+}
diff --git a/Module7/SimpleLanguage2/Visitors/AutoVisitor.cs b/Module7/SimpleLanguage2/Visitors/AutoVisitor.cs
new file mode 100644
index 0000000..7c92bab
--- /dev/null
+++ b/Module7/SimpleLanguage2/Visitors/AutoVisitor.cs
@@ -0,0 +1,45 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    // базовая логика обхода без действий
+    // Если нужны действия или другая логика обхода, то соответствующие методы надо переопределять
+    // При переопределении методов для задания действий необходимо не забывать обходить подузлы
+    class AutoVisitor: Visitor
+    {
+        public override void VisitBinOpNode(BinOpNode binop) 
+        {
+            binop.Left.Visit(this);
+            binop.Right.Visit(this);
+        }
+        public override void VisitAssignNode(AssignNode a) 
+        {
+            // для каких-то визиторов порядок может быть обратный - вначале обойти выражение, потом - идентификатор
+            a.Id.Visit(this);
+            a.Expr.Visit(this);
+        }
+        public override void VisitCycleNode(CycleNode c) 
+        {
+            c.Expr.Visit(this);
+            c.Stat.Visit(this);
+        }
+        public override void VisitBlockNode(BlockNode bl) 
+        {
+            foreach (var st in bl.StList)
+                st.Visit(this);
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+            w.Expr.Visit(this);
+        }
+        public override void VisitVarDefNode(VarDefNode w) 
+        {
+            foreach (var v in w.vars)
+                v.Visit(this);
+        }
+    }
+}
diff --git a/Module7/SimpleLanguage2/Visitors/PrettyPrintVisitor.cs b/Module7/SimpleLanguage2/Visitors/PrettyPrintVisitor.cs
new file mode 100644
index 0000000..87892b1
--- /dev/null
+++ b/Module7/SimpleLanguage2/Visitors/PrettyPrintVisitor.cs
@@ -0,0 +1,88 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    class PrettyPrintVisitor: Visitor
+    {
+        public string Text = "";
+        private int Indent = 0;
+
+        private string IndentStr()
+        {
+            return new string(' ', Indent);
+        }
+        private void IndentPlus()
+        {
+            Indent += 2;
+        }
+        private void IndentMinus()
+        {
+            Indent -= 2;
+        }
+        public override void VisitIdNode(IdNode id) 
+        {
+            Text += id.Name;
+        }
+        public override void VisitIntNumNode(IntNumNode num) 
+        {
+            Text += num.Num.ToString();
+        }
+        public override void VisitBinOpNode(BinOpNode binop) 
+        {
+            Text += "(";
+            binop.Left.Visit(this);
+            Text += " " + binop.Op + " ";
+            binop.Right.Visit(this);
+            Text += ")";
+        }
+        public override void VisitAssignNode(AssignNode a) 
+        {
+            Text += IndentStr();
+            a.Id.Visit(this);
+            Text += " := ";
+            a.Expr.Visit(this);
+        }
+        public override void VisitCycleNode(CycleNode c) 
+        {
+            Text += IndentStr() + "cycle ";
+            c.Expr.Visit(this);
+            Text += Environment.NewLine;
+            c.Stat.Visit(this);
+        }
+        public override void VisitBlockNode(BlockNode bl) 
+        {
+            Text += IndentStr() + "begin" + Environment.NewLine;
+            IndentPlus();
+
+            var Count = bl.StList.Count;
+
+            if (Count>0)
+                bl.StList[0].Visit(this);
+            for (var i = 1; i < Count; i++)
+            {
+                Text += ';';
+                if (!(bl.StList[i] is EmptyNode))
+                    Text += Environment.NewLine;
+                bl.StList[i].Visit(this);
+            }
+            IndentMinus();
+            Text += Environment.NewLine + IndentStr() + "end";
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+            Text += IndentStr() + "write(";
+            w.Expr.Visit(this);
+            Text += ")";
+        }
+        public override void VisitVarDefNode(VarDefNode w) 
+        {
+            Text += IndentStr() + "var " + w.vars[0].Name;
+            for (int i = 1; i < w.vars.Count; i++)
+                Text += ',' + w.vars[i].Name;
+        }
+    }
+}
diff --git a/Module7/SimpleLanguage2/Visitors/Visitor.cs b/Module7/SimpleLanguage2/Visitors/Visitor.cs
new file mode 100644
index 0000000..b9dcae0
--- /dev/null
+++ b/Module7/SimpleLanguage2/Visitors/Visitor.cs
@@ -0,0 +1,21 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    public abstract class Visitor
+    {
+        public virtual void VisitIdNode(IdNode id) { }
+        public virtual void VisitIntNumNode(IntNumNode num) { }
+        public virtual void VisitBinOpNode(BinOpNode binop) { }
+        public virtual void VisitAssignNode(AssignNode a) { }
+        public virtual void VisitCycleNode(CycleNode c) { }
+        public virtual void VisitBlockNode(BlockNode bl) { }
+        public virtual void VisitWriteNode(WriteNode w) { }
+        public virtual void VisitVarDefNode(VarDefNode w) { }
+        public virtual void VisitEmptyNode(EmptyNode w) { }
+    }
+}
diff --git a/Module7/SimpleLanguage2/a.txt b/Module7/SimpleLanguage2/a.txt
new file mode 100644
index 0000000..14eeab4
--- /dev/null
+++ b/Module7/SimpleLanguage2/a.txt
@@ -0,0 +1,11 @@
+begin
+  var a,b,d;
+  b := 2;
+  a := 3;
+  a := a * 4 + b;;;
+  cycle 3
+  begin
+    a := a + 1;
+    write(a)
+  end
+end
diff --git a/Module7/SimpleLanguage2/generateParserScanner.bat b/Module7/SimpleLanguage2/generateParserScanner.bat
new file mode 100644
index 0000000..7ca5476
--- /dev/null
+++ b/Module7/SimpleLanguage2/generateParserScanner.bat
@@ -0,0 +1,3 @@
+cls
+gplex.exe /unicode SimpleLex.lex
+gppg.exe /no-lines /gplex SimpleYacc.y
diff --git a/Module8/SimpleLanguage3/Main.cs b/Module8/SimpleLanguage3/Main.cs
new file mode 100644
index 0000000..4c8a1f5
--- /dev/null
+++ b/Module8/SimpleLanguage3/Main.cs
@@ -0,0 +1,65 @@
+п»їusing System;
+using System.IO;
+using System.Text;
+using System.Reflection;
+using System.Collections.Generic;
+using SimpleScanner;
+using SimpleParser;
+using SimpleLang.Visitors;
+
+namespace SimpleCompiler
+{
+    public class SimpleCompilerMain
+    {
+        public static void Main()
+        {
+            string FileName = @"..\..\a.txt";
+            try
+            {
+                string Text = File.ReadAllText(FileName);
+
+                Scanner scanner = new Scanner();
+                scanner.SetSource(Text, 0);
+
+                Parser parser = new Parser(scanner);
+
+                var b = parser.Parse();
+                if (!b)
+                    Console.WriteLine("Ошибка");
+                else
+                {
+                    Console.WriteLine("Синтаксическое дерево построено");
+
+                    var avis = new AssignCountVisitor();
+                    parser.root.Visit(avis);
+                    Console.WriteLine("Количество присваиваний = {0}", avis.Count);
+                    Console.WriteLine("-------------------------------");
+
+                    var pp = new PrettyPrintVisitor();
+                    parser.root.Visit(pp);
+                    Console.WriteLine(pp.Text);
+                    Console.WriteLine("-------------------------------");
+
+                    var code = new GenCodeVisitor();
+                    parser.root.Visit(code);
+                    code.EndProgram();
+                    //code.PrintCommands();
+                    Console.WriteLine("-------------------------------");
+
+                    code.RunProgram();
+                }
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("Файл {0} не найден", FileName);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("{0}", e);
+            }
+
+            Console.ReadLine();
+        }
+
+    }
+}
diff --git a/Module8/SimpleLanguage3/ParserHelper.cs b/Module8/SimpleLanguage3/ParserHelper.cs
new file mode 100644
index 0000000..a085ecd
--- /dev/null
+++ b/Module8/SimpleLanguage3/ParserHelper.cs
@@ -0,0 +1,33 @@
+п»їusing System.Collections.Generic;
+using System;
+
+namespace SimpleParser
+{
+
+    public enum type { tint, tdouble };
+
+    public static class SymbolTable // Таблица символов
+    {
+        public static Dictionary<string, type> vars = new Dictionary<string, type>(); // таблица символов
+        public static void NewVarDef(string name, type t)
+        {
+            if (vars.ContainsKey(name))
+                throw new Exception("Переменная " + name + " уже определена");
+            else vars.Add(name, t);
+        }
+    }
+
+    public class LexException : Exception
+    {
+        public LexException(string msg) : base(msg) { }
+    }
+    
+    public class SyntaxException : Exception
+    {
+        public SyntaxException(string msg) : base(msg) { }
+    }
+
+    public static class ParserHelper
+    {
+    }
+}
\ No newline at end of file
diff --git a/Module8/SimpleLanguage3/ProgramTree.cs b/Module8/SimpleLanguage3/ProgramTree.cs
new file mode 100644
index 0000000..e48dcb5
--- /dev/null
+++ b/Module8/SimpleLanguage3/ProgramTree.cs
@@ -0,0 +1,145 @@
+п»їusing System.Collections.Generic;
+using SimpleLang.Visitors;
+
+namespace ProgramTree
+{
+    public enum AssignType { Assign, AssignPlus, AssignMinus, AssignMult, AssignDivide };
+
+    public abstract class Node // базовый класс для всех узлов    
+    {
+        public abstract void Visit(Visitor v);
+    }
+
+    public abstract class ExprNode : Node // базовый класс для всех выражений
+    {
+    }
+
+    public class IdNode : ExprNode
+    {
+        public string Name { get; set; }
+        public IdNode(string name) { Name = name; }
+        public override void Visit(Visitor v)
+        {
+            v.VisitIdNode(this);
+        }
+    }
+
+    public class IntNumNode : ExprNode
+    {
+        public int Num { get; set; }
+        public IntNumNode(int num) { Num = num; }
+        public override void Visit(Visitor v)
+        {
+            v.VisitIntNumNode(this);
+        }
+    }
+
+    public class BinOpNode : ExprNode
+    {
+        public ExprNode Left { get; set; }
+        public ExprNode Right { get; set; }
+        public char Op { get; set; }
+        public BinOpNode(ExprNode Left, ExprNode Right, char op) 
+        {
+            this.Left = Left;
+            this.Right = Right;
+            this.Op = op;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitBinOpNode(this);
+        }
+    }
+
+    public abstract class StatementNode : Node // базовый класс для всех операторов
+    {
+    }
+
+    public class AssignNode : StatementNode
+    {
+        public IdNode Id { get; set; }
+        public ExprNode Expr { get; set; }
+        public AssignType AssOp { get; set; }
+        public AssignNode(IdNode id, ExprNode expr, AssignType assop = AssignType.Assign)
+        {
+            Id = id;
+            Expr = expr;
+            AssOp = assop;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitAssignNode(this);
+        }
+    }
+
+    public class CycleNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public StatementNode Stat { get; set; }
+        public CycleNode(ExprNode expr, StatementNode stat)
+        {
+            Expr = expr;
+            Stat = stat;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitCycleNode(this);
+        }
+    }
+
+    public class BlockNode : StatementNode
+    {
+        public List<StatementNode> StList = new List<StatementNode>();
+        public BlockNode(StatementNode stat)
+        {
+            Add(stat);
+        }
+        public void Add(StatementNode stat)
+        {
+            StList.Add(stat);
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitBlockNode(this);
+        }
+    }
+
+    public class WriteNode : StatementNode
+    {
+        public ExprNode Expr { get; set; }
+        public WriteNode(ExprNode Expr)
+        {
+            this.Expr = Expr;
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitWriteNode(this);
+        }
+    }
+
+    public class EmptyNode : StatementNode
+    {
+        public override void Visit(Visitor v)
+        {
+            v.VisitEmptyNode(this);
+        }
+    }
+
+    public class VarDefNode : StatementNode
+    {
+        public List<IdNode> vars = new List<IdNode>();
+        public VarDefNode(IdNode id)
+        {
+            Add(id);
+        }
+
+        public void Add(IdNode id)
+        {
+            vars.Add(id);
+        }
+        public override void Visit(Visitor v)
+        {
+            v.VisitVarDefNode(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Module8/SimpleLanguage3/Properties/AssemblyInfo.cs b/Module8/SimpleLanguage3/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..896cc99
--- /dev/null
+++ b/Module8/SimpleLanguage3/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+п»їusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется с помощью 
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("SimpleLang")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SimpleLang")]
+[assembly: AssemblyCopyright("Copyright В©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми 
+// для COM-компонентов.  Если требуется обратиться к типу в этой сборке через 
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("06dba63f-4805-4cd3-8a93-b329b2c7e37b")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+//      Основной номер версии
+//      Дополнительный номер версии 
+//      Номер построения
+//      Редакция
+//
+// Можно задать все значения или принять номер построения и номер редакции по умолчанию, 
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Module8/SimpleLanguage3/ShiftReduceParserCode.cs b/Module8/SimpleLanguage3/ShiftReduceParserCode.cs
new file mode 100644
index 0000000..c110ba1
--- /dev/null
+++ b/Module8/SimpleLanguage3/ShiftReduceParserCode.cs
@@ -0,0 +1,944 @@
+// Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2009
+// (see accompanying GPPGcopyright.rtf)
+#define EXPORT_GPPG
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+namespace QUT.Gppg
+{
+    /// <summary>
+    /// Abstract class for GPPG shift-reduce parsers.
+    /// Parsers generated by GPPG derive from this base
+    /// class, overriding the abstract Initialize() and
+    /// DoAction() methods.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type</typeparam>
+    /// <typeparam name="TSpan">Location type</typeparam>
+#if EXPORT_GPPG
+    public abstract class ShiftReduceParser<TValue, TSpan>
+#else
+    internal abstract class ShiftReduceParser<TValue, TSpan>
+#endif
+ where TSpan : IMerge<TSpan>, new()
+    {
+        public AbstractScanner<TValue, TSpan> scanner;
+        /// <summary>
+        /// The abstract scanner for this parser.
+        /// </summary>
+        protected AbstractScanner<TValue, TSpan> Scanner {
+            get { return scanner; }
+            set { scanner = value; }
+        }
+
+        /// <summary>
+        /// Constructor for base class
+        /// </summary>
+        /// <param name="scanner">Scanner instance for this parser</param>
+        protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
+        {
+            this.scanner = scanner;
+        }
+
+        // ==============================================================
+        //                    TECHNICAL EXPLANATION.
+        //   Why the next two fields are not exposed via properties.
+        // ==============================================================
+        // These fields are of the generic parameter types, and are
+        // frequently instantiated as struct types in derived classes.
+        // Semantic actions are defined in the derived classes and refer
+        // to instance fields of these structs.  Is such cases the code
+        // "get_CurrentSemanticValue().myField = blah;" will fail since
+        // the getter pushes the value of the field, not the reference.
+        // So, in the presence of properties, gppg would need to encode
+        // such field accesses as ... 
+        //  "tmp = get_CurrentSemanticValue(); // Fetch value
+        //   tmp.myField = blah;               // update
+        //   set_CurrentSemanticValue(tmp); "  // Write update back.
+        // There is no issue if TValue is restricted to be a ref type.
+        // The same explanation applies to scanner.yylval.
+        // ==============================================================
+        /// <summary>
+        /// The current value of the "$$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TValue CurrentSemanticValue;
+
+        /// <summary>
+        /// The current value of the "@$" symbolic variable in the parser
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        protected TSpan CurrentLocationSpan;
+
+        private TSpan LastSpan;
+        private int NextToken;
+        private State FsaState;
+        private bool recovering;
+        private int tokensSinceLastError;
+
+        private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
+        private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
+        private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
+
+        /// <summary>
+        /// The stack of semantic value (YYSTYPE) values.
+        /// </summary>
+        protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
+
+        /// <summary>
+        /// The stack of location value (YYLTYPE) varlues.
+        /// </summary>
+        protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
+
+        private int errorToken;
+        private int endOfFileToken;
+        private string[] nonTerminals;
+        private State[] states;
+        private Rule[] rules;
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the rule list into this base class.
+        /// </summary>
+        /// <param name="rules">The array of Rule objects</param>
+        protected void InitRules(Rule[] rules) { this.rules = rules; }
+
+      /// <summary>
+      /// Initialization method to allow derived classes to
+      /// insert the states table into this base class.
+      /// </summary>
+      /// <param name="states">The pre-initialized states table</param>
+        protected void InitStates(State[] states) { this.states = states; }
+
+      /// <summary>
+      /// OBSOLETE FOR VERSION 1.4.0
+      /// </summary>
+      /// <param name="size"></param>
+        protected void InitStateTable(int size) { states = new State[size]; }
+
+        /// <summary>
+        /// Initialization method to allow derived classes
+        /// to insert the special value for the error and EOF tokens.
+        /// </summary>
+        /// <param name="err">The error state ordinal</param>
+        /// <param name="end">The EOF stat ordinal</param>
+        protected void InitSpecialTokens(int err, int end)
+        {
+            errorToken = err;
+            endOfFileToken = end;
+        }
+
+        /// <summary>
+        /// Initialization method to allow derived classes to
+        /// insert the non-terminal symbol names into this base class.
+        /// </summary>
+        /// <param name="names">Non-terminal symbol names</param>
+        protected void InitNonTerminals(string[] names) { nonTerminals = names; }
+
+        #region YYAbort, YYAccept etcetera.
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AcceptException : Exception
+        {
+            internal AcceptException() { }
+            protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class AbortException : Exception
+        {
+            internal AbortException() { }
+            protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+        [Serializable]
+        [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+        // Reason for FxCop message suppression -
+        // This exception cannot escape from the local context
+        private class ErrorException : Exception
+        {
+            internal ErrorException() { }
+            protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
+        }
+
+        // The following methods are only called from within
+        // a semantic action. The thrown exceptions can never
+        // propagate outside the ShiftReduceParser class in 
+        // which they are nested.
+
+        /// <summary>
+        /// Force parser to terminate, returning "true"
+        /// </summary>
+        protected static void YYAccept() { throw new AcceptException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning "false"
+        /// </summary>
+        protected static void YYAbort() { throw new AbortException(); }
+
+        /// <summary>
+        /// Force parser to terminate, returning
+        /// "false" if error recovery fails.
+        /// </summary>
+        protected static void YYError() { throw new ErrorException(); }
+
+        /// <summary>
+        /// Check if parser in error recovery state.
+        /// </summary>
+        protected bool YYRecovering { get { return recovering; } }
+        #endregion
+
+        /// <summary>
+        /// Abstract base method. ShiftReduceParser calls this
+        /// to initialize the base class data structures.  Concrete
+        /// parser classes must override this method.
+        /// </summary>
+        protected abstract void Initialize();
+
+        /// <summary>
+        /// Main entry point of the Shift-Reduce Parser.
+        /// </summary>
+        /// <returns>True if parse succeeds, else false for
+        /// unrecoverable errors</returns>
+        public bool Parse()
+        {
+            Initialize();	// allow derived classes to instantiate rules, states and nonTerminals
+
+            NextToken = 0;
+            FsaState = states[0];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+
+            while (true)
+            {
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+                int action = FsaState.defaultAction;
+
+                if (FsaState.ParserTable != null)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif
+                        // We save the last token span, so that the location span
+                        // of production right hand sides that begin or end with a
+                        // nullable production will be correct.
+                        LastSpan = scanner.yylloc;
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+                }
+
+                if (action > 0)         // shift
+                {
+                    Shift(action);
+                }
+                else if (action < 0)   // reduce
+                {
+                    try
+                    {
+                        Reduce(-action);
+                        if (action == -1)	// accept
+                            return true;
+                    }
+                    catch (Exception x)
+                    {
+                        if (x is AbortException)
+                            return false;
+                        else if (x is AcceptException)
+                            return true;
+                        else if (x is ErrorException && !ErrorRecovery())
+                            return false;
+                        else
+                            throw;  // Rethrow x, preserving information.
+
+                    }
+                }
+                else if (action == 0)   // error
+                    if (!ErrorRecovery())
+                        return false;
+            }
+        }
+
+        private void Shift(int stateIndex)
+        {
+#if TRACE_ACTIONS
+				Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
+#endif
+            FsaState = states[stateIndex];
+
+            valueStack.Push(scanner.yylval);
+            StateStack.Push(FsaState);
+            LocationStack.Push(scanner.yylloc);
+
+            if (recovering)
+            {
+                if (NextToken != errorToken)
+                    tokensSinceLastError++;
+
+                if (tokensSinceLastError > 5)
+                    recovering = false;
+            }
+
+            if (NextToken != endOfFileToken)
+                NextToken = 0;
+        }
+
+        private void Reduce(int ruleNumber)
+        {
+#if TRACE_ACTIONS
+				DisplayRule(ruleNumber);
+#endif
+            Rule rule = rules[ruleNumber];
+            //
+            //  Default actions for unit productions.
+            //
+            if (rule.RightHandSide.Length == 1)
+            {
+                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
+                CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
+            }
+            else
+            {
+                if (rule.RightHandSide.Length == 0)
+                {
+                    // Create a new blank value.
+                    // Explicit semantic action may mutate this value
+                    CurrentSemanticValue = default(TValue);
+                    // The location span for an empty production will start with the
+                    // beginning of the next lexeme, and end with the finish of the
+                    // previous lexeme.  This gives the correct behaviour when this
+                    // nonsense value is used in later Merge operations.
+                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
+                        scanner.yylloc.Merge(LastSpan) :
+                        default(TSpan));
+                }
+                else
+                {
+                    // Default action: $$ = $1;
+                    CurrentSemanticValue = valueStack.TopElement();
+                    //  Default action "@$ = @1.Merge(@N)" for location info.
+                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
+                    TSpan atN = LocationStack[LocationStack.Depth - 1];
+                    CurrentLocationSpan = 
+                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
+                }
+            }
+
+            DoAction(ruleNumber);
+
+            for (int i = 0; i < rule.RightHandSide.Length; i++)
+            {
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+            }
+
+#if TRACE_ACTIONS
+				DisplayStack();
+#endif
+            FsaState = StateStack.TopElement();
+
+            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
+                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
+
+            StateStack.Push(FsaState);
+            valueStack.Push(CurrentSemanticValue);
+            LocationStack.Push(CurrentLocationSpan);
+        }
+
+        /// <summary>
+        /// Execute the selected action from array.
+        /// Must be overriden in derived classes.
+        /// </summary>
+        /// <param name="actionNumber">Index of the action to perform</param>
+        protected abstract void DoAction(int actionNumber);
+
+        private bool ErrorRecovery()
+        {
+            bool discard;
+
+            if (!recovering) // if not recovering from previous error
+                ReportError();
+
+            if (!FindErrorRecoveryState())
+                return false;
+            //
+            //  The interim fix for the "looping in error recovery"
+            //  artifact involved moving the setting of the recovering 
+            //  bool until after invalid tokens have been discarded.
+            //
+            ShiftErrorToken();
+            discard = DiscardInvalidTokens();
+            recovering = true;
+            tokensSinceLastError = 0;
+            return discard;
+        }
+
+        private void ReportError1()
+        {
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
+
+            if (FsaState.ParserTable.Count < 7)
+            {
+                bool first = true;
+                foreach (int terminal in FsaState.ParserTable.Keys)
+                {
+                    if (first)
+                        errorMsg.Append(", expecting ");
+                    else
+                        errorMsg.Append(", or ");
+
+                    errorMsg.Append(TerminalToString(terminal));
+                    first = false;
+                }
+            }
+            scanner.yyerror(errorMsg.ToString());
+        }
+
+        private void ReportError()
+        {
+            object[] args = new object[FsaState.ParserTable.Keys.Count+1];
+            args[0] = TerminalToString(NextToken);
+            int i=1;
+            foreach (int terminal in FsaState.ParserTable.Keys)
+            {
+                args[i] = TerminalToString(terminal);
+                i++;
+            }
+            scanner.yyerror("",args);
+        }
+
+        private void ShiftErrorToken()
+        {
+            int old_next = NextToken;
+            NextToken = errorToken;
+
+            Shift(FsaState.ParserTable[NextToken]);
+
+#if TRACE_ACTIONS
+				Console.Error.WriteLine("Entering state {0} ", FsaState.number);
+#endif
+            NextToken = old_next;
+        }
+
+        private bool FindErrorRecoveryState()
+        {
+            while (true)    // pop states until one found that accepts error token
+            {
+                if (FsaState.ParserTable != null &&
+                    FsaState.ParserTable.ContainsKey(errorToken) &&
+                    FsaState.ParserTable[errorToken] > 0) // shift
+                    return true;
+
+#if TRACE_ACTIONS
+					Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
+#endif
+                StateStack.Pop();
+                valueStack.Pop();
+                LocationStack.Pop();
+
+#if TRACE_ACTIONS
+					DisplayStack();
+#endif
+                if (StateStack.IsEmpty())
+                {
+#if TRACE_ACTIONS
+                        Console.Error.Write("Aborting: didn't find a state that accepts error token");
+#endif
+                    return false;
+                }
+                else
+                    FsaState = StateStack.TopElement();
+            }
+        }
+
+        private bool DiscardInvalidTokens()
+        {
+
+            int action = FsaState.defaultAction;
+
+            if (FsaState.ParserTable != null)
+            {
+                // Discard tokens until find one that works ...
+                while (true)
+                {
+                    if (NextToken == 0)
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.Write("Reading a token: ");
+#endif                       
+                        NextToken = scanner.yylex();
+                    }
+
+#if TRACE_ACTIONS
+                        Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
+#endif
+                    if (NextToken == endOfFileToken)
+                        return false;
+
+                    if (FsaState.ParserTable.ContainsKey(NextToken))
+                        action = FsaState.ParserTable[NextToken];
+
+                    if (action != 0)
+                        return true;
+                    else
+                    {
+#if TRACE_ACTIONS
+                            Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
+#endif
+                        NextToken = 0;
+                    }
+                }
+            }
+            else if (recovering && tokensSinceLastError == 0)
+            {
+                // 
+                //  Boolean recovering is not set until after the first
+                //  error token has been shifted.  Thus if we get back 
+                //  here with recovering set and no tokens read we are
+                //  looping on the same error recovery action.  This 
+                //  happens if current_state.ParserTable is null because
+                //  the state has an LR(0) reduction, but not all
+                //  lookahead tokens are valid.  This only occurs for
+                //  error productions that *end* on "error".
+                //
+                //  This action discards tokens one at a time until
+                //  the looping stops.  Another attack would be to always
+                //  use the LALR(1) table if a production ends on "error"
+                //
+#if TRACE_ACTIONS
+                    Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
+#endif
+                if (NextToken == endOfFileToken)
+                    return false;
+                NextToken = 0;
+                return true;
+            }
+            else
+                return true;
+
+        }
+
+        /// <summary>
+        /// Traditional YACC method.  Discards the next input token.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyclearin() { NextToken = 0; }
+
+        /// <summary>
+        /// Tradional YACC method. Clear the "recovering" flag.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        protected void yyerrok()
+        {
+            recovering = false;
+        }
+
+        /// <summary>
+        /// OBSOLETE FOR VERSION 1.4.0
+        /// Method used by derived types to insert new
+        /// state instances in the "states" array.
+        /// </summary>
+        /// <param name="stateNumber">index of the state</param>
+        /// <param name="state">data for the state</param>
+        protected void AddState(int stateNumber, State state)
+        {
+            states[stateNumber] = state;
+            state.number = stateNumber;
+        }
+
+        private void DisplayStack()
+        {
+            Console.Error.Write("State now");
+            for (int i = 0; i < StateStack.Depth; i++)
+                Console.Error.Write(" {0}", StateStack[i].number);
+            Console.Error.WriteLine();
+        }
+
+        private void DisplayRule(int ruleNumber)
+        {
+            Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
+            DisplayProduction(rules[ruleNumber]);
+        }
+
+        private void DisplayProduction(Rule rule)
+        {
+            if (rule.RightHandSide.Length == 0)
+                Console.Error.Write("/* empty */ ");
+            else
+                foreach (int symbol in rule.RightHandSide)
+                    Console.Error.Write("{0} ", SymbolToString(symbol));
+
+            Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
+        }
+
+        /// <summary>
+        /// Abstract state class naming terminal symbols.
+        /// This is overridden by derived classes with the
+        /// name (or alias) to be used in error messages.
+        /// </summary>
+        /// <param name="terminal">The terminal ordinal</param>
+        /// <returns></returns>
+        protected abstract string TerminalToString(int terminal);
+
+        private string SymbolToString(int symbol)
+        {
+            if (symbol < 0)
+                return nonTerminals[-symbol];
+            else
+                return TerminalToString(symbol);
+        }
+
+        /// <summary>
+        /// Return text representation of argument character
+        /// </summary>
+        /// <param name="input">The character to convert</param>
+        /// <returns>String representation of the character</returns>
+        protected static string CharToString(char input)
+        {
+            switch (input)
+            {
+                case '\a': return @"'\a'";
+                case '\b': return @"'\b'";
+                case '\f': return @"'\f'";
+                case '\n': return @"'\n'";
+                case '\r': return @"'\r'";
+                case '\t': return @"'\t'";
+                case '\v': return @"'\v'";
+                case '\0': return @"'\0'";
+                default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Classes implementing this interface must supply a
+    /// method that merges two location objects to return
+    /// a new object of the same type.
+    /// GPPG-generated parsers have the default location
+    /// action equivalent to "@$ = @1.Merge(@N);" where N
+    /// is the right-hand-side length of the production.
+    /// </summary>
+    /// <typeparam name="TSpan">The Location type</typeparam>
+#if EXPORT_GPPG
+    public interface IMerge<TSpan>
+#else
+    internal interface IMerge<TSpan>
+#endif
+    {
+        /// <summary>
+        /// Interface method that creates a location object from
+        /// the current and last object.  Typically used to create
+        /// a location object extending from the start of the @1
+        /// object to the end of the @N object.
+        /// </summary>
+        /// <param name="last">The lexically last object to merge</param>
+        /// <returns>The merged location object</returns>
+        TSpan Merge(TSpan last);
+    }
+
+    /// <summary>
+    /// This is the default class that carries location
+    /// information from the scanner to the parser.
+    /// If you don't declare "%YYLTYPE Foo" the parser
+    /// will expect to deal with this type.
+    /// </summary>
+#if EXPORT_GPPG
+    public class LexLocation : IMerge<LexLocation>
+#else
+    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
+    internal class LexLocation : IMerge<LexLocation>
+#endif
+    {
+        private int startLine;   // start line
+        private int startColumn; // start column
+        private int endLine;     // end line
+        private int endColumn;   // end column
+
+        /// <summary>
+        /// The line at which the text span starts.
+        /// </summary>
+        public int StartLine { get { return startLine; } }
+
+        /// <summary>
+        /// The column at which the text span starts.
+        /// </summary>
+        public int StartColumn { get { return startColumn; } }
+
+        /// <summary>
+        /// The line on which the text span ends.
+        /// </summary>
+        public int EndLine { get { return endLine; } }
+
+        /// <summary>
+        /// The column of the first character
+        /// beyond the end of the text span.
+        /// </summary>
+        public int EndColumn { get { return endColumn; } }
+
+        /// <summary>
+        /// Default no-arg constructor.
+        /// </summary>
+        public LexLocation()
+        { }
+
+        /// <summary>
+        /// Constructor for text-span with given start and end.
+        /// </summary>
+        /// <param name="sl">start line</param>
+        /// <param name="sc">start column</param>
+        /// <param name="el">end line </param>
+        /// <param name="ec">end column</param>
+        public LexLocation(int sl, int sc, int el, int ec)
+        { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
+
+        /// <summary>
+        /// Create a text location which spans from the 
+        /// start of "this" to the end of the argument "last"
+        /// </summary>
+        /// <param name="last">The last location in the result span</param>
+        /// <returns>The merged span</returns>
+        public LexLocation Merge(LexLocation last)
+        { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
+
+    }
+
+    /// <summary>
+    /// Abstract scanner class that GPPG expects its scanners to 
+    /// extend.
+    /// </summary>
+    /// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
+    /// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
+#if EXPORT_GPPG
+    public abstract class AbstractScanner<TValue, TSpan>
+#else
+    internal abstract class AbstractScanner<TValue, TSpan>
+#endif
+        where TSpan : IMerge<TSpan>
+    {
+        /// <summary>
+        /// Lexical value optionally set by the scanner. The value
+        /// is of the %YYSTYPE type declared in the parser spec.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        // A field must be declared for this value of parametric type,
+        // since it may be instantiated by a value struct.  If it were 
+        // implemented as a property, machine generated code in derived
+        // types would not be able to select on the returned value.
+        public TValue yylval;                     // Lexical value: set by scanner
+
+        /// <summary>
+        /// Current scanner location property. The value is of the
+        /// type declared by %YYLTYPE in the parser specification.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual TSpan yylloc
+        {
+            get { return default(TSpan); }       // Empty implementation allowing
+            set { /* skip */ }                   // yylloc to be ignored entirely.
+        }
+
+        /// <summary>
+        /// Main call point for LEX-like scanners.  Returns an int
+        /// corresponding to the token recognized by the scanner.
+        /// </summary>
+        /// <returns>An int corresponding to the token</returns>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public abstract int yylex();
+
+        /// <summary>
+        /// Traditional error reporting provided by LEX-like scanners
+        /// to their YACC-like clients.
+        /// </summary>
+        /// <param name="format">Message format string</param>
+        /// <param name="args">Optional array of args</param>
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
+        // Reason for FxCop message suppression -
+        // This is a traditional name for YACC-like functionality
+        public virtual void yyerror(string format, params object[] args) { }
+    }
+
+    /// <summary>
+    /// Encapsulated state for the parser.
+    /// Opaque to users, visible to the tool-generated code.
+    /// </summary>
+#if EXPORT_GPPG
+    public class State
+#else
+    internal class State
+#endif
+    {
+        internal int number;
+        internal Dictionary<int, int> ParserTable;   // Terminal -> ParseAction
+        internal Dictionary<int, int> Goto;          // NonTerminal -> State;
+        internal int defaultAction; // = 0;		     // ParseAction
+
+        /// <summary>
+        /// State transition data for this state. Pairs of elements of the 
+        /// goto array associate symbol ordinals with next state indices.
+        /// The actions array is passed to another constructor. 
+        /// </summary>
+        /// <param name="actions">The action list</param>
+        /// <param name="goToList">Next state data</param>
+        public State(int[] actions, int[] goToList)
+            : this(actions)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+
+        /// <summary>
+        /// Action data for this state. Pairs of elements of the 
+        /// action array associate action ordinals with each of
+        /// those symbols that have actions in the current state.
+        /// </summary>
+        /// <param name="actions">The action array</param>
+        public State(int[] actions)
+        {
+            ParserTable = new Dictionary<int, int>();
+            for (int i = 0; i < actions.Length; i += 2)
+                ParserTable.Add(actions[i], actions[i + 1]);
+        }
+
+        /// <summary>
+        /// Set the default action for this state.
+        /// </summary>
+        /// <param name="defaultAction">Ordinal of the default action</param>
+        public State(int defaultAction)
+        {
+            this.defaultAction = defaultAction;
+        }
+
+        /// <summary>
+        /// Set the default action and the state transition table.
+        /// </summary>
+        /// <param name="defaultAction">The default action</param>
+        /// <param name="goToList">Transitions from this state</param>
+        public State(int defaultAction, int[] goToList)
+            : this(defaultAction)
+        {
+            Goto = new Dictionary<int, int>();
+            for (int i = 0; i < goToList.Length; i += 2)
+                Goto.Add(goToList[i], goToList[i + 1]);
+        }
+    }
+
+    /// <summary>
+    /// Rule representation at runtime.
+    /// </summary>
+#if EXPORT_GPPG
+    public class Rule
+#else
+    internal class Rule
+#endif
+    {
+        internal int LeftHandSide; // symbol
+        internal int[] RightHandSide; // symbols
+
+        /// <summary>
+        /// Rule constructor.  This holds the ordinal of
+        /// the left hand side symbol, and the list of
+        /// right hand side symbols, in lexical order.
+        /// </summary>
+        /// <param name="left">The LHS non-terminal</param>
+        /// <param name="right">The RHS symbols, in lexical order</param>
+        public Rule(int left, int[] right)
+        {
+            this.LeftHandSide = left;
+            this.RightHandSide = right;
+        }
+    }
+
+    /// <summary>
+    /// Stack utility for the shift-reduce parser.
+    /// GPPG parsers have three instances:
+    /// (1) The parser state stack, T = QUT.Gppg.State,
+    /// (2) The semantic value stack, T = TValue,
+    /// (3) The location stack, T = TSpan.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+#if EXPORT_GPPG
+    public class PushdownPrefixState<T>
+#else
+    internal class PushdownPrefixState<T>
+#endif
+    {
+        //  Note that we cannot use the BCL Stack<T> class
+        //  here as derived types need to index into stacks.
+        //
+        private T[] array = new T[8];
+        private int tos = 0;
+
+        /// <summary>
+        /// Indexer for values of the stack below the top.
+        /// </summary>
+        /// <param name="index">index of the element, starting from the bottom</param>
+        /// <returns>the selected element</returns>
+        public T this[int index] { get { return array[index]; } }
+
+        /// <summary>
+        /// The current depth of the stack.
+        /// </summary>
+        public int Depth { get { return tos; } }
+
+        internal void Push(T value)
+        {
+            if (tos >= array.Length)
+            {
+                T[] newarray = new T[array.Length * 2];
+                System.Array.Copy(array, newarray, tos);
+                array = newarray;
+            }
+            array[tos++] = value;
+        }
+
+        internal T Pop()
+        {
+            T rslt = array[--tos];
+            array[tos] = default(T);
+            return rslt;
+        }
+
+        internal T TopElement() { return array[tos - 1]; }
+
+        internal bool IsEmpty() { return tos == 0; }
+    }
+}
\ No newline at end of file
diff --git a/Module8/SimpleLanguage3/SimpleLang3.csproj b/Module8/SimpleLanguage3/SimpleLang3.csproj
new file mode 100644
index 0000000..c189535
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleLang3.csproj
@@ -0,0 +1,68 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SimpleLang</RootNamespace>
+    <AssemblyName>SimpleLang</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Visitors\AssignCountVisitor.cs" />
+    <Compile Include="Visitors\AutoVisitor.cs" />
+    <Compile Include="Visitors\GenCodeVisitors\GenCodeVisitor.cs" />
+    <Compile Include="Visitors\GenCodeVisitors\GenCodeCreator.cs" />
+    <Compile Include="Visitors\PrettyPrintVisitor.cs" />
+    <Compile Include="Visitors\Visitor.cs" />
+    <Compile Include="Main.cs" />
+    <Compile Include="ParserHelper.cs" />
+    <Compile Include="ProgramTree.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShiftReduceParserCode.cs" />
+    <Compile Include="SimpleLex.cs" />
+    <Compile Include="SimpleYacc.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- 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">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/Module8/SimpleLanguage3/SimpleLang3.sln b/Module8/SimpleLanguage3/SimpleLang3.sln
new file mode 100644
index 0000000..091c760
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleLang3.sln
@@ -0,0 +1,22 @@
+п»ї
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLang3", "SimpleLang3.csproj", "{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.ActiveCfg = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Debug|x86.Build.0 = Debug|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.ActiveCfg = Release|x86
+		{12B9D996-7B4A-4EE4-9AD8-2E24EAF3F574}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Module8/SimpleLanguage3/SimpleLex.cs b/Module8/SimpleLanguage3/SimpleLex.cs
new file mode 100644
index 0000000..e20b477
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleLex.cs
@@ -0,0 +1,1531 @@
+//
+//  This CSharp output file generated by Gardens Point LEX
+//  Version:  1.1.3.301
+//  Machine:  HUB
+//  DateTime: 21.09.2017 21:02:17
+//  UserName: someone
+//  GPLEX input file <SimpleLex.lex>
+//  GPLEX frame file <embedded resource>
+//
+//  Option settings: unicode, parser, minimize
+//  Option settings: classes, compressMap, compressNext, persistBuffer, embedbuffers
+//  Fallback code page: Target machine default
+//
+
+//
+// Experimental embedded frame
+// Version 1.1.3 of 18-April-2010
+//
+//
+#define BACKUP
+#define PERSIST
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+
+using SimpleParser;
+using QUT.Gppg;
+using System.Linq;
+
+namespace SimpleScanner
+{   
+    /// <summary>
+    /// Summary Canonical example of GPLEX automaton
+    /// </summary>
+    
+#if STANDALONE
+    //
+    // These are the dummy declarations for stand-alone GPLEX applications
+    // normally these declarations would come from the parser.
+    // If you declare /noparser, or %option noparser then you get this.
+    //
+
+     public enum Tokens
+    { 
+      EOF = 0, maxParseToken = int.MaxValue 
+      // must have at least these two, values are almost arbitrary
+    }
+
+     public abstract class ScanBase
+    {
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public abstract int yylex();
+
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
+        protected virtual bool yywrap() { return true; }
+
+#if BABEL
+        protected abstract int CurrentSc { get; set; }
+        // EolState is the 32-bit of state data persisted at 
+        // the end of each line for Visual Studio colorization.  
+        // The default is to return CurrentSc.  You must override
+        // this if you want more complicated behavior.
+        public virtual int EolState { 
+            get { return CurrentSc; }
+            set { CurrentSc = value; } 
+        }
+    }
+    
+     public interface IColorScan
+    {
+        void SetSource(string source, int offset);
+        int GetNext(ref int state, out int start, out int end);
+#endif // BABEL
+    }
+
+#endif // STANDALONE
+    
+    // If the compiler can't find the scanner base class maybe you
+    // need to run GPPG with the /gplex option, or GPLEX with /noparser
+#if BABEL
+     public sealed partial class Scanner : ScanBase, IColorScan
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+        
+        protected override int CurrentSc 
+        {
+             // The current start state is a property
+             // to try to avoid the user error of setting
+             // scState but forgetting to update the FSA
+             // start state "currentStart"
+             //
+             get { return currentScOrd; }  // i.e. return YY_START;
+             set { currentScOrd = value;   // i.e. BEGIN(value);
+                   currentStart = startState[value]; }
+        }
+#else  // BABEL
+     public sealed partial class Scanner : ScanBase
+    {
+        private ScanBuff buffer;
+        int currentScOrd;  // start condition ordinal
+#endif // BABEL
+        
+        /// <summary>
+        /// The input buffer for this scanner.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public ScanBuff Buffer { get { return buffer; } }
+        
+        private static int GetMaxParseToken() {
+     System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken");
+            return (f == null ? int.MaxValue : (int)f.GetValue(null));
+        }
+        
+        static int parserMax = GetMaxParseToken();
+        
+        enum Result {accept, noMatch, contextFound};
+
+        const int maxAccept = 17;
+        const int initial = 18;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+
+#region user code
+#endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;      // last code read
+        int cCol;      // column number of code
+        int lNum;      // current line number
+        //
+        // The following instance variables are used, among other
+        // things, for constructing the yylloc location objects.
+        //
+        int tokPos;        // buffer position at start of token
+        int tokCol;        // zero-based column number at start of token
+        int tokLin;        // line number at start of token
+        int tokEPos;       // buffer position at end of token
+        int tokECol;       // column number at end of token
+        int tokELin;       // line number at end of token
+        string tokTxt;     // lazily constructed text of token
+#if STACK          
+        private Stack<int> scStack = new Stack<int>();
+#endif // STACK
+
+#region ScannerTables
+    struct Table {
+        public int min; public int rng; public int dflt;
+        public sbyte[] nxt;
+        public Table(int m, int x, int d, sbyte[] n) {
+            min = m; rng = x; dflt = d; nxt = n;
+        }
+    };
+
+    static int[] startState = new int[] {18, 0};
+
+#region CompressedCharacterMap
+    //
+    // 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' */ 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, 
+/*      'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+    static sbyte MapC(int code)
+    { // '\0' <= code <= '\U0010FFFF'
+      if (code < 123) // '\0' <= code <= 'z'
+        return mapC0[code - 0];
+      else // '{' <= code <= '\U0010FFFF'
+        return (sbyte)14;
+    }
+#endregion
+
+    static Table[] NxS = new Table[20] {
+/* NxS[   0] */ new Table(0, 0, 0, null),
+/* NxS[   1] */ new Table(1, 2, -1, new sbyte[] {1, 19}),
+/* 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[   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[   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(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}),
+    };
+
+int NextState() {
+    if (code == ScanBuff.EndOfFile)
+        return eofNum;
+    else
+        unchecked {
+            int rslt;
+            int idx = MapC(code) - NxS[state].min;
+            if (idx < 0) idx += 15;
+            if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
+            else rslt = NxS[state].nxt[idx];
+            return rslt;
+        }
+}
+
+#endregion
+
+
+#if BACKUP
+        // ==============================================================
+        // == Nested struct used for backup in automata that do backup ==
+        // ==============================================================
+
+        struct Context // class used for automaton backup.
+        {
+            public int bPos;
+            public int rPos; // scanner.readPos saved value
+            public int cCol;
+            public int lNum; // Need this in case of backup over EOL.
+            public int state;
+            public int cChr;
+        }
+        
+        private Context ctx = new Context();
+#endif // BACKUP
+
+        // ==============================================================
+        // ==== Nested struct to support input switching in scanners ====
+        // ==============================================================
+
+		struct BufferContext {
+            internal ScanBuff buffSv;
+			internal int chrSv;
+			internal int cColSv;
+			internal int lNumSv;
+		}
+
+        // ==============================================================
+        // ===== Private methods to save and restore buffer contexts ====
+        // ==============================================================
+
+        /// <summary>
+        /// This method creates a buffer context record from
+        /// the current buffer object, together with some
+        /// scanner state values. 
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        BufferContext MkBuffCtx()
+		{
+			BufferContext rslt;
+			rslt.buffSv = this.buffer;
+			rslt.chrSv = this.code;
+			rslt.cColSv = this.cCol;
+			rslt.lNumSv = this.lNum;
+			return rslt;
+		}
+
+        /// <summary>
+        /// This method restores the buffer value and allied
+        /// scanner state from the given context record value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void RestoreBuffCtx(BufferContext value)
+		{
+			this.buffer = value.buffSv;
+			this.code = value.chrSv;
+			this.cCol = value.cColSv;
+			this.lNum = value.lNumSv;
+        } 
+        // =================== End Nested classes =======================
+
+#if !NOFILES
+     public Scanner(Stream file) {
+            SetSource(file, 0); // unicode option
+        }
+
+        public Scanner(Stream file, string codepage) {
+            SetSource(file, CodePageHandling.GetCodePage(codepage));
+        }
+        
+#endif // !NOFILES
+
+     public Scanner() { }
+
+        private int readPos;
+
+        void GetCode()
+        {
+            if (code == '\n')  // This needs to be fixed for other conventions
+                               // i.e. [\r\n\205\u2028\u2029]
+            { 
+                cCol = -1;
+                lNum++;
+            }
+            readPos = buffer.Pos;
+
+            // Now read new codepoint.
+            code = buffer.Read();
+            if (code > ScanBuff.EndOfFile)
+            {
+#if (!BYTEMODE)
+                if (code >= 0xD800 && code <= 0xDBFF)
+                {
+                    int next = buffer.Read();
+                    if (next < 0xDC00 || next > 0xDFFF)
+                        code = ScanBuff.UnicodeReplacementChar;
+                    else
+                        code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
+                }
+#endif
+                cCol++;
+            }
+        }
+
+        void MarkToken()
+        {
+#if (!PERSIST)
+            buffer.Mark();
+#endif
+            tokPos = readPos;
+            tokLin = lNum;
+            tokCol = cCol;
+        }
+        
+        void MarkEnd()
+        {
+            tokTxt = null;
+            tokEPos = readPos;
+            tokELin = lNum;
+            tokECol = cCol;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int Peek()
+        {
+            int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
+            GetCode(); rslt = code;
+            lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
+            return rslt;
+        }
+
+        // ==============================================================
+        // =====    Initialization of string-based input buffers     ====
+        // ==============================================================
+
+        /// <summary>
+        /// Create and initialize a StringBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the input string</param>
+        /// <param name="offset">starting offset in the string</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(string source, int offset)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.buffer.Pos = offset;
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+
+#if !NOFILES        
+        // ================ LineBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a LineBuff buffer object for this scanner
+        /// </summary>
+        /// <param name="source">the list of input strings</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(IList<string> source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            this.lNum = 0;
+            GetCode();
+        }
+
+        // =============== StreamBuffer Initialization ==================
+
+        /// <summary>
+        /// Create and initialize a StreamBuff buffer object for this scanner.
+        /// StreamBuff is buffer for 8-bit byte files.
+        /// </summary>
+        /// <param name="source">the input byte stream</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source)
+        {
+            this.buffer = ScanBuff.GetBuffer(source);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+        
+#if !BYTEMODE
+        // ================ TextBuffer Initialization ===================
+
+        /// <summary>
+        /// Create and initialize a TextBuff buffer object for this scanner.
+        /// TextBuff is a buffer for encoded unicode files.
+        /// </summary>
+        /// <param name="source">the input text file</param>
+        /// <param name="fallbackCodePage">Code page to use if file has
+        /// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        public void SetSource(Stream source, int fallbackCodePage)
+        {
+            this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
+            this.lNum = 0;
+            this.code = '\n'; // to initialize yyline, yycol and lineStart
+            GetCode();
+        }
+#endif // !BYTEMODE
+#endif // !NOFILES
+        
+        // ==============================================================
+
+#if BABEL
+        //
+        //  Get the next token for Visual Studio
+        //
+        //  "state" is the inout mode variable that maintains scanner
+        //  state between calls, using the EolState property. In principle,
+        //  if the calls of EolState are costly set could be called once
+        //  only per line, at the start; and get called only at the end
+        //  of the line. This needs more infrastructure ...
+        //
+        public int GetNext(ref int state, out int start, out int end)
+        {
+                Tokens next;
+            int s, e;
+            s = state;        // state at start
+            EolState = state;
+                next = (Tokens)Scan();
+            state = EolState;
+            e = state;       // state at end;
+            start = tokPos;
+            end = tokEPos - 1; // end is the index of last char.
+            return (int)next;
+        }        
+#endif // BABEL
+
+        // ======== AbstractScanner<> Implementation =========
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
+        public override int yylex()
+        {
+            // parserMax is set by reflecting on the Tokens
+            // enumeration.  If maxParseToken is defined
+            // that is used, otherwise int.MaxValue is used.
+            int next;
+            do { next = Scan(); } while (next >= parserMax);
+            return next;
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yypos { get { return tokPos; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yyline { get { return tokLin; } }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        int yycol { get { return tokCol; } }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
+        public string yytext
+        {
+            get 
+            {
+                if (tokTxt == null) 
+                    tokTxt = buffer.GetString(tokPos, tokEPos);
+                return tokTxt;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void yyless(int n)
+        {
+            buffer.Pos = tokPos;
+            // Must read at least one char, so set before start.
+            cCol = tokCol - 1; 
+            GetCode();
+            // Now ensure that line counting is correct.
+            lNum = tokLin;
+            // And count the rest of the text.
+            for (int i = 0; i < n; i++) GetCode();
+            MarkEnd();
+        }
+       
+        //
+        //  It would be nice to count backward in the text
+        //  but it does not seem possible to re-establish
+        //  the correct column counts except by going forward.
+        //
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        void _yytrunc(int n) { yyless(yyleng - n); }
+        
+        //
+        // This is painful, but we no longer count
+        // codepoints.  For the overwhelming majority 
+        // of cases the single line code is fast, for
+        // the others, well, at least it is all in the
+        // buffer so no files are touched. Note that we
+        // can't use (tokEPos - tokPos) because of the
+        // possibility of surrogate pairs in the token.
+        //
+        [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 {
+                    int ch;
+                    int count = 0;
+                    int save = buffer.Pos;
+                    buffer.Pos = tokPos;
+                    do {
+                        ch = buffer.Read();
+                        if (!char.IsHighSurrogate((char)ch)) count++;
+                    } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
+                    buffer.Pos = save; 
+                    return count;
+                }
+#endif // BYTEMODE
+            }
+        }
+        
+        // ============ methods available in actions ==============
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int YY_START {
+            get { return currentScOrd; }
+            set { currentScOrd = value; 
+                  currentStart = startState[value]; 
+            } 
+        }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void BEGIN(int next) {
+            currentScOrd = next;
+            currentStart = startState[next];
+        }
+
+        // ============== The main tokenizer code =================
+
+        int Scan()
+        {
+            try {
+                for (; ; )
+                {
+                    int next;              // next state to enter                   
+#if BACKUP
+                    Result rslt = Result.noMatch;
+#endif // BACKUP
+#if LEFTANCHORS
+                    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...
+                        GetCode();
+                    }
+                    
+#else // !LEFTANCHORS
+                    state = currentStart;
+                    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();
+                    
+                    while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
+#if BACKUP
+                        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;
+                        }
+                        else
+#endif // BACKUP
+                        {
+                            state = next;
+                            GetCode();
+                        }
+                    if (state <= maxAccept) 
+                    {
+                        MarkEnd();
+#region ActionSwitch
+#pragma warning disable 162
+    switch (state)
+    {
+        case eofNum:
+            if (yywrap())
+                return (int)Tokens.EOF;
+            break;
+        case 1:
+yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM;
+            break;
+        case 2:
+        case 4:
+LexError();
+            break;
+        case 3:
+int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+            break;
+        case 5:
+return (int)Tokens.SEMICOLON;
+            break;
+        case 6:
+return (int)Tokens.MINUS;
+            break;
+        case 7:
+return (int)Tokens.PLUS;
+            break;
+        case 8:
+return (int)Tokens.MULT;
+            break;
+        case 9:
+return (int)Tokens.DIV;
+            break;
+        case 10:
+return (int)Tokens.LPAREN;
+            break;
+        case 11:
+return (int)Tokens.RPAREN;
+            break;
+        case 12:
+return (int)Tokens.COLUMN;
+            break;
+        case 13:
+return (int)Tokens.ASSIGNMULT;
+            break;
+        case 14:
+return (int)Tokens.ASSIGNPLUS;
+            break;
+        case 15:
+return (int)Tokens.ASSIGNMINUS;
+            break;
+        case 16:
+return (int)Tokens.ASSIGN;
+            break;
+        case 17:
+yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+            break;
+        default:
+            break;
+    }
+#pragma warning restore 162
+#endregion
+                    }
+                }
+            } // end try
+            finally {
+// User-specified epilog to scan()
+yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+// End, user-specified epilog
+            } // end finally
+        }
+
+#if BACKUP
+        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;
+            ctx.lNum  = lNum;
+            ctx.state = state;
+            ctx.cChr  = code;
+        }
+
+        void RestoreStateAndPos(ref Context ctx)
+        {
+            buffer.Pos = ctx.bPos;
+            readPos = ctx.rPos;
+            cCol  = ctx.cCol;
+            lNum  = ctx.lNum;
+            state = ctx.state;
+            code  = ctx.cChr;
+        }
+
+#endif // BACKUP
+
+        // ============= End of the tokenizer code ================
+
+#if STACK        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void yy_clear_stack() { scStack.Clear(); }
+        
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal int yy_top_state() { return scStack.Peek(); }
+        
+        internal void yy_push_state(int state)
+        {
+            scStack.Push(currentScOrd);
+            BEGIN(state);
+        }
+        
+        internal void yy_pop_state()
+        {
+            // Protect against input errors that pop too far ...
+            if (scStack.Count > 0) {
+				int newSc = scStack.Pop();
+				BEGIN(newSc);
+            } // Otherwise leave stack unchanged.
+        }
+ #endif // STACK
+
+        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal void ECHO() { Console.Out.Write(yytext); }
+        
+#region UserCodeSection
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("write",(int)Tokens.WRITE);
+    keywords.Add("var",(int)Tokens.VAR);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
+
+#endregion
+    } // end class $Scanner
+
+// ==============================================================
+// <auto-generated>
+// This code automatically produced from an embedded resource.
+// Do not edit this file, or it will become incompatible with 
+// the specification from which it was generated.
+// </auto-generated>
+// ==============================================================
+
+// Code copied from GPLEX embedded resource
+    [Serializable]
+    public class BufferException : Exception
+    {
+        public BufferException() { }
+        public BufferException(string message) : base(message) { }
+        public BufferException(string message, Exception innerException)
+            : base(message, innerException) { }
+        protected BufferException(SerializationInfo info, StreamingContext context)
+            : base(info, context) { }
+    }
+
+    public abstract class ScanBuff
+    {
+        private string fileNm;
+
+        public const int EndOfFile = -1;
+        public const int UnicodeReplacementChar = 0xFFFD;
+
+        public bool IsFile { get { return (fileNm != null); } }
+        public string FileName { get { return fileNm; } set { fileNm = value; } }
+
+        public abstract int Pos { get; set; }
+        public abstract int Read();
+        public virtual void Mark() { }
+
+        public abstract string GetString(int begin, int limit);
+
+        public static ScanBuff GetBuffer(string source)
+        {
+            return new StringBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(IList<string> source)
+        {
+            return new LineBuffer(source);
+        }
+
+        public static ScanBuff GetBuffer(Stream source)
+        {
+            return new BuildBuffer(source);
+        }
+
+#if (!BYTEMODE)
+        public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
+        {
+            return new BuildBuffer(source, fallbackCodePage);
+        }
+#endif
+    }
+
+    #region Buffer classes
+
+    // ==============================================================
+    // =====  Definitions for various ScanBuff derived classes   ====
+    // ==============================================================
+    // ===============         String input          ================
+    // ==============================================================
+
+    /// <summary>
+    /// This class reads characters from a single string as
+    /// required, for example, by Visual Studio language services
+    /// </summary>
+    sealed class StringBuffer : ScanBuff
+    {
+        string str;        // input buffer
+        int bPos;          // current position in buffer
+        int sLen;
+
+        public StringBuffer(string source)
+        {
+            this.str = source;
+            this.sLen = source.Length;
+            this.FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (bPos < sLen) return str[bPos++];
+            else if (bPos == sLen) { bPos++; return '\n'; }   // one strike, see new line
+            else { bPos++; return EndOfFile; }                // two strikes and you're out!
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            //  "limit" can be greater than sLen with the BABEL
+            //  option set.  Read returns a "virtual" EOL if
+            //  an attempt is made to read past the end of the
+            //  string buffer.  Without the guard any attempt 
+            //  to fetch yytext for a token that includes the 
+            //  EOL will throw an index exception.
+            if (limit > sLen) limit = sLen;
+            if (limit <= begin) return "";
+            else return str.Substring(begin, limit - begin);
+        }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+        public override string ToString() { return "StringBuffer"; }
+    }
+
+    // ==============================================================
+    //  The LineBuff class contributed by Nigel Horspool, 
+    //  nigelh@cs.uvic.cs
+    // ==============================================================
+
+    sealed class LineBuffer : ScanBuff
+    {
+        IList<string> line;    // list of source lines from a file
+        int numLines;          // number of strings in line list
+        string curLine;        // current line in that list
+        int cLine;             // index of current line in the list
+        int curLen;            // length of current line
+        int curLineStart;      // position of line start in whole file
+        int curLineEnd;        // position of line end in whole file
+        int maxPos;            // max position ever visited in whole file
+        int cPos;              // ordinal number of code in source
+
+        // Constructed from a list of strings, one per source line.
+        // The lines have had trailing '\n' characters removed.
+        public LineBuffer(IList<string> lineList)
+        {
+            line = lineList;
+            numLines = line.Count;
+            cPos = curLineStart = 0;
+            curLine = (numLines > 0 ? line[0] : "");
+            maxPos = curLineEnd = curLen = curLine.Length;
+            cLine = 1;
+            FileName = null;
+        }
+
+        public override int Read()
+        {
+            if (cPos < curLineEnd)
+                return curLine[cPos++ - curLineStart];
+            if (cPos++ == curLineEnd)
+                return '\n';
+            if (cLine >= numLines)
+                return EndOfFile;
+            curLine = line[cLine];
+            curLen = curLine.Length;
+            curLineStart = curLineEnd + 1;
+            curLineEnd = curLineStart + curLen;
+            if (curLineEnd > maxPos)
+                maxPos = curLineEnd;
+            cLine++;
+            return curLen > 0 ? curLine[0] : '\n';
+        }
+
+        // To speed up searches for the line containing a position
+        private int cachedPosition;
+        private int cachedIxdex;
+        private int cachedLineStart;
+
+        // Given a position pos within the entire source, the results are
+        //   ix     -- the index of the containing line
+        //   lstart -- the position of the first character on that line
+        private void findIndex(int pos, out int ix, out int lstart)
+        {
+            if (pos >= cachedPosition)
+            {
+                ix = cachedIxdex; lstart = cachedLineStart;
+            }
+            else
+            {
+                ix = lstart = 0;
+            }
+            for (; ; )
+            {
+                int len = line[ix].Length + 1;
+                if (pos < lstart + len) break;
+                lstart += len;
+                ix++;
+            }
+            cachedPosition = pos;
+            cachedIxdex = ix;
+            cachedLineStart = lstart;
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            if (begin >= maxPos || limit <= begin) return "";
+            int endIx, begIx, endLineStart, begLineStart;
+            findIndex(begin, out begIx, out begLineStart);
+            int begCol = begin - begLineStart;
+            findIndex(limit, out endIx, out endLineStart);
+            int endCol = limit - endLineStart;
+            string s = line[begIx];
+            if (begIx == endIx)
+            {
+                // the usual case, substring all on one line
+                return (endCol <= s.Length) ?
+                    s.Substring(begCol, endCol - begCol)
+                    : s.Substring(begCol) + "\n";
+            }
+            // the string spans multiple lines, yuk!
+            StringBuilder sb = new StringBuilder();
+            if (begCol < s.Length)
+                sb.Append(s.Substring(begCol));
+            for (; ; )
+            {
+                sb.Append("\n");
+                s = line[++begIx];
+                if (begIx >= endIx) break;
+                sb.Append(s);
+            }
+            if (endCol <= s.Length)
+            {
+                sb.Append(s.Substring(0, endCol));
+            }
+            else
+            {
+                sb.Append(s);
+                sb.Append("\n");
+            }
+            return sb.ToString();
+        }
+
+        public override int Pos
+        {
+            get { return cPos; }
+            set
+            {
+                cPos = value;
+                findIndex(cPos, out cLine, out curLineStart);
+                curLine = line[cLine];
+                curLineEnd = curLineStart + curLine.Length;
+            }
+        }
+
+        public override string ToString() { return "LineBuffer"; }
+    }
+
+
+    // ==============================================================
+    // =====     class BuildBuff : for unicode text files    ========
+    // ==============================================================
+
+    class BuildBuffer : ScanBuff
+    {
+        // Double buffer for char stream.
+        class BufferElement
+        {
+            StringBuilder bldr = new StringBuilder();
+            StringBuilder next = new StringBuilder();
+            int minIx;
+            int maxIx;
+            int brkIx;
+            bool appendToNext;
+
+            internal BufferElement() { }
+
+            internal int MaxIndex { get { return maxIx; } }
+            // internal int MinIndex { get { return minIx; } }
+
+            internal char this[int index]
+            {
+                get
+                {
+                    if (index < minIx || index >= maxIx)
+                        throw new BufferException("Index was outside data buffer");
+                    else if (index < brkIx)
+                        return bldr[index - minIx];
+                    else
+                        return next[index - brkIx];
+                }
+            }
+
+            internal void Append(char[] block, int count)
+            {
+                maxIx += count;
+                if (appendToNext)
+                    this.next.Append(block, 0, count);
+                else
+                {
+                    this.bldr.Append(block, 0, count);
+                    brkIx = maxIx;
+                    appendToNext = true;
+                }
+            }
+
+            internal string GetString(int start, int limit)
+            {
+                if (limit <= start)
+                    return "";
+                if (start >= minIx && limit <= maxIx)
+                    if (limit < brkIx) // String entirely in bldr builder
+                        return bldr.ToString(start - minIx, limit - start);
+                    else if (start >= brkIx) // String entirely in next builder
+                        return next.ToString(start - brkIx, limit - start);
+                    else // Must do a string-concatenation
+                        return
+                            bldr.ToString(start - minIx, brkIx - start) +
+                            next.ToString(0, limit - brkIx);
+                else
+                    throw new BufferException("String was outside data buffer");
+            }
+
+            internal void Mark(int limit)
+            {
+                if (limit > brkIx + 16) // Rotate blocks
+                {
+                    StringBuilder temp = bldr;
+                    bldr = next;
+                    next = temp;
+                    next.Length = 0;
+                    minIx = brkIx;
+                    brkIx = maxIx;
+                }
+            }
+        }
+
+        BufferElement data = new BufferElement();
+
+        int bPos;            // Postion index in the StringBuilder
+        BlockReader NextBlk; // Delegate that serves char-arrays;
+
+        private string EncodingName
+        {
+            get
+            {
+                StreamReader rdr = NextBlk.Target as StreamReader;
+                return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
+            }
+        }
+
+        public BuildBuffer(Stream stream)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Raw(stream);
+        }
+
+#if (!BYTEMODE)
+        public BuildBuffer(Stream stream, int fallbackCodePage)
+        {
+            FileStream fStrm = (stream as FileStream);
+            if (fStrm != null) FileName = fStrm.Name;
+            NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
+        }
+#endif
+
+        /// <summary>
+        /// Marks a conservative lower bound for the buffer,
+        /// allowing space to be reclaimed.  If an application 
+        /// needs to call GetString at arbitrary past locations 
+        /// in the input stream, Mark() is not called.
+        /// </summary>
+        public override void Mark() { data.Mark(bPos - 2); }
+
+        public override int Pos
+        {
+            get { return bPos; }
+            set { bPos = value; }
+        }
+
+
+        /// <summary>
+        /// Read returns the ordinal number of the next char, or 
+        /// EOF (-1) for an end of stream.  Note that the next
+        /// code point may require *two* calls of Read().
+        /// </summary>
+        /// <returns></returns>
+        public override int Read()
+        {
+            //
+            //  Characters at positions 
+            //  [data.offset, data.offset + data.bldr.Length)
+            //  are available in data.bldr.
+            //
+            if (bPos < data.MaxIndex)
+            {
+                // ch0 cannot be EOF
+                return (int)data[bPos++];
+            }
+            else // Read from underlying stream
+            {
+                // Experimental code, blocks of page size
+                char[] chrs = new char[4096];
+                int count = NextBlk(chrs, 0, 4096);
+                if (count == 0)
+                    return EndOfFile;
+                else
+                {
+                    data.Append(chrs, count);
+                    return (int)data[bPos++];
+                }
+            }
+        }
+
+        public override string GetString(int begin, int limit)
+        {
+            return data.GetString(begin, limit);
+        }
+
+        public override string ToString()
+        {
+            return "StringBuilder buffer, encoding: " + this.EncodingName;
+        }
+    }
+
+    // =============== End ScanBuff-derived classes ==================
+
+    public delegate int BlockReader(char[] block, int index, int number);
+
+    // A delegate factory, serving up a delegate that
+    // reads a block of characters from the underlying
+    // encoded stream, via a StreamReader object.
+    //
+    public static class BlockReaderFactory
+    {
+        public static BlockReader Raw(Stream stream)
+        {
+            return delegate(char[] block, int index, int number)
+            {
+                byte[] b = new byte[number];
+                int count = stream.Read(b, 0, number);
+                int i = 0;
+                int j = index;
+                for (; i < count; i++, j++)
+                    block[j] = (char)b[i];
+                return count;
+            };
+        }
+
+#if (!BYTEMODE)
+        public static BlockReader Get(Stream stream, int fallbackCodePage)
+        {
+            Encoding encoding;
+            int preamble = Preamble(stream);
+
+            if (preamble != 0)  // There is a valid BOM here!
+                encoding = Encoding.GetEncoding(preamble);
+            else if (fallbackCodePage == -1) // Fallback is "raw" bytes
+                return Raw(stream);
+            else if (fallbackCodePage != -2) // Anything but "guess"
+                encoding = Encoding.GetEncoding(fallbackCodePage);
+            else // This is the "guess" option
+            {
+                int guess = new Guesser(stream).GuessCodePage();
+                stream.Seek(0, SeekOrigin.Begin);
+                if (guess == -1) // ==> this is a 7-bit file
+                    encoding = Encoding.ASCII;
+                else if (guess == 65001)
+                    encoding = Encoding.UTF8;
+                else             // ==> use the machine default
+                    encoding = Encoding.Default;
+            }
+            StreamReader reader = new StreamReader(stream, encoding);
+            return reader.Read;
+        }
+
+        static int Preamble(Stream stream)
+        {
+            int b0 = stream.ReadByte();
+            int b1 = stream.ReadByte();
+
+            if (b0 == 0xfe && b1 == 0xff)
+                return 1201; // UTF16BE
+            if (b0 == 0xff && b1 == 0xfe)
+                return 1200; // UTF16LE
+
+            int b2 = stream.ReadByte();
+            if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
+                return 65001; // UTF8
+            //
+            // There is no unicode preamble, so we
+            // return denoter for the machine default.
+            //
+            stream.Seek(0, SeekOrigin.Begin);
+            return 0;
+        }
+#endif // !BYTEMODE
+    }
+    #endregion Buffer classes
+
+    // ==============================================================
+    // ============      class CodePageHandling         =============
+    // ==============================================================
+
+    public static class CodePageHandling
+    {
+        public static int GetCodePage(string option)
+        {
+            string command = option.ToUpperInvariant();
+            if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
+                command = command.Substring(9);
+            try
+            {
+                if (command.Equals("RAW"))
+                    return -1;
+                else if (command.Equals("GUESS"))
+                    return -2;
+                else if (command.Equals("DEFAULT"))
+                    return 0;
+                else if (char.IsDigit(command[0]))
+                    return int.Parse(command, CultureInfo.InvariantCulture);
+                else
+                {
+                    Encoding enc = Encoding.GetEncoding(command);
+                    return enc.CodePage;
+                }
+            }
+            catch (FormatException)
+            {
+                Console.Error.WriteLine(
+                    "Invalid format \"{0}\", using machine default", option);
+            }
+            catch (ArgumentException)
+            {
+                Console.Error.WriteLine(
+                    "Unknown code page \"{0}\", using machine default", option);
+            }
+            return 0;
+        }
+    }
+#region guesser
+#if (!BYTEMODE)
+    // ==============================================================
+    // ============          Encoding Guesser           =============
+    // ==============================================================
+
+    /// <summary>
+    /// This class provides a simple finite state automaton that
+    /// scans the file looking for (1) valid UTF-8 byte patterns,
+    /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
+    /// The method then guesses whether it is UTF-8 or maybe some 
+    /// local machine default encoding.  This works well for the
+    /// various Latin encodings.
+    /// </summary>
+    internal class Guesser
+    {
+        ScanBuff buffer;
+
+        public int GuessCodePage() { return Scan(); }
+
+        const int maxAccept = 10;
+        const int initial = 0;
+        const int eofNum = 0;
+        const int goStart = -1;
+        const int INITIAL = 0;
+        const int EndToken = 0;
+
+        #region user code
+        /* 
+         *  Reads the bytes of a file to determine if it is 
+         *  UTF-8 or a single-byte code page file.
+         */
+        public long utfX;
+        public long uppr;
+        #endregion user code
+
+        int state;
+        int currentStart = startState[0];
+        int code;
+
+        #region ScannerTables
+        static int[] startState = new int[] { 11, 0 };
+
+        #region CharacterMap
+        static sbyte[] map = new sbyte[256] {
+/*     '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*      'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+/*   '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
+/*   '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+/*   '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
+/*   '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
+        #endregion
+
+        static sbyte[][] nextState = new sbyte[][] {
+            new sbyte[] {0, 0, 0, 0, 0, 0},
+            new sbyte[] {-1, -1, 10, -1, -1, -1},
+            new sbyte[] {-1, -1, -1, -1, -1, -1},
+            new sbyte[] {-1, -1, 8, -1, -1, -1},
+            new sbyte[] {-1, -1, 5, -1, -1, -1},
+            new sbyte[] {-1, -1, 6, -1, -1, -1},
+            new sbyte[] {-1, -1, 7, -1, -1, -1},
+            null,
+            new sbyte[] {-1, -1, 9, -1, -1, -1},
+            null,
+            null,
+            new sbyte[] {-1, 1, 2, 3, 4, 2}
+        };
+
+
+        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
+        // Reason for suppression: cannot have self-reference in array initializer.
+        static Guesser()
+        {
+            nextState[7] = nextState[2];
+            nextState[9] = nextState[2];
+            nextState[10] = nextState[2];
+        }
+
+        int NextState()
+        {
+            if (code == ScanBuff.EndOfFile)
+                return eofNum;
+            else
+                return nextState[state][map[code]];
+        }
+        #endregion
+
+        public Guesser(System.IO.Stream file) { SetSource(file); }
+
+        public void SetSource(System.IO.Stream source)
+        {
+            this.buffer = new BuildBuffer(source);
+            code = buffer.Read();
+        }
+
+        int Scan()
+        {
+            for (; ; )
+            {
+                int next;
+                state = currentStart;
+                while ((next = NextState()) == goStart)
+                    code = buffer.Read();
+
+                state = next;
+                code = buffer.Read();
+
+                while ((next = NextState()) > eofNum)
+                {
+                    state = next;
+                    code = buffer.Read();
+                }
+                if (state <= maxAccept)
+                {
+                    #region ActionSwitch
+#pragma warning disable 162
+                    switch (state)
+                    {
+                        case eofNum:
+                            switch (currentStart)
+                            {
+                                case 11:
+                                    if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
+                                    else if (uppr * 10 > utfX) return 0;   /* default code page */
+                                    else return 65001;                     /* UTF-8 encoding */
+                                    break;
+                            }
+                            return EndToken;
+                        case 1: // Recognized '{Upper128}',	Shortest string "\xC0"
+                        case 2: // Recognized '{Upper128}',	Shortest string "\x80"
+                        case 3: // Recognized '{Upper128}',	Shortest string "\xE0"
+                        case 4: // Recognized '{Upper128}',	Shortest string "\xF0"
+                            uppr++;
+                            break;
+                        case 5: // Recognized '{Utf8pfx4}{Utf8cont}',	Shortest string "\xF0\x80"
+                            uppr += 2;
+                            break;
+                        case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}',	Shortest string "\xF0\x80\x80"
+                            uppr += 3;
+                            break;
+                        case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}',	Shortest string "\xF0\x80\x80\x80"
+                            utfX += 3;
+                            break;
+                        case 8: // Recognized '{Utf8pfx3}{Utf8cont}',	Shortest string "\xE0\x80"
+                            uppr += 2;
+                            break;
+                        case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}',	Shortest string "\xE0\x80\x80"
+                            utfX += 2;
+                            break;
+                        case 10: // Recognized '{Utf8pfx2}{Utf8cont}',	Shortest string "\xC0\x80"
+                            utfX++;
+                            break;
+                        default:
+                            break;
+                    }
+#pragma warning restore 162
+                    #endregion
+                }
+            }
+        }
+    } // end class Guesser
+    
+#endif // !BYTEMODE
+#endregion
+
+// End of code copied from embedded resource
+
+} // end namespace
diff --git a/Module8/SimpleLanguage3/SimpleLex.lex b/Module8/SimpleLanguage3/SimpleLex.lex
new file mode 100644
index 0000000..00dfa12
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleLex.lex
@@ -0,0 +1,90 @@
+%using SimpleParser;
+%using QUT.Gppg;
+%using System.Linq;
+
+%namespace SimpleScanner
+
+Alpha 	[a-zA-Z_]
+Digit   [0-9] 
+AlphaDigit {Alpha}|{Digit}
+INTNUM  {Digit}+
+REALNUM {INTNUM}\.{INTNUM}
+ID {Alpha}{AlphaDigit}* 
+
+%%
+
+{INTNUM} { 
+  yylval.iVal = int.Parse(yytext); 
+  return (int)Tokens.INUM; 
+}
+
+{REALNUM} { 
+  yylval.dVal = double.Parse(yytext); 
+  return (int)Tokens.RNUM;
+}
+
+{ID}  { 
+  int res = ScannerHelper.GetIDToken(yytext);
+  if (res == (int)Tokens.ID)
+	yylval.sVal = yytext;
+  return res;
+}
+
+":=" { return (int)Tokens.ASSIGN; }
+";" { return (int)Tokens.SEMICOLON; }
+"-=" { return (int)Tokens.ASSIGNMINUS; }
+"+=" { return (int)Tokens.ASSIGNPLUS; }
+"*=" { return (int)Tokens.ASSIGNMULT; }
+"+" { return (int)Tokens.PLUS; }
+"-" { return (int)Tokens.MINUS; }
+"*" { return (int)Tokens.MULT; }
+"/" { return (int)Tokens.DIV; }
+"(" { return (int)Tokens.LPAREN; }
+")" { return (int)Tokens.RPAREN; }
+"," { return (int)Tokens.COLUMN; }
+
+[^ \r\n] {
+	LexError();
+}
+
+%{
+  yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
+%}
+
+%%
+
+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));
+  throw new SyntaxException(errorMsg);
+}
+
+public void LexError()
+{
+  string errorMsg = string.Format("({0},{1}): Неизвестный символ {2}", yyline, yycol, yytext);
+  throw new LexException(errorMsg);
+}
+
+class ScannerHelper 
+{
+  private static Dictionary<string,int> keywords;
+
+  static ScannerHelper() 
+  {
+    keywords = new Dictionary<string,int>();
+    keywords.Add("begin",(int)Tokens.BEGIN);
+    keywords.Add("end",(int)Tokens.END);
+    keywords.Add("cycle",(int)Tokens.CYCLE);
+    keywords.Add("write",(int)Tokens.WRITE);
+    keywords.Add("var",(int)Tokens.VAR);
+  }
+  public static int GetIDToken(string s)
+  {
+	if (keywords.ContainsKey(s.ToLower()))
+	  return keywords[s];
+	else
+      return (int)Tokens.ID;
+  }
+  
+}
diff --git a/Module8/SimpleLanguage3/SimpleYacc.cs b/Module8/SimpleLanguage3/SimpleYacc.cs
new file mode 100644
index 0000000..fa0d511
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleYacc.cs
@@ -0,0 +1,274 @@
+// This code was generated by the Gardens Point Parser Generator
+// Copyright (c) Wayne Kelly, QUT 2005-2010
+// (see accompanying GPPGcopyright.rtf)
+
+// GPPG version 1.3.6
+// Machine:  HUB
+// DateTime: 21.09.2017 21:02:18
+// UserName: someone
+// Input file <SimpleYacc.y>
+
+// options: no-lines gplex
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using QUT.Gppg;
+using System.IO;
+using ProgramTree;
+
+namespace SimpleParser
+{
+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,INUM=20,RNUM=21,ID=22};
+
+public struct ValueType
+{ 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+// Abstract base class for GPLEX scanners
+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; }
+}
+
+public class Parser: ShiftReduceParser<ValueType, LexLocation>
+{
+  // 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
+
+#pragma warning disable 649
+  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 string[] nonTerms = new string[] {
+      "progr", "expr", "ident", "T", "F", "statement", "assign", "block", "cycle", 
+      "write", "empty", "var", "varlist", "stlist", "$accept", "Anon@1", };
+
+  static Parser() {
+    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[]{22,18,3,4,5,31,11,35,12,40,4,-11,10,-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[]{4,6,10,7});
+    states[6] = new State(-23);
+    states[7] = new State(new int[]{22,18,3,4,5,31,11,35,12,40,4,-11,10,-11},new int[]{-6,8,-7,9,-3,10,-8,29,-9,30,-10,34,-12,39,-11,46});
+    states[8] = new State(-4);
+    states[9] = new State(-5);
+    states[10] = new State(new int[]{6,11});
+    states[11] = new State(new int[]{22,18,20,19,17,20},new int[]{-2,12,-4,28,-5,27,-3,17});
+    states[12] = new State(new int[]{13,13,14,23,4,-13,10,-13});
+    states[13] = new State(new int[]{22,18,20,19,17,20},new int[]{-4,14,-5,27,-3,17});
+    states[14] = new State(new int[]{15,15,16,25,13,-14,14,-14,4,-14,10,-14,18,-14,22,-14,3,-14,5,-14,11,-14,12,-14});
+    states[15] = new State(new int[]{22,18,20,19,17,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[]{22,18,20,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(-22);
+    states[23] = new State(new int[]{22,18,20,19,17,20},new int[]{-4,24,-5,27,-3,17});
+    states[24] = new State(new int[]{15,15,16,25,13,-15,14,-15,4,-15,10,-15,18,-15,22,-15,3,-15,5,-15,11,-15,12,-15});
+    states[25] = new State(new int[]{22,18,20,19,17,20},new int[]{-5,26,-3,17});
+    states[26] = new State(-18);
+    states[27] = new State(-19);
+    states[28] = new State(new int[]{15,15,16,25,13,-16,14,-16,4,-16,10,-16,18,-16,22,-16,3,-16,5,-16,11,-16,12,-16});
+    states[29] = new State(-6);
+    states[30] = new State(-7);
+    states[31] = new State(new int[]{22,18,20,19,17,20},new int[]{-2,32,-4,28,-5,27,-3,17});
+    states[32] = new State(new int[]{13,13,14,23,22,18,3,4,5,31,11,35,12,40,4,-11,10,-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[]{17,36});
+    states[36] = new State(new int[]{22,18,20,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(-25);
+    states[39] = new State(-9);
+    states[40] = new State(-26,new int[]{-16,41});
+    states[41] = new State(new int[]{22,18},new int[]{-13,42,-3,45});
+    states[42] = new State(new int[]{19,43,4,-27,10,-27});
+    states[43] = new State(new int[]{22,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);
+
+    rules[1] = new Rule(-15, 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,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[]{22});
+    rules[13] = new Rule(-7, new int[]{-3,6,-2});
+    rules[14] = new Rule(-2, new int[]{-2,13,-4});
+    rules[15] = new Rule(-2, new int[]{-2,14,-4});
+    rules[16] = new Rule(-2, new int[]{-4});
+    rules[17] = new Rule(-4, new int[]{-4,15,-5});
+    rules[18] = new Rule(-4, new int[]{-4,16,-5});
+    rules[19] = new Rule(-4, new int[]{-5});
+    rules[20] = new Rule(-5, new int[]{-3});
+    rules[21] = new Rule(-5, new int[]{20});
+    rules[22] = new Rule(-5, new int[]{17,-2,18});
+    rules[23] = new Rule(-8, new int[]{3,-14,4});
+    rules[24] = new Rule(-9, new int[]{5,-2,-6});
+    rules[25] = new Rule(-10, new int[]{11,17,-2,18});
+    rules[26] = new Rule(-16, new int[]{});
+    rules[27] = new Rule(-12, new int[]{12,-16,-13});
+    rules[28] = new Rule(-13, new int[]{-3});
+    rules[29] = new Rule(-13, new int[]{-13,19,-3});
+  }
+
+  protected override void Initialize() {
+    this.InitSpecialTokens((int)Tokens.error, (int)Tokens.EOF);
+    this.InitStates(states);
+    this.InitRules(rules);
+    this.InitNonTerminals(nonTerms);
+  }
+
+  protected override void DoAction(int action)
+  {
+    switch (action)
+    {
+      case 2: // progr -> block
+{ root = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 3: // stlist -> statement
+{ 
+				CurrentSemanticValue.blVal = new BlockNode(ValueStack[ValueStack.Depth-1].stVal); 
+			}
+        break;
+      case 4: // stlist -> stlist, SEMICOLON, statement
+{ 
+				ValueStack[ValueStack.Depth-3].blVal.Add(ValueStack[ValueStack.Depth-1].stVal); 
+				CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-3].blVal; 
+			}
+        break;
+      case 5: // statement -> assign
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 6: // statement -> block
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].blVal; }
+        break;
+      case 7: // statement -> cycle
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 8: // statement -> write
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 9: // statement -> var
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 10: // statement -> empty
+{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; }
+        break;
+      case 11: // empty -> /* empty */
+{ CurrentSemanticValue.stVal = new EmptyNode(); }
+        break;
+      case 12: // 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+" не описана");
+			CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); 
+		}
+        break;
+      case 13: // 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
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'+'); }
+        break;
+      case 15: // expr -> expr, MINUS, T
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'-'); }
+        break;
+      case 16: // expr -> T
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
+        break;
+      case 17: // 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
+{ CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'/'); }
+        break;
+      case 19: // T -> F
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; }
+        break;
+      case 20: // F -> ident
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; }
+        break;
+      case 21: // F -> INUM
+{ CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); }
+        break;
+      case 22: // F -> LPAREN, expr, RPAREN
+{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; }
+        break;
+      case 23: // block -> BEGIN, stlist, END
+{ CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; }
+        break;
+      case 24: // 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
+{ CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); }
+        break;
+      case 26: // Anon@1 -> /* empty */
+{ InDefSect = true; }
+        break;
+      case 27: // 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
+{ 
+			CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); 
+		}
+        break;
+      case 29: // 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;
+    }
+  }
+
+  protected override string TerminalToString(int 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/SimpleLanguage3/SimpleYacc.lst b/Module8/SimpleLanguage3/SimpleYacc.lst
new file mode 100644
index 0000000..2de6038
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleYacc.lst
@@ -0,0 +1,139 @@
+
+// ==========================================================================
+//  GPPG error listing for yacc source file <SimpleYacc.y>
+// ==========================================================================
+//  Version:  1.3.6
+//  Machine:  SSM
+//  DateTime: 19.08.2014 13:28:35
+//  UserName: Станислав
+// ==========================================================================
+
+
+%{
+// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
+    public BlockNode root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+	private bool InDefSect = false;
+%}
+
+%output = SimpleYacc.cs
+
+%union { 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+
+%using System.IO;
+%using ProgramTree;
+
+%namespace SimpleParser
+
+%start progr
+
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%token <iVal> INUM 
+%token <dVal> RNUM 
+%token <sVal> ID
+
+%type <nVal> varlist 
+%type <eVal> expr ident T F 
+%type <stVal> statement assign block cycle write empty var  
+%type <blVal> stlist block
+
+%%
+// 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}
+// ------------------------------------------------------------------
+
+progr   : block { root = $1; }
+		;
+
+stlist	: statement 
+			{ 
+				$$ = new BlockNode($1); 
+			}
+		| stlist SEMICOLON statement 
+			{ 
+				$1.Add($3); 
+				$$ = $1; 
+			}
+		;
+
+statement: assign { $$ = $1; }
+		| block   { $$ = $1; }
+		| cycle   { $$ = $1; }
+		| write   { $$ = $1; }
+		| var     { $$ = $1; }
+		| empty   { $$ = $1; }
+		;
+
+empty	: { $$ = new EmptyNode(); }
+		;
+	
+ident 	: ID 
+		{
+			if (!InDefSect)
+				if (!SymbolTable.vars.ContainsKey($1))
+					throw new Exception("("+@1.StartLine+","+@1.StartColumn+"): Ïåðåìåííàÿ "+$1+" íå îïèñàíà");
+			$$ = new IdNode($1); 
+		}	
+	;
+	
+assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
+		;
+
+expr	: expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
+		| expr MINUS T { $$ = new BinOpNode($1,$3,'-'); }
+		| T { $$ = $1; }
+		;
+		
+T 		: T MULT F { $$ = new BinOpNode($1,$3,'*'); }
+		| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
+		| F { $$ = $1; }
+		;
+		
+F 		: ident  { $$ = $1 as IdNode; }
+		| INUM { $$ = new IntNumNode($1); }
+		| LPAREN expr RPAREN { $$ = $2; }
+		;
+
+block	: BEGIN stlist END { $$ = $2; }
+		;
+
+cycle	: CYCLE expr st { $$ = new CycleNode($2,$3); }
+		;
+		
+write	: WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); }
+		;
+		
+var		: VAR { InDefSect = true; } varlist 
+		{ 
+			foreach (var v in ($3 as VarDefNode).vars)
+				SymbolTable.NewVarDef(v.Name, type.tint);
+			InDefSect = false;	
+		}
+		;
+
+varlist	: ident 
+		{ 
+			$$ = new VarDefNode($1 as IdNode); 
+		}
+		| varlist COLUMN ident 
+		{ 
+			($1 as VarDefNode).Add($3 as IdNode);
+			$$ = $1;
+		}
+		;
+	
+%%
+
+// ==========================================================================
+
diff --git a/Module8/SimpleLanguage3/SimpleYacc.y b/Module8/SimpleLanguage3/SimpleYacc.y
new file mode 100644
index 0000000..20087e0
--- /dev/null
+++ b/Module8/SimpleLanguage3/SimpleYacc.y
@@ -0,0 +1,119 @@
+%{
+// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
+    public BlockNode root; // Корневой узел синтаксического дерева 
+    public Parser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
+	private bool InDefSect = false;
+%}
+
+%output = SimpleYacc.cs
+
+%union { 
+			public double dVal; 
+			public int iVal; 
+			public string sVal; 
+			public Node nVal;
+			public ExprNode eVal;
+			public StatementNode stVal;
+			public BlockNode blVal;
+       }
+
+%using System.IO;
+%using ProgramTree;
+
+%namespace SimpleParser
+
+%start progr
+
+%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
+%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 <blVal> stlist block
+
+%%
+
+progr   : block { root = $1; }
+		;
+
+stlist	: statement 
+			{ 
+				$$ = new BlockNode($1); 
+			}
+		| stlist SEMICOLON statement 
+			{ 
+				$1.Add($3); 
+				$$ = $1; 
+			}
+		;
+
+statement: assign { $$ = $1; }
+		| block   { $$ = $1; }
+		| cycle   { $$ = $1; }
+		| write   { $$ = $1; }
+		| var     { $$ = $1; }
+		| empty   { $$ = $1; }
+		;
+
+empty	: { $$ = new EmptyNode(); }
+		;
+	
+ident 	: ID 
+		{
+			if (!InDefSect)
+				if (!SymbolTable.vars.ContainsKey($1))
+					throw new Exception("("+@1.StartLine+","+@1.StartColumn+"): Переменная "+$1+" не описана");
+			$$ = new IdNode($1); 
+		}	
+	;
+	
+assign 	: ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); }
+		;
+
+expr	: expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
+		| expr MINUS T { $$ = new BinOpNode($1,$3,'-'); }
+		| T { $$ = $1; }
+		;
+		
+T 		: T MULT F { $$ = new BinOpNode($1,$3,'*'); }
+		| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
+		| F { $$ = $1; }
+		;
+		
+F 		: ident  { $$ = $1 as IdNode; }
+		| INUM { $$ = new IntNumNode($1); }
+		| LPAREN expr RPAREN { $$ = $2; }
+		;
+
+block	: BEGIN stlist END { $$ = $2; }
+		;
+
+cycle	: CYCLE expr statement { $$ = new CycleNode($2,$3); }
+		;
+		
+write	: WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); }
+		;
+		
+var		: VAR { InDefSect = true; } varlist 
+		{ 
+			foreach (var v in ($3 as VarDefNode).vars)
+				SymbolTable.NewVarDef(v.Name, type.tint);
+			InDefSect = false;	
+		}
+		;
+
+varlist	: ident 
+		{ 
+			$$ = new VarDefNode($1 as IdNode); 
+		}
+		| varlist COLUMN ident 
+		{ 
+			($1 as VarDefNode).Add($3 as IdNode);
+			$$ = $1;
+		}
+		;
+	
+%%
+
diff --git a/Module8/SimpleLanguage3/Visitors/AssignCountVisitor.cs b/Module8/SimpleLanguage3/Visitors/AssignCountVisitor.cs
new file mode 100644
index 0000000..43d8554
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/AssignCountVisitor.cs
@@ -0,0 +1,23 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    class AssignCountVisitor : AutoVisitor
+    {
+        public int Count = 0;
+        public override void VisitAssignNode(AssignNode a)
+        {
+            Count += 1;
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+        }
+        public override void VisitVarDefNode(VarDefNode w)
+        { 
+        }
+    }
+}
diff --git a/Module8/SimpleLanguage3/Visitors/AutoVisitor.cs b/Module8/SimpleLanguage3/Visitors/AutoVisitor.cs
new file mode 100644
index 0000000..7c92bab
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/AutoVisitor.cs
@@ -0,0 +1,45 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    // базовая логика обхода без действий
+    // Если нужны действия или другая логика обхода, то соответствующие методы надо переопределять
+    // При переопределении методов для задания действий необходимо не забывать обходить подузлы
+    class AutoVisitor: Visitor
+    {
+        public override void VisitBinOpNode(BinOpNode binop) 
+        {
+            binop.Left.Visit(this);
+            binop.Right.Visit(this);
+        }
+        public override void VisitAssignNode(AssignNode a) 
+        {
+            // для каких-то визиторов порядок может быть обратный - вначале обойти выражение, потом - идентификатор
+            a.Id.Visit(this);
+            a.Expr.Visit(this);
+        }
+        public override void VisitCycleNode(CycleNode c) 
+        {
+            c.Expr.Visit(this);
+            c.Stat.Visit(this);
+        }
+        public override void VisitBlockNode(BlockNode bl) 
+        {
+            foreach (var st in bl.StList)
+                st.Visit(this);
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+            w.Expr.Visit(this);
+        }
+        public override void VisitVarDefNode(VarDefNode w) 
+        {
+            foreach (var v in w.vars)
+                v.Visit(this);
+        }
+    }
+}
diff --git a/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeCreator.cs b/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeCreator.cs
new file mode 100644
index 0000000..7353771
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeCreator.cs
@@ -0,0 +1,104 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection.Emit;
+using System.Reflection;
+
+namespace SimpleLang.Visitors
+{
+    class GenCodeCreator
+    {
+        private DynamicMethod dyn;
+        private ILGenerator gen;
+        private bool write_commands = true;
+        private static MethodInfo writeLineInt = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
+
+        public List<string> commands = new List<string>();
+
+        public GenCodeCreator()
+        {
+            dyn = new DynamicMethod("My", null, null, typeof(void));
+            gen = dyn.GetILGenerator();
+        }
+
+        public void Emit(OpCode op)
+        {
+            gen.Emit(op);
+            if (write_commands)
+                commands.Add(op.ToString());
+        }
+
+        public void Emit(OpCode op, int num)
+        {
+            gen.Emit(op,num);
+            if (write_commands)
+                commands.Add(op.ToString() + " " + num);
+        }
+
+        public void Emit(OpCode op, LocalBuilder lb)
+        {
+            gen.Emit(op, lb);
+            if (write_commands)
+                commands.Add(op.ToString() + " var" + lb.LocalIndex);
+        }
+
+        public void Emit(OpCode op, Label l)
+        {
+            gen.Emit(op, l);
+            if (write_commands)
+                commands.Add(op.ToString() + " Label" + l.GetHashCode());
+        }
+
+        public LocalBuilder DeclareLocal(Type t)
+        {
+            var lb = gen.DeclareLocal(t);
+            if (write_commands)
+                commands.Add("DeclareLocal " + "var" + lb.LocalIndex + ": " + t);
+            return lb;
+        }
+
+        public Label DefineLabel()
+        {
+            var l = gen.DefineLabel();
+            if (write_commands)
+                commands.Add("DefineLabel" + " Label" + l.GetHashCode());
+
+            return l;
+        }
+
+        public void MarkLabel(Label l)
+        {
+            gen.MarkLabel(l);
+            if (write_commands)
+                commands.Add("MarkLabel" + " Label" + l.GetHashCode());
+        }
+
+        public void EmitWriteLine()
+        {
+            gen.Emit(OpCodes.Call, writeLineInt);
+            if (write_commands)
+                commands.Add("WriteLine");
+        }
+
+        public void EndProgram()
+        {
+            gen.Emit(OpCodes.Ret);
+        }
+
+        public void RunProgram()
+        {
+            dyn.Invoke(null, null);
+        }
+
+        public void WriteCommandsOn()
+        {
+            write_commands = true;
+        }
+
+        public void WriteCommandsOff()
+        {
+            write_commands = false;
+        }
+    }
+}
diff --git a/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeVisitor.cs b/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeVisitor.cs
new file mode 100644
index 0000000..58959fa
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/GenCodeVisitors/GenCodeVisitor.cs
@@ -0,0 +1,113 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+using System.Reflection.Emit;
+
+namespace SimpleLang.Visitors
+{
+    class GenCodeVisitor: Visitor
+    {
+        private Dictionary<string, LocalBuilder> vars = new Dictionary<string, LocalBuilder>();
+        private GenCodeCreator genc;
+
+        public GenCodeVisitor()
+        {
+            genc = new GenCodeCreator();
+        }
+        public override void VisitIdNode(IdNode id) 
+        {
+            // Этот Visit не вызывается если переменная стоит слева от оператора присваивания !
+            // Т.е. он вызывается только если id находится в выражении, а значит, мы просто кладем его значение на стек!
+            genc.Emit(OpCodes.Ldloc, vars[id.Name]);
+        }
+        public override void VisitIntNumNode(IntNumNode num) 
+        {
+            genc.Emit(OpCodes.Ldc_I4, num.Num);
+        }
+        public override void VisitBinOpNode(BinOpNode binop) 
+        {
+            binop.Left.Visit(this);
+            binop.Right.Visit(this);
+            switch (binop.Op)
+            {
+                case '+':
+                    genc.Emit(OpCodes.Add);
+                    break;
+                case '-':
+                    genc.Emit(OpCodes.Sub);
+                    break;
+                case '*':
+                    genc.Emit(OpCodes.Mul);
+                    break;
+                case '/':
+                    genc.Emit(OpCodes.Div);
+                    break;
+            }
+        }
+        public override void VisitAssignNode(AssignNode a) 
+        {
+            a.Expr.Visit(this);
+            genc.Emit(OpCodes.Stloc, vars[a.Id.Name]);
+        }
+        public override void VisitCycleNode(CycleNode c) 
+        {
+            var i = genc.DeclareLocal(typeof(int)); // переменная цикла cycle
+            c.Expr.Visit(this); // сгенерировать команды, связанные с вычислением количества итераций цикла
+            genc.Emit(OpCodes.Stloc, i); // i := кво итераций
+
+            Label startLoop = genc.DefineLabel();
+            Label endLoop = genc.DefineLabel();
+            
+            genc.MarkLabel(startLoop);
+
+            genc.Emit(OpCodes.Ldloc, i); 
+            genc.Emit(OpCodes.Ldc_I4_0);
+            genc.Emit(OpCodes.Ble, endLoop); // if i<=0 then goto endLoop
+
+            c.Stat.Visit(this); // выполнить тело цикла
+
+            genc.Emit(OpCodes.Ldloc, i); // положить i на стек
+            genc.Emit(OpCodes.Ldc_I4_1); // положить 1 на стек
+            genc.Emit(OpCodes.Sub);
+            genc.Emit(OpCodes.Stloc, i); // i := i - 1;
+
+            genc.Emit(OpCodes.Br, startLoop);
+
+            genc.MarkLabel(endLoop);
+        }
+        public override void VisitBlockNode(BlockNode bl) 
+        {
+            foreach (var st in bl.StList)
+                st.Visit(this);
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+            w.Expr.Visit(this);
+            genc.EmitWriteLine();
+        }
+
+        public override void VisitVarDefNode(VarDefNode w) 
+        {
+            foreach (var v in w.vars)
+                vars[v.Name] = genc.DeclareLocal(typeof(int));
+        }
+
+        public void EndProgram()
+        {
+            genc.EndProgram();
+        }
+
+        public void RunProgram()
+        {
+            genc.RunProgram();
+        }
+
+        public void PrintCommands()
+        {
+            foreach (var s in genc.commands)
+                Console.WriteLine(s);
+        }
+    }
+}
diff --git a/Module8/SimpleLanguage3/Visitors/PrettyPrintVisitor.cs b/Module8/SimpleLanguage3/Visitors/PrettyPrintVisitor.cs
new file mode 100644
index 0000000..87892b1
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/PrettyPrintVisitor.cs
@@ -0,0 +1,88 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    class PrettyPrintVisitor: Visitor
+    {
+        public string Text = "";
+        private int Indent = 0;
+
+        private string IndentStr()
+        {
+            return new string(' ', Indent);
+        }
+        private void IndentPlus()
+        {
+            Indent += 2;
+        }
+        private void IndentMinus()
+        {
+            Indent -= 2;
+        }
+        public override void VisitIdNode(IdNode id) 
+        {
+            Text += id.Name;
+        }
+        public override void VisitIntNumNode(IntNumNode num) 
+        {
+            Text += num.Num.ToString();
+        }
+        public override void VisitBinOpNode(BinOpNode binop) 
+        {
+            Text += "(";
+            binop.Left.Visit(this);
+            Text += " " + binop.Op + " ";
+            binop.Right.Visit(this);
+            Text += ")";
+        }
+        public override void VisitAssignNode(AssignNode a) 
+        {
+            Text += IndentStr();
+            a.Id.Visit(this);
+            Text += " := ";
+            a.Expr.Visit(this);
+        }
+        public override void VisitCycleNode(CycleNode c) 
+        {
+            Text += IndentStr() + "cycle ";
+            c.Expr.Visit(this);
+            Text += Environment.NewLine;
+            c.Stat.Visit(this);
+        }
+        public override void VisitBlockNode(BlockNode bl) 
+        {
+            Text += IndentStr() + "begin" + Environment.NewLine;
+            IndentPlus();
+
+            var Count = bl.StList.Count;
+
+            if (Count>0)
+                bl.StList[0].Visit(this);
+            for (var i = 1; i < Count; i++)
+            {
+                Text += ';';
+                if (!(bl.StList[i] is EmptyNode))
+                    Text += Environment.NewLine;
+                bl.StList[i].Visit(this);
+            }
+            IndentMinus();
+            Text += Environment.NewLine + IndentStr() + "end";
+        }
+        public override void VisitWriteNode(WriteNode w) 
+        {
+            Text += IndentStr() + "write(";
+            w.Expr.Visit(this);
+            Text += ")";
+        }
+        public override void VisitVarDefNode(VarDefNode w) 
+        {
+            Text += IndentStr() + "var " + w.vars[0].Name;
+            for (int i = 1; i < w.vars.Count; i++)
+                Text += ',' + w.vars[i].Name;
+        }
+    }
+}
diff --git a/Module8/SimpleLanguage3/Visitors/Visitor.cs b/Module8/SimpleLanguage3/Visitors/Visitor.cs
new file mode 100644
index 0000000..b9dcae0
--- /dev/null
+++ b/Module8/SimpleLanguage3/Visitors/Visitor.cs
@@ -0,0 +1,21 @@
+п»їusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ProgramTree;
+
+namespace SimpleLang.Visitors
+{
+    public abstract class Visitor
+    {
+        public virtual void VisitIdNode(IdNode id) { }
+        public virtual void VisitIntNumNode(IntNumNode num) { }
+        public virtual void VisitBinOpNode(BinOpNode binop) { }
+        public virtual void VisitAssignNode(AssignNode a) { }
+        public virtual void VisitCycleNode(CycleNode c) { }
+        public virtual void VisitBlockNode(BlockNode bl) { }
+        public virtual void VisitWriteNode(WriteNode w) { }
+        public virtual void VisitVarDefNode(VarDefNode w) { }
+        public virtual void VisitEmptyNode(EmptyNode w) { }
+    }
+}
diff --git a/Module8/SimpleLanguage3/a.txt b/Module8/SimpleLanguage3/a.txt
new file mode 100644
index 0000000..14eeab4
--- /dev/null
+++ b/Module8/SimpleLanguage3/a.txt
@@ -0,0 +1,11 @@
+begin
+  var a,b,d;
+  b := 2;
+  a := 3;
+  a := a * 4 + b;;;
+  cycle 3
+  begin
+    a := a + 1;
+    write(a)
+  end
+end
diff --git a/Module8/SimpleLanguage3/generateParserScanner.bat b/Module8/SimpleLanguage3/generateParserScanner.bat
new file mode 100644
index 0000000..7ca5476
--- /dev/null
+++ b/Module8/SimpleLanguage3/generateParserScanner.bat
@@ -0,0 +1,3 @@
+cls
+gplex.exe /unicode SimpleLex.lex
+gppg.exe /no-lines /gplex SimpleYacc.y
-- 
GitLab