-
- {/*
*/}
+
+
Ошибок: {errorCount} | Предупреждений: {warningsCount}
+ {data.errors.map(error => {
+ return (
+
+ {error.isCritical ? 'Ошибка' : 'Предупреждение'} {getRSErrorPrefix(error)}:
+ {getRSErrorMessage(error)}
+
+ );
+ })}
+ {data.astText &&
+
+
+ {data.astText}
+
}
)
}
diff --git a/rsconcept/frontend/src/pages/RSFormPage/elements/StatusBar.tsx b/rsconcept/frontend/src/pages/RSFormPage/elements/StatusBar.tsx
index b5b770c2..a7c24e03 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/elements/StatusBar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/elements/StatusBar.tsx
@@ -1,11 +1,11 @@
import { useMemo } from 'react';
-import { ExpressionParse,ExpressionStatus, type IConstituenta, inferStatus, ParsingStatus } from '../../../utils/models';
+import { ExpressionStatus, type IConstituenta, IExpressionParse,inferStatus, ParsingStatus } from '../../../utils/models';
import { getStatusInfo } from '../../../utils/staticUI';
interface StatusBarProps {
isModified?: boolean
- parseData?: ExpressionParse
+ parseData?: IExpressionParse
constituenta?: IConstituenta
}
diff --git a/rsconcept/frontend/src/pages/RSFormPage/elements/ViewSideConstituents.tsx b/rsconcept/frontend/src/pages/RSFormPage/elements/ViewSideConstituents.tsx
index f95db7f0..641379f5 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/elements/ViewSideConstituents.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/elements/ViewSideConstituents.tsx
@@ -75,7 +75,7 @@ function ViewSideConstituents({ expression }: ViewSideConstituentsProps) {
name: 'Описание',
id: 'description',
selector: (cst: IConstituenta) =>
- cst.term?.resolved ?? cst.definition?.text.resolved ?? cst.definition?.formal ?? cst.convention ?? '',
+ cst.term.resolved || cst.definition.text.resolved || cst.definition.formal || cst.convention,
minWidth: '350px',
wrap: true,
conditionalCellStyles: [
diff --git a/rsconcept/frontend/src/pages/RSFormPage/elements/textEditing.ts b/rsconcept/frontend/src/pages/RSFormPage/elements/textEditing.ts
index 22448077..78fb79f4 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/elements/textEditing.ts
+++ b/rsconcept/frontend/src/pages/RSFormPage/elements/textEditing.ts
@@ -171,6 +171,7 @@ export class TextWrapper implements IManagedText {
case 'q': return this.insertToken(TokenID.BIGPR);
case 'w': return this.insertToken(TokenID.SMALLPR);
case 'e': return this.insertToken(TokenID.BOOLEAN);
+ case 'E': return this.insertToken(TokenID.DECART);
case 'r': return this.insertToken(TokenID.REDUCE);
case 't': return this.insertToken(TokenID.NT_RECURSIVE_FULL);
case 'a': return this.insertToken(TokenID.INTERSECTION);
diff --git a/rsconcept/frontend/src/utils/backendAPI.ts b/rsconcept/frontend/src/utils/backendAPI.ts
index c9345656..24242aad 100644
--- a/rsconcept/frontend/src/utils/backendAPI.ts
+++ b/rsconcept/frontend/src/utils/backendAPI.ts
@@ -5,14 +5,14 @@ import { type ErrorInfo } from '../components/BackendError'
import { FilterType, RSFormsFilter } from '../hooks/useRSForms'
import { config } from './constants'
import {
- ExpressionParse,
IConstituentaList,
IConstituentaMeta,
ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstUpdateData,
- ICurrentUser, IRSFormCreateData, IRSFormData,
+ ICurrentUser, IExpressionParse,
+IRSExpression,
+IRSFormCreateData, IRSFormData,
IRSFormMeta, IRSFormUpdateData, IRSFormUploadData, IUserInfo,
- IUserLoginData, IUserProfile, IUserSignupData, RSExpression
-} from './models'
+ IUserLoginData, IUserProfile, IUserSignupData} from './models'
// ================ Data transfer types ================
export type DataCallback
= (data: ResponseData) => void;
@@ -201,7 +201,7 @@ export function patchMoveConstituenta(schema: string, request: FrontExchange) {
+export function postCheckExpression(schema: string, request: FrontExchange) {
AxiosPost({
title: `Check expression for RSForm id=${schema}: ${request.data.expression }`,
endpoint: `${config.url.BASE}rsforms/${schema}/check/`,
diff --git a/rsconcept/frontend/src/utils/enums.ts b/rsconcept/frontend/src/utils/enums.ts
index 9458f31e..4ae91c97 100644
--- a/rsconcept/frontend/src/utils/enums.ts
+++ b/rsconcept/frontend/src/utils/enums.ts
@@ -103,58 +103,72 @@ export enum TokenID {
END,
}
-export enum RSError {
-
+export enum RSErrorClass {
+ LEXER,
+ PARSER,
+ SEMANTIC,
+ UNKNOWN
}
- // '8201': 'Число превышает максимально допустимое значение 2147483647!',
- // '8203': 'Нераспознанный символ!',
- // '8400': 'Неопределенная синтаксическая ошибка!',
- // '8406': 'Пропущена скобка ‘)’!',
- // '8407': 'Пропущена скобка ‘}’!',
- // '8408': 'Некорректная кванторная декларация переменной!',
- // '8414': 'Некорректное объявление аргументов функции!',
- // '8415': 'Некорректное имя локальной переменной в декларации функции!',
- // '2801': 'Повторное объявление локальной переменной!',
- // '2802': 'Локальная переменная объявлена, но не использована!',
- // '8801': 'Использование необъявленной локальной переменной!',
- // '8802': 'Повторное объявление локальной переменной внутри области действия!',
- // '8803': 'Типизация операндов не совпадает!',
- // '8804': 'Использована конституента с неопределенной типизацией!',
- // '8805': 'Одна из проекций декартова произведения не является типизированным множеством имеющим характер множества!',
- // '8806': 'Аргумент булеана не является типизированным множеством имеющим характер множества!',
- // '8807': 'Операнд теоретико-множественного оператора не является типизированным множеством имеющим характер множества!',
- // '8808': 'Операнд оператора card не является типизированным множеством имеющим характер множества!',
- // '8809': 'Операнд оператора debool не является типизированным множеством имеющим характер множества!',
- // '880A': 'Неизвестное имя функции!',
- // '880B': 'Некорректное использование имени функции без аргументов!',
- // '8810': 'Операнд оператора red не является типизированным множеством имеющим характер двойного булеана!',
- // '8811': 'Некорректная типизация аргумента: проекция не определена!',
- // '8812': 'Некорректная типизация аргумента: T(Pri(a)) = B(Pi(D(T(a))))!',
- // '8813': 'Типизация элементов перечисления не совпадает!',
- // '8814': 'Некорректная декларация связанных локальных переменных: количестве переменных в кортеже не соответствует размерности декартова произведения типизации!',
- // '8815': 'Локальная переменная используется вне области действия!',
- // '8816': 'Несоответствие типизаций операндов для предиката!',
- // '8818': 'Некорректное количество аргументов терм-функции!',
- // '8819': 'Типизация аргумента терм-функции не совпадает с объявленной!',
- // '881A': 'Сравнение кортежа или элемента с пустым множеством!',
- // '881C': 'Выражение родовой структуры должно быть ступенью!',
- // '881F': 'Ожидалось выражение объявления функции!',
- // '8820': 'Некорректное использование пустого множества как типизированного выражения!',
- // '8821': 'Радикалы запрещены вне деклараций терм-функций!',
- // '8822': 'Типизация аргумента фильтра не корректна!',
- // '8823': 'Количество параметров фильтра не соответствует количеству индексов!',
- // '8824': 'Для выбранного типа не поддерживаются арифметические операции!',
- // '8825': 'Типизации не совместимы для выбранной операции/предиката!',
- // '8826': 'Для выбранного типа не поддерживаются предикаты порядка!',
- // '8840': 'Используется неинтерпретируемый глобальный идентификатор!',
- // '8841': 'Использование свойства в качестве значения!',
- // '8842': 'Не удалось получить дерево разбора для глобального идентификатора!',
- // '8843': 'Функция не интерпретируется для данных аргументов!',
- // '8A00': 'Неизвестная ошибка: вычисление прервано!',
- // '8A01': 'Превышен пределен количества элементов множества!',
- // '8A02': 'Превышен пределен количества элементов в основании булеана!',
- // '8A03': 'Использование конституенты с неопределенным значением!',
- // '8A04': 'Превышен предел количества итераций!',
- // '8A05': 'Попытка взять debool от многоэлементного множества!',
- // '8A06': 'Попытка перебрать бесконечное множество!'
\ No newline at end of file
+export enum RSErrorType {
+ syntax = 0x8400, // Неизвестная синтаксическая ошибка
+ missingParanthesis = 0x8406, // Пропущена скобка ')'
+ missingCurlyBrace = 0x8407, // Пропущена скобка '}'
+ invalidQuantifier = 0x8408, // Некорректная кванторная декларация
+ expectedArgDeclaration = 0x8414, // Ожидалось объявление аргументов
+ expectedLocal = 0x8415, // Ожидалось имя локальной переменной
+ localDoubleDeclare = 0x2801, // Повторное использование одного и того же имени переменной
+ localNotUsed = 0x2802, // Переменная объявлена но не использована
+
+ localUndeclared = 0x8801, // Использование необъявленной переменной
+ localShadowing = 0x8802, // Повторное объявление переменной
+
+ typesNotEqual = 0x8803, // Некорректное использование операций
+ globalNotTyped = 0x8804, // Не определена типизация глобальной конституенты
+ invalidDecart = 0x8805, // Одна из проекций не является множеством
+ invalidBoolean = 0x8806, // Попытка взять булеан от элемента, не имеющего характер множества
+ invalidTypeOperation = 0x8807, // Применение ТМО к операндам, не имеющим характер множества
+ invalidCard = 0x8808, // Мощность множества не определена для элемента
+ invalidDebool = 0x8809, // Дебулеан берется от немножества
+ globalFuncMissing = 0x880A, // Неизвестное имя функции
+ globalFuncWithoutArgs = 0x880B, // Некорректное использование имени функции без аргументов
+ invalidReduce = 0x8810, // Red можно брать только от двойного булеана
+ invalidProjectionTuple = 0x8811, // Не определена проекция
+ invalidProjectionSet = 0x8812, // Большая проекция определена только для множеств!
+ invalidEnumeration = 0x8813, // Типизация аргументов перечисления не совпадает
+ ivalidBinding = 0x8814, // Количество переменных в кортеже не соответствует размерности декартова произведения
+ localOutOfScope = 0x8815, // Использование имени вне области видимости
+ invalidElementPredicat = 0x8816, // Несоответствие типов для проверки принадлежности
+ invalidArgsArtity = 0x8818, // Некорректное количество аргументов терм-функции
+ invalidArgumentType = 0x8819, // Типизация аргумента не совпадает с объявленной
+ invalidEqualsEmpty = 0x881A, // Сравнение с пустым множеством не множества
+ globalStructure = 0x881C, // Родовая структура должна быть ступенью
+ globalExpectedFunction = 0x881F, // Ожидалось выражение объявления функции
+ emptySetUsage = 0x8820, // Некорректное использование пустого множества как типизированного выражения
+ radicalUsage = 0x8821, // Радикалы запрещены вне деклараций терм-функций
+ invalidFilterArgumentType = 0x8822, // Типизация аргумента фильтра не корректна
+ invalidFilterArity = 0x8823, // Количество параметров фильра не соответствует количеству индексов
+ arithmeticNotSupported = 0x8824, // Для данного типа не поддерживается арифметика
+ typesNotCompatible = 0x8825, // Типы не совместимы в данном контексте
+ orderingNotSupported = 0x8826, // Для данного типа не поддерживается порядок элементов
+
+ globalNoValue = 0x8840, // Используется неинтерпретируемый глобальный идентификатор
+ invalidPropertyUsage = 0x8841, // Использование свойства в качестве значения
+ globalMissingAST = 0x8842, // Не удалось получить дерево разбора для глобального идентификатора
+ globalFuncNoInterpretation = 0x8843, // Функция не интерпретируется для данных аргументов
+}
+
+const ERRCODE_LEXER_MASK = 0x0200;
+const ERRCODE_PARSER_MASK = 0x0400;
+const ERRCODE_TYPE_MASK = 0x0800;
+export function resolveErrorClass(error: RSErrorType): RSErrorClass {
+ if ((error & ERRCODE_LEXER_MASK) != 0) {
+ return RSErrorClass.LEXER;
+ } else if ((error & ERRCODE_PARSER_MASK) != 0) {
+ return RSErrorClass.PARSER;
+ } else if ((error & ERRCODE_TYPE_MASK) != 0) {
+ return RSErrorClass.SEMANTIC;
+ } else {
+ return RSErrorClass.UNKNOWN;
+ }
+}
diff --git a/rsconcept/frontend/src/utils/models.ts b/rsconcept/frontend/src/utils/models.ts
index 9487f637..2dc456d6 100644
--- a/rsconcept/frontend/src/utils/models.ts
+++ b/rsconcept/frontend/src/utils/models.ts
@@ -1,3 +1,5 @@
+import { RSErrorType, TokenID } from './enums'
+
// ========= Users ===========
export interface IUser {
id: number | null
@@ -21,45 +23,53 @@ export interface IUserSignupData extends Omit {
export interface IUserProfile extends Omit {}
export interface IUserInfo extends Omit {}
-// ======== Parsing ============
-// ValueClass
-export enum ValueClass {
- INVALID = 'invalid',
- VALUE = 'value',
- PROPERTY = 'property'
-}
-
-// Syntax
+// ======== RS Parsing ============
export enum Syntax {
UNDEF = 'undefined',
ASCII = 'ascii',
MATH = 'math'
}
-// ParsingStatus
+export enum ValueClass {
+ INVALID = 'invalid',
+ VALUE = 'value',
+ PROPERTY = 'property'
+}
+
export enum ParsingStatus {
UNDEF = 'undefined',
VERIFIED = 'verified',
INCORRECT = 'incorrect'
}
-export interface RSErrorDescription {
- errorType: number
+export interface IRSErrorDescription {
+ errorType: RSErrorType
position: number
isCritical: boolean
params: string[]
}
-export interface ExpressionParse {
+export interface ISyntaxTreeNode {
+ uid: number
+ parent: number
+ typeID: TokenID
+ start: number
+ finish: number
+ data: unknown
+}
+export type SyntaxTree = ISyntaxTreeNode[]
+
+export interface IExpressionParse {
parseResult: boolean
syntax: Syntax
typification: string
valueClass: ValueClass
+ errors: IRSErrorDescription[]
astText: string
- errors: RSErrorDescription[]
+ ast: SyntaxTree
}
-export interface RSExpression {
+export interface IRSExpression {
expression: string
}
diff --git a/rsconcept/frontend/src/utils/staticUI.ts b/rsconcept/frontend/src/utils/staticUI.ts
index e7c6ee5a..27eeabb2 100644
--- a/rsconcept/frontend/src/utils/staticUI.ts
+++ b/rsconcept/frontend/src/utils/staticUI.ts
@@ -1,5 +1,5 @@
-import { TokenID } from './enums';
-import { CstType, ExpressionStatus, type IConstituenta, type IRSForm, ParsingStatus, ValueClass } from './models';
+import { resolveErrorClass,RSErrorClass, RSErrorType, TokenID } from './enums';
+import { CstType, ExpressionStatus, type IConstituenta, IRSErrorDescription,type IRSForm, ParsingStatus, ValueClass } from './models';
export interface IRSButtonData {
text: string
@@ -30,7 +30,7 @@ export function getRSButtonData(id: TokenID): IRSButtonData {
};
case TokenID.DECART: return {
text: '×',
- tooltip: 'Декартово произведение [Shift + 8]'
+ tooltip: 'Декартово произведение [Shift + 8 / Alt + Shift + E]'
};
case TokenID.PUNC_PL: return {
text: '( )',
@@ -321,4 +321,104 @@ export function getCloneTitle(schema: IRSForm): string {
} else {
return (schema.title + '+');
}
-}
\ No newline at end of file
+}
+
+export function getRSErrorPrefix(error: IRSErrorDescription): string {
+ const id = error.errorType.toString(16)
+ switch(resolveErrorClass(error.errorType)) {
+ case RSErrorClass.LEXER: return 'L' + id;
+ case RSErrorClass.PARSER: return 'P' + id;
+ case RSErrorClass.SEMANTIC: return 'S' + id;
+ case RSErrorClass.UNKNOWN: return 'U' + id;
+ }
+}
+
+export function getRSErrorMessage(error: IRSErrorDescription): string {
+ switch (error.errorType) {
+ case RSErrorType.syntax:
+ return 'UNKNOWN SYNTAX ERROR';
+ case RSErrorType.missingParanthesis:
+ return 'Некорректная конструкция языка родов структур, проверьте структуру выражения';
+ case RSErrorType.missingCurlyBrace:
+ return "Пропущен символ '}'";
+ case RSErrorType.invalidQuantifier:
+ return 'Некорректная кванторная декларация';
+ case RSErrorType.expectedArgDeclaration:
+ return 'Ожидалось объявление аргументов терм-функции';
+ case RSErrorType.expectedLocal:
+ return 'Ожидалось имя локальной переменной';
+
+ case RSErrorType.localDoubleDeclare:
+ return `Предупреждение! Повторное объявление локальной переменной ${error.params[0]}`;
+ case RSErrorType.localNotUsed:
+ return `Предупреждение! Переменная объявлена но не использована: ${error.params[0]}`;
+ case RSErrorType.localShadowing:
+ return `Повторное объявление переменной: ${error.params[0]}`;
+
+ case RSErrorType.typesNotEqual:
+ return `Типизация операндов не совпадает! ${error.params[0]} != ${error.params[1]}`;
+ case RSErrorType.globalNotTyped:
+ return `Типизация конституенты не определена: ${error.params[0]}`;
+ case RSErrorType.invalidDecart:
+ return `τ(α×b) = ℬ(𝔇τ(α)×𝔇τ(b)). Некорректная типизация аргумента: ${error.params[0]}`;
+ case RSErrorType.invalidBoolean:
+ return `τ(ℬ(a)) = ℬℬ𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
+ case RSErrorType.invalidTypeOperation:
+ return `Типизация операнда теоретико-множественной операции не корректна: ${error.params[0]}`;
+ case RSErrorType.invalidCard:
+ return `Некорректная типизация аргумента операции мощности: ${error.params[0]}`;
+ case RSErrorType.invalidDebool:
+ return `τ(debool(a)) = 𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
+ case RSErrorType.globalFuncMissing:
+ return `Неизвестное имя функции: ${error.params[0]}`;
+ case RSErrorType.globalFuncWithoutArgs:
+ return `Некорректное использование имени функции без аргументов: ${error.params[0]}`;
+ case RSErrorType.invalidReduce:
+ return `τ(red(a)) = ℬ𝔇𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
+ case RSErrorType.invalidProjectionTuple:
+ return `Проекция не определена: ${error.params[0]} -> ${error.params[1]}`;
+ case RSErrorType.invalidProjectionSet:
+ return `τ(Pri(a)) = ℬ𝒞i𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
+ case RSErrorType.invalidEnumeration:
+ return `Типизация аргументов перечисления не совпадает: ${error.params[0]} != ${error.params[1]}`;
+ case RSErrorType.ivalidBinding:
+ return `Количество переменных в кортеже не соответствует размерности декартова произведения`;
+ case RSErrorType.localOutOfScope:
+ return `Использование имени переменной вне области действия: ${error.params[0]}`;
+ case RSErrorType.invalidElementPredicat:
+ return `Несоответствие типизаций операндов для оператора: ${error.params[0]}${error.params[1]}${error.params[2]}`;
+ case RSErrorType.invalidArgsArtity:
+ return `Неверное число аргументов терм-функции: ${error.params[0]} != ${error.params[1]}`;
+ case RSErrorType.invalidArgumentType:
+ return `Типизация аргумента терм-функции не соответствует объявленной: ${error.params[0]} != ${error.params[1]}`;
+ case RSErrorType.invalidEqualsEmpty:
+ return `Только множества можно сравнивать с пустым множеством: ${error.params[0]}`;
+ case RSErrorType.globalStructure:
+ return `Выражение родовой структуры должно быть ступенью`;
+ case RSErrorType.globalExpectedFunction:
+ return `Ожидалось выражение объявления функции`;
+ case RSErrorType.emptySetUsage:
+ return `Запрещено использование пустого множества как типизированного выражения`;
+ case RSErrorType.radicalUsage:
+ return `Радикалы запрещены вне деклараций терм-функци: ${error.params[0]}`;
+ case RSErrorType.invalidFilterArgumentType:
+ return `Типизация аргумента фильтра не корректна: ${error.params[0]}(${error.params[1]})`;
+ case RSErrorType.invalidFilterArity:
+ return `Количество параметров фильтра не соответствует количеству индексов`;
+ case RSErrorType.arithmeticNotSupported:
+ return `Тип не поддерживает арифметические операторы: ${error.params[0]}`;
+ case RSErrorType.typesNotCompatible:
+ return `Типы не совместимы для выбранной операции: ${error.params[0]} и ${error.params[1]}`;
+ case RSErrorType.orderingNotSupported:
+ return `Тип не поддерживает предикаты порядка: ${error.params[0]}`;
+ case RSErrorType.globalNoValue:
+ return `Используется неинтерпретируемый глобальный идентификатор: ${error.params[0]}`;
+ case RSErrorType.invalidPropertyUsage:
+ return `Использование неитерируемого множества в качестве значения`;
+ case RSErrorType.globalMissingAST:
+ return `Не удалось получить дерево разбора для глобального идентификатора: ${error.params[0]}`;
+ case RSErrorType.globalFuncNoInterpretation:
+ return `Функция не интерпретируется для данных аргументов`;
+ }
+ return 'UNKNOWN ERROR';
+}