F: Update ConceptCore API for error messages

This commit is contained in:
Ivan 2024-09-22 19:02:17 +03:00
parent a69bedb033
commit 6b86dc3a16
9 changed files with 117 additions and 111 deletions

View File

@ -1,3 +1,5 @@
22.09.2024 Экстеор 4.9.5
• сообщения об ошибках при несоответствии выражения конституенте
30.08.2024 Экстеор 4.9.4 30.08.2024 Экстеор 4.9.4
• исправлена загрузка файлов версий 2017-2020 годов • исправлена загрузка файлов версий 2017-2020 годов
14.06.2024 Экстеор 4.9.3 14.06.2024 Экстеор 4.9.3

View File

@ -1182,8 +1182,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,9,4,1000 FILEVERSION 4,9,5,1000
PRODUCTVERSION 4,9,4,1000 PRODUCTVERSION 4,9,5,1000
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -1201,13 +1201,13 @@ BEGIN
VALUE "Comments", "Ýêñïëèêàòîð òåîðèé " VALUE "Comments", "Ýêñïëèêàòîð òåîðèé "
VALUE "CompanyName", "ÍÏ ÖÈÂÒ ÊÎÍÖÅÏÒ" VALUE "CompanyName", "ÍÏ ÖÈÂÒ ÊÎÍÖÅÏÒ"
VALUE "FileDescription", "Ýêñòåîð 4.9" VALUE "FileDescription", "Ýêñòåîð 4.9"
VALUE "FileVersion", "4.9.4.1000" VALUE "FileVersion", "4.9.5.1000"
VALUE "InternalName", "Ýêñòåîð 4.9" VALUE "InternalName", "Ýêñòåîð 4.9"
VALUE "LegalCopyright", "Copyright © NPMP CIHT CONCEPT 1994-2024" VALUE "LegalCopyright", "Copyright © NPMP CIHT CONCEPT 1994-2024"
VALUE "LegalTrademarks", "Ýêñòåîð™" VALUE "LegalTrademarks", "Ýêñòåîð™"
VALUE "OriginalFilename", "Exteor.exe" VALUE "OriginalFilename", "Exteor.exe"
VALUE "ProductName", "Ýêñòåîð 4.9" VALUE "ProductName", "Ýêñòåîð 4.9"
VALUE "ProductVersion", "4.9.4.1000" VALUE "ProductVersion", "4.9.5.1000"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -3517,13 +3517,20 @@ BEGIN
IXTRS_PAR_SYNTHAXERROR "Ñèíòàêñè÷åñêàÿ îøèáêà" IXTRS_PAR_SYNTHAXERROR "Ñèíòàêñè÷åñêàÿ îøèáêà"
IXTRS_RS_CHECK_SUCCESS "Ïðîâåðêà êîððåêòíîñòè âûðàæåíèÿ: ÎÊ" IXTRS_RS_CHECK_SUCCESS "Ïðîâåðêà êîððåêòíîñòè âûðàæåíèÿ: ÎÊ"
IXTRS_PAR_FAILURE "Ñèíòàêñè÷åñêèé àíàëèç âûðàæåíèÿ: ÎØÈÁÊÀ" IXTRS_PAR_FAILURE "Ñèíòàêñè÷åñêèé àíàëèç âûðàæåíèÿ: ÎØÈÁÊÀ"
IXTRS_TYPE_INCONSISTENT "Òèïèçàöèÿ âûðàæåíèÿ íå ñîîòâåòñòâóåò òèïó êîíñòèòóåíòû\n\n"
END END
STRINGTABLE STRINGTABLE
BEGIN BEGIN
IXTRS_CST_NONEMPTY_BASE "Непустое выражение базисного/константного множества"
IXTRS_CST_EMPTY_DERIVED "Пустое выражение для сложного понятия или утверждения"
IXTRS_CALLABLE_NO_ARGS "Отсутствуют аргументы для параметризованной конституенты"
IXTRS_CST_NONCALLABLE_ARGS
"Параметризованное выражение не подходит для данного типа конституенты"
IXTRS_CST_EXPECTED_LOGICAL
"Данный тип конституенты требует логического выражения"
IXTRS_CST_EXPECTED_TYPED
"Данный тип конституенты требует теоретико-множественного выражения"
IXTRS_TYPE_STRUCTURE "Âûðàæåíèå ðîäîâîé ñòðóêòóðû äîëæíî áûòü ñòóïåíüþ" IXTRS_TYPE_STRUCTURE "Âûðàæåíèå ðîäîâîé ñòðóêòóðû äîëæíî áûòü ñòóïåíüþ"
IXTRS_TYPE_FUNCTION "Îæèäàëîñü âûðàæåíèå îáúÿâëåíèÿ ôóíêöèè"
IXTRS_USE_RADICAL "Ðàäèêàëû çàïðåùåíû âíå äåêëàðàöèé òåðì-ôóíêöè: %1" IXTRS_USE_RADICAL "Ðàäèêàëû çàïðåùåíû âíå äåêëàðàöèé òåðì-ôóíêöè: %1"
IXTRS_FILTER_ARGUMENT "Òèïèçàöèÿ àðãóìåíòà ôèëüòðà íå êîððåêòíà: %1(%2)" IXTRS_FILTER_ARGUMENT "Òèïèçàöèÿ àðãóìåíòà ôèëüòðà íå êîððåêòíà: %1(%2)"
IXTRS_FILTER_PARAM_ARITY IXTRS_FILTER_PARAM_ARITY

View File

@ -478,8 +478,13 @@
#define IXTRS_OSS_RUNALL_PROMPT 3209 #define IXTRS_OSS_RUNALL_PROMPT 3209
#define IXTRS_OSS_RUNALL_SUCCESS 3210 #define IXTRS_OSS_RUNALL_SUCCESS 3210
#define IXTRE_CANNOT_SAVE_DATA 3211 #define IXTRE_CANNOT_SAVE_DATA 3211
#define IXTRS_CST_NONEMPTY_BASE 3470
#define IXTRS_CST_EMPTY_DERIVED 3471
#define IXTRS_CALLABLE_NO_ARGS 3472
#define IXTRS_CST_NONCALLABLE_ARGS 3473
#define IXTRS_CST_EXPECTED_LOGICAL 3474
#define IXTRS_CST_EXPECTED_TYPED 3475
#define IXTRS_TYPE_STRUCTURE 3480 #define IXTRS_TYPE_STRUCTURE 3480
#define IXTRS_TYPE_FUNCTION 3483
#define IXTRS_USE_RADICAL 3485 #define IXTRS_USE_RADICAL 3485
#define IXTRS_FILTER_ARGUMENT 3486 #define IXTRS_FILTER_ARGUMENT 3486
#define IXTRS_FILTER_PARAM_ARITY 3487 #define IXTRS_FILTER_PARAM_ARITY 3487
@ -493,7 +498,6 @@
#define IXTRS_PAR_SYNTHAXERROR 3500 #define IXTRS_PAR_SYNTHAXERROR 3500
#define IXTRS_RS_CHECK_SUCCESS 3501 #define IXTRS_RS_CHECK_SUCCESS 3501
#define IXTRS_PAR_FAILURE 3502 #define IXTRS_PAR_FAILURE 3502
#define IXTRS_TYPE_INCONSISTENT 3503
#define IXTRS_PAR_EXPECTED_RP 3504 #define IXTRS_PAR_EXPECTED_RP 3504
#define IXTRS_PAR_EXPECTED_RC 3505 #define IXTRS_PAR_EXPECTED_RC 3505
#define IXTRS_PAR_QUANTDECL 3506 #define IXTRS_PAR_QUANTDECL 3506

View File

@ -54,7 +54,7 @@ enum class ModelStatus : uint8_t {
[[nodiscard]] CString BasicDescriptionOf(ccl::oss::PictID pict, ccl::oss::OSSchema& oss); [[nodiscard]] CString BasicDescriptionOf(ccl::oss::PictID pict, ccl::oss::OSSchema& oss);
[[nodiscard]] CString DescriptionOf(const ccl::rslang::Auditor& analytics, BOOL showAST); [[nodiscard]] CString DescriptionOf(const ccl::semantic::SchemaAuditor& analytics, BOOL showAST);
[[nodiscard]] CString DescriptionOf(const ccl::rslang::Interpreter& calculator, [[nodiscard]] CString DescriptionOf(const ccl::rslang::Interpreter& calculator,
const std::optional<ccl::rslang::ExpressionValue>& result, const std::optional<ccl::rslang::ExpressionValue>& result,
BOOL showAST); BOOL showAST);

View File

@ -75,8 +75,6 @@ DECLARE_MESSAGE_MAP()
afx_msg void OnSimpleSyntax(); afx_msg void OnSimpleSyntax();
private: private:
std::tuple<std::string, long> GetAnalyseExpr() const;
void UpdateStatus(ccl::semantic::ParsingStatus status, ccl::rslang::ValueClass vclass); void UpdateStatus(ccl::semantic::ParsingStatus status, ccl::rslang::ValueClass vclass);
void SetModified(BOOL bChanged = TRUE); void SetModified(BOOL bChanged = TRUE);
BOOL IsModified() const noexcept; BOOL IsModified() const noexcept;
@ -88,7 +86,7 @@ private:
void InitCstNameList(); void InitCstNameList();
void UpdateStatusBar(); void UpdateStatusBar();
void Analyse(); void ExpressAnalyse();
}; };
} // namespace xtr::dialog } // namespace xtr::dialog

View File

@ -11,7 +11,7 @@ class RSEdit : public BuffRichEdit {
EntityUID activeUID{}; EntityUID activeUID{};
ccl::rslang::Parser parser{}; ccl::rslang::Parser parser{};
std::unique_ptr<ccl::rslang::Auditor> checker{ nullptr }; std::unique_ptr<ccl::semantic::SchemaAuditor> checker{ nullptr };
CString astText{}; CString astText{};
StrPos prefixLen{ 0 }; StrPos prefixLen{ 0 };

View File

@ -46,17 +46,17 @@ namespace {
} }
} }
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::LexerEID error) noexcept { [[nodiscard]] constexpr uint32_t MsgIDFor(const uint32_t eid) noexcept {
switch (error) { using ccl::rslang::LexerEID;
default:
case ccl::rslang::LexerEID::unknownSymbol: return IXTRS_LEX_UNKNOWN_SYM;
}
}
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ParseEID error) noexcept {
using ccl::rslang::ParseEID; using ccl::rslang::ParseEID;
switch (error) { using ccl::rslang::SemanticEID;
default: using ccl::rslang::ValueEID;
using ccl::semantic::CstTypeEID;
switch (static_cast<LexerEID>(eid)) {
case LexerEID::unknownSymbol: return IXTRS_LEX_UNKNOWN_SYM;
}
switch (static_cast<ParseEID>(eid)) {
case ParseEID::syntax: return IXTRS_PAR_SYNTHAXERROR; case ParseEID::syntax: return IXTRS_PAR_SYNTHAXERROR;
case ParseEID::missingParenthesis: return IXTRS_PAR_EXPECTED_RP; case ParseEID::missingParenthesis: return IXTRS_PAR_EXPECTED_RP;
case ParseEID::missingCurlyBrace: return IXTRS_PAR_EXPECTED_RC; case ParseEID::missingCurlyBrace: return IXTRS_PAR_EXPECTED_RC;
@ -65,12 +65,8 @@ namespace {
case ParseEID::expectedDeclaration: return IXTRS_PAR_EXPECTED_ARGDECL; case ParseEID::expectedDeclaration: return IXTRS_PAR_EXPECTED_ARGDECL;
case ParseEID::expectedLocal: return IXTRS_PAR_EXPECTED_VAR; case ParseEID::expectedLocal: return IXTRS_PAR_EXPECTED_VAR;
} }
}
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::SemanticEID error) noexcept { switch (static_cast<SemanticEID>(eid)) {
using ccl::rslang::SemanticEID;
switch (error) {
default:
case SemanticEID::localUndeclared: return IXTRS_TYPE_NAME_UKNOWN; case SemanticEID::localUndeclared: return IXTRS_TYPE_NAME_UKNOWN;
case SemanticEID::localShadowing: return IXTRS_TYPE_NAME_DECLARED; case SemanticEID::localShadowing: return IXTRS_TYPE_NAME_DECLARED;
case SemanticEID::globalFuncMissing: return IXTRS_TYPE_UNKNOWN_FUNCTION; case SemanticEID::globalFuncMissing: return IXTRS_TYPE_UNKNOWN_FUNCTION;
@ -94,7 +90,6 @@ namespace {
case SemanticEID::invalidArgsArity: return IXTRS_TYPE_FUNC_ARGNUM; case SemanticEID::invalidArgsArity: return IXTRS_TYPE_FUNC_ARGNUM;
case SemanticEID::invalidArgumentType: return IXTRS_TYPE_FUNC_WRONG_ARG; case SemanticEID::invalidArgumentType: return IXTRS_TYPE_FUNC_WRONG_ARG;
case SemanticEID::globalStructure: return IXTRS_TYPE_STRUCTURE; case SemanticEID::globalStructure: return IXTRS_TYPE_STRUCTURE;
case SemanticEID::globalExpectedFunction: return IXTRS_TYPE_FUNCTION;
case SemanticEID::radicalUsage: return IXTRS_USE_RADICAL; case SemanticEID::radicalUsage: return IXTRS_USE_RADICAL;
case SemanticEID::invalidFilterArgumentType: return IXTRS_FILTER_ARGUMENT; case SemanticEID::invalidFilterArgumentType: return IXTRS_FILTER_ARGUMENT;
case SemanticEID::invalidFilterArity: return IXTRS_FILTER_PARAM_ARITY; case SemanticEID::invalidFilterArity: return IXTRS_FILTER_PARAM_ARITY;
@ -107,12 +102,17 @@ namespace {
case SemanticEID::globalMissingAST: return IXTRS_GLOBAL_NO_AST; case SemanticEID::globalMissingAST: return IXTRS_GLOBAL_NO_AST;
case SemanticEID::globalFuncNoInterpretation: return IXTRS_FUNCTION_CALL_INVALID; case SemanticEID::globalFuncNoInterpretation: return IXTRS_FUNCTION_CALL_INVALID;
} }
}
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ValueEID error) noexcept { switch (static_cast<CstTypeEID>(eid)) {
using ccl::rslang::ValueEID; case CstTypeEID::cstNonemptyBase: return IXTRS_CST_NONEMPTY_BASE;
switch (error) { case CstTypeEID::cstEmptyDerived: return IXTRS_CST_EMPTY_DERIVED;
default: case CstTypeEID::cstCallableNoArgs: return IXTRS_CALLABLE_NO_ARGS;
case CstTypeEID::cstNonCallableHasArgs: return IXTRS_CST_NONCALLABLE_ARGS;
case CstTypeEID::cstExpectedLogical: return IXTRS_CST_EXPECTED_LOGICAL;
case CstTypeEID::cstExpectedTyped: return IXTRS_CST_EXPECTED_TYPED;
}
switch (static_cast<ValueEID>(eid)) {
case ValueEID::unknownError: return IXTRS_VALUE_UNKNOWN_ERROR; case ValueEID::unknownError: return IXTRS_VALUE_UNKNOWN_ERROR;
case ValueEID::typedOverflow: return IXTRS_VALUE_SET_LIMIT; case ValueEID::typedOverflow: return IXTRS_VALUE_SET_LIMIT;
case ValueEID::booleanLimit: return IXTRS_VALUE_BOOL_LIMIT; case ValueEID::booleanLimit: return IXTRS_VALUE_BOOL_LIMIT;
@ -121,6 +121,8 @@ namespace {
case ValueEID::invalidDebool: return IXTRS_VALUE_DEBOOL; case ValueEID::invalidDebool: return IXTRS_VALUE_DEBOOL;
case ValueEID::iterateInfinity: return IXTRS_ITERATE_INFINITY; case ValueEID::iterateInfinity: return IXTRS_ITERATE_INFINITY;
} }
return 0;
} }
[[nodiscard]] CString ErrorMessage(const uint32_t errorCode, const std::vector<std::string>& params) { [[nodiscard]] CString ErrorMessage(const uint32_t errorCode, const std::vector<std::string>& params) {
@ -128,16 +130,7 @@ namespace {
auto prefix = Label(errType); auto prefix = Label(errType);
prefix.AppendFormat(LR"(%04X)", errorCode); prefix.AppendFormat(LR"(%04X)", errorCode);
prefix += LR"(: )"; prefix += LR"(: )";
const uint32_t msgID = [&]() noexcept -> uint32_t { const uint32_t msgID = MsgIDFor(errorCode);
switch (errType) {
default:
case ErrorType::UNKNOWN: return 0;
case ErrorType::LEXER: return MsgIDFor(static_cast<ccl::rslang::LexerEID>(errorCode));
case ErrorType::PARSER: return MsgIDFor(static_cast<ccl::rslang::ParseEID>(errorCode));
case ErrorType::SEMANTIC: return MsgIDFor(static_cast<ccl::rslang::SemanticEID>(errorCode));
case ErrorType::VALUE: return MsgIDFor(static_cast<ccl::rslang::ValueEID>(errorCode));
}
}();
if (msgID == 0) { if (msgID == 0) {
return prefix; return prefix;
} else { } else {
@ -437,15 +430,15 @@ CString BasicDescriptionOf(const ccl::oss::PictID pict, ccl::oss::OSSchema& oss)
return infoStr; return infoStr;
} }
CString DescriptionOf(const ccl::rslang::Auditor& analytics, const BOOL showAST) { CString DescriptionOf(const ccl::semantic::SchemaAuditor& analytics, const BOOL showAST) {
CString msgLog{}; CString msgLog{};
const ccl::rslang::ExpressionType* type = &analytics.GetType(); const ccl::rslang::ExpressionType* type = &analytics.GetType();
if (!analytics.isParsed) { if (!analytics.IsParsed()) {
msgLog += mfc::LoadSID(IXTRS_PAR_FAILURE); msgLog += mfc::LoadSID(IXTRS_PAR_FAILURE);
} else if (!analytics.isTypeCorrect) { } else if (!analytics.IsTypeCorrect()) {
type = nullptr; type = nullptr;
msgLog += mfc::LoadSID(IXTRS_TYPECHECK_FAILURE); msgLog += mfc::LoadSID(IXTRS_TYPECHECK_FAILURE);
} else if (!analytics.isValueCorrect) { } else if (!analytics.IsValueCorrect()) {
msgLog += mfc::LoadSID(IXTRS_VALUECHECK_FAILURE); msgLog += mfc::LoadSID(IXTRS_VALUECHECK_FAILURE);
} else { } else {
msgLog += mfc::LoadSID(IXTRS_RS_CHECK_SUCCESS); msgLog += mfc::LoadSID(IXTRS_RS_CHECK_SUCCESS);
@ -459,9 +452,9 @@ CString DescriptionOf(const ccl::rslang::Auditor& analytics, const BOOL showAST)
msgLog += '\n'; msgLog += '\n';
msgLog += mfc::FormatSID(IXTRS_REPORT_VALUE_CLASS, Label(analytics.GetValueClass()).GetString()); msgLog += mfc::FormatSID(IXTRS_REPORT_VALUE_CLASS, Label(analytics.GetValueClass()).GetString());
if (showAST && analytics.isParsed) { if (showAST && analytics.IsParsed()) {
msgLog += '\n'; msgLog += '\n';
msgLog += mfc::FormatSID(IXTRS_REPORT_AST, mfc::ToMFC(AST2String::Apply(analytics.parser.AST())).GetString()); msgLog += mfc::FormatSID(IXTRS_REPORT_AST, mfc::ToMFC(AST2String::Apply(analytics.AST())).GetString());
} }
return msgLog; return msgLog;

View File

@ -400,19 +400,18 @@ BOOL CstDataPage::OnInsertBtn(uint32_t command) {
} }
void CstDataPage::OnAnalyse() { void CstDataPage::OnAnalyse() {
auto [str, basePos] = GetAnalyseExpr(); const auto& cst = parent.editor->GetRS(parent.activeUID);
const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
auto analyser = parent.editor->Core().RSLang().MakeAuditor(); auto analyser = parent.editor->Core().RSLang().MakeAuditor();
const ccl::rslang::ExpressionType* type{ nullptr }; const ccl::rslang::ExpressionType* type{ nullptr };
const auto typeOK = analyser->CheckType(str, ccl::rslang::Syntax::MATH);
const auto typeOK = analyser->CheckConstituenta(cst.alias, definitionText, cst.type);
if (typeOK) { if (typeOK) {
type = &analyser->GetType(); type = &analyser->GetType();
} }
const auto rstype = parent.editor->GetRS(parent.activeUID).type; if (!typeOK) {
const auto typeConsistent = typeOK
&& (!ccl::semantic::IsBaseSet(rstype) || expressionCtrl.Text().IsEmpty())
&& ccl::semantic::Schema::CheckTypeConstistency(analyser->GetType(), rstype);
if (!typeConsistent) {
UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid); UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid);
} else { } else {
if (!analyser->CheckValue()) { if (!analyser->CheckValue()) {
@ -423,7 +422,7 @@ void CstDataPage::OnAnalyse() {
} }
if (!empty(analyser->Errors().All())) { if (!empty(analyser->Errors().All())) {
auto errorPosition = std::max(analyser->Errors().FirstErrorPos() - basePos, 0L); auto errorPosition = std::max(static_cast<long>(analyser->Errors().FirstErrorPos() - analyser->prefixLen), 0L);
auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION)); auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION));
re->SetFocus(); re->SetFocus();
re->SetSel(errorPosition, errorPosition); re->SetSel(errorPosition, errorPosition);
@ -431,9 +430,6 @@ void CstDataPage::OnAnalyse() {
typificationCtrl.SetWindowTextW(info::Label(type)); typificationCtrl.SetWindowTextW(info::Label(type));
auto log = info::DescriptionOf(*analyser, XTROptions::ParseRSL().showAST); auto log = info::DescriptionOf(*analyser, XTROptions::ParseRSL().showAST);
if (typeOK && !typeConsistent) {
log = mfc::LoadSID(IXTRS_TYPE_INCONSISTENT) + log;
}
logCtrl.SetWindowTextW(log); logCtrl.SetWindowTextW(log);
} }
@ -450,15 +446,23 @@ void CstDataPage::OnCalculate() {
} }
BeginWaitCursor(); BeginWaitCursor();
auto[str, basePos] = GetAnalyseExpr(); const auto& cst = parent.editor->GetRS(parent.activeUID);
const auto expr = mfc::ToSTL(expressionCtrl.Text());
const auto fullExpr = ccl::rslang::Generator::GlobalDefinition(
cst.alias,
expr,
cst.type == CstType::structured
);
const auto basePos = static_cast<StrPos>(ssize(fullExpr) - ssize(expr));
ccl::rslang::Interpreter calculator{ ccl::rslang::Interpreter calculator{
parent.editor->Core().RSLang(), parent.editor->Core().RSLang(),
parent.editor->Core().RSLang().ASTContext(), parent.editor->Core().RSLang().ASTContext(),
parent.editor->Model().Calculations().Context() parent.editor->Model().Calculations().Context()
}; };
const auto calcResult = calculator.Evaluate(str, ccl::rslang::Syntax::MATH); const auto calcResult = calculator.Evaluate(fullExpr, ccl::rslang::Syntax::MATH);
if (!calcResult.has_value()) { if (!calcResult.has_value()) {
auto errorPosition = std::max(calculator.Errors().FirstErrorPos() - basePos, 0L); auto errorPosition = std::max(static_cast<long>(calculator.Errors().FirstErrorPos() - basePos), 0L);
auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION)); auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION));
re->SetFocus(); re->SetFocus();
re->SetSel(errorPosition, errorPosition); re->SetSel(errorPosition, errorPosition);
@ -473,8 +477,8 @@ void CstDataPage::OnCalculate() {
} }
void CstDataPage::OnSimpleSyntax() { void CstDataPage::OnSimpleSyntax() {
auto [expr, basePos] = GetAnalyseExpr(); const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
const auto asciiExpr = ccl::rslang::ConvertTo(expr, ccl::rslang::Syntax::ASCII); const auto asciiExpr = ccl::rslang::ConvertTo(definitionText, ccl::rslang::Syntax::ASCII);
logCtrl.SetWindowTextW(mfc::ToMFC(asciiExpr)); logCtrl.SetWindowTextW(mfc::ToMFC(asciiExpr));
} }
@ -487,14 +491,6 @@ BOOL CstDataPage::IsModified() const noexcept {
return isModified; return isModified;
} }
std::tuple<std::string, long> CstDataPage::GetAnalyseExpr() const {
const auto& cst = parent.editor->GetRS(parent.activeUID);
const auto expr = mfc::ToSTL(expressionCtrl.Text());
const auto fullExpr = ccl::rslang::Generator::GlobalDefinition(cst.alias, expr,
cst.type == CstType::structured);
return { fullExpr, static_cast<long>(ssize(fullExpr) - ssize(expr)) };
}
void CstDataPage::UpdateStatus(const ParsingStatus status, const ValueClass vclass) { void CstDataPage::UpdateStatus(const ParsingStatus status, const ValueClass vclass) {
parseStatus = status; parseStatus = status;
valueStatus = vclass; valueStatus = vclass;
@ -525,7 +521,7 @@ void CstDataPage::ClearSyntaxWindow() {
void CstDataPage::RunAutocheck() { void CstDataPage::RunAutocheck() {
if (parseStatus != ParsingStatus::VERIFIED && XTROptions::ParseRSL().autoCheck) { if (parseStatus != ParsingStatus::VERIFIED && XTROptions::ParseRSL().autoCheck) {
Analyse(); ExpressAnalyse();
} }
} }
@ -558,10 +554,11 @@ void CstDataPage::InitCstNameList() {
namePicker.SetRedraw(TRUE); namePicker.SetRedraw(TRUE);
} }
void CstDataPage::Analyse() { void CstDataPage::ExpressAnalyse() {
auto[str, basePos] = GetAnalyseExpr(); const auto& cst = parent.editor->GetRS(parent.activeUID);
const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
auto analyser = parent.editor->Core().RSLang().MakeAuditor(); auto analyser = parent.editor->Core().RSLang().MakeAuditor();
if (!analyser->CheckType(str, ccl::rslang::Syntax::MATH)) { if (!analyser->CheckConstituenta(cst.alias, definitionText, cst.type)) {
UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid); UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid);
} else if (!analyser->CheckValue()) { } else if (!analyser->CheckValue()) {
UpdateStatus(ParsingStatus::VERIFIED, ValueClass::invalid); UpdateStatus(ParsingStatus::VERIFIED, ValueClass::invalid);

View File

@ -425,8 +425,7 @@ BOOL RSEdit::UpdateAST() {
return FALSE; return FALSE;
} else { } else {
const auto& cst = context->GetRS(activeUID); const auto& cst = context->GetRS(activeUID);
const auto expression = Generator::GlobalDefinition(cst.alias, mfc::ToSTL(text), cst.type == CstType::structured); checker->CheckConstituenta(cst.alias, mfc::ToSTL(text), cst.type);
checker->CheckType(expression, ccl::rslang::Syntax::MATH);
astText = text; astText = text;
navigatorEnabled = FALSE; navigatorEnabled = FALSE;
activeNode = std::nullopt; activeNode = std::nullopt;
@ -438,25 +437,28 @@ void RSEdit::FormatSelectedBlock(const StrRange selection) {
static constexpr COLORREF clrBg{ RGB(235, 235, 235) }; static constexpr COLORREF clrBg{ RGB(235, 235, 235) };
static constexpr COLORREF clrReadOnlyBg{ RGB(255, 255, 211) }; static constexpr COLORREF clrReadOnlyBg{ RGB(255, 255, 211) };
if (XTROptions::ParseRSL().enableNavigator && if (!XTROptions::ParseRSL().enableNavigator ||
GetFocus()->GetSafeHwnd() == m_hWnd && GetFocus()->GetSafeHwnd() != m_hWnd ||
context != nullptr && UpdateAST() && checker->isParsed) { context == nullptr || !UpdateAST() || !checker->IsParsed()) {
auto selectedNode = activeNode; return;
if (!navigatorEnabled) {
const auto clientRange = StrRange{ selection.start + prefixLen, selection.finish + prefixLen };
selectedNode = ccl::rslang::FindMinimalNode(checker->parser.AST().Root(), clientRange);
}
if (selectedNode.has_value()) {
const auto start = std::max(selectedNode.value()->pos.start - prefixLen, 0);
const auto end = std::min(selectedNode.value()->pos.finish - prefixLen, astText.GetLength());
auto format = design::CharFormatRE();
format.dwMask = CFM_BACKCOLOR;
format.crBackColor = (GetStyle() & ES_READONLY) == 0 ? clrBg : clrReadOnlyBg;
SetSel(start, end);
SetSelectionCharFormat(format);
}
} }
auto selectedNode = activeNode;
if (!navigatorEnabled) {
const auto clientRange = StrRange{ selection.start + prefixLen, selection.finish + prefixLen };
selectedNode = ccl::rslang::FindMinimalNode(checker->AST().Root(), clientRange);
}
if (selectedNode.has_value()) {
const auto start = std::max(selectedNode.value()->pos.start - prefixLen, 0);
const auto end = std::min(selectedNode.value()->pos.finish - prefixLen, astText.GetLength());
auto format = design::CharFormatRE();
format.dwMask = CFM_BACKCOLOR;
format.crBackColor = (GetStyle() & ES_READONLY) == 0 ? clrBg : clrReadOnlyBg;
SetSel(start, end);
SetSelectionCharFormat(format);
}
} }
void RSEdit::FormatIdentifier(const ccl::rslang::TokenID tid, const StrRange pos) { void RSEdit::FormatIdentifier(const ccl::rslang::TokenID tid, const StrRange pos) {
@ -506,21 +508,24 @@ void RSEdit::AddReference() {
} }
BOOL RSEdit::NavigatorOn() { BOOL RSEdit::NavigatorOn() {
using ccl::rslang::FindMinimalNode;
if (navigatorEnabled) { if (navigatorEnabled) {
return TRUE; return TRUE;
} else if (!checker->isParsed) { }
if (!checker->IsParsed()) {
activeNode = std::nullopt; activeNode = std::nullopt;
MessageBeep(MB_ICONERROR); MessageBeep(MB_ICONERROR);
return FALSE; return FALSE;
} else { }
navigatorEnabled = TRUE;
const auto sel = GetSelectionRange(); navigatorEnabled = TRUE;
activeNode = FindMinimalNode(checker->parser.AST().Root(), const auto sel = GetSelectionRange();
StrRange{ sel.start + prefixLen, sel.finish + prefixLen }); activeNode = ccl::rslang::FindMinimalNode(
return TRUE; checker->AST().Root(),
} StrRange{ sel.start + prefixLen, sel.finish + prefixLen }
);
return TRUE;
} }
BOOL RSEdit::MoveUp() noexcept { BOOL RSEdit::MoveUp() noexcept {
@ -529,13 +534,13 @@ BOOL RSEdit::MoveUp() noexcept {
BOOL RSEdit::MoveDown() { BOOL RSEdit::MoveDown() {
if (!activeNode.has_value() || activeNode->ChildrenCount() == 0) { if (!activeNode.has_value() || activeNode->ChildrenCount() == 0) {
return false; return FALSE;
} else if (activeNode->IsRoot()) { } else if (activeNode->IsRoot()) {
activeNode->MoveToChild(1); // Note: Для корневого узла перывым потомком является сама конституента activeNode->MoveToChild(1); // Note: Для корневого узла перывым потомком является сама конституента
return true; return TRUE;
} else { } else {
activeNode->MoveToChild(0); activeNode->MoveToChild(0);
return true; return TRUE;
} }
} }