@rsconcept/domain 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/cctext/index.d.ts +1 -0
  4. package/dist/cctext/index.js +42 -0
  5. package/dist/cctext/index.js.map +1 -0
  6. package/dist/cctext/language-api.d.ts +43 -0
  7. package/dist/cctext/language-api.js +252 -0
  8. package/dist/cctext/language-api.js.map +1 -0
  9. package/dist/cctext/language.d.ts +58 -0
  10. package/dist/cctext/language.js +44 -0
  11. package/dist/cctext/language.js.map +1 -0
  12. package/dist/graph/graph.d.ts +62 -0
  13. package/dist/graph/graph.js +385 -0
  14. package/dist/graph/graph.js.map +1 -0
  15. package/dist/graph/index.d.ts +1 -0
  16. package/dist/graph/index.js +384 -0
  17. package/dist/graph/index.js.map +1 -0
  18. package/dist/index.d.ts +28 -0
  19. package/dist/index.js +5851 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/library/folder-tree.d.ts +32 -0
  22. package/dist/library/folder-tree.js +136 -0
  23. package/dist/library/folder-tree.js.map +1 -0
  24. package/dist/library/index.d.ts +17 -0
  25. package/dist/library/index.js +2800 -0
  26. package/dist/library/index.js.map +1 -0
  27. package/dist/library/library-api.d.ts +6 -0
  28. package/dist/library/library-api.js +13 -0
  29. package/dist/library/library-api.js.map +1 -0
  30. package/dist/library/library.d.ts +56 -0
  31. package/dist/library/library.js +23 -0
  32. package/dist/library/library.js.map +1 -0
  33. package/dist/library/oss-api.d.ts +47 -0
  34. package/dist/library/oss-api.js +1105 -0
  35. package/dist/library/oss-api.js.map +1 -0
  36. package/dist/library/oss-layout-api.d.ts +36 -0
  37. package/dist/library/oss-layout-api.js +330 -0
  38. package/dist/library/oss-layout-api.js.map +1 -0
  39. package/dist/library/oss-layout.d.ts +25 -0
  40. package/dist/library/oss-layout.js +1 -0
  41. package/dist/library/oss-layout.js.map +1 -0
  42. package/dist/library/oss.d.ts +136 -0
  43. package/dist/library/oss.js +30 -0
  44. package/dist/library/oss.js.map +1 -0
  45. package/dist/library/rsengine.d.ts +116 -0
  46. package/dist/library/rsengine.js +2604 -0
  47. package/dist/library/rsengine.js.map +1 -0
  48. package/dist/library/rsform-api.d.ts +74 -0
  49. package/dist/library/rsform-api.js +879 -0
  50. package/dist/library/rsform-api.js.map +1 -0
  51. package/dist/library/rsform.d.ts +206 -0
  52. package/dist/library/rsform.js +32 -0
  53. package/dist/library/rsform.js.map +1 -0
  54. package/dist/library/rsmodel-api.d.ts +43 -0
  55. package/dist/library/rsmodel-api.js +836 -0
  56. package/dist/library/rsmodel-api.js.map +1 -0
  57. package/dist/library/rsmodel.d.ts +52 -0
  58. package/dist/library/rsmodel.js +25 -0
  59. package/dist/library/rsmodel.js.map +1 -0
  60. package/dist/library/structure-planner.d.ts +33 -0
  61. package/dist/library/structure-planner.js +481 -0
  62. package/dist/library/structure-planner.js.map +1 -0
  63. package/dist/parsing/ast.d.ts +49 -0
  64. package/dist/parsing/ast.js +93 -0
  65. package/dist/parsing/ast.js.map +1 -0
  66. package/dist/parsing/index.d.ts +3 -0
  67. package/dist/parsing/index.js +141 -0
  68. package/dist/parsing/index.js.map +1 -0
  69. package/dist/parsing/lezer-tree.d.ts +13 -0
  70. package/dist/parsing/lezer-tree.js +50 -0
  71. package/dist/parsing/lezer-tree.js.map +1 -0
  72. package/dist/rslang/api.d.ts +53 -0
  73. package/dist/rslang/api.js +846 -0
  74. package/dist/rslang/api.js.map +1 -0
  75. package/dist/rslang/ast-annotations.d.ts +18 -0
  76. package/dist/rslang/ast-annotations.js +56 -0
  77. package/dist/rslang/ast-annotations.js.map +1 -0
  78. package/dist/rslang/error.d.ts +85 -0
  79. package/dist/rslang/error.js +159 -0
  80. package/dist/rslang/error.js.map +1 -0
  81. package/dist/rslang/eval/calculator.d.ts +43 -0
  82. package/dist/rslang/eval/calculator.js +1639 -0
  83. package/dist/rslang/eval/calculator.js.map +1 -0
  84. package/dist/rslang/eval/evaluation-cache.d.ts +36 -0
  85. package/dist/rslang/eval/evaluation-cache.js +310 -0
  86. package/dist/rslang/eval/evaluation-cache.js.map +1 -0
  87. package/dist/rslang/eval/evaluator.d.ts +70 -0
  88. package/dist/rslang/eval/evaluator.js +1514 -0
  89. package/dist/rslang/eval/evaluator.js.map +1 -0
  90. package/dist/rslang/eval/value-api.d.ts +48 -0
  91. package/dist/rslang/eval/value-api.js +490 -0
  92. package/dist/rslang/eval/value-api.js.map +1 -0
  93. package/dist/rslang/eval/value.d.ts +36 -0
  94. package/dist/rslang/eval/value.js +118 -0
  95. package/dist/rslang/eval/value.js.map +1 -0
  96. package/dist/rslang/index.d.ts +17 -0
  97. package/dist/rslang/index.js +4314 -0
  98. package/dist/rslang/index.js.map +1 -0
  99. package/dist/rslang/labels.d.ts +16 -0
  100. package/dist/rslang/labels.js +315 -0
  101. package/dist/rslang/labels.js.map +1 -0
  102. package/dist/rslang/parser/expression-generator.d.ts +10 -0
  103. package/dist/rslang/parser/expression-generator.js +451 -0
  104. package/dist/rslang/parser/expression-generator.js.map +1 -0
  105. package/dist/rslang/parser/normalize.d.ts +11 -0
  106. package/dist/rslang/parser/normalize.js +507 -0
  107. package/dist/rslang/parser/normalize.js.map +1 -0
  108. package/dist/rslang/parser/parser.d.ts +5 -0
  109. package/dist/rslang/parser/parser.js +24 -0
  110. package/dist/rslang/parser/parser.js.map +1 -0
  111. package/dist/rslang/parser/parser.terms.d.ts +42 -0
  112. package/dist/rslang/parser/parser.terms.js +84 -0
  113. package/dist/rslang/parser/parser.terms.js.map +1 -0
  114. package/dist/rslang/parser/syntax-errors.d.ts +11 -0
  115. package/dist/rslang/parser/syntax-errors.js +403 -0
  116. package/dist/rslang/parser/syntax-errors.js.map +1 -0
  117. package/dist/rslang/parser/token.d.ts +79 -0
  118. package/dist/rslang/parser/token.js +95 -0
  119. package/dist/rslang/parser/token.js.map +1 -0
  120. package/dist/rslang/semantic/analyzer.d.ts +39 -0
  121. package/dist/rslang/semantic/analyzer.js +2604 -0
  122. package/dist/rslang/semantic/analyzer.js.map +1 -0
  123. package/dist/rslang/semantic/arguments-extractor.d.ts +42 -0
  124. package/dist/rslang/semantic/arguments-extractor.js +366 -0
  125. package/dist/rslang/semantic/arguments-extractor.js.map +1 -0
  126. package/dist/rslang/semantic/type-auditor.d.ts +73 -0
  127. package/dist/rslang/semantic/type-auditor.js +1570 -0
  128. package/dist/rslang/semantic/type-auditor.js.map +1 -0
  129. package/dist/rslang/semantic/typification-api.d.ts +27 -0
  130. package/dist/rslang/semantic/typification-api.js +320 -0
  131. package/dist/rslang/semantic/typification-api.js.map +1 -0
  132. package/dist/rslang/semantic/typification-parser.d.ts +12 -0
  133. package/dist/rslang/semantic/typification-parser.js +226 -0
  134. package/dist/rslang/semantic/typification-parser.js.map +1 -0
  135. package/dist/rslang/semantic/typification.d.ts +119 -0
  136. package/dist/rslang/semantic/typification.js +74 -0
  137. package/dist/rslang/semantic/typification.js.map +1 -0
  138. package/dist/rslang/semantic/value-auditor.d.ts +43 -0
  139. package/dist/rslang/semantic/value-auditor.js +523 -0
  140. package/dist/rslang/semantic/value-auditor.js.map +1 -0
  141. package/dist/rslang/semantic/value-class.d.ts +10 -0
  142. package/dist/rslang/semantic/value-class.js +9 -0
  143. package/dist/rslang/semantic/value-class.js.map +1 -0
  144. package/dist/rslang/typification-graph.d.ts +33 -0
  145. package/dist/rslang/typification-graph.js +311 -0
  146. package/dist/rslang/typification-graph.js.map +1 -0
  147. package/dist/shared/branded.d.ts +7 -0
  148. package/dist/shared/branded.js +1 -0
  149. package/dist/shared/branded.js.map +1 -0
  150. package/dist/shared/hash.d.ts +6 -0
  151. package/dist/shared/hash.js +18 -0
  152. package/dist/shared/hash.js.map +1 -0
  153. package/dist/shared/index.d.ts +2 -0
  154. package/dist/shared/index.js +18 -0
  155. package/dist/shared/index.js.map +1 -0
  156. package/package.json +184 -0
  157. package/src/cctext/index.ts +9 -0
  158. package/src/cctext/language-api.test.ts +149 -0
  159. package/src/cctext/language-api.ts +285 -0
  160. package/src/cctext/language.ts +80 -0
  161. package/src/graph/graph.test.ts +392 -0
  162. package/src/graph/graph.ts +433 -0
  163. package/src/graph/index.ts +1 -0
  164. package/src/index.ts +96 -0
  165. package/src/library/folder-tree.test.ts +47 -0
  166. package/src/library/folder-tree.ts +156 -0
  167. package/src/library/index.ts +46 -0
  168. package/src/library/library-api.test.ts +32 -0
  169. package/src/library/library-api.ts +11 -0
  170. package/src/library/library.ts +61 -0
  171. package/src/library/oss-api.ts +449 -0
  172. package/src/library/oss-layout-api.ts +377 -0
  173. package/src/library/oss-layout.ts +27 -0
  174. package/src/library/oss.ts +150 -0
  175. package/src/library/rsengine.ts +593 -0
  176. package/src/library/rsform-api.ts +533 -0
  177. package/src/library/rsform.ts +228 -0
  178. package/src/library/rsmodel-api.ts +340 -0
  179. package/src/library/rsmodel.ts +50 -0
  180. package/src/library/structure-planner.ts +143 -0
  181. package/src/parsing/ast.ts +136 -0
  182. package/src/parsing/index.ts +15 -0
  183. package/src/parsing/lezer-tree.ts +69 -0
  184. package/src/rslang/api.test.ts +116 -0
  185. package/src/rslang/api.ts +183 -0
  186. package/src/rslang/ast-annotations.ts +70 -0
  187. package/src/rslang/error.ts +129 -0
  188. package/src/rslang/eval/calculator.test.ts +124 -0
  189. package/src/rslang/eval/calculator.ts +121 -0
  190. package/src/rslang/eval/evaluation-cache.ts +257 -0
  191. package/src/rslang/eval/evaluator.test.ts +352 -0
  192. package/src/rslang/eval/evaluator.ts +935 -0
  193. package/src/rslang/eval/value-api.test.ts +105 -0
  194. package/src/rslang/eval/value-api.ts +444 -0
  195. package/src/rslang/eval/value.ts +102 -0
  196. package/src/rslang/index.ts +23 -0
  197. package/src/rslang/labels.ts +191 -0
  198. package/src/rslang/parser/expression-generator.test.ts +100 -0
  199. package/src/rslang/parser/expression-generator.ts +466 -0
  200. package/src/rslang/parser/normalize.test.ts +99 -0
  201. package/src/rslang/parser/normalize.ts +462 -0
  202. package/src/rslang/parser/parser.terms.ts +42 -0
  203. package/src/rslang/parser/parser.test.ts +153 -0
  204. package/src/rslang/parser/parser.ts +20 -0
  205. package/src/rslang/parser/rslang.grammar +251 -0
  206. package/src/rslang/parser/syntax-errors.ts +209 -0
  207. package/src/rslang/parser/token.ts +106 -0
  208. package/src/rslang/semantic/analyzer.test.ts +59 -0
  209. package/src/rslang/semantic/analyzer.ts +179 -0
  210. package/src/rslang/semantic/arguments-extractor.ts +327 -0
  211. package/src/rslang/semantic/type-auditor.test.ts +326 -0
  212. package/src/rslang/semantic/type-auditor.ts +1049 -0
  213. package/src/rslang/semantic/typification-api.test.ts +46 -0
  214. package/src/rslang/semantic/typification-api.ts +321 -0
  215. package/src/rslang/semantic/typification-parser.test.ts +50 -0
  216. package/src/rslang/semantic/typification-parser.ts +220 -0
  217. package/src/rslang/semantic/typification.ts +180 -0
  218. package/src/rslang/semantic/value-auditor.test.ts +206 -0
  219. package/src/rslang/semantic/value-auditor.ts +332 -0
  220. package/src/rslang/semantic/value-class.ts +11 -0
  221. package/src/rslang/typification-graph.ts +155 -0
  222. package/src/shared/branded.ts +6 -0
  223. package/src/shared/hash.ts +17 -0
  224. package/src/shared/index.ts +2 -0
@@ -0,0 +1,251 @@
1
+ ///////////////////////////////////////////////////////////
2
+ // ------------- Generator Definitions --------------------
3
+ ///////////////////////////////////////////////////////////
4
+ @detectDelim
5
+
6
+ ///////////////////////////////////////////////////////////
7
+ // ------------- Precedence Definitions --------------------
8
+ ///////////////////////////////////////////////////////////
9
+ @precedence {
10
+ decl @cut,
11
+ set_bool @right,
12
+ times @left,
13
+ plus @left minus @left,
14
+ set_decart @left set_union @left set_intersect @left set_minus @left set_symminus @left,
15
+ expr_pred @left,
16
+ not @right,
17
+ quant @right,
18
+ log_and @left,
19
+ log_or @left,
20
+ log_impl @left,
21
+ log_equiv @left
22
+ }
23
+
24
+ ///////////////////////////////////////////////////////////
25
+ // ------------- Terminal Tokens --------------------------
26
+ ///////////////////////////////////////////////////////////
27
+ @tokens {
28
+ space { @whitespace+ }
29
+ Integer { $[0-9]+ }
30
+ EmptySet { "∅" }
31
+ IntegerSet { "Z" }
32
+
33
+ BigPr { "Pr"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
34
+ SmallPr { "pr"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
35
+ Filter { "Fi"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
36
+ Card { "card" }
37
+ Bool { "bool" }
38
+ Debool { "debool" }
39
+ Red { "red" }
40
+
41
+ Global { $[XCSDATN]$[0-9]+ }
42
+ Function { "F"$[0-9]+ }
43
+ Predicate { "P"$[0-9]+ }
44
+ Radical { "R"$[0-9]+ }
45
+ Local { $[_a-zα-ω]($[a-zα-ω])*$[0-9]* }
46
+ PrefixR { "R" }
47
+ PrefixI { "I" }
48
+ PrefixD { "D" }
49
+
50
+ "¬"
51
+ "∀" "∃" "⇔" "⇒" "∨" "&"
52
+ "ℬ"
53
+ "+" "-" "*" "∪" "\\" "∆" "∩" "×"
54
+ "∈" "∉" "⊆" "⊄" "⊂" ">" "≥" "≤" "<" "≠" "="
55
+ ":∈" ":="
56
+
57
+ "," ";" "|"
58
+ "[" "]"
59
+ "{" "}"
60
+ "(" ")"
61
+
62
+ @precedence {
63
+ Filter
64
+ BigPr
65
+ Predicate
66
+ Function
67
+ Global
68
+ Radical
69
+ PrefixR
70
+ PrefixI
71
+ PrefixD
72
+ }
73
+ @precedence {
74
+ Card
75
+ Bool
76
+ Debool
77
+ Red
78
+ SmallPr
79
+ Local
80
+ }
81
+ }
82
+
83
+ @skip { space }
84
+
85
+
86
+ ///////////////////////////////////////////////////////////////////////////////
87
+ // ------------------------- Grammar Rules ------------------------------------
88
+ ///////////////////////////////////////////////////////////////////////////////
89
+
90
+ // ------------------------- Language Expression ------------------------------
91
+ @top Expression {
92
+ expr_atom |
93
+ Function_decl
94
+ }
95
+
96
+ expr_atom {
97
+ Logic |
98
+ Setexpr
99
+ }
100
+
101
+ Function_decl {
102
+ "[" Arguments "]" expr_atom
103
+ }
104
+
105
+
106
+ // ------------------------- Variables and arguments -------------------------
107
+ Arguments {
108
+ Declaration |
109
+ Arguments "," Declaration
110
+ }
111
+ Declaration {
112
+ Variable "∈" expr_atom
113
+ }
114
+ Variable {
115
+ Local |
116
+ Tuple
117
+ }
118
+ Variable_pack {
119
+ Variable |
120
+ Variable_pack "," Variable
121
+ }
122
+
123
+
124
+ // ------------------------- Logic Expressions --------------------------------
125
+ Logic {
126
+ Logic_predicates |
127
+ Logic_unary |
128
+ Logic_binary |
129
+ "(" Logic ")"
130
+ }
131
+
132
+ Logic_predicates {
133
+ Variable ":∈" expr_atom |
134
+ Variable ":=" expr_atom |
135
+ expr_atom !expr_pred "∈" expr_atom |
136
+ expr_atom !expr_pred "∉" expr_atom |
137
+ expr_atom !expr_pred "⊆" expr_atom |
138
+ expr_atom !expr_pred "⊄" expr_atom |
139
+ expr_atom !expr_pred "⊂" expr_atom |
140
+ expr_atom !expr_pred ">" expr_atom |
141
+ expr_atom !expr_pred "≥" expr_atom |
142
+ expr_atom !expr_pred "<" expr_atom |
143
+ expr_atom !expr_pred "≤" expr_atom |
144
+ expr_atom !expr_pred "≠" expr_atom |
145
+ expr_atom !expr_pred "=" expr_atom
146
+ }
147
+
148
+ Logic_unary {
149
+ !not "¬" expr_atom |
150
+ Predicate "[" expr_enum "]" |
151
+ Logic_quantor
152
+ }
153
+
154
+ Logic_quantor {
155
+ "∀" Variable_pack "∈" expr_atom !quant expr_atom |
156
+ "∃" Variable_pack "∈" expr_atom !quant expr_atom
157
+ }
158
+
159
+ Logic_binary {
160
+ expr_atom !log_equiv "⇔" expr_atom |
161
+ expr_atom !log_impl "⇒" expr_atom |
162
+ expr_atom !log_or "∨" expr_atom |
163
+ expr_atom !log_and "&" expr_atom
164
+ }
165
+
166
+
167
+ // ------------------------- Set Expressions ----------------------------------
168
+ Setexpr {
169
+ literal |
170
+ identifier |
171
+ Setexpr_binary |
172
+ setexpr_generators |
173
+ Function "[" expr_enum "]" |
174
+ textFunction "(" expr_atom ")"
175
+ }
176
+ textFunction {
177
+ BigPr |
178
+ SmallPr |
179
+ Card |
180
+ Bool |
181
+ Debool |
182
+ Red
183
+ }
184
+ expr_enum {
185
+ expr_atom |
186
+ Expr_enum_min2
187
+ }
188
+ Expr_enum_min2 {
189
+ expr_enum "," expr_atom
190
+ }
191
+
192
+ literal {
193
+ Integer |
194
+ EmptySet |
195
+ IntegerSet
196
+ }
197
+ identifier {
198
+ Local ~local_decl |
199
+ Global |
200
+ Radical
201
+ }
202
+
203
+ Setexpr_binary {
204
+ expr_atom !times "*" expr_atom |
205
+ expr_atom !plus "+" expr_atom |
206
+ expr_atom !minus "-" expr_atom |
207
+ expr_atom !set_union "∪" expr_atom |
208
+ expr_atom !set_minus "\\" expr_atom |
209
+ expr_atom !set_symminus "∆" expr_atom |
210
+ expr_atom !set_intersect "∩" expr_atom |
211
+ expr_atom !set_decart "×" expr_atom |
212
+ "(" Setexpr_binary ")"
213
+ }
214
+
215
+ setexpr_generators {
216
+ Enumeration |
217
+ Tuple |
218
+ Boolean |
219
+ Filter_expression |
220
+ Declarative |
221
+ Imperative |
222
+ Recursion
223
+ }
224
+ Enumeration {
225
+ "{" expr_enum "}"
226
+ }
227
+ Tuple {
228
+ "(" Expr_enum_min2 ")"
229
+ }
230
+ Boolean {
231
+ !set_bool "ℬ" "(" expr_atom ")" |
232
+ !set_bool "ℬ" Boolean
233
+ }
234
+ Filter_expression {
235
+ Filter "[" expr_enum "]" "(" expr_atom ")"
236
+ }
237
+
238
+ Declarative {
239
+ "{" Local ~local_decl "∈" expr_atom "|" expr_atom "}" |
240
+ PrefixD "{" Variable "∈" expr_atom "|" expr_atom "}"
241
+ }
242
+ Recursion {
243
+ PrefixR "{" Variable ":=" expr_atom ("|" expr_atom)? "|" expr_atom "}"
244
+ }
245
+ Imperative {
246
+ PrefixI "{" expr_atom "|" Imp_blocks "}"
247
+ }
248
+ Imp_blocks {
249
+ expr_atom |
250
+ Imp_blocks ";" expr_atom
251
+ }
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Module: Syntactic errors reporting.
3
+ */
4
+
5
+ import { type AstNode, visitAstDFS } from '../../parsing';
6
+ import { annotateError } from '../ast-annotations';
7
+ import { type ErrorReporter, RSErrorCode, type RSErrorDescription } from '../error';
8
+
9
+ import { Variable } from './parser.terms';
10
+ import { TokenID } from './token';
11
+
12
+ export function extractSyntaxErrors(
13
+ ast: AstNode,
14
+ expression: string,
15
+ reporter: ErrorReporter,
16
+ annotateErrors: boolean = false
17
+ ) {
18
+ const bracketError = extractBracketErrors(expression);
19
+ if (bracketError !== null) {
20
+ reporter(bracketError);
21
+ if (annotateErrors) {
22
+ annotateError(ast, bracketError.code, bracketError.params);
23
+ }
24
+ }
25
+ const hasBracketErrors = bracketError !== null;
26
+ visitAstDFS(ast, node => extractInternal(node, reporter, annotateErrors, hasBracketErrors));
27
+ }
28
+
29
+ // ====== Internals =========
30
+ function extractInternal(
31
+ node: AstNode,
32
+ reporter: ErrorReporter,
33
+ annotateErrors: boolean,
34
+ ignoreUnknownErrors: boolean
35
+ ) {
36
+ if (node.typeID !== TokenID.ERROR) {
37
+ return;
38
+ }
39
+
40
+ function emit(target: AstNode, code: RSErrorCode) {
41
+ reporter({ code: code, from: target.from, to: target.to });
42
+ if (annotateErrors) {
43
+ annotateError(target, code);
44
+ }
45
+ }
46
+
47
+ const parent = node.parent;
48
+ if (parent === null) {
49
+ if (!ignoreUnknownErrors) {
50
+ return emit(node, RSErrorCode.unknownSyntax);
51
+ }
52
+ return;
53
+ }
54
+
55
+ if (parent.typeID === Variable) {
56
+ return emit(parent, RSErrorCode.expectedLocal);
57
+ }
58
+
59
+ if (!ignoreUnknownErrors) {
60
+ emit(node.from === node.to ? parent : node, RSErrorCode.unknownSyntax);
61
+ }
62
+ }
63
+
64
+ type OpenBracket = '(' | '[' | '{';
65
+ type CloseBracket = ')' | ']' | '}';
66
+
67
+ interface BracketFrame {
68
+ bracket: OpenBracket;
69
+ index: number;
70
+ }
71
+
72
+ function extractBracketErrors(expression: string): RSErrorDescription | null {
73
+ const stack: BracketFrame[] = [];
74
+
75
+ for (let pos = 0; pos < expression.length; pos++) {
76
+ const symbol = expression[pos];
77
+ if (isOpenBracket(symbol)) {
78
+ if (isDoubleParenthesis(expression, pos)) {
79
+ return {
80
+ code: RSErrorCode.doubleParenthesis,
81
+ from: pos,
82
+ to: pos + 2
83
+ };
84
+ }
85
+ stack.push({ bracket: symbol, index: pos });
86
+ continue;
87
+ }
88
+ if (!isCloseBracket(symbol)) {
89
+ continue;
90
+ }
91
+
92
+ const expectedOpen = closeToOpen(symbol);
93
+ const top = stack[stack.length - 1];
94
+ if (top === undefined) {
95
+ return {
96
+ code: RSErrorCode.missingOpenBracket,
97
+ from: pos,
98
+ to: pos + 1,
99
+ params: [expectedOpen]
100
+ };
101
+ }
102
+
103
+ if (top.bracket !== expectedOpen) {
104
+ return {
105
+ code: RSErrorCode.bracketMismatch,
106
+ from: pos,
107
+ to: pos + 1,
108
+ params: [openToClose(top.bracket), symbol]
109
+ };
110
+ }
111
+
112
+ stack.pop();
113
+ }
114
+
115
+ if (stack.length > 0) {
116
+ const unclosed = stack[0];
117
+ const code = missingBracketCode(unclosed.bracket);
118
+ return {
119
+ code,
120
+ from: expression.length,
121
+ to: expression.length
122
+ };
123
+ }
124
+
125
+ return null;
126
+ }
127
+
128
+ function missingBracketCode(bracket: OpenBracket): RSErrorCode {
129
+ switch (bracket) {
130
+ case '(':
131
+ return RSErrorCode.missingParenthesis;
132
+ case '[':
133
+ return RSErrorCode.missingSquareBracket;
134
+ case '{':
135
+ return RSErrorCode.missingCurlyBrace;
136
+ }
137
+ }
138
+
139
+ function isOpenBracket(symbol: string): symbol is OpenBracket {
140
+ return symbol === '(' || symbol === '[' || symbol === '{';
141
+ }
142
+
143
+ function isCloseBracket(symbol: string): symbol is CloseBracket {
144
+ return symbol === ')' || symbol === ']' || symbol === '}';
145
+ }
146
+
147
+ function openToClose(symbol: OpenBracket): CloseBracket {
148
+ switch (symbol) {
149
+ case '(':
150
+ return ')';
151
+ case '[':
152
+ return ']';
153
+ case '{':
154
+ return '}';
155
+ }
156
+ }
157
+
158
+ function closeToOpen(symbol: CloseBracket): OpenBracket {
159
+ switch (symbol) {
160
+ case ')':
161
+ return '(';
162
+ case ']':
163
+ return '[';
164
+ case '}':
165
+ return '{';
166
+ }
167
+ }
168
+
169
+ function isDoubleParenthesis(expression: string, pos: number): boolean {
170
+ const isOpenDoubleParenthesis = expression[pos] === '(' && expression[pos + 1] === '(';
171
+ if (!isOpenDoubleParenthesis) {
172
+ return false;
173
+ }
174
+
175
+ const outerClose = findMatchingCloseBracket(expression, pos);
176
+ const innerClose = findMatchingCloseBracket(expression, pos + 1);
177
+ if (outerClose < 0 || innerClose < 0) {
178
+ return false;
179
+ }
180
+
181
+ return outerClose === innerClose + 1;
182
+ }
183
+
184
+ function findMatchingCloseBracket(expression: string, openPos: number): number {
185
+ if (expression[openPos] !== '(') {
186
+ return -1;
187
+ }
188
+
189
+ const stack: OpenBracket[] = [];
190
+ for (let index = openPos; index < expression.length; index++) {
191
+ const symbol = expression[index];
192
+ if (isOpenBracket(symbol)) {
193
+ stack.push(symbol);
194
+ continue;
195
+ }
196
+ if (!isCloseBracket(symbol)) {
197
+ continue;
198
+ }
199
+ const top = stack.pop();
200
+ if (top === undefined || top !== closeToOpen(symbol)) {
201
+ return -1;
202
+ }
203
+ if (stack.length === 0) {
204
+ return index;
205
+ }
206
+ }
207
+
208
+ return -1;
209
+ }
@@ -0,0 +1,106 @@
1
+ import { TOKEN_ERROR } from '../../parsing';
2
+
3
+ /** Represents RSLang token types. */
4
+ export const TokenID = {
5
+ // Global, local IDs and literals
6
+ ERROR: TOKEN_ERROR,
7
+
8
+ ID_LOCAL: 258,
9
+ ID_GLOBAL: 259,
10
+ ID_FUNCTION: 260,
11
+ ID_PREDICATE: 261,
12
+ ID_RADICAL: 262,
13
+ LIT_INTEGER: 263,
14
+ LIT_WHOLE_NUMBERS: 264,
15
+ LIT_EMPTYSET: 265,
16
+
17
+ // Arithmetic
18
+ PLUS: 266,
19
+ MINUS: 267,
20
+ MULTIPLY: 268,
21
+
22
+ // Integer predicate symbols
23
+ GREATER: 269,
24
+ LESSER: 270,
25
+ GREATER_OR_EQ: 271,
26
+ LESSER_OR_EQ: 272,
27
+
28
+ // Equality comparison
29
+ EQUAL: 273,
30
+ NOTEQUAL: 274,
31
+
32
+ // Logic predicate symbols
33
+ QUANTOR_UNIVERSAL: 275,
34
+ QUANTOR_EXISTS: 276,
35
+ LOGIC_NOT: 277,
36
+ LOGIC_EQUIVALENT: 278,
37
+ LOGIC_IMPLICATION: 279,
38
+ LOGIC_OR: 280,
39
+ LOGIC_AND: 281,
40
+
41
+ // Set theory predicate symbols
42
+ SET_IN: 282,
43
+ SET_NOT_IN: 283,
44
+ SUBSET: 284,
45
+ SUBSET_OR_EQ: 285,
46
+ NOT_SUBSET: 286,
47
+
48
+ // Set theory operators
49
+ DECART: 287,
50
+ SET_UNION: 288,
51
+ SET_INTERSECTION: 289,
52
+ SET_MINUS: 290,
53
+ SET_SYMMETRIC_MINUS: 291,
54
+ BOOLEAN: 292,
55
+
56
+ // Structure operations
57
+ BIGPR: 293,
58
+ SMALLPR: 294,
59
+ FILTER: 295,
60
+ CARD: 296,
61
+ BOOL: 297,
62
+ DEBOOL: 298,
63
+ REDUCE: 299,
64
+
65
+ // Term constructions prefixes
66
+ DECLARATIVE: 300,
67
+ RECURSIVE: 301,
68
+ IMPERATIVE: 302,
69
+
70
+ ITERATE: 303,
71
+ ASSIGN: 304,
72
+
73
+ // Punctuation
74
+ PUNCTUATION_DEFINE: 305,
75
+ PUNCTUATION_STRUCT: 306,
76
+ PUNCTUATION_PL: 307,
77
+ PUNCTUATION_PR: 308,
78
+ PUNCTUATION_CL: 309,
79
+ PUNCTUATION_CR: 310,
80
+ PUNCTUATION_SL: 311,
81
+ PUNCTUATION_SR: 312,
82
+ PUNCTUATION_BAR: 313,
83
+ PUNCTUATION_COMMA: 314,
84
+ PUNCTUATION_SEMICOLON: 315,
85
+
86
+ // ======= Non-terminal tokens =========
87
+ NT_ENUM_DECL: 316,
88
+ NT_TUPLE: 317,
89
+ NT_ENUMERATION: 318,
90
+ NT_TUPLE_DECL: 319,
91
+ NT_ARG_DECL: 320,
92
+
93
+ NT_FUNC_DEFINITION: 321,
94
+ NT_ARGUMENTS: 322,
95
+ NT_FUNC_CALL: 323,
96
+
97
+ NT_DECLARATIVE_EXPR: 324,
98
+ NT_IMPERATIVE_EXPR: 325,
99
+ NT_RECURSIVE_FULL: 326,
100
+ NT_RECURSIVE_SHORT: 327,
101
+
102
+ // ======= Helper tokens ========
103
+ INTERRUPT: 328,
104
+ END: 329
105
+ } as const;
106
+ export type TokenID = (typeof TokenID)[keyof typeof TokenID];
@@ -0,0 +1,59 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+
3
+ import { RSErrorCode, type RSErrorDescription } from '../error';
4
+ import { labelType } from '../labels';
5
+
6
+ import { type AnalysisOptions, RSLangAnalyzer } from './analyzer';
7
+ import { basic, bool, tuple, TypeClass } from './typification';
8
+ import { ValueClass } from './value-class';
9
+
10
+ describe('RSLang analyzer', () => {
11
+ let analyzer: RSLangAnalyzer;
12
+
13
+ function expectError(input: string, options: AnalysisOptions, expectedError: RSErrorDescription) {
14
+ const result = analyzer.checkFull(input, options);
15
+ expect(result.success).toBe(false);
16
+ expect(result.errors.length).toBe(1);
17
+ expect(result.errors[0]).toMatchObject(expectedError);
18
+ }
19
+
20
+ beforeEach(() => {
21
+ analyzer = new RSLangAnalyzer();
22
+ analyzer.addBase('X1');
23
+ analyzer.addBase('C1', true);
24
+ analyzer.setGlobal('S1', bool(tuple([basic('X1'), basic('X1')])), ValueClass.VALUE);
25
+ analyzer.setGlobal('D1', bool(basic('X1')), ValueClass.PROPERTY);
26
+ });
27
+
28
+ it('Empty expression', () => {
29
+ const result = analyzer.checkFull('');
30
+ expect(result.success).toBe(false);
31
+ expect(result.type).toBe(null);
32
+ expect(result.valueClass).toBe(null);
33
+ expect(result.errors.length).toBe(1);
34
+ expect(result.errors[0]).toMatchObject({ code: RSErrorCode.cstEmptyDerived, from: 0, to: 0 });
35
+ });
36
+
37
+ it('Domain', () => {
38
+ const result = analyzer.checkFull('ℬ(X1)', { isDomain: true });
39
+ expect(result.success).toBe(true);
40
+ expect(labelType(result.type)).toBe('ℬ(X1)');
41
+ expect(result.valueClass).toBe(ValueClass.VALUE);
42
+ expect(result.errors.length).toBe(0);
43
+
44
+ expectError('X1∩X1', { isDomain: true }, { code: RSErrorCode.globalStructure, from: 0, to: 5 });
45
+ });
46
+
47
+ it('Expected type', () => {
48
+ expectError('X1', { expected: TypeClass.logic }, { code: RSErrorCode.expectedType, from: 0, to: 2 });
49
+ expectError('1=1', { expected: TypeClass.typification }, { code: RSErrorCode.expectedType, from: 0, to: 3 });
50
+ expectError('1=1', { expected: TypeClass.function }, { code: RSErrorCode.expectedType, from: 0, to: 3 });
51
+ expectError('[a ∈ X1] a=a', { expected: TypeClass.function }, { code: RSErrorCode.expectedType, from: 0, to: 12 });
52
+ expectError('[a ∈ X1] a', { expected: TypeClass.predicate }, { code: RSErrorCode.expectedType, from: 0, to: 10 });
53
+ });
54
+
55
+ it('Reports analyzer-level ranges for whole-expression errors', () => {
56
+ const result = analyzer.checkFull('X1', { expected: TypeClass.logic });
57
+ expect(result.errors[0]).toMatchObject({ code: RSErrorCode.expectedType, from: 0, to: 2 });
58
+ });
59
+ });