Рефакторинг таблицы символов, чтобы заполнялся только один словарь (#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
def random() -> float:
return PABCSystem.random()
return PABCSystem.Random()
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;
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>();
foreach (var symInfo in symbolInfos.InfoList)
{
if (distinctNames.Find(info => info.Name == symInfo.Name) == null)
distinctNames.Add(symInfo);
}
foreach (var symInfo in distinctNames)
{
var node = symInfo.sym_info;
// Если достаем из pcu, то надо восстановить полную информацию
if (symInfo is wrapped_definition_node wdn)
if (node is wrapped_definition_node wdn)
{
// У некоторых дубликатов sym_info offset не задан, ищем тот, где задан
symInfo = names.Value.InfoList.Find(si => ((wrapped_definition_node)si.sym_info).offset > 0)?.sym_info;
node = symbolInfos.InfoList.Find(si => si.Name == symInfo.Name
&& ((wrapped_definition_node)si.sym_info).offset > 0)?.sym_info;
if (symInfo == null)
if (node == null)
continue;
wdn = (wrapped_definition_node)symInfo;
wdn = (wrapped_definition_node)node;
// Если это не синоним типа, то восстанавливаем семантическую информацию
if (!wdn.is_synonim)
symInfo = wdn.PCUReader.CreateInterfaceMember(wdn.offset, names.Key);
node = wdn.PCUReader.CreateInterfaceMember(wdn.offset, symInfo.Name);
}
currentUnit.NamesFromUsedUnits[unitName].Add(names.Key,
symInfo.general_node_type == general_node_type.variable_node
|| symInfo.general_node_type == general_node_type.constant_definition
|| symInfo.general_node_type == general_node_type.event_node);
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,12 +279,14 @@ namespace PascalABCCompiler.PCU
return null; // return comp.RecompileUnit(file_name);
}
ChangeState(this, PCUReaderWriterState.BeginReadTree, unit);
var unitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
// Задаем регистрозависимость таблицы символов для правильного добавления и поиска
SemanticRulesConstants.SymbolTableCaseSensitive = unitLanguage.CaseSensitive;
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)
PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun);
//ssyy
@ -292,8 +294,6 @@ namespace PascalABCCompiler.PCU
cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope);
//\ssyy
cun.implementation_scope.CaseSensitive = unitLanguageCaseSensitive;
string SourceFileName = pcu_file.SourceFileName;
if (Path.GetDirectoryName(SourceFileName) == "")
{

View file

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

View file

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

View file

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

View file

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

View file

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