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