diff --git a/.gitignore b/.gitignore index 8a012047e..957ad7155 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,12 @@ **/PascalABCNETLinux.exe **/PascalABCNETLinux.exe.config +**/SPythonLanguageInfo.dll +**/SPythonParser.dll +**/SPythonParser.dll.config +**/SPythonStandardTreeConverter.dll +**/SPythonSyntaxTreeVisitor.dll + # external .dll files copied to bin /bin/AvalonDock.dll /bin/PT4Tools.dll diff --git a/CodeExamples/SPython/GraphWPF_use_example.pys b/CodeExamples/SPython/GraphWPF_use_example.pys new file mode 100644 index 000000000..fd9d70def --- /dev/null +++ b/CodeExamples/SPython/GraphWPF_use_example.pys @@ -0,0 +1,10 @@ +from GraphWPF import * + +color = RandomColor() + +def MouseMove(x: float, y: float, mb: int): + if mb == 1: + FillCircle(x, y, 10, color) + + +OnMouseMove = MouseMove diff --git a/CodeExamples/SPython/argmin.pys b/CodeExamples/SPython/argmin.pys new file mode 100644 index 000000000..eb142e0ae --- /dev/null +++ b/CodeExamples/SPython/argmin.pys @@ -0,0 +1,18 @@ +# индекс минимального элемента +def argmin(arr: list[int]) -> int: + if len(arr) == 0: + return -1 + res = 0 + for i in range(1, len(arr)): + if arr[i] < arr[res]: + res = i + return res + + + + +print(argmin([1, 2, 3])) +print(argmin([3, 2, 1])) +# a = [4,9,16,8,2,15,13,13,15,2,8,16,9,4] +a = [i ** 2 % 17 for i in range(2, 16)] +print(argmin([i ** 2 % 17 for i in range(2, 16)])) diff --git a/CodeExamples/SPython/compound_conditions_example.pys b/CodeExamples/SPython/compound_conditions_example.pys new file mode 100644 index 000000000..20332be55 --- /dev/null +++ b/CodeExamples/SPython/compound_conditions_example.pys @@ -0,0 +1,27 @@ +N = 7 + +# Выводит первые N чисел, +# которые можно тремя различными +# способами представить как +# сумму двух квадратов целых чисел +def print_sequence(N: int): + a = 0 + while True: + a += 1 + for b in range(1, a): + for c in range(1, b): + for d in range(1, c + 1): + for e in range(1, d): + for f in range(1, e): + if a ** 2 + f ** 2 == b ** 2 + e ** 2 == c ** 2 + d ** 2: + print(a ** 2 + f ** 2, '\t= ', + a, '^2 + ', f, '^2 \t= ', + b, '^2 + ', e, '^2 \t= ', + c, '^2 + ', d, '^2', sep='') + + N -= 1 + if N == 0: + return + + +print_sequence(N) \ No newline at end of file diff --git a/CodeExamples/SPython/delete_by_mouse.pys b/CodeExamples/SPython/delete_by_mouse.pys new file mode 100644 index 000000000..1bb6b6a05 --- /dev/null +++ b/CodeExamples/SPython/delete_by_mouse.pys @@ -0,0 +1,42 @@ +from WPFObjects import RectangleWPF, ObjectUnderPoint +from WPFObjects import Colors, Window, OnMouseDown +from PABCSystem import Random, Inc, Milliseconds + +CountSquares = 10 +StatusRect: RectangleWPF +CurrentDigit = 1 +Mistakes = 0 + +def DrawStatusText(): + if CurrentDigit <= CountSquares: + StatusRect.Text = ('Удалено квадратов: ' + str(CurrentDigit-1) + + '\tОшибок: ' + str(Mistakes)) + else: + StatusRect.Text = ('Игра окончена. Время: ' + str(Milliseconds // 1000) + + ' с.\tОшибок: ' + str(Mistakes)) + + +def MyMouseDown(x: float, y: float, mb: int): + ob = ObjectUnderPoint(x, y) + if ob is RectangleWPF and ob != StatusRect: + if ob.Number == CurrentDigit: + ob.Destroy() + Inc(CurrentDigit) + DrawStatusText() + else: + ob.Color = Colors.Red + Inc(Mistakes) + DrawStatusText() + + +Window.Title = 'Игра: удали все квадраты по порядку' +for i in range(1, CountSquares + 1): + x = Random(Window.Width - 50) + y = Random(Window.Height - 100) + ob = new RectangleWPF(x, y, 50, 50, Colors.LightGreen, 1) + ob.FontSize = 25 + ob.Number = i +StatusRect = new RectangleWPF(0, Window.Height - 40, + Window.Width, 40, Colors.LightBlue) +DrawStatusText() +OnMouseDown = MyMouseDown \ No newline at end of file diff --git a/CodeExamples/SPython/game_example.pys b/CodeExamples/SPython/game_example.pys new file mode 100644 index 000000000..12f30b832 --- /dev/null +++ b/CodeExamples/SPython/game_example.pys @@ -0,0 +1,26 @@ +import random as rnd + +hidden_number = rnd.randint(1, 100) +print('Угадай число от 1 до 100') +attempts = 0 +left_border = 1 +right_border = 100 +while True: + attempts += 1 + guess = int(input('Попытка ' + str(attempts) + ':')) + if guess < left_border or right_border < guess: + print('Число', guess, 'не из диапазона', + '[' + str(left_border) + ',', str(right_border) + ']') + continue + if guess < hidden_number: + left_border = guess + 1 + print('Загаданное число больше', guess); + elif guess > hidden_number: + right_border = guess - 1 + print('Загаданное число меньше', guess); + else: + print('Победа!!!') + break + print('Попробуй число от', left_border, + 'до', right_border) +print('Тебе понадобилось', attempts, 'попыток') \ No newline at end of file diff --git a/CodeExamples/SPython/in_out_example.pys b/CodeExamples/SPython/in_out_example.pys new file mode 100644 index 000000000..c5bf877f2 --- /dev/null +++ b/CodeExamples/SPython/in_out_example.pys @@ -0,0 +1,24 @@ +a = int(input('Введите первое число:')) +b = int(input('Введите второе число:')) + +def print_expressions(a: int, b: int): + print(a, ' +', b, '=', a + b, end = '\n') + print(a, ' -', b, '=', a - b, end = '\n') + print(a, ' *', b, '=', a * b, end = '\n') + print(a, ' %', b, '=', a % b, end = '\n') + print(a, ' /', b, '=', a / b, end = '\n') + print(a, '//', b, '=', a // b, end = '\n') + print(a, '**', b, '=', a ** b, end = '\n') + +print_expressions(a, b) + + +# Введите первое число: 10 +# Введите второе число: 6 +# 10 + 6 = 16 +# 10 - 6 = 4 +# 10 * 6 = 60 +# 10 % 6 = 4 +# 10 / 6 = 1.66666666666667 +# 10 // 6 = 1 +# 10 ** 6 = 1000000 diff --git a/CodeExamples/SPython/list_use_example.pys b/CodeExamples/SPython/list_use_example.pys new file mode 100644 index 000000000..a00806436 --- /dev/null +++ b/CodeExamples/SPython/list_use_example.pys @@ -0,0 +1,13 @@ +def print_matr(matr: list[list[int]]): + for row in matr: + for elem in row: + print(elem, '\t', end=' ') + print() + + +matrix_of_integers: list[list[int]] +matrix_of_integers = [ + [j * i for j in range(1, 10)] + for i in range(1, 10) if i % 2 == 0 + ] +print_matr(matrix_of_integers) \ No newline at end of file diff --git a/CodeExamples/SPython/new.pys b/CodeExamples/SPython/new.pys new file mode 100644 index 000000000..dcd45a73c --- /dev/null +++ b/CodeExamples/SPython/new.pys @@ -0,0 +1,9 @@ +a = [1, 2, 3] +a.append(4) +a.insert(4, 2) +b = a.copy() +b.reverse() +print(b) +print(a) +print(a.count(2)) +print(a.pop(1)) diff --git a/CodeExamples/SPython/random1.pys b/CodeExamples/SPython/random1.pys new file mode 100644 index 000000000..d7e159ad4 --- /dev/null +++ b/CodeExamples/SPython/random1.pys @@ -0,0 +1,8 @@ +#unit random +import PABCSystem + +def random() -> float: + return PABCSystem.random() + +def randint(a: int, b: int) -> int: + return PABCSystem.random(a, b) \ No newline at end of file diff --git a/CodeExamples/SPython/set_example.pys b/CodeExamples/SPython/set_example.pys new file mode 100644 index 000000000..575d1c54f --- /dev/null +++ b/CodeExamples/SPython/set_example.pys @@ -0,0 +1,11 @@ +from time import time + +s: set[int] = set() +t1 = time() + +for i in range(1, 10000): + s |= {i} + +t2 = time() +print(t2 - t1) +print(len(s)) \ No newline at end of file diff --git a/CodeExamples/SPython/time1.pas b/CodeExamples/SPython/time1.pas new file mode 100644 index 000000000..8731ff81f --- /dev/null +++ b/CodeExamples/SPython/time1.pas @@ -0,0 +1,15 @@ +unit time1; + +interface + +function time(): real; + +function forty_two(): real; + +implementation + +function time() : real := DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + +function forty_two() : real := 42; + +end. \ No newline at end of file diff --git a/CodeExamples/SPython/time_measurement_example.pas b/CodeExamples/SPython/time_measurement_example.pas new file mode 100644 index 000000000..ffe9bdad8 --- /dev/null +++ b/CodeExamples/SPython/time_measurement_example.pas @@ -0,0 +1,18 @@ +begin + var n := 60000; + var t1 := Milliseconds; + var sm := 0.0; + var i := 1.0; + while i < n do + begin + var j := 1.0; + while j < n do + begin + sm += 1.0 / i / j; + j += 1; + end; + i += 1; + end; + var t2 := Milliseconds; + print(t2 - t1); +end. \ No newline at end of file diff --git a/CodeExamples/SPython/time_measurement_example.pys b/CodeExamples/SPython/time_measurement_example.pys new file mode 100644 index 000000000..fe054776e --- /dev/null +++ b/CodeExamples/SPython/time_measurement_example.pys @@ -0,0 +1,16 @@ +import time + +n = 60000 +start = time.time() +sm: float = 0 + +i = 1.0 +while i < n: + j = 1.0 + while j < n: + sm += 1.0 / i / j + j += 1 + i += 1 + +end = time.time(); +print(end - start) \ No newline at end of file diff --git a/CodeExamples/SPython/unit_example.pys b/CodeExamples/SPython/unit_example.pys new file mode 100644 index 000000000..a70ba349b --- /dev/null +++ b/CodeExamples/SPython/unit_example.pys @@ -0,0 +1,18 @@ +# Рекурсивная функция вычисления факториала +def factorial(n: int)-> bigint: + if n == 0: + return 1 + return n * factorial(n - 1) + + +# Не рекурсивная функция вычисления числа Фибоначчи +def fibonacci(n: int)-> bigint: + if n <= 1: + return n + f1: bigint = 0 + f2: bigint = 1 + for i in range(n - 1): + t = f1 + f2 + f1 = f2 + f2 = t + return f2 diff --git a/CodeExamples/SPython/unit_use_example.pas b/CodeExamples/SPython/unit_use_example.pas new file mode 100644 index 000000000..fc31a373d --- /dev/null +++ b/CodeExamples/SPython/unit_use_example.pas @@ -0,0 +1,15 @@ +Uses unit_example; + +const N: integer = 10; + +begin + println('Последовательность чисел Фибоначчи:'); + for var i := 1 to N do + println('F(' + i + ')=', fibonacci(i)); + println(); + + println('Последовательность факториалов:'); + for var i := 1 to N do + println(i + '!=', factorial(i)); + println(); +end. diff --git a/CodeExamples/SPython/unit_use_example.pys b/CodeExamples/SPython/unit_use_example.pys new file mode 100644 index 000000000..87308e0eb --- /dev/null +++ b/CodeExamples/SPython/unit_use_example.pys @@ -0,0 +1,19 @@ +from unit_example import fibonacci as F, factorial as fact + +N = 10 + +fibs = [F(i) for i in range(1, N + 1)] +print("Последовательность чисел Фибоначчи:") +i = 0 +for fib_num in fibs: + i += 1 + print('F(' + str(i) + ')\t=', fib_num) +print() + +facts = [fact(i) for i in range(1, N + 1)] +print("Последовательность факториалов:") +i = 0 +for fact_num in facts: + i += 1 + print(str(i) + '!\t=', fact_num) +print() \ No newline at end of file diff --git a/LanguagePlugins/SPython/SPythonLanguageInfo/Properties/AssemblyInfo.cs b/LanguagePlugins/SPython/SPythonLanguageInfo/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a84c62787 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonLanguageInfo/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные со сборкой. +[assembly: AssemblyTitle("SPythonLanguage")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SPythonLanguage")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// COM, задайте атрибуту ComVisible значение TRUE для этого типа. +[assembly: ComVisible(false)] + +// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM +[assembly: Guid("dff88e9f-afb3-4986-84fe-77f8a04cb6f0")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Редакция +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguage.cs b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguage.cs new file mode 100644 index 000000000..239113ea5 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguage.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using Languages.Facade; +using PascalABCCompiler.SyntaxTreeConverters; +using PascalABCCompiler.SystemLibrary; +using PascalABCCompiler.TreeConverter; + +namespace Languages.SPython +{ + public class SPythonLanguage : BaseLanguage + { + public SPythonLanguage() : base( + name: "SPython", + version: "0.0.1", + copyright: "Copyright © 2023-2025 by Vladislav Krylov, Egor Movchan", + + languageInformation: new Frontend.Data.SPythonLanguageInformation(), + parser: new SPythonParser.SPythonLanguageParser(), + docParser: null, + + syntaxTreeConverters: new List() { new Frontend.Converters.StandardSyntaxTreeConverter(), new SyntaxSemanticVisitors.LambdaAnyConverter() }, + applySyntaxTreeConvertersForIntellisense: true, + + filesExtensions: new string[] { ".pys" }, + caseSensitive: true, + systemUnitNames: new string[] { "SPythonSystem", "SPythonHidden", "SPythonSystemPys" } + ) + { + ((SPythonParser.SPythonLanguageParser)Parser).SyntaxTreeConvertersForIntellisense = SyntaxTreeConverters; + } + + /// + /// TODO: требуется проверка и настройка работы EVA + /// + public override void SetSemanticConstants() + { + SemanticRulesConstants.ClassBaseType = SystemLibrary.object_type; + SemanticRulesConstants.StructBaseType = SystemLibrary.value_type; + SemanticRulesConstants.AddResultVariable = true; + SemanticRulesConstants.ZeroBasedStrings = true; + SemanticRulesConstants.FastStrings = false; + SemanticRulesConstants.InitStringAsEmptyString = true; + SemanticRulesConstants.UseDivisionAssignmentOperatorsForIntegerTypes = false; + SemanticRulesConstants.ManyVariablesOneInitializator = false; + SemanticRulesConstants.OrderIndependedMethodNames = true; + SemanticRulesConstants.OrderIndependedFunctionNames = false; + SemanticRulesConstants.OrderIndependedTypeNames = false; + SemanticRulesConstants.EnableExitProcedure = true; + SemanticRulesConstants.StrongPointersTypeCheckForDotNet = true; + SemanticRulesConstants.AllowChangeLoopVariable = false; + SemanticRulesConstants.AllowGlobalVisibilityForPABCDll = true; + SemanticRulesConstants.AllowMethodCallsWithoutParentheses = false; + } + + public override void SetSyntaxTreeToSemanticTreeConverter() + { + SyntaxTreeToSemanticTreeConverter = new SPythonSyntaxTreeVisitor.spython_syntax_tree_visitor(LanguageProvider.Instance.MainLanguage.SyntaxTreeToSemanticTreeConverter); + } + + } +} diff --git a/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInfo.csproj b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInfo.csproj new file mode 100644 index 000000000..d0e4f2111 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInfo.csproj @@ -0,0 +1,25 @@ + + + + net40 + + Languages.SPython + + ..\..\..\bin\ + false + + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs new file mode 100644 index 000000000..8e46912d8 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonLanguageInfo/SPythonLanguageInformation.cs @@ -0,0 +1,1669 @@ +using PascalABCCompiler.Parsers; +using PascalABCCompiler.ParserTools.Directives; +using PascalABCCompiler.SyntaxTree; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Languages.SPython.Frontend.Data +{ + internal class SPythonLanguageInformation : BaseLanguageInformation + { + public override BaseKeywords KeywordsStorage { get; } = new SPythonParser.SPythonKeywords(); + + public override Dictionary ValidDirectives { get; protected set; } + + public override string BodyStartBracket => null; + + public override string BodyEndBracket => null; + + public override string ParameterDelimiter => ","; + + public override string ResultVariableName => null; + + public override string ProcedureName => null; + + public override string FunctionName => "def"; + + public override string GenericTypesStartBracket => "["; + + public override string GenericTypesEndBracket => "]"; + + public override string ReturnTypeDelimiter => "->"; + + public override bool CaseSensitive => true; + + public override bool IncludeDotNetEntities => true; + + public override bool AddStandardUnitNamesToUserScope => false; + + public override bool AddStandardNetNamespacesToUserScope => false; + + public override bool UsesFunctionsOverlappingSourceContext => true; + + private readonly Dictionary renamings = new Dictionary + { + ["biginteger"] = "bigint" + }; + + private readonly HashSet exclutions = new HashSet + { + "__NewSetCreatorInternal" + }; + + private readonly Dictionary specialModulesAliases = new Dictionary + { + { "time", "time1" }, + { "random", "random1" }, + }; + + public override Dictionary SpecialModulesAliases => specialModulesAliases; + + public override void RenameOrExcludeSpecialNames(SymInfo[] symInfos) + { + for (var i = 0; i < symInfos.Length; i++) + { + if (symInfos[i] == null) + continue; + + if (renamings.TryGetValue(symInfos[i].name, out var newName)) + { + // копирование на всякий случай + symInfos[i] = new SymInfo(symInfos[i]); + symInfos[i].name = newName; + } + else if (exclutions.Contains(symInfos[i].name)) + { + symInfos[i] = new SymInfo(symInfos[i]); + symInfos[i].not_include = true; + } + } + } + + public override string ConstructHeader(string meth, IProcScope scope, int tabCount) + { + throw new NotImplementedException(); + } + + public override string ConstructHeader(IProcRealizationScope scope, int tabCount) + { + throw new NotImplementedException(); + } + + public override string ConstructOverridedMethodHeader(IProcScope scope, out int off) + { + throw new NotImplementedException(); + } + + public override string FindExpression(int off, string Text, int line, int col, out KeywordKind keyw) + { + int i = off - 1; + int bound = 0; + bool punkt_sym = false; + keyw = KeywordKind.None; + System.Text.StringBuilder sb = new StringBuilder(); + Stack tokens = new Stack(); + Stack kav = new Stack(); + Stack ugl_skobki = new Stack(); + int num_in_ident = -1; + keyw = TestForKeyword(Text, i); + if (keyw == KeywordKind.Punkt) return ""; + while (i >= bound) + { + bool end = false; + char ch = Text[i]; + if (kav.Count == 0 && (char.IsLetterOrDigit(ch) || ch == '_' || ch == '&' || ch == '\'' || ch == '!')) + { + num_in_ident = i; + if (kav.Count == 0 && tokens.Count == 0) + { + int tmp = i; + if (ch == '\'') + { + i--; + if (kav.Count == 0) + kav.Push('\''); + while (i >= 0) + { + if (Text[i] != '\'') + i--; + else + { + if (i >= 1 && Text[i - 1] == '\'') + i -= 2; + else + break; + } + } + + if (i >= 0) + i--; + } + else + while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!')) + { + i--; + } + while (i >= 0 && (Text[i] == ' ' || char.IsControl(Text[i]) || Text[i] == '}')) + { + if (Text[i] != '}') + i--; + else + { + while (i >= 0 && Text[i] != '{') //propusk kommentariev + i--; + if (i >= 0) + i--; + } + } + if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!')) + { + bound = i + 1; + TestForKeyword(Text, i, ref bound, punkt_sym, out keyw); + for (int j = tmp; j > bound; j--) + { + sb.Insert(0, Text[j]); + } + if (sb.ToString().Trim() == "new") + return ""; + i = bound; + continue; + } + else if (i >= 0 && Text[i] == '\'') return ""; + i = tmp; + } + else + if (ch == '\'') + kav.Push('\''); + sb.Insert(0, ch);//.Append(Text[i]); + } + else if (ch == '.' || ch == '^' || ch == '&' || ch == '?' && IsPunctuation(Text, i + 1)) + { + if (ch == '.' && i >= 1 && Text[i - 1] == '.' && tokens.Count == 0) + end = true; + else if (ch == '?' && i + 1 < Text.Length && Text[i + 1] != '.') + end = true; + else + sb.Insert(0, ch); + if (ch != '.') + punkt_sym = true; + } + else if (ch == '}') + { + if (kav.Count == 0) + { + while (i >= 0 && Text[i] != '{') + { + if (Text[i] != '$')//skip {$ + sb.Insert(0, Text[i]); + i--; + } + if (i < 0) + { + break; + } + else if (Text[i] == '{') + { + sb.Insert(0, '{'); + } + } + else + sb.Insert(0, ch); + } + else if (ch == '{') + { + if (kav.Count == 0) + { + if (keyw == KeywordKind.None) + return sb.ToString(); + sb.Insert(0, ch); + break; + } + else sb.Insert(0, ch); + } + else + switch (ch) + { + case ')': + case ']': + if (kav.Count == 0) + { + string tmps = sb.ToString().Trim(' ', '\r', '\t', '\n'); + if (tmps.Length >= 1 && (char.IsLetter(tmps[0]) || tmps[0] == '_' || tmps[0] == '&' || tmps[0] == '?' || tmps[0] == '!') && tokens.Count == 0) + end = true; + else + tokens.Push(ch); + } + if (!end) + { + sb.Insert(0, ch); + punkt_sym = true; + } + break; + case '>': + if (tokens.Count == 0) + { + int j = i + 1; + + while (j < Text.Length && char.IsWhiteSpace(Text[j])) + j++; + + if (ugl_skobki.Count > 0 || i == off - 1 || j == off && off == Text.Length || j < Text.Length && Text[i - 1] != '-' && (Text[j] == '.' || Text[j] == '(')) + { + ugl_skobki.Push('>'); + sb.Insert(0, ch); + } + else if (i >= 1 && Text[i - 1] == '-') + { + if (!(kav.Count == 0 && tokens.Count == 0)) + sb.Insert(0, ch); + } + else + end = true; + } + else + sb.Insert(0, ch); + break; + case '<': + if (tokens.Count == 0) + { + if (ugl_skobki.Count > 0) + { + ugl_skobki.Pop(); + sb.Insert(0, ch); + } + else + end = true; + } + else + sb.Insert(0, ch); + break; + case '[': + case '(': + case '|': + if (ch == '|' && ((tokens.Count == 0) || (tokens.Peek() == ']') || (tokens.Peek() == ')') || (tokens.Peek() == ','))) + // Закрывающий | - после него (tokens.Pop()) - пусто или ] ) , + { + if (kav.Count == 0) + { + string tmps = sb.ToString().Trim(' ', '\r', '\t', '\n'); + if (tmps.Length >= 1 && (char.IsLetter(tmps[0]) || tmps[0] == '_' || tmps[0] == '&' || tmps[0] == '?' || tmps[0] == '!') && tokens.Count == 0) + end = true; + else + tokens.Push(ch); + } + if (!end) + { + sb.Insert(0, ch); + punkt_sym = true; + } + } + else + { + if (kav.Count == 0) // в т.ч. открывающий | + { + if (tokens.Count > 0) + { + tokens.Pop(); + punkt_sym = true; + sb.Insert(0, ch); + if (ch == '(') + { + int tmp = i--; + /*while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&')) + { + i--; + }*/ + while (i >= 0 && (Text[i] == ' ' || char.IsControl(Text[i]) || Text[i] == '}')) + { + if (Text[i] != '}') + i--; + else + { + while (i >= 0 && Text[i] != '{') //propusk kommentariev + i--; + if (i >= 0) + i--; + } + } + if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!' || Text[i] == '?' && IsPunctuation(Text, i + 1))) + { + bound = i + 1; + TestForKeyword(Text, i, ref bound, punkt_sym, out keyw); + if (keyw != KeywordKind.None && tokens.Count == 0) + { + end = true; + } + else bound = 0; + } + else if (i >= 0 && Text[i] == '\'') return ""; + i = tmp; + } + } + else + { + end = true; + if (ch == '[') + { + keyw = KeywordKind.SquareBracket; + } + } + + } + else sb.Insert(0, ch); punkt_sym = true; + } + break; + case '\'': + if (kav.Count == 0) kav.Push(ch); else kav.Pop(); + sb.Insert(0, ch); + punkt_sym = true; break; + default: + if (!(ch == ' ' || char.IsControl(ch))) + { + if (kav.Count == 0) + { + if (ch == ',' && ugl_skobki.Count > 0) + sb.Insert(0, ch); + else + if (tokens.Count == 0) + end = true; + else + sb.Insert(0, ch); + } + else + sb.Insert(0, ch); + } + else + { + if (Text[i] == '\n') + { + bool one_line_comment = false; + int comment_position = -1; + if (CheckForComment(Text, i - 1, out comment_position, out one_line_comment)) + { + if (!one_line_comment) + end = true; + else + { + sb.Insert(0, ch); + i = comment_position; + } + + } + else + sb.Insert(0, ch); + } + else + sb.Insert(0, ch); + } + punkt_sym = true; + break; + } + + if (end) + { + bool one_line_comment = false; + int comment_position = -1; + if (CheckForComment(Text, i, out comment_position, out one_line_comment)) + { + int new_line_ind = sb.ToString().IndexOf('\n'); + if (new_line_ind != -1) sb = sb.Remove(0, new_line_ind + 1); + else sb = sb.Remove(0, sb.Length); + } + break; + } + i--; + } + + //return RemovePossibleKeywords(sb); + if (sb.Length > 0 && sb[sb.Length - 1] == '?') + sb.Remove(sb.Length - 1, 1); + + return sb.ToString().Trim(); + } + + private bool CheckForComment(string Text, int off, out int comment_position, out bool one_line_comment) + { + int i = off; + one_line_comment = false; + comment_position = -1; + Stack kav = new Stack(); + bool is_comm = false; + while (i >= 0 && !is_comm && Text[i] != '\n' && Text[i] != '\r') + { + if (Text[i] == '\'' || Text[i] == '"') + { + if (kav.Count == 0) kav.Push('\''); + else kav.Pop(); + } + else if (Text[i] == '{') + { + if (kav.Count == 0) + { + comment_position = i; + while (i >= 0 && Text[i] != '\'' && Text[i] != '"') + i--; + if (i >= 1 && Text[i - 1] == '$') + return false; + is_comm = true; + return is_comm; + } + } + else if (Text[i] == '}') + { + return false; + } + else if (Text[i] == '#') + if (kav.Count == 0) + { + is_comm = true; + one_line_comment = true; + comment_position = i - 1; + } + + i--; + } + return is_comm; + } + + public override string FindExpressionForMethod(int off, string Text, int line, int col, char pressed_key, ref int num_param) + { + int i = off - 1; + string pattern = null; + int bound = 0; + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + Stack tokens = new Stack(); + Stack kav = new Stack(); + Stack skobki = new Stack(); + Stack ugl_skobki = new Stack(); + bool comma_pressed = pressed_key == ','; + int num_in_ident = -1; + bool punkt_sym = false; + int next; + KeywordKind keyw = TestForKeyword(Text, i); + bool on_brace = false; + if (keyw == KeywordKind.Punkt) + return ""; + try + { + while (i >= bound) + { + bool end = false; + char ch = Text[i]; + if ((char.IsLetterOrDigit(ch) || ch == '_' || ch == '&' || ch == '!') && !isOperator(Text, i, out next)) + { + num_in_ident = i; + if (kav.Count == 0 && tokens.Count == 0) + { + int tmp = i; + while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!') && !isOperator(Text, i, out next)) + { + i--; + } + while (i >= 0 && (Text[i] == ' ' || char.IsControl(Text[i]) || Text[i] == '}')) + { + if (Text[i] != '}') + i--; + else + { + while (i >= 0 && Text[i] != '{') //propusk kommentariev + i--; + if (i >= 0) + i--; + } + } + if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!') && !isOperator(Text, i, out next)) + { + bound = i + 1; + TestForKeyword(Text, i, ref bound, punkt_sym, out keyw); + if (keyw == KeywordKind.New && comma_pressed) + bound = 0; + if (keyw == KeywordKind.Function || keyw == KeywordKind.Constructor || keyw == KeywordKind.Destructor) + return ""; + } + else if (i >= 0 && (Text[i] == '\'' || Text[i] == '"')) return ""; + i = tmp; + } + sb.Insert(0, ch);//.Append(Text[i]); + } + else if (ch == '.') sb.Insert(0, ch); + else if (ch == '}') + { + if (kav.Count == 0) + { + while (i >= 0 && Text[i] != '{') + { + sb.Insert(0, Text[i]); + i--; + } + if (i < 0) + { + break; + } + else if (Text[i] == '{') + { + sb.Insert(0, '{'); + } + } + else + sb.Insert(0, ch); + } + else if (ch == '{') + { + if (kav.Count == 0) + { + sb.Insert(0, ch); + break; + } + else sb.Insert(0, ch); + } + else + switch (ch) + { + case ')': + case ']': + case '>': + // Добавил это условие для питона EVA + if (pressed_key == '(' && ch == ')' && !sb.ToString().Contains(".") && tokens.Count == 0) + { + end = true; + break; + } + if (kav.Count == 0) + { + int j = i + 1; + + while (j < Text.Length && char.IsWhiteSpace(Text[j])) + j++; + if (ch != '>') + tokens.Push(ch); + if (ch == ')') + skobki.Push(ch); + if (tokens.Count > 0 || pressed_key == ',') + sb.Insert(0, ch); + else if (i == off - 1 || j == off && off == Text.Length || ugl_skobki.Count > 0 || j < Text.Length && Text[i - 1] != '-' && (Text[j] == '.' || Text[j] == '(')) + { + tokens.Push(ch); + ugl_skobki.Push(ch); + sb.Insert(0, ch); + } + else + end = true; + } + else + sb.Insert(0, ch); break; + case '[': + case '<': + case '(': + if (kav.Count == 0)//esli ne v kavychkah + { + if (ch == '(') + if (skobki.Count > 0) + skobki.Pop(); + else skobki.Push('('); + //esli byli zakryvaushie tokeny (polagaem, chto skobki korrektny, esli net, to parser v lubom sluchae ne proparsit + if (tokens.Count > 0) + { + if (ch != '<') + tokens.Pop(); + else if (ugl_skobki.Count > 0) + { + tokens.Pop(); + ugl_skobki.Pop(); + } + sb.Insert(0, ch);//dobavljaem k stroke + if (ch == '(') + { + int tmp = i--; + /*while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&')) + { + i--; + }*/ + while (i >= 0 && (Text[i] == ' ' || char.IsControl(Text[i]) || Text[i] == '}')) + { + if (Text[i] != '}') + { + i--; + } + else + { + while (i >= 0 && Text[i] != '{') + { + //propusk kommentariev + i--; + } + if (i >= 0) + i--; + } + } + + if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '!')) + { + bound = i + 1; + TestForKeyword(Text, i, ref bound, punkt_sym, out keyw); + if (keyw == KeywordKind.New) + bound = 0; + else + if (keyw != KeywordKind.None && tokens.Count == 0) + end = true; + else + bound = 0; + } + else if (i >= 0 && (Text[i] == '\'' || Text[i] == '"')) return ""; + i = tmp; + } + } + else if (ch == '<' || ch == '>') + { + if (tokens.Count > 0 || pressed_key == ',') + sb.Insert(0, ch); + else + end = true; + } + else + if (!comma_pressed) //esli my ne v parametrah + end = true; //zakonchili, tak kak doshli do pervoj skobki + else + { + sb.Remove(0, sb.Length);//doshli do skobki, byla nazhata zapjataja, poetomu udaljaem vse parametry + if (ch == '(') + on_brace = true; + //on_skobka = true; + comma_pressed = false; + } + } + else sb.Insert(0, ch); + break; + case '\'': + case '"': + if (kav.Count == 0) + kav.Push(ch); + else + kav.Pop(); + sb.Insert(0, ch); + if (kav.Count == 0 && tokens.Count == 0) + end = true; + break; + default: + if (!(ch == ' ' || char.IsControl(ch))) + { + if (ch == '^') + sb.Insert(0, ch); + else + if (kav.Count == 0)//ne v kavychkah + { + if (tokens.Count == 0) + { + if (ch != ',' && !comma_pressed) + end = true;//esli ne na zapjatoj i ne v parametrah, to finish + else if (ch == ',' && !comma_pressed) + end = true; + else if (ch == ',' && (pressed_key == '(' || pressed_key == '[')) + end = true; + else + { + sb.Insert(0, ch);//prodolzhaem + if (isOperator(Text, i, out next)) + { + i = next; + continue; + } + } + + } + else + sb.Insert(0, ch);//esli est skobki, prodolzhaem + if (!end && ch == ',') + { + if (tokens.Count == 0) + num_param++;//esli na zapjatoj, uvelichivaem nomer parametra + } + } + else + sb.Insert(0, ch);//prodolzhaem + + } + else + if (Text[i] == '\n') + { + bool one_line_comment = false; + int comment_position = -1; + if (CheckForComment(Text, i - 1, out comment_position, out one_line_comment)) //proverjaem, net li kommenta ne predydushej stroke + { + if (!one_line_comment) + end = true; + else + { + sb.Insert(0, ch); + i = comment_position; + } + + } + else + sb.Insert(0, ch);//a inache vyrazhenie na neskolkih strokah + } + else + sb.Insert(0, ch); + break; + } + + if (end) + { + if (comma_pressed && !on_brace) + return ""; + bool one_line_comment = false; + int comment_position = -1; + if (CheckForComment(Text, i, out comment_position, out one_line_comment))//proverka na kommentarii + { + int new_line_ind = sb.ToString().IndexOf('\n'); + if (new_line_ind != -1) sb = sb.Remove(0, new_line_ind + 1); + else sb = sb.Remove(0, sb.Length); + } + break; + } + i--; + } + if (pressed_key == ',') + num_param++; + } + catch (Exception e) + { + + } + if (pressed_key == ',' && (!on_brace || skobki.Count == 0)) + return ""; + //return RemovePossibleKeywords(sb); + return sb.ToString().Trim(); + } + + private bool isOperator(string Text, int i, out int next) + { + next = i; + if (i >= 3) + { + string op = Text.Substring(i - 2, 3).ToLower().Trim(); + if (op == "and" || op == "div" || op == "mod" || op == "xor") + { + if (!char.IsLetterOrDigit(Text[i - 3]) && Text[i - 3] != '_' && Text[i - 3] != '&' && !(i + 1 < Text.Length && char.IsLetterOrDigit(Text[i + 1]))) + { + next = i - 3; + return true; + } + return false; + } + } + if (i >= 2) + { + string op = Text.Substring(i - 1, 2).ToLower().Trim(); + if (op == "or") + { + if (!char.IsLetterOrDigit(Text[i - 2]) && Text[i - 2] != '_' && Text[i - 2] != '&' && !(i + 1 < Text.Length && char.IsLetterOrDigit(Text[i + 1]))) + { + next = i - 2; + return true; + } + return false; + } + } + return false; + } + + public override string FindExpressionFromAnyPosition(int off, string Text, int line, int col, out string expr_without_brackets) + { + int i = off - 1; + + // это например вызов метода без параметров + expr_without_brackets = null; + var keyw = KeywordKind.None; + if (i < 0) + return ""; + bool is_char = false; + + // идем в обе стороны от off + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + if (Text[i] != ' ' && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1) || Text[i] == '!')) + { + //sb.Remove(0,sb.Length); + while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1) || Text[i] == '!')) + { + //sb.Insert(0,Text[i]);//.Append(Text[i]); + i--; + } + is_char = true; + } + i = off; + if (i < Text.Length && Text[i] != ' ' && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1) || Text[i] == '!')) + { + while (i < Text.Length && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '!')) + { + //sb.Append(Text[i]);//.Append(Text[i]); + i++; + } + is_char = true; + } + if (is_char) + { + expr_without_brackets = FindExpression(i, Text, line, col, out keyw); + } + bool is_new = keyw == KeywordKind.New; + bool meth_call = false; + KeywordKind new_keyw = KeywordKind.None; + int j = i; + bool in_comment = false; + bool brackets = false; + while (j < Text.Length) + { + char c = Text[j]; + + if (c == '(' && !in_comment) + { + Stack sk_stack = new Stack(); + in_comment = false; + bool in_kav = false; + sk_stack.Push('('); + j++; + while (j < Text.Length) + { + c = Text[j]; + if (c == '(' && !in_kav) + sk_stack.Push('('); + else + if (c == ')' && !in_kav) + { + if (sk_stack.Count == 0) + { + break; + } + else + { + sk_stack.Pop(); + if (sk_stack.Count == 0) + { + i = j + 1; + meth_call = true; + break; + } + } + } + else if ((c == '\'' || c == '"') && !in_comment) + { + in_kav = !in_kav; + } + else if (c == '{' && !in_kav) + { + in_comment = true; + } + else if (c == '}' && !in_kav) + { + in_comment = false; + } + else if (c == '#' && !in_kav && !in_comment) + { + break; + } + j++; + } + break; + } + else if ((c == '<' || c == '&' && j < Text.Length - 1 && Text[j + 1] == '<') && !in_comment) + { + Stack sk_stack = new Stack(); + if (c == '&') + j++; + sk_stack.Push('<'); + j++; + bool generic = false; + while (j < Text.Length) + { + c = Text[j]; + if (c == '>') + { + sk_stack.Pop(); + if (sk_stack.Count == 0) + { + i = j + 1; + generic = true; + break; + } + } + else if (c == '<') + { + sk_stack.Push('<'); + + } + else if (!char.IsLetterOrDigit(c) && c != '?' && c != '&' && c != '.' && c != ' ' && c != '\t' && c != '\n' && c != ',' && c != '!') + { + break; + } + j++; + } + if (generic) + { + //break; + } + } + else if (c == '[' && !in_comment) + { + brackets = true; + break; + } + else if (c == '{') + { + in_comment = true; + } + else if (c == '}') + { + if (!in_comment) + break; + else + in_comment = false; + } + else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') + { + + } + else + { + if (!in_comment) + break; + } + j++; + } + if (is_new && string.Compare(expr_without_brackets.Trim(' ', '\n', '\t', '\r'), "new", true) == 0 && !meth_call) + { + expr_without_brackets = null; + return null; + } + if (is_char) + { + string ss = FindExpression(i, Text, line, col, out new_keyw); + if (brackets && is_new) + { + int ind = ss.ToLower().IndexOf("new"); + if (ind != -1) + return ss.Substring(ind + 3); + } + if (is_new && ss != null && ss.IndexOf("new") == -1 && ss.IndexOf(":") != -1) + return expr_without_brackets + "(true?" + ss; + return ss; + } + return null; + } + + // TODO: Реализовать EVA + public override string GetArrayDescription(string elementType, int rank) + { + return ""; + } + + public override string GetClassKeyword(class_keyword keyw) + { + switch (keyw) + { + case class_keyword.Class: return "class"; + case class_keyword.TemplateClass: return "template class"; + } + return null; + } + + // TODO: Реализовать EVA + public override string GetCompiledTypeRepresentation(Type t, MemberInfo mi, ref int line, ref int col) + { + return ""; + } + + public override string GetDescription(IBaseScope scope) + { + switch (scope.Kind) + { + case ScopeKind.Type: return GetDescriptionForType(scope as ITypeScope); + case ScopeKind.CompiledType: return GetDescriptionForCompiledType(scope as ICompiledTypeScope); + case ScopeKind.Procedure: return GetDescriptionForProcedure(scope as IProcScope); + case ScopeKind.ElementScope: return GetDescriptionForElementScope(scope as IElementScope); + case ScopeKind.TypeSynonim: return GetSynonimDescription(scope as ITypeSynonimScope); + case ScopeKind.Namespace: return GetDescriptionForNamespace(scope as INamespaceScope); + case ScopeKind.CompiledMethod: return GetDescriptionForCompiledMethod(scope as ICompiledMethodScope); + + /*case ScopeKind.Array: return GetDescriptionForArray(scope as IArrayScope); + case ScopeKind.Enum: return GetDescriptionForEnum(scope as IEnumScope); + case ScopeKind.Set: return GetDescriptionForSet(scope as ISetScope); + + case ScopeKind.CompiledField: return GetDescriptionForCompiledField(scope as ICompiledFieldScope); + case ScopeKind.CompiledProperty: return GetDescriptionForCompiledProperty(scope as ICompiledPropertyScope); + + + case ScopeKind.CompiledConstructor: return GetDescriptionForCompiledConstructor(scope as ICompiledConstructorScope);*/ + } + return ""; + } + + protected string GetDescriptionForProcedure(IProcScope scope) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + string extensionType = null; + if (scope.IsExtension && scope.Parameters.Length > 0) + { + extensionType = GetSimpleDescription(scope.Parameters[0].Type); + } + if (scope.IsExtension) + { + if (extensionType != null && extensionType.IndexOf(' ') != -1) + { + sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + " " + extensionType + ") "); + extensionType = null; + } + else + { + sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + ") "); + } + } + + if (scope.IsStatic) sb.Append("static "); + if (scope.IsConstructor()) + sb.Append("constructor "); + else + sb.Append("def "); + /*if (scope.ReturnType == null) + sb.Append("procedure "); + else + sb.Append("function ");*/ + if (!scope.IsConstructor()) + { + if (extensionType != null) + { + sb.Append(extensionType + "."); + sb.Append(scope.Name); + } + else + { + sb.Append(GetTopScopeName(scope.TopScope)); + sb.Append(scope.Name); + } + } + else + { + sb.Append(GetTopScopeNameWithoutDot(scope.TopScope)); + } + + sb.Append(GetGenericString(scope.TemplateParameters)); + sb.Append('('); + IElementScope[] parameters = scope.Parameters; + for (int i = 0; i < parameters.Length; i++) + { + if (scope.IsExtension && i == 0) + continue; + sb.Append(GetSimpleDescription(parameters[i])); + if (i < parameters.Length - 1) + { + sb.Append("; "); + } + } + sb.Append(')'); + if (scope.ReturnType != null && !scope.IsConstructor() && !(scope.ReturnType is IProcType && (scope.ReturnType as IProcType).Target == scope)) + sb.Append(" " + ReturnTypeDelimiter + " " + GetSimpleDescription(scope.ReturnType)); + //if (scope.IsStatic) sb.Append("; static"); + if (scope.IsVirtual) sb.Append("; "); + else if (scope.IsAbstract) sb.Append("; abstract"); + else if (scope.IsOverride) sb.Append("; override"); + else if (scope.IsReintroduce) sb.Append("; reintroduce"); + sb.Append(';'); + return sb.ToString(); + } + + protected string GetDescriptionForElementScope(IElementScope scope) + { + string type_name = null; + StringBuilder sb = new StringBuilder(); + if (scope.Type == null) type_name = ""; + else + type_name = GetSimpleDescription(scope.Type); + if (type_name.StartsWith("$")) + type_name = type_name.Substring(1, type_name.Length - 1); + switch (scope.ElemKind) + { + case SymbolKind.Variable: sb.Append("var " + GetTopScopeName(scope.TopScope) + scope.Name + ((type_name != "") ? ": " + type_name : "")); break; + case SymbolKind.Parameter: sb.Append(kind_of_param(scope) + "parameter " + scope.Name + ": " + type_name + (scope.ConstantValue != null ? (":=" + scope.ConstantValue.ToString()) : "")); break; + case SymbolKind.Field: + if (scope.IsStatic) + sb.Append("static "); + else + sb.Append("var "); + sb.Append(GetTopScopeName(scope.TopScope) + scope.Name + ": " + type_name); + // append_modifiers(sb, scope); + //if (scope.IsStatic) sb.Append("; static"); + if (scope.IsReadOnly) sb.Append("; readonly"); + break; + + } + sb.Append(';'); + return sb.ToString(); + } + + protected override string kind_of_param(IElementScope scope) + { + switch (scope.ParamKind) + { + case PascalABCCompiler.SyntaxTree.parametr_kind.const_parametr: return "const "; + case PascalABCCompiler.SyntaxTree.parametr_kind.var_parametr: return "var "; + case PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr: return "params "; + case PascalABCCompiler.SyntaxTree.parametr_kind.out_parametr: return "out "; + } + return ""; + } + + protected override string GetFullTypeName(Type ctn, bool no_alias = true) + { + TypeCode tc = Type.GetTypeCode(ctn); + if (ctn.FullName == null && !ctn.IsArray && !ctn.IsGenericTypeDefinition && ctn.IsGenericParameter) + return ctn.Name; + if (!ctn.IsEnum) + { + switch (tc) + { + case TypeCode.Int32: return "int"; + case TypeCode.Double: return "float"; + case TypeCode.Boolean: return "bool"; + case TypeCode.String: return "str"; + case TypeCode.Char: return "char"; + } + /*if (ctn.IsPointer) + if (ctn.FullName == "System.Void*") + return "pointer"; + else + return "^" + GetFullTypeName(ctn.GetElementType());*/ + } + else + return ctn.FullName; + if (!no_alias) + { + if (ctn.Name.Contains("Func`") || ctn.Name.Contains("Predicate`")) + return getLambdaRepresentation(ctn, true, new List()); + else if (ctn.Name.Contains("Action`")) + return getLambdaRepresentation(ctn, false, new List()); + else if (ctn.Name == "IEnumerable`1") + return "sequence of " + GetShortTypeName(ctn.GetGenericArguments()[0], false); + else if (ctn.Name.Contains("Tuple`")) + return get_tuple_string(ctn); + } + int gen_pos = ctn.Name.IndexOf("`"); + if (gen_pos != -1 || ctn.IsGenericType) + { + int len = ctn.GetGenericArguments().Length; + Type[] gen_ps = ctn.GetGenericArguments(); + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + if (gen_pos != -1) + sb.Append(ctn.Namespace + "." + ctn.Name.Substring(0, gen_pos)); + else + sb.Append(ctn.Namespace + "." + ctn.Name); + sb.Append(GenericTypesStartBracket); + for (int i = 0; i < len; i++) + { + sb.Append(gen_ps[i].Name); + if (i < len - 1) + sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + return sb.ToString(); + } + if (ctn.IsArray) + { + var rank = ctn.GetArrayRank(); + var strrank = rank > 1 ? "[" + new string(',', rank - 1) + "]" : ""; + return $"array{strrank}" + " of " + GetFullTypeName(ctn.GetElementType()); + } + if (ctn == Type.GetType("System.Void*")) return "pointer"; + if (ctn.IsNested) + return ctn.Name; + return ctn.FullName; + } + + public override string GetKeyword(SymbolKind kind) + { + switch (kind) + { + case SymbolKind.Class: return "class"; + case SymbolKind.Enum: return "enum"; + case SymbolKind.Null: return "None"; + } + return ""; + } + + public override string GetShortName(ICompiledConstructorScope scope) + { + return "create"; + } + + public override string GetShortTypeName(Type ctn, bool noalias = true) + { + TypeCode tc = Type.GetTypeCode(ctn); + if (ctn.FullName == null && !ctn.IsArray && !ctn.IsGenericTypeDefinition && ctn.IsGenericParameter) + return ctn.Name; + if (!ctn.IsEnum) + { + switch (tc) + { + case TypeCode.Int32: return "int"; + case TypeCode.Double: return "float"; + case TypeCode.Boolean: return "bool"; + case TypeCode.String: return "str"; + case TypeCode.Char: return "char"; + } + /*if (ctn.IsPointer) + if (ctn.FullName == "System.Void*") + return "pointer"; + else + return "^" + GetShortTypeName(ctn.GetElementType(), noalias);*/ + } + else return ctn.Name; + if (ctn.Name.Contains("`")) + { + if (!noalias) + { + if (ctn.Name.Contains("Func`") || ctn.Name.Contains("Predicate`")) + return getLambdaRepresentation(ctn, true, new List()); + else if (ctn.Name.Contains("Action`")) + return getLambdaRepresentation(ctn, false, new List()); + else if (ctn.Name == "IEnumerable`1") + return "sequence of " + GetShortTypeName(ctn.GetGenericArguments()[0], false); + else if (ctn.Name.Contains("Tuple`")) + return get_tuple_string(ctn); + } + int len = ctn.GetGenericArguments().Length; + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append(ctn.Name.Substring(0, ctn.Name.IndexOf('`'))); + sb.Append('['); + if (!noalias) + { + Type[] gen_ps = ctn.GetGenericArguments(); + for (int i = 0; i < len; i++) + { + sb.Append(gen_ps[i].Name); + if (i < len - 1) + sb.Append(", "); + } + } + sb.Append(']'); + return sb.ToString(); + } + if (ctn.IsArray) + { + var rank = ctn.GetArrayRank(); + var strrank = rank > 1 ? "[" + new string(',', rank - 1) + "]" : ""; + return $"array{strrank}" + " of " + GetShortTypeName(ctn.GetElementType()); + } + //if (ctn == Type.GetType("System.Void*")) return PascalABCCompiler.StringConstants.pointer_type_name; + return ctn.Name; + } + + public override string GetSimpleDescription(IBaseScope scope) + { + if (scope == null) + return ""; + switch (scope.Kind) + { + case ScopeKind.Array: + case ScopeKind.Enum: + case ScopeKind.Set: + if (scope is ITypeScope && (scope as ITypeScope).Aliased) + return scope.Name; + break; + case ScopeKind.TypeSynonim: + case ScopeKind.Type: + if (scope.Name == "biginteger") + return "bigint"; + break; + } + switch (scope.Kind) + { + case ScopeKind.Type: return GetSimpleDescriptionForType(scope as ITypeScope); + case ScopeKind.CompiledType: return GetSimpleDescriptionForCompiledType(scope as ICompiledTypeScope, false); + case ScopeKind.Procedure: return GetSimpleDescriptionForProcedure(scope as IProcScope); + case ScopeKind.ElementScope: return GetSimpleDescriptionForElementScope(scope as IElementScope); + case ScopeKind.TypeSynonim: return GetSimpleSynonimDescription(scope as ITypeSynonimScope); + case ScopeKind.Array: return GetDescriptionForArray(scope as IArrayScope); + case ScopeKind.UnitInterface: return GetDescriptionForModule(scope as IInterfaceUnitScope); + case ScopeKind.Namespace: return GetDescriptionForNamespace(scope as INamespaceScope); + case ScopeKind.CompiledMethod: return GetDescriptionForCompiledMethod(scope as ICompiledMethodScope); + + /*case ScopeKind.Enum: return GetDescriptionForEnum(scope as IEnumScope); + case ScopeKind.Set: return GetDescriptionForSet(scope as ISetScope); + + case ScopeKind.CompiledField: return GetDescriptionForCompiledField(scope as ICompiledFieldScope); + case ScopeKind.CompiledProperty: return GetDescriptionForCompiledProperty(scope as ICompiledPropertyScope); + + + case ScopeKind.CompiledConstructor: return GetDescriptionForCompiledConstructor(scope as ICompiledConstructorScope);*/ + } + return ""; + } + + private string GetDescriptionForModule(IInterfaceUnitScope scope) + { + var p = specialModulesAliases.FirstOrDefault(kv => kv.Value == scope.Name); + + if (!p.Equals(default(KeyValuePair))) + return "unit " + p.Key; + + return "unit " + scope.Name; + } + + private string GetDescriptionForNamespace(INamespaceScope scope) + { + return "namespace " + scope.Name; + } + + private string GetSimpleSynonimDescription(ITypeSynonimScope scope) + { + return scope.Name; + } + + protected string GetDescriptionForArray(IArrayScope scope) + { + StringBuilder sb = new StringBuilder(); + sb.Append("array"); + ITypeScope[] inds = scope.Indexers; + if (!scope.IsDynamic) + { + sb.Append('['); + for (int i = 0; i < inds.Length; i++) + { + sb.Append(GetSimpleDescription(inds[i])); + if (i < inds.Length - 1) sb.Append(','); + } + sb.Append(']'); + } + if (scope.ElementType != null) + { + string s = GetSimpleDescription(scope.ElementType); + if (s.Length > 0 && s[0] == '$') s = s.Substring(1, s.Length - 1); + sb.Append(" of " + s); + } + return sb.ToString(); + } + + private string GetSimpleDescriptionForCompiledType(ICompiledTypeScope scope, bool fullName) + { + if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Func`")) + { + return getLambdaRepresentation(scope, true); + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Action`")) + { + return getLambdaRepresentation(scope, false); + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Predicate`1")) + { + return getLambdaRepresentation(scope, false); + } + if (scope.CompiledType.Name == "IEnumerable`1") + { + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + return "sequence of " + GetSimpleDescriptionWithoutNamespace(instances[0]); + } + else + return "sequence of T"; + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Tuple`")) + { + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + return get_tuple_string(instances); + } + else + return "(T1,...)"; + } + else + { + string s = !fullName ? GetShortTypeName(scope.CompiledType) : GetFullTypeName(scope.CompiledType); + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + int ind = s.IndexOf(GenericTypesStartBracket); + if (ind != -1) sb.Append(s.Substring(0, ind)); + else + sb.Append(s); + sb.Append(GenericTypesStartBracket); + for (int i = 0; i < instances.Length; i++) + { + sb.Append(GetSimpleDescriptionWithoutNamespace(instances[i])); + if (i < instances.Length - 1) sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + s = sb.ToString(); + } + return s; + } + } + + public override string GetStandardTypeByKeyword(KeywordKind keyw) + { + switch (keyw) + { + case KeywordKind.IntType: return "int"; + case KeywordKind.DoubleType: return "float"; + case KeywordKind.CharType: return "char"; + case KeywordKind.BoolType: return "bool"; + case KeywordKind.StringType: return "str"; + } + return null; + } + + public override string GetStringForChar(char c) + { + return "'" + c.ToString() + "'"; + } + + public override string GetStringForSharpChar(int num) + { + return "#" + num.ToString(); + } + + public override string GetStringForString(string s) + { + return "'" + s + "'"; + } + + public override string GetSynonimDescription(ITypeScope scope) + { + return "type " + scope.Name + GetGenericString(scope.TemplateArguments) + " = " + scope.Description; + } + + public override string GetSynonimDescription(ITypeSynonimScope scope) + { + if (scope.ActType is ICompiledTypeScope && !(scope.ActType as ICompiledTypeScope).Aliased) + return "type " + scope.Name + GetGenericString(scope.TemplateArguments) + " = " + GetSimpleDescriptionForCompiledType(scope.ActType as ICompiledTypeScope, true); + else + return "type " + scope.Name + GetGenericString(scope.TemplateArguments) + " = " + GetSimpleDescription(scope.ActType); + } + + public override string GetSynonimDescription(IProcScope scope) + { + return "type " + scope.Name + " = " + scope.Description; + } + + public override bool IsDefinitionIdentifierAfterKeyword(KeywordKind keyw) + { + if (keyw == KeywordKind.Function || keyw == KeywordKind.Constructor || keyw == KeywordKind.Punkt) + return true; + return false; + } + + public override bool IsMethodCallParameterSeparator(char key) + { + return key == ','; + } + + public override bool IsTypeAfterKeyword(KeywordKind keyw) + { + if (keyw == KeywordKind.Colon) + return true; + return false; + } + + public override KeywordKind TestForKeyword(string Text, int i) + { + StringBuilder sb = new StringBuilder(); + int orig_i = i; + int j = i; + bool in_keyw = false; + while (j >= 0 && Text[j] != '\n') + j--; + Stack kav_stack = new Stack(); + j++; + bool in_format_str = false; + while (j <= i) + { + if (Text[j] == '\'' || Text[j] == '"') + { + if (kav_stack.Count == 0 && !in_keyw) + { + if (j == 0 || Text[j - 1] != '$') + kav_stack.Push('\''); + else + { + in_keyw = false; + in_format_str = true; + } + + } + else if (kav_stack.Count > 0) + kav_stack.Pop(); + } + else if (Text[j] == '{' && kav_stack.Count == 0 && !in_format_str) + in_keyw = true; + else + if (Text[j] == '}') + in_keyw = false; + j++; + } + j = i; + if ((kav_stack.Count != 0 || in_keyw) && !in_format_str) return PascalABCCompiler.Parsers.KeywordKind.Punkt; + if (j >= 0 && Text[j] == '.') return PascalABCCompiler.Parsers.KeywordKind.Punkt; + while (j >= 0) + { + //if (Text[j] == '{') return PascalABCCompiler.Parsers.KeywordKind.Punkt; + if (!in_keyw && (Text[j] == '\'' || Text[j] == '"' || Text[j] == '\n')) + break; + if (Text[j] == '}') + in_keyw = true; + else + if (Text[j] == '#' && !in_keyw) + return PascalABCCompiler.Parsers.KeywordKind.Punkt; + j--; + } + //if (j>= 0 && Text[j] == '\'') return CodeCompletion.KeywordKind.kw_punkt; + while (i >= 0 && (Text[i] == ' ' || char.IsControl(Text[i]))) i--; + if (i >= 0 && Text[i] == ':') return PascalABCCompiler.Parsers.KeywordKind.Colon; + + if (i >= 0 && Text[i] == ',') + { + + while (i >= 0 && Text[i] != '\n') + { + if (char.IsLetterOrDigit(Text[i])) + sb.Insert(0, Text[i]); + else + { + PascalABCCompiler.Parsers.KeywordKind keyw = GetKeywordKind(sb.ToString()); + if (keyw == PascalABCCompiler.Parsers.KeywordKind.Uses) + return PascalABCCompiler.Parsers.KeywordKind.Uses; + else if (keyw == PascalABCCompiler.Parsers.KeywordKind.Var) + return PascalABCCompiler.Parsers.KeywordKind.Var; + else sb.Remove(0, sb.Length); + } + i--; + } + } + else + while (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '!')) + { + sb.Insert(0, Text[i]); + i--; + } + string s = sb.ToString().ToLower(); + + return GetKeywordKind(s); + } + + private string GetDescriptionForType(ITypeScope scope) + { + string template_str = GetTemplateString(scope); + switch (scope.ElemKind) + { + case SymbolKind.Class: + string mod = ""; + if (scope.IsStatic) + mod = "static "; + + if (scope.TopScope != null && scope.TopScope.Name != "" && !scope.TopScope.Name.Contains("$")) + return mod + "class " + scope.TopScope.Name + "." + scope.Name + template_str; + else return mod + "class " + scope.Name + template_str; + + case SymbolKind.Enum: + if (scope.TopScope != null && scope.TopScope.Name != "" && !scope.TopScope.Name.Contains("$")) + return "enum " + scope.TopScope.Name + "." + scope.Name; + else return "enum " + scope.Name; + } + + if (scope.TopScope != null) + return scope.TopScope.Name + "." + scope.Name; + else return scope.Name; + } + + private string GetDescriptionForCompiledType(ICompiledTypeScope scope) + { + string s = GetFullTypeName(scope.CompiledType); + ITypeScope[] instances = scope.GenericInstances; + if (instances.Length > 0) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + int ind = s.IndexOf(GenericTypesStartBracket); + if (ind != -1) sb.Append(s.Substring(0, ind)); + else + sb.Append(s); + sb.Append(GenericTypesStartBracket); + for (int i = 0; i < instances.Length; i++) + { + sb.Append(GetSimpleDescriptionWithoutNamespace(instances[i])); + //sb.Append(instances[i].Name); + if (i < instances.Length - 1) sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + s = sb.ToString(); + } + + switch (scope.ElemKind) + { + case SymbolKind.Class: + string mod = ""; + if (scope.IsStatic) + mod = "static "; + else + { + if (scope.IsAbstract) + mod = "abstract "; + if (scope.IsFinal) + mod += "sealed "; + } + return mod + "class " + s; + case SymbolKind.Interface: + return "interface " + s; + case SymbolKind.Enum: + return "enum " + s; + case SymbolKind.Delegate: + return "delegate " + s; + case SymbolKind.Struct: + return "record " + s; + case SymbolKind.Type: + return "type " + s; + } + return s; + } + } +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Errors.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Errors.cs new file mode 100644 index 000000000..96b3a4941 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Errors.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using PascalABCCompiler.Errors; +using PascalABCCompiler.SyntaxTree; + +namespace SPythonParser +{ + public class SPythonUnexpectedToken : SyntaxError + { + private string _message; + private string _expected; + public SPythonUnexpectedToken(string _file_name, string expected, SourceContext _source_context, syntax_tree_node _node) + : base("", _file_name, _source_context, _node) + { + _message = string.Format(StringResources.Get("EXPECTED{0}"), expected); + _expected = expected; + } + + public override string Message + { + get + { + return _message; + } + } + + public string Expected + { + get + { + return _expected; + } + set + { + _expected = value; + _message = string.Format(StringResources.Get("EXPECTED{0}"), _expected); + } + } + } +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/IndentArranger.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/IndentArranger.cs new file mode 100644 index 000000000..541de0bb3 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/IndentArranger.cs @@ -0,0 +1,238 @@ +using System; +using System.Linq; +using System.IO; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using SyntaxVisitors; +using PascalABCCompiler.SyntaxTree; + +namespace SPythonParser +{ + public class IndentArranger + { + private int lineCounter = -1; + + // количество пробелов соответствующее одному \t (в одном отступе) + private const int indentSpaceNumber = 4; + private const string indentToken = "#{"; + private const string unindentToken = "#}"; + private const string badIndentToken = "#!"; + private const string programBeginWithIndentToken = "#b"; + private const string endOfLineToken = "#;"; + private const string endOfFIleToken = "#$"; + public const string createdFileNameAddition = "_processed"; + + // регулярное выражение разбивающее строку программы на группы, последняя из которых - комментарий в конце строки + private static readonly Regex programLineRegex = new Regex("^(([^\n\"\'#])+|(\'([^\'\n\\\\]|\\\\.)*\')|(\"([^\"\n\\\\]|\\\\.)*\"))*(#.*)?$"); + + private static readonly Regex reg = new Regex(@"'([^'\\]*(\\.[^'\\]*)*)'|""([^""\\]*(\\.[^""\\]*)*)"""); + + + public IndentArranger() {} + + public void ProcessSourceText(ref string sourceText) + { + //string[] programLines = sourceText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + // В редакторе в особых случаях добавляется \n вместо \r\n + string[] programLines = sourceText.Split(new string[] { "\n" }, StringSplitOptions.None); + + // удаляем комментарии в тексте программы + EraseComments(ref programLines); + + // добавляем токены для начала/конца отступов и ; в конце stmt + ArrangeIndents(ref programLines); + + sourceText = String.Join("\n", programLines); + + // нужен токен в конце для правильного позиционирования ошибок, + // допущенных в конце программы + sourceText += endOfFIleToken; + + // создание файла с полученным текстом для дебага + //File.WriteAllText("./processed_file.txt", sourceText); + } + + private void EraseComments(ref string[] programLines) + { + for (int i = 0; i < programLines.Length; ++i) + { + Match programLineMatch = programLineRegex.Match(programLines[i]); + if (programLineMatch.Success) + { + Group programLineComment = programLineMatch.Groups[programLineMatch.Groups.Count - 1]; + if (programLineComment.Success) + programLines[i] = programLines[i].Substring(0, programLineComment.Index); + } + } + } + + int bracketCount = 0; + int prevBracketCount = 0; + + private void CountBrackets(string programLine) + { + string cleanLine = reg.Replace(programLine, match => ""); + + foreach (char c in cleanLine) + { + switch (c) + { + case '(': + case '{': + case '[': + ++bracketCount; + break; + + case ')': + case '}': + case ']': + --bracketCount; + break; + } + } + } + + // считывает первый токен в строке (с первого символа латиницы или _) + // возвращает тип этого токена + private bool IsFirstTokenElseOrElif(string line) + { + int beginIndex = 0; + for (beginIndex = 0; beginIndex < line.Length; ++beginIndex) + if (!Char.IsWhiteSpace(line[beginIndex])) + break; + if (line.Length < beginIndex + 4) return false; + + // получаем строковое представление токена + string firstToken = line.Substring(beginIndex, 4); + return firstToken == "else" || firstToken == "elif"; + } + + private void ArrangeIndents(ref string[] programLines) + { + Stack indentStack = new Stack(); + indentStack.Push(0); + bool skipped_first = false; + + foreach (var line in programLines) + { + lineCounter++; + prevBracketCount = bracketCount; + CountBrackets(line); + if (lineCounter > 0 && LineEndsWithBackSlash(ref programLines[lineCounter - 1])) + continue; + if (prevBracketCount != 0) + continue; + + bool isEmptyLine = true; // строка не содержит символов кроме \s\t\n\r + int currentLineSpaceCounter = 0; + + for (int i = 0; i < line.Length; ++i) + { + if (line[i] == '\t') + { + // один \t выравнивает до следующего отступа + currentLineSpaceCounter += indentSpaceNumber; + currentLineSpaceCounter &= ~(indentSpaceNumber - 1); + } + else if (char.IsWhiteSpace(line[i])) + currentLineSpaceCounter++; + else + { + isEmptyLine = false; + break; + } + } + + if (isEmptyLine) continue; + + int previosSpaceCounter = indentStack.Peek(); + // текущий отступ соответствует предыдущему отступу + if (currentLineSpaceCounter == previosSpaceCounter) + { + if (!skipped_first) + { + skipped_first = true; + continue; + } + AddSemicolonIfNeeded(ref programLines[lineCounter - 1]); + } + // текущий отступ соответствует увеличению + else if (currentLineSpaceCounter > previosSpaceCounter) + { + if (skipped_first && lineCounter != 0) + { + programLines[lineCounter - 1] += indentToken; + indentStack.Push(currentLineSpaceCounter); + } + else + programLines[lineCounter] = programBeginWithIndentToken; + } + // оставшиеся случаи: отступ некорректный или уменьшение на один или несколько отступов + else + { + int unindentCounter = 0; + while (currentLineSpaceCounter < previosSpaceCounter) + { + indentStack.Pop(); + unindentCounter++; + previosSpaceCounter = indentStack.Peek(); + } + + // текущий отступ соответствует уменьшению на один или несколько отступов + if (currentLineSpaceCounter == previosSpaceCounter) + { + // если сейчас ветка elif/else, то это не конец команды + // поэтому ставить ; в конце не надо (она будет после блока elif/else) + bool isEndOfStatement = !IsFirstTokenElseOrElif(line); + + unindentCounter--; + AddSemicolonIfNeeded(ref programLines[lineCounter - 1]); + + programLines[lineCounter - 1] += unindentToken + + string.Concat(Enumerable.Repeat(endOfLineToken + unindentToken, unindentCounter)) + + (isEndOfStatement ? endOfLineToken : ""); + } + // количество пробелов в строке является некорректным + // (не соответствует количеству пробелов в строке с любым отступом) + else // currentLineSpaceCounter > indentStack.Peek() + { + if (lineCounter != 0) + programLines[lineCounter - 1] += badIndentToken; + } + } + } + + + if (lineCounter != -1 && indentStack.Count() > 1) + { + // закрытие всех отступов в конце файла + AddSemicolonIfNeeded(ref programLines[lineCounter]); + programLines[lineCounter] += unindentToken + + string.Concat(Enumerable.Repeat(endOfLineToken + unindentToken, indentStack.Count() - 2)); + } + } + + private int IndexOfLastSignificantSymbol(string s) + { + int i = s.Length - 1; + while (i > -1 && Char.IsWhiteSpace(s[i])) --i; + return i; + } + + private bool LineEndsWithBackSlash(ref string s) + { + int i = IndexOfLastSignificantSymbol(s); + if (i == -1 || s[i] != '\\') + return false; + s = s.Substring(0, i); + return true; + } + + private void AddSemicolonIfNeeded(ref string s) + { + int i = IndexOfLastSignificantSymbol(s); + if (i == -1 || s[i] != ';') + s += endOfLineToken; + } + } +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Keywords.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Keywords.cs new file mode 100644 index 000000000..6ede7414f --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Keywords.cs @@ -0,0 +1,45 @@ +using PascalABCCompiler.Parsers; +using SPythonParserYacc; + +namespace SPythonParser +{ + + public class SPythonKeywords : BaseKeywords + { + + protected override string FileName => "keywordsmap.pys"; + + public SPythonKeywords() : base(true) + { + CreateNewKeyword("if", Tokens.IF); + CreateNewKeyword("elif", Tokens.ELIF); + CreateNewKeyword("else", Tokens.ELSE); + CreateNewKeyword("while", Tokens.WHILE); + CreateNewKeyword("for", Tokens.FOR); + CreateNewKeyword("in", Tokens.IN); + CreateNewKeyword("def", Tokens.DEF, KeywordKind.Function, true); + CreateNewKeyword("return", Tokens.RETURN); + CreateNewKeyword("break", Tokens.BREAK); + CreateNewKeyword("continue", Tokens.CONTINUE); + CreateNewKeyword("and", Tokens.AND); + CreateNewKeyword("or", Tokens.OR); + CreateNewKeyword("not", Tokens.NOT); + CreateNewKeyword("import", Tokens.IMPORT /*, KeywordKind.Uses*/); + CreateNewKeyword("from", Tokens.FROM); + CreateNewKeyword("global", Tokens.GLOBAL); + CreateNewKeyword("True", Tokens.TRUE); + CreateNewKeyword("False", Tokens.FALSE); + CreateNewKeyword("as", Tokens.AS); + CreateNewKeyword("pass", Tokens.PASS); + CreateNewKeyword("class", Tokens.CLASS, isTypeKeyword: true); + CreateNewKeyword("lambda", Tokens.LAMBDA); + CreateNewKeyword("exit", Tokens.EXIT); + CreateNewKeyword("new", Tokens.NEW, KeywordKind.New); + CreateNewKeyword("is", Tokens.IS); + CreateNewKeyword("decltype", Tokens.DECLTYPE); + } + + protected override int GetIdToken() => (int)Tokens.ID; + } + +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Properties/AssemblyInfo.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b791dfd70 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("SPythonParser")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SPythonParser")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("81fe2baa-d100-4596-a392-f03bbe30f829")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.cs new file mode 100644 index 000000000..07ddec874 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.cs @@ -0,0 +1,2798 @@ +// +// This CSharp output file generated by Gardens Point LEX +// Version: 1.1.3.301 +// Machine: DESKTOP-56159VE +// DateTime: 17.06.2025 14:06:30 +// UserName: ???? +// GPLEX input file +// GPLEX frame file +// +// Option settings: unicode, parser, minimize +// Option settings: classes, compressMap, compressNext, persistBuffer, embedbuffers +// Fallback code page: Target machine default +// + +// +// Experimental embedded frame +// Version 1.1.3 of 18-April-2010 +// +// +#define BACKUP +#define PERSIST + +using System; +using System.IO; +using System.Text; +using System.Globalization; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Diagnostics.CodeAnalysis; + +using SPythonParser; +using QUT.Gppg; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.ParserTools; +using SPythonParserYacc; +using SPythonParser; + +namespace SPythonParser +{ + /// + /// Summary Canonical example of GPLEX automaton + /// + +#if STANDALONE + // + // These are the dummy declarations for stand-alone GPLEX applications + // normally these declarations would come from the parser. + // If you declare /noparser, or %option noparser then you get this. + // + + public enum Tokens + { + EOF = 0, maxParseToken = int.MaxValue + // must have at least these two, values are almost arbitrary + } + + public abstract class ScanBase + { + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")] + public abstract int yylex(); + + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")] + protected virtual bool yywrap() { return true; } + +#if BABEL + protected abstract int CurrentSc { get; set; } + // EolState is the 32-bit of state data persisted at + // the end of each line for Visual Studio colorization. + // The default is to return CurrentSc. You must override + // this if you want more complicated behavior. + public virtual int EolState { + get { return CurrentSc; } + set { CurrentSc = value; } + } + } + + public interface IColorScan + { + void SetSource(string source, int offset); + int GetNext(ref int state, out int start, out int end); +#endif // BABEL + } + +#endif // STANDALONE + + // If the compiler can't find the scanner base class maybe you + // need to run GPPG with the /gplex option, or GPLEX with /noparser +#if BABEL + public sealed partial class Scanner : ScanBase, IColorScan + { + private ScanBuff buffer; + int currentScOrd; // start condition ordinal + + protected override int CurrentSc + { + // The current start state is a property + // to try to avoid the user error of setting + // scState but forgetting to update the FSA + // start state "currentStart" + // + get { return currentScOrd; } // i.e. return YY_START; + set { currentScOrd = value; // i.e. BEGIN(value); + currentStart = startState[value]; } + } +#else // BABEL + public sealed partial class Scanner : ScanBase + { + private ScanBuff buffer; + int currentScOrd; // start condition ordinal +#endif // BABEL + + /// + /// The input buffer for this scanner. + /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public ScanBuff Buffer { get { return buffer; } } + + private static int GetMaxParseToken() { + System.Reflection.FieldInfo f = typeof(Tokens).GetField("maxParseToken"); + return (f == null ? int.MaxValue : (int)f.GetValue(null)); + } + + static int parserMax = GetMaxParseToken(); + + enum Result {accept, noMatch, contextFound}; + + const int maxAccept = 65; + const int initial = 66; + const int eofNum = 0; + const int goStart = -1; + const int INITIAL = 0; + +#region user code +private SPythonKeywords keywords; + public SPythonParserTools parserTools; + public List Defines = new List(); + private int last_line_needed_colon = -1; + private LexLocation currentLexLocation; + private LexLocation prevLexLocation + = new LexLocation(-1, -1, -1, -1, ""); + + public Scanner(string text, SPythonParserTools parserTools, PascalABCCompiler.Parsers.BaseKeywords keywords, List defines = null) + { + this.parserTools = parserTools; + this.keywords = (SPythonKeywords)keywords; + if (defines != null) + this.Defines.AddRange(defines); + SetSource(text, 0); + } +#endregion user code + + int state; + int currentStart = startState[0]; + int code; // last code read + int cCol; // column number of code + int lNum; // current line number + // + // The following instance variables are used, among other + // things, for constructing the yylloc location objects. + // + int tokPos; // buffer position at start of token + int tokCol; // zero-based column number at start of token + int tokLin; // line number at start of token + int tokEPos; // buffer position at end of token + int tokECol; // column number at end of token + int tokELin; // line number at end of token + string tokTxt; // lazily constructed text of token +#if STACK + private Stack scStack = new Stack(); +#endif // STACK + +#region ScannerTables + struct Table { + public int min; public int rng; public int dflt; + public sbyte[] nxt; + public Table(int m, int x, int d, sbyte[] n) { + min = m; rng = x; dflt = d; nxt = n; + } + }; + + static int[] startState = new int[] {66, 0}; + +#region TwoLevelCharacterMap + // + // There are 49 equivalence classes + // There are 256 character sequence regions + // There are 47 tables, 12032 entries + // + static sbyte[] mLo0 = new sbyte[256] { +/* '\0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 8, 48, 48, +/* '\x10' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\x20' */ 8, 21, 10, 26, 47, 18, 23, 7, 34, 35, 17, 15, 32, 16, 6, 13, +/* '0' */ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 29, 19, 14, 20, 48, +/* '@' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* 'P' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 30, 9, 31, 25, 2, +/* '`' */ 48, 44, 4, 12, 12, 36, 11, 12, 12, 5, 12, 12, 12, 45, 42, 41, +/* 'p' */ 38, 12, 39, 40, 43, 12, 12, 12, 37, 46, 12, 27, 24, 28, 22, 48, +/* '\x80' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\x90' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\xA0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 48, 48, 48, 48, 48, +/* '\xB0' */ 48, 48, 48, 48, 48, 12, 48, 48, 48, 48, 12, 48, 48, 48, 48, 48, +/* '\xC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\xD0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\xE0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\xF0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo1 = new sbyte[256] { +/* '\u0100' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0110' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0120' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0130' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0140' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0150' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0160' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0170' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0180' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0190' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u01F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo2 = new sbyte[256] { +/* '\u0200' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0210' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0220' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0230' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0240' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0250' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0260' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0270' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0280' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0290' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u02A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u02B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u02C0' */ 12, 12, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u02D0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u02E0' */ 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 48, +/* '\u02F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo3 = new sbyte[256] { +/* '\u0300' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0310' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0320' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0330' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0340' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0350' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0360' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0370' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 48, 48, +/* '\u0380' */ 48, 48, 48, 48, 48, 48, 12, 48, 12, 12, 12, 48, 12, 48, 12, 12, +/* '\u0390' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u03A0' */ 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u03B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u03C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u03D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u03E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u03F0' */ 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo4 = new sbyte[256] { +/* '\u0400' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0410' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0420' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0430' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0440' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0450' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0460' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0470' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0480' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\u0490' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u04F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo5 = new sbyte[256] { +/* '\u0500' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0510' */ 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0520' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0530' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0540' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0550' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 12, 48, 48, 48, 48, 48, 48, +/* '\u0560' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0570' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0580' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0590' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u05A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u05B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u05C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u05D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u05E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u05F0' */ 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo6 = new sbyte[256] { +/* '\u0600' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0610' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0620' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0630' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u0640' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u0650' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0660' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, +/* '\u0670' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0680' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0690' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u06A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u06B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u06C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u06D0' */ 12, 12, 12, 12, 48, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u06E0' */ 48, 48, 48, 48, 48, 12, 12, 48, 48, 48, 48, 48, 48, 48, 12, 12, +/* '\u06F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 48, 48, 12 }; + static sbyte[] mLo7 = new sbyte[256] { +/* '\u0700' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0710' */ 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0720' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0730' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0740' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, +/* '\u0750' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0760' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\u0770' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0780' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0790' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u07A0' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u07B0' */ 48, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u07C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\u07D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u07E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u07F0' */ 48, 48, 48, 48, 12, 12, 48, 48, 48, 48, 12, 48, 48, 48, 48, 48 }; + static sbyte[] mLo8 = new sbyte[256] { +/* '\u0800' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0810' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0820' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0830' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0840' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0850' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0860' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0870' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0880' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0890' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u08F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo9 = new sbyte[256] { +/* '\u0900' */ 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0910' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0920' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0930' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 12, 48, 48, +/* '\u0940' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0950' */ 12, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0960' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0970' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, +/* '\u0980' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 12, +/* '\u0990' */ 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u09A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u09B0' */ 12, 48, 12, 48, 48, 48, 12, 12, 12, 12, 48, 48, 48, 12, 48, 48, +/* '\u09C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 48, +/* '\u09D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 48, 12, +/* '\u09E0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u09F0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo10 = new sbyte[256] { +/* '\u0A00' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 12, +/* '\u0A10' */ 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0A20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0A30' */ 12, 48, 12, 12, 48, 12, 12, 48, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\u0A40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0A50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 48, 12, 48, +/* '\u0A60' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0A70' */ 48, 48, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0A80' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, +/* '\u0A90' */ 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0AA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0AB0' */ 12, 48, 12, 12, 48, 12, 12, 12, 12, 12, 48, 48, 48, 12, 48, 48, +/* '\u0AC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0AD0' */ 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0AE0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0AF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo11 = new sbyte[256] { +/* '\u0B00' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 12, +/* '\u0B10' */ 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0B20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0B30' */ 12, 48, 12, 12, 48, 12, 12, 12, 12, 12, 48, 48, 48, 12, 48, 48, +/* '\u0B40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0B50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 48, 12, +/* '\u0B60' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0B70' */ 48, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0B80' */ 48, 48, 48, 12, 48, 12, 12, 12, 12, 12, 12, 48, 48, 48, 12, 12, +/* '\u0B90' */ 12, 48, 12, 12, 12, 12, 48, 48, 48, 12, 12, 48, 12, 48, 12, 12, +/* '\u0BA0' */ 48, 48, 48, 12, 12, 48, 48, 48, 12, 12, 12, 48, 48, 48, 12, 12, +/* '\u0BB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\u0BC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0BD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0BE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0BF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo12 = new sbyte[256] { +/* '\u0C00' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\u0C10' */ 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0C20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0C30' */ 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\u0C40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0C50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0C60' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0C70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0C80' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\u0C90' */ 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0CA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0CB0' */ 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 48, 48, 48, 12, 48, 48, +/* '\u0CC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0CD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 48, +/* '\u0CE0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0CF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo13 = new sbyte[256] { +/* '\u0D00' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\u0D10' */ 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0D20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\u0D30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\u0D40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0D50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0D60' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0D70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0D80' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0D90' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\u0DA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0DB0' */ 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, 48, +/* '\u0DC0' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0DD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0DE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0DF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo14 = new sbyte[256] { +/* '\u0E00' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0E10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0E20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0E30' */ 12, 48, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0E40' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0E50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0E60' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0E70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0E80' */ 48, 12, 12, 48, 12, 48, 48, 12, 12, 48, 12, 48, 48, 12, 48, 48, +/* '\u0E90' */ 48, 48, 48, 48, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, +/* '\u0EA0' */ 48, 12, 12, 12, 48, 12, 48, 12, 48, 48, 12, 12, 48, 12, 12, 12, +/* '\u0EB0' */ 12, 48, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 48, 48, +/* '\u0EC0' */ 12, 12, 12, 12, 12, 48, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0ED0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 48, 48, +/* '\u0EE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0EF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo15 = new sbyte[256] { +/* '\u0F00' */ 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0F10' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0F20' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0F30' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0F40' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, +/* '\u0F50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u0F60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u0F70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0F80' */ 48, 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 48, 48, 48, 48, +/* '\u0F90' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FA0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FB0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u0FF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo16 = new sbyte[256] { +/* '\u1000' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1010' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1020' */ 12, 12, 48, 12, 12, 12, 12, 12, 48, 12, 12, 48, 48, 48, 48, 48, +/* '\u1030' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1040' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1050' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1060' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1070' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1080' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1090' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u10A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u10B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u10C0' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u10D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u10E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u10F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, 48, 48 }; + static sbyte[] mLo17 = new sbyte[256] { +/* '\u1100' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1110' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1120' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1130' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1140' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1150' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 12, +/* '\u1160' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1170' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1180' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1190' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11A0' */ 12, 12, 12, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u11F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo18 = new sbyte[256] { +/* '\u1200' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1210' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1220' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1230' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1240' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 48, 48, +/* '\u1250' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, 12, 12, 12, 12, 48, 48, +/* '\u1260' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1270' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1280' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 48, 48, +/* '\u1290' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u12A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u12B0' */ 12, 48, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u12C0' */ 12, 48, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u12D0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u12E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u12F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo19 = new sbyte[256] { +/* '\u1300' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1310' */ 12, 48, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1320' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1330' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1340' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1350' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u1360' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1370' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1380' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1390' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u13A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u13B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u13C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u13D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u13E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u13F0' */ 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo20 = new sbyte[256] { +/* '\u1400' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1410' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1420' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1430' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1440' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1450' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1460' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1470' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1480' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1490' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u14F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo22 = new sbyte[256] { +/* '\u1600' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1610' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1620' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1630' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1640' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1650' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1660' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 12, +/* '\u1670' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1680' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1690' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u16A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u16B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u16C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u16D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u16E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\u16F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo23 = new sbyte[256] { +/* '\u1700' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\u1710' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1720' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1730' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1740' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1750' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1760' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\u1770' */ 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1780' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1790' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u17A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u17B0' */ 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u17C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u17D0' */ 48, 48, 48, 48, 48, 48, 48, 12, 48, 48, 48, 48, 12, 48, 48, 48, +/* '\u17E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u17F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo24 = new sbyte[256] { +/* '\u1800' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1810' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1820' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1830' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1840' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1850' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1860' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1870' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1880' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1890' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u18A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, +/* '\u18B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u18C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u18D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u18E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u18F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo25 = new sbyte[256] { +/* '\u1900' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1910' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\u1920' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1930' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1940' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1950' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1960' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\u1970' */ 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1980' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1990' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u19A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\u19B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u19C0' */ 48, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u19D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u19E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u19F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo26 = new sbyte[256] { +/* '\u1A00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1A10' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A20' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A30' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A60' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A80' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1A90' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AA0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AB0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1AF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo27 = new sbyte[256] { +/* '\u1B00' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1B10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1B20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1B30' */ 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1B40' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, +/* '\u1B50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1B60' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1B70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1B80' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1B90' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BA0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BB0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1BF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo29 = new sbyte[256] { +/* '\u1D00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1D90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1DA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1DB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1DC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1DD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1DE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u1DF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo30 = new sbyte[256] { +/* '\u1E00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1E90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, +/* '\u1EA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1EB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1EC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1ED0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1EE0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1EF0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo31 = new sbyte[256] { +/* '\u1F00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1F10' */ 12, 12, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\u1F20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1F30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1F40' */ 12, 12, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\u1F50' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, 12, 48, 12, 48, 12, +/* '\u1F60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1F70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\u1F80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1F90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1FA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u1FB0' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, +/* '\u1FC0' */ 48, 48, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\u1FD0' */ 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, +/* '\u1FE0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\u1FF0' */ 48, 48, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48 }; + static sbyte[] mLo32 = new sbyte[256] { +/* '\u2000' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2010' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2020' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2030' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2040' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2050' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2060' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2070' */ 48, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, +/* '\u2080' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2090' */ 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u20F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo33 = new sbyte[256] { +/* '\u2100' */ 48, 48, 12, 48, 48, 48, 48, 12, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\u2110' */ 12, 12, 12, 12, 48, 12, 48, 48, 48, 12, 12, 12, 12, 12, 48, 48, +/* '\u2120' */ 48, 48, 48, 48, 12, 48, 12, 48, 12, 48, 12, 12, 12, 12, 48, 12, +/* '\u2130' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, +/* '\u2140' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 48, 48, 48, 48, 12, 48, +/* '\u2150' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2160' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2170' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2180' */ 48, 48, 48, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2190' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u21F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo44 = new sbyte[256] { +/* '\u2C00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2C10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2C20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2C30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2C40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2C50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2C60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\u2C70' */ 48, 48, 48, 48, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2C80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2C90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2CA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2CB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2CC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2CD0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2CE0' */ 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2CF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo45 = new sbyte[256] { +/* '\u2D00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D20' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2D30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D60' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 12, +/* '\u2D70' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2D80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u2D90' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2DA0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2DB0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2DC0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2DD0' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u2DE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u2DF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo48 = new sbyte[256] { +/* '\u3000' */ 48, 48, 48, 48, 48, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u3010' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u3020' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u3030' */ 48, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 12, 12, 48, 48, 48, +/* '\u3040' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3050' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3060' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3070' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3080' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3090' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 12, 12, 12, +/* '\u30A0' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u30B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u30C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u30D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u30E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u30F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12 }; + static sbyte[] mLo49 = new sbyte[256] { +/* '\u3100' */ 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3110' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3120' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\u3130' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3140' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3150' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3160' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3170' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u3180' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\u3190' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u31A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u31B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u31C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u31D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u31E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u31F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo77 = new sbyte[256] { +/* '\u4D00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4D90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4DA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u4DB0' */ 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u4DC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u4DD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u4DE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u4DF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo159 = new sbyte[256] { +/* '\u9F00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9F90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9FA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\u9FB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, +/* '\u9FC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u9FD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u9FE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\u9FF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo164 = new sbyte[256] { +/* '\uA400' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA410' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA420' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA430' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA440' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA450' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA460' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA470' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA480' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, +/* '\uA490' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA4F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo167 = new sbyte[256] { +/* '\uA700' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA710' */ 48, 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\uA720' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA730' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA740' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA750' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA760' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA770' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA780' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA790' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA7F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo168 = new sbyte[256] { +/* '\uA800' */ 12, 12, 48, 12, 12, 12, 48, 12, 12, 12, 12, 48, 12, 12, 12, 12, +/* '\uA810' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA820' */ 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA830' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA840' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA850' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA860' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uA870' */ 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA880' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA890' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8A0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uA8F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo215 = new sbyte[256] { +/* '\uD700' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD710' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD720' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD730' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD740' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD750' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD760' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD770' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD780' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD790' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uD7A0' */ 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uD7B0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uD7C0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uD7D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uD7E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uD7F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo250 = new sbyte[256] { +/* '\uFA00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\uFA30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA40' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\uFA70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFA90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFAA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFAB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFAC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFAD0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\uFAE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFAF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mLo251 = new sbyte[256] { +/* '\uFB00' */ 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFB10' */ 48, 48, 48, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 12, 48, 12, +/* '\uFB20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\uFB30' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 48, 12, 48, +/* '\uFB40' */ 12, 12, 48, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFB50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFB60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFB70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFB80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFB90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFBA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFBB0' */ 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFBC0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFBD0' */ 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFBE0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFBF0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mLo253 = new sbyte[256] { +/* '\uFD00' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD10' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\uFD40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFD50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD60' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFD90' */ 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFDA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFDB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFDC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFDD0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFDE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFDF0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48 }; + static sbyte[] mLo254 = new sbyte[256] { +/* '\uFE00' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE10' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE20' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE30' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE40' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE50' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE60' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFE70' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFE80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFE90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFEA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFEB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFEC0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFED0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFEE0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFEF0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48 }; + static sbyte[] mLo255 = new sbyte[256] { +/* '\uFF00' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFF10' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFF20' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFF30' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\uFF40' */ 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFF50' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, +/* '\uFF60' */ 48, 48, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFF70' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFF80' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFF90' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFFA0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\uFFB0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\uFFC0' */ 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\uFFD0' */ 48, 48, 12, 12, 12, 12, 12, 12, 48, 48, 12, 12, 12, 48, 48, 48, +/* '\uFFE0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\uFFF0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + + static sbyte[][] map = new sbyte[256][] { +/* '\u00xx' */ mLo0, mLo1, mLo2, mLo3, mLo4, mLo5, mLo6, mLo7, mLo8, mLo9, mLo10, mLo11, mLo12, mLo13, mLo14, mLo15, +/* '\u10xx' */ mLo16, mLo17, mLo18, mLo19, mLo20, mLo1, mLo22, mLo23, mLo24, mLo25, mLo26, mLo27, mLo8, mLo29, mLo30, mLo31, +/* '\u20xx' */ mLo32, mLo33, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo44, mLo45, mLo8, mLo8, +/* '\u30xx' */ mLo48, mLo49, mLo8, mLo8, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\u40xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo77, mLo1, mLo1, +/* '\u50xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\u60xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\u70xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\u80xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\u90xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo159, +/* '\uA0xx' */ mLo1, mLo1, mLo1, mLo1, mLo164, mLo8, mLo8, mLo167, mLo168, mLo8, mLo8, mLo8, mLo1, mLo1, mLo1, mLo1, +/* '\uB0xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\uC0xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, +/* '\uD0xx' */ mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo1, mLo215, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, +/* '\uE0xx' */ mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, +/* '\uF0xx' */ mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo8, mLo1, mLo250, mLo251, mLo1, mLo253, mLo254, mLo255}; + +#endregion + +#region CompressedCharacterMap + // + // There are 49 equivalence classes + // There are 21 character sequence regions + // There are 6 tables, 1255 entries + // There are 15 runs, 0 singletons + // Decision tree depth is 5 + // + static sbyte[] mapC0 = new sbyte[251] { +/* '\U00010000' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, +/* '\U00010010' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010020' */ 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010030' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 48, 12, +/* '\U00010040' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\U00010050' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\U00010060' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010070' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010080' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010090' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100C0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000100F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }; + static sbyte[] mapC2 = new sbyte[256] { +/* '\U00010300' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010310' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\U00010320' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010330' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010340' */ 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, 48, 48, 48, 48, +/* '\U00010350' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010360' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010370' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010380' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010390' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 48, +/* '\U000103A0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000103B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000103C0' */ 12, 12, 12, 12, 48, 48, 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U000103D0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U000103E0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U000103F0' */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }; + static sbyte[] mapC5 = new sbyte[64] { +/* '\U00010800' */ 12, 12, 12, 12, 12, 12, 48, 48, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\U00010810' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010820' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010830' */ 12, 12, 12, 12, 12, 12, 48, 12, 12, 48, 48, 48, 12, 48, 48, 12 }; + static sbyte[] mapC9 = new sbyte[52] { +/* '\U00010A00' */ 12, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* '\U00010A10' */ 12, 12, 12, 12, 48, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010A20' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U00010A30' */ 12, 12, 12, 12 }; + static sbyte[] mapC13 = new sbyte[338] { +/* '\U0001D400' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D410' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D420' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D430' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D440' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D450' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D460' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D470' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D480' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D490' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\U0001D4A0' */ 48, 48, 12, 48, 48, 12, 12, 48, 48, 12, 12, 12, 12, 48, 12, 12, +/* '\U0001D4B0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 48, 12, 12, 12, +/* '\U0001D4C0' */ 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D4D0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D4E0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D4F0' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D500' */ 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 48, 48, 12, 12, 12, +/* '\U0001D510' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\U0001D520' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D530' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 48, +/* '\U0001D540' */ 12, 12, 12, 12, 12, 48, 12, 48, 48, 48, 12, 12, 12, 12, 12, 12, +/* '\U0001D550' */ 12, 48 }; + static sbyte[] mapC15 = new sbyte[294] { +/* '\U0001D6A6' */ 48, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D6B6' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, +/* '\U0001D6C6' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D6D6' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D6E6' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D6F6' */ 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D706' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\U0001D716' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D726' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, +/* '\U0001D736' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D746' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\U0001D756' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D766' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, +/* '\U0001D776' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D786' */ 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D796' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D7A6' */ 12, 12, 12, 48, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +/* '\U0001D7B6' */ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 48, 12, 12, +/* '\U0001D7C6' */ 12, 12, 12, 12, 12, 12 }; + + static sbyte MapC(int code) + { // '\U00010000' <= code <= '\U0010FFFF' + if (code < 68148) // '\U00010000' <= code <= '\U00010A33' + if (code < 67584) // '\U00010000' <= code <= '\U000107FF' + if (code < 66304) // '\U00010000' <= code <= '\U000102FF' + if (code < 65787) // '\U00010000' <= code <= '\U000100FA' + return mapC0[code - 65536]; + else // '\U000100FB' <= code <= '\U000102FF' + return (sbyte)48; + else // '\U00010300' <= code <= '\U000107FF' + if (code < 66560) // '\U00010300' <= code <= '\U000103FF' + return mapC2[code - 66304]; + else // '\U00010400' <= code <= '\U000107FF' + if (code < 66718) // '\U00010400' <= code <= '\U0001049D' + return (sbyte)12; + else // '\U0001049E' <= code <= '\U000107FF' + return (sbyte)48; + else // '\U00010800' <= code <= '\U00010A33' + if (code < 67840) // '\U00010800' <= code <= '\U000108FF' + if (code < 67648) // '\U00010800' <= code <= '\U0001083F' + return mapC5[code - 67584]; + else // '\U00010840' <= code <= '\U000108FF' + return (sbyte)48; + else // '\U00010900' <= code <= '\U00010A33' + if (code < 67862) // '\U00010900' <= code <= '\U00010915' + return (sbyte)12; + else // '\U00010916' <= code <= '\U00010A33' + if (code < 68096) // '\U00010916' <= code <= '\U000109FF' + return (sbyte)48; + else // '\U00010A00' <= code <= '\U00010A33' + return mapC9[code - 68096]; + else // '\U00010A34' <= code <= '\U0010FFFF' + if (code < 120486) // '\U00010A34' <= code <= '\U0001D6A5' + if (code < 74607) // '\U00010A34' <= code <= '\U0001236E' + if (code < 73728) // '\U00010A34' <= code <= '\U00011FFF' + return (sbyte)48; + else // '\U00012000' <= code <= '\U0001236E' + return (sbyte)12; + else // '\U0001236F' <= code <= '\U0001D6A5' + if (code < 119808) // '\U0001236F' <= code <= '\U0001D3FF' + return (sbyte)48; + else // '\U0001D400' <= code <= '\U0001D6A5' + if (code < 120146) // '\U0001D400' <= code <= '\U0001D551' + return mapC13[code - 119808]; + else // '\U0001D552' <= code <= '\U0001D6A5' + return (sbyte)12; + else // '\U0001D6A6' <= code <= '\U0010FFFF' + if (code < 173783) // '\U0001D6A6' <= code <= '\U0002A6D6' + if (code < 120780) // '\U0001D6A6' <= code <= '\U0001D7CB' + return mapC15[code - 120486]; + else // '\U0001D7CC' <= code <= '\U0002A6D6' + if (code < 131072) // '\U0001D7CC' <= code <= '\U0001FFFF' + return (sbyte)48; + else // '\U00020000' <= code <= '\U0002A6D6' + return (sbyte)12; + else // '\U0002A6D7' <= code <= '\U0010FFFF' + if (code < 194560) // '\U0002A6D7' <= code <= '\U0002F7FF' + return (sbyte)48; + else // '\U0002F800' <= code <= '\U0010FFFF' + if (code < 195102) // '\U0002F800' <= code <= '\U0002FA1D' + return (sbyte)12; + else // '\U0002FA1E' <= code <= '\U0010FFFF' + return (sbyte)48; + } +#endregion + + + static sbyte Map(int code) + { + if (code <= 65535) + return map[code / 256][code % 256]; + else + return MapC(code); + } + + static Table[] NxS = new Table[104] { +/* NxS[ 0] */ new Table(0, 0, 0, null), +/* NxS[ 1] */ new Table(1, 6, -1, new sbyte[] {1, 103, 1, 102, -1, 64}), +/* NxS[ 2] */ new Table(36, 26, -1, new sbyte[] {2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, -1, -1, -1, 2, 2, 2, 2, 2, -1, -1, -1, + -1, -1, 2, 2}), +/* NxS[ 3] */ new Table(4, 3, -1, new sbyte[] {102, -1, 64}), +/* NxS[ 4] */ new Table(1, 3, -1, new sbyte[] {62, -1, 63}), +/* NxS[ 5] */ new Table(0, 10, 99, new sbyte[] {-1, 99, 99, 99, 99, 99, + 99, 61, 99, 100}), +/* NxS[ 6] */ new Table(0, 0, -1, null), +/* NxS[ 7] */ new Table(0, 11, 97, new sbyte[] {-1, 97, 97, 97, 97, 97, + 97, 97, 97, 98, 61}), +/* NxS[ 8] */ new Table(36, 26, -1, new sbyte[] {2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, -1, -1, -1, 2, 2, 2, 2, 2, -1, 93, -1, + -1, 94, 2, 2}), +/* NxS[ 9] */ new Table(13, 2, -1, new sbyte[] {57, 58}), +/* NxS[ 10] */ new Table(14, 1, -1, new sbyte[] {56}), +/* NxS[ 11] */ new Table(14, 1, -1, new sbyte[] {55}), +/* NxS[ 12] */ new Table(14, 7, -1, new sbyte[] {53, -1, -1, -1, -1, -1, + 54}), +/* NxS[ 13] */ new Table(14, 4, -1, new sbyte[] {51, -1, -1, 52}), +/* NxS[ 14] */ new Table(0, 0, -1, null), +/* NxS[ 15] */ new Table(14, 6, -1, new sbyte[] {45, -1, -1, -1, -1, 46}), +/* NxS[ 16] */ new Table(14, 7, -1, new sbyte[] {42, -1, -1, -1, -1, -1, + 43}), +/* NxS[ 17] */ new Table(14, 1, -1, new sbyte[] {41}), +/* NxS[ 18] */ new Table(0, 0, -1, null), +/* NxS[ 19] */ new Table(14, 1, -1, new sbyte[] {40}), +/* NxS[ 20] */ new Table(14, 1, -1, new sbyte[] {39}), +/* NxS[ 21] */ new Table(14, 1, -1, new sbyte[] {38}), +/* NxS[ 22] */ new Table(47, 32, -1, new sbyte[] {37, -1, -1, -1, -1, -1, + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, -1, -1, -1, -1, -1, 34, 35, 36}), +/* NxS[ 23] */ new Table(0, 0, -1, null), +/* NxS[ 24] */ new Table(0, 0, -1, null), +/* NxS[ 25] */ new Table(0, 0, -1, null), +/* NxS[ 26] */ new Table(0, 0, -1, null), +/* NxS[ 27] */ new Table(0, 0, -1, null), +/* NxS[ 28] */ new Table(0, 0, -1, null), +/* NxS[ 29] */ new Table(0, 0, -1, null), +/* NxS[ 30] */ new Table(0, 0, -1, null), +/* NxS[ 31] */ new Table(0, 0, -1, null), +/* NxS[ 32] */ new Table(0, 0, -1, null), +/* NxS[ 33] */ new Table(0, 0, -1, null), +/* NxS[ 34] */ new Table(0, 0, -1, null), +/* NxS[ 35] */ new Table(0, 0, -1, null), +/* NxS[ 36] */ new Table(0, 0, -1, null), +/* NxS[ 37] */ new Table(0, 0, -1, null), +/* NxS[ 38] */ new Table(0, 0, -1, null), +/* NxS[ 39] */ new Table(0, 0, -1, null), +/* NxS[ 40] */ new Table(0, 0, -1, null), +/* NxS[ 41] */ new Table(0, 0, -1, null), +/* NxS[ 42] */ new Table(0, 0, -1, null), +/* NxS[ 43] */ new Table(14, 1, -1, new sbyte[] {44}), +/* NxS[ 44] */ new Table(0, 0, -1, null), +/* NxS[ 45] */ new Table(0, 0, -1, null), +/* NxS[ 46] */ new Table(36, 28, -1, new sbyte[] {67, -1, -1, -1, 68, -1, + -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 47}), +/* NxS[ 47] */ new Table(0, 0, -1, null), +/* NxS[ 48] */ new Table(0, 0, -1, null), +/* NxS[ 49] */ new Table(0, 0, -1, null), +/* NxS[ 50] */ new Table(0, 0, -1, null), +/* NxS[ 51] */ new Table(0, 0, -1, null), +/* NxS[ 52] */ new Table(0, 0, -1, null), +/* NxS[ 53] */ new Table(0, 0, -1, null), +/* NxS[ 54] */ new Table(0, 0, -1, null), +/* NxS[ 55] */ new Table(0, 0, -1, null), +/* NxS[ 56] */ new Table(0, 0, -1, null), +/* NxS[ 57] */ new Table(14, 1, -1, new sbyte[] {59}), +/* NxS[ 58] */ new Table(0, 0, -1, null), +/* NxS[ 59] */ new Table(0, 0, -1, null), +/* NxS[ 60] */ new Table(0, 0, -1, null), +/* NxS[ 61] */ new Table(0, 0, -1, null), +/* NxS[ 62] */ new Table(1, 3, -1, new sbyte[] {62, 101, 62}), +/* NxS[ 63] */ new Table(0, 0, -1, null), +/* NxS[ 64] */ new Table(1, 3, -1, new sbyte[] {62, -1, 63}), +/* NxS[ 65] */ new Table(0, 0, -1, null), +/* NxS[ 66] */ new Table(47, 38, 2, new sbyte[] {6, 6, -1, 1, 2, 3, + 2, 2, 4, 5, -1, 6, 7, 8, 2, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}), +/* NxS[ 67] */ new Table(37, 1, -1, new sbyte[] {83}), +/* NxS[ 68] */ new Table(43, 1, -1, new sbyte[] {74}), +/* NxS[ 69] */ new Table(46, 1, -1, new sbyte[] {70}), +/* NxS[ 70] */ new Table(38, 1, -1, new sbyte[] {71}), +/* NxS[ 71] */ new Table(36, 1, -1, new sbyte[] {72}), +/* NxS[ 72] */ new Table(20, 1, -1, new sbyte[] {73}), +/* NxS[ 73] */ new Table(20, 1, -1, new sbyte[] {48}), +/* NxS[ 74] */ new Table(44, 1, -1, new sbyte[] {75}), +/* NxS[ 75] */ new Table(43, 1, -1, new sbyte[] {76}), +/* NxS[ 76] */ new Table(36, 1, -1, new sbyte[] {77}), +/* NxS[ 77] */ new Table(45, 1, -1, new sbyte[] {78}), +/* NxS[ 78] */ new Table(36, 1, -1, new sbyte[] {79}), +/* NxS[ 79] */ new Table(42, 1, -1, new sbyte[] {80}), +/* NxS[ 80] */ new Table(43, 1, -1, new sbyte[] {81}), +/* NxS[ 81] */ new Table(20, 1, -1, new sbyte[] {82}), +/* NxS[ 82] */ new Table(20, 1, -1, new sbyte[] {49}), +/* NxS[ 83] */ new Table(38, 1, -1, new sbyte[] {84}), +/* NxS[ 84] */ new Table(39, 1, -1, new sbyte[] {85}), +/* NxS[ 85] */ new Table(36, 1, -1, new sbyte[] {86}), +/* NxS[ 86] */ new Table(40, 1, -1, new sbyte[] {87}), +/* NxS[ 87] */ new Table(40, 1, -1, new sbyte[] {88}), +/* NxS[ 88] */ new Table(5, 1, -1, new sbyte[] {89}), +/* NxS[ 89] */ new Table(41, 1, -1, new sbyte[] {90}), +/* NxS[ 90] */ new Table(42, 1, -1, new sbyte[] {91}), +/* NxS[ 91] */ new Table(20, 1, -1, new sbyte[] {92}), +/* NxS[ 92] */ new Table(20, 1, -1, new sbyte[] {50}), +/* NxS[ 93] */ new Table(0, 10, 93, new sbyte[] {-1, 93, 93, 93, 93, 93, + 93, 60, 93, 96}), +/* NxS[ 94] */ new Table(0, 11, 94, new sbyte[] {-1, 94, 94, 94, 94, 94, + 94, 94, 94, 95, 60}), +/* NxS[ 95] */ new Table(0, 1, 94, new sbyte[] {-1}), +/* NxS[ 96] */ new Table(0, 1, 93, new sbyte[] {-1}), +/* NxS[ 97] */ new Table(0, 11, 97, new sbyte[] {-1, 97, 97, 97, 97, 97, + 97, 97, 97, 98, 61}), +/* NxS[ 98] */ new Table(0, 1, 97, new sbyte[] {-1}), +/* NxS[ 99] */ new Table(0, 10, 99, new sbyte[] {-1, 99, 99, 99, 99, 99, + 99, 61, 99, 100}), +/* NxS[ 100] */ new Table(0, 1, 99, new sbyte[] {-1}), +/* NxS[ 101] */ new Table(1, 3, -1, new sbyte[] {62, -1, 62}), +/* NxS[ 102] */ new Table(5, 1, -1, new sbyte[] {65}), +/* NxS[ 103] */ new Table(1, 3, -1, new sbyte[] {1, -1, 1}), + }; + +int NextState() { + if (code == ScanBuff.EndOfFile) + return eofNum; + else + unchecked { + int rslt; + int idx = Map(code) - NxS[state].min; + if (idx < 0) idx += 49; + if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt; + else rslt = NxS[state].nxt[idx]; + return rslt; + } +} + +#endregion + + +#if BACKUP + // ============================================================== + // == Nested struct used for backup in automata that do backup == + // ============================================================== + + struct Context // class used for automaton backup. + { + public int bPos; + public int rPos; // scanner.readPos saved value + public int cCol; + public int lNum; // Need this in case of backup over EOL. + public int state; + public int cChr; + } + + private Context ctx = new Context(); +#endif // BACKUP + + // ============================================================== + // ==== Nested struct to support input switching in scanners ==== + // ============================================================== + + struct BufferContext { + internal ScanBuff buffSv; + internal int chrSv; + internal int cColSv; + internal int lNumSv; + } + + // ============================================================== + // ===== Private methods to save and restore buffer contexts ==== + // ============================================================== + + /// + /// This method creates a buffer context record from + /// the current buffer object, together with some + /// scanner state values. + /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + BufferContext MkBuffCtx() + { + BufferContext rslt; + rslt.buffSv = this.buffer; + rslt.chrSv = this.code; + rslt.cColSv = this.cCol; + rslt.lNumSv = this.lNum; + return rslt; + } + + /// + /// This method restores the buffer value and allied + /// scanner state from the given context record value. + /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + void RestoreBuffCtx(BufferContext value) + { + this.buffer = value.buffSv; + this.code = value.chrSv; + this.cCol = value.cColSv; + this.lNum = value.lNumSv; + } + // =================== End Nested classes ======================= + +#if !NOFILES + public Scanner(Stream file) { + SetSource(file, 0); // unicode option + } + + public Scanner(Stream file, string codepage) { + SetSource(file, CodePageHandling.GetCodePage(codepage)); + } + +#endif // !NOFILES + + public Scanner() { } + + private int readPos; + + void GetCode() + { + if (code == '\n') // This needs to be fixed for other conventions + // i.e. [\r\n\205\u2028\u2029] + { + cCol = -1; + lNum++; + } + readPos = buffer.Pos; + + // Now read new codepoint. + code = buffer.Read(); + if (code > ScanBuff.EndOfFile) + { +#if (!BYTEMODE) + if (code >= 0xD800 && code <= 0xDBFF) + { + int next = buffer.Read(); + if (next < 0xDC00 || next > 0xDFFF) + code = ScanBuff.UnicodeReplacementChar; + else + code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF)); + } +#endif + cCol++; + } + } + + void MarkToken() + { +#if (!PERSIST) + buffer.Mark(); +#endif + tokPos = readPos; + tokLin = lNum; + tokCol = cCol; + } + + void MarkEnd() + { + tokTxt = null; + tokEPos = readPos; + tokELin = lNum; + tokECol = cCol; + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + int Peek() + { + int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos; + GetCode(); rslt = code; + lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv; + return rslt; + } + + // ============================================================== + // ===== Initialization of string-based input buffers ==== + // ============================================================== + + /// + /// Create and initialize a StringBuff buffer object for this scanner + /// + /// the input string + /// starting offset in the string + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public void SetSource(string source, int offset) + { + this.buffer = ScanBuff.GetBuffer(source); + this.buffer.Pos = offset; + this.lNum = 0; + this.code = '\n'; // to initialize yyline, yycol and lineStart + GetCode(); + } + +#if !NOFILES + // ================ LineBuffer Initialization =================== + + /// + /// Create and initialize a LineBuff buffer object for this scanner + /// + /// the list of input strings + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public void SetSource(IList source) + { + this.buffer = ScanBuff.GetBuffer(source); + this.code = '\n'; // to initialize yyline, yycol and lineStart + this.lNum = 0; + GetCode(); + } + + // =============== StreamBuffer Initialization ================== + + /// + /// Create and initialize a StreamBuff buffer object for this scanner. + /// StreamBuff is buffer for 8-bit byte files. + /// + /// the input byte stream + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public void SetSource(Stream source) + { + this.buffer = ScanBuff.GetBuffer(source); + this.lNum = 0; + this.code = '\n'; // to initialize yyline, yycol and lineStart + GetCode(); + } + +#if !BYTEMODE + // ================ TextBuffer Initialization =================== + + /// + /// Create and initialize a TextBuff buffer object for this scanner. + /// TextBuff is a buffer for encoded unicode files. + /// + /// the input text file + /// Code page to use if file has + /// no BOM. For 0, use machine default; for -1, 8-bit binary + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public void SetSource(Stream source, int fallbackCodePage) + { + this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage); + this.lNum = 0; + this.code = '\n'; // to initialize yyline, yycol and lineStart + GetCode(); + } +#endif // !BYTEMODE +#endif // !NOFILES + + // ============================================================== + +#if BABEL + // + // Get the next token for Visual Studio + // + // "state" is the inout mode variable that maintains scanner + // state between calls, using the EolState property. In principle, + // if the calls of EolState are costly set could be called once + // only per line, at the start; and get called only at the end + // of the line. This needs more infrastructure ... + // + public int GetNext(ref int state, out int start, out int end) + { + Tokens next; + int s, e; + s = state; // state at start + EolState = state; + next = (Tokens)Scan(); + state = EolState; + e = state; // state at end; + start = tokPos; + end = tokEPos - 1; // end is the index of last char. + return (int)next; + } +#endif // BABEL + + // ======== AbstractScanner<> Implementation ========= + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")] + public override int yylex() + { + // parserMax is set by reflecting on the Tokens + // enumeration. If maxParseToken is defined + // that is used, otherwise int.MaxValue is used. + int next; + do { next = Scan(); } while (next >= parserMax); + return next; + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + int yypos { get { return tokPos; } } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + int yyline { get { return tokLin; } } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + int yycol { get { return tokCol; } } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")] + public string yytext + { + get + { + if (tokTxt == null) + tokTxt = buffer.GetString(tokPos, tokEPos); + return tokTxt; + } + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + void yyless(int n) + { + buffer.Pos = tokPos; + // Must read at least one char, so set before start. + cCol = tokCol - 1; + GetCode(); + // Now ensure that line counting is correct. + lNum = tokLin; + // And count the rest of the text. + for (int i = 0; i < n; i++) GetCode(); + MarkEnd(); + } + + // + // It would be nice to count backward in the text + // but it does not seem possible to re-establish + // the correct column counts except by going forward. + // + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + void _yytrunc(int n) { yyless(yyleng - n); } + + // + // This is painful, but we no longer count + // codepoints. For the overwhelming majority + // of cases the single line code is fast, for + // the others, well, at least it is all in the + // buffer so no files are touched. Note that we + // can't use (tokEPos - tokPos) because of the + // possibility of surrogate pairs in the token. + // + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")] + public int yyleng + { + get { +#if BYTEMODE + return tokEPos - tokPos; +#else + if (tokELin == tokLin) + return tokECol - tokCol; + else { + int ch; + int count = 0; + int save = buffer.Pos; + buffer.Pos = tokPos; + do { + ch = buffer.Read(); + if (!char.IsHighSurrogate((char)ch)) count++; + } while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile); + buffer.Pos = save; + return count; + } +#endif // BYTEMODE + } + } + + // ============ methods available in actions ============== + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal int YY_START { + get { return currentScOrd; } + set { currentScOrd = value; + currentStart = startState[value]; + } + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void BEGIN(int next) { + currentScOrd = next; + currentStart = startState[next]; + } + + // ============== The main tokenizer code ================= + + int Scan() + { + try { + for (; ; ) + { + int next; // next state to enter +#if BACKUP + Result rslt = Result.noMatch; +#endif // BACKUP +#if LEFTANCHORS + for (;;) + { + // Discard characters that do not start any pattern. + // Must check the left anchor condition after *every* GetCode! + state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart); + if ((next = NextState()) != goStart) + break; // LOOP EXIT HERE... + GetCode(); + } + +#else // !LEFTANCHORS + state = currentStart; + while ((next = NextState()) == goStart) + // At this point, the current character has no + // transition from the current state. We discard + // the "no-match" char. In traditional LEX such + // characters are echoed to the console. + GetCode(); +#endif // LEFTANCHORS + // At last, a valid transition ... + MarkToken(); + state = next; + GetCode(); + + while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum +#if BACKUP + if (state <= maxAccept && next > maxAccept) // need to prepare backup data + { + // ctx is an object. The fields may be + // mutated by the call to Recurse2. + // On return the data in ctx is the + // *latest* accept state that was found. + + rslt = Recurse2(ref ctx, next); + if (rslt == Result.noMatch) + RestoreStateAndPos(ref ctx); + break; + } + else +#endif // BACKUP + { + state = next; + GetCode(); + } + if (state <= maxAccept) + { + MarkEnd(); +#region ActionSwitch +#pragma warning disable 162 + switch (state) + { + case eofNum: + if (yywrap()) + return (int)Tokens.EOF; + break; + case 1: + case 3: +yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_spy_int_const(yytext,currentLexLocation); + return (int)Tokens.INTNUM; + break; + case 2: + case 8: +string cur_yytext = yytext; + int res = keywords.KeywordOrIDToken(cur_yytext); + currentLexLocation = CurrentLexLocation; + yylval = new SPythonParserYacc.ValueType(); + switch (res) + { + case (int)Tokens.ID: + yylval.id = parserTools.create_ident(cur_yytext, currentLexLocation); + break; + case (int)Tokens.AND: + yylval.op = new op_type_node(Operators.LogicalAND, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.OR: + yylval.op = new op_type_node(Operators.LogicalOR, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.NOT: + yylval.op = new op_type_node(Operators.LogicalNOT, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.IF: + case (int)Tokens.ELIF: + case (int)Tokens.ELSE: + case (int)Tokens.WHILE: + case (int)Tokens.FOR: + case (int)Tokens.DEF: + last_line_needed_colon = CurrentLexLocation.StartLine; + break; + case (int)Tokens.CLASS: + case (int)Tokens.LAMBDA: + parserTools.AddErrorFromResource("UNSUPPORTED_CONSTRUCTION_{0}", currentLexLocation, yytext); + break; + } + + return res; + break; + case 4: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.DOT; + break; + case 5: + case 6: + case 7: + case 17: + case 22: +parserTools.AddErrorFromResource("UNEXPECTED_TOKEN_{0}", CurrentLexLocation, yytext); + return (int)Tokens.EOF; + break; + case 9: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Division); return (int)Tokens.DIVIDE; + break; + case 10: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Assignment); return (int)Tokens.ASSIGN; + break; + case 11: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Plus); return (int)Tokens.PLUS; + break; + case 12: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Minus); return (int)Tokens.MINUS; + break; + case 13: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Multiplication); return (int)Tokens.STAR; + break; + case 14: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.ModulusRemainder); return (int)Tokens.PERCENTAGE; + break; + case 15: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Less); return (int)Tokens.LESS; + break; + case 16: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Greater); return (int)Tokens.GREATER; + break; + case 18: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalNOT); return (int)Tokens.BINNOT; + break; + case 19: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalAND); return (int)Tokens.BINAND; + break; + case 20: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalOR); return (int)Tokens.BINOR; + break; + case 21: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseXOR); return (int)Tokens.BINXOR; + break; + case 23: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACE; + break; + case 24: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACE; + break; + case 25: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.SEMICOLON; + break; + case 26: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACKET; + break; + case 27: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACKET; + break; + case 28: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COMMA; + break; + case 29: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COLON; + break; + case 30: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LPAR; + break; + case 31: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RPAR; + break; + case 32: +parserTools.AddErrorFromResource("PROGRAM_BEGIN_WITH_INDENT", + CurrentLexLocation); + return (int)Tokens.EOF; + break; + case 33: +parserTools.AddErrorFromResource("WRONG_INDENT", + new LexLocation(CurrentLexLocation.StartLine + 1, 0, CurrentLexLocation.StartLine + 1, 0)); + return (int)Tokens.EOF; + break; + case 34: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.INDENT; + break; + case 35: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.UNINDENT; + break; + case 36: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.END_OF_LINE; + break; + case 37: +return (int)Tokens.END_OF_FILE; + break; + case 38: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseXOR); return (int)Tokens.BINXOREQUAL; + break; + case 39: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseOR); return (int)Tokens.BINOREQUAL; + break; + case 40: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseAND); return (int)Tokens.BINANDEQUAL; + break; + case 41: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.NotEqual); return (int)Tokens.NOTEQUAL; + break; + case 42: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.GreaterEqual); return (int)Tokens.GREATEREQUAL; + break; + case 43: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseRightShift); return (int)Tokens.SHR; + break; + case 44: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseRightShift); return (int)Tokens.SHREQUAL; + break; + case 45: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LessEqual); return (int)Tokens.LESSEQUAL; + break; + case 46: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseLeftShift); return (int)Tokens.SHL; + break; + case 47: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseLeftShift); return (int)Tokens.SHLEQUAL; + break; + case 48: +return (int)Tokens.tkParseModeType; + break; + case 49: +return (int)Tokens.tkParseModeStatement; + break; + case 50: +return (int)Tokens.tkParseModeExpression; + break; + case 51: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentMultiplication); return (int)Tokens.STAREQUAL; + break; + case 52: +yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.STARSTAR; + break; + case 53: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentSubtraction); return (int)Tokens.MINUSEQUAL; + break; + case 54: +yylval = new SPythonParserYacc.ValueType(); yylval.ti = new token_info(yytext); return (int)Tokens.ARROW; + break; + case 55: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentAddition); return (int)Tokens.PLUSEQUAL; + break; + case 56: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Equal); return (int)Tokens.EQUAL; + break; + case 57: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.IntegerDivision); return (int)Tokens.SLASHSLASH; + break; + case 58: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentDivision); return (int)Tokens.DIVEQUAL; + break; + case 59: +yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentIntDivision); return (int)Tokens.INTDIVISIONEQUAL; + break; + case 60: +yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_fstring(yytext,currentLexLocation); + return (int)Tokens.FSTRINGNUM; + break; + case 61: +yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.stn = parserTools.create_string_const(yytext,currentLexLocation); + return (int)Tokens.STRINGNUM; + break; + case 62: + case 63: + case 64: +yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_double_const(yytext,currentLexLocation); + return (int)Tokens.REALNUM; + break; + case 65: +yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_bigint_const(yytext,currentLexLocation); + return (int)Tokens.BIGINT; + break; + default: + break; + } +#pragma warning restore 162 +#endregion + } + } + } // end try + finally { +// User-specified epilog to scan() +prevLexLocation = yylloc; + if (currentLexLocation != null) + yylloc = currentLexLocation; + else + yylloc = CurrentLexLocation; + + currentLexLocation = null; +// End, user-specified epilog + } // end finally + } + +#if BACKUP + Result Recurse2(ref Context ctx, int next) + { + // Assert: at entry "state" is an accept state AND + // NextState(state, code) != goStart AND + // NextState(state, code) is not an accept state. + // + SaveStateAndPos(ref ctx); + state = next; + GetCode(); + + while ((next = NextState()) > eofNum) + { + if (state <= maxAccept && next > maxAccept) // need to update backup data + SaveStateAndPos(ref ctx); + state = next; + if (state == eofNum) return Result.accept; + GetCode(); + } + return (state <= maxAccept ? Result.accept : Result.noMatch); + } + + void SaveStateAndPos(ref Context ctx) + { + ctx.bPos = buffer.Pos; + ctx.rPos = readPos; + ctx.cCol = cCol; + ctx.lNum = lNum; + ctx.state = state; + ctx.cChr = code; + } + + void RestoreStateAndPos(ref Context ctx) + { + buffer.Pos = ctx.bPos; + readPos = ctx.rPos; + cCol = ctx.cCol; + lNum = ctx.lNum; + state = ctx.state; + code = ctx.cChr; + } + +#endif // BACKUP + + // ============= End of the tokenizer code ================ + +#if STACK + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void yy_clear_stack() { scStack.Clear(); } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal int yy_top_state() { return scStack.Peek(); } + + internal void yy_push_state(int state) + { + scStack.Push(currentScOrd); + BEGIN(state); + } + + internal void yy_pop_state() + { + // Protect against input errors that pop too far ... + if (scStack.Count > 0) { + int newSc = scStack.Pop(); + BEGIN(newSc); + } // Otherwise leave stack unchanged. + } + #endif // STACK + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void ECHO() { Console.Out.Write(yytext); } + +#region UserCodeSection + +public LexLocation CurrentLexLocation +{ + get { + return new LexLocation(tokLin, tokCol, tokELin, tokECol, parserTools.currentFileName); + } +} + +public override void yyerror(string format, params object[] args) +{ + string expected = parserTools.ExpectedToken(last_line_needed_colon == prevLexLocation.StartLine, args); + LexLocation lexLocation = parserTools.GetLexLocation( + yytext, expected, prevLexLocation, CurrentLexLocation); + + if (yytext == "#{" && expected == "END_OF_LINE") { + parserTools.AddErrorFromResource("WRONG_INDENT", lexLocation); + } + else { + string errorMsg = parserTools.CreateErrorString(yytext, expected); + parserTools.AddError(errorMsg, lexLocation); + } +} + +protected override bool yywrap() +{ + return true; +} + +#endregion + } // end class $Scanner + +// ============================================================== +// +// This code automatically produced from an embedded resource. +// Do not edit this file, or it will become incompatible with +// the specification from which it was generated. +// +// ============================================================== + +// Code copied from GPLEX embedded resource + [Serializable] + public class BufferException : Exception + { + public BufferException() { } + public BufferException(string message) : base(message) { } + public BufferException(string message, Exception innerException) + : base(message, innerException) { } + protected BufferException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } + + public abstract class ScanBuff + { + private string fileNm; + + public const int EndOfFile = -1; + public const int UnicodeReplacementChar = 0xFFFD; + + public bool IsFile { get { return (fileNm != null); } } + public string FileName { get { return fileNm; } set { fileNm = value; } } + + public abstract int Pos { get; set; } + public abstract int Read(); + public virtual void Mark() { } + + public abstract string GetString(int begin, int limit); + + public static ScanBuff GetBuffer(string source) + { + return new StringBuffer(source); + } + + public static ScanBuff GetBuffer(IList source) + { + return new LineBuffer(source); + } + + public static ScanBuff GetBuffer(Stream source) + { + return new BuildBuffer(source); + } + +#if (!BYTEMODE) + public static ScanBuff GetBuffer(Stream source, int fallbackCodePage) + { + return new BuildBuffer(source, fallbackCodePage); + } +#endif + } + + #region Buffer classes + + // ============================================================== + // ===== Definitions for various ScanBuff derived classes ==== + // ============================================================== + // =============== String input ================ + // ============================================================== + + /// + /// This class reads characters from a single string as + /// required, for example, by Visual Studio language services + /// + sealed class StringBuffer : ScanBuff + { + string str; // input buffer + int bPos; // current position in buffer + int sLen; + + public StringBuffer(string source) + { + this.str = source; + this.sLen = source.Length; + this.FileName = null; + } + + public override int Read() + { + if (bPos < sLen) return str[bPos++]; + else if (bPos == sLen) { bPos++; return '\n'; } // one strike, see new line + else { bPos++; return EndOfFile; } // two strikes and you're out! + } + + public override string GetString(int begin, int limit) + { + // "limit" can be greater than sLen with the BABEL + // option set. Read returns a "virtual" EOL if + // an attempt is made to read past the end of the + // string buffer. Without the guard any attempt + // to fetch yytext for a token that includes the + // EOL will throw an index exception. + if (limit > sLen) limit = sLen; + if (limit <= begin) return ""; + else return str.Substring(begin, limit - begin); + } + + public override int Pos + { + get { return bPos; } + set { bPos = value; } + } + + public override string ToString() { return "StringBuffer"; } + } + + // ============================================================== + // The LineBuff class contributed by Nigel Horspool, + // nigelh@cs.uvic.cs + // ============================================================== + + sealed class LineBuffer : ScanBuff + { + IList line; // list of source lines from a file + int numLines; // number of strings in line list + string curLine; // current line in that list + int cLine; // index of current line in the list + int curLen; // length of current line + int curLineStart; // position of line start in whole file + int curLineEnd; // position of line end in whole file + int maxPos; // max position ever visited in whole file + int cPos; // ordinal number of code in source + + // Constructed from a list of strings, one per source line. + // The lines have had trailing '\n' characters removed. + public LineBuffer(IList lineList) + { + line = lineList; + numLines = line.Count; + cPos = curLineStart = 0; + curLine = (numLines > 0 ? line[0] : ""); + maxPos = curLineEnd = curLen = curLine.Length; + cLine = 1; + FileName = null; + } + + public override int Read() + { + if (cPos < curLineEnd) + return curLine[cPos++ - curLineStart]; + if (cPos++ == curLineEnd) + return '\n'; + if (cLine >= numLines) + return EndOfFile; + curLine = line[cLine]; + curLen = curLine.Length; + curLineStart = curLineEnd + 1; + curLineEnd = curLineStart + curLen; + if (curLineEnd > maxPos) + maxPos = curLineEnd; + cLine++; + return curLen > 0 ? curLine[0] : '\n'; + } + + // To speed up searches for the line containing a position + private int cachedPosition; + private int cachedIxdex; + private int cachedLineStart; + + // Given a position pos within the entire source, the results are + // ix -- the index of the containing line + // lstart -- the position of the first character on that line + private void findIndex(int pos, out int ix, out int lstart) + { + if (pos >= cachedPosition) + { + ix = cachedIxdex; lstart = cachedLineStart; + } + else + { + ix = lstart = 0; + } + for (; ; ) + { + int len = line[ix].Length + 1; + if (pos < lstart + len) break; + lstart += len; + ix++; + } + cachedPosition = pos; + cachedIxdex = ix; + cachedLineStart = lstart; + } + + public override string GetString(int begin, int limit) + { + if (begin >= maxPos || limit <= begin) return ""; + int endIx, begIx, endLineStart, begLineStart; + findIndex(begin, out begIx, out begLineStart); + int begCol = begin - begLineStart; + findIndex(limit, out endIx, out endLineStart); + int endCol = limit - endLineStart; + string s = line[begIx]; + if (begIx == endIx) + { + // the usual case, substring all on one line + return (endCol <= s.Length) ? + s.Substring(begCol, endCol - begCol) + : s.Substring(begCol) + "\n"; + } + // the string spans multiple lines, yuk! + StringBuilder sb = new StringBuilder(); + if (begCol < s.Length) + sb.Append(s.Substring(begCol)); + for (; ; ) + { + sb.Append("\n"); + s = line[++begIx]; + if (begIx >= endIx) break; + sb.Append(s); + } + if (endCol <= s.Length) + { + sb.Append(s.Substring(0, endCol)); + } + else + { + sb.Append(s); + sb.Append("\n"); + } + return sb.ToString(); + } + + public override int Pos + { + get { return cPos; } + set + { + cPos = value; + findIndex(cPos, out cLine, out curLineStart); + curLine = line[cLine]; + curLineEnd = curLineStart + curLine.Length; + } + } + + public override string ToString() { return "LineBuffer"; } + } + + + // ============================================================== + // ===== class BuildBuff : for unicode text files ======== + // ============================================================== + + class BuildBuffer : ScanBuff + { + // Double buffer for char stream. + class BufferElement + { + StringBuilder bldr = new StringBuilder(); + StringBuilder next = new StringBuilder(); + int minIx; + int maxIx; + int brkIx; + bool appendToNext; + + internal BufferElement() { } + + internal int MaxIndex { get { return maxIx; } } + // internal int MinIndex { get { return minIx; } } + + internal char this[int index] + { + get + { + if (index < minIx || index >= maxIx) + throw new BufferException("Index was outside data buffer"); + else if (index < brkIx) + return bldr[index - minIx]; + else + return next[index - brkIx]; + } + } + + internal void Append(char[] block, int count) + { + maxIx += count; + if (appendToNext) + this.next.Append(block, 0, count); + else + { + this.bldr.Append(block, 0, count); + brkIx = maxIx; + appendToNext = true; + } + } + + internal string GetString(int start, int limit) + { + if (limit <= start) + return ""; + if (start >= minIx && limit <= maxIx) + if (limit < brkIx) // String entirely in bldr builder + return bldr.ToString(start - minIx, limit - start); + else if (start >= brkIx) // String entirely in next builder + return next.ToString(start - brkIx, limit - start); + else // Must do a string-concatenation + return + bldr.ToString(start - minIx, brkIx - start) + + next.ToString(0, limit - brkIx); + else + throw new BufferException("String was outside data buffer"); + } + + internal void Mark(int limit) + { + if (limit > brkIx + 16) // Rotate blocks + { + StringBuilder temp = bldr; + bldr = next; + next = temp; + next.Length = 0; + minIx = brkIx; + brkIx = maxIx; + } + } + } + + BufferElement data = new BufferElement(); + + int bPos; // Postion index in the StringBuilder + BlockReader NextBlk; // Delegate that serves char-arrays; + + private string EncodingName + { + get + { + StreamReader rdr = NextBlk.Target as StreamReader; + return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName); + } + } + + public BuildBuffer(Stream stream) + { + FileStream fStrm = (stream as FileStream); + if (fStrm != null) FileName = fStrm.Name; + NextBlk = BlockReaderFactory.Raw(stream); + } + +#if (!BYTEMODE) + public BuildBuffer(Stream stream, int fallbackCodePage) + { + FileStream fStrm = (stream as FileStream); + if (fStrm != null) FileName = fStrm.Name; + NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage); + } +#endif + + /// + /// Marks a conservative lower bound for the buffer, + /// allowing space to be reclaimed. If an application + /// needs to call GetString at arbitrary past locations + /// in the input stream, Mark() is not called. + /// + public override void Mark() { data.Mark(bPos - 2); } + + public override int Pos + { + get { return bPos; } + set { bPos = value; } + } + + + /// + /// Read returns the ordinal number of the next char, or + /// EOF (-1) for an end of stream. Note that the next + /// code point may require *two* calls of Read(). + /// + /// + public override int Read() + { + // + // Characters at positions + // [data.offset, data.offset + data.bldr.Length) + // are available in data.bldr. + // + if (bPos < data.MaxIndex) + { + // ch0 cannot be EOF + return (int)data[bPos++]; + } + else // Read from underlying stream + { + // Experimental code, blocks of page size + char[] chrs = new char[4096]; + int count = NextBlk(chrs, 0, 4096); + if (count == 0) + return EndOfFile; + else + { + data.Append(chrs, count); + return (int)data[bPos++]; + } + } + } + + public override string GetString(int begin, int limit) + { + return data.GetString(begin, limit); + } + + public override string ToString() + { + return "StringBuilder buffer, encoding: " + this.EncodingName; + } + } + + // =============== End ScanBuff-derived classes ================== + + public delegate int BlockReader(char[] block, int index, int number); + + // A delegate factory, serving up a delegate that + // reads a block of characters from the underlying + // encoded stream, via a StreamReader object. + // + public static class BlockReaderFactory + { + public static BlockReader Raw(Stream stream) + { + return delegate(char[] block, int index, int number) + { + byte[] b = new byte[number]; + int count = stream.Read(b, 0, number); + int i = 0; + int j = index; + for (; i < count; i++, j++) + block[j] = (char)b[i]; + return count; + }; + } + +#if (!BYTEMODE) + public static BlockReader Get(Stream stream, int fallbackCodePage) + { + Encoding encoding; + int preamble = Preamble(stream); + + if (preamble != 0) // There is a valid BOM here! + encoding = Encoding.GetEncoding(preamble); + else if (fallbackCodePage == -1) // Fallback is "raw" bytes + return Raw(stream); + else if (fallbackCodePage != -2) // Anything but "guess" + encoding = Encoding.GetEncoding(fallbackCodePage); + else // This is the "guess" option + { + int guess = new Guesser(stream).GuessCodePage(); + stream.Seek(0, SeekOrigin.Begin); + if (guess == -1) // ==> this is a 7-bit file + encoding = Encoding.ASCII; + else if (guess == 65001) + encoding = Encoding.UTF8; + else // ==> use the machine default + encoding = Encoding.Default; + } + StreamReader reader = new StreamReader(stream, encoding); + return reader.Read; + } + + static int Preamble(Stream stream) + { + int b0 = stream.ReadByte(); + int b1 = stream.ReadByte(); + + if (b0 == 0xfe && b1 == 0xff) + return 1201; // UTF16BE + if (b0 == 0xff && b1 == 0xfe) + return 1200; // UTF16LE + + int b2 = stream.ReadByte(); + if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf) + return 65001; // UTF8 + // + // There is no unicode preamble, so we + // return denoter for the machine default. + // + stream.Seek(0, SeekOrigin.Begin); + return 0; + } +#endif // !BYTEMODE + } + #endregion Buffer classes + + // ============================================================== + // ============ class CodePageHandling ============= + // ============================================================== + + public static class CodePageHandling + { + public static int GetCodePage(string option) + { + string command = option.ToUpperInvariant(); + if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase)) + command = command.Substring(9); + try + { + if (command.Equals("RAW")) + return -1; + else if (command.Equals("GUESS")) + return -2; + else if (command.Equals("DEFAULT")) + return 0; + else if (char.IsDigit(command[0])) + return int.Parse(command, CultureInfo.InvariantCulture); + else + { + Encoding enc = Encoding.GetEncoding(command); + return enc.CodePage; + } + } + catch (FormatException) + { + Console.Error.WriteLine( + "Invalid format \"{0}\", using machine default", option); + } + catch (ArgumentException) + { + Console.Error.WriteLine( + "Unknown code page \"{0}\", using machine default", option); + } + return 0; + } + } +#region guesser +#if (!BYTEMODE) + // ============================================================== + // ============ Encoding Guesser ============= + // ============================================================== + + /// + /// This class provides a simple finite state automaton that + /// scans the file looking for (1) valid UTF-8 byte patterns, + /// (2) bytes >= 0x80 which are not part of a UTF-8 sequence. + /// The method then guesses whether it is UTF-8 or maybe some + /// local machine default encoding. This works well for the + /// various Latin encodings. + /// + internal class Guesser + { + ScanBuff buffer; + + public int GuessCodePage() { return Scan(); } + + const int maxAccept = 10; + const int initial = 0; + const int eofNum = 0; + const int goStart = -1; + const int INITIAL = 0; + const int EndToken = 0; + + #region user code + /* + * Reads the bytes of a file to determine if it is + * UTF-8 or a single-byte code page file. + */ + public long utfX; + public long uppr; + #endregion user code + + int state; + int currentStart = startState[0]; + int code; + + #region ScannerTables + static int[] startState = new int[] { 11, 0 }; + + #region CharacterMap + static sbyte[] map = new sbyte[256] { +/* '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 }; + #endregion + + static sbyte[][] nextState = new sbyte[][] { + new sbyte[] {0, 0, 0, 0, 0, 0}, + new sbyte[] {-1, -1, 10, -1, -1, -1}, + new sbyte[] {-1, -1, -1, -1, -1, -1}, + new sbyte[] {-1, -1, 8, -1, -1, -1}, + new sbyte[] {-1, -1, 5, -1, -1, -1}, + new sbyte[] {-1, -1, 6, -1, -1, -1}, + new sbyte[] {-1, -1, 7, -1, -1, -1}, + null, + new sbyte[] {-1, -1, 9, -1, -1, -1}, + null, + null, + new sbyte[] {-1, 1, 2, 3, 4, 2} + }; + + + [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] + // Reason for suppression: cannot have self-reference in array initializer. + static Guesser() + { + nextState[7] = nextState[2]; + nextState[9] = nextState[2]; + nextState[10] = nextState[2]; + } + + int NextState() + { + if (code == ScanBuff.EndOfFile) + return eofNum; + else + return nextState[state][map[code]]; + } + #endregion + + public Guesser(System.IO.Stream file) { SetSource(file); } + + public void SetSource(System.IO.Stream source) + { + this.buffer = new BuildBuffer(source); + code = buffer.Read(); + } + + int Scan() + { + for (; ; ) + { + int next; + state = currentStart; + while ((next = NextState()) == goStart) + code = buffer.Read(); + + state = next; + code = buffer.Read(); + + while ((next = NextState()) > eofNum) + { + state = next; + code = buffer.Read(); + } + if (state <= maxAccept) + { + #region ActionSwitch +#pragma warning disable 162 + switch (state) + { + case eofNum: + switch (currentStart) + { + case 11: + if (utfX == 0 && uppr == 0) return -1; /* raw ascii */ + else if (uppr * 10 > utfX) return 0; /* default code page */ + else return 65001; /* UTF-8 encoding */ + break; + } + return EndToken; + case 1: // Recognized '{Upper128}', Shortest string "\xC0" + case 2: // Recognized '{Upper128}', Shortest string "\x80" + case 3: // Recognized '{Upper128}', Shortest string "\xE0" + case 4: // Recognized '{Upper128}', Shortest string "\xF0" + uppr++; + break; + case 5: // Recognized '{Utf8pfx4}{Utf8cont}', Shortest string "\xF0\x80" + uppr += 2; + break; + case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}', Shortest string "\xF0\x80\x80" + uppr += 3; + break; + case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}', Shortest string "\xF0\x80\x80\x80" + utfX += 3; + break; + case 8: // Recognized '{Utf8pfx3}{Utf8cont}', Shortest string "\xE0\x80" + uppr += 2; + break; + case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}', Shortest string "\xE0\x80\x80" + utfX += 2; + break; + case 10: // Recognized '{Utf8pfx2}{Utf8cont}', Shortest string "\xC0\x80" + utfX++; + break; + default: + break; + } +#pragma warning restore 162 + #endregion + } + } + } + } // end class Guesser + +#endif // !BYTEMODE +#endregion + +// End of code copied from embedded resource + +} // end namespace diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.lex b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.lex new file mode 100644 index 000000000..8e1a01c55 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonLexer.lex @@ -0,0 +1,240 @@ +%using SPythonParser; +%using QUT.Gppg; +%using PascalABCCompiler.SyntaxTree; +%using PascalABCCompiler.ParserTools; +%using SPythonParserYacc; +%using SPythonParser; + +%namespace SPythonParser + +Alpha [[:IsLetter:]_] +NonZeroDigit [1-9] +Digit 0|{NonZeroDigit} +AlphaDigit {Alpha}|{Digit} +INTNUM ({NonZeroDigit}(_?{Digit})*)|0 +REALNUM ({INTNUM}?\.{INTNUM})|({INTNUM}\.) +STRINGNUM (\'([^\'\n\\]|\\.)*\')|(\"([^\"\n\\]|\\.)*\") +FSTRINGNUM f((\'([^\'\n\\]|\\.)*\')|(\"([^\"\n\\]|\\.)*\")) +ID {Alpha}{AlphaDigit}* +BIGINTNUM {INTNUM}bi + +%{ + private SPythonKeywords keywords; + public SPythonParserTools parserTools; + public List Defines = new List(); + private int last_line_needed_colon = -1; + private LexLocation currentLexLocation; + private LexLocation prevLexLocation + = new LexLocation(-1, -1, -1, -1, ""); + + public Scanner(string text, SPythonParserTools parserTools, PascalABCCompiler.Parsers.BaseKeywords keywords, List defines = null) + { + this.parserTools = parserTools; + this.keywords = (SPythonKeywords)keywords; + if (defines != null) + this.Defines.AddRange(defines); + SetSource(text, 0); + } +%} + +%% + +{INTNUM} { + yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_spy_int_const(yytext,currentLexLocation); + return (int)Tokens.INTNUM; +} + +{BIGINTNUM} { + yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_bigint_const(yytext,currentLexLocation); + return (int)Tokens.BIGINT; +} + +{REALNUM} { + yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_double_const(yytext,currentLexLocation); + return (int)Tokens.REALNUM; +} + +{STRINGNUM} { + yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.stn = parserTools.create_string_const(yytext,currentLexLocation); + return (int)Tokens.STRINGNUM; +} + +{FSTRINGNUM} { + yylval = new SPythonParserYacc.ValueType(); + currentLexLocation = CurrentLexLocation; + yylval.ex = parserTools.create_fstring(yytext,currentLexLocation); + return (int)Tokens.FSTRINGNUM; +} + +{ID} { + string cur_yytext = yytext; + int res = keywords.KeywordOrIDToken(cur_yytext); + currentLexLocation = CurrentLexLocation; + yylval = new SPythonParserYacc.ValueType(); + switch (res) + { + case (int)Tokens.ID: + yylval.id = parserTools.create_ident(cur_yytext, currentLexLocation); + break; + case (int)Tokens.AND: + yylval.op = new op_type_node(Operators.LogicalAND, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.OR: + yylval.op = new op_type_node(Operators.LogicalOR, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.NOT: + yylval.op = new op_type_node(Operators.LogicalNOT, currentLexLocation); + yylval.op.text = cur_yytext; + break; + case (int)Tokens.IF: + case (int)Tokens.ELIF: + case (int)Tokens.ELSE: + case (int)Tokens.WHILE: + case (int)Tokens.FOR: + case (int)Tokens.DEF: + last_line_needed_colon = CurrentLexLocation.StartLine; + break; + case (int)Tokens.CLASS: + case (int)Tokens.LAMBDA: + parserTools.AddErrorFromResource("UNSUPPORTED_CONSTRUCTION_{0}", currentLexLocation, yytext); + break; + } + + return res; +} + +"//=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentIntDivision); return (int)Tokens.INTDIVISIONEQUAL; } + +"+=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentAddition); return (int)Tokens.PLUSEQUAL; } +"-=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentSubtraction); return (int)Tokens.MINUSEQUAL; } +"*=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentMultiplication); return (int)Tokens.STAREQUAL; } +"/=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentDivision); return (int)Tokens.DIVEQUAL; } + +"+" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Plus); return (int)Tokens.PLUS; } +"-" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Minus); return (int)Tokens.MINUS; } +"*" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Multiplication); return (int)Tokens.STAR; } +"//" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.IntegerDivision); return (int)Tokens.SLASHSLASH; } +"/" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Division); return (int)Tokens.DIVIDE; } +"%" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.ModulusRemainder); return (int)Tokens.PERCENTAGE; } + +"<=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LessEqual); return (int)Tokens.LESSEQUAL; } +">=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.GreaterEqual); return (int)Tokens.GREATEREQUAL; } +"<" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Less); return (int)Tokens.LESS; } +">" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Greater); return (int)Tokens.GREATER; } +"==" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Equal); return (int)Tokens.EQUAL; } +"!=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.NotEqual); return (int)Tokens.NOTEQUAL; } +"=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Assignment); return (int)Tokens.ASSIGN; } + +//"~" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseNOT); return (int)Tokens.BINNOT; } +"~" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalNOT); return (int)Tokens.BINNOT; } +//"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseAND); return (int)Tokens.BINAND; } +"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalAND); return (int)Tokens.BINAND; } +//"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseOR); return (int)Tokens.BINOR; } +"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalOR); return (int)Tokens.BINOR; } +"<<" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseLeftShift); return (int)Tokens.SHL; } +">>" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseRightShift); return (int)Tokens.SHR; } +"^" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseXOR); return (int)Tokens.BINXOR; } + +//"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseAND); return (int)Tokens.BINAND; } +"&=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseAND); return (int)Tokens.BINANDEQUAL; } +//"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseOR); return (int)Tokens.BINOR; } +"|=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseOR); return (int)Tokens.BINOREQUAL; } +"<<=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseLeftShift); return (int)Tokens.SHLEQUAL; } +">>=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseRightShift); return (int)Tokens.SHREQUAL; } +"^=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseXOR); return (int)Tokens.BINXOREQUAL; } + + +"#{" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.INDENT; } +"#}" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.UNINDENT; } +"#;" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.END_OF_LINE; } + +"{" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACE; } +"}" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACE; } +"[" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACKET; } +"]" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACKET; } + +"->" { yylval = new SPythonParserYacc.ValueType(); yylval.ti = new token_info(yytext); return (int)Tokens.ARROW; } + +"." { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.DOT; } +"," { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COMMA; } +":" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COLON; } +";" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.SEMICOLON; } +"(" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LPAR; } +")" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RPAR; } +"**" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.STARSTAR; } + +\<\\> { return (int)Tokens.tkParseModeExpression; } +\<\\> { return (int)Tokens.tkParseModeStatement; } +\<\\> { return (int)Tokens.tkParseModeType; } + +"#!" { + parserTools.AddErrorFromResource("WRONG_INDENT", + new LexLocation(CurrentLexLocation.StartLine + 1, 0, CurrentLexLocation.StartLine + 1, 0)); + return (int)Tokens.EOF; +} + +"#b" { + parserTools.AddErrorFromResource("PROGRAM_BEGIN_WITH_INDENT", + CurrentLexLocation); + return (int)Tokens.EOF; +} + +"#$" { + return (int)Tokens.END_OF_FILE; +} + +[^ \r\n] { + parserTools.AddErrorFromResource("UNEXPECTED_TOKEN_{0}", CurrentLexLocation, yytext); + return (int)Tokens.EOF; +} + +%{ + //yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol); + prevLexLocation = yylloc; + if (currentLexLocation != null) + yylloc = currentLexLocation; + else + yylloc = CurrentLexLocation; + + currentLexLocation = null; +%} + +%% + +public LexLocation CurrentLexLocation +{ + get { + return new LexLocation(tokLin, tokCol, tokELin, tokECol, parserTools.currentFileName); + } +} + +public override void yyerror(string format, params object[] args) +{ + string expected = parserTools.ExpectedToken(last_line_needed_colon == prevLexLocation.StartLine, args); + LexLocation lexLocation = parserTools.GetLexLocation( + yytext, expected, prevLexLocation, CurrentLexLocation); + + if (yytext == "#{" && expected == "END_OF_LINE") { + parserTools.AddErrorFromResource("WRONG_INDENT", lexLocation); + } + else { + string errorMsg = parserTools.CreateErrorString(yytext, expected); + parserTools.AddError(errorMsg, lexLocation); + } +} + +protected override bool yywrap() +{ + return true; +} + diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.cs new file mode 100644 index 000000000..ea1d9dd1a --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.cs @@ -0,0 +1,146 @@ +using System.IO; +using System.Collections.Generic; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.Parsers; +using SPythonParserYacc; +using PascalABCCompiler.SyntaxTreeConverters; + + + +namespace SPythonParser +{ + + public class SPythonLanguageParser : BaseParser + { + public List SyntaxTreeConvertersForIntellisense { get; set; } + + public override void Reset() + { + CompilerDirectives = new List(); + + Errors.Clear(); + } + + protected override void PreBuildTree(string FileName) + { + CompilerDirectives = new List(); + + } + + protected override syntax_tree_node BuildTreeInNormalMode(string FileName, string Text, bool compilingNotMainProgram, List DefinesList = null) + { + Errors.Clear(); + Warnings.Clear(); + + syntax_tree_node root = Parse(Text, FileName, false, compilingNotMainProgram, DefinesList); + + if (Errors.Count > 0) + return null; + + if (root != null && root is compilation_unit) + (root as compilation_unit).file_name = FileName; + + return root; + } + + public syntax_tree_node Parse(string Text, string fileName, bool buildTreeForFormatter = false, bool compilingNotMainProgram = false, List definesList = null) + { +#if DEBUG +#if _ERR + FileInfo f = new FileInfo(FileName); + var sv = Path.ChangeExtension(FileName,".grmtrack1"); + var sw = new StreamWriter(sv); + Console.SetError(sw); +#endif +#endif + SPythonParserTools parserTools = new SPythonParserTools(Errors, Warnings, LanguageInformation.ValidDirectives, buildTreeForFormatter, false, + Path.GetFullPath(fileName), CompilerDirectives); // контекст сканера и парсера + + + IndentArranger ia = new IndentArranger(); + ia.ProcessSourceText(ref Text); + + var scanner = new Scanner(Text, parserTools, LanguageInformation.KeywordsStorage, definesList); + + SPythonGPPGParser parser = new SPythonGPPGParser(scanner, parserTools, compilingNotMainProgram); + + if (!parser.Parse()) + if (Errors.Count == 0) + parserTools.AddErrorFromResource("UNEXPECTED_SYNTAX_ERROR", null); +#if DEBUG +#if _ERR + sw.Close(); +#endif +#endif + return parser.root; + } + + protected override syntax_tree_node BuildTreeInTypeExprMode(string FileName, string Text) + { + Text = string.Concat("<>", Text); + + var expr = Parse(Text, FileName) as expression; + + if (expr == null) + return null; + + foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense) + { + expr = (expression)converter.Convert(expr, true); + } + + return expr; + } + + protected override syntax_tree_node BuildTreeInExprMode(string FileName, string Text) + { + if (Text == string.Empty) + return null; + + Text = string.Concat("<>", Text); + + var expr = Parse(Text, FileName) as expression; + + if (expr == null) + return null; + + foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense) + { + expr = (expression)converter.Convert(expr, true); + } + + return expr; + } + + protected override syntax_tree_node BuildTreeInSpecialMode(string FileName, string Text, bool compilingNotMainProgram) + { + Errors.Clear(); + + return Parse(Text, FileName, compilingNotMainProgram); + } + + protected override syntax_tree_node BuildTreeInFormatterMode(string FileName, string Text) + { + Errors.Clear(); + + return Parse(Text, FileName, true); + } + + protected override syntax_tree_node BuildTreeInStatementMode(string FileName, string Text) + { + Text = string.Concat("<>", Text); + + var st = Parse(Text, FileName) as statement; + + if (st == null) + return null; + + foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense) + { + st = (statement)converter.Convert(st, true); + } + + return st; + } + } +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.csproj b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.csproj new file mode 100644 index 000000000..209cf371c --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.csproj @@ -0,0 +1,21 @@ + + + + net40 + + Languages.SPython.Frontend.Wrapping + + ..\..\..\bin\ + false + + false + + + + + + + + + + \ No newline at end of file diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.y b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.y new file mode 100644 index 000000000..bbc9dda99 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParser.y @@ -0,0 +1,1098 @@ +%{ + public syntax_tree_node root; + public List errors; + // public string current_file_name; + // public int max_errors = 10; + public SPythonParserTools parserTools; + public List CompilerDirectives; + public ParserLambdaHelper lambdaHelper = new ParserLambdaHelper(); + public bool is_unit_to_be_parsed = false; + + public SPythonGPPGParser(AbstractScanner scanner, SPythonParserTools parserTools, + bool isUnitToBeParsed) : base(scanner) + { + this.parserTools = parserTools; + this.is_unit_to_be_parsed = isUnitToBeParsed; + } +%} + +%using PascalABCCompiler.SyntaxTree; +%using PascalABCCompiler.ParserTools; +%using PascalABCCompiler.Errors; +%using System.Linq; +%using System.Collections.Generic; +%using System.IO; +%using SPythonParser; + +%output = SPythonParserYacc.cs +%partial +%parsertype SPythonGPPGParser + +%namespace SPythonParserYacc + +%union { + public expression ex; + public ident id; + public Object ob; + public op_type_node op; + public syntax_tree_node stn; + public token_info ti; + public type_definition td; +} + +%token FOR IN WHILE IF ELSE ELIF DEF RETURN BREAK CONTINUE IMPORT FROM GLOBAL AS PASS CLASS LAMBDA EXIT NEW IS +%token INDENT UNINDENT END_OF_FILE END_OF_LINE DECLTYPE +%token INTNUM REALNUM TRUE FALSE BIGINT FSTRINGNUM +%token LPAR RPAR LBRACE RBRACE LBRACKET RBRACKET DOT COMMA COLON SEMICOLON ARROW +%token STRINGNUM +%token ASSIGN PLUSEQUAL MINUSEQUAL STAREQUAL DIVEQUAL BINXOREQUAL SHLEQUAL SHREQUAL BINANDEQUAL BINOREQUAL INTDIVISIONEQUAL +%token PLUS MINUS STAR DIVIDE SLASHSLASH PERCENTAGE +%token ID +%token LESS GREATER LESSEQUAL GREATEREQUAL EQUAL NOTEQUAL +%token AND OR NOT STARSTAR BINNOT BINXOR SHL SHR BINAND BINOR +%token tkParseModeExpression tkParseModeStatement tkParseModeType + +%left OR +%left AND +%left NOT +%left LESS GREATER LESSEQUAL GREATEREQUAL EQUAL NOTEQUAL +%left BINOR +%left BINXOR +%left BINAND +%left SHL SHR +%left PLUS MINUS +%left STAR DIVIDE SLASHSLASH PERCENTAGE +%right STARSTAR +%left BINNOT + +%type ident dotted_ident func_name_ident type_decl_identifier +%type expr proc_func_call const_value variable optional_condition act_param new_expr is_expr variable_as_type +%type act_param_list optional_act_param_list proc_func_decl return_stmt break_stmt continue_stmt global_stmt pass_stmt +%type var_stmt assign_stmt if_stmt stmt proc_func_call_stmt while_stmt for_stmt optional_else optional_elif exit_stmt +%type expr_list +%type stmt_list block +%type program param_name form_param_sect form_param_list optional_form_param_list dotted_ident_list +%type ident_as_ident ident_as_ident_list ident_list +%type proc_func_header type_ref simple_type_identifier template_type +%type import_clause template_type_params template_param_list parts stmt_or_expression expr_mapping_list +%type optional_semicolon end_of_line variable_list +%type assign_type +%type expr_mapping +%type list_constant set_constant dict_constant generator_object generator_object_for_dict +%type tuple_expr assign_right_part turbo_tuple_expr + +%start program + +/* +ident = identifier +expr = expression +stmt = statement +proc = procedure +func = function +const = constant +decl = declaration +param = parameter +assign = assignment +form = formal +sect = section +act = actual +*/ + +%% +program + : stmt_list optional_semicolon END_OF_FILE + { + // main program + if (!is_unit_to_be_parsed) { + var stl = $1 as statement_list; + stl.left_logical_bracket = new token_info(""); + stl.right_logical_bracket = new token_info(""); + var bl = new block(new declarations(), stl, @$); + root = $$ = NewProgramModule(null, null, new uses_list(), bl, $2, @$); + root.source_context = bl.source_context; + } + // unit + else { + var interface_part = new interface_node(new declarations(), new uses_list(), null, null); + var initialization_part = new initfinal_part(null, $1 as statement_list, null, null, null, @$); + + root = $$ = new unit_module( + new unit_name(new ident(Path.GetFileNameWithoutExtension(parserTools.currentFileName)), + UnitHeaderKeyword.Unit, @$), interface_part, null, + initialization_part.initialization_sect, + initialization_part.finalization_sect, null, @$); + } + } + | parts END_OF_FILE + { + root = $1; + } + ; + +parts + : tkParseModeExpression expr + { $$ = $2; } + | tkParseModeExpression DECLTYPE type_decl_identifier + { $$ = $3; } + | tkParseModeType variable_as_type + { $$ = $2; } + | tkParseModeStatement stmt_or_expression + { $$ = $2; } + ; + +type_decl_identifier + : ident + { + $$ = $1; + } + | ident template_type_params + { + $$ = new template_type_name($1.name, $2 as ident_list, @$); + } + ; + +variable_as_type + : dotted_ident + { + $$ = $1; + } + | dotted_ident template_type_params + { + $$ = new ident_with_templateparams($1 as addressed_value, $2 as template_param_list, @$); + } + ; + +stmt_or_expression + : expr + { $$ = new expression_as_statement($1,@$);} + | assign_stmt + { $$ = $1; } + | var_stmt + { $$ = $1; } + ; + +stmt_list + : stmt + { + $$ = new statement_list($1 as statement, @$); + } + | stmt_list end_of_line stmt + { + $$ = ($1 as statement_list).Add($3 as statement, @$); + } + ; + +stmt + : assign_stmt + { + $$ = $1; + } + | var_stmt + { + $$ = $1; + } + | if_stmt + { + $$ = $1; + } + | proc_func_call_stmt + { + $$ = $1; + } + | while_stmt + { + $$ = $1; + } + | for_stmt + { + $$ = $1; + } + | return_stmt + { + $$ = $1; + } + | break_stmt + { + $$ = $1; + } + | continue_stmt + { + $$ = $1; + } + | global_stmt + { + $$ = $1; + } + | pass_stmt + { + $$ = $1; + } + | exit_stmt + { + $$ = $1; + } + | proc_func_decl + { + $$ = new declarations_as_statement(new declarations($1 as procedure_definition, @$), @$); + } + | import_clause + { + $$ = $1; + } + ; + +import_clause + : IMPORT ident_as_ident_list + { + $$ = new import_statement($2 as as_statement_list, @$); + } + | FROM ident IMPORT ident_as_ident_list + { + $$ = new from_import_statement($2 as ident, false, $4 as as_statement_list, @$); + } + | FROM ident IMPORT STAR + { + $$ = new from_import_statement($2 as ident, true, null, @$); + } + ; + +pass_stmt + : PASS + { + $$ = new empty_statement(); + } + ; + +exit_stmt + : EXIT LPAR optional_act_param_list RPAR + { + parserTools.AddErrorFromResource("UNSUPPORTED_CONSTRUCTION_{0}", @$, "exit"); + } + ; + +global_stmt + : GLOBAL dotted_ident_list + { + $$ = new global_statement($2 as ident_list, @$); + } + ; + +ident + : ID + { + $$ = $1; + } + ; + +dotted_ident + : ident + { + $$ = $1; + } + | dotted_ident DOT ident + { + $$ = new ident($1.name + "." + $3.name, @$); + } + ; + +dotted_ident_list + : dotted_ident + { + $$ = new ident_list($1, @$); + } + | dotted_ident_list COMMA dotted_ident + { + $$ = ($1 as ident_list).Add($3, @$); + } + ; + +ident_as_ident + : ident AS ident + { + $$ = new as_statement($1, $3, @$); + } + | ident + { + $$ = new as_statement($1, $1, @$); + } + ; + +ident_as_ident_list + : ident_as_ident + { + $$ = new as_statement_list($1 as as_statement, @$); + } + | ident_as_ident_list COMMA ident_as_ident + { + $$ = ($1 as as_statement_list).Add($3 as as_statement, @$); + } + ; + +expr_mapping + : expr COLON expr + { + expression_list el = new expression_list(new List { $1, $3 }, @$); + $$ = new tuple_node(el, @$); + } + ; + +expr_mapping_list + : expr_mapping + { + $$ = new expression_list($1, @$); + } + | expr_mapping_list COMMA expr_mapping + { + $$ = ($1 as expression_list).Add($3, @$); + } + ; + +var_stmt + : variable COLON type_ref + { + var vds = new var_def_statement(new ident_list($1 as ident, @1), $3, null, definition_attribute.None, false, @$); + $$ = new var_statement(vds, @$); + } + | variable COLON type_ref ASSIGN expr + { + var vds = new var_def_statement(new ident_list($1 as ident, @1), $3, $5, definition_attribute.None, false, @$); + $$ = new var_statement(vds, @$); + } + ; + +assign_right_part + : expr + { + $$ = $1; + } + | turbo_tuple_expr + { + $$ = $1; + } + ; + +assign_stmt + : variable ASSIGN assign_right_part + { + if (!($1 is addressed_value)) + parserTools.AddErrorFromResource("LEFT_SIDE_CANNOT_BE_ASSIGNED_TO", @$); + $$ = new assign($1 as addressed_value, $3, $2.type, @$); + } + | variable assign_type assign_right_part + { + if (!($1 is addressed_value)) + parserTools.AddErrorFromResource("LEFT_SIDE_CANNOT_BE_ASSIGNED_TO", @$); + $$ = new assign($1 as addressed_value, $3, $2.type, @$); + } + | LPAR variable COMMA variable_list RPAR ASSIGN assign_right_part + { + // if False: + if ($6.type != Operators.Assignment) + parserTools.AddErrorFromResource("ONLY_BASE_ASSIGNMENT_FOR_TUPLE", @6); + ($4 as addressed_value_list).Insert(0, $2 as addressed_value); + ($4 as syntax_tree_node).source_context = LexLocation.MergeAll(@1, @2, @3, @4, @5); + $$ = new assign_tuple($4 as addressed_value_list, $7, @$); + } + | variable COMMA variable_list ASSIGN assign_right_part + { + // if False: + if ($4.type != Operators.Assignment) + parserTools.AddErrorFromResource("ONLY_BASE_ASSIGNMENT_FOR_TUPLE", @4); + ($3 as addressed_value_list).Insert(0, $1 as addressed_value); + ($3 as syntax_tree_node).source_context = LexLocation.MergeAll(@1, @2, @3); + $$ = new assign_tuple($3 as addressed_value_list, $5, @$); + } + ; + +assign_type + : PLUSEQUAL + { + $$ = $1; + } + | MINUSEQUAL + { + $$ = $1; + } + | STAREQUAL + { + $$ = $1; + } + | DIVEQUAL + { + $$ = $1; + } + | BINXOREQUAL + { + $$ = $1; + } + | SHLEQUAL + { + $$ = $1; + } + | SHREQUAL + { + $$ = $1; + } + | BINANDEQUAL + { + $$ = $1; + } + | BINOREQUAL + { + $$ = $1; + } + | INTDIVISIONEQUAL + { + $$ = $1; + } + ; + +expr + : expr IF expr ELSE expr + { + $$ = new question_colon_expression($3, $1, $5, @$); + } + | expr PLUS expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr STAR expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr DIVIDE expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr MINUS expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr LESS expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr GREATER expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr LESSEQUAL expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr GREATEREQUAL expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr EQUAL expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr NOTEQUAL expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr AND expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr OR expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr SLASHSLASH expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr PERCENTAGE expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr SHL expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr SHR expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr BINAND expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr BINOR expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr BINXOR expr + { + $$ = new bin_expr($1, $3, $2.type, @$); + } + | expr STARSTAR expr + { + addressed_value method_name = new ident("!pow", @$); + expression_list el = new expression_list(new List { $1, $3 }, @$); + $$ = new method_call(method_name, el, @$); + } + | expr IN expr + { + $$ = new bin_expr($1, $3, Operators.In, @$); + } + | expr NOT IN expr + { + // $$ = new bin_expr($1, $4, Operators.NotIn, @$); + $$ = new un_expr(new bin_expr($1, $4, Operators.In, @$),Operators.LogicalNOT,@$); + } + | MINUS expr + { + $$ = new un_expr($2, $1.type, @$); + } + | NOT expr + { + $$ = new un_expr($2, $1.type, @$); + } + | BINNOT expr + { + $$ = new un_expr($2, $1.type, @$); + } + | variable + { + $$ = $1; + } + | const_value + { + $$ = $1; + } + | new_expr + { + $$ = $1; + } + | is_expr + { + $$ = $1; + } + | tuple_expr + { + $$ = $1; + } + | LPAR expr RPAR + { + $$ = new bracket_expr($2, @$); + } + ; + +tuple_expr + : LPAR expr COMMA expr_list RPAR + { + // inherited from PABC + if (($4 as expression_list).Count > 6) + parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7", @$); + ($4 as expression_list).Insert(0, $2); + $$ = new tuple_node($4 as expression_list, @$); + } + ; + + // Способ задать кортеж без скобочек. + // Работает только для присваивания, типа + // a = 1, 2 или a, b = 1, 2 + // Название просто прикольное +turbo_tuple_expr + : expr COMMA expr_list + { + // inherited from PABC + if (($3 as expression_list).Count > 6) + parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7", @$); + ($3 as expression_list).Insert(0, $1); + $$ = new tuple_node($3 as expression_list, @$); + } + ; + +is_expr + : variable IS type_ref + { + $$ = parserTools.NewAsIsExpr($1, op_typecast.is_op, $3, @$); + } + ; + +new_expr + : NEW type_ref LPAR optional_act_param_list RPAR + { + $$ = new new_expr($2, $4 as expression_list, false, null, @$); + } + ; + +const_value + : INTNUM + { + $$ = $1; + } + | REALNUM + { + $$ = $1; + } + | TRUE + { + $$ = new ident("true", @$); + } + | FALSE + { + $$ = new ident("false", @$); + } + | STRINGNUM + { + $$ = $1 as literal; + } + | FSTRINGNUM + { + $$ = $1; + } + | BIGINT + { + $$ = $1; + } + ; + +expr_list + : expr + { + $$ = new expression_list($1, @$); + } + | expr_list COMMA expr + { + $$ = ($1 as expression_list).Add($3, @$); + } + ; + +if_stmt + : IF expr COLON block optional_elif + { + $$ = new if_node($2, $4 as statement, $5 as statement, @$); + } + ; + +optional_elif + : ELIF expr COLON block optional_elif + { + $$ = new if_node($2, $4 as statement, $5 as statement, @$); + } + | optional_else + { + $$ = $1; + } + ; + +optional_else + : ELSE COLON block + { + $$ = $3; + } + | + { + $$ = null; + } + ; + +while_stmt + : WHILE expr COLON block + { + $$ = new while_node($2, $4 as statement, WhileCycleType.While, @$); + } + ; + +for_stmt + : FOR ident IN expr COLON block + { + $$ = new foreach_stmt($2, new no_type_foreach(), $4, $6 as statement, null, @$); + } + | FOR ident COMMA ident_list IN expr COLON block + { + ($4 as ident_list).AddFirst($2); + var id = parserTools.NewId("#fe",@4); + var tttt = new assign_var_tuple($4 as ident_list, id, @$); + statement_list nine = $8 is statement_list ? $8 as statement_list : new statement_list($8 as statement, @8); + nine.Insert(0, tttt); + var fe = new foreach_stmt(id, new no_type_foreach(), $6, nine, null, @$); + fe.ext = $4 as ident_list; + $$ = fe; + } + ; + +ident_list + : ident + { + $$ = new ident_list($1, @$); + } + | ident_list COMMA ident + { + $$ = ($1 as ident_list).Add($3, @$); + } + ; + +func_name_ident + : ident + { + $$ = $1; + } + ; + +return_stmt + : RETURN assign_right_part + { + $$ = new return_statement($2, @$); + } + | RETURN + { + $$ = new return_statement(null, @$); + } + ; + +break_stmt + : BREAK + { + $$ = new procedure_call(new ident("break", @$), true, @$); + } + ; + +continue_stmt + : CONTINUE + { + $$ = new procedure_call(new ident("continue", @$), true, @$); + } + ; + +proc_func_call_stmt + : proc_func_call + { + $$ = new procedure_call($1 as addressed_value, $1 is ident, @$); + } + ; + +variable + : ident + { + $$ = $1; + } + | proc_func_call + { + $$ = $1; + } + | variable DOT ident + { + $$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$); + } + | const_value DOT ident + { + $$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$); + } + | list_constant + { + $$ = $1; + } + | set_constant + { + $$ = $1; + } + | dict_constant + { + $$ = $1; + } + // index property + | variable LBRACKET expr RBRACKET + { + var el = new expression_list($3 as expression, @$); + $$ = new indexer($1 as addressed_value, el, @$); + } + // list generator + | LBRACKET generator_object RBRACKET + { + dot_node dn = new dot_node($2 as addressed_value, (new ident("ToList")) as addressed_value, $2.source_context); + $$ = new method_call(dn as addressed_value, null, $2.source_context); + } + // set generator + | LBRACE generator_object RBRACE + { + dot_node dn = new dot_node($2 as addressed_value, (new ident("ToSet")) as addressed_value, $2.source_context); + $$ = new method_call(dn as addressed_value, null, $2.source_context); + } + // dict generator + | LBRACE generator_object_for_dict RBRACE + { + dot_node dn = new dot_node($2 as addressed_value, (new ident("ToDictionary")) as addressed_value, $2.source_context); + $$ = new method_call(dn as addressed_value, null, $2.source_context); + } + ; + +variable_list + : variable + { + $$ = new addressed_value_list($1 as addressed_value,@1); + } + | variable_list COMMA variable + { + ($1 as addressed_value_list).Add($3 as addressed_value); + ($1 as syntax_tree_node).source_context = LexLocation.MergeAll(@1,@2,@3); + $$ = $1; + } + ; + +generator_object + : expr FOR ident IN expr optional_condition + { + $$ = new generator_object($1, $3, $5, $6, @$); + } + ; + +generator_object_for_dict + : expr_mapping FOR ident IN expr optional_condition + { + $$ = new generator_object($1, $3, $5, $6, @$); + } + ; + +dict_constant + : LBRACE expr_mapping_list RBRACE + { + $$ = new method_call(new ident("Dict", @$), $2 as expression_list, @$); + } + | LBRACE RBRACE + { + $$ = new method_call(new ident("!empty_dict", @$), null, @$); + } + ; + +set_constant + : LBRACE expr_list RBRACE + { + $$ = new pascal_set_constant($2 as expression_list, @$); + } + ; + +list_constant + : LBRACKET expr_list RBRACKET + { + var acn = new array_const_new($2 as expression_list, '|', @$); + var dn = new dot_node(acn as addressed_value, (new ident("ToList", @$)) as addressed_value, @$); + $$ = new method_call(dn as addressed_value, null, @$); + } + | LBRACKET RBRACKET + { + $$ = new method_call(new ident("!empty_list", @$), null, @$); + } + ; + +optional_condition + : + { + $$ = null; + } + | IF expr + { + $$ = $2; + } + ; + +block + : INDENT stmt_list end_of_line UNINDENT + { + $$ = $2 as statement_list; + ($$ as statement_list).left_logical_bracket = $1; + ($$ as statement_list).right_logical_bracket = $4; + $$.source_context = LexLocation.MergeAll(@2, @3); + } + ; + +proc_func_decl + : proc_func_header block + { + $$ = new procedure_definition($1 as procedure_header, new block(null, $2 as statement_list, @2), @$); + } + ; + +proc_func_header + : DEF func_name_ident LPAR optional_form_param_list RPAR COLON + { + $$ = new procedure_header($4 as formal_parameters, new procedure_attributes_list(new List()), new method_name(null,null, $2, null, @2), null, @$); + } + | DEF func_name_ident LPAR optional_form_param_list RPAR ARROW type_ref COLON + { + $$ = new function_header($4 as formal_parameters, new procedure_attributes_list(new List()), new method_name(null,null, $2, null, @2), null, $7 as type_definition, @$); + } + ; + +proc_func_call + : variable LPAR optional_act_param_list RPAR + { + $$ = new method_call($1 as addressed_value, $3 as expression_list, @$); + } + ; + +simple_type_identifier + : ident + { + $$ = new named_type_reference($1, @$); + } + | simple_type_identifier DOT ident + { + $$ = ($1 as named_type_reference).Add($3, @$); + } + ; + +type_ref + : simple_type_identifier + { + $$ = $1 as named_type_reference; + } + | template_type + { + $$ = $1; + } + ; + +template_type + : simple_type_identifier template_type_params + { + $$ = new template_type_reference($1 as named_type_reference, $2 as template_param_list, @$); + } + ; + +template_type_params + : LBRACKET template_param_list RBRACKET + { + $$ = $2; + $$.source_context = @$; + } + ; + +template_param_list + : type_ref + { + $$ = new template_param_list($1, @$); + } + | template_param_list COMMA type_ref + { + $$ = ($1 as template_param_list).Add($3, @$); + } + ; + +param_name + : ident + { + $$ = new ident_list($1, @$); + } + ; + +form_param_sect + : param_name COLON type_ref + { + $$ = new typed_parameters($1 as ident_list, $3, parametr_kind.none, null, @$); + } + // *args + | STAR param_name COLON type_ref + { + var at = new array_type(null, $4, @$); + $$ = new typed_parameters($2 as ident_list, at, parametr_kind.params_parametr, null, @$); + } + // **kwargs + | STARSTAR param_name COLON type_ref + { + $$ = new typed_parameters($2 as ident_list, $4, parametr_kind.kwargs_parameter, null, @$); + } + ; + +form_param_list + : form_param_sect + { + $$ = new formal_parameters($1 as typed_parameters, @$); + } + | form_param_list COMMA form_param_sect + { + $$ = ($1 as formal_parameters).Add($3 as typed_parameters, @$); + } + ; + +optional_form_param_list + : form_param_list + { + $$ = $1; + } + | + { + $$ = null; + } + ; + +act_param + : expr + { + $$ = $1; + } + | ident ASSIGN expr + { + $$ = new name_assign_expr($1, $3, @$); + } + ; + +act_param_list + : act_param + { + $$ = new expression_list($1, @$); + } + | act_param_list COMMA act_param + { + $$ = ($1 as expression_list).Add($3, @$); + } + ; + +optional_act_param_list + : act_param_list + { + $$ = $1; + } + | generator_object + { + $$ = new expression_list($1, @$); + } + | + { + $$ = null; + } + ; + +end_of_line + : END_OF_LINE + { + $$ = $1; + } + | SEMICOLON + { + $$ = $1; + } + ; + +optional_semicolon + : SEMICOLON + { + $$ = $1; + } + | + { + $$ = null; + } + ; + +%% + + public program_module NewProgramModule(program_name progName, Object optHeadCompDirs, uses_list mainUsesClose, syntax_tree_node progBlock, Object optPoint, LexLocation loc) + { + var progModule = new program_module(progName, mainUsesClose, progBlock as block, null, loc); + progModule.Language = "SPython"; + if (optPoint == null && progBlock != null) + { + var fp = progBlock.source_context.end_position; + var err_stn = progBlock; + if ((progBlock is block) && (progBlock as block).program_code != null && (progBlock as block).program_code.subnodes != null && (progBlock as block).program_code.subnodes.Count > 0) + err_stn = (progBlock as block).program_code.subnodes[(progBlock as block).program_code.subnodes.Count - 1]; + //parserTools.errors.Add(new SPythonUnexpectedToken(parserTools.currentFileName, StringResources.Get("TKPOINT"), new SourceContext(fp.line_num, fp.column_num + 1, fp.line_num, fp.column_num + 1, 0, 0), err_stn)); + } + return progModule; + } diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserTools.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserTools.cs new file mode 100644 index 000000000..2b5462cbd --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserTools.cs @@ -0,0 +1,434 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.ParserTools; +using PascalABCCompiler.Parsers; +using System.Text; +using PascalABCCompiler.Errors; +using PascalABCCompiler.ParserTools.Directives; +using QUT.Gppg; +using System.Text.RegularExpressions; +using Languages.Facade; +using static System.Net.Mime.MediaTypeNames; + +namespace SPythonParser +{ + public static class StringResources + { + private static string prefix = "SPYTHONPARSER_"; + public static string Get(string Id) + { + string ret = PascalABCCompiler.StringResources.Get(prefix + Id); + if (ret == prefix + Id) + return Id; + else + return ret; + } + } + + public class SymbolTable + { + private SymbolTable outerScope; + private SortedSet symbols = new SortedSet(); + public SymbolTable(SymbolTable outerScope = null) + { + this.outerScope = outerScope; + } + + public bool Contains(string ident) + { + SymbolTable curr = this; + + while (curr != null) + { + if (curr.symbols.Contains(ident)) + return true; + curr = curr.outerScope; + } + + return false; + } + + public void Add(string ident) + { + symbols.Add(ident); + } + + public SymbolTable OuterScope { get { return outerScope; } } + } + public class SPythonParserTools : BaseParserTools + { + public bool build_tree_for_formatter = false; + public bool build_tree_for_format_strings = false; + + public override Dictionary TokenNum { get; protected set; } + + private void InitializeTokenNum() + { + TokenNum = new Dictionary(); + TokenNum["STATEMENT"] = StringResources.Get("STMT"); + TokenNum["EXPRESSION"] = StringResources.Get("EXPR"); + TokenNum["EOF"] = StringResources.Get("EOF1"); + TokenNum["ID"] = StringResources.Get("IDENTIFIER"); + TokenNum["INTNUM"] = StringResources.Get("INTNUM"); + TokenNum["REALNUM"] = StringResources.Get("REALNUM"); + TokenNum["STRINGNUM"] = StringResources.Get("STRINGNUM"); + TokenNum["END_OF_FILE"] = StringResources.Get("#$"); + TokenNum["#$"] = StringResources.Get("#$"); + TokenNum["INDENT"] = StringResources.Get("#{"); + TokenNum["#{"] = StringResources.Get("#{"); + TokenNum["UNINDENT"] = StringResources.Get("#}"); + TokenNum["#}"] = StringResources.Get("#}"); + TokenNum["END_OF_LINE"] = StringResources.Get("#;"); + TokenNum["#;"] = StringResources.Get("#;"); + //TokenNum["tkStringLiteral"] = StringResources.Get("TKSTRINGLITERAL"); + TokenNum["IN"] = "'in'"; + TokenNum["IMPORT"] = "'import'"; + TokenNum["SEMICOLON"] = "';'"; + TokenNum["ASSIGN"] = "'='"; + TokenNum["COLON"] = "':'"; + TokenNum["DOT"] = "'.'"; + TokenNum["LPAR"] = "'('"; + TokenNum["RPAR"] = "')'"; + TokenNum["LBRACKET"] = "'['"; + TokenNum["RBRACKET"] = "']'"; + TokenNum["tkQuestion"] = "'?'"; + TokenNum["COMMA"] = "','"; + TokenNum["PERCENTAGE"] = "'%'"; + TokenNum["DIVIDE"] = "'/'"; + TokenNum["MINUS"] = "'-'"; + TokenNum["PLUS"] = "'+'"; + TokenNum["SLASHSLASH"] = "'//'"; + TokenNum["STAR"] = "'*'"; + TokenNum["EQUAL"] = "'=='"; + TokenNum["NOTEQUAL"] = "'!='"; + TokenNum["GREATER"] = "'>'"; + TokenNum["GREATEREQUAL"] = "'>='"; + TokenNum["LESS"] = "'<'"; + TokenNum["LESSEQUAL"] = "'<='"; + TokenNum["ARROW"] = "'->'"; + } + + public SPythonParserTools(List errors, List warnings, + Dictionary validDirectives, bool buildTreeForFormatter = false, bool buildTreeForFormatterStrings = false, + string currentFileName = null, List compilerDirectives = null) + : base(errors, warnings, validDirectives, buildTreeForFormatter, buildTreeForFormatterStrings, currentFileName, compilerDirectives) + { + + InitializeTokenNum(); + } + + public int TokenPriority(string tok) + { + switch (tok) + { + case "END_OF_LINE": + return 300; + case "STATEMENT": + return 100; + case "EXPRESSION": + return 100; + case "EQUAL": + return 90; + case "COLON": + return 200; + case "ASSIGN": + return 70; + case "ID": + return 60; + case "LPAR": + return 100; + case "RPAR": + return 130; + case "DOT": + return 20; + case "RBRACKET": + return 10; + case "GREATER": + return 5; + } + return 0; + } + + protected override string ReplaceSpecialSymbols(string text) + { + StringBuilder new_text = new StringBuilder(text); + int curr = 0; + for (int i = 0; i < text.Length; ++i) + { + if (text[i] != '\\') new_text[curr++] = text[i]; + else switch (text[i + 1]) + { + case 'a': new_text[curr++] = '\a'; ++i; break; + case '0': new_text[curr++] = '\0'; ++i; break; + case 'b': new_text[curr++] = '\b'; ++i; break; + case 't': new_text[curr++] = '\t'; ++i; break; + case 'n': new_text[curr++] = '\n'; ++i; break; + case 'v': new_text[curr++] = '\v'; ++i; break; + case 'f': new_text[curr++] = '\f'; ++i; break; + case 'r': new_text[curr++] = '\r'; ++i; break; + + case '\'': new_text[curr++] = '\''; ++i; break; + case '"': new_text[curr++] = '"'; ++i; break; + case '\\': new_text[curr++] = '\\'; ++i; break; + + default: new_text[curr++] = '\\'; break; + } + } + return new_text.ToString().Substring(0, curr); + } + + public override literal create_string_const(string text, SourceContext sc) + { + literal lt; + text = ReplaceSpecialSymbols(text.Substring(1, text.Length - 2)); + lt = new string_const(text); + lt.source_context = sc; + return lt; + } + + private int num1 = 0; + + public ident NewId(string prefix, SourceContext sc = null) + { + num1++; + return new ident(prefix + num1.ToString(),sc); + } + + private expression RemoveBracesAndContent(string input, SourceContext sc) + { + var regex = new Regex(@"\{([^}]+)\}"); + var parts = new List(); + + int lastIndex = 0; + foreach (Match m in regex.Matches(input)) + { + var innerRegex = new Regex(@"^([^:]*)(?::(.*))?$"); + + SourceContext expr_sc = new SourceContext(sc.LeftSourceContext, sc.RightSourceContext); + expr_sc.begin_position.column_num += m.Index + 3; + + var raw = m.Groups[1].Value; + var innerMatch = innerRegex.Match(raw); + + if (!innerMatch.Success) + { + AddErrorFromResource("ILL_FORMED_FSTRING_{0}", expr_sc, raw); + return null; + } + + string expr_text = innerMatch.Groups[1].Value; + string format = innerMatch.Groups[2].Success ? innerMatch.Groups[2].Value : null; + + SourceContext format_sc = new SourceContext(sc.LeftSourceContext, sc.RightSourceContext); + format_sc.begin_position.column_num += m.Index + 4 + expr_text.Length; + + if (format != null) + { + var formatRegex = new Regex(@"^(x|X|d|b|\.(0|([1-9][0-9]*))f)$"); + var formatMatch = formatRegex.Match(format); + if (!formatMatch.Success) + AddErrorFromResource("FSTRING_UNNKOWN_FORMAT_{0}", format_sc, format); + format = formatMatch.Value; + } + + if (m.Index > lastIndex) + { + var text = input.Substring(lastIndex, m.Index - lastIndex); + if (text != "") + parts.Add(new string_const(text, sc)); + } + + List errors = new List(); + expression expr = + LanguageProvider.Instance.SelectLanguageByExtension(currentFileName).Parser + .GetExpression(currentFileName, expr_text, errors, new List()); + + if (expr == null) + { + AddErrorFromResource("FSTRING_NESTED_EXPRESSION_{0}_PARSING_FAILURE", expr_sc, expr_text); + expr = new expression(); + } + + expr.source_context = expr_sc; + method_call mc; + if (format == null) + { + mc = new method_call(new ident("str"), new expression_list(expr, sc), sc); + } + else + { + mc = new method_call(new ident("!format"), + new expression_list(new List { expr, new string_const(format, sc) }, sc), sc); + } + parts.Add(mc); + lastIndex = m.Index + m.Length; + } + + if (lastIndex < input.Length) + { + var text = input.Substring(lastIndex); + if (text != "") + parts.Add(new string_const(text, sc)); + } + + expression result = parts[parts.Count - 1]; + for (int i = parts.Count - 2; i >= 0; i--) + { + result = new bin_expr(parts[i], result, Operators.Plus, sc); + } + + return result; + } + + public expression create_fstring(string text, SourceContext sc) + { + text = ReplaceSpecialSymbols(text.Substring(2, text.Length - 3)); + expression res = RemoveBracesAndContent(text, sc); + res.source_context = sc; + return res; + } + + public LexLocation GetLexLocation(string found, string expected, LexLocation prev_loc, LexLocation curr_loc) + { + // жертвы, чтобы достать имя файла + SourceContext sc = curr_loc; + if (found == "#{" && expected == "END_OF_LINE" || + found == "#;" && expected == "INDENT") + return new LexLocation(curr_loc.StartLine + 1, 0, curr_loc.StartLine + 1, 0, sc.FileName); + if (found == "#{" || found == "#;") + return new LexLocation(prev_loc.EndLine, prev_loc.EndColumn, prev_loc.EndLine, prev_loc.EndColumn + 1, sc.FileName); + return curr_loc; + } + + public string ExpectedToken(bool line_needs_colon, params object[] args) { + string found = args[0].ToString(); + List tokens = new List(args.Skip(1).Cast()); + + if (tokens.Count != 1) { + tokens = tokens.Except((new string[] { found })).ToList(); + } + + // Это - временное решение, пока эти слова относятся к идентификаторам (что неправильно) + //if (tokens.Contains("ID")) + // tokens = tokens.Except((new string[] { "tkAbstract", "tkOverload", "tkReintroduce", "tkOverride", "tkVirtual", "tkAt", "tkOn", "tkName", "tkForward", "tkRead", "tkWrite" })).ToList(); + + if (tokens.Contains("FOR") && tokens.Contains("IF") && tokens.Contains("WHILE") && tokens.Contains("DEF")) + return "STATEMENT"; + + if (tokens.Contains("ID") && tokens.Contains("INTNUM") && tokens.Contains("REALNUM") && tokens.Contains("STRINGNUM")) + return "EXPRESSION"; + + if (line_needs_colon && tokens.Contains("COLON")) + return "COLON"; + + tokens = tokens.OrderByDescending(s => TokenPriority(s)).ToList(); + + return tokens.First(); + } + + public const_node create_spy_int_const(string text, SourceContext sc) { + + return create_int_const(text.Replace("_", ""), sc); + } + + public string CreateErrorString(string yytext, string exp_token) + { + if (yytext.Equals("#;") && exp_token.Equals("INDENT")) + { + return StringResources.Get("LINE_WITHOUT_INDENT"); + } + + if (yytext.Equals("#{") && !exp_token.Equals("END_OF_LINE")) + { + yytext = "#;"; + } + if (exp_token.Equals("INDENT")) + { + exp_token = "END_OF_LINE"; + } + + string prefix = ""; + if (yytext != "") + prefix = StringResources.Get("FOUND{0}"); + else + prefix = StringResources.Get("FOUNDEOF"); + + var ExpectedString = StringResources.Get("EXPECTED{1}"); + + if (exp_token.Equals("STATEMENT") || + exp_token.Equals("ID") || + exp_token.Equals("INDENT") || + exp_token.Equals("UNINDENT") || + exp_token.Equals("UNINDENT") || + exp_token.Equals("END_OF_LINE") || + exp_token.Equals("END_OF_FILE")) + ExpectedString = StringResources.Get("EXPECTEDR{1}"); + else if (exp_token.Equals("STRINGNUM")) + ExpectedString = StringResources.Get("EXPECTEDF{1}"); + var MaxTokHuman = ConvertToHumanName(exp_token); + + if (yytext == "#{" || yytext == "#}" || yytext == "#;" || yytext == "#$") + { + prefix = StringResources.Get("FOUNDM{0}"); + yytext = ConvertToHumanName(yytext); + return string.Format(prefix + ExpectedString, yytext, MaxTokHuman); + } + + return string.Format(prefix + ExpectedString, "'" + yytext + "'", MaxTokHuman); + } + + + + + /* public string CreateErrorString(string yytext, LexLocation yyloc, params object[] args) + { + string expected = String.Join(", ", args.Skip(1).Select(x => x.ToString())); + string err = $"PARSER ERROR \"{yytext}\" AT LINE #{yyloc.StartLine}: EXPECTED {expected}, FOUND {args[0]}"; + return err; + }*/ + + protected override string GetFromStringResources(string id) + { + return StringResources.Get(id); + } + + protected override string ExtractDirectiveTextWithoutSpecialSymbols(string directive) + { + throw new NotImplementedException(); + } + + public typecast_node NewAsIsExpr(syntax_tree_node term, op_typecast typecast_op, type_definition simple_or_template_type_reference, LexLocation loc) + { + var naie = new typecast_node((addressed_value)term, simple_or_template_type_reference, typecast_op, loc); + + return naie; + } + } + + // temp + public class ParserLambdaHelper + { + private int lambda_num = 0; + public List lambdaDefinitions; + public static string lambdaPrefix = "<>lambda"; + + public ParserLambdaHelper() + { + lambdaDefinitions = new List(); + } + + public string CreateLambdaName() + { + lambda_num++; + return lambdaPrefix + lambda_num.ToString(); + } + + public bool IsLambdaName(ident id) + { + return id.name.StartsWith(lambdaPrefix); + } + } +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserYacc.cs b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserYacc.cs new file mode 100644 index 000000000..fb50a6ecd --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/SPythonParserYacc.cs @@ -0,0 +1,1621 @@ +// This code was generated by the Gardens Point Parser Generator +// Copyright (c) Wayne Kelly, QUT 2005-2010 +// (see accompanying GPPGcopyright.rtf) + +// GPPG version 1.3.6 +// Machine: DESKTOP-56159VE +// DateTime: 17.06.2025 14:06:30 +// UserName: ???? +// Input file + +// options: no-lines gplex + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using QUT.Gppg; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.ParserTools; +using PascalABCCompiler.Errors; +using System.Linq; +using System.Collections.Generic; +using System.IO; +using SPythonParser; + +namespace SPythonParserYacc +{ +public enum Tokens { + error=1,EOF=2,FOR=3,IN=4,WHILE=5,IF=6, + ELSE=7,ELIF=8,DEF=9,RETURN=10,BREAK=11,CONTINUE=12, + IMPORT=13,FROM=14,GLOBAL=15,AS=16,PASS=17,CLASS=18, + LAMBDA=19,EXIT=20,NEW=21,IS=22,INDENT=23,UNINDENT=24, + END_OF_FILE=25,END_OF_LINE=26,DECLTYPE=27,INTNUM=28,REALNUM=29,TRUE=30, + FALSE=31,BIGINT=32,FSTRINGNUM=33,LPAR=34,RPAR=35,LBRACE=36, + RBRACE=37,LBRACKET=38,RBRACKET=39,DOT=40,COMMA=41,COLON=42, + SEMICOLON=43,ARROW=44,STRINGNUM=45,ASSIGN=46,PLUSEQUAL=47,MINUSEQUAL=48, + STAREQUAL=49,DIVEQUAL=50,BINXOREQUAL=51,SHLEQUAL=52,SHREQUAL=53,BINANDEQUAL=54, + BINOREQUAL=55,INTDIVISIONEQUAL=56,PLUS=57,MINUS=58,STAR=59,DIVIDE=60, + SLASHSLASH=61,PERCENTAGE=62,ID=63,LESS=64,GREATER=65,LESSEQUAL=66, + GREATEREQUAL=67,EQUAL=68,NOTEQUAL=69,AND=70,OR=71,NOT=72, + STARSTAR=73,BINNOT=74,BINXOR=75,SHL=76,SHR=77,BINAND=78, + BINOR=79,tkParseModeExpression=80,tkParseModeStatement=81,tkParseModeType=82}; + +public partial struct ValueType +{ + public expression ex; + public ident id; + public Object ob; + public op_type_node op; + public syntax_tree_node stn; + public token_info ti; + public type_definition td; +} +// Abstract base class for GPLEX scanners +public abstract class ScanBase : AbstractScanner { + private LexLocation __yylloc = new LexLocation(); + public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } } + protected virtual bool yywrap() { return true; } +} + +public partial class SPythonGPPGParser: ShiftReduceParser +{ + // Verbatim content from SPythonParser.y + public syntax_tree_node root; + public List errors; + // public string current_file_name; + // public int max_errors = 10; + public SPythonParserTools parserTools; + public List CompilerDirectives; + public ParserLambdaHelper lambdaHelper = new ParserLambdaHelper(); + public bool is_unit_to_be_parsed = false; + + public SPythonGPPGParser(AbstractScanner scanner, SPythonParserTools parserTools, + bool isUnitToBeParsed) : base(scanner) + { + this.parserTools = parserTools; + this.is_unit_to_be_parsed = isUnitToBeParsed; + } + // End verbatim content from SPythonParser.y + +#pragma warning disable 649 + private static Dictionary aliasses; +#pragma warning restore 649 + private static Rule[] rules = new Rule[182]; + private static State[] states = new State[337]; + private static string[] nonTerms = new string[] { + "ident", "dotted_ident", "func_name_ident", "type_decl_identifier", "expr", + "proc_func_call", "const_value", "variable", "optional_condition", "act_param", + "new_expr", "is_expr", "variable_as_type", "act_param_list", "optional_act_param_list", + "proc_func_decl", "return_stmt", "break_stmt", "continue_stmt", "global_stmt", + "pass_stmt", "var_stmt", "assign_stmt", "if_stmt", "stmt", "proc_func_call_stmt", + "while_stmt", "for_stmt", "optional_else", "optional_elif", "exit_stmt", + "expr_list", "stmt_list", "block", "program", "param_name", "form_param_sect", + "form_param_list", "optional_form_param_list", "dotted_ident_list", "ident_as_ident", + "ident_as_ident_list", "ident_list", "proc_func_header", "type_ref", "simple_type_identifier", + "template_type", "import_clause", "template_type_params", "template_param_list", + "parts", "stmt_or_expression", "expr_mapping_list", "optional_semicolon", + "end_of_line", "variable_list", "assign_type", "expr_mapping", "list_constant", + "set_constant", "dict_constant", "generator_object", "generator_object_for_dict", + "tuple_expr", "assign_right_part", "turbo_tuple_expr", "$accept", }; + + static SPythonGPPGParser() { + states[0] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,34,198,6,207,5,227,3,232,10,248,11,251,12,253,15,255,17,264,20,266,9,273,13,300,14,308,80,319,82,325,81,329},new int[]{-35,1,-33,3,-25,315,-23,8,-8,9,-1,79,-6,197,-7,181,-59,92,-60,98,-61,109,-22,205,-24,206,-26,225,-27,226,-28,231,-17,247,-18,250,-19,252,-20,254,-21,263,-31,265,-16,270,-44,271,-48,299,-51,317}); + states[1] = new State(new int[]{2,2}); + states[2] = new State(-1); + states[3] = new State(new int[]{43,316,26,313,25,-181},new int[]{-54,4,-55,6}); + states[4] = new State(new int[]{25,5}); + states[5] = new State(-2); + states[6] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,34,198,6,207,5,227,3,232,10,248,11,251,12,253,15,255,17,264,20,266,9,273,13,300,14,308},new int[]{-25,7,-23,8,-8,9,-1,79,-6,197,-7,181,-59,92,-60,98,-61,109,-22,205,-24,206,-26,225,-27,226,-28,231,-17,247,-18,250,-19,252,-20,254,-21,263,-31,265,-16,270,-44,271,-48,299}); + states[7] = new State(-16); + states[8] = new State(-17); + states[9] = new State(new int[]{46,10,34,69,40,163,38,165,41,175,42,183,47,187,48,188,49,189,50,190,51,191,52,192,53,193,54,194,55,195,56,196},new int[]{-57,173}); + states[10] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-65,11,-5,12,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-66,172}); + states[11] = new State(-53); + states[12] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,170,43,-51,26,-51,25,-51}); + states[13] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,14,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[14] = new State(new int[]{7,15,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[15] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,16,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[16] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-67,43,-67,26,-67,25,-67,7,-67,3,-67,35,-67,39,-67,37,-67,42,-67}); + states[17] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,18,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[18] = new State(new int[]{6,13,57,-68,59,19,60,21,58,-68,64,-68,65,-68,66,-68,67,-68,68,-68,69,-68,70,-68,71,-68,61,41,62,43,76,-68,77,-68,78,-68,79,-68,75,-68,73,55,4,57,72,-68,41,-68,43,-68,26,-68,25,-68,7,-68,3,-68,35,-68,39,-68,37,-68,42,-68}); + states[19] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,20,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[20] = new State(new int[]{6,13,57,-69,59,-69,60,-69,58,-69,64,-69,65,-69,66,-69,67,-69,68,-69,69,-69,70,-69,71,-69,61,-69,62,-69,76,-69,77,-69,78,-69,79,-69,75,-69,73,55,4,57,72,-69,41,-69,43,-69,26,-69,25,-69,7,-69,3,-69,35,-69,39,-69,37,-69,42,-69}); + states[21] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,22,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[22] = new State(new int[]{6,13,57,-70,59,-70,60,-70,58,-70,64,-70,65,-70,66,-70,67,-70,68,-70,69,-70,70,-70,71,-70,61,-70,62,-70,76,-70,77,-70,78,-70,79,-70,75,-70,73,55,4,57,72,-70,41,-70,43,-70,26,-70,25,-70,7,-70,3,-70,35,-70,39,-70,37,-70,42,-70}); + states[23] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,24,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[24] = new State(new int[]{6,13,57,-71,59,19,60,21,58,-71,64,-71,65,-71,66,-71,67,-71,68,-71,69,-71,70,-71,71,-71,61,41,62,43,76,-71,77,-71,78,-71,79,-71,75,-71,73,55,4,57,72,-71,41,-71,43,-71,26,-71,25,-71,7,-71,3,-71,35,-71,39,-71,37,-71,42,-71}); + states[25] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,26,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[26] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-72,65,-72,66,-72,67,-72,68,-72,69,-72,70,-72,71,-72,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-72,41,-72,43,-72,26,-72,25,-72,7,-72,3,-72,35,-72,39,-72,37,-72,42,-72}); + states[27] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,28,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[28] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-73,65,-73,66,-73,67,-73,68,-73,69,-73,70,-73,71,-73,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-73,41,-73,43,-73,26,-73,25,-73,7,-73,3,-73,35,-73,39,-73,37,-73,42,-73}); + states[29] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,30,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[30] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-74,65,-74,66,-74,67,-74,68,-74,69,-74,70,-74,71,-74,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-74,41,-74,43,-74,26,-74,25,-74,7,-74,3,-74,35,-74,39,-74,37,-74,42,-74}); + states[31] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,32,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[32] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-75,65,-75,66,-75,67,-75,68,-75,69,-75,70,-75,71,-75,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-75,41,-75,43,-75,26,-75,25,-75,7,-75,3,-75,35,-75,39,-75,37,-75,42,-75}); + states[33] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,34,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[34] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-76,65,-76,66,-76,67,-76,68,-76,69,-76,70,-76,71,-76,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-76,41,-76,43,-76,26,-76,25,-76,7,-76,3,-76,35,-76,39,-76,37,-76,42,-76}); + states[35] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,36,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[36] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-77,65,-77,66,-77,67,-77,68,-77,69,-77,70,-77,71,-77,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-77,41,-77,43,-77,26,-77,25,-77,7,-77,3,-77,35,-77,39,-77,37,-77,42,-77}); + states[37] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,38,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[38] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,-78,71,-78,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-78,43,-78,26,-78,25,-78,7,-78,3,-78,35,-78,39,-78,37,-78,42,-78}); + states[39] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,40,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[40] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,-79,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-79,43,-79,26,-79,25,-79,7,-79,3,-79,35,-79,39,-79,37,-79,42,-79}); + states[41] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,42,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[42] = new State(new int[]{6,13,57,-80,59,-80,60,-80,58,-80,64,-80,65,-80,66,-80,67,-80,68,-80,69,-80,70,-80,71,-80,61,-80,62,-80,76,-80,77,-80,78,-80,79,-80,75,-80,73,55,4,57,72,-80,41,-80,43,-80,26,-80,25,-80,7,-80,3,-80,35,-80,39,-80,37,-80,42,-80}); + states[43] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,44,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[44] = new State(new int[]{6,13,57,-81,59,-81,60,-81,58,-81,64,-81,65,-81,66,-81,67,-81,68,-81,69,-81,70,-81,71,-81,61,-81,62,-81,76,-81,77,-81,78,-81,79,-81,75,-81,73,55,4,57,72,-81,41,-81,43,-81,26,-81,25,-81,7,-81,3,-81,35,-81,39,-81,37,-81,42,-81}); + states[45] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,46,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[46] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-82,65,-82,66,-82,67,-82,68,-82,69,-82,70,-82,71,-82,61,41,62,43,76,-82,77,-82,78,-82,79,-82,75,-82,73,55,4,57,72,-82,41,-82,43,-82,26,-82,25,-82,7,-82,3,-82,35,-82,39,-82,37,-82,42,-82}); + states[47] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,48,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[48] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-83,65,-83,66,-83,67,-83,68,-83,69,-83,70,-83,71,-83,61,41,62,43,76,-83,77,-83,78,-83,79,-83,75,-83,73,55,4,57,72,-83,41,-83,43,-83,26,-83,25,-83,7,-83,3,-83,35,-83,39,-83,37,-83,42,-83}); + states[49] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,50,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[50] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-84,65,-84,66,-84,67,-84,68,-84,69,-84,70,-84,71,-84,61,41,62,43,76,45,77,47,78,-84,79,-84,75,-84,73,55,4,57,72,-84,41,-84,43,-84,26,-84,25,-84,7,-84,3,-84,35,-84,39,-84,37,-84,42,-84}); + states[51] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,52,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[52] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-85,65,-85,66,-85,67,-85,68,-85,69,-85,70,-85,71,-85,61,41,62,43,76,45,77,47,78,49,79,-85,75,53,73,55,4,57,72,-85,41,-85,43,-85,26,-85,25,-85,7,-85,3,-85,35,-85,39,-85,37,-85,42,-85}); + states[53] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,54,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[54] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,-86,65,-86,66,-86,67,-86,68,-86,69,-86,70,-86,71,-86,61,41,62,43,76,45,77,47,78,49,79,-86,75,-86,73,55,4,57,72,-86,41,-86,43,-86,26,-86,25,-86,7,-86,3,-86,35,-86,39,-86,37,-86,42,-86}); + states[55] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,56,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[56] = new State(new int[]{6,13,57,-87,59,-87,60,-87,58,-87,64,-87,65,-87,66,-87,67,-87,68,-87,69,-87,70,-87,71,-87,61,-87,62,-87,76,-87,77,-87,78,-87,79,-87,75,-87,73,55,4,57,72,-87,41,-87,43,-87,26,-87,25,-87,7,-87,3,-87,35,-87,39,-87,37,-87,42,-87}); + states[57] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,58,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[58] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-88,43,-88,26,-88,25,-88,7,-88,3,-88,35,-88,39,-88,37,-88,42,-88}); + states[59] = new State(new int[]{4,60}); + states[60] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,61,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[61] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-89,43,-89,26,-89,25,-89,7,-89,3,-89,35,-89,39,-89,37,-89,42,-89}); + states[62] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,63,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[63] = new State(new int[]{6,13,57,-90,59,19,60,21,58,-90,64,-90,65,-90,66,-90,67,-90,68,-90,69,-90,70,-90,71,-90,61,41,62,43,76,-90,77,-90,78,-90,79,-90,75,-90,73,55,4,57,72,-90,41,-90,43,-90,26,-90,25,-90,7,-90,3,-90,35,-90,39,-90,37,-90,42,-90}); + states[64] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,65,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[65] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,-91,71,-91,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,-91,41,-91,43,-91,26,-91,25,-91,7,-91,3,-91,35,-91,39,-91,37,-91,42,-91}); + states[66] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,67,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[67] = new State(new int[]{6,13,57,-92,59,-92,60,-92,58,-92,64,-92,65,-92,66,-92,67,-92,68,-92,69,-92,70,-92,71,-92,61,-92,62,-92,76,-92,77,-92,78,-92,79,-92,75,-92,73,-92,4,57,72,-92,41,-92,43,-92,26,-92,25,-92,7,-92,3,-92,35,-92,39,-92,37,-92,42,-92}); + states[68] = new State(new int[]{34,69,40,163,38,165,22,168,6,-93,57,-93,59,-93,60,-93,58,-93,64,-93,65,-93,66,-93,67,-93,68,-93,69,-93,70,-93,71,-93,61,-93,62,-93,76,-93,77,-93,78,-93,79,-93,75,-93,73,-93,4,-93,72,-93,41,-93,43,-93,26,-93,25,-93,7,-93,3,-93,35,-93,39,-93,37,-93,42,-93}); + states[69] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127,35,-177},new int[]{-15,70,-14,72,-10,116,-5,117,-8,68,-1,76,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-62,134}); + states[70] = new State(new int[]{35,71}); + states[71] = new State(-154); + states[72] = new State(new int[]{41,73,35,-175}); + states[73] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-10,74,-5,75,-8,68,-1,76,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[74] = new State(-174); + states[75] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-171,35,-171}); + states[76] = new State(new int[]{46,77,34,-128,40,-128,38,-128,22,-128,6,-128,57,-128,59,-128,60,-128,58,-128,64,-128,65,-128,66,-128,67,-128,68,-128,69,-128,70,-128,71,-128,61,-128,62,-128,76,-128,77,-128,78,-128,79,-128,75,-128,73,-128,4,-128,72,-128,3,-128,41,-128,35,-128}); + states[77] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,78,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[78] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,41,-172,35,-172}); + states[79] = new State(-128); + states[80] = new State(-37); + states[81] = new State(-129); + states[82] = new State(new int[]{40,83,6,-94,57,-94,59,-94,60,-94,58,-94,64,-94,65,-94,66,-94,67,-94,68,-94,69,-94,70,-94,71,-94,61,-94,62,-94,76,-94,77,-94,78,-94,79,-94,75,-94,73,-94,4,-94,72,-94,41,-94,43,-94,26,-94,25,-94,7,-94,3,-94,35,-94,39,-94,37,-94,42,-94}); + states[83] = new State(new int[]{63,80},new int[]{-1,84}); + states[84] = new State(-131); + states[85] = new State(-103); + states[86] = new State(-104); + states[87] = new State(-105); + states[88] = new State(-106); + states[89] = new State(-107); + states[90] = new State(-108); + states[91] = new State(-109); + states[92] = new State(-132); + states[93] = new State(new int[]{39,159,58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-32,94,-62,160,-5,162,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[94] = new State(new int[]{39,95,41,96}); + states[95] = new State(-146); + states[96] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,97,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[97] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,39,-111,41,-111,37,-111,35,-111,43,-111,26,-111,25,-111}); + states[98] = new State(-133); + states[99] = new State(new int[]{37,147,58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-32,100,-53,102,-62,148,-63,150,-5,152,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-58,153}); + states[100] = new State(new int[]{37,101,41,96}); + states[101] = new State(-145); + states[102] = new State(new int[]{37,103,41,104}); + states[103] = new State(-143); + states[104] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-58,105,-5,106,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[105] = new State(-48); + states[106] = new State(new int[]{42,107,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[107] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,108,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[108] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,3,-46,37,-46,41,-46}); + states[109] = new State(-134); + states[110] = new State(-95); + states[111] = new State(new int[]{63,80},new int[]{-45,112,-46,135,-1,144,-47,145}); + states[112] = new State(new int[]{34,113}); + states[113] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127,35,-177},new int[]{-15,114,-14,72,-10,116,-5,117,-8,68,-1,76,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-62,134}); + states[114] = new State(new int[]{35,115}); + states[115] = new State(-102); + states[116] = new State(-173); + states[117] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,3,118,41,-171,35,-171}); + states[118] = new State(new int[]{63,80},new int[]{-1,119}); + states[119] = new State(new int[]{4,120}); + states[120] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,121,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[121] = new State(new int[]{6,123,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,35,-148,39,-148,37,-148},new int[]{-9,122}); + states[122] = new State(-141); + states[123] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,124,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[124] = new State(new int[]{7,15,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,35,-149,39,-149,37,-149}); + states[125] = new State(-96); + states[126] = new State(-97); + states[127] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,128,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[128] = new State(new int[]{41,129,35,133,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[129] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-32,130,-5,132,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[130] = new State(new int[]{35,131,41,96}); + states[131] = new State(-99); + states[132] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,35,-110,41,-110,43,-110,26,-110,25,-110}); + states[133] = new State(-98); + states[134] = new State(-176); + states[135] = new State(new int[]{40,136,38,139,34,-157,39,-157,41,-157,6,-157,57,-157,59,-157,60,-157,58,-157,64,-157,65,-157,66,-157,67,-157,68,-157,69,-157,70,-157,71,-157,61,-157,62,-157,76,-157,77,-157,78,-157,79,-157,75,-157,73,-157,4,-157,72,-157,43,-157,26,-157,25,-157,7,-157,3,-157,35,-157,37,-157,42,-157,46,-157},new int[]{-49,138}); + states[136] = new State(new int[]{63,80},new int[]{-1,137}); + states[137] = new State(-156); + states[138] = new State(-159); + states[139] = new State(new int[]{63,80},new int[]{-50,140,-45,146,-46,135,-1,144,-47,145}); + states[140] = new State(new int[]{39,141,41,142}); + states[141] = new State(-160); + states[142] = new State(new int[]{63,80},new int[]{-45,143,-46,135,-1,144,-47,145}); + states[143] = new State(-162); + states[144] = new State(-155); + states[145] = new State(-158); + states[146] = new State(-161); + states[147] = new State(-144); + states[148] = new State(new int[]{37,149}); + states[149] = new State(-137); + states[150] = new State(new int[]{37,151}); + states[151] = new State(-138); + states[152] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,42,107,3,118,37,-110,41,-110}); + states[153] = new State(new int[]{3,154,37,-47,41,-47}); + states[154] = new State(new int[]{63,80},new int[]{-1,155}); + states[155] = new State(new int[]{4,156}); + states[156] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,157,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[157] = new State(new int[]{6,123,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,37,-148},new int[]{-9,158}); + states[158] = new State(-142); + states[159] = new State(-147); + states[160] = new State(new int[]{39,161}); + states[161] = new State(-136); + states[162] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,3,118,39,-110,41,-110}); + states[163] = new State(new int[]{63,80},new int[]{-1,164}); + states[164] = new State(-130); + states[165] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,166,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[166] = new State(new int[]{39,167,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[167] = new State(-135); + states[168] = new State(new int[]{63,80},new int[]{-45,169,-46,135,-1,144,-47,145}); + states[169] = new State(-101); + states[170] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-32,171,-5,132,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[171] = new State(new int[]{41,96,43,-100,26,-100,25,-100}); + states[172] = new State(-52); + states[173] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-65,174,-5,12,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-66,172}); + states[174] = new State(-54); + states[175] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99},new int[]{-56,176,-8,182,-1,79,-6,81,-7,181,-59,92,-60,98,-61,109}); + states[176] = new State(new int[]{46,177,41,179}); + states[177] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-65,178,-5,12,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-66,172}); + states[178] = new State(-56); + states[179] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99},new int[]{-8,180,-1,79,-6,81,-7,181,-59,92,-60,98,-61,109}); + states[180] = new State(new int[]{34,69,40,163,38,165,46,-140,41,-140,35,-140}); + states[181] = new State(new int[]{40,83}); + states[182] = new State(new int[]{34,69,40,163,38,165,46,-139,41,-139,35,-139}); + states[183] = new State(new int[]{63,80},new int[]{-45,184,-46,135,-1,144,-47,145}); + states[184] = new State(new int[]{46,185,43,-49,26,-49,25,-49}); + states[185] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,186,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[186] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,43,-50,26,-50,25,-50}); + states[187] = new State(-57); + states[188] = new State(-58); + states[189] = new State(-59); + states[190] = new State(-60); + states[191] = new State(-61); + states[192] = new State(-62); + states[193] = new State(-63); + states[194] = new State(-64); + states[195] = new State(-65); + states[196] = new State(-66); + states[197] = new State(new int[]{46,-129,34,-129,40,-129,38,-129,41,-129,42,-129,47,-129,48,-129,49,-129,50,-129,51,-129,52,-129,53,-129,54,-129,55,-129,56,-129,43,-127,26,-127,25,-127}); + states[198] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99},new int[]{-8,199,-1,79,-6,81,-7,181,-59,92,-60,98,-61,109}); + states[199] = new State(new int[]{41,200,34,69,40,163,38,165}); + states[200] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99},new int[]{-56,201,-8,182,-1,79,-6,81,-7,181,-59,92,-60,98,-61,109}); + states[201] = new State(new int[]{35,202,41,179}); + states[202] = new State(new int[]{46,203}); + states[203] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-65,204,-5,12,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-66,172}); + states[204] = new State(-55); + states[205] = new State(-18); + states[206] = new State(-19); + states[207] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,208,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[208] = new State(new int[]{42,209,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[209] = new State(new int[]{23,221},new int[]{-34,210}); + states[210] = new State(new int[]{8,212,7,218,43,-116,26,-116,25,-116},new int[]{-30,211,-29,217}); + states[211] = new State(-112); + states[212] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,213,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[213] = new State(new int[]{42,214,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[214] = new State(new int[]{23,221},new int[]{-34,215}); + states[215] = new State(new int[]{8,212,7,218,43,-116,26,-116,25,-116},new int[]{-30,216,-29,217}); + states[216] = new State(-113); + states[217] = new State(-114); + states[218] = new State(new int[]{42,219}); + states[219] = new State(new int[]{23,221},new int[]{-34,220}); + states[220] = new State(-115); + states[221] = new State(new int[]{63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,34,198,6,207,5,227,3,232,10,248,11,251,12,253,15,255,17,264,20,266,9,273,13,300,14,308},new int[]{-33,222,-25,315,-23,8,-8,9,-1,79,-6,197,-7,181,-59,92,-60,98,-61,109,-22,205,-24,206,-26,225,-27,226,-28,231,-17,247,-18,250,-19,252,-20,254,-21,263,-31,265,-16,270,-44,271,-48,299}); + states[222] = new State(new int[]{26,313,43,314},new int[]{-55,223}); + states[223] = new State(new int[]{24,224,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,34,198,6,207,5,227,3,232,10,248,11,251,12,253,15,255,17,264,20,266,9,273,13,300,14,308},new int[]{-25,7,-23,8,-8,9,-1,79,-6,197,-7,181,-59,92,-60,98,-61,109,-22,205,-24,206,-26,225,-27,226,-28,231,-17,247,-18,250,-19,252,-20,254,-21,263,-31,265,-16,270,-44,271,-48,299}); + states[224] = new State(-150); + states[225] = new State(-20); + states[226] = new State(-21); + states[227] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,228,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[228] = new State(new int[]{42,229,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[229] = new State(new int[]{23,221},new int[]{-34,230}); + states[230] = new State(-117); + states[231] = new State(-22); + states[232] = new State(new int[]{63,80},new int[]{-1,233}); + states[233] = new State(new int[]{4,234,41,238}); + states[234] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,235,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[235] = new State(new int[]{42,236,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[236] = new State(new int[]{23,221},new int[]{-34,237}); + states[237] = new State(-118); + states[238] = new State(new int[]{63,80},new int[]{-43,239,-1,246}); + states[239] = new State(new int[]{4,240,41,244}); + states[240] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,241,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[241] = new State(new int[]{42,242,6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59}); + states[242] = new State(new int[]{23,221},new int[]{-34,243}); + states[243] = new State(-119); + states[244] = new State(new int[]{63,80},new int[]{-1,245}); + states[245] = new State(-121); + states[246] = new State(-120); + states[247] = new State(-23); + states[248] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127,43,-124,26,-124,25,-124},new int[]{-65,249,-5,12,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-66,172}); + states[249] = new State(-123); + states[250] = new State(-24); + states[251] = new State(-125); + states[252] = new State(-25); + states[253] = new State(-126); + states[254] = new State(-26); + states[255] = new State(new int[]{63,80},new int[]{-40,256,-2,262,-1,261}); + states[256] = new State(new int[]{41,257,43,-36,26,-36,25,-36}); + states[257] = new State(new int[]{63,80},new int[]{-2,258,-1,261}); + states[258] = new State(new int[]{40,259,41,-41,43,-41,26,-41,25,-41}); + states[259] = new State(new int[]{63,80},new int[]{-1,260}); + states[260] = new State(-39); + states[261] = new State(-38); + states[262] = new State(new int[]{40,259,41,-40,43,-40,26,-40,25,-40}); + states[263] = new State(-27); + states[264] = new State(-34); + states[265] = new State(-28); + states[266] = new State(new int[]{34,267}); + states[267] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127,35,-177},new int[]{-15,268,-14,72,-10,116,-5,117,-8,68,-1,76,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-62,134}); + states[268] = new State(new int[]{35,269}); + states[269] = new State(-35); + states[270] = new State(-29); + states[271] = new State(new int[]{23,221},new int[]{-34,272}); + states[272] = new State(-151); + states[273] = new State(new int[]{63,80},new int[]{-3,274,-1,298}); + states[274] = new State(new int[]{34,275}); + states[275] = new State(new int[]{63,80,59,289,73,293,35,-170},new int[]{-39,276,-38,282,-37,297,-36,285,-1,288}); + states[276] = new State(new int[]{35,277}); + states[277] = new State(new int[]{42,278,44,279}); + states[278] = new State(-152); + states[279] = new State(new int[]{63,80},new int[]{-45,280,-46,135,-1,144,-47,145}); + states[280] = new State(new int[]{42,281}); + states[281] = new State(-153); + states[282] = new State(new int[]{41,283,35,-169}); + states[283] = new State(new int[]{63,80,59,289,73,293},new int[]{-37,284,-36,285,-1,288}); + states[284] = new State(-168); + states[285] = new State(new int[]{42,286}); + states[286] = new State(new int[]{63,80},new int[]{-45,287,-46,135,-1,144,-47,145}); + states[287] = new State(-164); + states[288] = new State(-163); + states[289] = new State(new int[]{63,80},new int[]{-36,290,-1,288}); + states[290] = new State(new int[]{42,291}); + states[291] = new State(new int[]{63,80},new int[]{-45,292,-46,135,-1,144,-47,145}); + states[292] = new State(-165); + states[293] = new State(new int[]{63,80},new int[]{-36,294,-1,288}); + states[294] = new State(new int[]{42,295}); + states[295] = new State(new int[]{63,80},new int[]{-45,296,-46,135,-1,144,-47,145}); + states[296] = new State(-166); + states[297] = new State(-167); + states[298] = new State(-122); + states[299] = new State(-30); + states[300] = new State(new int[]{63,80},new int[]{-42,301,-41,307,-1,304}); + states[301] = new State(new int[]{41,302,43,-31,26,-31,25,-31}); + states[302] = new State(new int[]{63,80},new int[]{-41,303,-1,304}); + states[303] = new State(-45); + states[304] = new State(new int[]{16,305,41,-43,43,-43,26,-43,25,-43}); + states[305] = new State(new int[]{63,80},new int[]{-1,306}); + states[306] = new State(-42); + states[307] = new State(-44); + states[308] = new State(new int[]{63,80},new int[]{-1,309}); + states[309] = new State(new int[]{13,310}); + states[310] = new State(new int[]{59,312,63,80},new int[]{-42,311,-41,307,-1,304}); + states[311] = new State(new int[]{41,302,43,-32,26,-32,25,-32}); + states[312] = new State(-33); + states[313] = new State(-178); + states[314] = new State(-179); + states[315] = new State(-15); + states[316] = new State(new int[]{25,-180,63,-179,28,-179,29,-179,30,-179,31,-179,45,-179,33,-179,32,-179,38,-179,36,-179,34,-179,6,-179,5,-179,3,-179,10,-179,11,-179,12,-179,15,-179,17,-179,20,-179,9,-179,13,-179,14,-179}); + states[317] = new State(new int[]{25,318}); + states[318] = new State(-3); + states[319] = new State(new int[]{27,321,58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,320,-8,68,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[320] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,25,-4}); + states[321] = new State(new int[]{63,80},new int[]{-4,322,-1,323}); + states[322] = new State(-5); + states[323] = new State(new int[]{38,139,25,-8},new int[]{-49,324}); + states[324] = new State(-9); + states[325] = new State(new int[]{63,80},new int[]{-13,326,-2,327,-1,261}); + states[326] = new State(-6); + states[327] = new State(new int[]{40,259,38,139,25,-10},new int[]{-49,328}); + states[328] = new State(-11); + states[329] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,333},new int[]{-52,330,-5,331,-8,332,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126,-23,335,-22,336}); + states[330] = new State(-7); + states[331] = new State(new int[]{6,13,57,17,59,19,60,21,58,23,64,25,65,27,66,29,67,31,68,33,69,35,70,37,71,39,61,41,62,43,76,45,77,47,78,49,79,51,75,53,73,55,4,57,72,59,25,-12}); + states[332] = new State(new int[]{34,69,40,163,38,165,22,168,46,10,41,175,42,183,47,187,48,188,49,189,50,190,51,191,52,192,53,193,54,194,55,195,56,196,6,-93,57,-93,59,-93,60,-93,58,-93,64,-93,65,-93,66,-93,67,-93,68,-93,69,-93,70,-93,71,-93,61,-93,62,-93,76,-93,77,-93,78,-93,79,-93,75,-93,73,-93,4,-93,72,-93,25,-93},new int[]{-57,173}); + states[333] = new State(new int[]{58,62,72,64,74,66,63,80,28,85,29,86,30,87,31,88,45,89,33,90,32,91,38,93,36,99,21,111,34,127},new int[]{-5,128,-8,334,-1,79,-6,81,-7,82,-59,92,-60,98,-61,109,-11,110,-12,125,-64,126}); + states[334] = new State(new int[]{41,200,34,69,40,163,38,165,22,168,35,-93,6,-93,57,-93,59,-93,60,-93,58,-93,64,-93,65,-93,66,-93,67,-93,68,-93,69,-93,70,-93,71,-93,61,-93,62,-93,76,-93,77,-93,78,-93,79,-93,75,-93,73,-93,4,-93,72,-93}); + states[335] = new State(-13); + states[336] = new State(-14); + + rules[1] = new Rule(-67, new int[]{-35,2}); + rules[2] = new Rule(-35, new int[]{-33,-54,25}); + rules[3] = new Rule(-35, new int[]{-51,25}); + rules[4] = new Rule(-51, new int[]{80,-5}); + rules[5] = new Rule(-51, new int[]{80,27,-4}); + rules[6] = new Rule(-51, new int[]{82,-13}); + rules[7] = new Rule(-51, new int[]{81,-52}); + rules[8] = new Rule(-4, new int[]{-1}); + rules[9] = new Rule(-4, new int[]{-1,-49}); + rules[10] = new Rule(-13, new int[]{-2}); + rules[11] = new Rule(-13, new int[]{-2,-49}); + rules[12] = new Rule(-52, new int[]{-5}); + rules[13] = new Rule(-52, new int[]{-23}); + rules[14] = new Rule(-52, new int[]{-22}); + rules[15] = new Rule(-33, new int[]{-25}); + rules[16] = new Rule(-33, new int[]{-33,-55,-25}); + rules[17] = new Rule(-25, new int[]{-23}); + rules[18] = new Rule(-25, new int[]{-22}); + rules[19] = new Rule(-25, new int[]{-24}); + rules[20] = new Rule(-25, new int[]{-26}); + rules[21] = new Rule(-25, new int[]{-27}); + rules[22] = new Rule(-25, new int[]{-28}); + rules[23] = new Rule(-25, new int[]{-17}); + rules[24] = new Rule(-25, new int[]{-18}); + rules[25] = new Rule(-25, new int[]{-19}); + rules[26] = new Rule(-25, new int[]{-20}); + rules[27] = new Rule(-25, new int[]{-21}); + rules[28] = new Rule(-25, new int[]{-31}); + rules[29] = new Rule(-25, new int[]{-16}); + rules[30] = new Rule(-25, new int[]{-48}); + rules[31] = new Rule(-48, new int[]{13,-42}); + rules[32] = new Rule(-48, new int[]{14,-1,13,-42}); + rules[33] = new Rule(-48, new int[]{14,-1,13,59}); + rules[34] = new Rule(-21, new int[]{17}); + rules[35] = new Rule(-31, new int[]{20,34,-15,35}); + rules[36] = new Rule(-20, new int[]{15,-40}); + rules[37] = new Rule(-1, new int[]{63}); + rules[38] = new Rule(-2, new int[]{-1}); + rules[39] = new Rule(-2, new int[]{-2,40,-1}); + rules[40] = new Rule(-40, new int[]{-2}); + rules[41] = new Rule(-40, new int[]{-40,41,-2}); + rules[42] = new Rule(-41, new int[]{-1,16,-1}); + rules[43] = new Rule(-41, new int[]{-1}); + rules[44] = new Rule(-42, new int[]{-41}); + rules[45] = new Rule(-42, new int[]{-42,41,-41}); + rules[46] = new Rule(-58, new int[]{-5,42,-5}); + rules[47] = new Rule(-53, new int[]{-58}); + rules[48] = new Rule(-53, new int[]{-53,41,-58}); + rules[49] = new Rule(-22, new int[]{-8,42,-45}); + rules[50] = new Rule(-22, new int[]{-8,42,-45,46,-5}); + rules[51] = new Rule(-65, new int[]{-5}); + rules[52] = new Rule(-65, new int[]{-66}); + rules[53] = new Rule(-23, new int[]{-8,46,-65}); + rules[54] = new Rule(-23, new int[]{-8,-57,-65}); + rules[55] = new Rule(-23, new int[]{34,-8,41,-56,35,46,-65}); + rules[56] = new Rule(-23, new int[]{-8,41,-56,46,-65}); + rules[57] = new Rule(-57, new int[]{47}); + rules[58] = new Rule(-57, new int[]{48}); + rules[59] = new Rule(-57, new int[]{49}); + rules[60] = new Rule(-57, new int[]{50}); + rules[61] = new Rule(-57, new int[]{51}); + rules[62] = new Rule(-57, new int[]{52}); + rules[63] = new Rule(-57, new int[]{53}); + rules[64] = new Rule(-57, new int[]{54}); + rules[65] = new Rule(-57, new int[]{55}); + rules[66] = new Rule(-57, new int[]{56}); + rules[67] = new Rule(-5, new int[]{-5,6,-5,7,-5}); + rules[68] = new Rule(-5, new int[]{-5,57,-5}); + rules[69] = new Rule(-5, new int[]{-5,59,-5}); + rules[70] = new Rule(-5, new int[]{-5,60,-5}); + rules[71] = new Rule(-5, new int[]{-5,58,-5}); + rules[72] = new Rule(-5, new int[]{-5,64,-5}); + rules[73] = new Rule(-5, new int[]{-5,65,-5}); + rules[74] = new Rule(-5, new int[]{-5,66,-5}); + rules[75] = new Rule(-5, new int[]{-5,67,-5}); + rules[76] = new Rule(-5, new int[]{-5,68,-5}); + rules[77] = new Rule(-5, new int[]{-5,69,-5}); + rules[78] = new Rule(-5, new int[]{-5,70,-5}); + rules[79] = new Rule(-5, new int[]{-5,71,-5}); + rules[80] = new Rule(-5, new int[]{-5,61,-5}); + rules[81] = new Rule(-5, new int[]{-5,62,-5}); + rules[82] = new Rule(-5, new int[]{-5,76,-5}); + rules[83] = new Rule(-5, new int[]{-5,77,-5}); + rules[84] = new Rule(-5, new int[]{-5,78,-5}); + rules[85] = new Rule(-5, new int[]{-5,79,-5}); + rules[86] = new Rule(-5, new int[]{-5,75,-5}); + rules[87] = new Rule(-5, new int[]{-5,73,-5}); + rules[88] = new Rule(-5, new int[]{-5,4,-5}); + rules[89] = new Rule(-5, new int[]{-5,72,4,-5}); + rules[90] = new Rule(-5, new int[]{58,-5}); + rules[91] = new Rule(-5, new int[]{72,-5}); + rules[92] = new Rule(-5, new int[]{74,-5}); + rules[93] = new Rule(-5, new int[]{-8}); + rules[94] = new Rule(-5, new int[]{-7}); + rules[95] = new Rule(-5, new int[]{-11}); + rules[96] = new Rule(-5, new int[]{-12}); + rules[97] = new Rule(-5, new int[]{-64}); + rules[98] = new Rule(-5, new int[]{34,-5,35}); + rules[99] = new Rule(-64, new int[]{34,-5,41,-32,35}); + rules[100] = new Rule(-66, new int[]{-5,41,-32}); + rules[101] = new Rule(-12, new int[]{-8,22,-45}); + rules[102] = new Rule(-11, new int[]{21,-45,34,-15,35}); + rules[103] = new Rule(-7, new int[]{28}); + rules[104] = new Rule(-7, new int[]{29}); + rules[105] = new Rule(-7, new int[]{30}); + rules[106] = new Rule(-7, new int[]{31}); + rules[107] = new Rule(-7, new int[]{45}); + rules[108] = new Rule(-7, new int[]{33}); + rules[109] = new Rule(-7, new int[]{32}); + rules[110] = new Rule(-32, new int[]{-5}); + rules[111] = new Rule(-32, new int[]{-32,41,-5}); + rules[112] = new Rule(-24, new int[]{6,-5,42,-34,-30}); + rules[113] = new Rule(-30, new int[]{8,-5,42,-34,-30}); + rules[114] = new Rule(-30, new int[]{-29}); + rules[115] = new Rule(-29, new int[]{7,42,-34}); + rules[116] = new Rule(-29, new int[]{}); + rules[117] = new Rule(-27, new int[]{5,-5,42,-34}); + rules[118] = new Rule(-28, new int[]{3,-1,4,-5,42,-34}); + rules[119] = new Rule(-28, new int[]{3,-1,41,-43,4,-5,42,-34}); + rules[120] = new Rule(-43, new int[]{-1}); + rules[121] = new Rule(-43, new int[]{-43,41,-1}); + rules[122] = new Rule(-3, new int[]{-1}); + rules[123] = new Rule(-17, new int[]{10,-65}); + rules[124] = new Rule(-17, new int[]{10}); + rules[125] = new Rule(-18, new int[]{11}); + rules[126] = new Rule(-19, new int[]{12}); + rules[127] = new Rule(-26, new int[]{-6}); + rules[128] = new Rule(-8, new int[]{-1}); + rules[129] = new Rule(-8, new int[]{-6}); + rules[130] = new Rule(-8, new int[]{-8,40,-1}); + rules[131] = new Rule(-8, new int[]{-7,40,-1}); + rules[132] = new Rule(-8, new int[]{-59}); + rules[133] = new Rule(-8, new int[]{-60}); + rules[134] = new Rule(-8, new int[]{-61}); + rules[135] = new Rule(-8, new int[]{-8,38,-5,39}); + rules[136] = new Rule(-8, new int[]{38,-62,39}); + rules[137] = new Rule(-8, new int[]{36,-62,37}); + rules[138] = new Rule(-8, new int[]{36,-63,37}); + rules[139] = new Rule(-56, new int[]{-8}); + rules[140] = new Rule(-56, new int[]{-56,41,-8}); + rules[141] = new Rule(-62, new int[]{-5,3,-1,4,-5,-9}); + rules[142] = new Rule(-63, new int[]{-58,3,-1,4,-5,-9}); + rules[143] = new Rule(-61, new int[]{36,-53,37}); + rules[144] = new Rule(-61, new int[]{36,37}); + rules[145] = new Rule(-60, new int[]{36,-32,37}); + rules[146] = new Rule(-59, new int[]{38,-32,39}); + rules[147] = new Rule(-59, new int[]{38,39}); + rules[148] = new Rule(-9, new int[]{}); + rules[149] = new Rule(-9, new int[]{6,-5}); + rules[150] = new Rule(-34, new int[]{23,-33,-55,24}); + rules[151] = new Rule(-16, new int[]{-44,-34}); + rules[152] = new Rule(-44, new int[]{9,-3,34,-39,35,42}); + rules[153] = new Rule(-44, new int[]{9,-3,34,-39,35,44,-45,42}); + rules[154] = new Rule(-6, new int[]{-8,34,-15,35}); + rules[155] = new Rule(-46, new int[]{-1}); + rules[156] = new Rule(-46, new int[]{-46,40,-1}); + rules[157] = new Rule(-45, new int[]{-46}); + rules[158] = new Rule(-45, new int[]{-47}); + rules[159] = new Rule(-47, new int[]{-46,-49}); + rules[160] = new Rule(-49, new int[]{38,-50,39}); + rules[161] = new Rule(-50, new int[]{-45}); + rules[162] = new Rule(-50, new int[]{-50,41,-45}); + rules[163] = new Rule(-36, new int[]{-1}); + rules[164] = new Rule(-37, new int[]{-36,42,-45}); + rules[165] = new Rule(-37, new int[]{59,-36,42,-45}); + rules[166] = new Rule(-37, new int[]{73,-36,42,-45}); + rules[167] = new Rule(-38, new int[]{-37}); + rules[168] = new Rule(-38, new int[]{-38,41,-37}); + rules[169] = new Rule(-39, new int[]{-38}); + rules[170] = new Rule(-39, new int[]{}); + rules[171] = new Rule(-10, new int[]{-5}); + rules[172] = new Rule(-10, new int[]{-1,46,-5}); + rules[173] = new Rule(-14, new int[]{-10}); + rules[174] = new Rule(-14, new int[]{-14,41,-10}); + rules[175] = new Rule(-15, new int[]{-14}); + rules[176] = new Rule(-15, new int[]{-62}); + rules[177] = new Rule(-15, new int[]{}); + rules[178] = new Rule(-55, new int[]{26}); + rules[179] = new Rule(-55, new int[]{43}); + rules[180] = new Rule(-54, new int[]{43}); + rules[181] = new Rule(-54, new int[]{}); + } + + protected override void Initialize() { + this.InitSpecialTokens((int)Tokens.error, (int)Tokens.EOF); + this.InitStates(states); + this.InitRules(rules); + this.InitNonTerminals(nonTerms); + } + + protected override void DoAction(int action) + { + switch (action) + { + case 2: // program -> stmt_list, optional_semicolon, END_OF_FILE +{ + // main program + if (!is_unit_to_be_parsed) { + var stl = ValueStack[ValueStack.Depth-3].stn as statement_list; + stl.left_logical_bracket = new token_info(""); + stl.right_logical_bracket = new token_info(""); + var bl = new block(new declarations(), stl, CurrentLocationSpan); + root = CurrentSemanticValue.stn = NewProgramModule(null, null, new uses_list(), bl, ValueStack[ValueStack.Depth-2].ob, CurrentLocationSpan); + root.source_context = bl.source_context; + } + // unit + else { + var interface_part = new interface_node(new declarations(), new uses_list(), null, null); + var initialization_part = new initfinal_part(null, ValueStack[ValueStack.Depth-3].stn as statement_list, null, null, null, CurrentLocationSpan); + + root = CurrentSemanticValue.stn = new unit_module( + new unit_name(new ident(Path.GetFileNameWithoutExtension(parserTools.currentFileName)), + UnitHeaderKeyword.Unit, CurrentLocationSpan), interface_part, null, + initialization_part.initialization_sect, + initialization_part.finalization_sect, null, CurrentLocationSpan); + } + } + break; + case 3: // program -> parts, END_OF_FILE +{ + root = ValueStack[ValueStack.Depth-2].stn; + } + break; + case 4: // parts -> tkParseModeExpression, expr +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].ex; } + break; + case 5: // parts -> tkParseModeExpression, DECLTYPE, type_decl_identifier +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].id; } + break; + case 6: // parts -> tkParseModeType, variable_as_type +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].ex; } + break; + case 7: // parts -> tkParseModeStatement, stmt_or_expression +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; } + break; + case 8: // type_decl_identifier -> ident +{ + CurrentSemanticValue.id = ValueStack[ValueStack.Depth-1].id; + } + break; + case 9: // type_decl_identifier -> ident, template_type_params +{ + CurrentSemanticValue.id = new template_type_name(ValueStack[ValueStack.Depth-2].id.name, ValueStack[ValueStack.Depth-1].stn as ident_list, CurrentLocationSpan); + } + break; + case 10: // variable_as_type -> dotted_ident +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].id; + } + break; + case 11: // variable_as_type -> dotted_ident, template_type_params +{ + CurrentSemanticValue.ex = new ident_with_templateparams(ValueStack[ValueStack.Depth-2].id as addressed_value, ValueStack[ValueStack.Depth-1].stn as template_param_list, CurrentLocationSpan); + } + break; + case 12: // stmt_or_expression -> expr +{ CurrentSemanticValue.stn = new expression_as_statement(ValueStack[ValueStack.Depth-1].ex,CurrentLocationSpan);} + break; + case 13: // stmt_or_expression -> assign_stmt +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; } + break; + case 14: // stmt_or_expression -> var_stmt +{ CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; } + break; + case 15: // stmt_list -> stmt +{ + CurrentSemanticValue.stn = new statement_list(ValueStack[ValueStack.Depth-1].stn as statement, CurrentLocationSpan); + } + break; + case 16: // stmt_list -> stmt_list, end_of_line, stmt +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as statement_list).Add(ValueStack[ValueStack.Depth-1].stn as statement, CurrentLocationSpan); + } + break; + case 17: // stmt -> assign_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 18: // stmt -> var_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 19: // stmt -> if_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 20: // stmt -> proc_func_call_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 21: // stmt -> while_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 22: // stmt -> for_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 23: // stmt -> return_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 24: // stmt -> break_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 25: // stmt -> continue_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 26: // stmt -> global_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 27: // stmt -> pass_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 28: // stmt -> exit_stmt +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 29: // stmt -> proc_func_decl +{ + CurrentSemanticValue.stn = new declarations_as_statement(new declarations(ValueStack[ValueStack.Depth-1].stn as procedure_definition, CurrentLocationSpan), CurrentLocationSpan); + } + break; + case 30: // stmt -> import_clause +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 31: // import_clause -> IMPORT, ident_as_ident_list +{ + CurrentSemanticValue.stn = new import_statement(ValueStack[ValueStack.Depth-1].stn as as_statement_list, CurrentLocationSpan); + } + break; + case 32: // import_clause -> FROM, ident, IMPORT, ident_as_ident_list +{ + CurrentSemanticValue.stn = new from_import_statement(ValueStack[ValueStack.Depth-3].id as ident, false, ValueStack[ValueStack.Depth-1].stn as as_statement_list, CurrentLocationSpan); + } + break; + case 33: // import_clause -> FROM, ident, IMPORT, STAR +{ + CurrentSemanticValue.stn = new from_import_statement(ValueStack[ValueStack.Depth-3].id as ident, true, null, CurrentLocationSpan); + } + break; + case 34: // pass_stmt -> PASS +{ + CurrentSemanticValue.stn = new empty_statement(); + } + break; + case 35: // exit_stmt -> EXIT, LPAR, optional_act_param_list, RPAR +{ + parserTools.AddErrorFromResource("UNSUPPORTED_CONSTRUCTION_{0}", CurrentLocationSpan, "exit"); + } + break; + case 36: // global_stmt -> GLOBAL, dotted_ident_list +{ + CurrentSemanticValue.stn = new global_statement(ValueStack[ValueStack.Depth-1].stn as ident_list, CurrentLocationSpan); + } + break; + case 37: // ident -> ID +{ + CurrentSemanticValue.id = ValueStack[ValueStack.Depth-1].id; + } + break; + case 38: // dotted_ident -> ident +{ + CurrentSemanticValue.id = ValueStack[ValueStack.Depth-1].id; + } + break; + case 39: // dotted_ident -> dotted_ident, DOT, ident +{ + CurrentSemanticValue.id = new ident(ValueStack[ValueStack.Depth-3].id.name + "." + ValueStack[ValueStack.Depth-1].id.name, CurrentLocationSpan); + } + break; + case 40: // dotted_ident_list -> dotted_ident +{ + CurrentSemanticValue.stn = new ident_list(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 41: // dotted_ident_list -> dotted_ident_list, COMMA, dotted_ident +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as ident_list).Add(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 42: // ident_as_ident -> ident, AS, ident +{ + CurrentSemanticValue.stn = new as_statement(ValueStack[ValueStack.Depth-3].id, ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 43: // ident_as_ident -> ident +{ + CurrentSemanticValue.stn = new as_statement(ValueStack[ValueStack.Depth-1].id, ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 44: // ident_as_ident_list -> ident_as_ident +{ + CurrentSemanticValue.stn = new as_statement_list(ValueStack[ValueStack.Depth-1].stn as as_statement, CurrentLocationSpan); + } + break; + case 45: // ident_as_ident_list -> ident_as_ident_list, COMMA, ident_as_ident +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as as_statement_list).Add(ValueStack[ValueStack.Depth-1].stn as as_statement, CurrentLocationSpan); + } + break; + case 46: // expr_mapping -> expr, COLON, expr +{ + expression_list el = new expression_list(new List { ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex }, CurrentLocationSpan); + CurrentSemanticValue.ex = new tuple_node(el, CurrentLocationSpan); + } + break; + case 47: // expr_mapping_list -> expr_mapping +{ + CurrentSemanticValue.stn = new expression_list(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 48: // expr_mapping_list -> expr_mapping_list, COMMA, expr_mapping +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as expression_list).Add(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 49: // var_stmt -> variable, COLON, type_ref +{ + var vds = new var_def_statement(new ident_list(ValueStack[ValueStack.Depth-3].ex as ident, LocationStack[LocationStack.Depth-3]), ValueStack[ValueStack.Depth-1].td, null, definition_attribute.None, false, CurrentLocationSpan); + CurrentSemanticValue.stn = new var_statement(vds, CurrentLocationSpan); + } + break; + case 50: // var_stmt -> variable, COLON, type_ref, ASSIGN, expr +{ + var vds = new var_def_statement(new ident_list(ValueStack[ValueStack.Depth-5].ex as ident, LocationStack[LocationStack.Depth-5]), ValueStack[ValueStack.Depth-3].td, ValueStack[ValueStack.Depth-1].ex, definition_attribute.None, false, CurrentLocationSpan); + CurrentSemanticValue.stn = new var_statement(vds, CurrentLocationSpan); + } + break; + case 51: // assign_right_part -> expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 52: // assign_right_part -> turbo_tuple_expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 53: // assign_stmt -> variable, ASSIGN, assign_right_part +{ + if (!(ValueStack[ValueStack.Depth-3].ex is addressed_value)) + parserTools.AddErrorFromResource("LEFT_SIDE_CANNOT_BE_ASSIGNED_TO", CurrentLocationSpan); + CurrentSemanticValue.stn = new assign(ValueStack[ValueStack.Depth-3].ex as addressed_value, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 54: // assign_stmt -> variable, assign_type, assign_right_part +{ + if (!(ValueStack[ValueStack.Depth-3].ex is addressed_value)) + parserTools.AddErrorFromResource("LEFT_SIDE_CANNOT_BE_ASSIGNED_TO", CurrentLocationSpan); + CurrentSemanticValue.stn = new assign(ValueStack[ValueStack.Depth-3].ex as addressed_value, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 55: // assign_stmt -> LPAR, variable, COMMA, variable_list, RPAR, ASSIGN, + // assign_right_part +{ + // if False: + if (ValueStack[ValueStack.Depth-2].op.type != Operators.Assignment) + parserTools.AddErrorFromResource("ONLY_BASE_ASSIGNMENT_FOR_TUPLE", LocationStack[LocationStack.Depth-2]); + (ValueStack[ValueStack.Depth-4].ob as addressed_value_list).Insert(0, ValueStack[ValueStack.Depth-6].ex as addressed_value); + (ValueStack[ValueStack.Depth-4].ob as syntax_tree_node).source_context = LexLocation.MergeAll(LocationStack[LocationStack.Depth-7], LocationStack[LocationStack.Depth-6], LocationStack[LocationStack.Depth-5], LocationStack[LocationStack.Depth-4], LocationStack[LocationStack.Depth-3]); + CurrentSemanticValue.stn = new assign_tuple(ValueStack[ValueStack.Depth-4].ob as addressed_value_list, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 56: // assign_stmt -> variable, COMMA, variable_list, ASSIGN, assign_right_part +{ + // if False: + if (ValueStack[ValueStack.Depth-2].op.type != Operators.Assignment) + parserTools.AddErrorFromResource("ONLY_BASE_ASSIGNMENT_FOR_TUPLE", LocationStack[LocationStack.Depth-2]); + (ValueStack[ValueStack.Depth-3].ob as addressed_value_list).Insert(0, ValueStack[ValueStack.Depth-5].ex as addressed_value); + (ValueStack[ValueStack.Depth-3].ob as syntax_tree_node).source_context = LexLocation.MergeAll(LocationStack[LocationStack.Depth-5], LocationStack[LocationStack.Depth-4], LocationStack[LocationStack.Depth-3]); + CurrentSemanticValue.stn = new assign_tuple(ValueStack[ValueStack.Depth-3].ob as addressed_value_list, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 57: // assign_type -> PLUSEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 58: // assign_type -> MINUSEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 59: // assign_type -> STAREQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 60: // assign_type -> DIVEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 61: // assign_type -> BINXOREQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 62: // assign_type -> SHLEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 63: // assign_type -> SHREQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 64: // assign_type -> BINANDEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 65: // assign_type -> BINOREQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 66: // assign_type -> INTDIVISIONEQUAL +{ + CurrentSemanticValue.op = ValueStack[ValueStack.Depth-1].op; + } + break; + case 67: // expr -> expr, IF, expr, ELSE, expr +{ + CurrentSemanticValue.ex = new question_colon_expression(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-5].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 68: // expr -> expr, PLUS, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 69: // expr -> expr, STAR, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 70: // expr -> expr, DIVIDE, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 71: // expr -> expr, MINUS, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 72: // expr -> expr, LESS, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 73: // expr -> expr, GREATER, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 74: // expr -> expr, LESSEQUAL, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 75: // expr -> expr, GREATEREQUAL, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 76: // expr -> expr, EQUAL, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 77: // expr -> expr, NOTEQUAL, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 78: // expr -> expr, AND, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 79: // expr -> expr, OR, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 80: // expr -> expr, SLASHSLASH, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 81: // expr -> expr, PERCENTAGE, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 82: // expr -> expr, SHL, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 83: // expr -> expr, SHR, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 84: // expr -> expr, BINAND, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 85: // expr -> expr, BINOR, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 86: // expr -> expr, BINXOR, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 87: // expr -> expr, STARSTAR, expr +{ + addressed_value method_name = new ident("!pow", CurrentLocationSpan); + expression_list el = new expression_list(new List { ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex }, CurrentLocationSpan); + CurrentSemanticValue.ex = new method_call(method_name, el, CurrentLocationSpan); + } + break; + case 88: // expr -> expr, IN, expr +{ + CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, Operators.In, CurrentLocationSpan); + } + break; + case 89: // expr -> expr, NOT, IN, expr +{ + // $$ = new bin_expr($1, $4, Operators.NotIn, @$); + CurrentSemanticValue.ex = new un_expr(new bin_expr(ValueStack[ValueStack.Depth-4].ex, ValueStack[ValueStack.Depth-1].ex, Operators.In, CurrentLocationSpan),Operators.LogicalNOT,CurrentLocationSpan); + } + break; + case 90: // expr -> MINUS, expr +{ + CurrentSemanticValue.ex = new un_expr(ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 91: // expr -> NOT, expr +{ + CurrentSemanticValue.ex = new un_expr(ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 92: // expr -> BINNOT, expr +{ + CurrentSemanticValue.ex = new un_expr(ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); + } + break; + case 93: // expr -> variable +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 94: // expr -> const_value +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 95: // expr -> new_expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 96: // expr -> is_expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 97: // expr -> tuple_expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 98: // expr -> LPAR, expr, RPAR +{ + CurrentSemanticValue.ex = new bracket_expr(ValueStack[ValueStack.Depth-2].ex, CurrentLocationSpan); + } + break; + case 99: // tuple_expr -> LPAR, expr, COMMA, expr_list, RPAR +{ + // inherited from PABC + if ((ValueStack[ValueStack.Depth-2].stn as expression_list).Count > 6) + parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7", CurrentLocationSpan); + (ValueStack[ValueStack.Depth-2].stn as expression_list).Insert(0, ValueStack[ValueStack.Depth-4].ex); + CurrentSemanticValue.ex = new tuple_node(ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan); + } + break; + case 100: // turbo_tuple_expr -> expr, COMMA, expr_list +{ + // inherited from PABC + if ((ValueStack[ValueStack.Depth-1].stn as expression_list).Count > 6) + parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7", CurrentLocationSpan); + (ValueStack[ValueStack.Depth-1].stn as expression_list).Insert(0, ValueStack[ValueStack.Depth-3].ex); + CurrentSemanticValue.ex = new tuple_node(ValueStack[ValueStack.Depth-1].stn as expression_list, CurrentLocationSpan); + } + break; + case 101: // is_expr -> variable, IS, type_ref +{ + CurrentSemanticValue.ex = parserTools.NewAsIsExpr(ValueStack[ValueStack.Depth-3].ex, op_typecast.is_op, ValueStack[ValueStack.Depth-1].td, CurrentLocationSpan); + } + break; + case 102: // new_expr -> NEW, type_ref, LPAR, optional_act_param_list, RPAR +{ + CurrentSemanticValue.ex = new new_expr(ValueStack[ValueStack.Depth-4].td, ValueStack[ValueStack.Depth-2].stn as expression_list, false, null, CurrentLocationSpan); + } + break; + case 103: // const_value -> INTNUM +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 104: // const_value -> REALNUM +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 105: // const_value -> TRUE +{ + CurrentSemanticValue.ex = new ident("true", CurrentLocationSpan); + } + break; + case 106: // const_value -> FALSE +{ + CurrentSemanticValue.ex = new ident("false", CurrentLocationSpan); + } + break; + case 107: // const_value -> STRINGNUM +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].stn as literal; + } + break; + case 108: // const_value -> FSTRINGNUM +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 109: // const_value -> BIGINT +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 110: // expr_list -> expr +{ + CurrentSemanticValue.stn = new expression_list(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 111: // expr_list -> expr_list, COMMA, expr +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as expression_list).Add(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 112: // if_stmt -> IF, expr, COLON, block, optional_elif +{ + CurrentSemanticValue.stn = new if_node(ValueStack[ValueStack.Depth-4].ex, ValueStack[ValueStack.Depth-2].stn as statement, ValueStack[ValueStack.Depth-1].stn as statement, CurrentLocationSpan); + } + break; + case 113: // optional_elif -> ELIF, expr, COLON, block, optional_elif +{ + CurrentSemanticValue.stn = new if_node(ValueStack[ValueStack.Depth-4].ex, ValueStack[ValueStack.Depth-2].stn as statement, ValueStack[ValueStack.Depth-1].stn as statement, CurrentLocationSpan); + } + break; + case 114: // optional_elif -> optional_else +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 115: // optional_else -> ELSE, COLON, block +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 116: // optional_else -> /* empty */ +{ + CurrentSemanticValue.stn = null; + } + break; + case 117: // while_stmt -> WHILE, expr, COLON, block +{ + CurrentSemanticValue.stn = new while_node(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].stn as statement, WhileCycleType.While, CurrentLocationSpan); + } + break; + case 118: // for_stmt -> FOR, ident, IN, expr, COLON, block +{ + CurrentSemanticValue.stn = new foreach_stmt(ValueStack[ValueStack.Depth-5].id, new no_type_foreach(), ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].stn as statement, null, CurrentLocationSpan); + } + break; + case 119: // for_stmt -> FOR, ident, COMMA, ident_list, IN, expr, COLON, block +{ + (ValueStack[ValueStack.Depth-5].stn as ident_list).AddFirst(ValueStack[ValueStack.Depth-7].id); + var id = parserTools.NewId("#fe",LocationStack[LocationStack.Depth-5]); + var tttt = new assign_var_tuple(ValueStack[ValueStack.Depth-5].stn as ident_list, id, CurrentLocationSpan); + statement_list nine = ValueStack[ValueStack.Depth-1].stn is statement_list ? ValueStack[ValueStack.Depth-1].stn as statement_list : new statement_list(ValueStack[ValueStack.Depth-1].stn as statement, LocationStack[LocationStack.Depth-1]); + nine.Insert(0, tttt); + var fe = new foreach_stmt(id, new no_type_foreach(), ValueStack[ValueStack.Depth-3].ex, nine, null, CurrentLocationSpan); + fe.ext = ValueStack[ValueStack.Depth-5].stn as ident_list; + CurrentSemanticValue.stn = fe; + } + break; + case 120: // ident_list -> ident +{ + CurrentSemanticValue.stn = new ident_list(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 121: // ident_list -> ident_list, COMMA, ident +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as ident_list).Add(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 122: // func_name_ident -> ident +{ + CurrentSemanticValue.id = ValueStack[ValueStack.Depth-1].id; + } + break; + case 123: // return_stmt -> RETURN, assign_right_part +{ + CurrentSemanticValue.stn = new return_statement(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 124: // return_stmt -> RETURN +{ + CurrentSemanticValue.stn = new return_statement(null, CurrentLocationSpan); + } + break; + case 125: // break_stmt -> BREAK +{ + CurrentSemanticValue.stn = new procedure_call(new ident("break", CurrentLocationSpan), true, CurrentLocationSpan); + } + break; + case 126: // continue_stmt -> CONTINUE +{ + CurrentSemanticValue.stn = new procedure_call(new ident("continue", CurrentLocationSpan), true, CurrentLocationSpan); + } + break; + case 127: // proc_func_call_stmt -> proc_func_call +{ + CurrentSemanticValue.stn = new procedure_call(ValueStack[ValueStack.Depth-1].ex as addressed_value, ValueStack[ValueStack.Depth-1].ex is ident, CurrentLocationSpan); + } + break; + case 128: // variable -> ident +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].id; + } + break; + case 129: // variable -> proc_func_call +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 130: // variable -> variable, DOT, ident +{ + CurrentSemanticValue.ex = new dot_node(ValueStack[ValueStack.Depth-3].ex as addressed_value, ValueStack[ValueStack.Depth-1].id as addressed_value, CurrentLocationSpan); + } + break; + case 131: // variable -> const_value, DOT, ident +{ + CurrentSemanticValue.ex = new dot_node(ValueStack[ValueStack.Depth-3].ex as addressed_value, ValueStack[ValueStack.Depth-1].id as addressed_value, CurrentLocationSpan); + } + break; + case 132: // variable -> list_constant +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 133: // variable -> set_constant +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 134: // variable -> dict_constant +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 135: // variable -> variable, LBRACKET, expr, RBRACKET +{ + var el = new expression_list(ValueStack[ValueStack.Depth-2].ex as expression, CurrentLocationSpan); + CurrentSemanticValue.ex = new indexer(ValueStack[ValueStack.Depth-4].ex as addressed_value, el, CurrentLocationSpan); + } + break; + case 136: // variable -> LBRACKET, generator_object, RBRACKET +{ + dot_node dn = new dot_node(ValueStack[ValueStack.Depth-2].ex as addressed_value, (new ident("ToList")) as addressed_value, ValueStack[ValueStack.Depth-2].ex.source_context); + CurrentSemanticValue.ex = new method_call(dn as addressed_value, null, ValueStack[ValueStack.Depth-2].ex.source_context); + } + break; + case 137: // variable -> LBRACE, generator_object, RBRACE +{ + dot_node dn = new dot_node(ValueStack[ValueStack.Depth-2].ex as addressed_value, (new ident("ToSet")) as addressed_value, ValueStack[ValueStack.Depth-2].ex.source_context); + CurrentSemanticValue.ex = new method_call(dn as addressed_value, null, ValueStack[ValueStack.Depth-2].ex.source_context); + } + break; + case 138: // variable -> LBRACE, generator_object_for_dict, RBRACE +{ + dot_node dn = new dot_node(ValueStack[ValueStack.Depth-2].ex as addressed_value, (new ident("ToDictionary")) as addressed_value, ValueStack[ValueStack.Depth-2].ex.source_context); + CurrentSemanticValue.ex = new method_call(dn as addressed_value, null, ValueStack[ValueStack.Depth-2].ex.source_context); + } + break; + case 139: // variable_list -> variable +{ + CurrentSemanticValue.ob = new addressed_value_list(ValueStack[ValueStack.Depth-1].ex as addressed_value,LocationStack[LocationStack.Depth-1]); + } + break; + case 140: // variable_list -> variable_list, COMMA, variable +{ + (ValueStack[ValueStack.Depth-3].ob as addressed_value_list).Add(ValueStack[ValueStack.Depth-1].ex as addressed_value); + (ValueStack[ValueStack.Depth-3].ob as syntax_tree_node).source_context = LexLocation.MergeAll(LocationStack[LocationStack.Depth-3],LocationStack[LocationStack.Depth-2],LocationStack[LocationStack.Depth-1]); + CurrentSemanticValue.ob = ValueStack[ValueStack.Depth-3].ob; + } + break; + case 141: // generator_object -> expr, FOR, ident, IN, expr, optional_condition +{ + CurrentSemanticValue.ex = new generator_object(ValueStack[ValueStack.Depth-6].ex, ValueStack[ValueStack.Depth-4].id, ValueStack[ValueStack.Depth-2].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 142: // generator_object_for_dict -> expr_mapping, FOR, ident, IN, expr, + // optional_condition +{ + CurrentSemanticValue.ex = new generator_object(ValueStack[ValueStack.Depth-6].ex, ValueStack[ValueStack.Depth-4].id, ValueStack[ValueStack.Depth-2].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 143: // dict_constant -> LBRACE, expr_mapping_list, RBRACE +{ + CurrentSemanticValue.ex = new method_call(new ident("Dict", CurrentLocationSpan), ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan); + } + break; + case 144: // dict_constant -> LBRACE, RBRACE +{ + CurrentSemanticValue.ex = new method_call(new ident("!empty_dict", CurrentLocationSpan), null, CurrentLocationSpan); + } + break; + case 145: // set_constant -> LBRACE, expr_list, RBRACE +{ + CurrentSemanticValue.ex = new pascal_set_constant(ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan); + } + break; + case 146: // list_constant -> LBRACKET, expr_list, RBRACKET +{ + var acn = new array_const_new(ValueStack[ValueStack.Depth-2].stn as expression_list, '|', CurrentLocationSpan); + var dn = new dot_node(acn as addressed_value, (new ident("ToList", CurrentLocationSpan)) as addressed_value, CurrentLocationSpan); + CurrentSemanticValue.ex = new method_call(dn as addressed_value, null, CurrentLocationSpan); + } + break; + case 147: // list_constant -> LBRACKET, RBRACKET +{ + CurrentSemanticValue.ex = new method_call(new ident("!empty_list", CurrentLocationSpan), null, CurrentLocationSpan); + } + break; + case 148: // optional_condition -> /* empty */ +{ + CurrentSemanticValue.ex = null; + } + break; + case 149: // optional_condition -> IF, expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 150: // block -> INDENT, stmt_list, end_of_line, UNINDENT +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-3].stn as statement_list; + (CurrentSemanticValue.stn as statement_list).left_logical_bracket = ValueStack[ValueStack.Depth-4].ti; + (CurrentSemanticValue.stn as statement_list).right_logical_bracket = ValueStack[ValueStack.Depth-1].ti; + CurrentSemanticValue.stn.source_context = LexLocation.MergeAll(LocationStack[LocationStack.Depth-3], LocationStack[LocationStack.Depth-2]); + } + break; + case 151: // proc_func_decl -> proc_func_header, block +{ + CurrentSemanticValue.stn = new procedure_definition(ValueStack[ValueStack.Depth-2].td as procedure_header, new block(null, ValueStack[ValueStack.Depth-1].stn as statement_list, LocationStack[LocationStack.Depth-1]), CurrentLocationSpan); + } + break; + case 152: // proc_func_header -> DEF, func_name_ident, LPAR, optional_form_param_list, RPAR, + // COLON +{ + CurrentSemanticValue.td = new procedure_header(ValueStack[ValueStack.Depth-3].stn as formal_parameters, new procedure_attributes_list(new List()), new method_name(null,null, ValueStack[ValueStack.Depth-5].id, null, LocationStack[LocationStack.Depth-5]), null, CurrentLocationSpan); + } + break; + case 153: // proc_func_header -> DEF, func_name_ident, LPAR, optional_form_param_list, RPAR, + // ARROW, type_ref, COLON +{ + CurrentSemanticValue.td = new function_header(ValueStack[ValueStack.Depth-5].stn as formal_parameters, new procedure_attributes_list(new List()), new method_name(null,null, ValueStack[ValueStack.Depth-7].id, null, LocationStack[LocationStack.Depth-7]), null, ValueStack[ValueStack.Depth-2].td as type_definition, CurrentLocationSpan); + } + break; + case 154: // proc_func_call -> variable, LPAR, optional_act_param_list, RPAR +{ + CurrentSemanticValue.ex = new method_call(ValueStack[ValueStack.Depth-4].ex as addressed_value, ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan); + } + break; + case 155: // simple_type_identifier -> ident +{ + CurrentSemanticValue.td = new named_type_reference(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 156: // simple_type_identifier -> simple_type_identifier, DOT, ident +{ + CurrentSemanticValue.td = (ValueStack[ValueStack.Depth-3].td as named_type_reference).Add(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 157: // type_ref -> simple_type_identifier +{ + CurrentSemanticValue.td = ValueStack[ValueStack.Depth-1].td as named_type_reference; + } + break; + case 158: // type_ref -> template_type +{ + CurrentSemanticValue.td = ValueStack[ValueStack.Depth-1].td; + } + break; + case 159: // template_type -> simple_type_identifier, template_type_params +{ + CurrentSemanticValue.td = new template_type_reference(ValueStack[ValueStack.Depth-2].td as named_type_reference, ValueStack[ValueStack.Depth-1].stn as template_param_list, CurrentLocationSpan); + } + break; + case 160: // template_type_params -> LBRACKET, template_param_list, RBRACKET +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-2].stn; + CurrentSemanticValue.stn.source_context = CurrentLocationSpan; + } + break; + case 161: // template_param_list -> type_ref +{ + CurrentSemanticValue.stn = new template_param_list(ValueStack[ValueStack.Depth-1].td, CurrentLocationSpan); + } + break; + case 162: // template_param_list -> template_param_list, COMMA, type_ref +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as template_param_list).Add(ValueStack[ValueStack.Depth-1].td, CurrentLocationSpan); + } + break; + case 163: // param_name -> ident +{ + CurrentSemanticValue.stn = new ident_list(ValueStack[ValueStack.Depth-1].id, CurrentLocationSpan); + } + break; + case 164: // form_param_sect -> param_name, COLON, type_ref +{ + CurrentSemanticValue.stn = new typed_parameters(ValueStack[ValueStack.Depth-3].stn as ident_list, ValueStack[ValueStack.Depth-1].td, parametr_kind.none, null, CurrentLocationSpan); + } + break; + case 165: // form_param_sect -> STAR, param_name, COLON, type_ref +{ + var at = new array_type(null, ValueStack[ValueStack.Depth-1].td, CurrentLocationSpan); + CurrentSemanticValue.stn = new typed_parameters(ValueStack[ValueStack.Depth-3].stn as ident_list, at, parametr_kind.params_parametr, null, CurrentLocationSpan); + } + break; + case 166: // form_param_sect -> STARSTAR, param_name, COLON, type_ref +{ + CurrentSemanticValue.stn = new typed_parameters(ValueStack[ValueStack.Depth-3].stn as ident_list, ValueStack[ValueStack.Depth-1].td, parametr_kind.kwargs_parameter, null, CurrentLocationSpan); + } + break; + case 167: // form_param_list -> form_param_sect +{ + CurrentSemanticValue.stn = new formal_parameters(ValueStack[ValueStack.Depth-1].stn as typed_parameters, CurrentLocationSpan); + } + break; + case 168: // form_param_list -> form_param_list, COMMA, form_param_sect +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as formal_parameters).Add(ValueStack[ValueStack.Depth-1].stn as typed_parameters, CurrentLocationSpan); + } + break; + case 169: // optional_form_param_list -> form_param_list +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 170: // optional_form_param_list -> /* empty */ +{ + CurrentSemanticValue.stn = null; + } + break; + case 171: // act_param -> expr +{ + CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; + } + break; + case 172: // act_param -> ident, ASSIGN, expr +{ + CurrentSemanticValue.ex = new name_assign_expr(ValueStack[ValueStack.Depth-3].id, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 173: // act_param_list -> act_param +{ + CurrentSemanticValue.stn = new expression_list(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 174: // act_param_list -> act_param_list, COMMA, act_param +{ + CurrentSemanticValue.stn = (ValueStack[ValueStack.Depth-3].stn as expression_list).Add(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 175: // optional_act_param_list -> act_param_list +{ + CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; + } + break; + case 176: // optional_act_param_list -> generator_object +{ + CurrentSemanticValue.stn = new expression_list(ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + break; + case 177: // optional_act_param_list -> /* empty */ +{ + CurrentSemanticValue.stn = null; + } + break; + case 178: // end_of_line -> END_OF_LINE +{ + CurrentSemanticValue.ob = ValueStack[ValueStack.Depth-1].ti; + } + break; + case 179: // end_of_line -> SEMICOLON +{ + CurrentSemanticValue.ob = ValueStack[ValueStack.Depth-1].ti; + } + break; + case 180: // optional_semicolon -> SEMICOLON +{ + CurrentSemanticValue.ob = ValueStack[ValueStack.Depth-1].ti; + } + break; + case 181: // optional_semicolon -> /* empty */ +{ + CurrentSemanticValue.ob = null; + } + break; + } + } + + protected override string TerminalToString(int terminal) + { + if (aliasses != null && aliasses.ContainsKey(terminal)) + return aliasses[terminal]; + else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture)) + return ((Tokens)terminal).ToString(); + else + return CharToString((char)terminal); + } + + + public program_module NewProgramModule(program_name progName, Object optHeadCompDirs, uses_list mainUsesClose, syntax_tree_node progBlock, Object optPoint, LexLocation loc) + { + var progModule = new program_module(progName, mainUsesClose, progBlock as block, null, loc); + progModule.Language = "SPython"; + if (optPoint == null && progBlock != null) + { + var fp = progBlock.source_context.end_position; + var err_stn = progBlock; + if ((progBlock is block) && (progBlock as block).program_code != null && (progBlock as block).program_code.subnodes != null && (progBlock as block).program_code.subnodes.Count > 0) + err_stn = (progBlock as block).program_code.subnodes[(progBlock as block).program_code.subnodes.Count - 1]; + //parserTools.errors.Add(new SPythonUnexpectedToken(parserTools.currentFileName, StringResources.Get("TKPOINT"), new SourceContext(fp.line_num, fp.column_num + 1, fp.line_num, fp.column_num + 1, 0, 0), err_stn)); + } + return progModule; + } +} +} diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/_ReBuild.bat b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/_ReBuild.bat new file mode 100644 index 000000000..991ddde6d --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/_ReBuild.bat @@ -0,0 +1,4 @@ +call generateParser.bat +dotnet build -c Release --no-incremental -v d SPythonParser.csproj + +@IF %ERRORLEVEL% NEQ 0 PAUSE \ No newline at end of file diff --git a/LanguagePlugins/SPython/SPythonParserKrylovMovchan/generateParser.bat b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/generateParser.bat new file mode 100644 index 000000000..2c2451b17 --- /dev/null +++ b/LanguagePlugins/SPython/SPythonParserKrylovMovchan/generateParser.bat @@ -0,0 +1,4 @@ +cls +..\..\..\Utils\GPLex_GPPG\Gplex.exe /unicode SPythonLexer.lex +..\..\..\Utils\GPLex_GPPG\Gppg.exe /no-lines /gplex SPythonParser.y +pause \ No newline at end of file diff --git a/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Errors.cs b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Errors.cs new file mode 100644 index 000000000..7613e6c0e --- /dev/null +++ b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Errors.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using PascalABCCompiler.Errors; +using PascalABCCompiler.TreeConverter; +using PascalABCCompiler.TreeRealization; + +namespace SPythonSyntaxTreeVisitor +{ + class SPythonSemanticError : SimpleSemanticError + { + public SPythonSemanticError(location loc, string ErrResourceString, params object[] values) : base(loc, ErrResourceString, values) { } + public override string ToString() + { + string err_res = ErrorResourceString; + if (!ErrorResourceString.StartsWith("SPYTHONSEMANTIC_")) + { + err_res = "SEMANTICERROR_" + ErrorResourceString; + } + if (values != null) + return string.Format(PascalABCCompiler.StringResources.Get(err_res), values); + else + return string.Format(PascalABCCompiler.StringResources.Get(err_res), ""); + } + } +} diff --git a/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Properties/AssemblyInfo.cs b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e91b70eb6 --- /dev/null +++ b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные со сборкой. +[assembly: AssemblyTitle("SPythonSyntaxTreeVisitor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SPythonSyntaxTreeVisitor")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// COM, задайте атрибуту ComVisible значение TRUE для этого типа. +[assembly: ComVisible(false)] + +// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM +[assembly: Guid("d38a21e0-1d61-4905-82b3-1800e1991d57")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Редакция +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/SPythonSyntaxTreeVisitor.csproj b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/SPythonSyntaxTreeVisitor.csproj new file mode 100644 index 000000000..3027a5724 --- /dev/null +++ b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/SPythonSyntaxTreeVisitor.csproj @@ -0,0 +1,23 @@ + + + + net40 + + Languages.SPython.Backend.Conversion + + ..\..\..\..\bin\ + false + + false + + + + + + + + + + + + \ No newline at end of file diff --git a/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/spython_syntax_tree_visitor.cs b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/spython_syntax_tree_visitor.cs new file mode 100644 index 000000000..9c98f8b44 --- /dev/null +++ b/LanguagePlugins/SPython/SemanticAnalyzers/SPythonSyntaxTreeVisitor/spython_syntax_tree_visitor.cs @@ -0,0 +1,349 @@ +using System.Collections.Generic; +using PascalABCCompiler.SemanticTree; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.SystemLibrary; +using PascalABCCompiler.TreeConverter; +using PascalABCCompiler.TreeRealization; +using PascalABCCompiler.Errors; +using System.ComponentModel.Design; +using System; + +namespace SPythonSyntaxTreeVisitor +{ + // Возможно, стоит заменить на декоратор или стратегию вместо наследования EVA + public class spython_syntax_tree_visitor : syntax_tree_visitor + { + syntax_tree_visitor mainVisitor; + + public spython_syntax_tree_visitor(syntax_tree_visitor mainSyntaxTreeVisitor) : base(false) + { + + mainVisitor = mainSyntaxTreeVisitor; + convertion_data_and_alghoritms = mainSyntaxTreeVisitor.convertion_data_and_alghoritms; + ret = mainSyntaxTreeVisitor.ret; + context = mainSyntaxTreeVisitor.context; + contextChanger = mainSyntaxTreeVisitor.contextChanger; + + OnLeave = RunAdditionalChecks; + } + + private void RunAdditionalChecks(syntax_tree_node node) + { + switch (node) + { + case bin_expr _bin_expr: + expression_node left = convert_strong(_bin_expr.left); + expression_node right = convert_strong(_bin_expr.right); + if (_bin_expr.operation_type == Operators.Plus) + { + if ((left.type.name == "string" && right.type.name == "integer") || (left.type.name == "integer" && right.type.name == "string")) + { + AddError(left.location, "SPYTHONSEMANTIC_NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}", '+', left.type, right.type); ; + //base.AddError(left.location, "SPYTHONSEMANTIC_NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}", Operators.Plus, left.type, right.type); ; + return; + } + } + break; + } + return; + } + + protected override void get_system_module(common_unit_node psystem_unit) + { + init_system_module(psystem_unit); + + //esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat + if (debugging) + { + List si = SystemLibInitializer.CreateDiapason.SymbolInfo; + si = SystemLibInitializer.CreateObjDiapason.SymbolInfo; + si = SystemLibInitializer.TypedSetType.SymbolInfo; + } + + // SystemUnitAssigned = true; - убрали для SPython + CreateSpecialFields(psystem_unit); + } + + // Инициализируем только переменные экземпляра, не влияем на глобальное состояние в отличие от визитора Паскаля EVA + protected override void internal_reset() + { + _system_unit = mainVisitor._system_unit; + SystemLibrary.system_unit = _system_unit; + ResetSelfFields(); + } + + public override void AddError(location loc, string ErrResourceString, params object[] values) + { + Error err = new SPythonSemanticError(loc, ErrResourceString, values); + if (ErrResourceString == "FORWARD_DECLARATION_{0}_AS_BASE_TYPE") + { + throw err; + } + else + { + base.AddError(err); + } + } + + private type_node ConvertTypeNameToSPythonTypeName(type_node tn) + { + string new_name = tn.PrintableName; + new_name = new_name + .Replace(",", ", ") + .Replace("<", "[") + .Replace(">", "]") + .Replace("Tuple", "tuple") + .Replace("List", "list") + .Replace("NewSet", "set") + .Replace("Dictionary", "dict") + .Replace("empty_list", "list[anytype]") + .Replace("empty_set", "set[anytype]") + .Replace("empty_dict", "dict[anytype]") + .Replace("integer", "int") + .Replace("string", "str") + .Replace("real", "float") + .Replace("boolean", "bool") + .Replace("System.Numerics.BigInteger", "bigint") + ; + return new common_type_node(new_name, type_access_level.tal_public, null, null, tn.location); + } + + public override void AddError(Error err, bool shouldReturn = false) + { + // TODO : Add Error Rerouting according to SPython semantics + switch (err) + { + case OperatorCanNotBeAppliedToThisTypes _op_err: + if (_op_err.operator_name == "mod") + base.AddError(new OperatorCanNotBeAppliedToThisTypes("%", _op_err.left, _op_err.right, _op_err.loc), shouldReturn); + else if (_op_err.operator_name == "div") + base.AddError(new OperatorCanNotBeAppliedToThisTypes("//", _op_err.left, _op_err.right, _op_err.loc), shouldReturn); + return; + case FunctionExpectedProcedureMeet _proc_meet: + base.AddError(new SPythonSemanticError(_proc_meet.loc, "SPYTHONSEMANTIC_FUNCTION_{0}_NO_RETURN", _proc_meet.function.name)); + return; + case CanNotConvertTypes conv_err: + base.AddError(new CanNotConvertTypes(conv_err.expression_node, + ConvertTypeNameToSPythonTypeName(conv_err.from), + ConvertTypeNameToSPythonTypeName(conv_err.to), + conv_err.loc)); + return; + } + base.AddError(err, shouldReturn); + + } + + private Dictionary> containersNamesMapping = new Dictionary> + { + {"List", + new Dictionary { + { "append", "Add" }, + { "clear", "Clear" }, + { "insert", "Insert" }, + { "remove", "Remove" }, + { "pop", "pop" }, + { "index", "IndexOf" }, + { "count", "!count" }, + { "sort", "Sort" }, + { "reverse", "Reverse" }, + { "copy", "ToList" }, + { "Select", "Select" }, + { "Where", "Where" }, + } }, + + {"NewSet", + new Dictionary { + { "add", "add" }, + { "remove", "remove" }, + { "copy", "copy" }, + { "Select", "Select" }, + { "Where", "Where" }, + } }, + + {"Dictionary", + new Dictionary { + { "keys", "get_keys" }, + { "values", "get_values" }, + { "copy", "copy" }, + { "Select", "Select" }, + { "Where", "Where" }, + } } + }; + + + HashSet visited_method_calls = new HashSet(); + + public override void visit(method_call _method_call) + { + if (visited_method_calls.Contains(_method_call)) + { + base.visit(_method_call); + return; + } + visited_method_calls.Add(_method_call); + if (_method_call.dereferencing_value is dot_node dn && dn.right is ident id) + { + try + { + expression_node left = convert_strong(dn.left); + //dn.left = new semantic_addr_value(left); + if (left?.type != null) + foreach (string tName in containersNamesMapping.Keys) + { + if (left.type.name.StartsWith(tName)) + { + if (!containersNamesMapping[tName].ContainsKey(id.name)) + { + AddError(left.location, "SPYTHONSEMANTIC_TYPE_{0}_HAS_NO_{1}_METHOD", ConvertTypeNameToSPythonTypeName(left.type), id.name); + } + else + { + id.name = containersNamesMapping[tName][id.name]; + } + } + } + } + catch (ExpectedAnotherKindOfObject e) + { + } + } + base.visit(_method_call); + } + + public override void visit(assign _assign) + { + + if (_assign.from is bin_expr be && + _assign.to is ident il && + be.left is ident ir && + il.name == ir.name) + { + expression_node to = convert_strong(_assign.to); + SourceContext sc = _assign.source_context; + + if (to.type.name.StartsWith("NewSet")) + { + if (be.operation_type == Operators.LogicalAND) + { + var replace = new assign(new semantic_addr_value(to), be.right, Operators.AssignmentMultiplication, sc); + base.visit(replace); + return; + } + if (be.operation_type == Operators.LogicalOR) + { + var replace = new assign(new semantic_addr_value(to), be.right, Operators.AssignmentAddition, sc); + base.visit(replace); + return; + } + } + } + base.visit(_assign); + } + + public override void visit(bin_expr _bin_expr) + { + expression_node left = convert_strong(_bin_expr.left); + expression_node right = convert_strong(_bin_expr.right); + + var new_bin_expr = new bin_expr(new semantic_addr_value(left), new semantic_addr_value(right), _bin_expr.operation_type, _bin_expr.source_context); + + RunAdditionalChecks(new_bin_expr); + + switch (_bin_expr.operation_type) + { + case Operators.LogicalOR: + if (left.type.name.StartsWith("NewSet") && left.type.name == right.type.name) + { + new_bin_expr.operation_type = Operators.Plus; + } + break; + case Operators.LogicalAND: + if (left.type.name.StartsWith("NewSet") && left.type.name == right.type.name) + { + new_bin_expr.operation_type = Operators.Multiplication; + } + break; + /*case Operators.Plus: + if (left.type == right.type && left.type.name == "boolean") + { + var int_left = new method_call(new ident("int"), new expression_list(new semantic_addr_value(left, left.location)), left.location); + var int_right = new method_call(new ident("int"), new expression_list(new semantic_addr_value(right, right.location)), right.location); + var bti_bin_expr = new bin_expr(int_left, int_right, _bin_expr.operation_type, _bin_expr.source_context); + visit(bti_bin_expr); + return; + } + break;*/ + case Operators.Division: + if (left.type == right.type && left.type.name == "string") + { + var mcn = new method_call(new dot_node(new semantic_addr_value(left, left.location), new ident("IndexOf")), + new expression_list(new semantic_addr_value(right, right.location)), _bin_expr.source_context); + visit(mcn); + return; + } + break; + case Operators.IntegerDivision: + if (left.type == right.type && left.type.name == "real") + { + var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context; + exprlist.Add(new semantic_addr_value(left, left.location)); + exprlist.Add(new semantic_addr_value(right, right.location)); + var floornode = new method_call(new ident("!FloorDiv"), exprlist, _bin_expr.source_context); + visit(floornode); + return; + } + break; + case Operators.ModulusRemainder: + if (left.type == right.type && left.type.name == "real") + { + //var divnode = new bin_expr(new semantic_addr_value(left, left.location), new semantic_addr_value(right, right.location), Operators.IntegerDivision, _bin_expr.source_context); + //var multnode = new bin_expr(new semantic_addr_value(right, right.location), divnode, Operators.Multiplication); + //var modnode = new bin_expr(new semantic_addr_value(left, left.location), multnode, Operators.Minus); + var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context; + exprlist.Add(new semantic_addr_value(left, left.location)); + exprlist.Add(new semantic_addr_value(right, right.location)); + var modnode = new method_call(new ident("!FloorMod"), exprlist, _bin_expr.source_context); + visit(modnode); + return; + } + break; + } + base.visit(new_bin_expr); + } + + // Реализация глобальных переменных для семантики. Возможно, пригодится позже EVA + /*public override void visit(var_def_statement _var_def_statement) + { + if (_var_def_statement.vars_type != null) + { + var loc = get_location(_var_def_statement.vars_type); + type_node tn = find_type(_var_def_statement.vars_type as named_type_reference, loc); + _var_def_statement.vars_type = new semantic_type_node(tn); + } + base.visit(_var_def_statement); + } + + public override void visit(ident _ident) + { + var si = context.find_first(_ident.name)?.sym_info as var_definition_node; + if (si != null && si.type.name == "@UnknownType") + { + var loc = get_location(_ident); + AddError(loc, "SPYTHONSEMANTIC_USING_VARIABLE_BEFORE_ASSIGNMENT"); + } + base.visit(_ident); + }*/ + + /*public override void visit(named_type_reference _named_type_reference) + { + var loc = get_location(_named_type_reference); + type_node tn = find_type(_named_type_reference, loc); + if (tn.name == "UnknownType") + { + base.AddError(loc, "USING_VARIABLE_BEFORE_ASSIGNMENT"); + } + var _new_ntr = new semantic_addr_value(tn); + base.visit(_named_type_reference); + }*/ + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AddForwardDeclarationsVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AddForwardDeclarationsVisitor.cs new file mode 100644 index 000000000..1422c07bf --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AddForwardDeclarationsVisitor.cs @@ -0,0 +1,36 @@ +using PascalABCCompiler.SyntaxTree; + +namespace Languages.SPython.Frontend.Converters +{ + internal class AddForwardDeclarationsVisitor : BaseChangeVisitor + { + private declarations decls; + + public override void Enter(syntax_tree_node stn) + { + if (stn is program_module pm) + { + decls = pm.program_block.defs; + } + if (stn is interface_node intn) + { + decls = intn.interface_definitions; + } + + base.Enter(stn); + } + + public override void visit(procedure_header _procedure_header) + { + SourceContext context = _procedure_header.source_context; + var pd = new procedure_definition(_procedure_header.TypedClone(), null, context); + pd.proc_header.proc_attributes.Add(new procedure_attribute(proc_attribute.attr_forward, context)); + decls.Add(pd, context); + } + + public override void visit(function_header _function_header) + { + visit(_function_header as procedure_header); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AssignmentCharAsStringVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AssignmentCharAsStringVisitor.cs new file mode 100644 index 000000000..65d35eea8 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/AssignmentCharAsStringVisitor.cs @@ -0,0 +1,22 @@ +using PascalABCCompiler.SyntaxTree; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Languages.SPython.Frontend.Converters +{ + internal class AssignmentCharAsStringVisitor : BaseChangeVisitor + { + public AssignmentCharAsStringVisitor() { } + + public override void visit(assign _assign) + { + if (_assign.from is string_const sc + && sc.Value.Length == 1) + { + _assign.from = new method_call(new ident("str"), new expression_list(sc, sc.source_context), sc.source_context); + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/BitwiseAssignmentDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/BitwiseAssignmentDesugarVisitor.cs new file mode 100644 index 000000000..2fc44dcc1 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/BitwiseAssignmentDesugarVisitor.cs @@ -0,0 +1,46 @@ +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.SyntaxTreeConverters; +using System; + +namespace Languages.SPython.Frontend.Converters +{ + internal class BitwiseAssignmentDesugarVisitor : BaseChangeVisitor + { + public BitwiseAssignmentDesugarVisitor() { } + + public override void visit(assign _assign) + { + Operators bin_op_type; + + switch (_assign.operator_type) + { + case Operators.AssignmentBitwiseAND: { + bin_op_type = Operators.LogicalAND; + break; } + case Operators.AssignmentBitwiseOR: { + bin_op_type = Operators.LogicalOR; + break; } + case Operators.AssignmentBitwiseXOR: { + bin_op_type = Operators.BitwiseXOR; + break; } + case Operators.AssignmentBitwiseLeftShift: { + bin_op_type = Operators.BitwiseLeftShift; + break; } + case Operators.AssignmentBitwiseRightShift: { + bin_op_type = Operators.BitwiseRightShift; + break; } + case Operators.AssignmentIntDivision: { + bin_op_type = Operators.IntegerDivision; + break; + } + default: { + return; } + } + + SourceContext sc = _assign.source_context; + bin_expr from = new bin_expr(_assign.to.TypedClone(), _assign.from, bin_op_type, sc); + assign new_assign = new assign(_assign.to, from, sc); + Replace(_assign, new_assign); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/CompoundComparisonDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/CompoundComparisonDesugarVisitor.cs new file mode 100644 index 000000000..034efaaf7 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/CompoundComparisonDesugarVisitor.cs @@ -0,0 +1,101 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class CompoundComparisonDesugarVisitor : BaseChangeVisitor + { + private int curr_sl_index; + + public CompoundComparisonDesugarVisitor() { } + + public override void visit(statement_list sl) + { + if (sl == null) return; + for (var i = sl.subnodes_count - 1; i >= 0; i--) + { + curr_sl_index = i; + ProcessNode(sl[i]); + } + } + + private static statement_list GetCurrentStatementList(syntax_tree_node curr) + { + while (!(curr is statement_list)) curr = curr.Parent; + return curr as statement_list; + } + + private static bool IsComparison(bin_expr _bin_expr) + { + Operators Operator = _bin_expr.operation_type; + switch (Operator) + { + case Operators.Less: + case Operators.Greater: + case Operators.LessEqual: + case Operators.GreaterEqual: + case Operators.Equal: + case Operators.NotEqual: + return true; + } + return false; + } + + private static bool IsCompoundComparison(bin_expr _bin_expr) + { + return (_bin_expr.left is bin_expr left) && IsComparison(_bin_expr) && IsComparison(left); + } + + private int createdIdentsCounter = 0; + + private string NewIdentName() + { + string result = '%' + createdIdentsCounter.ToString(); + createdIdentsCounter++; + return result; + } + + public override void visit(bin_expr _bin_expr) + { + if (IsCompoundComparison(_bin_expr)) + { + // transform + // + // ((left comp1 middle) comp2 right) + // + // to + // + // var id: typeof(middle); + // ((left comp1 !assign(id, middle)) && (id comp2 right)) + // + // then recursive call for left + // P.S. !assign(a, b) assigns b to a and return a + + bin_expr left_comp_middle = _bin_expr.left as bin_expr; + expression left = left_comp_middle.left; + Operators comp1 = left_comp_middle.operation_type; + expression middle = left_comp_middle.right; + Operators comp2 = _bin_expr.operation_type; + expression right = _bin_expr.right; + ident id = new ident(NewIdentName(), middle.source_context); + type_definition td = new same_type_node(middle.TypedClone(), middle.source_context); + var_def_statement vds = new var_def_statement(id, td, middle.source_context); + statement_list curr_statement_list = GetCurrentStatementList(_bin_expr); + int index = curr_sl_index - curr_statement_list.subnodes_without_list_elements_count; + curr_statement_list.list.Insert(index, new var_statement(vds, middle.source_context)); + curr_sl_index++; + + addressed_value method_name = new ident("!assign", middle.source_context); + expression_list el = new expression_list(new List { id, middle }, middle.source_context); + method_call method_call = new method_call(method_name, el, middle.source_context); + bin_expr new_left = new bin_expr(left, method_call, comp1, new SourceContext(left.source_context, method_call.source_context)); + bin_expr new_right = new bin_expr(id, right, comp2, new SourceContext(id.source_context, right.source_context)); + bin_expr new_bin_expr = new bin_expr(new_left, new_right, Operators.LogicalAND, _bin_expr.source_context); + _bin_expr.Parent.ReplaceDescendant(_bin_expr, new_bin_expr); + new_bin_expr.left.visit(this); + } + else + base.visit(_bin_expr); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/EraseSpythonOnlyNodesVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/EraseSpythonOnlyNodesVisitor.cs new file mode 100644 index 000000000..94ff2d150 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/EraseSpythonOnlyNodesVisitor.cs @@ -0,0 +1,45 @@ +using PascalABCCompiler.SyntaxTree; +using System; + +namespace Languages.SPython.Frontend.Converters +{ + public class EraseSpythonOnlyNodesVisitor : BaseChangeVisitor + { + public EraseSpythonOnlyNodesVisitor() {} + + public override void visit(global_statement _global_statement) + { + DeleteInStatementList(_global_statement); + } + + public override void visit(import_statement _import_statement) + { + var upper = UpperNode(); + if (upper is interface_node _interface_node) + _interface_node.interface_definitions.ReplaceDescendant( + _import_statement, new empty_statement()); + else Replace(_import_statement, new empty_statement()); + } + + public override void visit(from_import_statement _from_import_statement) + { + var upper = UpperNode(); + if (upper is interface_node _interface_node) + _interface_node.interface_definitions.ReplaceDescendant( + _from_import_statement, new empty_statement()); + else Replace(_from_import_statement, new empty_statement()); + } + + public override void visit(tuple_node tup) + { + var dn = new ident("CreateTuple", tup.source_context); + var mc = new method_call(dn, tup.el, tup.source_context); + + //var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса! + + //ReplaceUsingParent(tup, mc); - исправление #1199. Оказывается, ReplaceUsingParent и Replace не эквивалентны - у копии Parent на старого родителя + Replace(tup, mc); + visit(mc); + } + } +} \ No newline at end of file diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FindFunctionsNamesVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FindFunctionsNamesVisitor.cs new file mode 100644 index 000000000..fee49c693 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FindFunctionsNamesVisitor.cs @@ -0,0 +1,15 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class FindFunctionsNamesVisitor : BaseChangeVisitor + { + public HashSet definedFunctionsNames = new HashSet(); + + public override void visit(procedure_definition pd) + { + definedFunctionsNames.Add(pd.proc_header.name.meth_name.name); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FunctionsWithNamedParametersDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FunctionsWithNamedParametersDesugarVisitor.cs new file mode 100644 index 000000000..6ecae5c23 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/FunctionsWithNamedParametersDesugarVisitor.cs @@ -0,0 +1,64 @@ +using PascalABCCompiler.SyntaxTree; +using System; +using System.Linq; + +namespace Languages.SPython.Frontend.Converters +{ + internal class FunctionsWithNamedParametersDesugarVisitor : BaseChangeVisitor + { + public FunctionsWithNamedParametersDesugarVisitor() { } + + public override void visit(method_call _method_call) + { + if (_method_call.parameters is expression_list exprl) { + expression_list args = new expression_list(); + expression_list kwargs_names_array = new expression_list(); + expression_list kwargs = new expression_list(); + + foreach (var expr in exprl.expressions) + { + if (expr is name_assign_expr nae) + { + kwargs_names_array.Add(new string_const(nae.name.name)); + kwargs_names_array.source_context + = new SourceContext(kwargs_names_array.source_context, expr.source_context); + kwargs.Add(nae.expr); + kwargs.source_context + = new SourceContext(kwargs.source_context, expr.source_context); + } + else if (kwargs.expressions.Count() == 0) + { + args.Add(expr); + args.source_context = new SourceContext(args.source_context, expr.source_context); + } + else throw new SPythonSyntaxVisitorError("ARG_AFTER_KWARGS", expr.source_context); + } + + if (kwargs.expressions.Count() != 0) + { + array_const_new acn = new array_const_new(kwargs_names_array, '|'); + kwargs.expressions.Insert(0, acn); + + ident method_name = new ident(); + if (_method_call.dereferencing_value is ident id) + { + method_name = id; + } + else if (_method_call.dereferencing_value is dot_node dnn) + { + method_name = dnn.right as ident; + } + + ident class_name = new ident("!" + method_name); + new_expr ne = new new_expr(new named_type_reference(class_name), kwargs, false, null); + + dot_node dn = new dot_node(ne, new ident(method_name.name), _method_call.source_context); + method_call new_method_call = new method_call(dn, args, _method_call.source_context); + Replace(_method_call, new_method_call); + return; + } + } + base.visit(_method_call); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/GeneratorObjectDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/GeneratorObjectDesugarVisitor.cs new file mode 100644 index 000000000..6a75f94ec --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/GeneratorObjectDesugarVisitor.cs @@ -0,0 +1,104 @@ +using PascalABCCompiler; +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class GeneratorObjectDesugarVisitor : BaseChangeVisitor + { + private ParserLambdaHelper lambdaHelper = new ParserLambdaHelper(); + private syntax_tree_node root; + private bool replaceRoot = false; + private syntax_tree_node lastDesugaredNode = null; + + public GeneratorObjectDesugarVisitor(syntax_tree_node root) + { + this.root = root; + } + + public syntax_tree_node UpdatedRoot() + { + if (replaceRoot) return lastDesugaredNode; + return root; + } + + public override void visit(generator_object _generator_object) + { + base.visit(_generator_object); + + dot_node dn; + ident_list idList; + formal_parameters formalPars; + statement_list sl; + function_lambda_definition lambda; + method_call mc; + + // [ expr1 for ident in expr2 if expr3 ] -> expr2.Where(ident -> expr3).Select(ident -> expr1) + if (_generator_object._condition != null) + { + string ident_name = _generator_object._ident.name; + idList = new ident_list(new ident(ident_name), _generator_object._ident.source_context); + formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context); + + dn = new dot_node(_generator_object._range as addressed_value, (new ident("Where")) as addressed_value, _generator_object.source_context); + + sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._condition, _generator_object._condition.source_context), _generator_object._condition.source_context); //! + sl.expr_lambda_body = true; + lambda = new function_lambda_definition( + lambdaHelper.CreateLambdaName(), formalPars, + new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context); + + mc = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context); + dn = new dot_node(mc as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context); + } + // [ expr1 for ident in expr2 ] -> expr2.Select(ident -> expr1) + else + dn = new dot_node(_generator_object._range as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context); + + + idList = new ident_list(_generator_object._ident, _generator_object._ident.source_context); + formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context); + + sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._expr, _generator_object._expr.source_context), _generator_object._expr.source_context); + sl.expr_lambda_body = true; + + lambda = new function_lambda_definition( + lambdaHelper.CreateLambdaName(), formalPars, + new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context); + + + method_call replaceTo = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context); + + if (root != _generator_object) + Replace(_generator_object, replaceTo); + else + { + replaceRoot = true; + lastDesugaredNode = replaceTo; + } + } + } + + public class ParserLambdaHelper + { + private int lambda_num = 0; + public List lambdaDefinitions; + public static string lambdaPrefix = "<>lambda"; + + public ParserLambdaHelper() + { + lambdaDefinitions = new List(); + } + + public string CreateLambdaName() + { + lambda_num++; + return lambdaPrefix + lambda_num.ToString(); + } + + public bool IsLambdaName(ident id) + { + return id.name.StartsWith(lambdaPrefix); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ImportToUsesVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ImportToUsesVisitor.cs new file mode 100644 index 000000000..3e937dc32 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ImportToUsesVisitor.cs @@ -0,0 +1,63 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class ImportToUsesVisitor : BaseChangeVisitor + { + Dictionary modulesNames = new Dictionary(); + + public ImportToUsesVisitor() { } + + private Dictionary specialModulesAliases = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation.SpecialModulesAliases; + + private string GetNameToImport(string nameToImport) + { + if (!specialModulesAliases.ContainsKey(nameToImport)) + return nameToImport; + else + return specialModulesAliases[nameToImport]; + } + + private void AddName(ident id) + { + string nameToImport = GetNameToImport(id.name); + if (!modulesNames.ContainsKey(nameToImport)) + modulesNames.Add(nameToImport, id.source_context); + } + + public override void visit(import_statement _import_statement) + { + foreach (as_statement as_Statement in _import_statement.modules_names.as_statements) + AddName(as_Statement.real_name); + } + + public override void visit(from_import_statement _from_import_statement) + { + AddName(_from_import_statement.module_name); + } + + public void AddUsesToUsesList(uses_list _uses_list) + { + foreach (string module_name in modulesNames.Keys) + { + SourceContext sc = modulesNames[module_name]; + uses_list us = new uses_list(new unit_or_namespace(module_name, sc), sc); + us[0].source_context = sc; + _uses_list.AddUsesList(us, sc); + } + } + + public override void Exit(syntax_tree_node stn) + { + if (stn is program_module pm) + { + AddUsesToUsesList(pm.used_units); + } + if (stn is unit_module um) + { + AddUsesToUsesList(um.interface_part.uses_modules); + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/KwargsFunctionDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/KwargsFunctionDesugarVisitor.cs new file mode 100644 index 000000000..9290783e4 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/KwargsFunctionDesugarVisitor.cs @@ -0,0 +1,205 @@ +using PascalABCCompiler; +using PascalABCCompiler.SyntaxTree; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Languages.SPython.Frontend.Converters +{ + internal class KwargsFunctionDesugarVisitor: BaseChangeVisitor + { + public KwargsFunctionDesugarVisitor() { } + + private declarations decls; + private declarations current_decls; + + public override void Enter(syntax_tree_node stn) + { + if (stn is program_module pm) + { + decls = pm.program_block.defs; + } + if (stn is interface_node intn) + { + decls = intn.interface_definitions; + } + if (stn is declarations_as_statement das) + { + current_decls = das.defs; + } + + base.Enter(stn); + } + + private typed_parameters LastParameter(procedure_definition pd) + { + return pd.proc_header.parameters.Last(); + } + + private bool HasParameters(procedure_definition pd) + { + return pd.proc_header.parameters != null; + } + + private bool IsKwargsParameter(typed_parameters tp) + { + return tp.param_kind == parametr_kind.kwargs_parameter; + } + + private bool HasKwargsParameter(procedure_definition pd) + { + if (!HasParameters(pd)) + return false; + + foreach (typed_parameters param in pd.proc_header.parameters.params_list) + { + if (IsKwargsParameter(param)) + return true; + } + + return false; + } + + string renameFrom = ""; + + private void RenameKwargParametor(procedure_definition pd) + { + renameFrom = LastParameter(pd).idents.idents[0].name; + var body = pd.proc_body; + base.visit(pd); + renameFrom = ""; + } + + public override void visit(ident id) + { + // сомнительно, лучше сделать другим визитором + if (renameFrom != "" && id.name == renameFrom) + { + id.name = "!kwargs"; + } + } + + private void AddNoKwargsVersion(procedure_definition pd) + { + procedure_definition noKwargsVersion = pd.TypedClone(); + typed_parameters kwargs_parameter = LastParameter(noKwargsVersion); + noKwargsVersion.proc_header.parameters.Remove(kwargs_parameter); + ident name = noKwargsVersion.proc_header.name.meth_name; + ident class_name = "!" + name; + + if (IsForwardDeclaration(noKwargsVersion.proc_header)) + { + decls.Add(noKwargsVersion); + } + else + { + List tp_list = noKwargsVersion.proc_header.parameters.params_list; + expression_list args = new expression_list(); + foreach (typed_parameters tp in tp_list) + { + foreach (ident id in tp.idents.list) + { + args.Add(id); + } + } + + new_expr ne = new new_expr(new named_type_reference(class_name), null, false, null); + + dot_node dn = new dot_node(ne, new ident(name.name)); + method_call method_call = new method_call(dn, args); + + statement stmt; + + if (pd.proc_header is function_header) + { + stmt = new assign(new ident(StringConstants.result_var_name), method_call, Operators.Assignment); + } + else + { + stmt = new procedure_call(method_call, false); + } + + statement_list stmtlist = new statement_list(stmt); + + declarations empty_declarations = new declarations(); + block block = new block(empty_declarations, stmtlist); + noKwargsVersion.proc_body = block; + current_decls.Add(noKwargsVersion); + } + } + + void CheckIfKwargParametorIsUsedCorrectly(procedure_definition pd) + { + var params_list = pd.proc_header.parameters.params_list; + for (int i = 0; i < params_list.Count() - 1; ++i) + { + if (IsKwargsParameter(params_list[i])) + { + throw new SPythonSyntaxVisitorError("KWARG_PARAMETOR_NOT_LAST", + params_list[i].source_context); + } + } + } + + public override void visit(procedure_definition pd) + { + if (!HasKwargsParameter(pd)) + return; + + // Проверяем что kwarg-параметр только последний + CheckIfKwargParametorIsUsedCorrectly(pd); + + RenameKwargParametor(pd); + + declaration d = CreateTypeDefinitionForKwargsFunction(pd); + AddNoKwargsVersion(pd); + Replace(pd, d); + } + + private bool IsForwardDeclaration(procedure_header _procedure_header) + { + foreach (procedure_attribute attr in _procedure_header.proc_attributes.proc_attributes) + if (attr.attribute_type is proc_attribute.attr_forward) + return true; + + return false; + } + + private declaration CreateTypeDefinitionForKwargsFunction(procedure_definition pd) + { + procedure_definition new_pd = pd.TypedClone(); + typed_parameters kwargs_parameter = LastParameter(new_pd); + new_pd.proc_header.parameters.Remove(kwargs_parameter); + ident name = new_pd.proc_header.name.meth_name; + ident class_name = "!" + name; + + if (IsForwardDeclaration(new_pd.proc_header)) + { + // base class type + template_param_list tpl = new template_param_list(kwargs_parameter.vars_type, kwargs_parameter.source_context); + ident base_class_name = new ident("kwargs_gen`1"); + named_type_reference ntr = new named_type_reference(base_class_name); + template_type_reference ttr = new template_type_reference(ntr, tpl); + named_type_reference_list ntrl = new named_type_reference_list(ttr); + + // class body + access_modifer_node amn = new access_modifer_node(access_modifer.public_modifer); + new_pd.proc_header.name.meth_name = new_pd.proc_header.name.meth_name; + class_members cm = new class_members(new_pd.proc_header); + class_body_list cbl = new class_body_list(cm); + + // type class declaration + class_definition cd = new class_definition(ntrl, cbl); + type_declaration td = new type_declaration(class_name, cd); + type_declarations result = new type_declarations(td); + + return result; + } + else + { + new_pd.proc_header.name = new method_name(null, class_name, name, null); + return new_pd; + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/MapDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/MapDesugarVisitor.cs new file mode 100644 index 000000000..bd6d53bb4 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/MapDesugarVisitor.cs @@ -0,0 +1,26 @@ +using PascalABCCompiler.SyntaxTree; + +namespace Languages.SPython.Frontend.Converters +{ + internal class MapDesugarVisitor : BaseChangeVisitor + { + public MapDesugarVisitor() { } + + public override void visit(method_call mc) + { + base.visit(mc); + + if (mc.dereferencing_value is ident map && map.name == "map" && + mc.parameters.Count == 2 && mc.parameters[0] is addressed_value av && + mc.parameters[1] is expression range) + { + ident ident = new ident("!map_iterable_element", mc.source_context); + expression expr = new method_call(av, new expression_list(ident), mc.source_context); + + generator_object go = new generator_object(expr, ident, range, null, mc.source_context); + + Replace(mc, go); + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/NameCorrectVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/NameCorrectVisitor.cs new file mode 100644 index 000000000..80e2301ab --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/NameCorrectVisitor.cs @@ -0,0 +1,205 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class NameCorrectVisitor : SymbolTableFillingVisitor + { + public HashSet variablesUsedAsGlobal = new HashSet(); + + public NameCorrectVisitor(Dictionary> namesFromUsedUnits, HashSet definedFunctionsNames) : base(namesFromUsedUnits) + { + foreach (string definedFunctionName in definedFunctionsNames) + { + symbolTable.Add(definedFunctionName, NameKind.ForwardDeclaredFunction); + } + } + + public override void Enter(syntax_tree_node stn) + { + if (stn is ident && stn.Parent is dot_node dn && dn.right == stn) + { + visitNode = false; + } + + base.Enter(stn); + } + + public override void visit(var_statement _var_statement) + { + if (symbolTable.IsOutermostScope()) + { + // не работает для нескольких переменных (var a1, a2, ...: type;) + ident id = _var_statement.var_def.vars.idents[0]; + symbolTable.Add(id.name, NameKind.GlobalVariable); + ProcessNode(_var_statement.var_def); + } + else base.visit(_var_statement); + } + + public override void visit(name_assign_expr _name_assign_expr) + { + ProcessNode(_name_assign_expr[1]); + } + + public override void visit(unit_or_namespace _unit_or_namespace) + { + + } + + public override void visit(unit_name _unit_name) + { + + } + + public override void visit(global_statement _global_statement) + { + foreach (ident _ident in _global_statement.idents.idents) + { + NameKind nameType = symbolTable[_ident.name]; + switch (nameType) + { + case NameKind.GlobalVariable: + case NameKind.ImportedNameAlias: + break; + case NameKind.Unknown: + throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}", + _ident.source_context, _ident.name); + default: + throw new SPythonSyntaxVisitorError("SCOPE_CONTAINS_NAME_{0}", + _ident.source_context, _ident.name); + } + } + + base.visit(_global_statement); + } + + public override void visit(named_type_reference _named_type_reference) + { + ident id = _named_type_reference.names[0]; + string name = id.name; + + if (name == "int" || name == "str" || name == "bool" || name == "float" || name == "set" || name == "list" || name == "dict") + { + return; + } + + NameKind nameKind = symbolTable[name]; + switch (nameKind) + { + case NameKind.ModuleAlias: + id.name = symbolTable.AliasToRealName(id.name); + break; + + case NameKind.ImportedNameAlias: + _named_type_reference.names.Insert(0, new ident(symbolTable.AliasToModuleName(id.name), id.source_context)); + _named_type_reference.names[1].name = symbolTable.AliasToRealName(_named_type_reference.names[1].name); + break; + + case NameKind.Unknown: + throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}", + id.source_context, id.name); + } + } + + public override void visit(ident _ident) + { + SourceContext sc = _ident.source_context; + NameKind nameKind = symbolTable[_ident.name]; + switch (nameKind) + { + case NameKind.ModuleAlias: + _ident.name = symbolTable.AliasToRealName(_ident.name); + break; + + case NameKind.ImportedNameAlias: + Replace(_ident, new dot_node(new ident(symbolTable.AliasToModuleName(_ident.name), sc) + , new ident(symbolTable.AliasToRealName(_ident.name), sc), sc)); + break; + + case NameKind.GlobalVariable: + if (symbolTable.IsInFunctionBody && + !variablesUsedAsGlobal.Contains(_ident.name)) + variablesUsedAsGlobal.Add(_ident.name); + break; + + case NameKind.ForwardDeclaredFunction: + if (!symbolTable.IsInFunctionBody) + throw new SPythonSyntaxVisitorError("FUNCTION_{0}_USED_BEFORE_DECLARATION", + sc, _ident.name); + break; + + case NameKind.Unknown: + throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}", + sc, _ident.name); + } + } + + // кидает ошибки если инициализировать пустой коллекцией + // не указывая типа переменной + private void CheckInitializationWithEmptyCollection(assign _assign) + { + // a = [] + // a = !empty_list() + // a = {} + // a = !empty_dict() + // a = set() + if (_assign.from is method_call mc && + mc.dereferencing_value is ident id && + mc.parameters == null) + { + if (id.name == "!empty_list") + { + throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_LIST_TYPE", + _assign.from.source_context); + } + else if (id.name == "!empty_dict") + { + throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_DICT_TYPE", + _assign.from.source_context); + } + if (id.name == "set") + { + throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_SET_TYPE", + _assign.from.source_context); + } + } + } + + //public override void visit(assign_tuple _assign_tuple) + //{ + // + //} + + public override void visit(assign _assign) + { + if (_assign.operator_type == Operators.Assignment && _assign.to is ident _ident) + { + if (!symbolTable.IsVisibleToAssign(_ident.name)) + { + // инициализация новой переменной с присвоением + if (symbolTable.IsOutermostScope()) + symbolTable.Add(_ident.name, NameKind.GlobalVariable); + else + symbolTable.Add(_ident.name, NameKind.LocalVariable); + + CheckInitializationWithEmptyCollection(_assign); + + var _var_statement = SyntaxTreeBuilder.BuildVarStatementNodeFromAssignNode(_assign); + + ReplaceStatement(_assign, _var_statement); + + ProcessNode(_var_statement); + return; + } + else if (symbolTable.IsInFunctionBody + && symbolTable[_ident.name] == NameKind.GlobalVariable + && !variablesUsedAsGlobal.Contains(_ident.name)) + { + variablesUsedAsGlobal.Add(_ident.name); + } + } + base.visit(_assign); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/Properties/AssemblyInfo.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..10d19ed97 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные со сборкой. +[assembly: AssemblyTitle("SPythonStandardTreeConverter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SPythonStandardTreeConverter")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// COM, задайте атрибуту ComVisible значение TRUE для этого типа. +[assembly: ComVisible(false)] + +// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM +[assembly: Guid("431aa1a0-81b9-4d93-9cb1-219bdf7825c9")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Редакция +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/RetainUsedGlobalVariablesVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/RetainUsedGlobalVariablesVisitor.cs new file mode 100644 index 000000000..c19d7b772 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/RetainUsedGlobalVariablesVisitor.cs @@ -0,0 +1,78 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + public class RetainUsedGlobalVariablesVisitor : BaseChangeVisitor + { + private HashSet variablesUsedAsGlobal = new HashSet(); + private int scopeCounter = 0; + private declarations decls; + private bool isUnitCompiled = false; + + public RetainUsedGlobalVariablesVisitor(HashSet variablesUsedAsGlobal) + { + this.variablesUsedAsGlobal = variablesUsedAsGlobal; + } + + // нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew + public override void DefaultVisit(syntax_tree_node n) + { + for (var i = 0; i < n.subnodes_count; i++) + ProcessNode(n[i]); + } + + public override void Enter(syntax_tree_node stn) + { + if (stn is statement_list) + { + scopeCounter++; + } + if (stn is program_module pm) + { + decls = pm.program_block.defs; + } + if (stn is interface_node intn) + { + isUnitCompiled = true; + decls = intn.interface_definitions; + } + + base.Enter(stn); + } + + public override void Exit(syntax_tree_node stn) + { + if (stn is statement_list) + { + scopeCounter--; + } + base.Exit(stn); + } + + public override void visit(var_statement _var_statement) + { + ident id = _var_statement.var_def.vars.idents[0]; + if (scopeCounter == 1 && (isUnitCompiled || variablesUsedAsGlobal.Contains(id.name))) + { + //variablesUsedAsGlobal.Remove(id.name); + SourceContext sc = _var_statement.source_context; + statement replace_to = new empty_statement(); + type_definition td = _var_statement.var_def.vars_type; + if (_var_statement.var_def.inital_value != null) + { + replace_to = new assign(id, _var_statement.var_def.inital_value, sc); + } + if (td == null) + { + (replace_to as assign).first_assignment_defines_type = true; + td = new named_type_reference(new ident("integer")); + } + var vds = new var_def_statement(new ident_list(id, id.source_context), td, null, definition_attribute.None, false, sc); + decls.Add(new variable_definitions(vds, sc), sc); + + ReplaceStatement(_var_statement, replace_to); + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ReturnDesugarVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ReturnDesugarVisitor.cs new file mode 100644 index 000000000..cc3e2e379 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/ReturnDesugarVisitor.cs @@ -0,0 +1,31 @@ +using PascalABCCompiler; +using PascalABCCompiler.SyntaxTree; + +namespace Languages.SPython.Frontend.Converters +{ + internal class ReturnDesugarVisitor : BaseChangeVisitor + { + public ReturnDesugarVisitor() { } + + public override void visit(return_statement _return_statement) + { + SourceContext sc = _return_statement.source_context; + + // return; + if (_return_statement.expr == null) + { + procedure_call pc = new procedure_call(new ident("exit", sc), true, sc); + Replace(_return_statement, pc); + } + // return expr; + else + { + statement res_assign = new assign(new ident(StringConstants.result_var_name), _return_statement.expr, Operators.Assignment, sc); + statement exit_call = new procedure_call(new ident("exit"), true, sc); + statement_list new_statement = new statement_list(res_assign, sc); + new_statement.Add(exit_call, sc); + Replace(_return_statement, new_statement); + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SPythonStandardTreeConverter.csproj b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SPythonStandardTreeConverter.csproj new file mode 100644 index 000000000..4398efd85 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SPythonStandardTreeConverter.csproj @@ -0,0 +1,20 @@ + + + + net40 + + Languages.SPython.Frontend.Converters + + ..\..\..\..\bin\ + false + + false + + + + + + + + + \ No newline at end of file diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StandardSyntaxTreeConverter.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StandardSyntaxTreeConverter.cs new file mode 100644 index 000000000..ef70ffa06 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StandardSyntaxTreeConverter.cs @@ -0,0 +1,148 @@ +using Languages.Pascal.Frontend.Converters; +using PascalABCCompiler; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.SyntaxTreeConverters; +using SyntaxVisitors; +using SyntaxVisitors.SugarVisitors; +using System; + +namespace Languages.SPython.Frontend.Converters +{ + public class StandardSyntaxTreeConverter : BaseSyntaxTreeConverter + { + public override string Name { get; } = "Standard"; + + protected override syntax_tree_node ApplyConversions(syntax_tree_node root, bool forIntellisense) + { + // кидает ошибки за использование + // неподдерживаемых конструкций языка + if (!forIntellisense) + new UnsupportedConstructsVisitor().ProcessNode(root); + + // добавление всех import ..., from ... import ... + // как uses в начале программы для сбора имён из этих модулей + if (!forIntellisense) + new ImportToUsesVisitor().ProcessNode(root); + + // замена + // name bin_bit_op= expr + // на + // name = name bin_bit_op (expr) + new TryCatchDecorator(new BitwiseAssignmentDesugarVisitor(), forIntellisense).ProcessNode(root); + + // замена return; на { exit(); } + // замена return expr; на { result := expr; exit(); } + new TryCatchDecorator(new ReturnDesugarVisitor(), forIntellisense).ProcessNode(root); + + // замена вызова функции map(func, sequence) + // на func(element) for element in sequence + new TryCatchDecorator(new MapDesugarVisitor(), forIntellisense).ProcessNode(root); + + // замена генерации последовательностей на Select.Where + // (не работает из-за лямбд (скорее всего), если переместить в ConvertAfterUsedModulesCompilation) + new TryCatchDecorator(new GeneratorObjectDesugarVisitor(root), forIntellisense).ProcessNode(root); + + // Выносим выражения с лямбдами из заголовка foreach + считаем максимум 10 вложенных лямбд + // украл из паскаля + StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor.New.ProcessNode(root); + new VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer(root as compilation_unit).ProcessNode(root); + FindOnExceptVarsAndApplyRenameVisitor.New.ProcessNode(root); + + // дешугаризация составных сравнительных операций (e.g. a == b == c) + new TryCatchDecorator(new CompoundComparisonDesugarVisitor(), forIntellisense).ProcessNode(root); + + return root; + } + + public override syntax_tree_node ConvertAfterUsedModulesCompilation(syntax_tree_node root, bool forIntellisense, in CompilationArtifactsUsedBySyntaxConverters compilationArtifacts) + { + // украл из паскаля, нужны для работы 'for i1, i2 in expr' (работает с кортежными присваиваниями) + var binder = new BindCollectLightSymInfo(root as compilation_unit); + new TryCatchDecorator(binder, forIntellisense).ProcessNode(root); + new TryCatchDecorator(new NewAssignTuplesDesugarVisitor(binder), forIntellisense).ProcessNode(root); + + // Заменяет + // variable_name = single_length_string + // на + // variable_name = str(single_length_string) + // чтобы при выведении типа правильно вывел str, а не char + new AssignmentCharAsStringVisitor().ProcessNode(root); + + // Сохраняет множество имён функций, которые объявлены в программе для NameCorrectVisitor + var ffv = new FindFunctionsNamesVisitor(); + + new TryCatchDecorator(ffv, forIntellisense).ProcessNode(root); + + // проверка корректности имён, разрешение неоднозначности + // сохранение множества переменных, использующихся как глобальные в ncv.variablesUsedAsGlobal + var ncv = new NameCorrectVisitor(compilationArtifacts.NamesFromUsedUnits, ffv.definedFunctionsNames); + + if (!new TryCatchDecorator(ncv, forIntellisense).ProcessNode(root)) + return root; + + // замена типов из SPython на типы из PascalABC.NET + new TryCatchDecorator(new TypeCorrectVisitor(forIntellisense), forIntellisense).ProcessNode(root); + + // вынос forward объявлений для всех функций в начало + new TryCatchDecorator(new AddForwardDeclarationsVisitor(), forIntellisense).ProcessNode(root); + + // выполняет генерацию кода для функций с kwarg-аргументами + new TryCatchDecorator(new KwargsFunctionDesugarVisitor(), forIntellisense).ProcessNode(root); + + // замена вызова функций с kwarg-аргументами на вызов метода класса + new TryCatchDecorator(new FunctionsWithNamedParametersDesugarVisitor(), forIntellisense).ProcessNode(root); + + // выносит объявлений переменных из ncv.variablesUsedAsGlobal на глобальный уровень + // (в модулях все переменные, объявленные на глобальном уровне являются глобальными) + new TryCatchDecorator(new RetainUsedGlobalVariablesVisitor(ncv.variablesUsedAsGlobal), forIntellisense).ProcessNode(root); + + // удаление специфичных синтаксических узлов Spython'a перед конвертацией в семантическое дерево + if (!forIntellisense) + new EraseSpythonOnlyNodesVisitor().ProcessNode(root); + + // перестроение структуры дерева, для последующих этапов компиляции + // итоговое представление: + // 1) forward объявления функций + // 2) объявления глобальных переменных (без присваиваний) + // 3) объявление функции %%MAIN%%, содержащей компилируемую программу + // 4) объявления функций, объявленных в программе + // 5) begin %%MAIN%%() end. + new TryCatchDecorator(new TreeNodesRearrangementVisitor(), forIntellisense).ProcessNode(root); + + return root; + } + + private class TryCatchDecorator + { + private WalkingVisitorNew internalVisitor; + private bool forIntellisense; + + public TryCatchDecorator(WalkingVisitorNew internalVisitor, bool forIntellisense) + { + this.internalVisitor = internalVisitor; + this.forIntellisense = forIntellisense; + } + + public bool ProcessNode(syntax_tree_node root) + { + if (forIntellisense) + { + try + { + internalVisitor.ProcessNode(root); + } + catch (Exception) + { + return false; + } + } + else + { + internalVisitor.ProcessNode(root); + } + + return true; + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StringResources.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StringResources.cs new file mode 100644 index 000000000..fd601bdaa --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/StringResources.cs @@ -0,0 +1,35 @@ +using PascalABCCompiler.Errors; +using PascalABCCompiler.SyntaxTree; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Languages.SPython.Frontend.Converters +{ + public static class SPythonStringResources + { + public static string Get(string key) + { + return PascalABCCompiler.StringResources.Get("SPYTHONSYNTAXTREEVISITORSERROR_" + key); + } + + public static string Get(string key, params object[] values) + { + return (string.Format(Get(key), values)); + } + } + + public class SPythonSyntaxVisitorError : SyntaxError + { + public SPythonSyntaxVisitorError(string resourcestring, SourceContext sc, params object[] values) : base(SPythonStringResources.Get(resourcestring, values), "", sc, null) + { + + } + public SPythonSyntaxVisitorError(string resourcestring, PascalABCCompiler.SyntaxTree.syntax_tree_node bad_node) + : base(SPythonStringResources.Get(resourcestring), "", bad_node.source_context, bad_node) + { + + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SymbolTableFillingVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SymbolTableFillingVisitor.cs new file mode 100644 index 000000000..b94fe8304 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/SymbolTableFillingVisitor.cs @@ -0,0 +1,459 @@ +using System; +using System.Collections.Generic; +using PascalABCCompiler; +using PascalABCCompiler.SyntaxTree; + +namespace Languages.SPython.Frontend.Converters +{ + // заполняет таблицу символов динамически, при проходе по дереву сверху вниз + public class SymbolTableFillingVisitor : BaseChangeVisitor + { + protected SymbolTable symbolTable; + + public SymbolTableFillingVisitor(Dictionary> par) { + symbolTable = new SymbolTable(par); + } + + // нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew + public override void DefaultVisit(syntax_tree_node n) + { + if (n == null) return; + for (var i = 0; i < n.subnodes_count; i++) + ProcessNode(n[i]); + } + + public override void Enter(syntax_tree_node stn) + { + if (stn is statement_list) + { + symbolTable.OpenLocalScope(); + } + if (stn is procedure_definition || stn is function_lambda_definition) + { + symbolTable.OpenLocalScope(); + symbolTable.IsInFunctionBody = true; + } + + base.Enter(stn); + } + + public override void Exit(syntax_tree_node stn) + { + if (stn is procedure_definition || stn is function_lambda_definition) + { + symbolTable.IsInFunctionBody = false; + symbolTable.CloseLocalScope(); + } + if (stn is statement_list) + { + symbolTable.CloseLocalScope(); + } + + base.Exit(stn); + } + + public override void visit(semantic_check_sugared_statement_node _) + { + // Скипаем. Узел нужен на семантике, здесь порождает лишние ошибки. + } + + private bool IsForwardDeclaration(procedure_header _procedure_header) + { + foreach (procedure_attribute attr in _procedure_header.proc_attributes.proc_attributes) + if (attr.attribute_type is proc_attribute.attr_forward) + return true; + + return false; + } + + public override void visit(procedure_header _procedure_header) + { + string procedure_name = _procedure_header.name.meth_name.name; + // Сейчас здесь не могут быть встречены forward-объявления функций + // но на будущее... + if (IsForwardDeclaration(_procedure_header)) + { + symbolTable.Add(procedure_name, NameKind.ForwardDeclaredFunction); + } + else + { + symbolTable.Add(procedure_name, NameKind.GlobalFunction); + } + base.visit(_procedure_header); + } + + public override void visit(function_header _function_header) + { + visit(_function_header as procedure_header); + } + + public override void visit(function_lambda_definition _function_lambda_definition) + { + foreach (ident id in _function_lambda_definition.ident_list.list) + symbolTable.Add(id.name, NameKind.LocalVariable); + + base.visit(_function_lambda_definition); + } + + public override void visit(foreach_stmt _foreach_stmt) + { + symbolTable.OpenLocalScope(); + symbolTable.Add(_foreach_stmt.identifier.name, NameKind.LocalVariable); + + if (_foreach_stmt.ext is ident_list _ident_list) + { + foreach (ident _ident in _ident_list.idents) + { + symbolTable.Add(_ident.name, NameKind.LocalVariable); + } + } + + base.visit(_foreach_stmt); + symbolTable.CloseLocalScope(); + } + + public override void visit(interface_node _interface_node) + { + ProcessNode(_interface_node.uses_modules); + ProcessNode(_interface_node.using_namespaces); + ProcessNode(_interface_node.interface_definitions); + } + + public override void visit(global_statement _global_statement) + { + foreach (ident _ident in _global_statement.idents.idents) + { + symbolTable.MakeVisibleForAssignment(_ident.name); + } + } + + public override void visit(typed_parameters _typed_parameters) + { + foreach (ident id in _typed_parameters.idents.idents) + symbolTable.Add(id.name, NameKind.LocalVariable); + + base.visit(_typed_parameters); + } + + public override void visit(var_statement _var_statement) + { + foreach (ident id in _var_statement.var_def.vars.idents) + symbolTable.Add(id.name, NameKind.LocalVariable); + + base.visit(_var_statement); + } + + public override void visit(import_statement _import_statement) + { + foreach (as_statement as_Statement in _import_statement.modules_names.as_statements) + { + string real_name = as_Statement.real_name.name; + string alias = as_Statement.alias.name; + if (SymbolTable.specialModulesAliases.ContainsKey(real_name)) + real_name = SymbolTable.specialModulesAliases[real_name]; + symbolTable.AddModuleAlias(real_name, alias); + } + } + + public override void visit(from_import_statement _from_import_statement) + { + string module_real_name = _from_import_statement.module_name.name; + string module_name = module_real_name; + if (SymbolTable.specialModulesAliases.ContainsKey(module_name)) + module_name = SymbolTable.specialModulesAliases[module_name]; + + if (_from_import_statement.is_star) + { + foreach (string name in symbolTable.ModuleNameToSymbols[module_name]) + symbolTable.AddAlias(name, name, module_name); + } + else + { + foreach (as_statement as_Statement in _from_import_statement.imported_names.as_statements) + { + if (!symbolTable.ModuleNameToSymbols[module_name].Contains(as_Statement.real_name.name)) + throw new SPythonSyntaxVisitorError("MODULE_{0}_HAS_NO_NAME_{1}", + _from_import_statement.source_context, module_real_name, as_Statement.real_name.name); + + symbolTable.AddAlias(as_Statement.real_name.name, as_Statement.alias.name, module_name); + } + } + } + + public override void visit(variable_definitions _variable_definitions) + { + foreach (var_def_statement vds in _variable_definitions.var_definitions) + { + foreach (ident id in vds.vars.idents) + { + symbolTable.Add(id.name, NameKind.GlobalVariable); + base.visit(_variable_definitions); + } + } + } + + [Flags] + protected enum NameKind + { + // Имя отсутствует в текущем контексте + Unknown = 0b_0000_0000, + // Ключевые слова языка + Keyword = 0b_0000_0001, + // Имя глобальной переменной + GlobalVariable = 0b_0000_0010, + // Имя глобальной функции + GlobalFunction = 0b_0000_0100, + // Имя подключённого модуля или его псевдоним + ModuleAlias = 0b_0000_1000, + // Имя, подключённое из модуля, или его псевдоним + ImportedNameAlias = 0b_0001_0000, + // Локальня переменная + LocalVariable = 0b_0010_0000, + // Имя глобальной forward-объявленной функции + ForwardDeclaredFunction = 0b_0100_0000, + } + + protected class SymbolTable + { + private Dictionary nameTypes = new Dictionary(); + private HashSet forwardDeclaredFunctions = new HashSet(); + + static string[] Keywords = { + "int", "float", "str", "bool", "tuple", // standard types + "break", "continue", "exit", "halt", // standard ops + "true", "false", // constants + }; + + private void FillKeywords() + { + foreach (var keyword in Keywords) + nameTypes.Add(keyword, NameKind.Keyword); + } + + public SymbolTable(Dictionary> par) + { + ModuleNameToSymbols = par; + FillKeywords(); + AddAliasesFromStandartLibraries(); + } + + public static Dictionary specialModulesAliases = new Dictionary + { + { "time", "time1" }, + { "random", "random1" }, + }; + + // names added to current function with global statements + private HashSet NamesAddedByGlobal = new HashSet(); + + private bool isInFunctionBody = false; + + public bool IsInFunctionBody { + get { return isInFunctionBody; } + set + { + isInFunctionBody = value; + if (isInFunctionBody) + { + Add(StringConstants.result_var_name, NameKind.LocalVariable); + } + else + { + NamesAddedByGlobal.Clear(); + } + } + } + + // module alias -> module real name + private Dictionary modulesAliases = new Dictionary(); + + private List StandardLibraries = new List { "SPythonSystem", "SPythonHidden", "SPythonSystemPys" }; + + // alias of function or global variable from module -> real name and module real name + private Dictionary> aliasToRealNameAndModuleName = new Dictionary>(); + + private LocalScope localVariables = new LocalScope(); + + // moduleRealName -> functions and global variables in this module real names + private Dictionary> moduleNameToSymbols; + + public Dictionary> ModuleNameToSymbols + { + get => moduleNameToSymbols; + set + { moduleNameToSymbols = value; } + } + + private void AddAliasesFromStandartLibraries() + { + foreach (string standardLibrary in StandardLibraries) + { + if (moduleNameToSymbols.ContainsKey(standardLibrary)) + foreach (string name in moduleNameToSymbols[standardLibrary]) + AddAlias(name, name, standardLibrary); + } + } + + public string AliasToRealName(string alias) + { + if (modulesAliases.ContainsKey(alias)) + return modulesAliases[alias]; + else + return aliasToRealNameAndModuleName[alias].Item1; + } + + public string AliasToModuleName(string alias) + { + return aliasToRealNameAndModuleName[alias].Item2; + } + + public void MakeVisibleForAssignment(string name) + { + NamesAddedByGlobal.Add(name); + } + + public bool IsVisibleToAssign(string name) + { + NameKind kind = this[name]; + if (kind == NameKind.Unknown) return false; + if (!isInFunctionBody) return true; + return (kind != NameKind.GlobalVariable && + kind != NameKind.ImportedNameAlias) || + NamesAddedByGlobal.Contains(name); + } + + public NameKind this[string name] + { + get { + if (localVariables.Contains(name)) + return NameKind.LocalVariable; + if (nameTypes.ContainsKey(name)) + return nameTypes[name]; + if (forwardDeclaredFunctions.Contains(name)) + return NameKind.ForwardDeclaredFunction; + return NameKind.Unknown; + } + } + + public void Add(string name, NameKind nameType) + { + switch (nameType) + { + case NameKind.LocalVariable: + localVariables.Add(name); + break; + case NameKind.GlobalVariable: + case NameKind.GlobalFunction: + AddGlobalName(name, nameType); + break; + case NameKind.ForwardDeclaredFunction: + forwardDeclaredFunctions.Add(name); + break; + default: + throw new NotImplementedException(); + } + } + + private void AddGlobalName(string name, NameKind nameType) + { + EraseNameAsLocal(name); + + if (nameTypes.ContainsKey(name)) + nameTypes[name] = nameType; + else nameTypes.Add(name, nameType); + } + + public void AddAlias(string realName, string alias, string moduleName) + { + if (aliasToRealNameAndModuleName.ContainsKey(alias)) + aliasToRealNameAndModuleName[alias] = Tuple.Create(realName, moduleName); + else aliasToRealNameAndModuleName.Add(alias, Tuple.Create(realName, moduleName)); + AddGlobalName(alias, NameKind.ImportedNameAlias); + } + + public void AddModuleAlias(string realName, string alias) + { + if (modulesAliases.ContainsKey(alias)) + modulesAliases[alias] = realName; + else modulesAliases.Add(alias, realName); + AddGlobalName(alias, NameKind.ModuleAlias); + } + + private void EraseNameAsLocal(string name) + { + localVariables.EraseName(name); + } + + public void OpenLocalScope() + { + localVariables = new LocalScope(localVariables); + } + + public void CloseLocalScope() + { + localVariables.ClearScope(); + } + + public bool IsOutermostScope() + { + return localVariables.IsOutermostScope(); + } + + public class LocalScope + { + private LocalScope outerScope; + private HashSet symbols = new HashSet(); + + public LocalScope(LocalScope outerScope = null) + { + this.outerScope = outerScope; + } + + public bool Contains(string name) + { + LocalScope curr = this; + + while (curr != null) + { + if (curr.symbols.Contains(name)) + return true; + curr = curr.outerScope; + } + + return false; + } + + public void EraseName(string name) + { + LocalScope curr = this; + + while (curr != null) + { + //if (curr.symbols.Contains(name)) + curr.symbols.Remove(name); + curr = curr.outerScope; + } + } + + public void Add(string ident) + { + symbols.Add(ident); + } + + public void ClearScope() + { + if (outerScope != null) + { + symbols = outerScope.symbols; + outerScope = outerScope.outerScope; + } + } + + public bool IsOutermostScope() + { + return outerScope.outerScope == null; + } + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TreeNodesRearrangementVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TreeNodesRearrangementVisitor.cs new file mode 100644 index 000000000..df84f358e --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TreeNodesRearrangementVisitor.cs @@ -0,0 +1,96 @@ +using PascalABCCompiler.SyntaxTree; +using System.Collections.Generic; + +namespace Languages.SPython.Frontend.Converters +{ + internal class TreeNodesRearrangementVisitor : BaseChangeVisitor + { + private procedure_definition mainFunction; + + // declaration после объявления мейна (объявления функций с определениями) + private List suffix = new List(); + + private declarations decls; + + private const string mainFunctionName = "%%MAIN%%"; + + private bool isInFunction = false; + private int scopeCounter = 0; + + public TreeNodesRearrangementVisitor() { } + + // нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew + public override void DefaultVisit(syntax_tree_node n) + { + if (n == null) return; + for (var i = 0; i < n.subnodes_count; i++) + ProcessNode(n[i]); + } + + public override void Enter(syntax_tree_node stn) + { + if (stn is procedure_definition) + { + isInFunction = true; + scopeCounter++; + } + if (stn is statement_list) + { + scopeCounter++; + } + if (stn is program_module pm) + { + decls = pm.program_block.defs; + } + if (stn is interface_node intn) + { + decls = intn.interface_definitions; + } + + base.Enter(stn); + } + + private void BuildMainFunction(statement_list _statement_list) + { + statement_list mainBody = _statement_list.TypedClone(); + procedure_header _procedure_header = new procedure_header(mainFunctionName); + block _block = new block(null, mainBody, mainBody.source_context); + //block _block = new block(null, new statement_list(), _statement_list.source_context); + mainFunction = new procedure_definition(_procedure_header, _block, false, _block.source_context); + } + + public override void Exit(syntax_tree_node stn) + { + if (stn is procedure_definition) + { + isInFunction = false; + scopeCounter--; + } + if (stn is statement_list sl) + { + scopeCounter--; + // вышли из внешнего statement_list внутри begin end. + if (!isInFunction && scopeCounter == 0) + { + BuildMainFunction(sl); + decls.list.Add(mainFunction); + foreach (declaration decl in suffix) + decls.list.Add(decl); + sl.list.Clear(); + sl.Add(new procedure_call(new method_call(new ident(mainFunctionName), null), true)); + } + } + + base.Exit(stn); + } + + public override void visit(declarations_as_statement _declarations_as_statement) + { + foreach (declaration decl in _declarations_as_statement.defs.defs) + { + suffix.Add(decl); + } + ReplaceStatement(_declarations_as_statement, new empty_statement()); + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TypeCorrectVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TypeCorrectVisitor.cs new file mode 100644 index 000000000..2ffa24cf0 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/TypeCorrectVisitor.cs @@ -0,0 +1,87 @@ +using PascalABCCompiler.SyntaxTree; + +namespace Languages.SPython.Frontend.Converters +{ + public class TypeCorrectVisitor : BaseChangeVisitor + { + + private bool forIntellisense; + + public TypeCorrectVisitor(bool forIntellisense) + { + this.forIntellisense = forIntellisense; + } + + public override void visit(template_type_reference ttr) + { + int index = ttr.name.names.Count - 1; + if (ttr.name.names[index].name == "tuple") + { + int cnt = ttr.params_list.Count; + if (cnt > 7) + { + throw new SPythonSyntaxVisitorError("LONG_TUPLE_TYPENAME", + ttr.source_context, cnt); + } + ttr.name.names[index].name += cnt; + } + base.visit(ttr); + } + + public override void visit(named_type_reference _named_type_reference) + { + ident id = _named_type_reference.names[_named_type_reference.names.Count - 1]; + + if (!forIntellisense) + { + switch (id.name) + { + case "int": + id.name = "integer"; + break; + case "float": + id.name = "real"; + break; + case "str": + id.name = "string"; + break; + case "bool": + id.name = "boolean"; + break; + case "bigint": + id.name = "biginteger"; + break; + + case "integer": + throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}", + id.source_context, id.name, "int"); + case "real": + throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}", + id.source_context, id.name, "float"); + case "string": + throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}", + id.source_context, id.name, "str"); + case "boolean": + throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}", + id.source_context, id.name, "bool"); + case "biginteger": + throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}", + id.source_context, id.name, "bigint"); + } + } + + switch (id.name) + { + case "list": + id.name = "!list"; + break; + case "dict": + id.name = "!dict"; + break; + case "set": + id.name = "!set"; + break; + } + } + } +} diff --git a/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/UnsupportedConstructsVisitor.cs b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/UnsupportedConstructsVisitor.cs new file mode 100644 index 000000000..8f60d50d4 --- /dev/null +++ b/LanguagePlugins/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/UnsupportedConstructsVisitor.cs @@ -0,0 +1,137 @@ +using Languages.SPython.Frontend.Converters; +using PascalABCCompiler.SyntaxTree; + +namespace Languages.Pascal.Frontend.Converters +{ + public class UnsupportedConstructsVisitor : BaseEnterExitVisitor + { + private int blockLevel = 0; + // function returns a value + private bool isInFunction = false; + // procedure doesn't return value + private bool isInProcedure = false; + + public UnsupportedConstructsVisitor() { } + + public override void Enter(syntax_tree_node st) + { + if (st is statement_list) + { + ++blockLevel; + } + if (st is procedure_definition pd) + { + if (pd.proc_header is function_header) + isInFunction = true; + else + isInProcedure = true; + } + } + + public override void Exit(syntax_tree_node st) + { + if (st is statement_list) + { + --blockLevel; + } + if (st is procedure_definition) + { + isInProcedure = isInFunction = false; + } + } + + public override void visit(return_statement _return_statement) + { + // 'return' или 'return expr' вне функции + if (!isInFunction && !isInProcedure) + { + throw new SPythonSyntaxVisitorError("RETURN_NOT_IN_FUNCTION", + _return_statement.source_context); + } + // 'return' внутри функции, которая должна возвращать значение + if (isInFunction && _return_statement.expr == null) + { + throw new SPythonSyntaxVisitorError("RETURN_NOT_RETURN_VALUE", + _return_statement.source_context); + } + // 'return expr' внутри функции, которая не возвращает значение + if (isInProcedure && _return_statement.expr != null) + { + throw new SPythonSyntaxVisitorError("RETURN_HAS_RETURN_VALUE", + _return_statement.expr.source_context); + } + + base.visit(_return_statement); + } + + public override void visit(global_statement _global_statement) + { + // конструкция 'global ...' используется вне функции + if (!isInProcedure && !isInFunction) + { + throw new SPythonSyntaxVisitorError("GLOBAL_NOT_IN_FUNCTION", + _global_statement.source_context); + } + // конструкция 'global ...' используется + // не на самом внешнем блоке внутри функции + if (blockLevel != 2) + { + throw new SPythonSyntaxVisitorError("GLOBAL_IN_NOT_OUTERMOST_BLOCK", + _global_statement.source_context); + } + + base.visit(_global_statement); + } + + public override void visit(import_statement _import_statement) + { + // конструкция 'import ...' + // используется не на глобальном уровне + if (blockLevel > 1) + { + throw new SPythonSyntaxVisitorError("LOCAL_IMPORT_USE", + _import_statement.source_context); + } + + base.visit(_import_statement); + } + + public override void visit(from_import_statement _from_import_statement) + { + // конструкция 'from ... import ...' + // используется не на глобальном уровне + if (blockLevel > 1) + { + throw new SPythonSyntaxVisitorError("LOCAL_FROM_IMPORT_USE", + _from_import_statement.source_context); + } + + base.visit(_from_import_statement); + } + + public override void visit(procedure_definition _procedure_definition) + { + // объявление функции не на глобальном уровне + if (blockLevel > 1) + { + throw new SPythonSyntaxVisitorError("LOCAL_FUNCTION_DECLARATION", + _procedure_definition.source_context); + } + + base.visit(_procedure_definition); + } + + public override void visit(assign_tuple _assign_tuple) + { + // выявление ошибок типа + // a, b = 1, 2, 3 + if (_assign_tuple.expr is tuple_node right_part + && _assign_tuple.vars.Count < right_part.el.Count + ) + { + throw new SPythonSyntaxVisitorError("LEFT_SIZE_TUPLE_ASSIGNMENT_LESS_THAN_RIGHT", + _assign_tuple.source_context); + } + } + } +} diff --git a/ParserTools/ParserTools/BaseLanguageInformation.cs b/ParserTools/ParserTools/BaseLanguageInformation.cs index addbd6732..945b46cc4 100644 --- a/ParserTools/ParserTools/BaseLanguageInformation.cs +++ b/ParserTools/ParserTools/BaseLanguageInformation.cs @@ -27,6 +27,9 @@ namespace PascalABCCompiler.Parsers public abstract string ReturnTypeDelimiter { get; } + public abstract string ProcedureName { get; } + public abstract string FunctionName { get; } + public abstract bool CaseSensitive { get; } public abstract bool IncludeDotNetEntities { get; } @@ -199,6 +202,362 @@ namespace PascalABCCompiler.Parsers return scope.Name + template_str; } + // TODO: Адаптировать к многоязычности EVA + protected string GetDescriptionForCompiledMethod(ICompiledMethodScope scope) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + string extensionType = null; + if (scope.IsExtension && scope.Parameters.Length > 0) + { + extensionType = GetSimpleDescription(scope.Parameters[0].Type); + } + if (scope.IsExtension) + { + if (extensionType.IndexOf(' ') != -1) + { + sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + " " + extensionType + ") "); + } + else + { + sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + ") "); + extensionType = null; + } + } + + if (scope.IsStatic && !scope.IsGlobal) sb.Append("static "); + if (scope.ReturnType == null && ProcedureName != null) + sb.Append(ProcedureName + " "); + else + sb.Append(FunctionName + " "); + Dictionary generic_param_args = null; + Dictionary class_generic_table = new Dictionary(); + ParameterInfo[] pis = scope.CompiledMethod.GetParameters(); + Type[] tt = scope.CompiledMethod.GetGenericArguments(); + int gen_ind = 0; + if (!scope.IsExtension) + { + sb.Append(GetShortTypeName(scope.CompiledMethod.DeclaringType)); + int ind = 0; + foreach (Type gen_arg in scope.CompiledMethod.DeclaringType.GetGenericArguments()) + { + if (gen_arg.IsGenericParameter) + { + if (generic_param_args == null) + generic_param_args = new Dictionary(); + if (scope.GenericArgs != null && scope.GenericArgs.Count > ind) + generic_param_args.Add(gen_arg.Name, scope.GenericArgs[ind]); + else if (scope.DeclaringType.TemplateArguments != null && scope.DeclaringType.TemplateArguments.Length > ind) + generic_param_args.Add(gen_arg.Name, scope.DeclaringType.TemplateArguments[ind]); + } + ind++; + } + + } + else + { + gen_ind = 0; + generic_param_args = new Dictionary(); + for (int i = 0; i < pis.Length; i++) + { + if (i == 0) + { + Type[] class_generic_args = pis[i].ParameterType.GetGenericArguments(); + for (int j = 0; j < class_generic_args.Length; j++) + { + if (!class_generic_table.ContainsKey(class_generic_args[i].Name)) + class_generic_table.Add(class_generic_args[i].Name, j); + if (scope.GenericArgs != null && scope.GenericArgs.Count > j) + { + if (scope.DeclaringType.GenericInstances.Length > 0) + generic_param_args[class_generic_args[i].Name] = GetSimpleDescription(scope.DeclaringType.GenericInstances[0]); + else if (scope.DeclaringType is ICompiledTypeScope) + { + Type ctn = (scope.DeclaringType as ICompiledTypeScope).CompiledType; + if (ctn.IsGenericType && !ctn.IsGenericTypeDefinition) + generic_param_args[class_generic_args[i].Name] = GetSimpleDescriptionForCompiledType((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[0]); + } + } + else if (scope.DeclaringType.TemplateArguments != null && scope.DeclaringType.TemplateArguments.Length > j) + generic_param_args[class_generic_args[i].Name] = scope.DeclaringType.TemplateArguments[j]; + } + break; + } + } + if (extensionType == null) + sb.Append(GetShortTypeName(scope.CompiledMethod.GetParameters()[0].ParameterType)); + } + //if (scope.Name != "Invoke") + { + if (extensionType == null) + sb.Append("."); + sb.Append(scope.Name); + } + + if (scope.CompiledMethod.GetGenericArguments().Length > 0) + { + sb.Append(GenericTypesStartBracket); + for (int i = gen_ind; i < tt.Length; i++) + { + if (class_generic_table.ContainsKey(tt[i].Name)) + { + int ind = class_generic_table[tt[i].Name]; + if (scope.GenericArgs != null && scope.GenericArgs.Count > ind) + { + if (scope.DeclaringType.GenericInstances.Length > ind) + { + sb.Append(GetSimpleDescription(scope.DeclaringType.GenericInstances[ind])); + if (!generic_param_args.ContainsKey(tt[i].Name)) + generic_param_args.Add(tt[i].Name, GetSimpleDescription(scope.DeclaringType.GenericInstances[ind])); + } + else if (scope.DeclaringType is ICompiledTypeScope) + { + Type ctn = (scope.DeclaringType as ICompiledTypeScope).CompiledType; + if (ctn.IsGenericType && !ctn.IsGenericTypeDefinition) + { + sb.Append(GetSimpleDescription((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[ind])); + if (!generic_param_args.ContainsKey(tt[i].Name)) + generic_param_args.Add(tt[i].Name, GetSimpleDescription((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[ind])); + } + } + } + } + + else + sb.Append(tt[i].Name); + if (i < tt.Length - 1) sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + } + sb.Append('('); + + for (int i = 0; i < pis.Length; i++) + { + if (i == 0 && scope.IsExtension) + continue; + if (pis[i].ParameterType.IsByRef) + sb.Append("var "); + else if (IsParams(pis[i])) + sb.Append("params "); + sb.Append(pis[i].Name); + sb.Append(": "); + string inst_type = null; + if (!pis[i].ParameterType.IsByRef) + { + if (scope.GenericArgs != null) + { + inst_type = get_type_instance(pis[i].ParameterType, scope.GenericArgs, generic_param_args); + } + if (inst_type == null) + sb.Append(GetShortTypeName(pis[i].ParameterType, false)); + else + sb.Append(inst_type); + if (pis[i].IsOptional) + { + sb.Append(" := "); + if (pis[i].DefaultValue != null) + { + if (pis[i].DefaultValue is string) sb.Append($"'{pis[i].DefaultValue.ToString()}'"); + else sb.Append(pis[i].DefaultValue.ToString()); + } + else sb.Append("nil"); + } + } + else + { + Type t = pis[i].ParameterType.GetElementType(); + if (scope.GenericArgs != null) + { + inst_type = get_type_instance(t, scope.GenericArgs, generic_param_args); + } + if (inst_type == null) + sb.Append(GetShortTypeName(t, false)); + else + sb.Append(inst_type); + } + if (i < pis.Length - 1) + sb.Append(ParameterDelimiter + " "); + } + sb.Append(')'); + string ret_inst_type = null; + if (scope.ReturnType != null) + { + if (scope.GenericArgs != null) + { + ret_inst_type = get_type_instance(scope.CompiledMethod.ReturnType, scope.GenericArgs, generic_param_args); + } + if (ret_inst_type == null) + { + if (scope.ReturnType is ICompiledTypeScope) + sb.Append(ReturnTypeDelimiter + " " + GetFullTypeName((scope.ReturnType as ICompiledTypeScope).CompiledType, false)); + else + sb.Append(ReturnTypeDelimiter + " " + GetSimpleDescription(scope.ReturnType)); + } + else + sb.Append(ReturnTypeDelimiter + " " + ret_inst_type); + } + //if (scope.CompiledMethod.IsStatic) sb.Append("; static"); + if (scope.IsVirtual) sb.Append("; "); + else if (scope.IsAbstract) sb.Append("; abstract"); + //else if (scope.CompiledMethod.IsHideBySig) sb.Append("; reintroduce"); + sb.Append(';'); + return sb.ToString(); + } + + // TODO: Адаптировать к многоязычности EVA + protected string GetDescriptionForCompiledMethod(MethodInfo mi) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + + if (mi.IsPublic) + sb.Append("public "); + else if (mi.IsFamily) + sb.Append("protected "); + if (mi.IsStatic) sb.Append("static "); + if (mi.ReturnType == typeof(void) && ProcedureName != null) + sb.Append(ProcedureName + " "); + else + sb.Append(FunctionName + " "); + sb.Append(prepare_member_name(mi.Name)); + if (mi.GetGenericArguments().Length > 0) + { + Type[] tt = mi.GetGenericArguments(); + sb.Append(GenericTypesStartBracket); + for (int i = 0; i < tt.Length; i++) + { + sb.Append(tt[i].Name); + if (i < tt.Length - 1) sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + } + sb.Append('('); + ParameterInfo[] pis = mi.GetParameters(); + for (int i = 0; i < pis.Length; i++) + { + if (pis[i].ParameterType.IsByRef) + sb.Append("var "); + else if (IsParams(pis[i])) + sb.Append("params "); + sb.Append(prepare_member_name(pis[i].Name)); + sb.Append(": "); + string inst_type = null; + if (!pis[i].ParameterType.IsByRef) + { + sb.Append(GetFullTypeName(pis[i].ParameterType)); + if (pis[i].IsOptional) + { + sb.Append(" := "); + if (pis[i].DefaultValue != null) + { + if (pis[i].DefaultValue is string) sb.Append($"'{pis[i].DefaultValue.ToString()}'"); + else sb.Append(pis[i].DefaultValue.ToString()); + } + else sb.Append("nil"); + } + } + else + { + Type t = pis[i].ParameterType.GetElementType(); + sb.Append(GetFullTypeName(t)); + } + + if (i < pis.Length - 1) + sb.Append(ParameterDelimiter + " "); + } + sb.Append(')'); + string ret_inst_type = null; + if (mi.ReturnType != typeof(void)) + { + sb.Append(ReturnTypeDelimiter + " " + GetFullTypeName(mi.ReturnType)); + } + //if (scope.CompiledMethod.IsStatic) sb.Append("; static"); + if (mi.IsVirtual && !mi.IsFinal) sb.Append("; "); + else if (mi.IsAbstract) sb.Append("; abstract"); + //else if (scope.CompiledMethod.IsHideBySig) sb.Append("; reintroduce"); + sb.Append(';'); + return sb.ToString(); + } + + protected string prepare_member_name(string s) + { + if (IsKeyword(s)) + return "&" + s; + return s; + } + + // TODO: Адаптировать к многоязычности EVA + protected string GetSimpleDescriptionForCompiledType(ICompiledTypeScope scope, bool fullName) + { + if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Func`")) + { + return getLambdaRepresentation(scope, true); + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Action`")) + { + return getLambdaRepresentation(scope, false); + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Predicate`1")) + { + return getLambdaRepresentation(scope, false); + } + else if (scope.CompiledType.Name == "IEnumerable`1") + { + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + return "sequence of " + GetSimpleDescriptionWithoutNamespace(instances[0]); + } + else + return "sequence of T"; + } + else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Tuple`")) + { + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + return get_tuple_string(instances); + } + else + return "(T1,...)"; + } + else + { + string s = !fullName ? GetShortTypeName(scope.CompiledType) : GetFullTypeName(scope.CompiledType); + ITypeScope[] instances = scope.GenericInstances; + if (instances != null && instances.Length > 0) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + int ind = s.IndexOf(GenericTypesStartBracket); + if (ind != -1) sb.Append(s.Substring(0, ind)); + else + sb.Append(s); + sb.Append(GenericTypesStartBracket); + for (int i = 0; i < instances.Length; i++) + { + sb.Append(GetSimpleDescriptionWithoutNamespace(instances[i])); + if (i < instances.Length - 1) sb.Append(", "); + } + sb.Append(GenericTypesEndBracket); + s = sb.ToString(); + } + return s; + } + } + + protected string GetSimpleDescriptionForCompiledType(ICompiledTypeScope scope) + { + return GetSimpleDescriptionForCompiledType(scope, false); + } + + protected bool IsParams(ParameterInfo _par) + { + object[] objarr = _par.GetCustomAttributes(typeof(ParamArrayAttribute), true); + if ((objarr == null) || (objarr.Length == 0)) + { + return false; + } + return true; + } + protected string GetTopScopeName(IBaseScope sc) { if (sc == null) return ""; diff --git a/PascalABCLanguageInfo/PascalABCLanguageInformation.cs b/PascalABCLanguageInfo/PascalABCLanguageInformation.cs index dbe593d2b..cab596b1f 100644 --- a/PascalABCLanguageInfo/PascalABCLanguageInformation.cs +++ b/PascalABCLanguageInfo/PascalABCLanguageInformation.cs @@ -131,6 +131,10 @@ namespace Languages.Pascal.Frontend.Data public override string ResultVariableName => "Result"; + public override string ProcedureName => "procedure"; + + public override string FunctionName => "function"; + public override string GenericTypesStartBracket => "<"; public override string GenericTypesEndBracket => ">"; @@ -1007,69 +1011,6 @@ namespace Languages.Pascal.Frontend.Data return s; } - protected string GetSimpleDescriptionForCompiledType(ICompiledTypeScope scope, bool fullName) - { - if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Func`")) - { - return getLambdaRepresentation(scope, true); - } - else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Action`")) - { - return getLambdaRepresentation(scope, false); - } - else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Predicate`1")) - { - return getLambdaRepresentation(scope, false); - } - else if (scope.CompiledType.Name == "IEnumerable`1") - { - ITypeScope[] instances = scope.GenericInstances; - if (instances != null && instances.Length > 0) - { - return "sequence of " + GetSimpleDescriptionWithoutNamespace(instances[0]); - } - else - return "sequence of T"; - } - else if (scope.CompiledType.Name != null && scope.CompiledType.Name.Contains("Tuple`")) - { - ITypeScope[] instances = scope.GenericInstances; - if (instances != null && instances.Length > 0) - { - return get_tuple_string(instances); - } - else - return "(T1,...)"; - } - else - { - string s = !fullName ? GetShortTypeName(scope.CompiledType) : GetFullTypeName(scope.CompiledType); - ITypeScope[] instances = scope.GenericInstances; - if (instances != null && instances.Length > 0) - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - int ind = s.IndexOf(GenericTypesStartBracket); - if (ind != -1) sb.Append(s.Substring(0, ind)); - else - sb.Append(s); - sb.Append(GenericTypesStartBracket); - for (int i = 0; i < instances.Length; i++) - { - sb.Append(GetSimpleDescriptionWithoutNamespace(instances[i])); - if (i < instances.Length - 1) sb.Append(", "); - } - sb.Append(GenericTypesEndBracket); - s = sb.ToString(); - } - return s; - } - } - - protected string GetSimpleDescriptionForCompiledType(ICompiledTypeScope scope) - { - return GetSimpleDescriptionForCompiledType(scope, false); - } - protected string GetDescriptionForArray(IArrayScope scope) { StringBuilder sb = new StringBuilder(); @@ -1376,289 +1317,6 @@ namespace Languages.Pascal.Frontend.Data return sb.ToString(); } - private bool is_params(ParameterInfo _par) - { - object[] objarr = _par.GetCustomAttributes(typeof(ParamArrayAttribute), true); - if ((objarr == null) || (objarr.Length == 0)) - { - return false; - } - return true; - } - - public string GetDescriptionForCompiledMethod(MethodInfo mi) - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - - if (mi.IsPublic) - sb.Append("public "); - else if (mi.IsFamily) - sb.Append("protected "); - if (mi.IsStatic) sb.Append("static "); - if (mi.ReturnType == typeof(void)) - sb.Append("procedure "); - else - sb.Append("function "); - sb.Append(prepare_member_name(mi.Name)); - if (mi.GetGenericArguments().Length > 0) - { - Type[] tt = mi.GetGenericArguments(); - sb.Append(GenericTypesStartBracket); - for (int i = 0; i < tt.Length; i++) - { - sb.Append(tt[i].Name); - if (i < tt.Length - 1) sb.Append(", "); - } - sb.Append(GenericTypesEndBracket); - } - sb.Append('('); - ParameterInfo[] pis = mi.GetParameters(); - for (int i = 0; i < pis.Length; i++) - { - if (pis[i].ParameterType.IsByRef) - sb.Append("var "); - else if (is_params(pis[i])) - sb.Append("params "); - sb.Append(prepare_member_name(pis[i].Name)); - sb.Append(": "); - string inst_type = null; - if (!pis[i].ParameterType.IsByRef) - { - sb.Append(GetFullTypeName(pis[i].ParameterType)); - if (pis[i].IsOptional) - { - sb.Append(" := "); - if (pis[i].DefaultValue != null) - { - if (pis[i].DefaultValue is string) sb.Append($"'{pis[i].DefaultValue.ToString()}'"); - else sb.Append(pis[i].DefaultValue.ToString()); - } - else sb.Append("nil"); - } - } - else - { - Type t = pis[i].ParameterType.GetElementType(); - sb.Append(GetFullTypeName(t)); - } - - if (i < pis.Length - 1) - sb.Append("; "); - } - sb.Append(')'); - string ret_inst_type = null; - if (mi.ReturnType != typeof(void)) - { - sb.Append(ReturnTypeDelimiter + " " + GetFullTypeName(mi.ReturnType)); - } - //if (scope.CompiledMethod.IsStatic) sb.Append("; static"); - if (mi.IsVirtual && !mi.IsFinal) sb.Append("; "); - else if (mi.IsAbstract) sb.Append("; abstract"); - //else if (scope.CompiledMethod.IsHideBySig) sb.Append("; reintroduce"); - sb.Append(';'); - return sb.ToString(); - } - - protected string GetDescriptionForCompiledMethod(ICompiledMethodScope scope) - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - string extensionType = null; - if (scope.IsExtension && scope.Parameters.Length > 0) - { - extensionType = GetSimpleDescription(scope.Parameters[0].Type); - } - if (scope.IsExtension) - { - if (extensionType.IndexOf(' ') != -1) - { - sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + " " + extensionType + ") "); - } - else - { - sb.Append("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION") + ") "); - extensionType = null; - } - } - - if (scope.IsStatic && !scope.IsGlobal) sb.Append("static "); - if (scope.ReturnType == null) - sb.Append("procedure "); - else - sb.Append("function "); - Dictionary generic_param_args = null; - Dictionary class_generic_table = new Dictionary(); - ParameterInfo[] pis = scope.CompiledMethod.GetParameters(); - Type[] tt = scope.CompiledMethod.GetGenericArguments(); - int gen_ind = 0; - if (!scope.IsExtension) - { - sb.Append(GetShortTypeName(scope.CompiledMethod.DeclaringType)); - int ind = 0; - foreach (Type gen_arg in scope.CompiledMethod.DeclaringType.GetGenericArguments()) - { - if (gen_arg.IsGenericParameter) - { - if (generic_param_args == null) - generic_param_args = new Dictionary(); - if (scope.GenericArgs != null && scope.GenericArgs.Count > ind) - generic_param_args.Add(gen_arg.Name, scope.GenericArgs[ind]); - else if (scope.DeclaringType.TemplateArguments != null && scope.DeclaringType.TemplateArguments.Length > ind) - generic_param_args.Add(gen_arg.Name, scope.DeclaringType.TemplateArguments[ind]); - } - ind++; - } - - } - else - { - gen_ind = 0; - generic_param_args = new Dictionary(); - for (int i = 0; i < pis.Length; i++) - { - if (i == 0) - { - Type[] class_generic_args = pis[i].ParameterType.GetGenericArguments(); - for (int j = 0; j < class_generic_args.Length; j++) - { - if (!class_generic_table.ContainsKey(class_generic_args[i].Name)) - class_generic_table.Add(class_generic_args[i].Name, j); - if (scope.GenericArgs != null && scope.GenericArgs.Count > j) - { - if (scope.DeclaringType.GenericInstances.Length > 0) - generic_param_args[class_generic_args[i].Name] = GetSimpleDescription(scope.DeclaringType.GenericInstances[0]); - else if (scope.DeclaringType is ICompiledTypeScope) - { - Type ctn = (scope.DeclaringType as ICompiledTypeScope).CompiledType; - if (ctn.IsGenericType && !ctn.IsGenericTypeDefinition) - generic_param_args[class_generic_args[i].Name] = GetSimpleDescriptionForCompiledType((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[0]); - } - } - else if (scope.DeclaringType.TemplateArguments != null && scope.DeclaringType.TemplateArguments.Length > j) - generic_param_args[class_generic_args[i].Name] = scope.DeclaringType.TemplateArguments[j]; - } - break; - } - } - if (extensionType == null) - sb.Append(GetShortTypeName(scope.CompiledMethod.GetParameters()[0].ParameterType)); - } - //if (scope.Name != "Invoke") - { - if (extensionType == null) - sb.Append("."); - sb.Append(scope.Name); - } - - if (scope.CompiledMethod.GetGenericArguments().Length > 0) - { - sb.Append(GenericTypesStartBracket); - for (int i = gen_ind; i < tt.Length; i++) - { - if (class_generic_table.ContainsKey(tt[i].Name)) - { - int ind = class_generic_table[tt[i].Name]; - if (scope.GenericArgs != null && scope.GenericArgs.Count > ind) - { - if (scope.DeclaringType.GenericInstances.Length > ind) - { - sb.Append(GetSimpleDescription(scope.DeclaringType.GenericInstances[ind])); - if (!generic_param_args.ContainsKey(tt[i].Name)) - generic_param_args.Add(tt[i].Name, GetSimpleDescription(scope.DeclaringType.GenericInstances[ind])); - } - else if (scope.DeclaringType is ICompiledTypeScope) - { - Type ctn = (scope.DeclaringType as ICompiledTypeScope).CompiledType; - if (ctn.IsGenericType && !ctn.IsGenericTypeDefinition) - { - sb.Append(GetSimpleDescription((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[ind])); - if (!generic_param_args.ContainsKey(tt[i].Name)) - generic_param_args.Add(tt[i].Name, GetSimpleDescription((scope.DeclaringType as ICompiledTypeScope).GetCompiledGenericArguments()[ind])); - } - } - } - } - - else - sb.Append(tt[i].Name); - if (i < tt.Length - 1) sb.Append(", "); - } - sb.Append(GenericTypesEndBracket); - } - sb.Append('('); - - for (int i = 0; i < pis.Length; i++) - { - if (i == 0 && scope.IsExtension) - continue; - if (pis[i].ParameterType.IsByRef) - sb.Append("var "); - else if (is_params(pis[i])) - sb.Append("params "); - sb.Append(pis[i].Name); - sb.Append(": "); - string inst_type = null; - if (!pis[i].ParameterType.IsByRef) - { - if (scope.GenericArgs != null) - { - inst_type = get_type_instance(pis[i].ParameterType, scope.GenericArgs, generic_param_args); - } - if (inst_type == null) - sb.Append(GetShortTypeName(pis[i].ParameterType, false)); - else - sb.Append(inst_type); - if (pis[i].IsOptional) - { - sb.Append(" := "); - if (pis[i].DefaultValue != null) - { - if (pis[i].DefaultValue is string) sb.Append($"'{pis[i].DefaultValue.ToString()}'"); - else sb.Append(pis[i].DefaultValue.ToString()); - } - else sb.Append("nil"); - } - } - else - { - Type t = pis[i].ParameterType.GetElementType(); - if (scope.GenericArgs != null) - { - inst_type = get_type_instance(t, scope.GenericArgs, generic_param_args); - } - if (inst_type == null) - sb.Append(GetShortTypeName(t, false)); - else - sb.Append(inst_type); - } - if (i < pis.Length - 1) - sb.Append("; "); - } - sb.Append(')'); - string ret_inst_type = null; - if (scope.ReturnType != null) - { - if (scope.GenericArgs != null) - { - ret_inst_type = get_type_instance(scope.CompiledMethod.ReturnType, scope.GenericArgs, generic_param_args); - } - if (ret_inst_type == null) - { - if (scope.ReturnType is ICompiledTypeScope) - sb.Append(ReturnTypeDelimiter + " " + GetFullTypeName((scope.ReturnType as ICompiledTypeScope).CompiledType, false)); - else - sb.Append(ReturnTypeDelimiter + " " + GetSimpleDescription(scope.ReturnType)); - } - else - sb.Append(ReturnTypeDelimiter + " " + ret_inst_type); - } - //if (scope.CompiledMethod.IsStatic) sb.Append("; static"); - if (scope.IsVirtual) sb.Append("; "); - else if (scope.IsAbstract) sb.Append("; abstract"); - //else if (scope.CompiledMethod.IsHideBySig) sb.Append("; reintroduce"); - sb.Append(';'); - return sb.ToString(); - } - private string GetDescriptionForNamespace(INamespaceScope scope) { return "namespace " + scope.Name; @@ -1747,13 +1405,6 @@ namespace Languages.Pascal.Frontend.Data return sb.ToString(); } - private string prepare_member_name(string s) - { - if (IsKeyword(s)) - return "&" + s; - return s; - } - protected string GetDescriptionForCompiledEvent(EventInfo ei) { MethodInfo add_meth = ei.GetAddMethod(true); @@ -1789,7 +1440,7 @@ namespace Languages.Pascal.Frontend.Data { if (pis[i].ParameterType.IsByRef) sb.Append("var "); - else if (is_params(pis[i])) + else if (IsParams(pis[i])) sb.Append("params "); sb.Append(prepare_member_name(pis[i].Name)); sb.Append(": "); @@ -1817,7 +1468,7 @@ namespace Languages.Pascal.Frontend.Data { if (pis[i].ParameterType.IsByRef) sb.Append("var "); - else if (is_params(pis[i])) + else if (IsParams(pis[i])) sb.Append("params "); sb.Append(pis[i].Name); sb.Append(": "); @@ -1984,7 +1635,7 @@ namespace Languages.Pascal.Frontend.Data { if (pis[i].ParameterType.IsByRef) sb.Append("var "); - else if (is_params(pis[i])) + else if (IsParams(pis[i])) sb.Append("params "); sb.Append(pis[i].Name); sb.Append(": "); @@ -2046,7 +1697,7 @@ namespace Languages.Pascal.Frontend.Data { if (pis[i].ParameterType.IsByRef) sb.Append("var "); - else if (is_params(pis[i])) + else if (IsParams(pis[i])) sb.Append("params "); sb.Append(pis[i].Name); sb.Append(": "); diff --git a/PascalABCNET.sln b/PascalABCNET.sln index cbd1edad7..ac6db69a3 100644 --- a/PascalABCNET.sln +++ b/PascalABCNET.sln @@ -103,6 +103,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringConstants", "StringCo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LambdaAnySynToSemConverter", "LambdaAnySynToSemConverter\LambdaAnySynToSemConverter.csproj", "{27D9800E-2689-4AA1-A2D6-128E4A9BAE98}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SemanticAnalyzers", "SemanticAnalyzers", "{AAA3A0F7-2990-4C44-BAC7-0C4BAA053E8A}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Parsers", "Parsers", "{E952792F-B9F0-450C-B0D8-3128DF95EF19}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PascalABCSaushkinParser", "Parsers\PascalABCParserNewSaushkin\PascalABCSaushkinParser.csproj", "{0ED020FF-D28E-4791-BBDD-B8B9BA714096}" @@ -111,6 +113,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PascalABCLanguageInfo", "Pa EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTreeConverters", "SyntaxTreeConverters\SyntaxTreeConverters.csproj", "{F10A5330-DCF4-4533-877C-7B1B1BE23884}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SPython", "SPython", "{C12F6C91-460E-4C66-9572-D4D5AB169DF9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SyntaxTreeConverters", "SyntaxTreeConverters", "{E51C8CE6-9785-4666-9CD2-BADB728933E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonSyntaxTreeVisitor", "LanguagePlugins\SPython\SemanticAnalyzers\SPythonSyntaxTreeVisitor\SPythonSyntaxTreeVisitor.csproj", "{D38A21E0-1D61-4905-82B3-1800E1991D57}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonStandardTreeConverter", "LanguagePlugins\SPython\SyntaxTreeConverters\SPythonStandardTreeConverter\SPythonStandardTreeConverter.csproj", "{431AA1A0-81B9-4D93-9CB1-219BDF7825C9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonParser", "LanguagePlugins\SPython\SPythonParserKrylovMovchan\SPythonParser.csproj", "{81FE2BAA-D100-4596-A392-F03BBE30F829}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonLanguageInfo", "LanguagePlugins\SPython\SPythonLanguageInfo\SPythonLanguageInfo.csproj", "{DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -523,6 +537,54 @@ Global {F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|Mixed Platforms.Build.0 = Release|Any CPU {F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|x86.ActiveCfg = Release|Any CPU {F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|x86.Build.0 = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|x86.ActiveCfg = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Debug|x86.Build.0 = Debug|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|Any CPU.Build.0 = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|x86.ActiveCfg = Release|Any CPU + {D38A21E0-1D61-4905-82B3-1800E1991D57}.Release|x86.Build.0 = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|x86.ActiveCfg = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Debug|x86.Build.0 = Debug|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|Any CPU.Build.0 = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|x86.ActiveCfg = Release|Any CPU + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9}.Release|x86.Build.0 = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|x86.ActiveCfg = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Debug|x86.Build.0 = Debug|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|Any CPU.Build.0 = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|x86.ActiveCfg = Release|Any CPU + {81FE2BAA-D100-4596-A392-F03BBE30F829}.Release|x86.Build.0 = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|x86.ActiveCfg = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Debug|x86.Build.0 = Debug|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|Any CPU.Build.0 = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|x86.ActiveCfg = Release|Any CPU + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -566,10 +628,17 @@ Global {A48D9069-D569-4110-9252-A10F139B669B} = {F8CE2712-826B-450B-A72F-D32D80C99858} {E8AEFBF9-0113-4FA4-BE45-6CDA555498B7} = {F8CE2712-826B-450B-A72F-D32D80C99858} {27D9800E-2689-4AA1-A2D6-128E4A9BAE98} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {AAA3A0F7-2990-4C44-BAC7-0C4BAA053E8A} = {C12F6C91-460E-4C66-9572-D4D5AB169DF9} {E952792F-B9F0-450C-B0D8-3128DF95EF19} = {F8CE2712-826B-450B-A72F-D32D80C99858} {0ED020FF-D28E-4791-BBDD-B8B9BA714096} = {E952792F-B9F0-450C-B0D8-3128DF95EF19} {BD902586-E0D5-407A-904A-32249B8B709E} = {F8CE2712-826B-450B-A72F-D32D80C99858} {F10A5330-DCF4-4533-877C-7B1B1BE23884} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {C12F6C91-460E-4C66-9572-D4D5AB169DF9} = {BB6973BA-B3A2-4B31-A986-7CB008F22C4F} + {E51C8CE6-9785-4666-9CD2-BADB728933E3} = {C12F6C91-460E-4C66-9572-D4D5AB169DF9} + {D38A21E0-1D61-4905-82B3-1800E1991D57} = {AAA3A0F7-2990-4C44-BAC7-0C4BAA053E8A} + {431AA1A0-81B9-4D93-9CB1-219BDF7825C9} = {E51C8CE6-9785-4666-9CD2-BADB728933E3} + {81FE2BAA-D100-4596-A392-F03BBE30F829} = {C12F6C91-460E-4C66-9572-D4D5AB169DF9} + {DFF88E9F-AFB3-4986-84FE-77F8A04CB6F0} = {C12F6C91-460E-4C66-9572-D4D5AB169DF9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {68E993E6-EE86-4DDF-B0A1-4FE884F8AC39} diff --git a/PascalABCNETLinux.sln b/PascalABCNETLinux.sln index e845977f9..fcd9beb60 100644 --- a/PascalABCNETLinux.sln +++ b/PascalABCNETLinux.sln @@ -63,6 +63,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageIntegrator", "Langu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PascalABCLanguageInfo", "PascalABCLanguageInfo\PascalABCLanguageInfo.csproj", "{BD902586-E0D5-407A-904A-32249B8B709E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LanguagePlugins", "LanguagePlugins", "{36D591C7-65C7-A0D1-1CBC-10CDE441BDC8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SPython", "SPython", "{D71D6350-AEE9-491F-A99E-9A2D00071020}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SemanticAnalyzers", "SemanticAnalyzers", "{9D2B6297-A896-40D0-BEED-2D28C2DE9A4D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SyntaxTreeConverters", "SyntaxTreeConverters", "{C4104880-9AC0-42F5-9962-D0C3FD143139}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonSyntaxTreeVisitor", "LanguagePlugins\SPython\SemanticAnalyzers\SPythonSyntaxTreeVisitor\SPythonSyntaxTreeVisitor.csproj", "{26DB8340-9A8F-16E1-6E6D-D59E97D05142}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonLanguageInfo", "LanguagePlugins\SPython\SPythonLanguageInfo\SPythonLanguageInfo.csproj", "{15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonStandardTreeConverter", "LanguagePlugins\SPython\SyntaxTreeConverters\SPythonStandardTreeConverter\SPythonStandardTreeConverter.csproj", "{6883EC33-B9FD-6D48-B0C3-16F451552C9F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonParser", "LanguagePlugins\SPython\SPythonParserKrylovMovchan\SPythonParser.csproj", "{CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -329,6 +345,54 @@ Global {BD902586-E0D5-407A-904A-32249B8B709E}.Release|Mixed Platforms.Build.0 = Release|Any CPU {BD902586-E0D5-407A-904A-32249B8B709E}.Release|x86.ActiveCfg = Release|Any CPU {BD902586-E0D5-407A-904A-32249B8B709E}.Release|x86.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|x86.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|x86.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Any CPU.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|x86.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|x86.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|x86.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Any CPU.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|x86.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|x86.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|x86.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Any CPU.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|x86.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|x86.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|x86.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|x86.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Any CPU.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|x86.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -360,6 +424,14 @@ Global {E8AEFBF9-0113-4FA4-BE45-6CDA555498B7} = {F8CE2712-826B-450B-A72F-D32D80C99858} {A48D9069-D569-4110-9252-A10F139B669B} = {F8CE2712-826B-450B-A72F-D32D80C99858} {BD902586-E0D5-407A-904A-32249B8B709E} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {36D591C7-65C7-A0D1-1CBC-10CDE441BDC8} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {D71D6350-AEE9-491F-A99E-9A2D00071020} = {36D591C7-65C7-A0D1-1CBC-10CDE441BDC8} + {9D2B6297-A896-40D0-BEED-2D28C2DE9A4D} = {D71D6350-AEE9-491F-A99E-9A2D00071020} + {C4104880-9AC0-42F5-9962-D0C3FD143139} = {D71D6350-AEE9-491F-A99E-9A2D00071020} + {26DB8340-9A8F-16E1-6E6D-D59E97D05142} = {9D2B6297-A896-40D0-BEED-2D28C2DE9A4D} + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F} = {D71D6350-AEE9-491F-A99E-9A2D00071020} + {6883EC33-B9FD-6D48-B0C3-16F451552C9F} = {C4104880-9AC0-42F5-9962-D0C3FD143139} + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446} = {D71D6350-AEE9-491F-A99E-9A2D00071020} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {68E993E6-EE86-4DDF-B0A1-4FE884F8AC39} diff --git a/bin/Highlighting/SPython.xshd b/bin/Highlighting/SPython.xshd new file mode 100644 index 000000000..36516cc97 --- /dev/null +++ b/bin/Highlighting/SPython.xshd @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + &<>~!%^*()-+=|\#/{}[]:;"' , .? + + + # + + + + ''' + ''' + + + + """ + """ + + + + ' + ' + + + + " + " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <>~!@%^*()-+=|\#/{}[]:;"' , .? + + + + + + + + + + + + diff --git a/bin/Lib/SPythonHidden.pas b/bin/Lib/SPythonHidden.pas new file mode 100644 index 000000000..c1a5cafa4 --- /dev/null +++ b/bin/Lib/SPythonHidden.pas @@ -0,0 +1,25 @@ +{$HiddenIdents} +unit SPythonHidden; + +interface + +// uses PABCSystem; + +function !Floor(x : real) : integer; + +function !FloorDiv(x: real; y: real): integer; + +function !FloorMod(x: real; y: real): real; + +type !UnknownType = class +end; + +implementation + +function !Floor(x : real) : integer := PABCSystem.Floor(x); + +function !FloorDiv(x: real; y: real): integer := PABCSystem.Floor(x / y); + +function !FloorMod(x: real; y: real): real := x - PABCSystem.Floor(x / y) * y; + +end. \ No newline at end of file diff --git a/bin/Lib/SPythonSystem.pas b/bin/Lib/SPythonSystem.pas new file mode 100644 index 000000000..78b560630 --- /dev/null +++ b/bin/Lib/SPythonSystem.pas @@ -0,0 +1,561 @@ +{$HiddenIdents} +unit SPythonSystem; + +{$reference '%GAC%\System.dll'} +{$reference '%GAC%\mscorlib.dll'} +{$reference '%GAC%\System.Core.dll'} +{$reference '%GAC%\System.Numerics.dll'} + +interface + +// uses PABCSystem; + +// Basic IO methods + +function input(): string; + +function input(s: string): string; + +type kwargs_gen = class + public !kwargs: Dictionary + := new Dictionary(); + + constructor Create( + keys: array of string; + params values: array of T + ); + begin + for var i := 0 to keys.count() - 1 do + !kwargs[keys[i]] := values[i]; + end; + + constructor Create( + keys: array of char; + params values: array of T + ); + begin + for var i := 0 to keys.count() - 1 do + !kwargs[keys[i]] := values[i]; + end; + + constructor Create(); begin end; + end; + +function all(s: sequence of boolean): boolean; +function any(s: sequence of boolean): boolean; + +function __NewSetCreatorInternal(params a: array of T): NewSet; + +procedure clear(var st: set of T); + +function int(val: string): integer; + +function int(val: real): integer; + +function round(val: real): integer; + +function split(s: string): sequence of string; + +function get_keys(dct: Dictionary): sequence of K; +function get_values(dct: Dictionary): sequence of V; + +function &type(obj: object): string; + +//function int(val: string): integer; +function int(b: boolean): integer; + +function str(val: object): string; + +function float(val: string): real; + +function float(x: integer): real; + +// Basic sequence functions + +function range(s: integer; e: integer; step: integer): sequence of integer; + +function range(e: integer): sequence of integer; + +function range(s: integer; e: integer): sequence of integer; + +function !format(obj: object; fmt: string): string; + +function !format(i: integer; fmt: string): string; + +function !format(val: real; fmt: string): string; + +//function all(seq: sequence of T): boolean; + +//function any(seq: sequence of T): boolean; + +// Standard Math functions + +function abs(x: integer): integer; + +function abs(x: real): real; + +// function floor(x: real): real; + +//Standard functions with Lists + +function len(lst: PABCSystem.List): integer; +function len(st: set of T): integer; +function len(dct: PABCSystem.Dictionary): integer; +function len(arr: array of T): integer; +function len(s: string): integer; + +function &set(sq: sequence of T): set of T; +function &list(sq: sequence of T): PABCSystem.List; + +function sorted(lst: PABCSystem.List): PABCSystem.List; + +function sum(lst: sequence of integer): integer; + +function sum(lst: sequence of real): real; + +function !assign(var a: T; b: T): T; + +function !pow(x, n: integer): integer; + +function !pow(x, n: biginteger): biginteger; + +function !pow(x: integer; y: real): real; + +function !pow(x: real; y: real): real; + +function bigint(x: integer): biginteger; + +function !pow_recursion(x, n: integer): integer; + +function !pow_recursion(x, n: biginteger): biginteger; + +// TUPLES BEGIN +function CreateTuple( + v1: T1; v2: T2 + ): System.Tuple; + +function CreateTuple( + v1: T1; v2: T2; v3: T3 + ): System.Tuple; + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4 + ): System.Tuple; + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5 + ): System.Tuple; + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6 + ): System.Tuple; + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7 + ): System.Tuple; + +// TUPLES END + +function Dict(params pairs: array of (TKey, TVal)): Dictionary; + +type + biginteger = PABCSystem.BigInteger; + !list = PABCSystem.List; + !dict = PABCSystem.Dictionary; + !set = set of T; + tuple2 = System.Tuple; + tuple3 = System.Tuple; + tuple4 = System.Tuple; + tuple5 = System.Tuple; + tuple6 = System.Tuple; + tuple7 = System.Tuple; + + empty_list = class + class function operator implicit(x: empty_list): !list; + begin + Result := new !list(); + end; + end; + + empty_set = class + class function operator implicit(x: empty_set): !set; + begin + Result := new !set; + end; + end; + + empty_dict = class + class function operator implicit(x: empty_dict): !dict; + begin + Result := new !dict(); + end; + end; + + +function !empty_list(): empty_list; +function !empty_dict(): empty_dict; +function &set(): empty_set; + +implementation + +function input(): string; +begin + PABCSystem.Print(); + Result := PABCSystem.ReadlnString(); +end; + +function input(s: string): string; +begin + PABCSystem.Print(s); + Result := PABCSystem.ReadlnString(); +end; + +function int(val: string): integer := integer.Parse(val); + +function int(val: real): integer := round(val); + +function int(b: boolean): integer; +begin + if b then + Result := 1 + else + Result := 0; +end; + +function &type(obj: object): string; +begin + Result := TypeName(obj) + .Replace('<', '[') + .Replace('>', ']') + .Replace('List', 'list') + .Replace('Tuple', 'tuple') + .Replace('Dictionary', 'dict') + .Replace('empty_list', 'list[anytype]') + .Replace('empty_set', 'set[anytype]') + .Replace('empty_dict', 'dict[anytype]') + .Replace('integer', 'int') + .Replace('string', 'str') + .Replace('real', 'float') + .Replace('boolean', 'bool') + .Replace('System.Numerics.BigInteger', 'bigint'); +end; + +function int(obj: object): integer := Convert.ToInt32(obj); + +function str(val: object): string := val.ToString(); + +function float(val: string): real := real.Parse(val); + +function float(x: integer): real := PABCSystem.Floor(x); + +function range(s: integer; e: integer; step: integer): sequence of integer; +begin + Result := PABCSystem.Range(s, e - 1, step); +end; + +function range(s: integer; e: integer): sequence of integer; +begin + Result := PABCSystem.Range(s, e - 1); +end; + +function range(e: integer): sequence of integer; +begin + Result := PABCSystem.Range(0, e - 1); +end; + +//function all(seq: sequence of T): boolean := seq.All(x -> x); + +//function any(seq: sequence of T): boolean := seq.Any(x -> x); + +function abs(x: integer): integer := if x >= 0 then x else -x; + +function abs(x: real): real := PABCSystem.Abs(x); + +function len(lst: PABCSystem.List): integer := lst.Count(); +function len(st: set of T): integer := st.Count(); +function len(dct: PABCSystem.Dictionary): integer := dct.Count(); +function len(arr: array of T): integer := arr.Count(); +function len(s: string): integer := s.Length; + +function sorted(lst: PABCSystem.List): PABCSystem.List; +begin + var new_list := new PABCSystem.List(lst); + new_list.sort(); + Result := new_list; +end; + +function sum(lst: sequence of integer): integer := lst.sum(); +function sum(lst: sequence of real): real := lst.sum(); + +function !assign(var a: T; b: T): T; +begin + a := b; + Result := a; +end; + +function !pow(x, n: biginteger): biginteger; +begin + if (n < 0) then + raise new System.ArgumentException('возведение в степень не работает для целой отрицательной степени типа bigint.'); + Result := !pow_recursion(x, n); +end; + +function !pow_recursion(x, n: biginteger): biginteger; +begin + + if (n = 0) then + Result := 1 + else begin + Result := !pow_recursion(x, n div 2); + Result *= Result; + if ((n mod 2) = 1) then + Result *= x; + end; +end; + +function !pow(x, n: integer): integer; +begin + if (n < 0) then + raise new System.ArgumentException('возведение в степень не работает для целой отрицательной степени, используйте привидение к типу с плавающей точкой.'); + Result := !pow_recursion(x, n); +end; + +function !pow(x: integer; y: real): real := Power(x, y); + +function !pow(x: real; y: real): real := Power(x, y); + +function !pow_recursion(x, n: integer): integer; +begin + + if (n = 0) then + Result := 1 + else begin + Result := !pow_recursion(x, n div 2); + Result *= Result; + if ((n mod 2) = 1) then + Result *= x; + end; +end; + +function bigint(x: integer): biginteger; +begin + Result := x; +end; + +function !count(Self: PABCSystem.List; val: T): integer; extensionmethod; +begin + Result := 0; + for var i := 0 to Self.Count - 1 do + if val = Self[i] then + Result += 1; +end; + +function pop(Self: PABCSystem.List; ind: integer): T; extensionmethod; +begin + Result := Self[ind]; + Self.RemoveAt(ind); +end; + +procedure add(Self: set of T; val: T); extensionmethod; +begin + Self += val; +end; + +procedure remove(Self: set of T; val: T); extensionmethod; +begin + Self -= val; +end; + +function get_keys(dct: Dictionary):= dct.keys; +function get_values(dct: Dictionary):= dct.values; + +function copy(Self: set of T): set of T; extensionmethod; +begin + Result := Self; +end; + +procedure clear(var st: set of T); +begin + st := []; +end; + +function __NewSetCreatorInternal(params a: array of T): NewSet; +begin + //Result._hs := new HashSet; + Result._hs.UnionWith(a); +end; + +// TUPLES BEGIN +function CreateTuple( + v1: T1; v2: T2 + ): System.Tuple + := (v1, v2); + +function CreateTuple( + v1: T1; v2: T2; v3: T3 + ): System.Tuple + := (v1, v2, v3); + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4 + ): System.Tuple + := (v1, v2, v3, v4); + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5 + ): System.Tuple + := (v1, v2, v3, v4, v5); + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6 + ): System.Tuple + := (v1, v2, v3, v4, v5, v6); + +function CreateTuple( + v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7 + ): System.Tuple + := (v1, v2, v3, v4, v5, v6, v7); + +// TUPLES END + +function Dict(params pairs: array of (TKey, TVal)): Dictionary; +begin + Result := new Dictionary(); + for var i := 0 to pairs.Length - 1 do + Result.Add(pairs[i][0], pairs[i][1]); +end; + +function &set(sq: sequence of T): set of T; +begin + foreach var e in sq do + Result.Add(e); +end; + +function &list(sq: sequence of T): PABCSystem.List := sq.ToList(); + +function all(s: sequence of boolean): boolean; +begin + Result := true; + foreach var elem in s do + if (not elem) then + begin + Result := false; + break; + end; +end; + +function any(s: sequence of boolean): boolean; +begin + Result := false; + foreach var elem in s do + if (elem) then + begin + Result := true; + break; + end; +end; + +function ToDictionary(Self: sequence of System.tuple): Dictionary; extensionmethod; +begin + Result := Self.ToDictionary(x->x[0],x->x[1]); +end; + +function !empty_list(): empty_list := new empty_list(); +function !empty_dict(): empty_dict := new empty_dict(); +function &set(): empty_set := new empty_set; + +function round(val: real): integer := PABCSystem.round(val); + +function split(s: string): sequence of string; +begin + var temp := ''; + var i := 0; + + while i <= s.Length - 1 do + begin + if (i <= s.Length - 1) and (s.Substring(i, 1) = ' ') then + begin + yield temp; + temp := ''; + i += 1; + end + else + begin + temp += s[i]; + i += 1; + end; + end; + + yield temp; +end; + +function !format(i: integer; fmt: string): string; +begin + if ((fmt.ToLower() = 'x') or (fmt = 'b') or (fmt = 'd')) then + begin + var HexChars := '0123456789abcdef'; + if (fmt = 'X') then + HexChars := HexChars.ToUpper(); + var value := Cardinal(i); + var radix := 10; + if (fmt.ToLower() = 'x') then radix := 16; + if (fmt = 'b') then radix := 2; + if value = 0 then + begin + Result := '0'; + Exit; + end; + + while value > 0 do + begin + var digit := value mod radix; + Result := HexChars[digit + 1] + Result; + value := value div radix; + end; + Exit; + end; + if (fmt[1] = '.') then + begin + Result := !format(i + 0.0, fmt); + Exit; + end; + raise new System.ArgumentException('Неверный формат для целочисленного аргумента'); +end; + +function !format(val: real; fmt: string): string; +begin + var digits: integer; + if (fmt.Length >= 3) and (fmt[1] = '.') and (fmt.EndsWith('f')) then + begin + var numStr := fmt.Substring(1, fmt.Length - 2); + if TryStrToInt(numStr, digits) then + begin + var intPart := Trunc(val); + if (digits = 0) then + begin + Result := intPart.ToString; + Exit; + end; + var frac := Abs(val - intPart); + + var fracPart := Round(frac * Power(10, digits)); + + var fracStr := fracPart.ToString; + while fracStr.Length < digits do + fracStr := '0' + fracStr; + + Result := intPart.ToString + '.' + fracStr; + Exit; + end; + end; + + raise new System.ArgumentException('Неверный формат для вещественного аргумента'); +end; + +function !format(obj: object; fmt: string): string; +begin + Result := ''; + raise new System.ArgumentException('Формат не соответствует типу данных выражения в f-строке'); +end; + +end. \ No newline at end of file diff --git a/bin/Lib/SPythonSystemPys.pys b/bin/Lib/SPythonSystemPys.pys new file mode 100644 index 000000000..8e3a39431 --- /dev/null +++ b/bin/Lib/SPythonSystemPys.pys @@ -0,0 +1,18 @@ +from PABCSystem import Object as obj, Write as pas_print +from SPythonSystem import range, len + +def print(*args: obj, **kwargs: str): + sep: str = ' ' + end: str = '\n' + if 'sep' in kwargs.keys(): + sep = kwargs['sep'] + if 'end' in kwargs.keys(): + end = kwargs['end'] + + for i in range(0, len(args) - 1): + pas_print(args[i]) + pas_print(sep) + + if len(args) != 0: + pas_print(args[len(args) - 1]) + pas_print(end) \ No newline at end of file diff --git a/bin/Lib/itertools.pys b/bin/Lib/itertools.pys new file mode 100644 index 000000000..488fae2a9 --- /dev/null +++ b/bin/Lib/itertools.pys @@ -0,0 +1,32 @@ +# объединяет списки целых в один +def chain(*args: list[int]) -> list[int]: + sz = 0 + for arg in args: + sz += len(arg) + + res = [0 for i in range(sz)] + i = 0 + for arg in args: + for j in range(len(arg)): + res[i] = arg[j] + i += 1 + return res + +# если вызвать как repeat(10, times=12) +def repeat(val: int, **kwargs: int) -> list[int]: + times = 1 + if 'times' in kwargs.keys(): + times = kwargs['times'] + return [val for i in range(times)] + +# если вызвать как repeat(10, 12) +def repeat(val: int, times: int) -> list[int]: + return repeat(val, times=times) + # можно просто так + # return [val for i in range(times)] + + +# просто функция, чтобы показать как итерироваться по kwargs +def print_int_kwargs(**kwargs: int): + for key, value in kwargs: + print(f'kwargs[{key}] = {value}') \ No newline at end of file diff --git a/bin/Lib/math.pys b/bin/Lib/math.pys new file mode 100644 index 000000000..99d6d8cce --- /dev/null +++ b/bin/Lib/math.pys @@ -0,0 +1,99 @@ +import PABCSystem + +pi = 3.14 + +def sqrt(x: float) -> float: + return PABCSystem.sqrt(x) + +def trunc(x: float) -> int: + return PABCSystem.trunc(x) + +def floor(x: float) -> int: + return PABCSystem.floor(x) + +def ceil(x: float) -> int: + return PABCSystem.ceil(x) + +def log(x: float) -> float: + return PABCSystem.Log(x) + +def log1p(x: float) -> float: + return PABCSystem.Log(1+ x) + +def log2(x: float) -> float: + return PABCSystem.Log2(x) + +def log10(x: float) -> float: + return PABCSystem.Log10(x) + +def log(x: float, base: int) -> float: + return PABCSystem.LogN(base, x) + +def exp(x: float) -> float: + return PABCSystem.exp(x) + +def expm1(x: float) -> float: + return PABCSystem.exp(x - 1) + +def exp2(x: float) -> float: + return PABCSystem.exp(log(2) * x) + +def sin(x: float) -> float: + return PABCSystem.sin(x) + +def sinh(x: float) -> float: + return PABCSystem.sinh(x) + +def cos(x: float) -> float: + return PABCSystem.cos(x) + +def cosh(x: float) -> float: + return PABCSystem.cosh(x) + +def tan(x: float) -> float: + return PABCSystem.tan(x) + +def tanh(x: float) -> float: + return PABCSystem.tanh(x) + +def acos(x: float) -> float: + return PABCSystem.arccos(x) + +def asin(x: float) -> float: + return PABCSystem.arcsin(x) + +def atan(x: float) -> float: + return PABCSystem.arctan(x) + +def atan2(y: float, x: float) -> float: + return PABCSystem.arctan(y / x) + +def pow(x: float, y: int) -> float: + return PABCSystem.power(x, y) + +def cbrt(x: float) -> float: + return pow(x, 1/3) + +def fabs(x: float) -> float: + return PABCSystem.abs(x) + +def pow(x: float, y: float) -> float: + return PABCSystem.power(x, y) + +def isqrt(x: int) -> int: + return floor(sqrt(x)) + +def remainder(x: int, y: int) -> int: + return x - (x // y) * y + +def factorial(n: int) -> int: + if n == 0: + return 1 + return n * factorial(n - 1) + +def perm(n: int, k: int) -> int: + return factorial(n) // factorial(n - k) + +def comb(n: int, k: int) -> int: + return perm(n, k) // factorial(k) + diff --git a/bin/Lng/Eng/SPythonParser.dat b/bin/Lng/Eng/SPythonParser.dat new file mode 100644 index 000000000..4b73fa0e4 --- /dev/null +++ b/bin/Lng/Eng/SPythonParser.dat @@ -0,0 +1,34 @@ +%PREFIX%=SPYTHONPARSER_ +FOUND{0}=Found {0} but +FOUNDM{0}=Found {0} but +FOUNDEOF=Found end of file but +EXPECTED{0}=Expected {0} +EXPECTED{1}=expected {1} +EXPECTEDR{1}=expected {1} +EXPECTEDF{1}=expected {1} +GLOBAL_VAR_{0}_SIM_PARAMETER=global variable name {0} is the same as parameter name +USING_VARIABLE_{0}_BEFORE_ASSIGNMENT=Variable {0} used before declaration +NO_GLOBAL_VAR_{0}=Unknown global name {0} +WRONG_INDENT=Indent does not match any block of code +PROGRAM_BEGIN_WITH_INDENT=Program can not begin with indent +UNEXPECTED_TOKEN_{0}=Unknown symbol {0} +UNSUPPORTED_CONSTRUCTION_{0}=Construction {0} is not support in current compiler version +LINE_WITHOUT_INDENT=Expected code block with indent +ILL_FORMED_FSTRING_{0}=Wrong f-string format {0} +FSTRING_UNNKOWN_FORMAT_{0}=Unknown format {0} +FSTRING_NESTED_EXPRESSION_{0}_PARSING_FAILURE=Expression '{0}' has an error + +IDENTIFIER=identifier +EOF1=end of file +EOL=end of line +STRINGNUM=string constant +INTNUM=integer +REALNUM=float +#{=indent +#}=end of indent +#$=end of file +#;=end of line + + +EXPR=expression +STMT=statement \ No newline at end of file diff --git a/bin/Lng/Eng/SPythonSemantic.dat b/bin/Lng/Eng/SPythonSemantic.dat new file mode 100644 index 000000000..7ffba1ad9 --- /dev/null +++ b/bin/Lng/Eng/SPythonSemantic.dat @@ -0,0 +1,4 @@ +%PREFIX%=SPYTHONSEMANTIC_ +NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}=Operation {0} is not supported for types {1} and {2} +FUNCTION_{0}_NO_RETURN=Function {0} does not return a value +TYPE_{0}_HAS_NO_{1}_METHOD=Type {0} does not have method {1} \ No newline at end of file diff --git a/bin/Lng/Eng/SPythonSyntaxTreeVisitorErrors.dat b/bin/Lng/Eng/SPythonSyntaxTreeVisitorErrors.dat new file mode 100644 index 000000000..3f6cc0b80 --- /dev/null +++ b/bin/Lng/Eng/SPythonSyntaxTreeVisitorErrors.dat @@ -0,0 +1,23 @@ +// Syntax tree conversion errors +%PREFIX%=SPYTHONSYNTAXTREEVISITORSERROR_ + +UNKNOWN_NAME_{0}=Unknown name '{0}' +MODULE_{0}_HAS_NO_NAME_{1}=Module '{0}' does not contains name '{1}' +SCOPE_CONTAINS_NAME_{0}=Name '{0}' is already in current scope +ARG_AFTER_KWARGS=Unnamed argument can not be after named one +PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}=Unknown type '{0}'. Maybe you meant '{1}' +LOCAL_IMPORT_USE=Current compile version supports 'import ...' only on outerscope +LOCAL_FROM_IMPORT_USE=Current compile version supports 'from ... import ...' only on global level +LOCAL_FUNCTION_DECLARATION=Current compile version supports function declaration on global level +GLOBAL_NOT_IN_FUNCTION=Construction 'global ...' may be used only inside a function +GLOBAL_IN_NOT_OUTERMOST_BLOCK=Construction 'global ...' is supported only on function outerscope +FUNCTION_{0}_USED_BEFORE_DECLARATION=Function '{0}' is declared later; its use before declaration is allowed only inside other functions +RETURN_NOT_RETURN_VALUE=The function must return a value +RETURN_HAS_RETURN_VALUE=The function must not return a value +RETURN_NOT_IN_FUNCTION='return ...' statement must be inside a function +IMPOSSIBLE_TO_INFER_LIST_TYPE=Cannot infer the type of the list +IMPOSSIBLE_TO_INFER_SET_TYPE=Cannot infer the type of the set +IMPOSSIBLE_TO_INFER_DICT_TYPE=Cannot infer the type of the dictionary +KWARG_PARAMETOR_NOT_LAST=Keyword argument parameter must be the last one +LONG_TUPLE_TYPENAME=Tuple size should be less than or equal to seven +LEFT_SIZE_TUPLE_ASSIGNMENT_LESS_THAN_RIGHT=Tuple assignment must have the same number of elements on both sides \ No newline at end of file diff --git a/bin/Lng/Rus/SPythonParser.dat b/bin/Lng/Rus/SPythonParser.dat new file mode 100644 index 000000000..f6f889324 --- /dev/null +++ b/bin/Lng/Rus/SPythonParser.dat @@ -0,0 +1,34 @@ +%PREFIX%=SPYTHONPARSER_ +FOUND{0}=Встречено {0}, а +FOUNDM{0}=Встречен {0}, а +FOUNDEOF=Встречен конец файла, а +EXPECTED{0}=Ожидалось {0} +EXPECTED{1}=ожидалось {1} +EXPECTEDR{1}=ожидался {1} +EXPECTEDF{1}=ожидалась {1} +GLOBAL_VAR_{0}_SIM_PARAMETER=имя глобальной переменной {0} совпадает с именем параметра функции +USING_VARIABLE_{0}_BEFORE_ASSIGNMENT=Использование переменной {0} до объявления +NO_GLOBAL_VAR_{0}=Неизвестная глобальная переменная {0} +WRONG_INDENT=Отступ не соответствует ни одному из блоков кода +PROGRAM_BEGIN_WITH_INDENT=Программа не может начинаться с отступа +UNEXPECTED_TOKEN_{0}=Неизвестный символ {0} +UNSUPPORTED_CONSTRUCTION_{0}=Конструкция {0} не поддерживается текущей версией компилятора +LINE_WITHOUT_INDENT=Ожидалось начало блока кода с отступом +ILL_FORMED_FSTRING_{0}=Неверный формат строки {0} +FSTRING_UNNKOWN_FORMAT_{0}=Неизвестный формат {0} +FSTRING_NESTED_EXPRESSION_{0}_PARSING_FAILURE=Ошибка в выражении '{0}' + +IDENTIFIER=идентификатор +EOF1=конец файла +EOL=конец строки +STRINGNUM=строковая константа +INTNUM=целое число +REALNUM=вещественное число +#{=отступ +#}=конец отступа +#$=конец файла +#;=конец строки + + +EXPR=выражение +STMT=оператор \ No newline at end of file diff --git a/bin/Lng/Rus/SPythonSyntaxTreeVisitorErrors.dat b/bin/Lng/Rus/SPythonSyntaxTreeVisitorErrors.dat new file mode 100644 index 000000000..be39e6f76 --- /dev/null +++ b/bin/Lng/Rus/SPythonSyntaxTreeVisitorErrors.dat @@ -0,0 +1,23 @@ +// Syntax tree conversion errors +%PREFIX%=SPYTHONSYNTAXTREEVISITORSERROR_ + +UNKNOWN_NAME_{0}=Неизвестное имя '{0}' +MODULE_{0}_HAS_NO_NAME_{1}=В модуле '{0}' не объявлено имя '{1}' +SCOPE_CONTAINS_NAME_{0}=Имя '{0}' присутствует в текущем пространстве имён +ARG_AFTER_KWARGS=После именованного аргумента может идти только именованный аргумент +PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}=Неизвестный тип '{0}', возможно Вы имели в виду '{1}' +LOCAL_IMPORT_USE=В текущей версии компилятора конструкция 'import ...' допустима только на глобальном уровне +LOCAL_FROM_IMPORT_USE=В текущей версии компилятора конструкция 'from ... import ...' допустима только на глобальном уровне +LOCAL_FUNCTION_DECLARATION=В текущей версии компилятора объявление функции допустимо только на глобальном уровне +GLOBAL_NOT_IN_FUNCTION=конструкция 'global ...' допустима только внутри функции +GLOBAL_IN_NOT_OUTERMOST_BLOCK=конструкция 'global ...' недопустима во вложенном блоке кода +FUNCTION_{0}_USED_BEFORE_DECLARATION='{0}' объявлена позже как функция, её использование до объявления допустимо только в теле других функций +RETURN_NOT_RETURN_VALUE=Функция должна возвращать значение +RETURN_HAS_RETURN_VALUE=Попытка вернуть значение из функции, у которой не указан тип возвращаемого значения +RETURN_NOT_IN_FUNCTION=Конструкция 'return ...' должна быть внутри функции +IMPOSSIBLE_TO_INFER_LIST_TYPE=Нельзя вычислить тип списка +IMPOSSIBLE_TO_INFER_SET_TYPE=Нельзя вычислить тип множества +IMPOSSIBLE_TO_INFER_DICT_TYPE=Нельзя вычислить тип словаря +KWARG_PARAMETOR_NOT_LAST=kwarg-параметр должен быть последним в списке параметров +LONG_TUPLE_TYPENAME=Размер кортежа не может быть больше семи +LEFT_SIZE_TUPLE_ASSIGNMENT_LESS_THAN_RIGHT=Количество переменных в левой части кортежного присваивания должно совпадать с размером кортежа в правой части \ No newline at end of file diff --git a/bin/Lng/Rus/SpythonSemantic.dat b/bin/Lng/Rus/SpythonSemantic.dat new file mode 100644 index 000000000..6376ff2a3 --- /dev/null +++ b/bin/Lng/Rus/SpythonSemantic.dat @@ -0,0 +1,4 @@ +%PREFIX%=SPYTHONSEMANTIC_ +NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}=Операция {0} неприменима к типам {1} и {2} +FUNCTION_{0}_NO_RETURN=Функция {0} не возвращает значение +TYPE_{0}_HAS_NO_{1}_METHOD=В типе {0} не определён метод {1} \ No newline at end of file diff --git a/pabcnetc.sln b/pabcnetc.sln index 99a29d3d7..f2155001b 100644 --- a/pabcnetc.sln +++ b/pabcnetc.sln @@ -45,8 +45,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTreeConverters", "Syn EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxVisitors", "SyntaxVisitors\SyntaxVisitors.csproj", "{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldConversionSyntax", "Yield\YieldConversionSyntax\YieldConversionSyntax.csproj", "{276EE073-60F6-46D2-8811-1B8026BCAADA}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LambdaAnySynToSemConverter", "LambdaAnySynToSemConverter\LambdaAnySynToSemConverter.csproj", "{27D9800E-2689-4AA1-A2D6-128E4A9BAE98}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PascalABCLanguageInfo", "PascalABCLanguageInfo\PascalABCLanguageInfo.csproj", "{BD902586-E0D5-407A-904A-32249B8B709E}" @@ -55,6 +53,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringConstants", "StringCo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageIntegrator", "LanguageIntegrator\LanguageIntegrator.csproj", "{A48D9069-D569-4110-9252-A10F139B669B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LanguagePlugins", "LanguagePlugins", "{36D591C7-65C7-A0D1-1CBC-10CDE441BDC8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SPython", "SPython", "{DFCE8D21-EF89-4922-B662-65CF93E0F61B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SemanticAnalyzers", "SemanticAnalyzers", "{571693BE-5B2B-4383-BDD8-130ABDCC0B3A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SyntaxTreeConverters", "SyntaxTreeConverters", "{D7D9CC20-E09F-4FBC-8EEE-9FAB8406FCBB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonSyntaxTreeVisitor", "LanguagePlugins\SPython\SemanticAnalyzers\SPythonSyntaxTreeVisitor\SPythonSyntaxTreeVisitor.csproj", "{26DB8340-9A8F-16E1-6E6D-D59E97D05142}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonStandardTreeConverter", "LanguagePlugins\SPython\SyntaxTreeConverters\SPythonStandardTreeConverter\SPythonStandardTreeConverter.csproj", "{6883EC33-B9FD-6D48-B0C3-16F451552C9F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonLanguageInfo", "LanguagePlugins\SPython\SPythonLanguageInfo\SPythonLanguageInfo.csproj", "{15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPythonParser", "LanguagePlugins\SPython\SPythonParserKrylovMovchan\SPythonParser.csproj", "{CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -231,18 +245,6 @@ Global {A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|Mixed Platforms.Build.0 = Release|Any CPU {A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|x86.ActiveCfg = Release|Any CPU {A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|x86.Build.0 = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|x86.ActiveCfg = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|x86.Build.0 = Debug|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Any CPU.Build.0 = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|x86.ActiveCfg = Release|Any CPU - {276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|x86.Build.0 = Release|Any CPU {27D9800E-2689-4AA1-A2D6-128E4A9BAE98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27D9800E-2689-4AA1-A2D6-128E4A9BAE98}.Debug|Any CPU.Build.0 = Debug|Any CPU {27D9800E-2689-4AA1-A2D6-128E4A9BAE98}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -291,6 +293,54 @@ Global {A48D9069-D569-4110-9252-A10F139B669B}.Release|Mixed Platforms.Build.0 = Release|Any CPU {A48D9069-D569-4110-9252-A10F139B669B}.Release|x86.ActiveCfg = Release|Any CPU {A48D9069-D569-4110-9252-A10F139B669B}.Release|x86.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|x86.ActiveCfg = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Debug|x86.Build.0 = Debug|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Any CPU.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|x86.ActiveCfg = Release|Any CPU + {26DB8340-9A8F-16E1-6E6D-D59E97D05142}.Release|x86.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Debug|x86.Build.0 = Debug|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Any CPU.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|x86.ActiveCfg = Release|Any CPU + {6883EC33-B9FD-6D48-B0C3-16F451552C9F}.Release|x86.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Debug|x86.Build.0 = Debug|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Any CPU.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|x86.ActiveCfg = Release|Any CPU + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F}.Release|x86.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|x86.ActiveCfg = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Debug|x86.Build.0 = Debug|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Any CPU.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|x86.ActiveCfg = Release|Any CPU + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -313,11 +363,18 @@ Global {CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09} = {F8CE2712-826B-450B-A72F-D32D80C99858} {F10A5330-DCF4-4533-877C-7B1B1BE23884} = {F8CE2712-826B-450B-A72F-D32D80C99858} {A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2} = {F8CE2712-826B-450B-A72F-D32D80C99858} - {276EE073-60F6-46D2-8811-1B8026BCAADA} = {F8CE2712-826B-450B-A72F-D32D80C99858} {27D9800E-2689-4AA1-A2D6-128E4A9BAE98} = {F8CE2712-826B-450B-A72F-D32D80C99858} {BD902586-E0D5-407A-904A-32249B8B709E} = {F8CE2712-826B-450B-A72F-D32D80C99858} {E8AEFBF9-0113-4FA4-BE45-6CDA555498B7} = {F8CE2712-826B-450B-A72F-D32D80C99858} {A48D9069-D569-4110-9252-A10F139B669B} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {36D591C7-65C7-A0D1-1CBC-10CDE441BDC8} = {F8CE2712-826B-450B-A72F-D32D80C99858} + {DFCE8D21-EF89-4922-B662-65CF93E0F61B} = {36D591C7-65C7-A0D1-1CBC-10CDE441BDC8} + {571693BE-5B2B-4383-BDD8-130ABDCC0B3A} = {DFCE8D21-EF89-4922-B662-65CF93E0F61B} + {D7D9CC20-E09F-4FBC-8EEE-9FAB8406FCBB} = {DFCE8D21-EF89-4922-B662-65CF93E0F61B} + {26DB8340-9A8F-16E1-6E6D-D59E97D05142} = {571693BE-5B2B-4383-BDD8-130ABDCC0B3A} + {6883EC33-B9FD-6D48-B0C3-16F451552C9F} = {D7D9CC20-E09F-4FBC-8EEE-9FAB8406FCBB} + {15D55C2B-37A6-850E-D0CF-74C43CBB9E3F} = {DFCE8D21-EF89-4922-B662-65CF93E0F61B} + {CEEEDB1E-B0E1-283E-13C3-BFE73FE8A446} = {DFCE8D21-EF89-4922-B662-65CF93E0F61B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {761C7A47-891E-47CF-B674-0C2B53D2E48C}