mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-08-13 20:30:36 +03:00
F: Implementing Association and Nominal pt1
This commit is contained in:
parent
b20787a741
commit
4742d241c3
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -179,6 +179,7 @@
|
|||
"viewsets",
|
||||
"wordform",
|
||||
"Wordforms",
|
||||
"XCSDATN",
|
||||
"Айзенштат",
|
||||
"Акименков",
|
||||
"Астрина",
|
||||
|
|
|
@ -299,7 +299,7 @@ class LibraryViewSet(viewsets.ModelViewSet):
|
|||
|
||||
with transaction.atomic():
|
||||
added, deleted = m.Editor.set_and_return_diff(item.pk, editors)
|
||||
if len(added) >= 0 or len(deleted) >= 0:
|
||||
if added or deleted:
|
||||
owned_schemas = OperationSchema.owned_schemasQ(item).only('pk')
|
||||
if owned_schemas.exists():
|
||||
m.Editor.objects.filter(
|
||||
|
|
|
@ -45,7 +45,7 @@ class OperationSchemaCached:
|
|||
self.cache.ensure_loaded_subs()
|
||||
operation = self.cache.operation_by_id[target]
|
||||
children = self.cache.extend_graph.outputs[target]
|
||||
if operation.result is not None and len(children) > 0:
|
||||
if operation.result is not None and children:
|
||||
ids = list(Constituenta.objects.filter(schema=operation.result).values_list('pk', flat=True))
|
||||
if not keep_constituents:
|
||||
self.engine.on_delete_inherited(operation.pk, ids)
|
||||
|
|
|
@ -47,7 +47,7 @@ class BlockSerializer(StrictModelSerializer):
|
|||
|
||||
|
||||
class ArgumentSerializer(StrictModelSerializer):
|
||||
''' Serializer: Operation data. '''
|
||||
''' Serializer: Operation arguments. '''
|
||||
class Meta:
|
||||
''' serializer metadata. '''
|
||||
model = Argument
|
||||
|
@ -55,7 +55,7 @@ class ArgumentSerializer(StrictModelSerializer):
|
|||
|
||||
|
||||
class ReplicaSerializer(StrictModelSerializer):
|
||||
''' Serializer: Replica data. '''
|
||||
''' Serializer: Replica relation. '''
|
||||
class Meta:
|
||||
''' serializer metadata. '''
|
||||
model = Replica
|
||||
|
|
|
@ -10,3 +10,11 @@ class ConstituentaAdmin(admin.ModelAdmin):
|
|||
ordering = ['schema', 'order']
|
||||
list_display = ['schema', 'order', 'alias', 'term_resolved', 'definition_resolved', 'crucial']
|
||||
search_fields = ['term_resolved', 'definition_resolved']
|
||||
|
||||
|
||||
@admin.register(models.Association)
|
||||
class AssociationAdmin(admin.ModelAdmin):
|
||||
''' Admin model: Association. '''
|
||||
ordering = ['container__schema', 'container', 'associate']
|
||||
list_display = ['container__schema__alias', 'container__alias', 'associate__alias']
|
||||
search_fields = ['container', 'associate']
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# Generated by Django 5.2.4 on 2025-08-09 10:55
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rsform', '0004_constituenta_crucial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='constituenta',
|
||||
name='cst_type',
|
||||
field=models.CharField(choices=[('nominal', 'Nominal'), ('basic', 'Base'), ('constant', 'Constant'), ('structure', 'Structured'), ('axiom', 'Axiom'), ('term', 'Term'), ('function', 'Function'), ('predicate', 'Predicate'), ('theorem', 'Theorem')], default='basic', max_length=10, verbose_name='Тип'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Association',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('associate', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='as_associate', to='rsform.constituenta', verbose_name='Ассоциированная конституента')),
|
||||
('container', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='as_container', to='rsform.constituenta', verbose_name='Составная конституента')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Ассоциация конституент',
|
||||
'verbose_name_plural': 'Ассоциации конституент',
|
||||
'unique_together': {('container', 'associate')},
|
||||
},
|
||||
),
|
||||
]
|
28
rsconcept/backend/apps/rsform/models/Association.py
Normal file
28
rsconcept/backend/apps/rsform/models/Association.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
''' Models: Synthesis Inheritance. '''
|
||||
from django.db.models import CASCADE, ForeignKey, Model
|
||||
|
||||
|
||||
class Association(Model):
|
||||
''' Association links nominal constituent to its content.'''
|
||||
container = ForeignKey(
|
||||
verbose_name='Составная конституента',
|
||||
to='rsform.Constituenta',
|
||||
on_delete=CASCADE,
|
||||
related_name='as_container'
|
||||
)
|
||||
associate = ForeignKey(
|
||||
verbose_name='Ассоциированная конституента',
|
||||
to='rsform.Constituenta',
|
||||
on_delete=CASCADE,
|
||||
related_name='as_associate'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
''' Model metadata. '''
|
||||
verbose_name = 'Ассоциация конституент'
|
||||
verbose_name_plural = 'Ассоциации конституент'
|
||||
unique_together = [['container', 'associate']]
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.container} -> {self.associate}'
|
|
@ -16,9 +16,9 @@ from django.db.models import (
|
|||
|
||||
from ..utils import apply_pattern
|
||||
|
||||
_RE_GLOBALS = r'[XCSADFPT]\d+' # cspell:disable-line
|
||||
_RE_GLOBALS = r'[XCSADFPTN]\d+' # cspell:disable-line
|
||||
_REF_ENTITY_PATTERN = re.compile(r'@{([^0-9\-].*?)\|.*?}')
|
||||
_GLOBAL_ID_PATTERN = re.compile(r'([XCSADFPT][0-9]+)') # cspell:disable-line
|
||||
_GLOBAL_ID_PATTERN = re.compile(r'([XCSADFPTN][0-9]+)') # cspell:disable-line
|
||||
|
||||
|
||||
def extract_globals(expression: str) -> set[str]:
|
||||
|
@ -38,6 +38,7 @@ def replace_entities(expression: str, mapping: dict[str, str]) -> str:
|
|||
|
||||
class CstType(TextChoices):
|
||||
''' Type of constituenta. '''
|
||||
NOMINAL = 'nominal'
|
||||
BASE = 'basic'
|
||||
CONSTANT = 'constant'
|
||||
STRUCTURED = 'structure'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
''' Django: Models. '''
|
||||
|
||||
from .Association import Association
|
||||
from .Constituenta import Constituenta, CstType, extract_globals, replace_entities, replace_globals
|
||||
from .OrderManager import OrderManager
|
||||
from .RSForm import DELETED_ALIAS, INSERT_LAST, RSForm
|
||||
|
|
|
@ -37,6 +37,7 @@ def get_type_prefix(cst_type: str) -> str:
|
|||
case CstType.FUNCTION: return 'F'
|
||||
case CstType.PREDICATE: return 'P'
|
||||
case CstType.THEOREM: return 'T'
|
||||
case CstType.NOMINAL: return 'N'
|
||||
return 'X'
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ class ReferenceSerializer(StrictSerializer):
|
|||
|
||||
|
||||
class InheritanceDataSerializer(StrictSerializer):
|
||||
''' Serializer: inheritance data. '''
|
||||
''' Serializer: Inheritance data. '''
|
||||
child = serializers.IntegerField()
|
||||
child_source = serializers.IntegerField()
|
||||
parent = serializers.IntegerField() # type: ignore
|
||||
|
|
|
@ -17,11 +17,19 @@ from apps.oss.models import Inheritance
|
|||
from shared import messages as msg
|
||||
from shared.serializers import StrictModelSerializer, StrictSerializer
|
||||
|
||||
from ..models import Constituenta, CstType, RSForm
|
||||
from ..models import Association, Constituenta, CstType, RSForm
|
||||
from .basics import CstParseSerializer, InheritanceDataSerializer
|
||||
from .io_pyconcept import PyConceptAdapter
|
||||
|
||||
|
||||
class AssociationSerializer(StrictModelSerializer):
|
||||
''' Serializer: Association relation. '''
|
||||
class Meta:
|
||||
''' serializer metadata. '''
|
||||
model = Association
|
||||
fields = ('argument', 'operation')
|
||||
|
||||
|
||||
class CstBaseSerializer(StrictModelSerializer):
|
||||
''' Serializer: Constituenta all data. '''
|
||||
class Meta:
|
||||
|
@ -134,6 +142,9 @@ class RSFormSerializer(StrictModelSerializer):
|
|||
inheritance = serializers.ListField(
|
||||
child=InheritanceDataSerializer()
|
||||
)
|
||||
association = serializers.ListField(
|
||||
child=AssociationSerializer()
|
||||
)
|
||||
oss = serializers.ListField(
|
||||
child=LibraryItemReferenceSerializer()
|
||||
)
|
||||
|
@ -164,6 +175,7 @@ class RSFormSerializer(StrictModelSerializer):
|
|||
result['items'] = []
|
||||
result['oss'] = []
|
||||
result['inheritance'] = []
|
||||
result['association'] = []
|
||||
for cst in Constituenta.objects.filter(schema=instance).defer('order').order_by('order'):
|
||||
result['items'].append(CstInfoSerializer(cst).data)
|
||||
for oss in LibraryItem.objects.filter(operations__result=instance).only('alias'):
|
||||
|
@ -171,6 +183,11 @@ class RSFormSerializer(StrictModelSerializer):
|
|||
'id': oss.pk,
|
||||
'alias': oss.alias
|
||||
})
|
||||
for assoc in Association.objects.filter(container__schema=instance).only('container_id', 'associate_id'):
|
||||
result['association'].append({
|
||||
'container': assoc.container_id,
|
||||
'associate': assoc.associate_id
|
||||
})
|
||||
return result
|
||||
|
||||
def to_versioned_data(self) -> dict:
|
||||
|
@ -200,37 +217,38 @@ class RSFormSerializer(StrictModelSerializer):
|
|||
instance = cast(LibraryItem, self.instance)
|
||||
schema = RSForm(instance)
|
||||
items: list[dict] = data['items']
|
||||
ids: list[int] = [item['id'] for item in items]
|
||||
processed: list[int] = []
|
||||
stored_ids: list[int] = [item['id'] for item in items]
|
||||
id_map: dict[int, int] = {}
|
||||
|
||||
for cst in schema.constituentsQ():
|
||||
if not cst.pk in ids:
|
||||
cst.delete()
|
||||
for existing_cst in schema.constituentsQ():
|
||||
if not existing_cst.pk in stored_ids:
|
||||
existing_cst.delete()
|
||||
else:
|
||||
cst_data = next(x for x in items if x['id'] == cst.pk)
|
||||
cst_data = next(x for x in items if x['id'] == existing_cst.pk)
|
||||
cst_data['schema'] = instance.pk
|
||||
new_cst = CstBaseSerializer(data=cst_data)
|
||||
new_cst.is_valid(raise_exception=True)
|
||||
new_cst.validated_data['order'] = ids.index(cst.pk)
|
||||
new_cst.update(
|
||||
instance=cst,
|
||||
validated_data=new_cst.validated_data
|
||||
cst_serializer = CstBaseSerializer(data=cst_data)
|
||||
cst_serializer.is_valid(raise_exception=True)
|
||||
cst_serializer.validated_data['order'] = stored_ids.index(existing_cst.pk)
|
||||
cst_serializer.update(
|
||||
instance=existing_cst,
|
||||
validated_data=cst_serializer.validated_data
|
||||
)
|
||||
processed.append(cst.pk)
|
||||
id_map[cst_data['id']] = existing_cst.pk
|
||||
|
||||
for cst_data in items:
|
||||
if cst_data['id'] not in processed:
|
||||
cst = schema.insert_last(cst_data['alias'])
|
||||
if cst_data['id'] not in id_map:
|
||||
old_id = cst_data['id']
|
||||
cst_data['id'] = cst.pk
|
||||
inserted_cst = schema.insert_last(cst_data['alias'])
|
||||
cst_data['id'] = inserted_cst.pk
|
||||
cst_data['schema'] = instance.pk
|
||||
new_cst = CstBaseSerializer(data=cst_data)
|
||||
new_cst.is_valid(raise_exception=True)
|
||||
new_cst.validated_data['order'] = ids.index(old_id)
|
||||
new_cst.update(
|
||||
instance=cst,
|
||||
validated_data=new_cst.validated_data
|
||||
cst_serializer = CstBaseSerializer(data=cst_data)
|
||||
cst_serializer.is_valid(raise_exception=True)
|
||||
cst_serializer.validated_data['order'] = stored_ids.index(old_id)
|
||||
cst_serializer.update(
|
||||
instance=inserted_cst,
|
||||
validated_data=cst_serializer.validated_data
|
||||
)
|
||||
id_map[old_id] = inserted_cst.pk
|
||||
|
||||
loaded_item = LibraryItemBaseNonStrictSerializer(data=data)
|
||||
loaded_item.is_valid(raise_exception=True)
|
||||
|
@ -239,6 +257,23 @@ class RSFormSerializer(StrictModelSerializer):
|
|||
validated_data=loaded_item.validated_data
|
||||
)
|
||||
|
||||
Association.objects.filter(container__schema=instance).delete()
|
||||
associations_to_create: list[Association] = []
|
||||
for assoc in data.get('association', []):
|
||||
old_container_id = assoc['container']
|
||||
old_associate_id = assoc['associate']
|
||||
container_id = id_map.get(old_container_id)
|
||||
associate_id = id_map.get(old_associate_id)
|
||||
if container_id and associate_id:
|
||||
associations_to_create.append(
|
||||
Association(
|
||||
container_id=container_id,
|
||||
associate_id=associate_id
|
||||
)
|
||||
)
|
||||
if associations_to_create:
|
||||
Association.objects.bulk_create(associations_to_create)
|
||||
|
||||
|
||||
class RSFormParseSerializer(StrictModelSerializer):
|
||||
''' Serializer: Detailed data for RSForm including parse. '''
|
||||
|
|
|
@ -6,11 +6,11 @@ from apps.library.models import LibraryItem
|
|||
from shared import messages as msg
|
||||
from shared.serializers import StrictSerializer
|
||||
|
||||
from ..models import Constituenta, RSFormCached
|
||||
from ..models import Constituenta, CstType, RSFormCached
|
||||
from ..utils import fix_old_references
|
||||
|
||||
_CST_TYPE = 'constituenta'
|
||||
_TRS_TYPE = 'rsform'
|
||||
_ENTITY_CONSTITUENTA = 'constituenta'
|
||||
_ENTITY_SCHEMA = 'rsform'
|
||||
_TRS_VERSION_MIN = 16
|
||||
_TRS_VERSION = 16
|
||||
_TRS_HEADER = 'Exteor 4.8.13.1000 - 30/05/2022'
|
||||
|
@ -30,11 +30,11 @@ class RSFormUploadSerializer(StrictSerializer):
|
|||
def generate_trs(schema: LibraryItem) -> dict:
|
||||
''' Generate TRS file for RSForm. '''
|
||||
items = []
|
||||
for cst in Constituenta.objects.filter(schema=schema).order_by('order'):
|
||||
for cst in Constituenta.objects.filter(schema=schema).exclude(cst_type=CstType.NOMINAL).order_by('order'):
|
||||
items.append(
|
||||
{
|
||||
'entityUID': cst.pk,
|
||||
'type': _CST_TYPE,
|
||||
'type': _ENTITY_CONSTITUENTA,
|
||||
'cstType': cst.cst_type,
|
||||
'alias': cst.alias,
|
||||
'convention': cst.convention,
|
||||
|
@ -53,7 +53,7 @@ def generate_trs(schema: LibraryItem) -> dict:
|
|||
}
|
||||
)
|
||||
return {
|
||||
'type': _TRS_TYPE,
|
||||
'type': _ENTITY_SCHEMA,
|
||||
'title': schema.title,
|
||||
'alias': schema.alias,
|
||||
'comment': schema.description,
|
||||
|
@ -72,7 +72,7 @@ class RSFormTRSSerializer(serializers.Serializer):
|
|||
def load_versioned_data(data: dict) -> dict:
|
||||
''' Load data from version. '''
|
||||
result = {
|
||||
'type': _TRS_TYPE,
|
||||
'type': _ENTITY_SCHEMA,
|
||||
'title': data['title'],
|
||||
'alias': data['alias'],
|
||||
'comment': data['description'],
|
||||
|
@ -85,7 +85,7 @@ class RSFormTRSSerializer(serializers.Serializer):
|
|||
for cst in data['items']:
|
||||
result['items'].append({
|
||||
'entityUID': cst['id'],
|
||||
'type': _CST_TYPE,
|
||||
'type': _ENTITY_CONSTITUENTA,
|
||||
'cstType': cst['cst_type'],
|
||||
'alias': cst['alias'],
|
||||
'convention': cst['convention'],
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
''' Tests for Django Models. '''
|
||||
from .t_Association import *
|
||||
from .t_Constituenta import *
|
||||
from .t_RSForm import *
|
||||
from .t_RSFormCached import *
|
||||
|
|
175
rsconcept/backend/apps/rsform/tests/s_models/t_Association.py
Normal file
175
rsconcept/backend/apps/rsform/tests/s_models/t_Association.py
Normal file
|
@ -0,0 +1,175 @@
|
|||
''' Testing models: Association. '''
|
||||
from django.db.utils import IntegrityError
|
||||
from django.test import TestCase
|
||||
|
||||
from apps.rsform.models import Association, Constituenta, CstType, RSForm
|
||||
|
||||
|
||||
class TestAssociation(TestCase):
|
||||
''' Testing Association model. '''
|
||||
|
||||
def setUp(self):
|
||||
self.schema = RSForm.create(title='Test1')
|
||||
|
||||
# Create test constituents
|
||||
self.container1 = Constituenta.objects.create(
|
||||
alias='C1',
|
||||
schema=self.schema.model,
|
||||
order=1,
|
||||
cst_type=CstType.NOMINAL
|
||||
)
|
||||
self.associate1 = Constituenta.objects.create(
|
||||
alias='A1',
|
||||
schema=self.schema.model,
|
||||
order=2,
|
||||
cst_type=CstType.BASE
|
||||
)
|
||||
|
||||
def test_str(self):
|
||||
''' Test string representation. '''
|
||||
association = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
expected_str = f'{self.container1} -> {self.associate1}'
|
||||
self.assertEqual(str(association), expected_str)
|
||||
|
||||
def test_create_association(self):
|
||||
''' Test basic association creation. '''
|
||||
association = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
self.assertEqual(association.container, self.container1)
|
||||
self.assertEqual(association.associate, self.associate1)
|
||||
self.assertIsNotNone(association.id)
|
||||
|
||||
def test_unique_constraint(self):
|
||||
''' Test unique constraint on container and associate. '''
|
||||
# Create first association
|
||||
Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
|
||||
# Try to create duplicate association
|
||||
with self.assertRaises(IntegrityError):
|
||||
Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
|
||||
def test_container_not_null(self):
|
||||
''' Test container field cannot be null. '''
|
||||
with self.assertRaises(IntegrityError):
|
||||
Association.objects.create(
|
||||
container=None,
|
||||
associate=self.associate1
|
||||
)
|
||||
|
||||
def test_associate_not_null(self):
|
||||
''' Test associate field cannot be null. '''
|
||||
with self.assertRaises(IntegrityError):
|
||||
Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=None
|
||||
)
|
||||
|
||||
def test_cascade_delete_container(self):
|
||||
''' Test cascade delete when container is deleted. '''
|
||||
association = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
association_id = association.id
|
||||
|
||||
# Delete the container
|
||||
self.container1.delete()
|
||||
|
||||
# Association should be deleted due to CASCADE
|
||||
with self.assertRaises(Association.DoesNotExist):
|
||||
Association.objects.get(id=association_id)
|
||||
|
||||
def test_cascade_delete_associate(self):
|
||||
''' Test cascade delete when associate is deleted. '''
|
||||
association = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
association_id = association.id
|
||||
|
||||
# Delete the associate
|
||||
self.associate1.delete()
|
||||
|
||||
# Association should be deleted due to CASCADE
|
||||
with self.assertRaises(Association.DoesNotExist):
|
||||
Association.objects.get(id=association_id)
|
||||
|
||||
def test_related_names(self):
|
||||
''' Test related names for foreign key relationships. '''
|
||||
association = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
|
||||
# Test container related name
|
||||
container_associations = self.container1.as_container.all()
|
||||
self.assertEqual(len(container_associations), 1)
|
||||
self.assertEqual(container_associations[0], association)
|
||||
|
||||
# Test associate related name
|
||||
associate_associations = self.associate1.as_associate.all()
|
||||
self.assertEqual(len(associate_associations), 1)
|
||||
self.assertEqual(associate_associations[0], association)
|
||||
|
||||
def test_multiple_associations_same_container(self):
|
||||
''' Test multiple associations with same container. '''
|
||||
associate3 = Constituenta.objects.create(
|
||||
alias='A3',
|
||||
schema=self.schema.model,
|
||||
order=3,
|
||||
cst_type=CstType.BASE
|
||||
)
|
||||
|
||||
association1 = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
association2 = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=associate3
|
||||
)
|
||||
|
||||
container_associations = self.container1.as_container.all()
|
||||
self.assertEqual(len(container_associations), 2)
|
||||
self.assertIn(association1, container_associations)
|
||||
self.assertIn(association2, container_associations)
|
||||
|
||||
def test_multiple_associations_same_associate(self):
|
||||
''' Test multiple associations with same associate. '''
|
||||
container3 = Constituenta.objects.create(
|
||||
alias='C3',
|
||||
schema=self.schema.model,
|
||||
order=3,
|
||||
cst_type=CstType.NOMINAL
|
||||
)
|
||||
|
||||
association1 = Association.objects.create(
|
||||
container=self.container1,
|
||||
associate=self.associate1
|
||||
)
|
||||
association2 = Association.objects.create(
|
||||
container=container3,
|
||||
associate=self.associate1
|
||||
)
|
||||
|
||||
associate_associations = self.associate1.as_associate.all()
|
||||
self.assertEqual(len(associate_associations), 2)
|
||||
self.assertIn(association1, associate_associations)
|
||||
self.assertIn(association2, associate_associations)
|
||||
|
||||
def test_meta_unique_together(self):
|
||||
''' Test Meta class unique_together constraint. '''
|
||||
unique_together = Association._meta.unique_together
|
||||
self.assertEqual(len(unique_together), 1)
|
||||
self.assertIn(('container', 'associate'), unique_together)
|
|
@ -13,7 +13,7 @@ export const parser = LRParser.deserialize({
|
|||
skippedNodes: [0],
|
||||
repeatNodeCount: 2,
|
||||
tokenData:
|
||||
".V~R!UOX$eXZ%VZ^%z^p$epq%Vqr'sr|$e|}'x}!O(f!O!Q$e!Q!R)i!R![*i![!b$e!b!c+k!c!d+v!d!e)i!e!f+v!f!g+v!g!h)i!h!i+v!i!r)i!r!s+v!s!t)i!t!u+v!u!v+v!v!w+v!w!z)i!z!{+v!{!})i!}#T$e#T#o)i#p#q-{#q#r.Q#r#y$e#y#z%z#z$f$e$f$g%z$g#BY$e#BY#BZ%z#BZ$IS$e$IS$I_%z$I_$I|$e$I|$JO%z$JO$JT$e$JT$JU%z$JU$KV$e$KV$KW%z$KW&FU$e&FU&FV%z&FV;'S$e;'S;=`%P<%lO$eP$jVgPOX$eZp$er!b$e!c#o$e#r;'S$e;'S;=`%P<%lO$eP%SP;=`<%l$e~%[Y^~X^%Vpq%V#y#z%V$f$g%V#BY#BZ%V$IS$I_%V$I|$JO%V$JT$JU%V$KV$KW%V&FU&FV%V~&RjgP^~OX$eXZ%VZ^%z^p$epq%Vr!b$e!c#o$e#r#y$e#y#z%z#z$f$e$f$g%z$g#BY$e#BY#BZ%z#BZ$IS$e$IS$I_%z$I_$I|$e$I|$JO%z$JO$JT$e$JT$JU%z$JU$KV$e$KV$KW%z$KW&FU$e&FU&FV%z&FV;'S$e;'S;=`%P<%lO$e~'xOh~R(PVfQgPOX$eZp$er!b$e!c#o$e#r;'S$e;'S;=`%P<%lO$eV(m^eSgPOX$eZp$er}$e}!O)i!O!Q$e!Q!R)i!R![*i![!b$e!c!})i!}#T$e#T#o)i#r;'S$e;'S;=`%P<%lO$eT)p]eSgPOX$eZp$er}$e}!O)i!O!Q$e!Q![)i![!b$e!c!})i!}#T$e#T#o)i#r;'S$e;'S;=`%P<%lO$eV*r]UQeSgPOX$eZp$er}$e}!O)i!O!Q$e!Q![*i![!b$e!c!})i!}#T$e#T#o)i#r;'S$e;'S;=`%P<%lO$e~+nP#o#p+q~+vOb~V+}^eSgPOX$eZp$er}$e}!O)i!O!Q$e!Q!R)i!R![,y![!b$e!c!})i!}#T$e#T#o)i#r;'S$e;'S;=`%P<%lO$eV-S]RQeSgPOX$eZp$er}$e}!O)i!O!Q$e!Q![,y![!b$e!c!})i!}#T$e#T#o)i#r;'S$e;'S;=`%P<%lO$e~.QOc~~.VOa~",
|
||||
".]~R!WOX$kXZ%]Z^&Q^p$kpq%]qr'yr|$k|}(O}!O(l!O!Q$k!Q!R)o!R![*o![!b$k!b!c+q!c!d+|!d!e)o!e!f+|!f!g+|!g!h)o!h!i+|!i!p)o!p!q+|!q!r)o!r!s+|!s!t)o!t!u+|!u!v+|!v!w+|!w!z)o!z!{+|!{!})o!}#T$k#T#o)o#p#q.R#q#r.W#r#y$k#y#z&Q#z$f$k$f$g&Q$g#BY$k#BY#BZ&Q#BZ$IS$k$IS$I_&Q$I_$I|$k$I|$JO&Q$JO$JT$k$JT$JU&Q$JU$KV$k$KV$KW&Q$KW&FU$k&FU&FV&Q&FV;'S$k;'S;=`%V<%lO$kP$pVgPOX$kZp$kr!b$k!c#o$k#r;'S$k;'S;=`%V<%lO$kP%YP;=`<%l$k~%bY^~X^%]pq%]#y#z%]$f$g%]#BY#BZ%]$IS$I_%]$I|$JO%]$JT$JU%]$KV$KW%]&FU&FV%]~&XjgP^~OX$kXZ%]Z^&Q^p$kpq%]r!b$k!c#o$k#r#y$k#y#z&Q#z$f$k$f$g&Q$g#BY$k#BY#BZ&Q#BZ$IS$k$IS$I_&Q$I_$I|$k$I|$JO&Q$JO$JT$k$JT$JU&Q$JU$KV$k$KV$KW&Q$KW&FU$k&FU&FV&Q&FV;'S$k;'S;=`%V<%lO$k~(OOh~R(VVfQgPOX$kZp$kr!b$k!c#o$k#r;'S$k;'S;=`%V<%lO$kV(s^eSgPOX$kZp$kr}$k}!O)o!O!Q$k!Q!R)o!R![*o![!b$k!c!})o!}#T$k#T#o)o#r;'S$k;'S;=`%V<%lO$kT)v]eSgPOX$kZp$kr}$k}!O)o!O!Q$k!Q![)o![!b$k!c!})o!}#T$k#T#o)o#r;'S$k;'S;=`%V<%lO$kV*x]UQeSgPOX$kZp$kr}$k}!O)o!O!Q$k!Q![*o![!b$k!c!})o!}#T$k#T#o)o#r;'S$k;'S;=`%V<%lO$k~+tP#o#p+w~+|Ob~V,T^eSgPOX$kZp$kr}$k}!O)o!O!Q$k!Q!R)o!R![-P![!b$k!c!})o!}#T$k#T#o)o#r;'S$k;'S;=`%V<%lO$kV-Y]RQeSgPOX$kZp$kr}$k}!O)o!O!Q$k!Q![-P![!b$k!c!})o!}#T$k#T#o)o#r;'S$k;'S;=`%V<%lO$k~.WOc~~.]Oa~",
|
||||
tokenizers: [0, 1, 2],
|
||||
topRules: { Text: [0, 1] },
|
||||
tokenPrec: 96
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
space { @whitespace+ }
|
||||
|
||||
Offset { $[-]?$[1-9]$[0-9]* }
|
||||
Global { $[XCSDATFPR]$[1-9]$[0-9]* }
|
||||
Global { $[XCSDATFPRN]$[1-9]$[0-9]* }
|
||||
|
||||
word { ![@{|}! \t\n]+ }
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ export const parser = LRParser.deserialize({
|
|||
skippedNodes: [0],
|
||||
repeatNodeCount: 0,
|
||||
tokenData:
|
||||
"6g~R!iX^%ppq%pvw&exy&jyz&oz{&t{|&y|}'O}!O'T!Q!['Y![!]'b!]!^'u!^!_'z!_!`(P!`!a(U!c!d(Z!e!f(Z!f!g(i!h!i(q!k!l)e!r!s)j!t!u*^!u!v(Z!v!w(Z!z!{(Z!|!}*n!}#O*s#O#P*x#P#Q*}#R#S+S#T#U+S#U#V+j#V#W-Y#W#X.u#X#d+S#d#e1_#e#f+S#f#g2t#g#o+S#o#p4O#p#q4T#q#r4Y#y#z%p$f$g%p$r$s4_%o%p4d5i6S+S#BY#BZ%p$IS$I_%p$I|$JO%p$JT$JU%p$KV$KW%p% l% m4i%%Y%%Z4n%%[%%]4s%&Y%&Z4x%&]%&^4}%&_%&`5S%&`%&a5X%&b%&c5^%&c%&d5c%'S%'T5h%'T%'U5m%'U%'V5r%(^%(_5w%(b%(c5|%(c%(d6R%)Q%)R6W%)S%)T6]%)U%)V6b&FU&FV%p~%uY!x~X^%ppq%p#y#z%p$f$g%p#BY#BZ%p$IS$I_%p$I|$JO%p$JT$JU%p$KV$KW%p&FU&FV%p~&jO!r~~&oOV~~&tOU~~&yOc~~'OOd~~'TO!Y~~'YOe~~'_P]~!Q!['Y~'eQ!_!`'k%&b%&c'p~'pO!P~~'uO!Z~~'zO|~~(PO!b~~(UO!e~~(ZO!`~~(^P!Q![(a~(fP`~!Q![(a~(nPx~!Q![(a~(tQ!Q![(z#]#^)S~)PP!Q~!Q![(z~)VP!R![)Y~)_Qr~|})S!Q![)Y~)jOy~~)mQ!Q![)s#f#g){~)xP!i~!Q![)s~*OP!R![*R~*WQ!S~|}){!Q![*R~*cP}~!Q![*f~*kPa~!Q![*f~*sO_~~*xOs~~*}Og~~+SOt~~+XRT~!Q![+b#T#o+S5i6S+S~+gPT~!Q![+b~+oTT~!Q![+b#T#c+S#c#d,O#d#o+S5i6S+S~,TTT~!Q![+b#T#c+S#c#d,d#d#o+S5i6S+S~,iTT~!Q![+b#T#`+S#`#a,x#a#o+S5i6S+S~-PR!V~T~!Q![+b#T#o+S5i6S+S~-_ST~!Q![+b#T#U-k#U#o+S5i6S+S~-pTT~!Q![+b#T#f+S#f#g.P#g#o+S5i6S+S~.UTT~!Q![+b#T#W+S#W#X.e#X#o+S5i6S+S~.lR!U~T~!Q![+b#T#o+S5i6S+S~.zTT~!Q![+b#T#X+S#X#Y/Z#Y#o+S5i6S+S~/`TT~!Q![+b#T#U+S#U#V/o#V#o+S5i6S+S~/tTT~!Q![+b#T#c+S#c#d0T#d#o+S5i6S+S~0YTT~!Q![+b#T#c+S#c#d0i#d#o+S5i6S+S~0nTT~!Q![+b#T#`+S#`#a0}#a#o+S5i6S+S~1UR!W~T~!Q![+b#T#o+S5i6S+S~1dTT~!Q![+b#T#f+S#f#g1s#g#o+S5i6S+S~1xST~!Q!R+b!R![2U#T#o+S5i6S+S~2]Q!T~T~|}2c!Q![2U~2fP!R![2i~2nQ!T~|}2c!Q![2i~2yTT~!Q![+b#T#X+S#X#Y3Y#Y#o+S5i6S+S~3_TT~!Q![+b#T#W+S#W#X3n#X#o+S5i6S+S~3uR!X~T~!Q![+b#T#o+S5i6S+S~4TOm~~4YOw~~4_Ol~~4dO!h~~4iOj~~4nOp~~4sO!p~~4xO!o~~4}O!k~~5SO!m~~5XO^~~5^Oh~~5cOv~~5hO![~~5mO!q~~5rOi~~5wOf~~5|O!d~~6RO!c~~6WO!a~~6]O!_~~6bO!^~~6gO!]~",
|
||||
"6j~R!jX^%spq%svw&hxy&myz&rz{&w{|&||}'R}!O'W!Q![']![!]'e!]!^'x!^!_'}!_!`(S!`!a(X!c!d(^!e!f(^!f!g(l!h!i(t!k!l)h!p!q(^!r!s)m!t!u*a!u!v(^!v!w(^!z!{(^!|!}*q!}#O*v#O#P*{#P#Q+Q#R#S+V#T#U+V#U#V+m#V#W-]#W#X.x#X#d+V#d#e1b#e#f+V#f#g2w#g#o+V#o#p4R#p#q4W#q#r4]#y#z%s$f$g%s$r$s4b%o%p4g5i6S+V#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s% l% m4l%%Y%%Z4q%%[%%]4v%&Y%&Z4{%&]%&^5Q%&_%&`5V%&`%&a5[%&b%&c5a%&c%&d5f%'S%'T5k%'T%'U5p%'U%'V5u%(^%(_5z%(b%(c6P%(c%(d6U%)Q%)R6Z%)S%)T6`%)U%)V6e&FU&FV%s~%xY!x~X^%spq%s#y#z%s$f$g%s#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s&FU&FV%s~&mO!r~~&rOV~~&wOU~~&|Oc~~'ROd~~'WO!Y~~']Oe~~'bP]~!Q![']~'hQ!_!`'n%&b%&c's~'sO!P~~'xO!Z~~'}O|~~(SO!b~~(XO!e~~(^O!`~~(aP!Q![(d~(iP`~!Q![(d~(qPx~!Q![(d~(wQ!Q![(}#]#^)V~)SP!Q~!Q![(}~)YP!R![)]~)bQr~|})V!Q![)]~)mOy~~)pQ!Q![)v#f#g*O~){P!i~!Q![)v~*RP!R![*U~*ZQ!S~|}*O!Q![*U~*fP}~!Q![*i~*nPa~!Q![*i~*vO_~~*{Os~~+QOg~~+VOt~~+[RT~!Q![+e#T#o+V5i6S+V~+jPT~!Q![+e~+rTT~!Q![+e#T#c+V#c#d,R#d#o+V5i6S+V~,WTT~!Q![+e#T#c+V#c#d,g#d#o+V5i6S+V~,lTT~!Q![+e#T#`+V#`#a,{#a#o+V5i6S+V~-SR!V~T~!Q![+e#T#o+V5i6S+V~-bST~!Q![+e#T#U-n#U#o+V5i6S+V~-sTT~!Q![+e#T#f+V#f#g.S#g#o+V5i6S+V~.XTT~!Q![+e#T#W+V#W#X.h#X#o+V5i6S+V~.oR!U~T~!Q![+e#T#o+V5i6S+V~.}TT~!Q![+e#T#X+V#X#Y/^#Y#o+V5i6S+V~/cTT~!Q![+e#T#U+V#U#V/r#V#o+V5i6S+V~/wTT~!Q![+e#T#c+V#c#d0W#d#o+V5i6S+V~0]TT~!Q![+e#T#c+V#c#d0l#d#o+V5i6S+V~0qTT~!Q![+e#T#`+V#`#a1Q#a#o+V5i6S+V~1XR!W~T~!Q![+e#T#o+V5i6S+V~1gTT~!Q![+e#T#f+V#f#g1v#g#o+V5i6S+V~1{ST~!Q!R+e!R![2X#T#o+V5i6S+V~2`Q!T~T~|}2f!Q![2X~2iP!R![2l~2qQ!T~|}2f!Q![2l~2|TT~!Q![+e#T#X+V#X#Y3]#Y#o+V5i6S+V~3bTT~!Q![+e#T#W+V#W#X3q#X#o+V5i6S+V~3xR!X~T~!Q![+e#T#o+V5i6S+V~4WOm~~4]Ow~~4bOl~~4gO!h~~4lOj~~4qOp~~4vO!p~~4{O!o~~5QO!k~~5VO!m~~5[O^~~5aOh~~5fOv~~5kO![~~5pO!q~~5uOi~~5zOf~~6PO!d~~6UO!c~~6ZO!a~~6`O!_~~6eO!^~~6jO!]~",
|
||||
tokenizers: [0],
|
||||
topRules: { Expression: [0, 1] },
|
||||
tokenPrec: 1739
|
||||
|
|
|
@ -15,7 +15,7 @@ export const parser = LRParser.deserialize({
|
|||
skippedNodes: [0],
|
||||
repeatNodeCount: 0,
|
||||
tokenData:
|
||||
"6P~R!jX^%spq%svw&hxy&myz&rz{&w{|&||}'R}!O'W!Q!R']!R[!h!i)d!k!l)z!r!s*P!t!u*g!u!v(|!v!w(|!z!{(|!|!}*w!}#O*|#O#P+R#P#Q+W#R#S+]#T#U+]#U#V+s#V#W-c#W#X/O#X#d+]#d#e1h#e#f+]#f#g2^#g#o+]#o#p3h#p#q3m#q#r3r#y#z%s$f$g%s$r$s3w%o%p3|5i6S+]#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s% l% m4R%%Y%%Z4W%%[%%]4]%&Y%&Z4b%&]%&^4g%&_%&`4l%&`%&a4q%&b%&c4v%&c%&d4{%'S%'T5Q%'T%'U5V%'U%'V5[%(^%(_5a%(b%(c5f%(c%(d5k%)Q%)R5p%)S%)T5u%)U%)V5z&FU&FV%s~%xY!V~X^%spq%s#y#z%s$f$g%s#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s&FU&FV%s~&mO!S~~&rOR~~&wO_~~&|OV~~'ROW~~'WO!s~~']OX~P'bP!`P!Q![']R'lQdQ!`P|}'r!Q!['eQ'uP!R!['xQ'}QdQ|}'r!Q!['x~(WQ!_!`(^%&b%&c(c~(cOm~~(hOp~~(mOk~~(rOw~~(wOz~~(|Ou~~)PP!Q![)S~)XPT~!Q![)S~)aPi~!Q![)S~)gQ!Q![)m#]#^)u~)rPn~!Q![)m~)zOc~~*POj~~*SQ!Q![*Y#f#g*b~*_P|~!Q![*Y~*gO!m~~*lPl~!Q![*o~*tPU~!Q![*o~*|O!b~~+ROe~~+WOZ~~+]Of~~+bRQ~!Q![+k#T#o+]5i6S+]~+pPQ~!Q![+k~+xTQ~!Q![+k#T#c+]#c#d,X#d#o+]5i6S+]~,^TQ~!Q![+k#T#c+]#c#d,m#d#o+]5i6S+]~,rTQ~!Q![+k#T#`+]#`#a-R#a#o+]5i6S+]~-YR!p~Q~!Q![+k#T#o+]5i6S+]~-hSQ~!Q![+k#T#U-t#U#o+]5i6S+]~-yTQ~!Q![+k#T#f+]#f#g.Y#g#o+]5i6S+]~._TQ~!Q![+k#T#W+]#W#X.n#X#o+]5i6S+]~.uR!o~Q~!Q![+k#T#o+]5i6S+]~/TTQ~!Q![+k#T#X+]#X#Y/d#Y#o+]5i6S+]~/iTQ~!Q![+k#T#U+]#U#V/x#V#o+]5i6S+]~/}TQ~!Q![+k#T#c+]#c#d0^#d#o+]5i6S+]~0cTQ~!Q![+k#T#c+]#c#d0r#d#o+]5i6S+]~0wTQ~!Q![+k#T#`+]#`#a1W#a#o+]5i6S+]~1_R!q~Q~!Q![+k#T#o+]5i6S+]~1mTQ~!Q![+k#T#f+]#f#g1|#g#o+]5i6S+]~2TR!n~Q~!Q![+k#T#o+]5i6S+]~2cTQ~!Q![+k#T#X+]#X#Y2r#Y#o+]5i6S+]~2wTQ~!Q![+k#T#W+]#W#X3W#X#o+]5i6S+]~3_R!r~Q~!Q![+k#T#o+]5i6S+]~3mO`~~3rOh~~3wOa~~3|O{~~4RO^~~4WOb~~4]O!Q~~4bO!P~~4gO}~~4lO!O~~4qO!a~~4vO[~~4{Og~~5QOq~~5VO!R~~5[O]~~5aOY~~5fOy~~5kOx~~5pOv~~5uOt~~5zOs~~6POr~",
|
||||
"6S~R!kX^%vpq%vvw&kxy&pyz&uz{&z{|'P|}'U}!O'Z!Q!R'`!RP!e!f)P!f!g)_!h!i)g!k!l)}!p!q)P!r!s*S!t!u*j!u!v)P!v!w)P!z!{)P!|!}*z!}#O+P#O#P+U#P#Q+Z#R#S+`#T#U+`#U#V+v#V#W-f#W#X/R#X#d+`#d#e1k#e#f+`#f#g2a#g#o+`#o#p3k#p#q3p#q#r3u#y#z%v$f$g%v$r$s3z%o%p4P5i6S+`#BY#BZ%v$IS$I_%v$I|$JO%v$JT$JU%v$KV$KW%v% l% m4U%%Y%%Z4Z%%[%%]4`%&Y%&Z4e%&]%&^4j%&_%&`4o%&`%&a4t%&b%&c4y%&c%&d5O%'S%'T5T%'T%'U5Y%'U%'V5_%(^%(_5d%(b%(c5i%(c%(d5n%)Q%)R5s%)S%)T5x%)U%)V5}&FU&FV%v~%{Y!V~X^%vpq%v#y#z%v$f$g%v#BY#BZ%v$IS$I_%v$I|$JO%v$JT$JU%v$KV$KW%v&FU&FV%v~&pO!S~~&uOR~~&zO_~~'POV~~'UOW~~'ZO!s~~'`OX~P'eP!`P!Q!['`R'oQdQ!`P|}'u!Q!['hQ'xP!R!['{Q(QQdQ|}'u!Q!['{~(ZQ!_!`(a%&b%&c(f~(fOm~~(kOp~~(pOk~~(uOw~~(zOz~~)POu~~)SP!Q![)V~)[PT~!Q![)V~)dPi~!Q![)V~)jQ!Q![)p#]#^)x~)uPn~!Q![)p~)}Oc~~*SOj~~*VQ!Q![*]#f#g*e~*bP|~!Q![*]~*jO!m~~*oPl~!Q![*r~*wPU~!Q![*r~+PO!b~~+UOe~~+ZOZ~~+`Of~~+eRQ~!Q![+n#T#o+`5i6S+`~+sPQ~!Q![+n~+{TQ~!Q![+n#T#c+`#c#d,[#d#o+`5i6S+`~,aTQ~!Q![+n#T#c+`#c#d,p#d#o+`5i6S+`~,uTQ~!Q![+n#T#`+`#`#a-U#a#o+`5i6S+`~-]R!p~Q~!Q![+n#T#o+`5i6S+`~-kSQ~!Q![+n#T#U-w#U#o+`5i6S+`~-|TQ~!Q![+n#T#f+`#f#g.]#g#o+`5i6S+`~.bTQ~!Q![+n#T#W+`#W#X.q#X#o+`5i6S+`~.xR!o~Q~!Q![+n#T#o+`5i6S+`~/WTQ~!Q![+n#T#X+`#X#Y/g#Y#o+`5i6S+`~/lTQ~!Q![+n#T#U+`#U#V/{#V#o+`5i6S+`~0QTQ~!Q![+n#T#c+`#c#d0a#d#o+`5i6S+`~0fTQ~!Q![+n#T#c+`#c#d0u#d#o+`5i6S+`~0zTQ~!Q![+n#T#`+`#`#a1Z#a#o+`5i6S+`~1bR!q~Q~!Q![+n#T#o+`5i6S+`~1pTQ~!Q![+n#T#f+`#f#g2P#g#o+`5i6S+`~2WR!n~Q~!Q![+n#T#o+`5i6S+`~2fTQ~!Q![+n#T#X+`#X#Y2u#Y#o+`5i6S+`~2zTQ~!Q![+n#T#W+`#W#X3Z#X#o+`5i6S+`~3bR!r~Q~!Q![+n#T#o+`5i6S+`~3pO`~~3uOh~~3zOa~~4PO{~~4UO^~~4ZOb~~4`O!Q~~4eO!P~~4jO}~~4oO!O~~4tO!a~~4yO[~~5OOg~~5TOq~~5YO!R~~5_O]~~5dOY~~5iOy~~5nOx~~5sOv~~5xOt~~5}Os~~6SOr~",
|
||||
tokenizers: [0, 1],
|
||||
topRules: { Expression: [0, 1] },
|
||||
tokenPrec: 1749
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
Debool { "debool" }
|
||||
Red { "red" }
|
||||
|
||||
Global { $[XCSDAT]$[0-9]+ }
|
||||
Global { $[XCSDATN]$[0-9]+ }
|
||||
Function { "F"$[0-9]+ }
|
||||
Predicate { "P"$[0-9]+ }
|
||||
Radical { "R"$[0-9]+ }
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
debool { "debool" }
|
||||
red { "red" }
|
||||
|
||||
Global { $[XCSDAT]$[0-9]+ }
|
||||
Global { $[XCSDATN]$[0-9]+ }
|
||||
Function { "F"$[0-9]+ }
|
||||
Predicate { "P"$[0-9]+ }
|
||||
Radical { "R"$[0-9]+ }
|
||||
|
|
|
@ -16,7 +16,7 @@ import { type AliasMapping, type IArgumentValue, RSErrorClass, type SyntaxTree }
|
|||
|
||||
// cspell:disable
|
||||
const LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\d*/g;
|
||||
const GLOBALS_REGEXP = /[XCSADFPT]\d+/g;
|
||||
const GLOBALS_REGEXP = /[XCSADFPTN]\d+/g;
|
||||
const COMPLEX_SYMBOLS_REGEXP = /[∀∃×ℬ;|:]/g;
|
||||
const TYPIFICATION_SET = /^ℬ+\([ℬ\(X\d+\)×]*\)$/g;
|
||||
// cspell:enable
|
||||
|
|
Loading…
Reference in New Issue
Block a user