Restructure models files

This commit is contained in:
IRBorisov 2023-09-11 20:31:54 +03:00
parent 67eff6c9fc
commit 3e416564b5
57 changed files with 790 additions and 660 deletions

View File

@ -1,5 +1,5 @@
import { LibraryFilterStrategy } from '../../models/miscelanious';
import { urls } from '../../utils/constants'; import { urls } from '../../utils/constants';
import { LibraryFilterStrategy } from '../../utils/models';
import TextURL from '../Common/TextURL'; import TextURL from '../Common/TextURL';
function HelpMain() { function HelpMain() {

View File

@ -1,4 +1,4 @@
import { IConstituenta } from '../../utils/models'; import { IConstituenta } from '../../models/rsform';
import { getCstTypificationLabel } from '../../utils/staticUI'; import { getCstTypificationLabel } from '../../utils/staticUI';
interface InfoConstituentaProps interface InfoConstituentaProps

View File

@ -1,7 +1,7 @@
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { LibraryFilterStrategy } from '../../utils/models'; import { LibraryFilterStrategy } from '../../models/miscelanious';
import Dropdown from '../Common/Dropdown'; import Dropdown from '../Common/Dropdown';
import DropdownButton from '../Common/DropdownButton'; import DropdownButton from '../Common/DropdownButton';

View File

@ -8,7 +8,7 @@ import { RefObject, useCallback, useMemo, useRef } from 'react';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { TokenID } from '../../utils/enums'; import { TokenID } from '../../models/rslang';
import Label from '../Common/Label'; import Label from '../Common/Label';
import { ccBracketMatching } from './bracketMatching'; import { ccBracketMatching } from './bracketMatching';
import { RSLanguage } from './rslang'; import { RSLanguage } from './rslang';

View File

@ -2,7 +2,7 @@
import { ReactCodeMirrorRef } from '@uiw/react-codemirror'; import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
import { TokenID } from '../../utils/enums'; import { TokenID } from '../../models/rslang';
export function getSymbolSubstitute(keyCode: string, shiftPressed: boolean): string | undefined { export function getSymbolSubstitute(keyCode: string, shiftPressed: boolean): string | undefined {
if (shiftPressed) { if (shiftPressed) {

View File

@ -1,7 +1,7 @@
import { Extension } from '@codemirror/state'; import { Extension } from '@codemirror/state';
import { hoverTooltip } from '@codemirror/view'; import { hoverTooltip } from '@codemirror/view';
import { IConstituenta } from '../../utils/models'; import { IConstituenta } from '../../models/rsform';
import { getCstTypificationLabel } from '../../utils/staticUI'; import { getCstTypificationLabel } from '../../utils/staticUI';
function createTooltipFor(cst: IConstituenta) { function createTooltipFor(cst: IConstituenta) {

View File

@ -2,8 +2,13 @@ import { createContext, useCallback, useContext, useLayoutEffect, useState } fro
import { type ErrorInfo } from '../components/BackendError'; import { type ErrorInfo } from '../components/BackendError';
import useLocalStorage from '../hooks/useLocalStorage'; import useLocalStorage from '../hooks/useLocalStorage';
import { IUserLoginData } from '../models/library';
import { ICurrentUser } from '../models/library';
import { IUserSignupData } from '../models/library';
import { IUserProfile } from '../models/library';
import { IUserInfo } from '../models/library';
import { IUserUpdatePassword } from '../models/library';
import { type DataCallback, getAuth, patchPassword,postLogin, postLogout, postSignup } from '../utils/backendAPI'; import { type DataCallback, getAuth, patchPassword,postLogin, postLogout, postSignup } from '../utils/backendAPI';
import { ICurrentUser, IUserInfo, IUserLoginData, IUserProfile, IUserSignupData, IUserUpdatePassword } from '../utils/models';
import { useUsers } from './UsersContext'; import { useUsers } from './UsersContext';
interface IAuthContext { interface IAuthContext {

View File

@ -1,8 +1,11 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { ErrorInfo } from '../components/BackendError'; import { ErrorInfo } from '../components/BackendError';
import { ILibraryFilter } from '../models/miscelanious';
import { IRSFormCreateData, IRSFormData } from '../models/rsform';
import { matchLibraryItem } from '../models/library';
import { ILibraryItem } from '../models/library';
import { DataCallback, deleteLibraryItem, getLibrary, postCloneLibraryItem, postNewRSForm } from '../utils/backendAPI'; import { DataCallback, deleteLibraryItem, getLibrary, postCloneLibraryItem, postNewRSForm } from '../utils/backendAPI';
import { ILibraryFilter, ILibraryItem, IRSFormCreateData, IRSFormData, matchLibraryItem } from '../utils/models';
import { useAuth } from './AuthContext'; import { useAuth } from './AuthContext';
interface ILibraryContext { interface ILibraryContext {

View File

@ -2,6 +2,13 @@ import { createContext, useCallback, useContext, useMemo, useState } from 'react
import { type ErrorInfo } from '../components/BackendError' import { type ErrorInfo } from '../components/BackendError'
import { useRSFormDetails } from '../hooks/useRSFormDetails' import { useRSFormDetails } from '../hooks/useRSFormDetails'
import { ILibraryItem } from '../models/library'
import {
IConstituentaList, IConstituentaMeta, ICstCreateData,
ICstMovetoData, ICstRenameData, ICstUpdateData,
IRSForm, IRSFormUploadData
} from '../models/rsform'
import { ILibraryUpdateData } from '../models/library'
import { import {
type DataCallback, deleteUnsubscribe, type DataCallback, deleteUnsubscribe,
getTRSFile, getTRSFile,
@ -9,11 +16,6 @@ getTRSFile,
patchLibraryItem, patchLibraryItem,
patchMoveConstituenta, patchRenameConstituenta, patchMoveConstituenta, patchRenameConstituenta,
patchResetAliases, patchUploadTRS, postClaimLibraryItem, postNewConstituenta, postSubscribe} from '../utils/backendAPI' patchResetAliases, patchUploadTRS, postClaimLibraryItem, postNewConstituenta, postSubscribe} from '../utils/backendAPI'
import {
IConstituentaList, IConstituentaMeta, ICstCreateData,
ICstMovetoData, ICstRenameData, ICstUpdateData, ILibraryItem,
ILibraryUpdateData, IRSForm, IRSFormUploadData
} from '../utils/models'
import { useAuth } from './AuthContext' import { useAuth } from './AuthContext'
import { useLibrary } from './LibraryContext' import { useLibrary } from './LibraryContext'

View File

@ -1,8 +1,9 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { ErrorInfo } from '../components/BackendError'; import { ErrorInfo } from '../components/BackendError';
import { IUserProfile } from '../models/library';
import { IUserUpdateData } from '../models/library';
import { DataCallback, getProfile, patchProfile } from '../utils/backendAPI'; import { DataCallback, getProfile, patchProfile } from '../utils/backendAPI';
import { IUserProfile, IUserUpdateData } from '../utils/models';
import { useUsers } from './UsersContext'; import { useUsers } from './UsersContext';
interface IUserProfileContext { interface IUserProfileContext {

View File

@ -1,7 +1,7 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { type IUserInfo } from '../models/library';
import { getActiveUsers } from '../utils/backendAPI'; import { getActiveUsers } from '../utils/backendAPI';
import { type IUserInfo } from '../utils/models';
interface IUsersContext { interface IUsersContext {
users: IUserInfo[] users: IUserInfo[]

View File

@ -1,9 +1,10 @@
import { useCallback, useState } from 'react' import { useCallback, useState } from 'react'
import { type ErrorInfo } from '../components/BackendError'; import { type ErrorInfo } from '../components/BackendError';
import { CstType, IConstituenta, type IRSForm } from '../models/rsform';
import { IExpressionParse, IFunctionArg } from '../models/rslang';
import { RSErrorType } from '../models/rslang';
import { DataCallback, postCheckExpression } from '../utils/backendAPI'; import { DataCallback, postCheckExpression } from '../utils/backendAPI';
import { RSErrorType } from '../utils/enums';
import { CstType, IConstituenta, IExpressionParse, IFunctionArg, type IRSForm } from '../utils/models';
import { getCstExpressionPrefix } from '../utils/staticUI'; import { getCstExpressionPrefix } from '../utils/staticUI';
const LOGIC_TYPIIFCATION = 'LOGIC'; const LOGIC_TYPIIFCATION = 'LOGIC';

View File

@ -1,8 +1,8 @@
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { type ErrorInfo } from '../components/BackendError'; import { type ErrorInfo } from '../components/BackendError';
import { IRSForm, IRSFormData,loadRSFormData } from '../models/rsform'
import { getRSFormDetails } from '../utils/backendAPI'; import { getRSFormDetails } from '../utils/backendAPI';
import { IRSForm, IRSFormData,LoadRSFormData } from '../utils/models'
export function useRSFormDetails({ target }: { target?: string }) { export function useRSFormDetails({ target }: { target?: string }) {
const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined); const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined);
@ -14,7 +14,7 @@ export function useRSFormDetails({ target }: { target?: string }) {
setInnerSchema(undefined); setInnerSchema(undefined);
return; return;
} }
const schema = LoadRSFormData(data); const schema = loadRSFormData(data);
setInnerSchema(schema); setInnerSchema(schema);
} }

View File

@ -1,8 +1,9 @@
import { useCallback, useState } from 'react' import { useCallback, useState } from 'react'
import { ErrorInfo } from '../components/BackendError'; import { ErrorInfo } from '../components/BackendError';
import { IReferenceData } from '../models/language';
import { IRSForm } from '../models/rsform';
import { DataCallback, postResolveText } from '../utils/backendAPI'; import { DataCallback, postResolveText } from '../utils/backendAPI';
import { IReferenceData,IRSForm } from '../utils/models';
function useResolveText({ schema }: { schema?: IRSForm }) { function useResolveText({ schema }: { schema?: IRSForm }) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);

View File

@ -0,0 +1,42 @@
// Module: Natural language model declarations.
// ====== Text morphology ========
// ====== Reference resolution =====
export interface IRefsText {
text: string
}
export enum ReferenceType {
ENTITY = 'entity',
SYNTACTIC = 'syntax'
}
export interface IEntityReference {
entity: string
form: string
}
export interface ISyntacticReference {
offset: number
nominal: string
}
export interface ITextPosition {
start: number
finish: number
}
export interface IResolvedReference {
type: ReferenceType
data: IEntityReference | ISyntacticReference
pos_input: ITextPosition
pos_output: ITextPosition
}
export interface IReferenceData {
input: string
output: string
refs: IResolvedReference[]
}

View File

@ -0,0 +1,65 @@
// Module: Schema library models.
// ========= Users ===========
export interface IUser {
id: number | null
username: string
is_staff: boolean
email: string
first_name: string
last_name: string
}
export interface ICurrentUser extends Pick<IUser, 'id' | 'username' | 'is_staff'> {
subscriptions: number[]
}
export interface IUserLoginData extends Pick<IUser, 'username'> {
password: string
}
export interface IUserSignupData extends Omit<IUser, 'is_staff' | 'id'> {
password: string
password2: string
}
export interface IUserUpdateData extends Omit<IUser, 'is_staff' | 'id'> { }
export interface IUserProfile extends Omit<IUser, 'is_staff'> { }
export interface IUserInfo extends Omit<IUserProfile, 'email'> { }
export interface IUserUpdatePassword {
old_password: string
new_password: string
}
// ========== LibraryItem ============
export enum LibraryItemType {
RSFORM = 'rsform',
OPERATIONS_SCHEMA = 'oss'
}
export interface ILibraryItem {
id: number
item_type: LibraryItemType
title: string
alias: string
comment: string
is_common: boolean
is_canonical: boolean
time_create: string
time_update: string
owner: number | null
}
export interface ILibraryUpdateData
extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'id' | 'owner'> {
}
// ============= API ===============
export function matchLibraryItem(query: string, target: ILibraryItem): boolean {
const queryI = query.toUpperCase()
if (target.alias.toUpperCase().match(queryI)) {
return true
} else if (target.title.toUpperCase().match(queryI)) {
return true
} else {
return false
}
}

View File

@ -0,0 +1,80 @@
// Module: Miscellanious frontend model types.
import { IConstituenta, IRSForm } from './rsform'
// Constituenta edit mode
export enum EditMode {
TEXT = 'text',
RSLANG = 'rslang'
}
// Dependency mode for schema analysis
export enum DependencyMode {
ALL = 0,
EXPRESSION,
OUTPUTS,
INPUTS,
EXPAND_OUTPUTS,
EXPAND_INPUTS
}
// Help manual topic compare mode
export enum HelpTopic {
MAIN = 'main',
RSLANG = 'rslang',
LIBRARY = 'library',
RSFORM = 'rsform',
CSTLIST = 'cstlist',
CONSTITUENTA = 'constituenta',
GRAPH_TERM = 'graph-term',
EXTEOR = 'exteor',
API = 'api'
}
// Constituent compare mode
export enum CstMatchMode {
ALL = 1,
EXPR,
TERM,
TEXT,
NAME
}
export interface ILibraryFilter {
query?: string
is_personal?: boolean
is_owned?: boolean
is_common?: boolean
is_canonical?: boolean
is_subscribed?: boolean
}
// Library premade filters
export enum LibraryFilterStrategy {
MANUAL = 'manual',
PERSONAL = 'personal',
COMMON = 'common',
SUBSCRIBE = 'subscribe',
CANONICAL = 'canonical',
OWNED = 'owned'
}
// ================== API ====================
export function applyGraphFilter(schema: IRSForm, start: number, mode: DependencyMode): IConstituenta[] {
if (mode === DependencyMode.ALL) {
return schema.items
}
let ids: number[] | undefined = undefined
switch (mode) {
case DependencyMode.OUTPUTS: { ids = schema.graph.nodes.get(start)?.outputs; break}
case DependencyMode.INPUTS: { ids = schema.graph.nodes.get(start)?.inputs; break}
case DependencyMode.EXPAND_OUTPUTS: { ids = schema.graph.expandOutputs([start]); break}
case DependencyMode.EXPAND_INPUTS: { ids = schema.graph.expandInputs([start]); break}
}
if (!ids) {
return schema.items
} else {
return schema.items.filter(cst => ids!.find(id => id === cst.id))
}
}

View File

@ -1,135 +1,9 @@
import { RSErrorType, TokenID } from './enums' import { Graph } from '../utils/Graph'
import { Graph } from './Graph' import { ILibraryUpdateData } from './library'
import { ILibraryItem } from './library'
import { CstMatchMode } from './miscelanious'
import { IFunctionArg, ParsingStatus, ValueClass } from './rslang'
// ========= Users ===========
export interface IUser {
id: number | null
username: string
is_staff: boolean
email: string
first_name: string
last_name: string
}
export interface ICurrentUser extends Pick<IUser, 'id' | 'username' | 'is_staff'> {
subscriptions: number[]
}
export interface IUserLoginData extends Pick<IUser, 'username'> {
password: string
}
export interface IUserSignupData extends Omit<IUser, 'is_staff' | 'id'> {
password: string
password2: string
}
export interface IUserUpdateData extends Omit<IUser, 'is_staff' | 'id'> {}
export interface IUserProfile extends Omit<IUser, 'is_staff'> {}
export interface IUserInfo extends Omit<IUserProfile, 'email'> {}
export interface IUserUpdatePassword {
old_password: string
new_password: string
}
// ======== RS Parsing ============
export interface IRSExpression {
expression: string
}
export enum Syntax {
UNDEF = 'undefined',
ASCII = 'ascii',
MATH = 'math'
}
export enum ValueClass {
INVALID = 'invalid',
VALUE = 'value',
PROPERTY = 'property'
}
export enum ParsingStatus {
UNDEF = 'undefined',
VERIFIED = 'verified',
INCORRECT = 'incorrect'
}
export interface IRSErrorDescription {
errorType: RSErrorType
position: number
isCritical: boolean
params: string[]
}
export interface ISyntaxTreeNode {
uid: number
parent: number
typeID: TokenID
start: number
finish: number
data: {
dataType: string,
value: unknown
}
}
export type SyntaxTree = ISyntaxTreeNode[]
export interface IFunctionArg {
alias: string
typification: string
}
export interface IExpressionParse {
parseResult: boolean
syntax: Syntax
typification: string
valueClass: ValueClass
errors: IRSErrorDescription[]
astText: string
ast: SyntaxTree
args: IFunctionArg[]
}
// ====== Reference resolution =====
export interface IRefsText {
text: string
}
export enum ReferenceType {
ENTITY = 'entity',
SYNTACTIC = 'syntax'
}
export interface IEntityReference {
entity: string
form: string
}
export interface ISyntacticReference {
offset: number
nominal: string
}
export interface ITextPosition {
start: number
finish: number
}
export interface IResolvedReference {
type: ReferenceType
data: IEntityReference | ISyntacticReference
pos_input: ITextPosition
pos_output: ITextPosition
}
export interface IReferenceData {
input: string
output: string
refs: IResolvedReference[]
}
// ====== Constituenta ==========
export enum CstType { export enum CstType {
BASE = 'basic', BASE = 'basic',
STRUCTURED = 'structure', STRUCTURED = 'structure',
@ -148,11 +22,22 @@ export enum CstClass {
TEMPLATE = 'template' TEMPLATE = 'template'
} }
// Constituenta expression status
export enum ExpressionStatus {
UNDEFINED = 'undefined',
UNKNOWN = 'unknown',
INCORRECT = 'incorrect',
INCALCULABLE = 'incalculable',
PROPERTY = 'property',
VERIFIED = 'verified'
}
export interface TermForm { export interface TermForm {
text: string text: string
tags: string tags: string
} }
// ====== Constituenta ==========
export interface IConstituentaMeta { export interface IConstituentaMeta {
id: number id: number
schema: number schema: number
@ -207,29 +92,6 @@ export interface ICstCreatedResponse {
schema: IRSFormData schema: IRSFormData
} }
// ========== LibraryItem ============
export enum LibraryItemType {
RSFORM = 'rsform',
OPERATIONS_SCHEMA = 'oss'
}
export interface ILibraryItem {
id: number
item_type: LibraryItemType
title: string
alias: string
comment: string
is_common: boolean
is_canonical: boolean
time_create: string
time_update: string
owner: number | null
}
export interface ILibraryUpdateData
extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'id' | 'owner'> {}
// ========== RSForm ============ // ========== RSForm ============
export interface IRSFormStats { export interface IRSFormStats {
count_all: number count_all: number
@ -273,120 +135,12 @@ export interface IRSFormUploadData {
fileName: string fileName: string
} }
// ========== Library ===== // ========== API =================
export enum LibraryFilterStrategy {
MANUAL = 'manual',
PERSONAL = 'personal',
COMMON = 'common',
SUBSCRIBE = 'subscribe',
CANONICAL = 'canonical',
OWNED = 'owned'
}
export interface ILibraryFilter {
query?: string
is_personal?: boolean
is_owned?: boolean
is_common?: boolean
is_canonical?: boolean
is_subscribed?: boolean
}
// ================ Misc types ================
// Constituenta edit mode
export enum EditMode {
TEXT = 'text',
RSLANG = 'rslang'
}
// RSExpression status
export enum ExpressionStatus {
UNDEFINED = 'undefined',
UNKNOWN = 'unknown',
INCORRECT = 'incorrect',
INCALCULABLE = 'incalculable',
PROPERTY = 'property',
VERIFIED = 'verified'
}
// Dependency mode for schema analysis
export enum DependencyMode {
ALL = 0,
EXPRESSION,
OUTPUTS,
INPUTS,
EXPAND_OUTPUTS,
EXPAND_INPUTS
}
// Constituent compare mode
export enum CstMatchMode {
ALL = 1,
EXPR,
TERM,
TEXT,
NAME
}
// Help manual topic compare mode
export enum HelpTopic {
MAIN = 'main',
RSLANG = 'rslang',
LIBRARY = 'library',
RSFORM = 'rsform',
CSTLIST = 'cstlist',
CONSTITUENTA = 'constituenta',
GRAPH_TERM = 'graph-term',
EXTEOR = 'exteor',
API = 'api'
}
// ========== Model functions =================
export function inferStatus(parse?: ParsingStatus, value?: ValueClass): ExpressionStatus {
if (!parse || !value) {
return ExpressionStatus.UNDEFINED;
}
if (parse === ParsingStatus.UNDEF) {
return ExpressionStatus.UNKNOWN;
}
if (parse === ParsingStatus.INCORRECT) {
return ExpressionStatus.INCORRECT;
}
if (value === ValueClass.INVALID) {
return ExpressionStatus.INCALCULABLE;
}
if (value === ValueClass.PROPERTY) {
return ExpressionStatus.PROPERTY;
}
return ExpressionStatus.VERIFIED;
}
export function inferTemplate(expression: string): boolean {
const match = expression.match(/R\d+/g);
return (match && match?.length > 0) ?? false;
}
export function inferClass(type: CstType, isTemplate: boolean): CstClass {
if (isTemplate) {
return CstClass.TEMPLATE;
}
switch (type) {
case CstType.BASE: return CstClass.BASIC;
case CstType.CONSTANT: return CstClass.BASIC;
case CstType.STRUCTURED: return CstClass.BASIC;
case CstType.TERM: return CstClass.DERIVED;
case CstType.FUNCTION: return CstClass.DERIVED;
case CstType.AXIOM: return CstClass.STATEMENT;
case CstType.PREDICATE: return CstClass.DERIVED;
case CstType.THEOREM: return CstClass.STATEMENT;
}
}
export function extractGlobals(expression: string): Set<string> { export function extractGlobals(expression: string): Set<string> {
return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []); return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []);
} }
export function LoadRSFormData(schema: IRSFormData): IRSForm { export function loadRSFormData(schema: IRSFormData): IRSForm {
const result = schema as IRSForm const result = schema as IRSForm
result.graph = new Graph; result.graph = new Graph;
if (!result.items) { if (!result.items) {
@ -480,31 +234,43 @@ export function matchConstituenta(query: string, target: IConstituenta, mode: Cs
return false; return false;
} }
export function matchLibraryItem(query: string, target: ILibraryItem): boolean { export function inferStatus(parse?: ParsingStatus, value?: ValueClass): ExpressionStatus {
const queryI = query.toUpperCase(); if (!parse || !value) {
if (target.alias.toUpperCase().match(queryI)) { return ExpressionStatus.UNDEFINED;
return true; }
} else if (target.title.toUpperCase().match(queryI)) { if (parse === ParsingStatus.UNDEF) {
return true; return ExpressionStatus.UNKNOWN;
} else { }
return false; if (parse === ParsingStatus.INCORRECT) {
return ExpressionStatus.INCORRECT;
}
if (value === ValueClass.INVALID) {
return ExpressionStatus.INCALCULABLE;
}
if (value === ValueClass.PROPERTY) {
return ExpressionStatus.PROPERTY;
}
return ExpressionStatus.VERIFIED;
}
export function inferTemplate(expression: string): boolean {
const match = expression.match(/R\d+/g);
return (match && match?.length > 0) ?? false;
}
export function inferClass(type: CstType, isTemplate: boolean): CstClass {
if (isTemplate) {
return CstClass.TEMPLATE;
}
switch (type) {
case CstType.BASE: return CstClass.BASIC;
case CstType.CONSTANT: return CstClass.BASIC;
case CstType.STRUCTURED: return CstClass.BASIC;
case CstType.TERM: return CstClass.DERIVED;
case CstType.FUNCTION: return CstClass.DERIVED;
case CstType.AXIOM: return CstClass.STATEMENT;
case CstType.PREDICATE: return CstClass.DERIVED;
case CstType.THEOREM: return CstClass.STATEMENT;
} }
} }
export function applyGraphFilter(schema: IRSForm, start: number, mode: DependencyMode): IConstituenta[] {
if (mode === DependencyMode.ALL) {
return schema.items;
}
let ids: number[] | undefined = undefined
switch (mode) {
case DependencyMode.OUTPUTS: { ids = schema.graph.nodes.get(start)?.outputs; break; }
case DependencyMode.INPUTS: { ids = schema.graph.nodes.get(start)?.inputs; break; }
case DependencyMode.EXPAND_OUTPUTS: { ids = schema.graph.expandOutputs([start]) ; break; }
case DependencyMode.EXPAND_INPUTS: { ids = schema.graph.expandInputs([start]) ; break; }
}
if (!ids) {
return schema.items;
} else {
return schema.items.filter(cst => ids!.find(id => id === cst.id));
}
}

View File

@ -0,0 +1,245 @@
// Module: RSLang model types
// ======== RS Parsing ============
export interface IRSExpression {
expression: string
}
export enum Syntax {
UNDEF = 'undefined',
ASCII = 'ascii',
MATH = 'math'
}
export enum ValueClass {
INVALID = 'invalid',
VALUE = 'value',
PROPERTY = 'property'
}
export enum ParsingStatus {
UNDEF = 'undefined',
VERIFIED = 'verified',
INCORRECT = 'incorrect'
}
export interface IRSErrorDescription {
errorType: RSErrorType
position: number
isCritical: boolean
params: string[]
}
export interface ISyntaxTreeNode {
uid: number
parent: number
typeID: TokenID
start: number
finish: number
data: {
dataType: string
value: unknown
}
}
export type SyntaxTree = ISyntaxTreeNode[]
export interface IFunctionArg {
alias: string
typification: string
}
export interface IExpressionParse {
parseResult: boolean
syntax: Syntax
typification: string
valueClass: ValueClass
errors: IRSErrorDescription[]
astText: string
ast: SyntaxTree
args: IFunctionArg[]
}
//! RS language token types enumeration
export enum TokenID {
// Global, local IDs and literals
ID_LOCAL = 258,
ID_GLOBAL,
ID_FUNCTION,
ID_PREDICATE,
ID_RADICAL,
LIT_INTEGER,
LIT_INTSET,
LIT_EMPTYSET,
// Aithmetic
PLUS,
MINUS,
MULTIPLY,
// Integer predicate symbols
GREATER,
LESSER,
GREATER_OR_EQ,
LESSER_OR_EQ,
// Equality comparison
EQUAL,
NOTEQUAL,
// Logic predicate symbols
FORALL,
EXISTS,
NOT,
EQUIVALENT,
IMPLICATION,
OR,
AND,
// Set theory predicate symbols
IN,
NOTIN,
SUBSET,
SUBSET_OR_EQ,
NOTSUBSET,
// Set theory operators
DECART,
UNION,
INTERSECTION,
SET_MINUS,
SYMMINUS,
BOOLEAN,
// Structure operations
BIGPR,
SMALLPR,
FILTER,
CARD,
BOOL,
DEBOOL,
REDUCE,
// Term constructions prefixes
DECLARATIVE,
RECURSIVE,
IMPERATIVE,
// Punctuation
PUNC_DEFINE,
PUNC_STRUCT,
PUNC_ASSIGN,
PUNC_ITERATE,
PUNC_PL,
PUNC_PR,
PUNC_CL,
PUNC_CR,
PUNC_SL,
PUNC_SR,
PUNC_BAR,
PUNC_COMMA,
PUNC_SEMICOLON,
// ======= Non-terminal tokens =========
NT_ENUM_DECL,
NT_TUPLE,
NT_ENUMERATION,
NT_TUPLE_DECL,
NT_ARG_DECL,
NT_FUNC_DEFINITION,
NT_ARGUMENTS,
NT_FUNC_CALL,
NT_DECLARATIVE_EXPR,
NT_IMPERATIVE_EXPR,
NT_RECURSIVE_FULL,
NT_RECURSIVE_SHORT,
NT_IMP_DECLARE,
NT_IMP_ASSIGN,
NT_IMP_LOGIC,
// ======= Helper tokens ========
INTERRUPT,
END
}
export enum RSErrorType {
syntax = 33792,
missingParanthesis = 33798,
missingCurlyBrace = 33799,
invalidQuantifier = 33800,
expectedArgDeclaration = 33812,
expectedLocal = 33813,
localDoubleDeclare = 10241,
localNotUsed = 10242,
localUndeclared = 34817,
localShadowing = 34818,
typesNotEqual = 34819,
globalNotTyped = 34820,
invalidDecart = 34821,
invalidBoolean = 34822,
invalidTypeOperation = 34823,
invalidCard = 34824,
invalidDebool = 34825,
globalFuncMissing = 34826,
globalFuncWithoutArgs = 34827,
invalidReduce = 34832,
invalidProjectionTuple = 34833,
invalidProjectionSet = 34834,
invalidEnumeration = 34835,
ivalidBinding = 34836,
localOutOfScope = 34837,
invalidElementPredicat = 34838,
invalidArgsArtity = 34840,
invalidArgumentType = 34841,
invalidEqualsEmpty = 34842,
globalStructure = 34844,
globalExpectedFunction = 34847,
emptySetUsage = 34848,
radicalUsage = 34849,
invalidFilterArgumentType = 34850,
invalidFilterArity = 34851,
arithmeticNotSupported = 34852,
typesNotCompatible = 34853,
orderingNotSupported = 34854,
// !!!! Добавлены по сравнению с ConceptCore !!!!!
globalNonemptyBase = 34855,
globalUnexpectedType = 34856,
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
globalNoValue = 34880,
invalidPropertyUsage = 34881,
globalMissingAST = 34882,
globalFuncNoInterpretation = 34883
}
// Error handling
export enum RSErrorClass {
LEXER,
PARSER,
SEMANTIC,
UNKNOWN
}
const ERRCODE_LEXER_MASK = 512;
const ERRCODE_PARSER_MASK = 1024;
const ERRCODE_TYPE_MASK = 2048;
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;
}
}

View File

@ -15,8 +15,9 @@ import { UploadIcon } from '../components/Icons';
import RequireAuth from '../components/RequireAuth'; import RequireAuth from '../components/RequireAuth';
import { useLibrary } from '../context/LibraryContext'; import { useLibrary } from '../context/LibraryContext';
import { useConceptNavigation } from '../context/NagivationContext'; import { useConceptNavigation } from '../context/NagivationContext';
import { LibraryItemType } from '../models/library';
import { IRSFormCreateData } from '../models/rsform';
import { EXTEOR_TRS_FILE } from '../utils/constants'; import { EXTEOR_TRS_FILE } from '../utils/constants';
import { IRSFormCreateData, LibraryItemType } from '../utils/models';
function CreateRSFormPage() { function CreateRSFormPage() {
const location = useLocation(); const location = useLocation();

View File

@ -6,7 +6,7 @@ import DropdownCheckbox from '../../components/Common/DropdownCheckbox';
import { FilterCogIcon } from '../../components/Icons'; import { FilterCogIcon } from '../../components/Icons';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import useDropdown from '../../hooks/useDropdown'; import useDropdown from '../../hooks/useDropdown';
import { LibraryFilterStrategy } from '../../utils/models'; import { LibraryFilterStrategy } from '../../models/miscelanious';
interface PickerStrategyProps { interface PickerStrategyProps {
value: LibraryFilterStrategy value: LibraryFilterStrategy

View File

@ -5,7 +5,8 @@ import { MagnifyingGlassIcon } from '../../components/Icons';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import useLocalStorage from '../../hooks/useLocalStorage'; import useLocalStorage from '../../hooks/useLocalStorage';
import { ILibraryFilter, LibraryFilterStrategy } from '../../utils/models'; import { ILibraryFilter } from '../../models/miscelanious';
import { LibraryFilterStrategy } from '../../models/miscelanious';
import PickerStrategy from './PickerStrategy'; import PickerStrategy from './PickerStrategy';

View File

@ -10,8 +10,8 @@ import { useAuth } from '../../context/AuthContext';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { useUsers } from '../../context/UsersContext'; import { useUsers } from '../../context/UsersContext';
import useLocalStorage from '../../hooks/useLocalStorage'; import useLocalStorage from '../../hooks/useLocalStorage';
import { ILibraryItem } from '../../models/library';
import { prefixes } from '../../utils/constants'; import { prefixes } from '../../utils/constants';
import { ILibraryItem } from '../../utils/models';
interface ViewLibraryProps { interface ViewLibraryProps {
items: ILibraryItem[] items: ILibraryItem[]

View File

@ -4,7 +4,8 @@ import BackendError from '../../components/BackendError'
import { ConceptLoader } from '../../components/Common/ConceptLoader' import { ConceptLoader } from '../../components/Common/ConceptLoader'
import { useLibrary } from '../../context/LibraryContext'; import { useLibrary } from '../../context/LibraryContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { ILibraryFilter, ILibraryItem } from '../../utils/models'; import { ILibraryItem } from '../../models/library';
import { ILibraryFilter } from '../../models/miscelanious';
import SearchPanel from './SearchPanel'; import SearchPanel from './SearchPanel';
import ViewLibrary from './ViewLibrary'; import ViewLibrary from './ViewLibrary';

View File

@ -10,7 +10,7 @@ import TextURL from '../components/Common/TextURL';
import { useAuth } from '../context/AuthContext'; import { useAuth } from '../context/AuthContext';
import { useConceptNavigation } from '../context/NagivationContext'; import { useConceptNavigation } from '../context/NagivationContext';
import { useConceptTheme } from '../context/ThemeContext'; import { useConceptTheme } from '../context/ThemeContext';
import { IUserLoginData } from '../utils/models'; import { IUserLoginData } from '../models/library';
function ProcessError({error}: {error: ErrorInfo}): React.ReactElement { function ProcessError({error}: {error: ErrorInfo}): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) { if (axios.isAxiosError(error) && error.response && error.response.status === 400) {

View File

@ -1,5 +1,5 @@
import { HelpTopic } from '../../models/miscelanious';
import { prefixes } from '../../utils/constants'; import { prefixes } from '../../utils/constants';
import { HelpTopic } from '../../utils/models';
import { mapTopicInfo } from '../../utils/staticUI'; import { mapTopicInfo } from '../../utils/staticUI';
interface TopicsListProps { interface TopicsListProps {

View File

@ -7,7 +7,7 @@ import HelpRSFormItems from '../../components/Help/HelpRSFormItems';
import HelpRSFormMeta from '../../components/Help/HelpRSFormMeta'; import HelpRSFormMeta from '../../components/Help/HelpRSFormMeta';
import HelpRSLang from '../../components/Help/HelpRSLang'; import HelpRSLang from '../../components/Help/HelpRSLang';
import HelpTermGraph from '../../components/Help/HelpTermGraph'; import HelpTermGraph from '../../components/Help/HelpTermGraph';
import { HelpTopic } from '../../utils/models'; import { HelpTopic } from '../../models/miscelanious';
interface ViewTopicProps { interface ViewTopicProps {
topic: HelpTopic topic: HelpTopic

View File

@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { HelpTopic } from '../../utils/models'; import { HelpTopic } from '../../models/miscelanious';
import TopicsList from './TopicsList'; import TopicsList from './TopicsList';
import ViewTopic from './ViewTopic'; import ViewTopic from './ViewTopic';

View File

@ -8,7 +8,7 @@ import TextInput from '../../components/Common/TextInput';
import { useLibrary } from '../../context/LibraryContext'; import { useLibrary } from '../../context/LibraryContext';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { IRSFormCreateData } from '../../utils/models'; import { IRSFormCreateData } from '../../models/rsform';
import { getCloneTitle } from '../../utils/staticUI'; import { getCloneTitle } from '../../utils/staticUI';
interface DlgCloneRSFormProps interface DlgCloneRSFormProps

View File

@ -4,7 +4,7 @@ import ConceptSelectSingle from '../../components/Common/ConceptSelectSingle';
import Modal, { ModalProps } from '../../components/Common/Modal'; import Modal, { ModalProps } from '../../components/Common/Modal';
import TextArea from '../../components/Common/TextArea'; import TextArea from '../../components/Common/TextArea';
import RSInput from '../../components/RSInput'; import RSInput from '../../components/RSInput';
import { CstType,ICstCreateData } from '../../utils/models'; import { CstType,ICstCreateData } from '../../models/rsform';
import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI'; import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI';
interface DlgCreateCstProps interface DlgCreateCstProps

View File

@ -0,0 +1,48 @@
import { useLayoutEffect, useState } from 'react';
import Modal from '../../components/Common/Modal';
import TextArea from '../../components/Common/TextArea';
import { IConstituenta } from '../../models/rsform';
interface DlgEditTermProps {
hideWindow: () => void
target: IConstituenta
onSave: () => void
}
function DlgEditTerm({ hideWindow, target, onSave }: DlgEditTermProps) {
const [term, setTerm] = useState('');
// function getData() {
// return {
// };
// }
const handleSubmit = () => onSave(); // getData()
useLayoutEffect(
() => {
setTerm(target.term_resolved);
}, [target]);
return (
<Modal
title='Редактирование термина'
hideWindow={hideWindow}
submitText='Сохранить данные'
canSubmit
onSubmit={handleSubmit}
>
<TextArea id='nominal' label='Начальная форма'
placeholder='Начальная форма'
rows={2}
value={term}
disabled={true}
spellCheck
/>
</Modal>
);
}
export default DlgEditTerm;

View File

@ -2,7 +2,7 @@ import { useLayoutEffect, useState } from 'react';
import Checkbox from '../../components/Common/Checkbox'; import Checkbox from '../../components/Common/Checkbox';
import Modal, { ModalProps } from '../../components/Common/Modal'; import Modal, { ModalProps } from '../../components/Common/Modal';
import { CstType } from '../../utils/models'; import { CstType } from '../../models/rsform';
import { getCstTypeLabel } from '../../utils/staticUI'; import { getCstTypeLabel } from '../../utils/staticUI';
import { GraphEditorParams } from './EditorTermGraph'; import { GraphEditorParams } from './EditorTermGraph';

View File

@ -4,7 +4,7 @@ import ConceptSelectSingle from '../../components/Common/ConceptSelectSingle';
import Modal, { ModalProps } from '../../components/Common/Modal'; import Modal, { ModalProps } from '../../components/Common/Modal';
import TextInput from '../../components/Common/TextInput'; import TextInput from '../../components/Common/TextInput';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { CstType, ICstRenameData } from '../../utils/models'; import { CstType, ICstRenameData } from '../../models/rsform';
import { createAliasFor, CstTypeSelector, getCstTypeLabel, getCstTypePrefix } from '../../utils/staticUI'; import { createAliasFor, CstTypeSelector, getCstTypeLabel, getCstTypePrefix } from '../../utils/staticUI';
interface DlgRenameCstProps interface DlgRenameCstProps

View File

@ -3,9 +3,9 @@ import { GraphCanvas,GraphEdge, GraphNode } from 'reagraph';
import Modal, { ModalProps } from '../../components/Common/Modal'; import Modal, { ModalProps } from '../../components/Common/Modal';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import { SyntaxTree } from '../../models/rslang';
import { graphDarkT, graphLightT } from '../../utils/color'; import { graphDarkT, graphLightT } from '../../utils/color';
import { resources } from '../../utils/constants'; import { resources } from '../../utils/constants';
import { SyntaxTree } from '../../utils/models';
import { getASTNodeColor, getASTNodeLabel } from '../../utils/staticUI'; import { getASTNodeColor, getASTNodeLabel } from '../../utils/staticUI';
interface DlgShowASTProps interface DlgShowASTProps

View File

@ -5,8 +5,8 @@ import Checkbox from '../../components/Common/Checkbox';
import FileInput from '../../components/Common/FileInput'; import FileInput from '../../components/Common/FileInput';
import Modal from '../../components/Common/Modal'; import Modal from '../../components/Common/Modal';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { IRSFormUploadData } from '../../models/rsform';
import { EXTEOR_TRS_FILE } from '../../utils/constants'; import { EXTEOR_TRS_FILE } from '../../utils/constants';
import { IRSFormUploadData } from '../../utils/models';
interface DlgUploadRSFormProps { interface DlgUploadRSFormProps {
hideWindow: () => void hideWindow: () => void

View File

@ -10,7 +10,9 @@ import HelpConstituenta from '../../components/Help/HelpConstituenta';
import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons'; import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/useWindowSize';
import { CstType, EditMode, ICstCreateData, ICstRenameData, ICstUpdateData, SyntaxTree } from '../../utils/models'; import { EditMode } from '../../models/miscelanious';
import { CstType, IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData } from '../../models/rsform';
import { SyntaxTree } from '../../models/rslang';
import { getCstTypificationLabel } from '../../utils/staticUI'; import { getCstTypificationLabel } from '../../utils/staticUI';
import EditorRSExpression from './EditorRSExpression'; import EditorRSExpression from './EditorRSExpression';
import ViewSideConstituents from './elements/ViewSideConstituents'; import ViewSideConstituents from './elements/ViewSideConstituents';
@ -22,25 +24,23 @@ const SIDELIST_HIDE_THRESHOLD = 1000;
interface EditorConstituentaProps { interface EditorConstituentaProps {
activeID?: number activeID?: number
activeCst?: IConstituenta | undefined
onOpenEdit: (cstID: number) => void onOpenEdit: (cstID: number) => void
onShowAST: (expression: string, ast: SyntaxTree) => void onShowAST: (expression: string, ast: SyntaxTree) => void
onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void
onRenameCst: (initial: ICstRenameData) => void onRenameCst: (initial: ICstRenameData) => void
onEditTerm: () => void
onDeleteCst: (selected: number[], callback?: (items: number[]) => void) => void onDeleteCst: (selected: number[], callback?: (items: number[]) => void) => void
isModified: boolean isModified: boolean
setIsModified: Dispatch<SetStateAction<boolean>> setIsModified: Dispatch<SetStateAction<boolean>>
} }
function EditorConstituenta({ function EditorConstituenta({
isModified, setIsModified, activeID, isModified, setIsModified, activeID, activeCst, onEditTerm,
onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst
}: EditorConstituentaProps) { }: EditorConstituentaProps) {
const windowSize = useWindowSize(); const windowSize = useWindowSize();
const { schema, processing, isEditable, cstUpdate } = useRSForm(); const { schema, processing, isEditable, cstUpdate, isForceAdmin } = useRSForm();
const activeCst = useMemo(
() => {
return schema?.items?.find((cst) => cst.id === activeID);
}, [schema?.items, activeID]);
const [editMode, setEditMode] = useState(EditMode.TEXT); const [editMode, setEditMode] = useState(EditMode.TEXT);
@ -139,14 +139,13 @@ function EditorConstituenta({
<div className='flex items-stretch w-full gap-2 mb-2 justify-stretch'> <div className='flex items-stretch w-full gap-2 mb-2 justify-stretch'>
<form onSubmit={handleSubmit} className='min-w-[50rem] max-w-min px-4 py-2 border-y border-r'> <form onSubmit={handleSubmit} className='min-w-[50rem] max-w-min px-4 py-2 border-y border-r'>
<div className='relative'> <div className='relative'>
<div className='absolute top-0 left-0'> <div className='absolute top-0 left-0'>
<MiniButton <MiniButton
tooltip='Сохранить изменения' tooltip='Сохранить изменения'
disabled={!isModified || !isEnabled} disabled={!isModified || !isEnabled}
icon={<SaveIcon size={6} color={isModified && isEnabled ? 'text-primary' : ''}/>} icon={<SaveIcon size={6} color={isModified && isEnabled ? 'text-primary' : ''}/>}
onClick={() => handleSubmit()} onClick={() => handleSubmit()}
> />
</MiniButton>
</div> </div>
</div> </div>
<div className='relative'> <div className='relative'>
@ -177,15 +176,26 @@ function EditorConstituenta({
<span className='ml-4'>{alias}</span> <span className='ml-4'>{alias}</span>
</div> </div>
<MiniButton <MiniButton
tooltip='Переименовать конституету' tooltip='Переименовать конституенту'
disabled={!isEnabled} disabled={!isEnabled}
noHover noHover
onClick={handleRename} onClick={handleRename}
icon={<PenIcon size={4} color={isEnabled ? 'text-primary' : ''} />} icon={<PenIcon size={4} color={isEnabled ? 'text-primary' : ''} />}
/> />
</div> </div>
{isForceAdmin && <div className='relative'>
<div className='absolute left-[3.2rem] top-[0.5rem]'>
<MiniButton
tooltip='Редактировать словоформы термина'
disabled={!isEnabled}
noHover
onClick={onEditTerm}
icon={<PenIcon size={4} color={isEnabled ? 'text-primary' : ''} />}
/>
</div>
</div>}
<ReferenceInput id='term' label='Термин' <ReferenceInput id='term' label='Термин'
placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение' placeholder='Обозначение, используемое в текстовых определениях данной схемы'
rows={2} rows={2}
value={term} value={term}
initialValue={activeCst?.term_raw ?? ''} initialValue={activeCst?.term_raw ?? ''}

View File

@ -10,8 +10,8 @@ import { ArrowDownIcon, ArrowUpIcon, DumpBinIcon, HelpIcon, MeshIcon, SmallPlusI
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/useWindowSize';
import { CstType, IConstituenta, ICstCreateData, ICstMovetoData } from '../../models/rsform'
import { prefixes } from '../../utils/constants'; import { prefixes } from '../../utils/constants';
import { CstType, IConstituenta, ICstCreateData, ICstMovetoData } from '../../utils/models'
import { getCstStatusFgColor, getCstTypePrefix, getCstTypeShortcut, getCstTypificationLabel, mapStatusInfo } from '../../utils/staticUI'; import { getCstStatusFgColor, getCstTypePrefix, getCstTypeShortcut, getCstTypificationLabel, mapStatusInfo } from '../../utils/staticUI';
// Window width cutoff for columns // Window width cutoff for columns

View File

@ -7,8 +7,9 @@ import RSInput from '../../components/RSInput';
import { TextWrapper } from '../../components/RSInput/textEditing'; import { TextWrapper } from '../../components/RSInput/textEditing';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import useCheckExpression from '../../hooks/useCheckExpression'; import useCheckExpression from '../../hooks/useCheckExpression';
import { TokenID } from '../../utils/enums'; import { IConstituenta } from '../../models/rsform';
import { IConstituenta, IRSErrorDescription, SyntaxTree } from '../../utils/models'; import { IRSErrorDescription, SyntaxTree } from '../../models/rslang';
import { TokenID } from '../../models/rslang';
import { getCstExpressionPrefix, getTypificationLabel } from '../../utils/staticUI'; import { getCstExpressionPrefix, getTypificationLabel } from '../../utils/staticUI';
import ParsingResult from './elements/ParsingResult'; import ParsingResult from './elements/ParsingResult';
import RSLocalButton from './elements/RSLocalButton'; import RSLocalButton from './elements/RSLocalButton';

View File

@ -13,7 +13,8 @@ import { CrownIcon, DownloadIcon, DumpBinIcon, HelpIcon, SaveIcon, ShareIcon } f
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { useUsers } from '../../context/UsersContext'; import { useUsers } from '../../context/UsersContext';
import { IRSFormCreateData, LibraryItemType } from '../../utils/models'; import { IRSFormCreateData } from '../../models/rsform';
import { LibraryItemType } from '../../models/library';
interface EditorRSFormProps { interface EditorRSFormProps {
onDestroy: () => void onDestroy: () => void

View File

@ -15,10 +15,10 @@ import { ArrowsRotateIcon, DumpBinIcon, FilterCogIcon, HelpIcon, SmallPlusIcon }
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import useLocalStorage from '../../hooks/useLocalStorage'; import useLocalStorage from '../../hooks/useLocalStorage';
import { CstType, IConstituenta, ICstCreateData } from '../../models/rsform';
import { graphDarkT, graphLightT, IColorTheme } from '../../utils/color'; import { graphDarkT, graphLightT, IColorTheme } from '../../utils/color';
import { prefixes, resources, TIMEOUT_GRAPH_REFRESH } from '../../utils/constants'; import { prefixes, resources, TIMEOUT_GRAPH_REFRESH } from '../../utils/constants';
import { Graph } from '../../utils/Graph'; import { Graph } from '../../utils/Graph';
import { CstType, IConstituenta, ICstCreateData } from '../../utils/models';
import { getCstClassColor, getCstStatusBgColor, import { getCstClassColor, getCstStatusBgColor,
GraphColoringSelector, GraphLayoutSelector, GraphColoringSelector, GraphLayoutSelector,
mapColoringLabels, mapLayoutLabels mapColoringLabels, mapLayoutLabels

View File

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import fileDownload from 'js-file-download'; import fileDownload from 'js-file-download';
import { useCallback, useLayoutEffect, useState } from 'react'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { TabList, TabPanel, Tabs } from 'react-tabs'; import { TabList, TabPanel, Tabs } from 'react-tabs';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
@ -14,12 +14,14 @@ import { useConceptNavigation } from '../../context/NagivationContext';
import { useRSForm } from '../../context/RSFormContext'; import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext'; import { useConceptTheme } from '../../context/ThemeContext';
import useModificationPrompt from '../../hooks/useModificationPrompt'; import useModificationPrompt from '../../hooks/useModificationPrompt';
import { ICstCreateData, ICstRenameData } from '../../models/rsform';
import { SyntaxTree } from '../../models/rslang';
import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants'; import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants';
import { ICstCreateData, ICstRenameData, SyntaxTree } from '../../utils/models';
import { createAliasFor } from '../../utils/staticUI'; import { createAliasFor } from '../../utils/staticUI';
import DlgCloneRSForm from './DlgCloneRSForm'; import DlgCloneRSForm from './DlgCloneRSForm';
import DlgCreateCst from './DlgCreateCst'; import DlgCreateCst from './DlgCreateCst';
import DlgDeleteCst from './DlgDeleteCst'; import DlgDeleteCst from './DlgDeleteCst';
import DlgEditTerm from './DlgEditTerm';
import DlgRenameCst from './DlgRenameCst'; import DlgRenameCst from './DlgRenameCst';
import DlgShowAST from './DlgShowAST'; import DlgShowAST from './DlgShowAST';
import DlgUploadRSForm from './DlgUploadRSForm'; import DlgUploadRSForm from './DlgUploadRSForm';
@ -64,6 +66,9 @@ function RSTabs() {
const [activeTab, setActiveTab] = useState<RSTabID>(RSTabID.CARD); const [activeTab, setActiveTab] = useState<RSTabID>(RSTabID.CARD);
const [activeID, setActiveID] = useState<number | undefined>(undefined); const [activeID, setActiveID] = useState<number | undefined>(undefined);
const activeCst = useMemo(
() => schema?.items?.find(cst => cst.id === activeID)
, [schema?.items, activeID]);
const [showUpload, setShowUpload] = useState(false); const [showUpload, setShowUpload] = useState(false);
const [showClone, setShowClone] = useState(false); const [showClone, setShowClone] = useState(false);
@ -82,6 +87,8 @@ function RSTabs() {
const [renameInitialData, setRenameInitialData] = useState<ICstRenameData>(); const [renameInitialData, setRenameInitialData] = useState<ICstRenameData>();
const [showRenameCst, setShowRenameCst] = useState(false); const [showRenameCst, setShowRenameCst] = useState(false);
const [showEditTerm, setShowEditTerm] = useState(false);
useLayoutEffect(() => { useLayoutEffect(() => {
if (schema) { if (schema) {
const oldTitle = document.title const oldTitle = document.title
@ -256,7 +263,7 @@ function RSTabs() {
} }
const fileName = (schema?.alias ?? 'Schema') + EXTEOR_TRS_FILE; const fileName = (schema?.alias ?? 'Schema') + EXTEOR_TRS_FILE;
download( download(
(data) => { (data: Blob) => {
try { try {
fileDownload(data, fileName); fileDownload(data, fileName);
} catch (error) { } catch (error) {
@ -265,7 +272,7 @@ function RSTabs() {
}); });
}, [schema?.alias, download, isModified]); }, [schema?.alias, download, isModified]);
const handleShowClone = useCallback( const promptClone = useCallback(
() => { () => {
if (isModified) { if (isModified) {
if (!window.confirm('Присутствуют несохраненные изменения. Продолжить без их учета?')) { if (!window.confirm('Присутствуют несохраненные изменения. Продолжить без их учета?')) {
@ -278,18 +285,25 @@ function RSTabs() {
const handleToggleSubscribe = useCallback( const handleToggleSubscribe = useCallback(
() => { () => {
if (isTracking) { if (isTracking) {
unsubscribe( unsubscribe(() => toast.success('Отслеживание отключено'));
() => {
toast.success('Отслеживание отключено');
});
} else { } else {
subscribe( subscribe(() => toast.success('Отслеживание включено'));
() => {
toast.success('Отслеживание включено');
});
} }
}, [isTracking, subscribe, unsubscribe]); }, [isTracking, subscribe, unsubscribe]);
const promptShowEditTerm = useCallback(
() => {
if (!activeCst) {
return;
}
if (isModified) {
if (!window.confirm('Присутствуют несохраненные изменения. Продолжить без их учета?')) {
return;
}
}
setShowEditTerm(true);
}, [isModified, activeCst]);
return ( return (
<div className='w-full'> <div className='w-full'>
{ loading && <ConceptLoader /> } { loading && <ConceptLoader /> }
@ -327,6 +341,12 @@ function RSTabs() {
onDelete={handleDeleteCst} onDelete={handleDeleteCst}
selected={toBeDeleted} selected={toBeDeleted}
/>} />}
{showEditTerm &&
<DlgEditTerm
hideWindow={() => setShowEditTerm(false)}
onSave={() => {}} // TODO: implement cst update
target={activeCst!}
/>}
<Tabs <Tabs
selectedIndex={activeTab} selectedIndex={activeTab}
onSelect={onSelectTab} onSelect={onSelectTab}
@ -340,7 +360,7 @@ function RSTabs() {
onClaim={onClaimSchema} onClaim={onClaimSchema}
onShare={onShareSchema} onShare={onShareSchema}
onToggleSubscribe={handleToggleSubscribe} onToggleSubscribe={handleToggleSubscribe}
showCloneDialog={handleShowClone} showCloneDialog={promptClone}
showUploadDialog={() => setShowUpload(true)} showUploadDialog={() => setShowUpload(true)}
/> />
<ConceptTab className='border-x-2 min-w-[7.8rem]'>Паспорт схемы</ConceptTab> <ConceptTab className='border-x-2 min-w-[7.8rem]'>Паспорт схемы</ConceptTab>
@ -377,11 +397,13 @@ function RSTabs() {
isModified={isModified} isModified={isModified}
setIsModified={setIsModified} setIsModified={setIsModified}
activeID={activeID} activeID={activeID}
activeCst={activeCst}
onOpenEdit={onOpenCst} onOpenEdit={onOpenCst}
onShowAST={onShowAST} onShowAST={onShowAST}
onCreateCst={promptCreateCst} onCreateCst={promptCreateCst}
onDeleteCst={promptDeleteCst} onDeleteCst={promptDeleteCst}
onRenameCst={promptRenameCst} onRenameCst={promptRenameCst}
onEditTerm={promptShowEditTerm}
/> />
</TabPanel> </TabPanel>

View File

@ -1,6 +1,6 @@
import ConceptTooltip from '../../../components/Common/ConceptTooltip'; import ConceptTooltip from '../../../components/Common/ConceptTooltip';
import InfoConstituenta from '../../../components/Help/InfoConstituenta'; import InfoConstituenta from '../../../components/Help/InfoConstituenta';
import { IConstituenta } from '../../../utils/models'; import { IConstituenta } from '../../../models/rsform';
interface ConstituentaTooltipProps { interface ConstituentaTooltipProps {
data: IConstituenta data: IConstituenta

View File

@ -3,7 +3,7 @@ import { useCallback } from 'react';
import Dropdown from '../../../components/Common/Dropdown'; import Dropdown from '../../../components/Common/Dropdown';
import DropdownButton from '../../../components/Common/DropdownButton'; import DropdownButton from '../../../components/Common/DropdownButton';
import useDropdown from '../../../hooks/useDropdown'; import useDropdown from '../../../hooks/useDropdown';
import { DependencyMode } from '../../../utils/models'; import { DependencyMode } from '../../../models/miscelanious';
import { getDependencyLabel } from '../../../utils/staticUI'; import { getDependencyLabel } from '../../../utils/staticUI';
interface DependencyModePickerProps { interface DependencyModePickerProps {
@ -30,27 +30,26 @@ function DependencyModePicker({ value, onChange }: DependencyModePickerProps) {
{getDependencyLabel(value)} {getDependencyLabel(value)}
</span> </span>
{ pickerMenu.isActive && { pickerMenu.isActive &&
<Dropdown stretchLeft > <Dropdown stretchLeft >
<DropdownButton onClick={() => handleChange(DependencyMode.ALL)}> <DropdownButton onClick={() => handleChange(DependencyMode.ALL)}>
<p><b>вся схема:</b> список всех конституент схемы</p> <p><b>вся схема:</b> список всех конституент схемы</p>
</DropdownButton> </DropdownButton>
<DropdownButton onClick={() => handleChange(DependencyMode.EXPRESSION)}> <DropdownButton onClick={() => handleChange(DependencyMode.EXPRESSION)}>
<p><b>выражение:</b> список идентификаторов из выражения</p> <p><b>выражение:</b> список идентификаторов из выражения</p>
</DropdownButton> </DropdownButton>
<DropdownButton onClick={() => handleChange(DependencyMode.OUTPUTS)}> <DropdownButton onClick={() => handleChange(DependencyMode.OUTPUTS)}>
<p><b>потребители:</b> конституенты, ссылающиеся на данную</p> <p><b>потребители:</b> конституенты, ссылающиеся на данную</p>
</DropdownButton> </DropdownButton>
<DropdownButton onClick={() => handleChange(DependencyMode.INPUTS)}> <DropdownButton onClick={() => handleChange(DependencyMode.INPUTS)}>
<p><b>поставщики:</b> конституенты, на которые ссылается данная</p> <p><b>поставщики:</b> конституенты, на которые ссылается данная</p>
</DropdownButton> </DropdownButton>
<DropdownButton onClick={() => handleChange(DependencyMode.EXPAND_OUTPUTS)}> <DropdownButton onClick={() => handleChange(DependencyMode.EXPAND_OUTPUTS)}>
<p><b>зависимые:</b> конституенты, зависящие по цепочке</p> <p><b>зависимые:</b> конституенты, зависящие по цепочке</p>
</DropdownButton> </DropdownButton>
<DropdownButton onClick={() => handleChange(DependencyMode.EXPAND_INPUTS)}> <DropdownButton onClick={() => handleChange(DependencyMode.EXPAND_INPUTS)}>
<p><b>влияющие:</b> конституенты, влияющие на данную (цепочка)</p> <p><b>влияющие:</b> конституенты, влияющие на данную (цепочка)</p>
</DropdownButton> </DropdownButton>
</Dropdown> </Dropdown>}
}
</div> </div>
); );
} }

View File

@ -3,7 +3,7 @@ import { useCallback } from 'react';
import Dropdown from '../../../components/Common/Dropdown'; import Dropdown from '../../../components/Common/Dropdown';
import DropdownButton from '../../../components/Common/DropdownButton'; import DropdownButton from '../../../components/Common/DropdownButton';
import useDropdown from '../../../hooks/useDropdown'; import useDropdown from '../../../hooks/useDropdown';
import { CstMatchMode } from '../../../utils/models'; import { CstMatchMode } from '../../../models/miscelanious';
import { getCstCompareLabel } from '../../../utils/staticUI'; import { getCstCompareLabel } from '../../../utils/staticUI';
interface MatchModePickerProps { interface MatchModePickerProps {

View File

@ -1,4 +1,4 @@
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '../../../utils/models'; import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '../../../models/rslang';
import { getRSErrorMessage, getRSErrorPrefix } from '../../../utils/staticUI'; import { getRSErrorMessage, getRSErrorPrefix } from '../../../utils/staticUI';
interface ParsingResultProps { interface ParsingResultProps {

View File

@ -1,6 +1,6 @@
import Divider from '../../../components/Common/Divider'; import Divider from '../../../components/Common/Divider';
import LabeledText from '../../../components/Common/LabeledText'; import LabeledText from '../../../components/Common/LabeledText';
import { type IRSFormStats } from '../../../utils/models'; import { type IRSFormStats } from '../../../models/rsform';
interface RSFormStatsProps { interface RSFormStatsProps {
stats: IRSFormStats stats: IRSFormStats

View File

@ -1,4 +1,4 @@
import { TokenID } from '../../../utils/enums'; import { TokenID } from '../../../models/rslang';
interface RSLocalButtonProps { interface RSLocalButtonProps {
text: string text: string

View File

@ -1,4 +1,4 @@
import { TokenID } from '../../../utils/enums'; import { TokenID } from '../../../models/rslang';
import { getRSButtonData } from '../../../utils/staticUI' import { getRSButtonData } from '../../../utils/staticUI'
interface RSTokenButtonProps { interface RSTokenButtonProps {

View File

@ -1,7 +1,9 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useConceptTheme } from '../../../context/ThemeContext'; import { useConceptTheme } from '../../../context/ThemeContext';
import { ExpressionStatus, type IConstituenta, IExpressionParse,inferStatus, ParsingStatus } from '../../../utils/models'; import { ExpressionStatus } from '../../../models/rsform';
import { type IConstituenta, inferStatus } from '../../../models/rsform';
import { IExpressionParse, ParsingStatus } from '../../../models/rslang';
import { getCstStatusBgColor, mapStatusInfo } from '../../../utils/staticUI'; import { getCstStatusBgColor, mapStatusInfo } from '../../../utils/staticUI';
interface StatusBarProps { interface StatusBarProps {

View File

@ -5,8 +5,11 @@ import { useRSForm } from '../../../context/RSFormContext';
import { useConceptTheme } from '../../../context/ThemeContext'; import { useConceptTheme } from '../../../context/ThemeContext';
import useLocalStorage from '../../../hooks/useLocalStorage'; import useLocalStorage from '../../../hooks/useLocalStorage';
import useWindowSize from '../../../hooks/useWindowSize'; import useWindowSize from '../../../hooks/useWindowSize';
import { DependencyMode } from '../../../models/miscelanious';
import { CstMatchMode } from '../../../models/miscelanious';
import { applyGraphFilter } from '../../../models/miscelanious';
import { CstType, extractGlobals, IConstituenta, matchConstituenta } from '../../../models/rsform';
import { prefixes } from '../../../utils/constants'; import { prefixes } from '../../../utils/constants';
import { applyGraphFilter, CstMatchMode, CstType, DependencyMode, extractGlobals, IConstituenta, matchConstituenta } from '../../../utils/models';
import { getCstDescription, getCstStatusFgColor, getMockConstituenta } from '../../../utils/staticUI'; import { getCstDescription, getCstStatusFgColor, getMockConstituenta } from '../../../utils/staticUI';
import ConstituentaTooltip from './ConstituentaTooltip'; import ConstituentaTooltip from './ConstituentaTooltip';
import DependencyModePicker from './DependencyModePicker'; import DependencyModePicker from './DependencyModePicker';

View File

@ -9,7 +9,7 @@ import SubmitButton from '../components/Common/SubmitButton';
import TextInput from '../components/Common/TextInput'; import TextInput from '../components/Common/TextInput';
import { useAuth } from '../context/AuthContext'; import { useAuth } from '../context/AuthContext';
import { useConceptNavigation } from '../context/NagivationContext'; import { useConceptNavigation } from '../context/NagivationContext';
import { type IUserSignupData } from '../utils/models'; import { type IUserSignupData } from '../models/library';
function RegisterPage() { function RegisterPage() {
const location = useLocation(); const location = useLocation();

View File

@ -6,7 +6,7 @@ import SubmitButton from '../../components/Common/SubmitButton';
import TextInput from '../../components/Common/TextInput'; import TextInput from '../../components/Common/TextInput';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { IUserUpdatePassword } from '../../utils/models'; import { IUserUpdatePassword } from '../../models/library';
function EditorPassword() { function EditorPassword() {

View File

@ -5,7 +5,7 @@ import SubmitButton from '../../components/Common/SubmitButton';
import TextInput from '../../components/Common/TextInput'; import TextInput from '../../components/Common/TextInput';
import { useUserProfile } from '../../context/UserProfileContext'; import { useUserProfile } from '../../context/UserProfileContext';
import useModificationPrompt from '../../hooks/useModificationPrompt'; import useModificationPrompt from '../../hooks/useModificationPrompt';
import { IUserUpdateData } from '../../utils/models'; import { IUserUpdateData } from '../../models/library';
function EditorProfile() { function EditorProfile() {
const { updateUser, user, processing } = useUserProfile(); const { updateUser, user, processing } = useUserProfile();

View File

@ -3,7 +3,7 @@ import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper } from '../../components/DataTable'; import DataTable, { createColumnHelper } from '../../components/DataTable';
import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptNavigation } from '../../context/NagivationContext';
import { ILibraryItem } from '../../utils/models'; import { ILibraryItem } from '../../models/library';
interface ViewSubscriptionsProps { interface ViewSubscriptionsProps {
items: ILibraryItem[] items: ILibraryItem[]

View File

@ -2,14 +2,23 @@ import axios, { AxiosError, AxiosRequestConfig } from 'axios'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { type ErrorInfo } from '../components/BackendError' import { type ErrorInfo } from '../components/BackendError'
import { config } from './constants' import { IReferenceData } from '../models/language'
import { IRefsText } from '../models/language'
import { ICurrentUser } from '../models/library'
import { IUserLoginData } from '../models/library'
import { IUserSignupData } from '../models/library'
import { IUserProfile } from '../models/library'
import { IUserUpdateData } from '../models/library'
import { IUserInfo } from '../models/library'
import { IUserUpdatePassword } from '../models/library'
import { ILibraryItem } from '../models/library'
import { ILibraryUpdateData } from '../models/library'
import { import {
IConstituentaList, IConstituentaMeta, IConstituentaList, IConstituentaMeta,
ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstRenameData, ICstUpdateData, ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstRenameData, ICstUpdateData,
ICurrentUser, IExpressionParse, ILibraryItem, ILibraryUpdateData, IReferenceData, IRefsText, IRSFormCreateData, IRSFormData, IRSFormUploadData} from '../models/rsform'
IRSExpression, IRSFormCreateData, IRSFormData, IRSFormUploadData, IUserInfo, import { IExpressionParse, IRSExpression } from '../models/rslang'
IUserLoginData, IUserProfile, IUserSignupData, IUserUpdateData, IUserUpdatePassword import { config } from './constants'
} from './models'
export function initBackend() { export function initBackend() {
axios.defaults.withCredentials = true; axios.defaults.withCredentials = true;

View File

@ -1,179 +0,0 @@
//! RS language token types enumeration
export enum TokenID {
// Global, local IDs and literals
ID_LOCAL = 258,
ID_GLOBAL,
ID_FUNCTION,
ID_PREDICATE,
ID_RADICAL,
LIT_INTEGER,
LIT_INTSET,
LIT_EMPTYSET,
// Aithmetic
PLUS,
MINUS,
MULTIPLY,
// Integer predicate symbols
GREATER,
LESSER,
GREATER_OR_EQ,
LESSER_OR_EQ,
// Equality comparison
EQUAL,
NOTEQUAL,
// Logic predicate symbols
FORALL,
EXISTS,
NOT,
EQUIVALENT,
IMPLICATION,
OR,
AND,
// Set theory predicate symbols
IN,
NOTIN,
SUBSET,
SUBSET_OR_EQ,
NOTSUBSET,
// Set theory operators
DECART,
UNION,
INTERSECTION,
SET_MINUS,
SYMMINUS,
BOOLEAN,
// Structure operations
BIGPR,
SMALLPR,
FILTER,
CARD,
BOOL,
DEBOOL,
REDUCE,
// Term constructions prefixes
DECLARATIVE,
RECURSIVE,
IMPERATIVE,
// Punctuation
PUNC_DEFINE,
PUNC_STRUCT,
PUNC_ASSIGN,
PUNC_ITERATE,
PUNC_PL,
PUNC_PR,
PUNC_CL,
PUNC_CR,
PUNC_SL,
PUNC_SR,
PUNC_BAR,
PUNC_COMMA,
PUNC_SEMICOLON,
// ======= Non-terminal tokens =========
NT_ENUM_DECL, // Перечисление переменных в кванторной декларации
NT_TUPLE, // Кортеж (a,b,c), типизация B(T(a)xT(b)xT(c))
NT_ENUMERATION, // Задание множества перечислением
NT_TUPLE_DECL, // Декларация переменных с помощью кортежа
NT_ARG_DECL, // Объявление аргумента
NT_FUNC_DEFINITION, // Определение функции
NT_ARGUMENTS, // Задание аргументов функции
NT_FUNC_CALL, // Вызов функции
NT_DECLARATIVE_EXPR, // Задание множества с помощью выражения D{x из H | A(x) }
NT_IMPERATIVE_EXPR, // Императивное определение
NT_RECURSIVE_FULL, // Полная рекурсия
NT_RECURSIVE_SHORT, // Сокращенная рекурсия
NT_IMP_DECLARE, // Блок декларации
NT_IMP_ASSIGN, // Блок присвоения
NT_IMP_LOGIC, // Блок проверки
// ======= Helper tokens ========
INTERRUPT,
END,
}
export enum RSErrorClass {
LEXER,
PARSER,
SEMANTIC,
UNKNOWN
}
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, // Для данного типа не поддерживается порядок элементов
// !!!! Добавлены по сравнению с ConceptCore !!!!!
globalNonemptyBase = 0x8827, // Непустое выражение базисного/константного множества
globalUnexpectedType = 0x8828, // Типизация выражения не соответствует типу конституенты
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
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;
}
}

View File

@ -1,14 +1,14 @@
import { LayoutTypes } from 'reagraph'; import { LayoutTypes } from 'reagraph';
import { DependencyMode } from '../models/miscelanious';
import { HelpTopic } from '../models/miscelanious';
import { CstMatchMode } from '../models/miscelanious';
import { ExpressionStatus } from '../models/rsform';
import { CstClass, CstType, IConstituenta, IRSForm } from '../models/rsform';
import { IFunctionArg, IRSErrorDescription, ISyntaxTreeNode, ParsingStatus, ValueClass } from '../models/rslang';
import { resolveErrorClass, RSErrorClass, RSErrorType, TokenID } from '../models/rslang';
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph'; import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
import { IColorTheme } from './color'; import { IColorTheme } from './color';
import { resolveErrorClass,RSErrorClass, RSErrorType, TokenID } from './enums';
import {
CstClass, CstMatchMode, CstType,
DependencyMode, ExpressionStatus, HelpTopic, IConstituenta,
IFunctionArg,IRSErrorDescription, IRSForm,
ISyntaxTreeNode, ParsingStatus, ValueClass
} from './models';
export interface IDescriptor { export interface IDescriptor {
text: string text: string
@ -66,11 +66,11 @@ export function getRSButtonData(id: TokenID): IDescriptor {
}; };
case TokenID.PUNC_PL: return { case TokenID.PUNC_PL: return {
text: '( )', text: '( )',
tooltip: 'Скобки вокруг выражения [ Alt + Shift + 9 ]' tooltip: 'Скобки вокруг выражения [Alt + Shift + 9 ]'
}; };
case TokenID.PUNC_SL: return { case TokenID.PUNC_SL: return {
text: '[ ]', text: '[ ]',
tooltip: 'Скобки вокруг выражения [ Alt + [ ]' tooltip: 'Скобки вокруг выражения [Alt + [ ]'
}; };
case TokenID.FORALL: return { case TokenID.FORALL: return {
text: '∀', text: '∀',
@ -490,7 +490,7 @@ export function getTypificationLabel({isValid, resultType, args}: {
return 'N/A'; return 'N/A';
} }
if (resultType === '' || resultType === 'LOGIC') { if (resultType === '' || resultType === 'LOGIC') {
resultType = 'Логический' resultType = 'Логический';
} }
if (args.length === 0) { if (args.length === 0) {
return resultType; return resultType;
@ -586,7 +586,7 @@ export function getRSErrorMessage(error: IRSErrorDescription): string {
case RSErrorType.emptySetUsage: case RSErrorType.emptySetUsage:
return `Запрещено использование пустого множества как типизированного выражения`; return `Запрещено использование пустого множества как типизированного выражения`;
case RSErrorType.radicalUsage: case RSErrorType.radicalUsage:
return `Радикалы запрещены вне деклараций терм-функци: ${error.params[0]}`; return `Радикалы запрещены вне деклараций терм-функции: ${error.params[0]}`;
case RSErrorType.invalidFilterArgumentType: case RSErrorType.invalidFilterArgumentType:
return `Типизация аргумента фильтра не корректна: ${error.params[0]}(${error.params[1]})`; return `Типизация аргумента фильтра не корректна: ${error.params[0]}(${error.params[1]})`;
case RSErrorType.invalidFilterArity: case RSErrorType.invalidFilterArity:
@ -694,79 +694,79 @@ export function getASTNodeLabel(node: ISyntaxTreeNode): string {
export function getASTNodeColor(node: ISyntaxTreeNode, colors: IColorTheme): string { export function getASTNodeColor(node: ISyntaxTreeNode, colors: IColorTheme): string {
switch(node.typeID) { switch(node.typeID) {
case TokenID.PUNC_DEFINE: case TokenID.PUNC_DEFINE:
case TokenID.PUNC_STRUCT: case TokenID.PUNC_STRUCT:
case TokenID.ID_LOCAL: case TokenID.ID_LOCAL:
return colors.bgGreen; return colors.bgGreen;
case TokenID.ID_GLOBAL: case TokenID.ID_GLOBAL:
case TokenID.ID_FUNCTION: case TokenID.ID_FUNCTION:
case TokenID.ID_PREDICATE: case TokenID.ID_PREDICATE:
case TokenID.ID_RADICAL: case TokenID.ID_RADICAL:
case TokenID.LIT_INTEGER: case TokenID.LIT_INTEGER:
case TokenID.LIT_EMPTYSET: case TokenID.LIT_EMPTYSET:
case TokenID.LIT_INTSET: case TokenID.LIT_INTSET:
return colors.bgTeal; return colors.bgTeal;
case TokenID.FORALL: case TokenID.FORALL:
case TokenID.EXISTS: case TokenID.EXISTS:
case TokenID.NOT: case TokenID.NOT:
case TokenID.AND: case TokenID.AND:
case TokenID.OR: case TokenID.OR:
case TokenID.IMPLICATION: case TokenID.IMPLICATION:
case TokenID.EQUIVALENT: case TokenID.EQUIVALENT:
case TokenID.GREATER: case TokenID.GREATER:
case TokenID.LESSER: case TokenID.LESSER:
case TokenID.EQUAL: case TokenID.EQUAL:
case TokenID.NOTEQUAL: case TokenID.NOTEQUAL:
case TokenID.GREATER_OR_EQ: case TokenID.GREATER_OR_EQ:
case TokenID.LESSER_OR_EQ: case TokenID.LESSER_OR_EQ:
case TokenID.IN: case TokenID.IN:
case TokenID.NOTIN: case TokenID.NOTIN:
case TokenID.SUBSET_OR_EQ: case TokenID.SUBSET_OR_EQ:
case TokenID.SUBSET: case TokenID.SUBSET:
case TokenID.NOTSUBSET: case TokenID.NOTSUBSET:
return colors.bgOrange; return colors.bgOrange;
case TokenID.NT_TUPLE: case TokenID.NT_TUPLE:
case TokenID.NT_ENUMERATION: case TokenID.NT_ENUMERATION:
case TokenID.BIGPR: case TokenID.BIGPR:
case TokenID.SMALLPR: case TokenID.SMALLPR:
case TokenID.FILTER: case TokenID.FILTER:
case TokenID.PLUS: case TokenID.PLUS:
case TokenID.MINUS: case TokenID.MINUS:
case TokenID.MULTIPLY: case TokenID.MULTIPLY:
case TokenID.BOOLEAN: case TokenID.BOOLEAN:
case TokenID.DECART: case TokenID.DECART:
case TokenID.INTERSECTION: case TokenID.INTERSECTION:
case TokenID.UNION: case TokenID.UNION:
case TokenID.SET_MINUS: case TokenID.SET_MINUS:
case TokenID.SYMMINUS: case TokenID.SYMMINUS:
case TokenID.REDUCE: case TokenID.REDUCE:
case TokenID.CARD: case TokenID.CARD:
case TokenID.BOOL: case TokenID.BOOL:
case TokenID.DEBOOL: case TokenID.DEBOOL:
return colors.bgBlue; return colors.bgBlue;
case TokenID.NT_FUNC_DEFINITION: case TokenID.NT_FUNC_DEFINITION:
case TokenID.NT_DECLARATIVE_EXPR: case TokenID.NT_DECLARATIVE_EXPR:
case TokenID.NT_IMPERATIVE_EXPR: case TokenID.NT_IMPERATIVE_EXPR:
case TokenID.NT_RECURSIVE_FULL: case TokenID.NT_RECURSIVE_FULL:
case TokenID.NT_ENUM_DECL: case TokenID.NT_ENUM_DECL:
case TokenID.NT_TUPLE_DECL: case TokenID.NT_TUPLE_DECL:
case TokenID.NT_ARG_DECL: case TokenID.NT_ARG_DECL:
case TokenID.NT_FUNC_CALL: case TokenID.NT_FUNC_CALL:
case TokenID.NT_ARGUMENTS: case TokenID.NT_ARGUMENTS:
case TokenID.NT_IMP_DECLARE: case TokenID.NT_IMP_DECLARE:
case TokenID.NT_IMP_ASSIGN: case TokenID.NT_IMP_ASSIGN:
case TokenID.NT_IMP_LOGIC: case TokenID.NT_IMP_LOGIC:
case TokenID.NT_RECURSIVE_SHORT: case TokenID.NT_RECURSIVE_SHORT:
return ''; return '';
case TokenID.PUNC_ASSIGN: case TokenID.PUNC_ASSIGN:
case TokenID.PUNC_ITERATE: case TokenID.PUNC_ITERATE:
return colors.bgRed;
}
// node
return colors.bgRed; return colors.bgRed;
}
// node
return colors.bgRed;
} }