@witchcraft/expressit 0.0.2

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 (307) hide show
  1. package/README.md +86 -0
  2. package/dist/ast/builders/array.d.ts +8 -0
  3. package/dist/ast/builders/array.d.ts.map +1 -0
  4. package/dist/ast/builders/array.js +31 -0
  5. package/dist/ast/builders/condition.d.ts +20 -0
  6. package/dist/ast/builders/condition.d.ts.map +1 -0
  7. package/dist/ast/builders/condition.js +28 -0
  8. package/dist/ast/builders/delim.d.ts +11 -0
  9. package/dist/ast/builders/delim.d.ts.map +1 -0
  10. package/dist/ast/builders/delim.js +20 -0
  11. package/dist/ast/builders/error.d.ts +9 -0
  12. package/dist/ast/builders/error.d.ts.map +1 -0
  13. package/dist/ast/builders/error.js +16 -0
  14. package/dist/ast/builders/expression.d.ts +12 -0
  15. package/dist/ast/builders/expression.d.ts.map +1 -0
  16. package/dist/ast/builders/expression.js +31 -0
  17. package/dist/ast/builders/group.d.ts +20 -0
  18. package/dist/ast/builders/group.d.ts.map +1 -0
  19. package/dist/ast/builders/group.js +47 -0
  20. package/dist/ast/builders/index.d.ts +12 -0
  21. package/dist/ast/builders/index.d.ts.map +1 -0
  22. package/dist/ast/builders/index.js +24 -0
  23. package/dist/ast/builders/isFullPos.d.ts +6 -0
  24. package/dist/ast/builders/isFullPos.d.ts.map +1 -0
  25. package/dist/ast/builders/isFullPos.js +6 -0
  26. package/dist/ast/builders/pos.d.ts +21 -0
  27. package/dist/ast/builders/pos.d.ts.map +1 -0
  28. package/dist/ast/builders/pos.js +28 -0
  29. package/dist/ast/builders/token.d.ts +12 -0
  30. package/dist/ast/builders/token.d.ts.map +1 -0
  31. package/dist/ast/builders/token.js +26 -0
  32. package/dist/ast/builders/type.d.ts +6 -0
  33. package/dist/ast/builders/type.d.ts.map +1 -0
  34. package/dist/ast/builders/type.js +37 -0
  35. package/dist/ast/builders/variable.d.ts +17 -0
  36. package/dist/ast/builders/variable.d.ts.map +1 -0
  37. package/dist/ast/builders/variable.js +62 -0
  38. package/dist/ast/classes/ArrayNode.d.ts +18 -0
  39. package/dist/ast/classes/ArrayNode.d.ts.map +1 -0
  40. package/dist/ast/classes/ArrayNode.js +55 -0
  41. package/dist/ast/classes/Condition.d.ts +13 -0
  42. package/dist/ast/classes/Condition.d.ts.map +1 -0
  43. package/dist/ast/classes/Condition.js +21 -0
  44. package/dist/ast/classes/ConditionNode.d.ts +73 -0
  45. package/dist/ast/classes/ConditionNode.d.ts.map +1 -0
  46. package/dist/ast/classes/ConditionNode.js +101 -0
  47. package/dist/ast/classes/ErrorToken.d.ts +27 -0
  48. package/dist/ast/classes/ErrorToken.d.ts.map +1 -0
  49. package/dist/ast/classes/ErrorToken.js +47 -0
  50. package/dist/ast/classes/Expression.d.ts +13 -0
  51. package/dist/ast/classes/Expression.d.ts.map +1 -0
  52. package/dist/ast/classes/Expression.js +19 -0
  53. package/dist/ast/classes/ExpressionNode.d.ts +21 -0
  54. package/dist/ast/classes/ExpressionNode.d.ts.map +1 -0
  55. package/dist/ast/classes/ExpressionNode.js +57 -0
  56. package/dist/ast/classes/GroupNode.d.ts +64 -0
  57. package/dist/ast/classes/GroupNode.d.ts.map +1 -0
  58. package/dist/ast/classes/GroupNode.js +69 -0
  59. package/dist/ast/classes/Node.d.ts +22 -0
  60. package/dist/ast/classes/Node.d.ts.map +1 -0
  61. package/dist/ast/classes/Node.js +28 -0
  62. package/dist/ast/classes/Token.d.ts +27 -0
  63. package/dist/ast/classes/Token.d.ts.map +1 -0
  64. package/dist/ast/classes/Token.js +28 -0
  65. package/dist/ast/classes/ValidToken.d.ts +26 -0
  66. package/dist/ast/classes/ValidToken.d.ts.map +1 -0
  67. package/dist/ast/classes/ValidToken.js +49 -0
  68. package/dist/ast/classes/VariableNode.d.ts +33 -0
  69. package/dist/ast/classes/VariableNode.d.ts.map +1 -0
  70. package/dist/ast/classes/VariableNode.js +58 -0
  71. package/dist/ast/classes/index.d.ts +12 -0
  72. package/dist/ast/classes/index.d.ts.map +1 -0
  73. package/dist/ast/classes/index.js +24 -0
  74. package/dist/ast/handlers.d.ts +42 -0
  75. package/dist/ast/handlers.d.ts.map +1 -0
  76. package/dist/ast/handlers.js +150 -0
  77. package/dist/ast/index.d.ts +4 -0
  78. package/dist/ast/index.d.ts.map +1 -0
  79. package/dist/ast/index.js +8 -0
  80. package/dist/examples/advancedValueComparer.d.ts +3 -0
  81. package/dist/examples/advancedValueComparer.d.ts.map +1 -0
  82. package/dist/examples/advancedValueComparer.js +28 -0
  83. package/dist/examples/shortcutContextParser.d.ts +22 -0
  84. package/dist/examples/shortcutContextParser.d.ts.map +1 -0
  85. package/dist/examples/shortcutContextParser.js +126 -0
  86. package/dist/global.d.js +1 -0
  87. package/dist/grammar/ParserBase.d.ts +51 -0
  88. package/dist/grammar/ParserBase.d.ts.map +1 -0
  89. package/dist/grammar/ParserBase.js +516 -0
  90. package/dist/grammar/createTokens.d.ts +56 -0
  91. package/dist/grammar/createTokens.d.ts.map +1 -0
  92. package/dist/grammar/createTokens.js +843 -0
  93. package/dist/grammar/index.d.ts +3 -0
  94. package/dist/grammar/index.d.ts.map +1 -0
  95. package/dist/grammar/index.js +6 -0
  96. package/dist/helpers/errors.d.ts +9 -0
  97. package/dist/helpers/errors.d.ts.map +1 -0
  98. package/dist/helpers/errors.js +41 -0
  99. package/dist/helpers/general/applyBoolean.d.ts +3 -0
  100. package/dist/helpers/general/applyBoolean.d.ts.map +1 -0
  101. package/dist/helpers/general/applyBoolean.js +17 -0
  102. package/dist/helpers/general/applyPrefix.d.ts +4 -0
  103. package/dist/helpers/general/applyPrefix.d.ts.map +1 -0
  104. package/dist/helpers/general/applyPrefix.js +9 -0
  105. package/dist/helpers/general/defaultConditionNormalizer.d.ts +3 -0
  106. package/dist/helpers/general/defaultConditionNormalizer.d.ts.map +1 -0
  107. package/dist/helpers/general/defaultConditionNormalizer.js +6 -0
  108. package/dist/helpers/general/defaultKeyParser.d.ts +3 -0
  109. package/dist/helpers/general/defaultKeyParser.d.ts.map +1 -0
  110. package/dist/helpers/general/defaultKeyParser.js +8 -0
  111. package/dist/helpers/general/defaultPrefixApplier.d.ts +3 -0
  112. package/dist/helpers/general/defaultPrefixApplier.d.ts.map +1 -0
  113. package/dist/helpers/general/defaultPrefixApplier.js +6 -0
  114. package/dist/helpers/general/defaultValueComparer.d.ts +3 -0
  115. package/dist/helpers/general/defaultValueComparer.d.ts.map +1 -0
  116. package/dist/helpers/general/defaultValueComparer.js +6 -0
  117. package/dist/helpers/general/index.d.ts +7 -0
  118. package/dist/helpers/general/index.d.ts.map +1 -0
  119. package/dist/helpers/general/index.js +14 -0
  120. package/dist/helpers/index.d.ts +4 -0
  121. package/dist/helpers/index.d.ts.map +1 -0
  122. package/dist/helpers/index.js +8 -0
  123. package/dist/helpers/parser/assignParents.d.ts +4 -0
  124. package/dist/helpers/parser/assignParents.d.ts.map +1 -0
  125. package/dist/helpers/parser/assignParents.js +71 -0
  126. package/dist/helpers/parser/checkParserOpts.d.ts +3 -0
  127. package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -0
  128. package/dist/helpers/parser/checkParserOpts.js +126 -0
  129. package/dist/helpers/parser/extractPosition.d.ts +9 -0
  130. package/dist/helpers/parser/extractPosition.d.ts.map +1 -0
  131. package/dist/helpers/parser/extractPosition.js +9 -0
  132. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +5 -0
  133. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -0
  134. package/dist/helpers/parser/getUnclosedRightParenCount.js +20 -0
  135. package/dist/helpers/parser/index.d.ts +9 -0
  136. package/dist/helpers/parser/index.d.ts.map +1 -0
  137. package/dist/helpers/parser/index.js +18 -0
  138. package/dist/helpers/parser/parseParserOptions.d.ts +4 -0
  139. package/dist/helpers/parser/parseParserOptions.d.ts.map +1 -0
  140. package/dist/helpers/parser/parseParserOptions.js +45 -0
  141. package/dist/helpers/parser/seal.d.ts +8 -0
  142. package/dist/helpers/parser/seal.d.ts.map +1 -0
  143. package/dist/helpers/parser/seal.js +10 -0
  144. package/dist/helpers/parser/setParent.d.ts +6 -0
  145. package/dist/helpers/parser/setParent.d.ts.map +1 -0
  146. package/dist/helpers/parser/setParent.js +4 -0
  147. package/dist/helpers/parser/unescape.d.ts +3 -0
  148. package/dist/helpers/parser/unescape.d.ts.map +1 -0
  149. package/dist/helpers/parser/unescape.js +6 -0
  150. package/dist/index.d.ts +6 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +17 -0
  153. package/dist/methods/autocomplete.d.ts +18 -0
  154. package/dist/methods/autocomplete.d.ts.map +1 -0
  155. package/dist/methods/autocomplete.js +109 -0
  156. package/dist/methods/autoreplace.d.ts +13 -0
  157. package/dist/methods/autoreplace.d.ts.map +1 -0
  158. package/dist/methods/autoreplace.js +36 -0
  159. package/dist/methods/autosuggest.d.ts +28 -0
  160. package/dist/methods/autosuggest.d.ts.map +1 -0
  161. package/dist/methods/autosuggest.js +371 -0
  162. package/dist/methods/evaluate.d.ts +11 -0
  163. package/dist/methods/evaluate.d.ts.map +1 -0
  164. package/dist/methods/evaluate.js +30 -0
  165. package/dist/methods/getBestIndex.d.ts +19 -0
  166. package/dist/methods/getBestIndex.d.ts.map +1 -0
  167. package/dist/methods/getBestIndex.js +53 -0
  168. package/dist/methods/getIndexes.d.ts +17 -0
  169. package/dist/methods/getIndexes.d.ts.map +1 -0
  170. package/dist/methods/getIndexes.js +97 -0
  171. package/dist/methods/index.d.ts +9 -0
  172. package/dist/methods/index.d.ts.map +1 -0
  173. package/dist/methods/index.js +18 -0
  174. package/dist/methods/normalize.d.ts +12 -0
  175. package/dist/methods/normalize.d.ts.map +1 -0
  176. package/dist/methods/normalize.js +99 -0
  177. package/dist/methods/validate.d.ts +11 -0
  178. package/dist/methods/validate.d.ts.map +1 -0
  179. package/dist/methods/validate.js +111 -0
  180. package/dist/package.js +7 -0
  181. package/dist/package.json.js +193 -0
  182. package/dist/parser.d.ts +58 -0
  183. package/dist/parser.d.ts.map +1 -0
  184. package/dist/parser.js +136 -0
  185. package/dist/types/ast.d.ts +70 -0
  186. package/dist/types/ast.d.ts.map +1 -0
  187. package/dist/types/ast.js +29 -0
  188. package/dist/types/autocomplete.d.ts +143 -0
  189. package/dist/types/autocomplete.d.ts.map +1 -0
  190. package/dist/types/autocomplete.js +24 -0
  191. package/dist/types/errors.d.ts +34 -0
  192. package/dist/types/errors.d.ts.map +1 -0
  193. package/dist/types/errors.js +10 -0
  194. package/dist/types/index.d.ts +5 -0
  195. package/dist/types/index.d.ts.map +1 -0
  196. package/dist/types/index.js +9 -0
  197. package/dist/types/parser.d.ts +451 -0
  198. package/dist/types/parser.d.ts.map +1 -0
  199. package/dist/types/parser.js +1 -0
  200. package/dist/utils/extractTokens.d.ts +8 -0
  201. package/dist/utils/extractTokens.d.ts.map +1 -0
  202. package/dist/utils/extractTokens.js +50 -0
  203. package/dist/utils/getCursorInfo.d.ts +7 -0
  204. package/dist/utils/getCursorInfo.d.ts.map +1 -0
  205. package/dist/utils/getCursorInfo.js +86 -0
  206. package/dist/utils/getOppositeDelimiter.d.ts +6 -0
  207. package/dist/utils/getOppositeDelimiter.d.ts.map +1 -0
  208. package/dist/utils/getOppositeDelimiter.js +35 -0
  209. package/dist/utils/getSurroundingErrors.d.ts +25 -0
  210. package/dist/utils/getSurroundingErrors.d.ts.map +1 -0
  211. package/dist/utils/getSurroundingErrors.js +37 -0
  212. package/dist/utils/index.d.ts +10 -0
  213. package/dist/utils/index.d.ts.map +1 -0
  214. package/dist/utils/index.js +20 -0
  215. package/dist/utils/isBracket.d.ts +3 -0
  216. package/dist/utils/isBracket.d.ts.map +1 -0
  217. package/dist/utils/isBracket.js +7 -0
  218. package/dist/utils/isDelimiter.d.ts +6 -0
  219. package/dist/utils/isDelimiter.d.ts.map +1 -0
  220. package/dist/utils/isDelimiter.js +17 -0
  221. package/dist/utils/isParen.d.ts +3 -0
  222. package/dist/utils/isParen.d.ts.map +1 -0
  223. package/dist/utils/isParen.js +7 -0
  224. package/dist/utils/isQuote.d.ts +4 -0
  225. package/dist/utils/isQuote.d.ts.map +1 -0
  226. package/dist/utils/isQuote.js +7 -0
  227. package/dist/utils/prettyAst.d.ts +35 -0
  228. package/dist/utils/prettyAst.d.ts.map +1 -0
  229. package/dist/utils/prettyAst.js +112 -0
  230. package/package.json +152 -0
  231. package/src/ast/builders/array.ts +45 -0
  232. package/src/ast/builders/condition.ts +56 -0
  233. package/src/ast/builders/delim.ts +39 -0
  234. package/src/ast/builders/error.ts +22 -0
  235. package/src/ast/builders/expression.ts +66 -0
  236. package/src/ast/builders/group.ts +79 -0
  237. package/src/ast/builders/index.ts +13 -0
  238. package/src/ast/builders/isFullPos.ts +10 -0
  239. package/src/ast/builders/pos.ts +57 -0
  240. package/src/ast/builders/token.ts +46 -0
  241. package/src/ast/builders/type.ts +32 -0
  242. package/src/ast/builders/variable.ts +89 -0
  243. package/src/ast/classes/ArrayNode.ts +46 -0
  244. package/src/ast/classes/Condition.ts +22 -0
  245. package/src/ast/classes/ConditionNode.ts +141 -0
  246. package/src/ast/classes/ErrorToken.ts +49 -0
  247. package/src/ast/classes/Expression.ts +26 -0
  248. package/src/ast/classes/ExpressionNode.ts +62 -0
  249. package/src/ast/classes/GroupNode.ts +127 -0
  250. package/src/ast/classes/Node.ts +47 -0
  251. package/src/ast/classes/Token.ts +59 -0
  252. package/src/ast/classes/ValidToken.ts +56 -0
  253. package/src/ast/classes/VariableNode.ts +67 -0
  254. package/src/ast/classes/index.ts +13 -0
  255. package/src/ast/handlers.ts +190 -0
  256. package/src/ast/index.ts +5 -0
  257. package/src/examples/advancedValueComparer.ts +31 -0
  258. package/src/examples/shortcutContextParser.ts +140 -0
  259. package/src/global.d.ts +4 -0
  260. package/src/grammar/ParserBase.ts +715 -0
  261. package/src/grammar/createTokens.ts +512 -0
  262. package/src/grammar/index.ts +4 -0
  263. package/src/helpers/errors.ts +45 -0
  264. package/src/helpers/general/applyBoolean.ts +9 -0
  265. package/src/helpers/general/applyPrefix.ts +7 -0
  266. package/src/helpers/general/defaultConditionNormalizer.ts +9 -0
  267. package/src/helpers/general/defaultKeyParser.ts +8 -0
  268. package/src/helpers/general/defaultPrefixApplier.ts +7 -0
  269. package/src/helpers/general/defaultValueComparer.ts +7 -0
  270. package/src/helpers/general/index.ts +8 -0
  271. package/src/helpers/index.ts +5 -0
  272. package/src/helpers/parser/assignParents.ts +51 -0
  273. package/src/helpers/parser/checkParserOpts.ts +143 -0
  274. package/src/helpers/parser/extractPosition.ts +15 -0
  275. package/src/helpers/parser/getUnclosedRightParenCount.ts +22 -0
  276. package/src/helpers/parser/index.ts +10 -0
  277. package/src/helpers/parser/parseParserOptions.ts +54 -0
  278. package/src/helpers/parser/seal.ts +14 -0
  279. package/src/helpers/parser/setParent.ts +5 -0
  280. package/src/helpers/parser/unescape.ts +4 -0
  281. package/src/index.ts +7 -0
  282. package/src/methods/autocomplete.ts +128 -0
  283. package/src/methods/autoreplace.ts +46 -0
  284. package/src/methods/autosuggest.ts +543 -0
  285. package/src/methods/evaluate.ts +37 -0
  286. package/src/methods/getBestIndex.ts +53 -0
  287. package/src/methods/getIndexes.ts +99 -0
  288. package/src/methods/index.ts +10 -0
  289. package/src/methods/normalize.ts +138 -0
  290. package/src/methods/validate.ts +141 -0
  291. package/src/package.js +11 -0
  292. package/src/parser.ts +183 -0
  293. package/src/types/ast.ts +148 -0
  294. package/src/types/autocomplete.ts +152 -0
  295. package/src/types/errors.ts +40 -0
  296. package/src/types/index.ts +6 -0
  297. package/src/types/parser.ts +479 -0
  298. package/src/utils/extractTokens.ts +67 -0
  299. package/src/utils/getCursorInfo.ts +106 -0
  300. package/src/utils/getOppositeDelimiter.ts +36 -0
  301. package/src/utils/getSurroundingErrors.ts +57 -0
  302. package/src/utils/index.ts +11 -0
  303. package/src/utils/isBracket.ts +6 -0
  304. package/src/utils/isDelimiter.ts +18 -0
  305. package/src/utils/isParen.ts +6 -0
  306. package/src/utils/isQuote.ts +6 -0
  307. package/src/utils/prettyAst.ts +152 -0
@@ -0,0 +1,715 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+
3
+ import { isArray, unreachable } from "@alanscodelog/utils"
4
+ import { EmbeddedActionsParser, EOF, type IToken, tokenMatcher } from "chevrotain"
5
+
6
+ import type { createTokens } from "./createTokens.js"
7
+
8
+ import { pos } from "../ast/builders/pos.js"
9
+ import { ArrayNode } from "../ast/classes/ArrayNode.js"
10
+ import { ConditionNode } from "../ast/classes/ConditionNode.js"
11
+ import { ErrorToken } from "../ast/classes/ErrorToken.js"
12
+ import type { ExpressionNode } from "../ast/classes/ExpressionNode.js"
13
+ import type { GroupNode } from "../ast/classes/GroupNode.js"
14
+ import type { ValidToken } from "../ast/classes/ValidToken.js"
15
+ import { VariableNode } from "../ast/classes/VariableNode.js"
16
+ import * as handle from "../ast/handlers.js"
17
+ import { extractPosition } from "../helpers/parser/extractPosition.js"
18
+ import { Parser } from "../parser.js"
19
+ import { type AnyToken, type ParserResults, type Position, TOKEN_TYPE, type TokenQuoteTypes } from "../types/ast.js"
20
+ import type { FullParserOptions } from "../types/parser.js"
21
+
22
+
23
+ function processToken<TDefined extends boolean = boolean>(token: IToken, shift: number): [TDefined extends true ? string : string | undefined, Position] {
24
+ let val: string | undefined = token.image
25
+ if (token.isInsertedInRecovery) val = undefined
26
+ return [val as any, extractPosition(token, shift)]
27
+ }
28
+ export class ParserBase<T extends {} = {}> extends EmbeddedActionsParser {
29
+ rawInput!: string
30
+
31
+ private subParser?: Parser
32
+
33
+ private subParser2?: Parser
34
+
35
+ constructor(opts: FullParserOptions<T>, t: ReturnType<typeof createTokens>["tokens"], { customOpAlsoNegation, expandedSepAlsoCustom }: ReturnType<typeof createTokens>["info"]) {
36
+ super(t, {
37
+ recoveryEnabled: true,
38
+ // skipValidations: true
39
+ })
40
+
41
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
42
+ const $ = this
43
+
44
+ $.RULE("main", () => {
45
+ const res = $.SUBRULE($.boolOr)
46
+ $.CONSUME(EOF)
47
+
48
+ return $.ACTION(() => {
49
+ if (res === undefined) {
50
+ const error = handle.token.value(undefined, { start: 0, end: 0 })
51
+ return error
52
+ }
53
+ return res
54
+ })
55
+ })
56
+ $.RULE("boolOr", () => {
57
+ const pairs: any[][] = []
58
+
59
+ const DEF = (): void => {
60
+ const exp = $.SUBRULE2($.boolAnd)
61
+ const extras: any[] = []
62
+
63
+ let next = $.LA(1)
64
+ $.OPTION1({
65
+ GATE: () => opts.onMissingBooleanOperator === "or" &&
66
+ (
67
+ tokenMatcher(next, t.VALUE) ||
68
+ tokenMatcher(next, t.QUOTE_ANY) ||
69
+ tokenMatcher(next, t.PAREN_L) ||
70
+ tokenMatcher(next, t.EXP_PROP_OP) ||
71
+ tokenMatcher(next, t.REGEX_START) ||
72
+ tokenMatcher(next, t.CUSTOM_PROP_OP)
73
+ ),
74
+ DEF: () => {
75
+ let dummyOp
76
+ const cond = $.SUBRULE3($.condition)
77
+ $.ACTION(() => {
78
+ // the operator is missing between the previous token and this exp
79
+ const prev = $.LA(-1)
80
+ const start = prev.endOffset! + 1
81
+ dummyOp = handle.operator.or("", pos({ start }, { fill: true }))
82
+ })
83
+
84
+ extras.push([dummyOp, cond])
85
+ },
86
+ })
87
+
88
+ next = $.LA(1)
89
+ pairs.push([exp, tokenMatcher(next, t.OPERATOR_OR) ? handle.operator.or(...processToken<true>(next, $.shift)) : undefined])
90
+ for (const extra of extras) {
91
+ pairs[pairs.length - 1].splice(1, 1, extra[0])
92
+ pairs.push([extra[1]])
93
+ }
94
+ }
95
+
96
+ $.MANY_SEP({ SEP: t.OPERATOR_OR, DEF })
97
+
98
+
99
+ $.OPTION({
100
+ // many sep sometimes fails to recover when it technically could
101
+ GATE: () => pairs.length === 0 && tokenMatcher($.LA(1), t.OPERATOR_OR),
102
+ DEF: () => {
103
+ $.MANY(() => {
104
+ const next = $.CONSUME(t.OPERATOR_OR)
105
+ pairs.push([undefined, handle.operator.or(...processToken<true>(next, $.shift))])
106
+ while (tokenMatcher($.LA(1), t.VALUE) || tokenMatcher($.LA(1), t.QUOTE_ANY) || tokenMatcher($.LA(1), t.PAREN_L)) {
107
+ pairs.push([$.SUBRULE3($.condition)])
108
+ }
109
+ })
110
+ },
111
+ })
112
+
113
+ return $.ACTION(() => {
114
+ let res = pairs[pairs.length - 1][0]
115
+ for (let i = pairs.length - 1; i > 0; i--) {
116
+ const before = pairs[i - 1]
117
+ if (res === undefined && before === undefined) return undefined
118
+ res = handle.expression(before[0], before[1], res)
119
+ }
120
+ return res
121
+ })
122
+ })
123
+ $.RULE("boolAnd", () => {
124
+ const pairs: any[][] = []
125
+
126
+ const DEF = (): void => {
127
+ const exp = $.SUBRULE2($.condition)
128
+ const extras: any[][] = []
129
+
130
+ let next = $.LA(1)
131
+ $.OPTION1({
132
+ GATE: () => ["error", "and"].includes(opts.onMissingBooleanOperator) &&
133
+ (
134
+ tokenMatcher(next, t.VALUE) ||
135
+ tokenMatcher(next, t.QUOTE_ANY) ||
136
+ tokenMatcher(next, t.PAREN_L) ||
137
+ tokenMatcher(next, t.EXP_PROP_OP) ||
138
+ tokenMatcher(next, t.REGEX_START) ||
139
+ tokenMatcher(next, t.CUSTOM_PROP_OP)
140
+ ),
141
+ DEF: () => {
142
+ $.MANY2(() => {
143
+ let dummyOp
144
+ const cond = $.SUBRULE3($.condition)
145
+ $.ACTION(() => {
146
+ if (opts.onMissingBooleanOperator === "and") {
147
+ // the operator is missing between the previous token and this exp
148
+ const prev = $.LA(-1)
149
+ const start = prev.endOffset! + 1
150
+ dummyOp = handle.operator.and("", pos({ start }, { fill: true }))
151
+ }
152
+ })
153
+
154
+ extras.push([dummyOp, cond])
155
+ })
156
+ },
157
+ })
158
+
159
+ next = $.LA(1)
160
+ pairs.push([exp, tokenMatcher(next, t.OPERATOR_AND) ? handle.operator.and(...processToken<true>(next, $.shift)) : undefined])
161
+ for (const extra of extras) {
162
+ pairs[pairs.length - 1].splice(1, 1, extra[0])
163
+ pairs.push([extra[1]])
164
+ }
165
+ }
166
+
167
+ $.MANY_SEP({ SEP: t.OPERATOR_AND, DEF })
168
+
169
+
170
+ $.OPTION({
171
+ GATE: () => pairs.length === 0 && tokenMatcher($.LA(1), t.OPERATOR_AND),
172
+ DEF: () => {
173
+ $.MANY(() => {
174
+ const next = $.CONSUME(t.OPERATOR_AND)
175
+ pairs.push([undefined, handle.operator.and(...processToken<true>(next, $.shift))])
176
+ while (tokenMatcher($.LA(1), t.VALUE) || tokenMatcher($.LA(1), t.QUOTE_ANY) || tokenMatcher($.LA(1), t.PAREN_L)) {
177
+ pairs.push([$.SUBRULE3($.condition)])
178
+ }
179
+ })
180
+ },
181
+ })
182
+
183
+ return $.ACTION(() => {
184
+ if (pairs.length === 0) return undefined // handle situations like `a ||` where b is missing
185
+ let res = pairs[pairs.length - 1][0]
186
+ for (let i = pairs.length - 1; i > 0; i--) {
187
+ const before = pairs[i - 1]
188
+ res = handle.expression(before[0], before[1], res)
189
+ }
190
+ return res
191
+ })
192
+ })
193
+
194
+ $.RULE("condition", () => {
195
+ const not = $.OPTION(() => $.SUBRULE($.not))
196
+
197
+ const property = $.OPTION2({
198
+ GATE: () => (
199
+ tokenMatcher($.LA(1), t.EXP_PROP_OP) ||
200
+ tokenMatcher($.LA(1), t.CUSTOM_PROP_OP) ||
201
+ tokenMatcher($.LA(2), t.EXP_PROP_OP) ||
202
+ tokenMatcher($.LA(2), t.CUSTOM_PROP_OP) ||
203
+ (
204
+ customOpAlsoNegation &&
205
+ (
206
+ tokenMatcher($.LA(2), t.SYM_NOT) ||
207
+ (tokenMatcher($.LA(0), t.SYM_NOT) && tokenMatcher($.LA(1), t.SYM_NOT))
208
+ )
209
+ )
210
+ ),
211
+ DEF: () => $.SUBRULE($.property),
212
+ }) as ReturnType<typeof $["property"]> | undefined
213
+ const propVal = $.ACTION(() => property?.prop?.value === undefined
214
+ ? undefined
215
+ : property.prop.value instanceof ErrorToken
216
+ ? ""
217
+ : property.prop.value.value)
218
+
219
+ const propOpVal = $.ACTION(() => property?.rest.propertyOperator === undefined
220
+ ? undefined
221
+ : property.rest.propertyOperator instanceof ErrorToken
222
+ ? ""
223
+ : property.rest.propertyOperator.value)
224
+
225
+ const isExpanded = $.ACTION(() => (property?.rest.sepL ?? property?.rest.sepR) !== undefined)
226
+ const convertRegexValues = $.ACTION(() =>
227
+ typeof opts.regexValues === "function" && !opts.regexValues(propVal, propOpVal, isExpanded))
228
+
229
+ const convertArrayValues = $.ACTION(() =>
230
+ typeof opts.arrayValues === "function" && !opts.arrayValues(propVal, propOpVal, isExpanded))
231
+
232
+
233
+ let value: ReturnType<typeof $["plainGroup"]> |
234
+ ReturnType<typeof $["plainBracketGroup"]> |
235
+ ReturnType<typeof $["variable"]> |
236
+ undefined = $.OR2([
237
+ {
238
+ GATE: () => opts.prefixableGroups && property === undefined &&
239
+ $.LA(1).tokenType !== t.PAREN_L && // moves to parsing group below
240
+ (
241
+ (
242
+ tokenMatcher($.LA(1), t.VALUE) &&
243
+ (
244
+ tokenMatcher($.LA(2), t.PAREN_L) || // a(
245
+ (tokenMatcher($.LA(2), t.QUOTE_ANY) && tokenMatcher($.LA(3), t.PAREN_L)) // a"(
246
+ )
247
+ ) ||
248
+ (
249
+ tokenMatcher($.LA(1), t.QUOTE_ANY) &&
250
+ (
251
+ tokenMatcher($.LA(2), t.PAREN_L) || // "(
252
+ (tokenMatcher($.LA(2), t.VALUE) &&
253
+ (
254
+ tokenMatcher($.LA(3), t.PAREN_L) || // "a(
255
+ (tokenMatcher($.LA(3), t.QUOTE_ANY) && tokenMatcher($.LA(4), t.PAREN_L)) // "a"(
256
+ )
257
+ )
258
+ )
259
+ )
260
+
261
+ )
262
+ ,
263
+ ALT: () => $.SUBRULE<any, any>($.variable, { ARGS: [{ unprefixed: true }]}), // un-prefixed
264
+ },
265
+ {
266
+ GATE: () => $.LA(1).tokenType !== t.PAREN_L,
267
+ ALT: () => $.SUBRULE2($.variable),
268
+ },
269
+ {
270
+ GATE: () => $.LA(1).tokenType === t.PAREN_L,
271
+ ALT: () => $.SUBRULE2<any, any>($.plainGroup, { ARGS: [{ onlyValues: property !== undefined, convertRegexValues, convertArrayValues }]}),
272
+ },
273
+ {
274
+ GATE: () => $.LA(1).tokenType === t.BRACKET_L,
275
+ ALT: () => $.SUBRULE2<any, any>($.plainBracketGroup, { ARGS: [{ convertArrayValues }]}),
276
+ },
277
+ {
278
+ GATE: () => not !== undefined || property !== undefined || $.LA(1).tokenType === EOF,
279
+ ALT: () => undefined,
280
+ },
281
+ ])
282
+
283
+ let group = $.OPTION3({
284
+ GATE: () => !(value instanceof ArrayNode) && !isArray(value) && (!value || opts.prefixableGroups) && $.LA(1).tokenType === t.PAREN_L, // is not already plain group
285
+ DEF: () => $.SUBRULE3<any, any>($.plainGroup, { ARGS: [{ onlyValues: property !== undefined, convertRegexValues, convertArrayValues }]}),
286
+ })
287
+
288
+
289
+ return $.ACTION(() => {
290
+ if (isArray(value)) {
291
+ group = value
292
+ value = undefined
293
+ }
294
+
295
+ if (convertRegexValues && value instanceof VariableNode && value.quote?.left.type === TOKEN_TYPE.REGEX) {
296
+ value = handle.variable(undefined, undefined, handle.token.value(
297
+ (value.quote?.left?.value ?? "") + (value.value.value ?? "") + (value.quote?.right?.value ?? ""),
298
+ pos(value)
299
+ ), undefined) as ReturnType<this["variable"]>
300
+ }
301
+ if (group) {
302
+ if (property) {
303
+ // @ts-expect-error group is spreadable
304
+ return handle.condition(not, property?.prop, property?.rest, handle.group(undefined, undefined, ...group))
305
+ }
306
+ if (value) {
307
+ // @ts-expect-error group is spreadable
308
+ return handle.group(undefined, handle.condition(not, undefined, undefined, value), ...group)
309
+ }
310
+ // @ts-expect-error group is spreadable
311
+ return handle.group(not, value, ...group)
312
+ }
313
+ if ([not, property, value].every(_ => _ === undefined)) return undefined
314
+ return handle.condition(not, property?.prop, property?.rest, value)
315
+ })
316
+ })
317
+
318
+ $.RULE("property", () => {
319
+ const prop: any = $.OPTION3(() => $.SUBRULE<any, any>($.variable, { ARGS: [{ unprefixed: true }]}))
320
+
321
+ const rest = $.OR([
322
+ {
323
+ ALT: () => {
324
+ let sepL: any = $.CONSUME(t.EXP_PROP_OP)
325
+ sepL &&= handle.token.sep(...processToken(sepL, $.shift))
326
+
327
+ let op: any = $.OPTION4(() => $.CONSUME2(t.VALUE_UNQUOTED))
328
+ op &&= handle.token.value(...processToken(op, $.shift))
329
+
330
+ let sepR: any = $.OPTION5(() => $.CONSUME2(t.EXP_PROP_OP))
331
+ sepR &&= handle.token.sep(...processToken(sepR, $.shift))
332
+ if (expandedSepAlsoCustom && op === undefined && sepR === undefined) {
333
+ op = sepL
334
+ op.type = TOKEN_TYPE.OP_CUSTOM
335
+ sepL = undefined
336
+ }
337
+ return { sepL, sepR, propertyOperator: op }
338
+ },
339
+ },
340
+ {
341
+ ALT: () => {
342
+ let op: any = $.CONSUME(t.CUSTOM_PROP_OP)
343
+ if (!op.isInsertedInRecovery) op = handle.token.custom(...processToken(op, $.shift))
344
+ return { propertyOperator: op }
345
+ },
346
+ },
347
+ {
348
+ GATE: () => customOpAlsoNegation,
349
+ ALT: () => {
350
+ let op: any = $.CONSUME2(t.SYM_NOT)
351
+ if (!op.isInsertedInRecovery) op = handle.token.custom(...processToken(op, $.shift))
352
+ return { propertyOperator: op }
353
+ },
354
+ },
355
+ ])
356
+
357
+ return { prop, rest }
358
+ })
359
+ $.RULE("plainGroup", (
360
+ { onlyValues = false, convertRegexValues = false, convertArrayValues = false }:
361
+ { onlyValues?: boolean, convertRegexValues?: boolean, convertArrayValues?: boolean } = {}) => {
362
+ const parenL = $.SUBRULE1($.parenL)
363
+ let parenLeftCount = 0
364
+ let start: undefined | number
365
+ let end: undefined | number
366
+ const condition = $.OPTION1({
367
+ GATE: () => !onlyValues,
368
+ DEF: () => $.SUBRULE1($.boolOr),
369
+ })
370
+
371
+ // bypasses self analysis (which goes into an infinite loop for some reason...)
372
+ // see subParser hack below for why
373
+ if (onlyValues && $.LA(1).tokenType !== EOF) {
374
+ while (
375
+ !tokenMatcher($.LA(1), EOF) &&
376
+ (!tokenMatcher($.LA(1), t.PAREN_R) || parenLeftCount !== 0)
377
+ ) {
378
+ const token = $.CONSUME(t.ANY)
379
+
380
+ start ??= extractPosition(token, this.shift).start
381
+ if (tokenMatcher(token, t.PAREN_L)) {
382
+ parenLeftCount++
383
+ }
384
+ if (tokenMatcher(token, t.PAREN_R)) {
385
+ parenLeftCount--
386
+ }
387
+ }
388
+ }
389
+
390
+ if (start !== undefined) {
391
+ end ??= extractPosition($.LA(0), this.shift).end
392
+ }
393
+
394
+ const parenR = $.OPTION2(() => $.SUBRULE1($.parenR))
395
+ return $.ACTION(() => {
396
+ if (start !== undefined) {
397
+ /**
398
+ * This is a bit of a hack to ignore forbidden expressions in groups when used as values (it would make no sense to do something like `prop:op(prop:op(...)))` or `prop:op:(prefix(...))`).
399
+ *
400
+ * Doing this from the tokenizer is very complicated because it would require keeping track of a lot of state since we need to know when a group follows something that even looks like a property/operator.
401
+ *
402
+ * This way we just consume all input until the correct next matching paren (or EOF) and re-parse it with a restricted version of the parser.
403
+ *
404
+ * Performance wise this should not be a problem since at most we add the time of one initialization per Parser/ParserBase class instance and only on demand. After that the parser is re-used when needed for any future parse calls. Additionally it only needs to be called once for the outer group used in a property value (i.e. `prop:OP:((()))` will only cause a single "sub parse").
405
+ */
406
+ const subInput = this.rawInput.slice(start, end)
407
+
408
+ if (this.subParser === undefined) {
409
+ this.subParser = new Parser({
410
+ ...opts,
411
+ customPropertyOperators: [],
412
+ expandedPropertySeparator: undefined,
413
+ regexValues: convertRegexValues,
414
+ arrayValues: convertArrayValues,
415
+ })
416
+ }
417
+ // @ts-expect-error extra param
418
+ const parsed = this.subParser.parse(" ".repeat(start) + subInput, { unsealed: true })
419
+ return [parenL, parsed, parenR]
420
+ }
421
+ // return parsed
422
+ return [parenL, condition, parenR]
423
+ })
424
+ })
425
+ $.RULE("plainBracketGroup", (
426
+ { convertArrayValues = false }:
427
+ { convertArrayValues?: boolean } = {}
428
+ ) => {
429
+ const bracketL = $.SUBRULE1($.bracketL)
430
+ const start = bracketL.start
431
+ const values: any[] = []
432
+ $.MANY({
433
+ GATE: () => !convertArrayValues,
434
+ DEF: () => values.push($.SUBRULE<any, any>($.variable, { ARGS: [{ unprefixed: false, bracketVal: true }]})),
435
+ })
436
+ // bypasses self analysis (which goes into an infinite loop for some reason...)
437
+ // see subParser hack below for why
438
+ if (convertArrayValues && $.LA(1).tokenType !== EOF) {
439
+ while (
440
+ !tokenMatcher($.LA(1), EOF) &&
441
+ !tokenMatcher($.LA(1), t.BRACKET_R)
442
+ ) {
443
+ $.CONSUME(t.ANY)
444
+ }
445
+ }
446
+ const bracketR = $.OPTION2(() => $.SUBRULE1($.bracketR))
447
+ const end = bracketR?.end
448
+
449
+ return $.ACTION(() => {
450
+ if (!convertArrayValues) return handle.array(bracketL, values, bracketR)
451
+ /**
452
+ * Similar problem as with regex values above.
453
+ */
454
+ const subInput = this.rawInput.slice(start, end)
455
+
456
+ if (this.subParser2 === undefined) {
457
+ this.subParser2 = new Parser({
458
+ ...opts,
459
+ customPropertyOperators: [],
460
+ expandedPropertySeparator: undefined,
461
+ arrayValues: false,
462
+ })
463
+ }
464
+ // @ts-expect-error extra param
465
+ const parsed = this.subParser2.parse(" ".repeat(start) + subInput, { unsealed: true })
466
+
467
+ if (parsed instanceof ConditionNode) {
468
+ return parsed.value
469
+ }
470
+ return parsed
471
+ })
472
+ })
473
+
474
+ $.RULE("not", () => {
475
+ const op = $.CONSUME(t.OPERATOR_NOT)
476
+ return $.ACTION(() => handle.operator.not(...processToken<true>(op, $.shift)))
477
+ })
478
+
479
+ $.RULE("variable", (
480
+ { unprefixed = false, bracketVal = false }:
481
+ { unprefixed?: boolean, bracketVal?: boolean } = {}
482
+ ) => {
483
+ let prefix: any = $.OPTION({
484
+ GATE: () => !unprefixed && opts.prefixableStrings !== undefined &&
485
+ tokenMatcher($.LA(2), t.QUOTE_ANY) &&
486
+ tokenMatcher($.LA(4), $.LA(2).tokenType) &&
487
+ opts.prefixableStrings.includes($.LA(1).image),
488
+ DEF: () => $.SUBRULE7<any, any>($.valueUnquoted, { ARGS: [{ bracketVal, onlyToken: true }]}),
489
+ })
490
+
491
+
492
+ prefix &&= handle.token.value(...processToken(prefix, $.shift))
493
+
494
+ const ARGS = [{ bracketVal }]
495
+ const val = $.OR([
496
+ {
497
+ ALT: () => {
498
+ const quoteL = $.SUBRULE($.quoteDouble)
499
+ const value = $.OPTION1(() => $.OR1([
500
+ { ALT: () => $.SUBRULE<any, any>($.valueUnquoted, { ARGS }) },
501
+ { ALT: () => $.SUBRULE($.valueNotDouble) },
502
+ ]))
503
+ const quoteR = $.SUBRULE2($.quoteDouble)
504
+ return $.ACTION(() => handle.variable(prefix, quoteL, value, quoteR))
505
+ },
506
+ },
507
+ {
508
+ ALT: () => {
509
+ const quoteL = $.SUBRULE($.quoteSingle)
510
+ const value = $.OPTION2(() => $.OR2([
511
+ { ALT: () => $.SUBRULE2<any, any>($.valueUnquoted, { ARGS }) },
512
+ { ALT: () => $.SUBRULE($.valueNotSingle) },
513
+ ]))
514
+ const quoteR = $.SUBRULE2($.quoteSingle)
515
+ return $.ACTION(() => handle.variable(prefix, quoteL, value, quoteR))
516
+ },
517
+ },
518
+ {
519
+ ALT: () => {
520
+ const quoteL = $.SUBRULE($.quoteBacktick)
521
+ const value = $.OPTION3(() => $.OR3([
522
+ { ALT: () => $.SUBRULE3<any, any>($.valueUnquoted, { ARGS }) },
523
+ { ALT: () => $.SUBRULE($.valueNotBacktick) },
524
+ ]))
525
+ const quoteR = $.SUBRULE2($.quoteBacktick)
526
+ return $.ACTION(() => handle.variable(prefix, quoteL, value, quoteR))
527
+ },
528
+ },
529
+ {
530
+ ALT: () => {
531
+ const quoteL = $.SUBRULE($.regexAny) as ValidToken<TOKEN_TYPE.REGEX> // the start can never match flags
532
+ // unlike other values, regexes will swallow all input if incorrect
533
+ const value = $.OPTION4(() => $.SUBRULE5($.valueRegex))
534
+ const quoteR = $.OPTION5(() => $.SUBRULE5($.regexAny))
535
+ return $.ACTION(() => {
536
+ const args = isArray(quoteR) ? quoteR : [quoteR] as [typeof quoteR]
537
+ return handle.variable(undefined, quoteL, value, args[0], args[1])
538
+ })
539
+ },
540
+ },
541
+ { // error
542
+ ALT: () => {
543
+ const value = $.SUBRULE4<any, any>($.valueUnquoted, { ARGS })
544
+ const quoteR = $.SUBRULE4($.valueDelimAny)
545
+ return $.ACTION(() => handle.variable(undefined, undefined, value, quoteR))
546
+ },
547
+ },
548
+ { // error
549
+ ALT: () => {
550
+ const quoteL = $.SUBRULE5($.valueDelimAny)
551
+ const value = $.OPTION6(() => $.SUBRULE5<any, any>($.valueUnquoted, { ARGS }))
552
+ return $.ACTION(() => handle.variable(undefined, quoteL, value, undefined))
553
+ },
554
+ },
555
+ {
556
+ ALT: () => {
557
+ const value = $.SUBRULE6<any, any>($.valueUnquoted, { ARGS })
558
+ return $.ACTION(() => handle.variable(undefined, undefined, value, undefined))
559
+ },
560
+ },
561
+ ])
562
+ return val
563
+ })
564
+
565
+ $.RULE("valueDelimAny", () => {
566
+ const value = $.CONSUME(t.QUOTE_ANY)
567
+ return $.ACTION(() => {
568
+ const type = value.image === `"`
569
+ ? "double"
570
+ : value.image === "'"
571
+ ? "single"
572
+ : value.image === "\\"
573
+ ? "regex"
574
+ : value.image === "`"
575
+ ? "tick"
576
+ : unreachable()
577
+ return handle.delimiter[type](...processToken(value, $.shift))
578
+ })
579
+ })
580
+ $.RULE("regexAny", () => {
581
+ const value = $.CONSUME(t.REGEX_ANY)
582
+ return $.ACTION(() => {
583
+ if (value.image.length > 1) {
584
+ // cheat a bit to extract the flags
585
+ const delim = {
586
+ image: "/",
587
+ startOffset: value.startOffset,
588
+ endOffset: value.startOffset,
589
+ }
590
+ const flags = {
591
+ image: value.image.slice(1),
592
+ startOffset: value.startOffset + 1,
593
+ endOffset: value.endOffset,
594
+ }
595
+ return [
596
+ handle.delimiter.regex(...processToken(delim as IToken, $.shift)),
597
+ handle.token.value(...processToken(flags as IToken, $.shift)),
598
+ ]
599
+ }
600
+ return handle.delimiter.regex(...processToken(value, $.shift))
601
+ })
602
+ })
603
+ $.RULE("valueRegex", () => {
604
+ const value = $.CONSUME(t.VALUE_REGEX)
605
+ return $.ACTION(() => handle.token.value(...processToken(value, $.shift)))
606
+ })
607
+ $.RULE("quoteSingle", () => {
608
+ const value = $.CONSUME(t.QUOTE_SINGLE)
609
+ return $.ACTION(() => handle.delimiter.single(...processToken(value, $.shift)))
610
+ })
611
+ $.RULE("quoteDouble", () => {
612
+ const value = $.CONSUME(t.QUOTE_DOUBLE)
613
+ return $.ACTION(() => handle.delimiter.double(...processToken(value, $.shift)))
614
+ })
615
+ $.RULE("quoteBacktick", () => {
616
+ const value = $.CONSUME(t.QUOTE_BACKTICK)
617
+ return $.ACTION(() => handle.delimiter.tick(...processToken(value, $.shift)))
618
+ })
619
+ $.RULE("valueNotSingle", () => {
620
+ const value = $.CONSUME(t.VALUE_FOR_SINGLE)
621
+ return $.ACTION(() => handle.token.value(...processToken(value, $.shift)))
622
+ })
623
+ $.RULE("valueNotDouble", () => {
624
+ const value = $.CONSUME(t.VALUE_FOR_DOUBLE)
625
+ return $.ACTION(() => handle.token.value(...processToken(value, $.shift)))
626
+ })
627
+ $.RULE("valueNotBacktick", () => {
628
+ const value = $.CONSUME(t.VALUE_FOR_BACKTICK)
629
+ return $.ACTION(() => handle.token.value(...processToken(value, $.shift)))
630
+ })
631
+ $.RULE("valueUnquoted", (
632
+ { bracketVal = false, onlyToken = false }:
633
+ { bracketVal?: boolean, onlyToken?: boolean } = {}
634
+ ) => {
635
+ const value: any = $.OR([
636
+ {
637
+ GATE: () => !bracketVal,
638
+ ALT: () => $.CONSUME(t.VALUE_UNQUOTED),
639
+ },
640
+ {
641
+ GATE: () => bracketVal,
642
+ ALT: () => $.CONSUME(t.BRACKET_VALUE_UNQUOTED),
643
+ },
644
+ ])
645
+ return $.ACTION(() => onlyToken ? value : handle.token.value(...processToken(value, $.shift)))
646
+ })
647
+ $.RULE("parenL", () => {
648
+ const value = $.CONSUME(t.PAREN_L)
649
+
650
+ return $.ACTION(() => {
651
+ // magic, see parse
652
+ const loc = extractPosition(value, $.shift)
653
+ return $.shift === 0 || loc.start > 0
654
+ ? handle.delimiter.parenL(value.isInsertedInRecovery ? undefined : value.image, loc)
655
+ : undefined
656
+ })
657
+ })
658
+ $.RULE("parenR", () => {
659
+ const value: any = $.CONSUME(t.PAREN_R)
660
+ return $.ACTION(() => handle.delimiter.parenR(...processToken(value, $.shift)))
661
+ })
662
+ $.RULE("bracketL", () => {
663
+ const value = $.CONSUME(t.BRACKET_L)
664
+
665
+ return $.ACTION(() => {
666
+ // magic, see parse
667
+ const loc = extractPosition(value, $.shift)
668
+ return $.shift === 0 || loc.start > 0
669
+ ? handle.delimiter.bracketL(value.isInsertedInRecovery ? undefined : value.image, loc)
670
+ : undefined
671
+ })
672
+ })
673
+ $.RULE("bracketR", () => {
674
+ const value: any = $.CONSUME(t.BRACKET_R)
675
+ return $.ACTION(() => handle.delimiter.bracketR(...processToken(value, $.shift)))
676
+ })
677
+ this.performSelfAnalysis()
678
+ }
679
+ }
680
+ export interface ParserBase {
681
+ shift: number
682
+ main: () => ParserResults
683
+ anySym: () => IToken
684
+ boolOr: () => ExpressionNode
685
+ boolAnd: () => ExpressionNode
686
+ condition: () => ConditionNode | GroupNode
687
+ // the arguments to add a property to a condition node
688
+ property: () => {
689
+ prop?: VariableNode
690
+ rest: {
691
+ sepL?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP>
692
+ sepR?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP>
693
+ propertyOperator?: ConditionNode["propertyOperator"]
694
+ }
695
+ }
696
+ // not an actual group node but the arguments to create one
697
+ plainGroup: () => [ValidToken<TOKEN_TYPE.PARENL>, GroupNode["expression"], ValidToken<TOKEN_TYPE.PARENR> | undefined]
698
+ plainBracketGroup: () => ArrayNode
699
+ not: () => ValidToken<TOKEN_TYPE.NOT> // is always valid since it's optional
700
+ variable: () => VariableNode
701
+ valueDelimAny: () => AnyToken<TokenQuoteTypes>
702
+ quoteSingle: () => AnyToken<TOKEN_TYPE.SINGLEQUOTE>
703
+ quoteDouble: () => AnyToken<TOKEN_TYPE.DOUBLEQUOTE>
704
+ quoteBacktick: () => AnyToken<TOKEN_TYPE.BACKTICK>
705
+ regexAny: () => AnyToken<TOKEN_TYPE.REGEX> | [AnyToken<TOKEN_TYPE.REGEX>, ValidToken<TOKEN_TYPE.VALUE>]
706
+ valueNotSingle: () => AnyToken<TOKEN_TYPE.VALUE>
707
+ valueNotDouble: () => AnyToken<TOKEN_TYPE.VALUE>
708
+ valueNotBacktick: () => AnyToken<TOKEN_TYPE.VALUE>
709
+ valueUnquoted: () => AnyToken<TOKEN_TYPE.VALUE>
710
+ valueRegex: () => AnyToken<TOKEN_TYPE.VALUE>
711
+ parenL: () => ValidToken<TOKEN_TYPE.PARENL> // always valid, see getUnclosedRightParenCount for magic
712
+ parenR: () => ValidToken<TOKEN_TYPE.PARENR> | undefined
713
+ bracketL: () => ValidToken<TOKEN_TYPE.BRACKETL> // always valid, see getUnclosedRightParenCount for magic
714
+ bracketR: () => ValidToken<TOKEN_TYPE.BRACKETR> | undefined
715
+ }