Рефакторинг таблицы символов, чтобы заполнялся только один словарь (#3417)

* Refactor SymbolTable to improve architecture

* Fix PABCSystem function calls in SPython standard modules

* Fix names search in SymbolTable and CollectNamesFromUsedUnits in Compiler

* Add SemanticRulesConstants.SymbolTableCaseSensitive setting in pcu reader

* Fix case sensitive search in DSSymbolTable class

* Add case sensitive search test cases for SPython

* Leave only one dictionary in SymbolsDictionary class

* Refactor Find function in SymbolsDictionary

* Fix math.pys module

* Fix str.pys

* Imrove Find method in SymbolsDictionary

* DefaultIfEmpty was wrong - need to use Any()
This commit is contained in:
Александр Земляк 2026-04-06 22:41:26 +03:00 committed by GitHub
parent 1a787952e9
commit c69daac622
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 218 additions and 201 deletions

View file

@ -2,7 +2,7 @@
import PABCSystem import PABCSystem
def random() -> float: def random() -> float:
return PABCSystem.random() return PABCSystem.Random()
def randint(a: int, b: int) -> int: def randint(a: int, b: int) -> int:
return PABCSystem.random(a, b) return PABCSystem.Random(a, b)

View file

@ -3073,30 +3073,44 @@ namespace PascalABCCompiler
var unitScope = (unit.SemanticTree as common_unit_node).scope; var unitScope = (unit.SemanticTree as common_unit_node).scope;
foreach (var names in unitScope.Symbols.DictCaseSensitive.Skip(1)) // Skip(1) для пропуска имени самого скоупа
foreach (var symbolInfos in unitScope.GetAllSymbolInfos().Skip(1))
{ {
definition_node symInfo = names.Value.InfoList[0].sym_info; // Составляем список отличающихся по регистру в имени символов из InfoList
var distinctNames = new List<TreeConverter.SymbolInfo>();
// Если достаем из pcu, то надо восстановить полную информацию
if (symInfo is wrapped_definition_node wdn) foreach (var symInfo in symbolInfos.InfoList)
{ {
// У некоторых дубликатов sym_info offset не задан, ищем тот, где задан if (distinctNames.Find(info => info.Name == symInfo.Name) == null)
symInfo = names.Value.InfoList.Find(si => ((wrapped_definition_node)si.sym_info).offset > 0)?.sym_info; distinctNames.Add(symInfo);
if (symInfo == null)
continue;
wdn = (wrapped_definition_node)symInfo;
// Если это не синоним типа, то восстанавливаем семантическую информацию
if (!wdn.is_synonim)
symInfo = wdn.PCUReader.CreateInterfaceMember(wdn.offset, names.Key);
} }
currentUnit.NamesFromUsedUnits[unitName].Add(names.Key, foreach (var symInfo in distinctNames)
symInfo.general_node_type == general_node_type.variable_node {
|| symInfo.general_node_type == general_node_type.constant_definition var node = symInfo.sym_info;
|| symInfo.general_node_type == general_node_type.event_node);
// Если достаем из pcu, то надо восстановить полную информацию
if (node is wrapped_definition_node wdn)
{
// У некоторых дубликатов sym_info offset не задан, ищем тот, где задан
node = symbolInfos.InfoList.Find(si => si.Name == symInfo.Name
&& ((wrapped_definition_node)si.sym_info).offset > 0)?.sym_info;
if (node == null)
continue;
wdn = (wrapped_definition_node)node;
// Если это не синоним типа, то восстанавливаем семантическую информацию
if (!wdn.is_synonim)
node = wdn.PCUReader.CreateInterfaceMember(wdn.offset, symInfo.Name);
}
currentUnit.NamesFromUsedUnits[unitName].Add(symInfo.Name,
node.general_node_type == general_node_type.variable_node
|| node.general_node_type == general_node_type.constant_definition
|| node.general_node_type == general_node_type.event_node);
}
} }
} }
} }

View file

@ -279,11 +279,13 @@ namespace PascalABCCompiler.PCU
return null; // return comp.RecompileUnit(file_name); return null; // return comp.RecompileUnit(file_name);
} }
ChangeState(this, PCUReaderWriterState.BeginReadTree, unit); ChangeState(this, PCUReaderWriterState.BeginReadTree, unit);
var unitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
// Задаем регистрозависимость таблицы символов для правильного добавления и поиска
SemanticRulesConstants.SymbolTableCaseSensitive = unitLanguage.CaseSensitive;
cun.scope = new WrappedUnitInterfaceScope(this); cun.scope = new WrappedUnitInterfaceScope(this);
bool unitLanguageCaseSensitive = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName).CaseSensitive;
cun.scope.CaseSensitive = unitLanguageCaseSensitive;
if (string.Compare(unit_name, StringConstants.pascalSystemUnitName, true)==0) if (string.Compare(unit_name, StringConstants.pascalSystemUnitName, true)==0)
PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun); PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun);
@ -292,8 +294,6 @@ namespace PascalABCCompiler.PCU
cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope); cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope);
//\ssyy //\ssyy
cun.implementation_scope.CaseSensitive = unitLanguageCaseSensitive;
string SourceFileName = pcu_file.SourceFileName; string SourceFileName = pcu_file.SourceFileName;
if (Path.GetDirectoryName(SourceFileName) == "") if (Path.GetDirectoryName(SourceFileName) == "")
{ {

View file

@ -1,5 +1,5 @@
s = '123#4\'#\'' #1212 s = '123#4\'#\'' #1212
s.IndexOf('3').print() #12121 s.IndexOf('3').Print() #12121
print(s) #1212 print(s) #1212
if True: if True:
print(2) print(2)

View file

@ -0,0 +1,5 @@
from case_sensitive_names_search_helper import *
from PABCSystem import Assert
Assert(FUNC(0) == 'integer')
Assert(func(0.0) == 'real')

View file

@ -0,0 +1,7 @@
unit case_sensitive_names_search_helper;
function FUNC(a: integer) : string := 'integer';
function func(a: real) : string := 'real';
end.

View file

@ -0,0 +1,5 @@
#!Неизвестное имя 'random'
from PABCSystem import *
print(Random(0))
print(random(0))

View file

@ -0,0 +1,4 @@
#!В модуле 'PABCSystem' не объявлено имя 'random'
from PABCSystem import random as rnd
print(rnd(0))

View file

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using PascalABCCompiler.TreeConverter;
namespace SymbolTable namespace SymbolTable
{ {
@ -12,106 +13,72 @@ namespace SymbolTable
/// </summary> /// </summary>
public class SymbolsDictionary public class SymbolsDictionary
{ {
public override string ToString() => dictCaseInsensitive.SkipWhile(x => x.Key != "").Skip(1).JoinIntoString(Environment.NewLine); public override string ToString() => namesToInfos.SkipWhile(x => x.Key != "").Skip(1).JoinIntoString(Environment.NewLine);
private Dictionary<string, HashTableNode> dictCaseSensitive; // Регистронезависимый словарь символов
private readonly Dictionary<string, HashTableNode> namesToInfos = new Dictionary<string, HashTableNode>(StringComparer.OrdinalIgnoreCase);
public Dictionary<string, HashTableNode> DictCaseSensitive //public SymbolsDictionary(int start_size)
{ //{
get // dictCaseInsensitive = new Dictionary<string, HashTableNode>(start_size, StringComparer.OrdinalIgnoreCase);
{ //}
if (dictCaseSensitive.Count == 0)
{
dictCaseSensitive = new Dictionary<string, HashTableNode>(dictCaseInsensitive);
}
return dictCaseSensitive;
}
}
private Dictionary<string, HashTableNode> dictCaseInsensitive;
public SymbolsDictionary()
{
dictCaseSensitive = new Dictionary<string, HashTableNode>();
dictCaseInsensitive = new Dictionary<string, HashTableNode>(StringComparer.OrdinalIgnoreCase);
}
public SymbolsDictionary(int start_size)
{
dictCaseInsensitive = new Dictionary<string, HashTableNode>(start_size, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Очистка сохраненных символов
/// </summary>
public void ClearTable() public void ClearTable()
{ {
dictCaseSensitive.Clear(); namesToInfos.Clear();
dictCaseInsensitive.Clear();
} }
public HashTableNode Add(string name, bool toCaseSensitive, PascalABCCompiler.TreeConverter.SymbolInfo info) /// <summary>
/// Добавить информацию info о символе с именем name
/// </summary>
public void Add(string name, SymbolInfo info)
{ {
HashTableNode node; bool exists = namesToInfos.TryGetValue(name, out var node);
if (toCaseSensitive) if (!exists)
{ {
bool exists = dictCaseSensitive.TryGetValue(name, out node); node = new HashTableNode();
if (!exists) namesToInfos[name] = node;
{
node = new HashTableNode(name);
dictCaseSensitive[name] = node;
bool existsInInsensitive = dictCaseInsensitive.TryGetValue(name, out var node2);
if (existsInInsensitive)
{
node2.InfoList.Add(info);
}
else
{
var nodeCopy = new HashTableNode(name);
nodeCopy.InfoList.Add(info);
dictCaseInsensitive[name] = nodeCopy;
}
}
}
else
{
bool exists = dictCaseInsensitive.TryGetValue(name, out node);
if (!exists)
{
node = new HashTableNode(name);
dictCaseInsensitive[name] = node;
}
} }
node.InfoList.Add(info); node.InfoList.Add(info);
return node;
} }
public HashTableNode Find(string name, bool inCaseSensitive) /// <summary>
/// Найти информацию о символе с именем name.
/// caseSensitiveSearch определяет регистрозависимость поиска
/// </summary>
public IEnumerable<SymbolInfo> Find(string name, bool caseSensitiveSearch)
{ {
HashTableNode node; // Если ищем регистрозависимо
if (caseSensitiveSearch)
if (inCaseSensitive)
{ {
if (namesToInfos.TryGetValue(name, out var node))
{
// Если есть точные совпадения, то надо взять только их
var infos = node.InfoList.Where(info => info.Name == name);
DictCaseSensitive.TryGetValue(name, out node); if (infos.Any())
return infos;
}
} }
// Если ищем регистронезависимо
else else
{ {
dictCaseInsensitive.TryGetValue(name, out node); if (namesToInfos.TryGetValue(name, out var node))
return node.InfoList;
} }
return node; return null;
} }
/// <summary>
/// Получить информацию обо всех сохраненных символах
/// </summary>
public IEnumerable<HashTableNode> GetAllSymbolInfos() => namesToInfos.Values;
} }
} }

View file

@ -6,7 +6,7 @@ using PascalABCCompiler.TreeConverter;
using System.Collections.Generic; using System.Collections.Generic;
using SymbolTable; using SymbolTable;
using System.Reflection; using System.Reflection;
using PascalABCCompiler.TreeRealization; using static PascalABCCompiler.TreeConverter.SemanticRulesConstants;
namespace PascalABCCompiler.TreeRealization namespace PascalABCCompiler.TreeRealization
{ {
@ -245,7 +245,13 @@ namespace SymbolTable
public void AddSymbol(string Name, SymbolInfo Inf) public void AddSymbol(string Name, SymbolInfo Inf)
{ {
SymbolTable.Add(this, Name, Inf); SymbolTable.Add(this, Name, Inf);
Inf.Name = Name;
} }
/// <summary>
/// Получить информацию обо всех символах скоупа
/// </summary>
public IEnumerable<HashTableNode> GetAllSymbolInfos() => Symbols.GetAllSymbolInfos();
} }
public class BlockScope : Scope public class BlockScope : Scope
@ -472,13 +478,17 @@ namespace SymbolTable
#region HashTableNode элемент хеш-таблицы #region HashTableNode элемент хеш-таблицы
public class HashTableNode public class HashTableNode
{ {
public string Name;
public List<SymbolInfo> InfoList; public List<SymbolInfo> InfoList;
public HashTableNode(string name) public HashTableNode()
{ {
Name = name;
InfoList = new List<SymbolInfo>(SymbolTableConstants.InfoList_StartSize); InfoList = new List<SymbolInfo>(SymbolTableConstants.InfoList_StartSize);
} }
public HashTableNode(List<SymbolInfo> infoList)
{
InfoList = infoList;
}
public override string ToString() public override string ToString()
{ {
System.Text.StringBuilder str = new System.Text.StringBuilder(); System.Text.StringBuilder str = new System.Text.StringBuilder();
@ -596,8 +606,6 @@ namespace SymbolTable
{ {
public List<Scope> ScopeTable; public List<Scope> ScopeTable;
internal bool CaseSensitive;
private Scope CurrentScope; private Scope CurrentScope;
private int ScopeIndex = -1; private int ScopeIndex = -1;
@ -642,9 +650,8 @@ namespace SymbolTable
}*/ }*/
#region DSSymbolTable(int hash_size,bool case_sensitive) #region DSSymbolTable(int hash_size,bool case_sensitive)
public DSSymbolTable(int hash_size,bool case_sensitive) public DSSymbolTable(int hash_size)
{ {
CaseSensitive = case_sensitive;
Clear(); Clear();
} }
#endregion #endregion
@ -720,8 +727,8 @@ namespace SymbolTable
public void Add(Scope InScope, string Name, SymbolInfo Inf) public void Add(Scope InScope, string Name, SymbolInfo Inf)
{ {
Inf.scope = InScope; Inf.scope = InScope;
// if (!InScope.CaseSensitive) Name = Name.ToLower(); InScope.Symbols.Add(Name, Inf);
var hn = InScope.Symbols.Add(Name, InScope.CaseSensitive, Inf);//ЗДЕСЬ ВОЗНИКАЕТ НЕДЕТЕРМЕНИРОВАННАЯ ОШИБКА - SSM 07.10.17 - странный комментарий. Вроде всё нормально.
// SSM 07.10.17 - переделал внутреннее представление HashTable на основе Dictionary // SSM 07.10.17 - переделал внутреннее представление HashTable на основе Dictionary
//if (hn == null) //if (hn == null)
// throw new Exception("Попытка добавить уже добавленное имя " + Name + " в HashTable. Обратитесь к разработчикам"); // throw new Exception("Попытка добавить уже добавленное имя " + Name + " в HashTable. Обратитесь к разработчикам");
@ -745,10 +752,13 @@ namespace SymbolTable
scope.TopScope.InternalScopes.Remove(scope); scope.TopScope.InternalScopes.Remove(scope);
} }
// Пока что считаем, что caseaSensitiveSearch совпадает с SymbolTableCaseSensitive EVA
public List<SymbolInfo> FindOnlyInScope(Scope scope, string Name, bool FindInUpperBlocks) => FindOnlyInScope(scope, Name, FindInUpperBlocks, SymbolTableCaseSensitive);
//Этот метод ищет ТОЛЬКО В УКАЗАННОЙ ОВ, и не смотрит есть ли имя выше. //Этот метод ищет ТОЛЬКО В УКАЗАННОЙ ОВ, и не смотрит есть ли имя выше.
//Если это ОВ типа UnitImplementationScope то имя ищется также и //Если это ОВ типа UnitImplementationScope то имя ищется также и
//в верней ОВ, которая типа UnitInterfaceScope //в верней ОВ, которая типа UnitInterfaceScope
public List<SymbolInfo> FindOnlyInScope(Scope scope, string Name, bool FindInUpperBlocks) public List<SymbolInfo> FindOnlyInScope(Scope scope, string Name, bool FindInUpperBlocks, bool caseSensitiveSearch)
{ {
// if (!scope.CaseSensitive) Name = Name.ToLower(); // if (!scope.CaseSensitive) Name = Name.ToLower();
CurrentScope = null; CurrentScope = null;
@ -762,7 +772,7 @@ namespace SymbolTable
} }
Scope CurrentArea = scope, bs; Scope CurrentArea = scope, bs;
HashTableNode tn; IEnumerable<SymbolInfo> infos;
do do
{ {
if (CurrentArea is UnitPartScope) //мы очутились в модуле if (CurrentArea is UnitPartScope) //мы очутились в модуле
@ -770,38 +780,38 @@ namespace SymbolTable
//мы в ImplementationPart? //мы в ImplementationPart?
if (CurrentArea is UnitImplementationScope) if (CurrentArea is UnitImplementationScope)
{ {
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
CurrentArea = CurrentArea.TopScope; CurrentArea = CurrentArea.TopScope;
} }
//сейча мы в InterfacePart //сейча мы в InterfacePart
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
if (Result.Count() > 0) if (Result.Count() > 0)
return Result; return Result;
} }
if (CurrentArea is WithScope)//мы очутились в With if (CurrentArea is WithScope)//мы очутились в With
{ {
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
if (Result.Count() > 0) //если что-то нашли то заканчиваем if (Result.Count() > 0) //если что-то нашли то заканчиваем
return Result; return Result;
FindAllInAreaList(Name, (CurrentArea as WithScope).WithScopes, true, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, (CurrentArea as WithScope).WithScopes, true, true, Result, caseSensitiveSearch);
if (Result.Count() > 0) //если что-то нашли то заканчиваем if (Result.Count() > 0) //если что-то нашли то заканчиваем
return Result; return Result;
} }
else else
{ {
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
{ {
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
return Result.Count() > 0 ? Result : null; return Result.Count() > 0 ? Result : null;
} }
} }
@ -811,13 +821,13 @@ namespace SymbolTable
return null; return null;
} }
private void FindAllInClass(string name, Scope ClassArea, bool OnlyInThisClass, List<SymbolInfo> Result, bool fromCaseSensitive) private void FindAllInClass(string name, Scope ClassArea, bool OnlyInThisClass, List<SymbolInfo> Result, bool caseSensitiveSearch)
{ {
HashTableNode tn; IEnumerable<SymbolInfo> infos;
Scope ar = ClassArea; Scope ar = ClassArea;
if ((tn = ar.Symbols.Find(name, fromCaseSensitive)) != null) if ((infos = ar.Symbols.Find(name, caseSensitiveSearch)) != null)
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
if (ar is DotNETScope) if (ar is DotNETScope)
{ {
@ -832,16 +842,16 @@ namespace SymbolTable
{ {
while (cl.BaseClassScope != null) while (cl.BaseClassScope != null)
{ {
tn = cl.BaseClassScope.Symbols.Find(name, fromCaseSensitive); // SSM 30/06/20 - надо исключать generis-параметры из поиска - их не существует в производном классе!!! infos = cl.BaseClassScope.Symbols.Find(name, caseSensitiveSearch); // SSM 30/06/20 - надо исключать generis-параметры из поиска - их не существует в производном классе!!!
if (tn != null) if (infos != null)
{ {
if (tn.InfoList[0].sym_info is PascalABCCompiler.TreeRealization.common_type_node cctt && cctt.is_generic_parameter) if (infos.First().sym_info is PascalABCCompiler.TreeRealization.common_type_node cctt && cctt.is_generic_parameter)
{ {
// пропустить!!! // пропустить!!!
} }
else else
{ {
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
} }
} }
@ -938,7 +948,7 @@ namespace SymbolTable
); );
} }
private void AddToSymbolInfo(List<SymbolInfo> from, List<SymbolInfo> to) private void AddToSymbolInfo(IEnumerable<SymbolInfo> from, List<SymbolInfo> to)
{ {
bool CheckVisible = CurrentScope != null, NeedAdd = false; bool CheckVisible = CurrentScope != null, NeedAdd = false;
SymbolInfo last_sym = to.LastOrDefault(); SymbolInfo last_sym = to.LastOrDefault();
@ -964,11 +974,11 @@ namespace SymbolTable
to.AddRange(sil); to.AddRange(sil);
} }
private void FindAllInAreaList(string name, Scope[] arr, bool need, List<SymbolInfo> Result, bool fromCaseSensitive) private void FindAllInAreaList(string name, Scope[] arr, bool need, List<SymbolInfo> Result, bool caseSensitiveSearch)
{ {
FindAllInAreaList(name, arr, false, need, Result, fromCaseSensitive); FindAllInAreaList(name, arr, false, need, Result, caseSensitiveSearch);
} }
public void FindAllInAreaList(string name, Scope[] arr, bool StopIfFind, bool NotOnlyInNetScopes, List<SymbolInfo> Result, bool fromCaseSensitive) public void FindAllInAreaList(string name, Scope[] arr, bool StopIfFind, bool NotOnlyInNetScopes, List<SymbolInfo> Result, bool caseSensitiveSearch)
{ {
if (arr == null) return; if (arr == null) return;
@ -1002,10 +1012,10 @@ namespace SymbolTable
else else
if (NotOnlyInNetScopes && sc != null) if (NotOnlyInNetScopes && sc != null)
{ {
var tn = sc.Symbols.Find(name, fromCaseSensitive); var infos = sc.Symbols.Find(name, caseSensitiveSearch);
if (tn != null) if (infos != null)
{ {
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
if (Result.Count > add && StopIfFind) if (Result.Count > add && StopIfFind)
return; return;
} }
@ -1038,7 +1048,12 @@ namespace SymbolTable
{ {
return FindAll(scope, Name, true, true, null); return FindAll(scope, Name, true, true, null);
} }
// Пока что считаем, что caseaSensitiveSearch совпадает с SymbolTableCaseSensitive EVA
private List<SymbolInfo> FindAll(Scope scope, string Name, bool OnlyInType, bool OnlyInThisClass, Scope FromScope) private List<SymbolInfo> FindAll(Scope scope, string Name, bool OnlyInType, bool OnlyInThisClass, Scope FromScope)
=> FindAll(scope, Name, OnlyInType, OnlyInThisClass, FromScope, SymbolTableCaseSensitive);
private List<SymbolInfo> FindAll(Scope scope, string Name, bool OnlyInType, bool OnlyInThisClass, Scope FromScope, bool caseSensitiveSearch)
{ {
if (OnlyInType && !(scope is ClassScope) && !(scope is SymbolTable.DotNETScope)) return null; if (OnlyInType && !(scope is ClassScope) && !(scope is SymbolTable.DotNETScope)) return null;
//if (!CaseSensitive) Name=Name.ToLower(); //if (!CaseSensitive) Name=Name.ToLower();
@ -1074,7 +1089,7 @@ namespace SymbolTable
if (scope != null) if (scope != null)
{ {
var a = (scope as UnitInterfaceScope).TopScopeArray.Where(x => x is PascalABCCompiler.NetHelper.NetScope).ToArray(); var a = (scope as UnitInterfaceScope).TopScopeArray.Where(x => x is PascalABCCompiler.NetHelper.NetScope).ToArray();
FindAllInAreaList(Name, a, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, a, true, Result, caseSensitiveSearch);
} }
if (Result.Count > 0) if (Result.Count > 0)
@ -1085,7 +1100,7 @@ namespace SymbolTable
Scope Area = scope; Scope Area = scope;
Scope[] used_units = null; Scope[] used_units = null;
HashTableNode tn = null; IEnumerable<SymbolInfo> infos = null;
if (!(scope is DotNETScope)) if (!(scope is DotNETScope))
{ {
Scope CurrentArea = Area; Scope CurrentArea = Area;
@ -1097,30 +1112,30 @@ namespace SymbolTable
if (CurrentArea is UnitImplementationScope) if (CurrentArea is UnitImplementationScope)
{ {
used_units = (CurrentArea as UnitImplementationScope).TopScopeArray; used_units = (CurrentArea as UnitImplementationScope).TopScopeArray;
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
CurrentArea = CurrentArea.TopScope; CurrentArea = CurrentArea.TopScope;
} }
//сейча мы в InterfacePart //сейча мы в InterfacePart
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
//смотрим в модулях //смотрим в модулях
FindAllInAreaList(Name, used_units, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, used_units, true, Result, caseSensitiveSearch);
FindAllInAreaList(Name, (CurrentArea as UnitInterfaceScope).TopScopeArray, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, (CurrentArea as UnitInterfaceScope).TopScopeArray, true, Result, caseSensitiveSearch);
return Result.Count > 0 ? Result : null; return Result.Count > 0 ? Result : null;
} }
else else
if (CurrentArea is IInterfaceScope) if (CurrentArea is IInterfaceScope)
{ {
FindAllInClass(Name, CurrentArea, OnlyInThisClass, Result, scope.CaseSensitive); FindAllInClass(Name, CurrentArea, OnlyInThisClass, Result, caseSensitiveSearch);
//if (Result.Count > 0) //если что-то нашли то заканчиваем //if (Result.Count > 0) //если что-то нашли то заканчиваем
// return Result; // return Result;
FindAllInAreaList(Name, (CurrentArea as IInterfaceScope).TopInterfaceScopeArray, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, (CurrentArea as IInterfaceScope).TopInterfaceScopeArray, true, Result, caseSensitiveSearch);
if (Result.Count > 0 || OnlyInType) //если что-то нашли то заканчиваем if (Result.Count > 0 || OnlyInType) //если что-то нашли то заканчиваем
return Result.Count > 0 ? Result : null; return Result.Count > 0 ? Result : null;
@ -1128,7 +1143,7 @@ namespace SymbolTable
else else
if (CurrentArea is ClassScope)//мы очутились в классе if (CurrentArea is ClassScope)//мы очутились в классе
{ {
FindAllInClass(Name, CurrentArea, OnlyInThisClass, Result, scope.CaseSensitive);//надо сделать поиск по его предкам FindAllInClass(Name, CurrentArea, OnlyInThisClass, Result, caseSensitiveSearch);//надо сделать поиск по его предкам
if (Result.Count > 0 || OnlyInType) //если что-то нашли то заканчиваем if (Result.Count > 0 || OnlyInType) //если что-то нашли то заканчиваем
return Result.Count > 0 ? Result : null; return Result.Count > 0 ? Result : null;
@ -1137,16 +1152,16 @@ namespace SymbolTable
else else
if (CurrentArea is WithScope)//мы очутились в With if (CurrentArea is WithScope)//мы очутились в With
{ {
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
if (Result.Count > 0) //если что-то нашли то заканчиваем if (Result.Count > 0) //если что-то нашли то заканчиваем
return Result; return Result;
Scope[] wscopes = (CurrentArea as WithScope).WithScopes; Scope[] wscopes = (CurrentArea as WithScope).WithScopes;
if (wscopes != null) if (wscopes != null)
foreach (Scope wsc in wscopes) foreach (Scope wsc in wscopes)
{ {
FindAllInClass(Name, wsc, OnlyInThisClass, Result, scope.CaseSensitive);//надо сделать поиск по его предкам FindAllInClass(Name, wsc, OnlyInThisClass, Result, caseSensitiveSearch);//надо сделать поиск по его предкам
if (Result.Count > 0) //если что-то нашли то заканчиваем if (Result.Count > 0) //если что-то нашли то заканчиваем
return Result; return Result;
@ -1154,10 +1169,10 @@ namespace SymbolTable
} }
else else
{ {
tn = CurrentArea.Symbols.Find(Name, scope.CaseSensitive); infos = CurrentArea.Symbols.Find(Name, caseSensitiveSearch);
if (tn != null) //что-то нашли! if (infos != null) //что-то нашли!
{ {
AddToSymbolInfo(tn.InfoList, Result); AddToSymbolInfo(infos, Result);
return Result.Count > 0 ? Result : null; return Result.Count > 0 ? Result : null;
} }
if (CurrentArea is ClassMethodScope)//мы очутились в методе класса if (CurrentArea is ClassMethodScope)//мы очутились в методе класса
@ -1167,7 +1182,7 @@ namespace SymbolTable
var currentLambdaDefScope = (CurrentArea as ClassMethodScope).CurrentLambdaDefScope; var currentLambdaDefScope = (CurrentArea as ClassMethodScope).CurrentLambdaDefScope;
if (currentLambdaDefScope != null) if (currentLambdaDefScope != null)
{ {
var defScopeRes = FindAll(currentLambdaDefScope, Name, OnlyInType, OnlyInThisClass, currentLambdaDefScope); var defScopeRes = FindAll(currentLambdaDefScope, Name, OnlyInType, OnlyInThisClass, currentLambdaDefScope, caseSensitiveSearch);
if (defScopeRes != null && defScopeRes.Count > 0) if (defScopeRes != null && defScopeRes.Count > 0)
{ {
@ -1176,7 +1191,7 @@ namespace SymbolTable
} }
// aab 26.04.19 end // aab 26.04.19 end
FindAllInClass(Name, (CurrentArea as ClassMethodScope).TopScope, OnlyInThisClass, Result, scope.CaseSensitive);//надо сделать поиск по его классу FindAllInClass(Name, (CurrentArea as ClassMethodScope).TopScope, OnlyInThisClass, Result, caseSensitiveSearch);//надо сделать поиск по его классу
if (Result.Count > 0) //если что-то нашли то заканчиваем if (Result.Count > 0) //если что-то нашли то заканчиваем
@ -1200,16 +1215,16 @@ namespace SymbolTable
Scope NextUnitArea = null; Scope NextUnitArea = null;
//\ssyy //\ssyy
Scope an; Scope an;
tn = Area.Symbols.Find(Name, scope.CaseSensitive); infos = Area.Symbols.Find(Name, caseSensitiveSearch);
while (Area != null) while (Area != null)
{ {
an = Area; an = Area;
if (an is DotNETScope) if (an is DotNETScope)
{ {
if (tn == null) if (infos == null)
AddToSymbolInfo(Result, (DotNETScope)an, Name); AddToSymbolInfo(Result, (DotNETScope)an, Name);
else else
FindAllInClass(Name, Area, false, Result, scope.CaseSensitive); FindAllInClass(Name, Area, false, Result, caseSensitiveSearch);
} }
if (Result.Count > 0) if (Result.Count > 0)
return Result; return Result;
@ -1217,18 +1232,18 @@ namespace SymbolTable
{ {
if (an is UnitImplementationScope) if (an is UnitImplementationScope)
{ {
FindAllInAreaList(Name, (an as UnitImplementationScope).TopScopeArray, true, Result, scope.CaseSensitive); FindAllInAreaList(Name, (an as UnitImplementationScope).TopScopeArray, true, Result, caseSensitiveSearch);
an = an.TopScope; an = an.TopScope;
} }
FindAllInAreaList(Name, (an as UnitInterfaceScope).TopScopeArray, false, Result, scope.CaseSensitive); FindAllInAreaList(Name, (an as UnitInterfaceScope).TopScopeArray, false, Result, caseSensitiveSearch);
if (Result.Count > 0) if (Result.Count > 0)
return Result; return Result;
} }
if (an is WithScope)//мы очутились в Width if (an is WithScope)//мы очутились в Width
{ {
FindAllInAreaList(Name, (an as WithScope).WithScopes, true, false, Result, scope.CaseSensitive); FindAllInAreaList(Name, (an as WithScope).WithScopes, true, false, Result, caseSensitiveSearch);
if (Result.Count > 0) //если что-то нашли то заканчиваем if (Result.Count > 0) //если что-то нашли то заканчиваем
return Result; return Result;
@ -1251,7 +1266,7 @@ namespace SymbolTable
//В предках ничего не нашли, ищем по интерфейсам... //В предках ничего не нашли, ищем по интерфейсам...
if (IntScope != null) if (IntScope != null)
{ {
FindAllInAreaList(Name, IntScope.TopInterfaceScopeArray, false, Result, scope.CaseSensitive); FindAllInAreaList(Name, IntScope.TopInterfaceScopeArray, false, Result, caseSensitiveSearch);
if (Result.Count > 0) //если что-то нашли то заканчиваем if (Result.Count > 0) //если что-то нашли то заканчиваем
return Result; return Result;
@ -1296,8 +1311,7 @@ namespace SymbolTable
} }
public class TreeConverterSymbolTable:DSSymbolTable public class TreeConverterSymbolTable:DSSymbolTable
{ {
public TreeConverterSymbolTable(bool case_sensitive):base(SymbolTableConstants.HashTable_StartSize,case_sensitive){} public TreeConverterSymbolTable():base(SymbolTableConstants.HashTable_StartSize){}
public TreeConverterSymbolTable():base(SymbolTableConstants.HashTable_StartSize,false){}
} }
public class SymbolTableController public class SymbolTableController
{ {

View file

@ -122,6 +122,8 @@ namespace PascalABCCompiler.TreeConverter
{ {
public override string ToString() => sym_info.ToString(); public override string ToString() => sym_info.ToString();
public string Name { get; set; }
//private readonly name_information_type _name_information_type; //private readonly name_information_type _name_information_type;
private definition_node _sym_info; private definition_node _sym_info;
@ -182,6 +184,7 @@ namespace PascalABCCompiler.TreeConverter
public SymbolInfo copy() public SymbolInfo copy()
{ {
SymbolInfo si = new SymbolInfo(); SymbolInfo si = new SymbolInfo();
si.Name = Name;
si._access_level = this.access_level; si._access_level = this.access_level;
si._sym_info = this._sym_info; si._sym_info = this._sym_info;
si._symbol_kind = this._symbol_kind; si._symbol_kind = this._symbol_kind;

View file

@ -159,8 +159,6 @@ namespace PascalABCCompiler.TreeConverter
ErrorsList = initializationData.errorsList; ErrorsList = initializationData.errorsList;
WarningsList = initializationData.warningsList; WarningsList = initializationData.warningsList;
SymbolTable.CaseSensitive = SemanticRulesConstants.SymbolTableCaseSensitive;
this.debug = initializationData.debug; this.debug = initializationData.debug;
this.debugging = initializationData.debugging; this.debugging = initializationData.debugging;
this.for_intellisense = initializationData.forIntellisense; this.for_intellisense = initializationData.forIntellisense;

View file

@ -3,16 +3,16 @@
pi = 3.14159265358979 pi = 3.14159265358979
def sqrt(x: float) -> float: def sqrt(x: float) -> float:
return PABCSystem.sqrt(x) return PABCSystem.Sqrt(x)
def trunc(x: float) -> int: def trunc(x: float) -> int:
return PABCSystem.trunc(x) return PABCSystem.Trunc(x)
def floor(x: float) -> int: def floor(x: float) -> int:
return PABCSystem.floor(x) return PABCSystem.Floor(x)
def ceil(x: float) -> int: def ceil(x: float) -> int:
return PABCSystem.ceil(x) return PABCSystem.Ceil(x)
def log(x: float) -> float: def log(x: float) -> float:
return PABCSystem.Log(x) return PABCSystem.Log(x)
@ -30,55 +30,55 @@ def log(x: float, base: int) -> float:
return PABCSystem.LogN(base, x) return PABCSystem.LogN(base, x)
def exp(x: float) -> float: def exp(x: float) -> float:
return PABCSystem.exp(x) return PABCSystem.Exp(x)
def expm1(x: float) -> float: def expm1(x: float) -> float:
return PABCSystem.exp(x - 1) return PABCSystem.Exp(x - 1)
def exp2(x: float) -> float: def exp2(x: float) -> float:
return PABCSystem.exp(log(2) * x) return PABCSystem.Exp(log(2) * x)
def sin(x: float) -> float: def sin(x: float) -> float:
return PABCSystem.sin(x) return PABCSystem.Sin(x)
def sinh(x: float) -> float: def sinh(x: float) -> float:
return PABCSystem.sinh(x) return PABCSystem.Sinh(x)
def cos(x: float) -> float: def cos(x: float) -> float:
return PABCSystem.cos(x) return PABCSystem.Cos(x)
def cosh(x: float) -> float: def cosh(x: float) -> float:
return PABCSystem.cosh(x) return PABCSystem.Cosh(x)
def tan(x: float) -> float: def tan(x: float) -> float:
return PABCSystem.tan(x) return PABCSystem.Tan(x)
def tanh(x: float) -> float: def tanh(x: float) -> float:
return PABCSystem.tanh(x) return PABCSystem.Tanh(x)
def acos(x: float) -> float: def acos(x: float) -> float:
return PABCSystem.arccos(x) return PABCSystem.ArcCos(x)
def asin(x: float) -> float: def asin(x: float) -> float:
return PABCSystem.arcsin(x) return PABCSystem.ArcSin(x)
def atan(x: float) -> float: def atan(x: float) -> float:
return PABCSystem.arctan(x) return PABCSystem.ArcTan(x)
def atan2(y: float, x: float) -> float: def atan2(y: float, x: float) -> float:
return PABCSystem.arctan(y / x) return PABCSystem.ArcTan(y / x)
def pow(x: float, y: int) -> float: def pow(x: float, y: int) -> float:
return PABCSystem.power(x, y) return PABCSystem.Power(x, y)
def cbrt(x: float) -> float: def cbrt(x: float) -> float:
return pow(x, 1/3) return pow(x, 1/3)
def fabs(x: float) -> float: def fabs(x: float) -> float:
return PABCSystem.abs(x) return PABCSystem.Abs(x)
def pow(x: float, y: float) -> float: def pow(x: float, y: float) -> float:
return PABCSystem.power(x, y) return PABCSystem.Power(x, y)
def isqrt(x: int) -> int: def isqrt(x: int) -> int:
return floor(sqrt(x)) return floor(sqrt(x))

View file

@ -2,7 +2,7 @@
import PABCSystem import PABCSystem
def random() -> float: def random() -> float:
return PABCSystem.random() return PABCSystem.Random()
def randint(a: int, b: int) -> int: def randint(a: int, b: int) -> int:
return PABCSystem.random(a, b) return PABCSystem.Random(a, b)