@itwin/grouping-mapping-widget 0.3.2 → 0.3.3

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 (169) hide show
  1. package/lib/cjs/formula/FormulaFunctionProvider.d.ts +18 -0
  2. package/lib/cjs/formula/FormulaFunctionProvider.js +136 -0
  3. package/lib/cjs/formula/FormulaFunctionProvider.js.map +1 -0
  4. package/lib/cjs/formula/FormulaOperatorsProvider.d.ts +34 -0
  5. package/lib/cjs/formula/FormulaOperatorsProvider.js +185 -0
  6. package/lib/cjs/formula/FormulaOperatorsProvider.js.map +1 -0
  7. package/lib/cjs/formula/FormulaSplitter.d.ts +2 -0
  8. package/lib/cjs/formula/FormulaSplitter.js +140 -0
  9. package/lib/cjs/formula/FormulaSplitter.js.map +1 -0
  10. package/lib/cjs/formula/FormulaTokensValidator.d.ts +5 -0
  11. package/lib/cjs/formula/FormulaTokensValidator.js +135 -0
  12. package/lib/cjs/formula/FormulaTokensValidator.js.map +1 -0
  13. package/lib/cjs/formula/FormulaValidator.d.ts +3 -0
  14. package/lib/cjs/formula/FormulaValidator.js +35 -0
  15. package/lib/cjs/formula/FormulaValidator.js.map +1 -0
  16. package/lib/cjs/formula/IResult.d.ts +5 -0
  17. package/lib/cjs/formula/IResult.js +3 -0
  18. package/lib/cjs/formula/IResult.js.map +1 -0
  19. package/lib/cjs/formula/InfixToPostfixConverter.d.ts +18 -0
  20. package/lib/cjs/formula/InfixToPostfixConverter.js +299 -0
  21. package/lib/cjs/formula/InfixToPostfixConverter.js.map +1 -0
  22. package/lib/cjs/formula/InputStream.d.ts +12 -0
  23. package/lib/cjs/formula/InputStream.js +36 -0
  24. package/lib/cjs/formula/InputStream.js.map +1 -0
  25. package/lib/cjs/formula/ParenthesisValidator.d.ts +7 -0
  26. package/lib/cjs/formula/ParenthesisValidator.js +34 -0
  27. package/lib/cjs/formula/ParenthesisValidator.js.map +1 -0
  28. package/lib/cjs/formula/Queue.d.ts +11 -0
  29. package/lib/cjs/formula/Queue.js +42 -0
  30. package/lib/cjs/formula/Queue.js.map +1 -0
  31. package/lib/cjs/formula/Stack.d.ts +14 -0
  32. package/lib/cjs/formula/Stack.js +71 -0
  33. package/lib/cjs/formula/Stack.js.map +1 -0
  34. package/lib/cjs/formula/StringBuilder.d.ts +9 -0
  35. package/lib/cjs/formula/StringBuilder.js +26 -0
  36. package/lib/cjs/formula/StringBuilder.js.map +1 -0
  37. package/lib/cjs/formula/Types.d.ts +8 -0
  38. package/lib/cjs/formula/Types.js +3 -0
  39. package/lib/cjs/formula/Types.js.map +1 -0
  40. package/lib/cjs/formula/Utils.d.ts +7 -0
  41. package/lib/cjs/formula/Utils.js +39 -0
  42. package/lib/cjs/formula/Utils.js.map +1 -0
  43. package/lib/cjs/widget/components/CalculatedPropertyAction.d.ts +1 -1
  44. package/lib/cjs/widget/components/CalculatedPropertyAction.js +3 -3
  45. package/lib/cjs/widget/components/CalculatedPropertyAction.js.map +1 -1
  46. package/lib/cjs/widget/components/CalculatedPropertyTable.d.ts +5 -2
  47. package/lib/cjs/widget/components/CalculatedPropertyTable.js +3 -27
  48. package/lib/cjs/widget/components/CalculatedPropertyTable.js.map +1 -1
  49. package/lib/cjs/widget/components/ConfirmMappingsImport.scss +4 -2
  50. package/lib/cjs/widget/components/CustomCalculationAction.d.ts +4 -2
  51. package/lib/cjs/widget/components/CustomCalculationAction.js +9 -4
  52. package/lib/cjs/widget/components/CustomCalculationAction.js.map +1 -1
  53. package/lib/cjs/widget/components/CustomCalculationTable.d.ts +5 -2
  54. package/lib/cjs/widget/components/CustomCalculationTable.js +3 -27
  55. package/lib/cjs/widget/components/CustomCalculationTable.js.map +1 -1
  56. package/lib/cjs/widget/components/GroupAction.js +2 -10
  57. package/lib/cjs/widget/components/GroupAction.js.map +1 -1
  58. package/lib/cjs/widget/components/GroupPropertyAction.d.ts +1 -1
  59. package/lib/cjs/widget/components/GroupPropertyAction.js +3 -3
  60. package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
  61. package/lib/cjs/widget/components/GroupPropertyTable.d.ts +5 -2
  62. package/lib/cjs/widget/components/GroupPropertyTable.js +3 -27
  63. package/lib/cjs/widget/components/GroupPropertyTable.js.map +1 -1
  64. package/lib/cjs/widget/components/MappingAction.js +2 -10
  65. package/lib/cjs/widget/components/MappingAction.js.map +1 -1
  66. package/lib/cjs/widget/components/MappingImportWizardModal.js +2 -2
  67. package/lib/cjs/widget/components/MappingImportWizardModal.js.map +1 -1
  68. package/lib/cjs/widget/components/MappingImportWizardModal.scss +6 -2
  69. package/lib/cjs/widget/components/PropertyMenu.js +68 -21
  70. package/lib/cjs/widget/components/PropertyMenu.js.map +1 -1
  71. package/lib/cjs/widget/components/SelectIModel.scss +2 -1
  72. package/lib/cjs/widget/components/SelectMapping.scss +2 -1
  73. package/lib/cjs/widget/components/SelectProject.js +9 -9
  74. package/lib/cjs/widget/components/SelectProject.js.map +1 -1
  75. package/lib/cjs/widget/components/SelectProject.scss +3 -8
  76. package/lib/cjs/widget/hooks/useFetchData.d.ts +9 -0
  77. package/lib/cjs/widget/hooks/useFetchData.js +41 -0
  78. package/lib/cjs/widget/hooks/useFetchData.js.map +1 -0
  79. package/lib/cjs/widget/hooks/useFormulaValidation.d.ts +6 -0
  80. package/lib/cjs/widget/hooks/useFormulaValidation.js +29 -0
  81. package/lib/cjs/widget/hooks/useFormulaValidation.js.map +1 -0
  82. package/lib/cjs/widget/utils.d.ts +1 -0
  83. package/lib/cjs/widget/utils.js +9 -0
  84. package/lib/cjs/widget/utils.js.map +1 -1
  85. package/lib/esm/formula/FormulaFunctionProvider.d.ts +18 -0
  86. package/lib/esm/formula/FormulaFunctionProvider.js +130 -0
  87. package/lib/esm/formula/FormulaFunctionProvider.js.map +1 -0
  88. package/lib/esm/formula/FormulaOperatorsProvider.d.ts +34 -0
  89. package/lib/esm/formula/FormulaOperatorsProvider.js +174 -0
  90. package/lib/esm/formula/FormulaOperatorsProvider.js.map +1 -0
  91. package/lib/esm/formula/FormulaSplitter.d.ts +2 -0
  92. package/lib/esm/formula/FormulaSplitter.js +136 -0
  93. package/lib/esm/formula/FormulaSplitter.js.map +1 -0
  94. package/lib/esm/formula/FormulaTokensValidator.d.ts +5 -0
  95. package/lib/esm/formula/FormulaTokensValidator.js +131 -0
  96. package/lib/esm/formula/FormulaTokensValidator.js.map +1 -0
  97. package/lib/esm/formula/FormulaValidator.d.ts +3 -0
  98. package/lib/esm/formula/FormulaValidator.js +31 -0
  99. package/lib/esm/formula/FormulaValidator.js.map +1 -0
  100. package/lib/esm/formula/IResult.d.ts +5 -0
  101. package/lib/esm/formula/IResult.js +2 -0
  102. package/lib/esm/formula/IResult.js.map +1 -0
  103. package/lib/esm/formula/InfixToPostfixConverter.d.ts +18 -0
  104. package/lib/esm/formula/InfixToPostfixConverter.js +295 -0
  105. package/lib/esm/formula/InfixToPostfixConverter.js.map +1 -0
  106. package/lib/esm/formula/InputStream.d.ts +12 -0
  107. package/lib/esm/formula/InputStream.js +32 -0
  108. package/lib/esm/formula/InputStream.js.map +1 -0
  109. package/lib/esm/formula/ParenthesisValidator.d.ts +7 -0
  110. package/lib/esm/formula/ParenthesisValidator.js +30 -0
  111. package/lib/esm/formula/ParenthesisValidator.js.map +1 -0
  112. package/lib/esm/formula/Queue.d.ts +11 -0
  113. package/lib/esm/formula/Queue.js +38 -0
  114. package/lib/esm/formula/Queue.js.map +1 -0
  115. package/lib/esm/formula/Stack.d.ts +14 -0
  116. package/lib/esm/formula/Stack.js +67 -0
  117. package/lib/esm/formula/Stack.js.map +1 -0
  118. package/lib/esm/formula/StringBuilder.d.ts +9 -0
  119. package/lib/esm/formula/StringBuilder.js +22 -0
  120. package/lib/esm/formula/StringBuilder.js.map +1 -0
  121. package/lib/esm/formula/Types.d.ts +8 -0
  122. package/lib/esm/formula/Types.js +2 -0
  123. package/lib/esm/formula/Types.js.map +1 -0
  124. package/lib/esm/formula/Utils.d.ts +7 -0
  125. package/lib/esm/formula/Utils.js +30 -0
  126. package/lib/esm/formula/Utils.js.map +1 -0
  127. package/lib/esm/widget/components/CalculatedPropertyAction.d.ts +1 -1
  128. package/lib/esm/widget/components/CalculatedPropertyAction.js +3 -3
  129. package/lib/esm/widget/components/CalculatedPropertyAction.js.map +1 -1
  130. package/lib/esm/widget/components/CalculatedPropertyTable.d.ts +5 -2
  131. package/lib/esm/widget/components/CalculatedPropertyTable.js +4 -28
  132. package/lib/esm/widget/components/CalculatedPropertyTable.js.map +1 -1
  133. package/lib/esm/widget/components/ConfirmMappingsImport.scss +4 -2
  134. package/lib/esm/widget/components/CustomCalculationAction.d.ts +4 -2
  135. package/lib/esm/widget/components/CustomCalculationAction.js +9 -4
  136. package/lib/esm/widget/components/CustomCalculationAction.js.map +1 -1
  137. package/lib/esm/widget/components/CustomCalculationTable.d.ts +5 -2
  138. package/lib/esm/widget/components/CustomCalculationTable.js +4 -28
  139. package/lib/esm/widget/components/CustomCalculationTable.js.map +1 -1
  140. package/lib/esm/widget/components/GroupAction.js +2 -10
  141. package/lib/esm/widget/components/GroupAction.js.map +1 -1
  142. package/lib/esm/widget/components/GroupPropertyAction.d.ts +1 -1
  143. package/lib/esm/widget/components/GroupPropertyAction.js +3 -3
  144. package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
  145. package/lib/esm/widget/components/GroupPropertyTable.d.ts +5 -2
  146. package/lib/esm/widget/components/GroupPropertyTable.js +4 -28
  147. package/lib/esm/widget/components/GroupPropertyTable.js.map +1 -1
  148. package/lib/esm/widget/components/MappingAction.js +2 -10
  149. package/lib/esm/widget/components/MappingAction.js.map +1 -1
  150. package/lib/esm/widget/components/MappingImportWizardModal.js +2 -2
  151. package/lib/esm/widget/components/MappingImportWizardModal.js.map +1 -1
  152. package/lib/esm/widget/components/MappingImportWizardModal.scss +6 -2
  153. package/lib/esm/widget/components/PropertyMenu.js +69 -22
  154. package/lib/esm/widget/components/PropertyMenu.js.map +1 -1
  155. package/lib/esm/widget/components/SelectIModel.scss +2 -1
  156. package/lib/esm/widget/components/SelectMapping.scss +2 -1
  157. package/lib/esm/widget/components/SelectProject.js +9 -9
  158. package/lib/esm/widget/components/SelectProject.js.map +1 -1
  159. package/lib/esm/widget/components/SelectProject.scss +3 -8
  160. package/lib/esm/widget/hooks/useFetchData.d.ts +9 -0
  161. package/lib/esm/widget/hooks/useFetchData.js +35 -0
  162. package/lib/esm/widget/hooks/useFetchData.js.map +1 -0
  163. package/lib/esm/widget/hooks/useFormulaValidation.d.ts +6 -0
  164. package/lib/esm/widget/hooks/useFormulaValidation.js +25 -0
  165. package/lib/esm/widget/hooks/useFormulaValidation.js.map +1 -0
  166. package/lib/esm/widget/utils.d.ts +1 -0
  167. package/lib/esm/widget/utils.js +7 -1
  168. package/lib/esm/widget/utils.js.map +1 -1
  169. package/package.json +2 -2
@@ -0,0 +1,131 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { getFormulaFunctionReturnType, getFunction } from "./FormulaFunctionProvider";
6
+ import { getOperatorArgumentCountBounds, getOperatorReturnType, isOperator } from "./FormulaOperatorsProvider";
7
+ import { TokenType } from "./InfixToPostfixConverter";
8
+ import { Stack } from "./Stack";
9
+ function isNumericalConstant(name) {
10
+ return [
11
+ "e",
12
+ "ln2",
13
+ "ln10",
14
+ "log2e",
15
+ "log10e",
16
+ "pi",
17
+ "sqrt1_2",
18
+ "sqrt2",
19
+ ].includes(name.toLowerCase());
20
+ }
21
+ export function validateTokens(tokens, properties) {
22
+ if (tokens.length === 0)
23
+ return "Formula cannot be empty.";
24
+ const argStack = new Stack();
25
+ while (tokens.length > 0) {
26
+ const token = tokens.dequeue();
27
+ switch (token.type) {
28
+ case TokenType.Number:
29
+ argStack.push("number");
30
+ break;
31
+ case TokenType.String:
32
+ argStack.push("string");
33
+ break;
34
+ case TokenType.Boolean:
35
+ argStack.push("boolean");
36
+ break;
37
+ case TokenType.Null:
38
+ argStack.push("undefined");
39
+ break;
40
+ case TokenType.Variable:
41
+ const isConstant = isNumericalConstant(token.value);
42
+ if (isConstant) {
43
+ argStack.push("number");
44
+ }
45
+ else {
46
+ const prop = properties[token.value];
47
+ if (!prop)
48
+ return `Variable "${token.value}" is not available.`;
49
+ argStack.push(prop);
50
+ }
51
+ break;
52
+ case TokenType.Operator:
53
+ if (!isOperator(token.value))
54
+ return `Operator "${token.value}" is not supported.`;
55
+ const operatorBounds = getOperatorArgumentCountBounds(token.value);
56
+ if (!operatorBounds)
57
+ return `Operator "${token.value}" is not supported.`;
58
+ if (operatorBounds[0] === 2 && token.argCount === 1)
59
+ return `Unary operator "${token.value}" is not supported.`;
60
+ if (argStack.length < token.argCount) {
61
+ return `Too few arguments given for ${token.argCount === 1 ? "unary" : "binary"} operator "${token.value}".`;
62
+ }
63
+ const opArgs = argStack.popN(token.argCount).reverse();
64
+ let operationResult;
65
+ if (opArgs.length === 1)
66
+ operationResult = getOperatorReturnType(token.value, opArgs[0]);
67
+ else if (opArgs.length === 2)
68
+ operationResult = getOperatorReturnType(token.value, opArgs[0], opArgs[1]);
69
+ else
70
+ return `Operator "${token.value}" does not support ${token.argCount} operands.`;
71
+ if (operationResult.errorMessage)
72
+ return operationResult.errorMessage;
73
+ else
74
+ argStack.push(operationResult.value);
75
+ break;
76
+ case TokenType.Function:
77
+ const fnArg = getFunction(token.value);
78
+ if (!fnArg)
79
+ return `Function "${token.value}" is not supported.`;
80
+ const fnArgBounds = fnArg.argumentCountBounds;
81
+ if (fnArgBounds[0] === 0 && fnArgBounds[1] === 0 && token.argCount > 0) {
82
+ return `Function "${token.value}" does not accept any arguments.`;
83
+ }
84
+ else if (fnArgBounds[1] === -1 && token.argCount < fnArgBounds[0]) {
85
+ if (fnArgBounds[0] === 1) {
86
+ return `Function "${token.value}" requires at least 1 argument.`;
87
+ }
88
+ else {
89
+ if (token.argCount === 1) {
90
+ return `Function "${token.value}" requires at least ${fnArgBounds[0]} arguments, but only 1 argument was given.`;
91
+ }
92
+ else {
93
+ return `Function "${token.value}" requires at least ${fnArgBounds[0]} arguments, but only ${token.argCount} arguments were given.`;
94
+ }
95
+ }
96
+ }
97
+ else if (fnArgBounds[0] === fnArgBounds[1] && token.argCount !== fnArgBounds[0]) {
98
+ if (fnArgBounds[0] === 1) {
99
+ return `Function "${token.value}" requires exactly 1 argument, but ${token.argCount} arguments were given.`;
100
+ }
101
+ else {
102
+ if (token.argCount === 1) {
103
+ return `Function "${token.value}" requires exactly ${fnArgBounds[0]} arguments, but 1 argument was given.`;
104
+ }
105
+ else {
106
+ return `Function "${token.value}" requires exactly ${fnArgBounds[0]} arguments, but ${token.argCount} arguments were given.`;
107
+ }
108
+ }
109
+ }
110
+ const fArgs = argStack.popN(token.argCount).reverse();
111
+ if (fArgs.length < token.argCount) {
112
+ return `Too few arguments given for function "${token.value}".`;
113
+ }
114
+ const functionResult = getFormulaFunctionReturnType(fnArg, fArgs);
115
+ if (functionResult.errorMessage)
116
+ return `Function "${token.value}" is invalid. ${functionResult.errorMessage}`;
117
+ else
118
+ argStack.push(functionResult.value);
119
+ break;
120
+ }
121
+ }
122
+ if (argStack.length !== 1) {
123
+ return "Formula is invalid.";
124
+ }
125
+ const resultType = argStack.pop();
126
+ if (!resultType || resultType === "undefined") {
127
+ return "Formula cannot always return null.";
128
+ }
129
+ return "";
130
+ }
131
+ //# sourceMappingURL=FormulaTokensValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormulaTokensValidator.js","sourceRoot":"","sources":["../../../src/formula/FormulaTokensValidator.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { getFormulaFunctionReturnType, getFunction } from \"./FormulaFunctionProvider\";\nimport { getOperatorArgumentCountBounds, getOperatorReturnType, isOperator } from \"./FormulaOperatorsProvider\";\nimport type { Token } from \"./InfixToPostfixConverter\";\nimport { TokenType } from \"./InfixToPostfixConverter\";\nimport type { Queue } from \"./Queue\";\nimport { Stack } from \"./Stack\";\nimport type { PossibleDataType, PropertyMap } from \"./Types\";\n\nfunction isNumericalConstant(name: string): boolean {\n return [\n \"e\",\n \"ln2\",\n \"ln10\",\n \"log2e\",\n \"log10e\",\n \"pi\",\n \"sqrt1_2\",\n \"sqrt2\",\n ].includes(name.toLowerCase());\n}\n\nexport function validateTokens(tokens: Queue<Token>, properties: PropertyMap): string {\n if (tokens.length === 0)\n return \"Formula cannot be empty.\";\n\n const argStack = new Stack<PossibleDataType>();\n\n while (tokens.length > 0) {\n const token = tokens.dequeue()!;\n\n switch (token.type) {\n case TokenType.Number:\n argStack.push(\"number\");\n break;\n case TokenType.String:\n argStack.push(\"string\");\n break;\n case TokenType.Boolean:\n argStack.push(\"boolean\");\n break;\n case TokenType.Null:\n argStack.push(\"undefined\");\n break;\n case TokenType.Variable:\n const isConstant = isNumericalConstant(token.value);\n if (isConstant) {\n argStack.push(\"number\");\n } else {\n const prop = properties[token.value];\n if (!prop)\n return `Variable \"${token.value}\" is not available.`;\n argStack.push(prop);\n }\n break;\n case TokenType.Operator:\n if (!isOperator(token.value))\n return `Operator \"${token.value}\" is not supported.`;\n\n const operatorBounds = getOperatorArgumentCountBounds(token.value);\n if (!operatorBounds)\n return `Operator \"${token.value}\" is not supported.`;\n\n if (operatorBounds[0] === 2 && token.argCount === 1)\n return `Unary operator \"${token.value}\" is not supported.`;\n\n if (argStack.length < token.argCount) {\n return `Too few arguments given for ${token.argCount === 1 ? \"unary\" : \"binary\"} operator \"${token.value}\".`;\n }\n const opArgs = argStack.popN(token.argCount).reverse();\n let operationResult;\n if (opArgs.length === 1)\n operationResult = getOperatorReturnType(token.value, opArgs[0]);\n else if (opArgs.length === 2)\n operationResult = getOperatorReturnType(token.value, opArgs[0], opArgs[1]);\n else\n return `Operator \"${token.value}\" does not support ${token.argCount} operands.`;\n\n if (operationResult.errorMessage)\n return operationResult.errorMessage;\n else\n argStack.push(operationResult.value!);\n\n break;\n case TokenType.Function:\n const fnArg = getFunction(token.value);\n if (!fnArg)\n return `Function \"${token.value}\" is not supported.`;\n\n const fnArgBounds = fnArg.argumentCountBounds;\n if (fnArgBounds[0] === 0 && fnArgBounds[1] === 0 && token.argCount > 0) {\n return `Function \"${token.value}\" does not accept any arguments.`;\n } else if (fnArgBounds[1] === -1 && token.argCount < fnArgBounds[0]) {\n if (fnArgBounds[0] === 1) {\n return `Function \"${token.value}\" requires at least 1 argument.`;\n } else {\n if (token.argCount === 1) {\n return `Function \"${token.value}\" requires at least ${fnArgBounds[0]} arguments, but only 1 argument was given.`;\n } else {\n return `Function \"${token.value}\" requires at least ${fnArgBounds[0]} arguments, but only ${token.argCount} arguments were given.`;\n }\n }\n } else if (fnArgBounds[0] === fnArgBounds[1] && token.argCount !== fnArgBounds[0]) {\n if (fnArgBounds[0] === 1) {\n return `Function \"${token.value}\" requires exactly 1 argument, but ${token.argCount} arguments were given.`;\n } else {\n if (token.argCount === 1) {\n return `Function \"${token.value}\" requires exactly ${fnArgBounds[0]} arguments, but 1 argument was given.`;\n } else {\n return `Function \"${token.value}\" requires exactly ${fnArgBounds[0]} arguments, but ${token.argCount} arguments were given.`;\n }\n }\n }\n\n const fArgs = argStack.popN(token.argCount).reverse();\n if (fArgs.length < token.argCount) {\n return `Too few arguments given for function \"${token.value}\".`;\n }\n\n const functionResult = getFormulaFunctionReturnType(fnArg, fArgs);\n if (functionResult.errorMessage)\n return `Function \"${token.value}\" is invalid. ${functionResult.errorMessage}`;\n else\n argStack.push(functionResult.value!);\n\n break;\n }\n }\n\n if (argStack.length !== 1) {\n return \"Formula is invalid.\";\n }\n\n const resultType = argStack.pop();\n if (!resultType || resultType === \"undefined\") {\n return \"Formula cannot always return null.\";\n }\n\n return \"\";\n}\n\n"]}
@@ -0,0 +1,3 @@
1
+ import type { PropertyMap } from "./Types";
2
+ export declare function validateFormula(formula: string, properties: PropertyMap): string;
3
+ //# sourceMappingURL=FormulaValidator.d.ts.map
@@ -0,0 +1,31 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { splitFormula } from "./FormulaSplitter";
6
+ import { validateTokens } from "./FormulaTokensValidator";
7
+ import { convertInfixToPostfix } from "./InfixToPostfixConverter";
8
+ import { ParenthesisState, validateParenthesis } from "./ParenthesisValidator";
9
+ export function validateFormula(formula, properties) {
10
+ var _a;
11
+ const parenthesisState = validateParenthesis(formula);
12
+ if (ParenthesisState.NotClosed === parenthesisState) {
13
+ return "Opened but not closed parenthesis found.";
14
+ }
15
+ else if (ParenthesisState.NotOpened === parenthesisState) {
16
+ return "Closed but not opened parenthesis found.";
17
+ }
18
+ let infixFormulaTokens;
19
+ try {
20
+ infixFormulaTokens = splitFormula(formula);
21
+ }
22
+ catch (ex) {
23
+ return ex.message;
24
+ }
25
+ const postfixFormulaTokens = convertInfixToPostfix(infixFormulaTokens);
26
+ if (undefined === postfixFormulaTokens.value) {
27
+ return (_a = postfixFormulaTokens.errorMessage) !== null && _a !== void 0 ? _a : "Unknown error";
28
+ }
29
+ return validateTokens(postfixFormulaTokens.value, properties);
30
+ }
31
+ //# sourceMappingURL=FormulaValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormulaValidator.js","sourceRoot":"","sources":["../../../src/formula/FormulaValidator.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG/E,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,UAAuB;;IACtE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,gBAAgB,CAAC,SAAS,KAAK,gBAAgB,EAAE;QACnD,OAAO,0CAA0C,CAAC;KACnD;SAAM,IAAI,gBAAgB,CAAC,SAAS,KAAK,gBAAgB,EAAE;QAC1D,OAAO,0CAA0C,CAAC;KACnD;IAED,IAAI,kBAAkB,CAAC;IACvB,IAAI;QACF,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;KAC5C;IAAC,OAAO,EAAE,EAAE;QACX,OAAQ,EAAY,CAAC,OAAO,CAAC;KAC9B;IAED,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IAEvE,IAAI,SAAS,KAAK,oBAAoB,CAAC,KAAK,EAAE;QAC5C,OAAO,MAAA,oBAAoB,CAAC,YAAY,mCAAI,eAAe,CAAC;KAC7D;IAED,OAAO,cAAc,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAChE,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { splitFormula } from \"./FormulaSplitter\";\nimport { validateTokens } from \"./FormulaTokensValidator\";\nimport { convertInfixToPostfix } from \"./InfixToPostfixConverter\";\nimport { ParenthesisState, validateParenthesis } from \"./ParenthesisValidator\";\nimport type { PropertyMap } from \"./Types\";\n\nexport function validateFormula(formula: string, properties: PropertyMap): string {\n const parenthesisState = validateParenthesis(formula);\n if (ParenthesisState.NotClosed === parenthesisState) {\n return \"Opened but not closed parenthesis found.\";\n } else if (ParenthesisState.NotOpened === parenthesisState) {\n return \"Closed but not opened parenthesis found.\";\n }\n\n let infixFormulaTokens;\n try {\n infixFormulaTokens = splitFormula(formula);\n } catch (ex) {\n return (ex as Error).message;\n }\n\n const postfixFormulaTokens = convertInfixToPostfix(infixFormulaTokens);\n\n if (undefined === postfixFormulaTokens.value) {\n return postfixFormulaTokens.errorMessage ?? \"Unknown error\";\n }\n\n return validateTokens(postfixFormulaTokens.value, properties);\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export interface IResult<T> {
2
+ value?: T;
3
+ errorMessage?: string;
4
+ }
5
+ //# sourceMappingURL=IResult.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IResult.js","sourceRoot":"","sources":["../../../src/formula/IResult.ts"],"names":[],"mappings":"","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nexport interface IResult<T> {\n value?: T;\n errorMessage?: string;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { IResult } from "./IResult";
2
+ import { Queue } from "./Queue";
3
+ export declare enum TokenType {
4
+ Number = 0,
5
+ Function = 1,
6
+ Operator = 2,
7
+ Variable = 3,
8
+ String = 4,
9
+ Boolean = 5,
10
+ Null = 6
11
+ }
12
+ export interface Token {
13
+ value: string;
14
+ type: TokenType;
15
+ argCount: number;
16
+ }
17
+ export declare function convertInfixToPostfix(infix: string[]): IResult<Queue<Token>>;
18
+ //# sourceMappingURL=InfixToPostfixConverter.d.ts.map
@@ -0,0 +1,295 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { isFunction } from "./FormulaFunctionProvider";
6
+ import { getBinaryOperator, getOperatorAssociativity, getOperatorPrecedence, getUnaryOperator, isOperator, isSupportedOperator, OperatorAssociativity } from "./FormulaOperatorsProvider";
7
+ import { Queue } from "./Queue";
8
+ import { Stack } from "./Stack";
9
+ import { isStringDelimiter } from "./Utils";
10
+ function isNumber(part) {
11
+ return !isNaN(Number(part)) || !isNaN(parseFloat(part));
12
+ }
13
+ function isStringLiteral(token) {
14
+ if (token.length < 2) {
15
+ return false;
16
+ }
17
+ const firstCharacter = token[0];
18
+ const lastCharacter = token[token.length - 1];
19
+ return firstCharacter === lastCharacter && isStringDelimiter(firstCharacter);
20
+ }
21
+ function isBoolean(token) {
22
+ const lower = token.toLowerCase();
23
+ return lower === "true" || lower === "false";
24
+ }
25
+ function isNull(token) {
26
+ return token.toLowerCase() === "null";
27
+ }
28
+ export var TokenType;
29
+ (function (TokenType) {
30
+ TokenType[TokenType["Number"] = 0] = "Number";
31
+ TokenType[TokenType["Function"] = 1] = "Function";
32
+ TokenType[TokenType["Operator"] = 2] = "Operator";
33
+ TokenType[TokenType["Variable"] = 3] = "Variable";
34
+ TokenType[TokenType["String"] = 4] = "String";
35
+ TokenType[TokenType["Boolean"] = 5] = "Boolean";
36
+ TokenType[TokenType["Null"] = 6] = "Null";
37
+ })(TokenType || (TokenType = {}));
38
+ var InternalTokenType;
39
+ (function (InternalTokenType) {
40
+ InternalTokenType[InternalTokenType["Number"] = 0] = "Number";
41
+ InternalTokenType[InternalTokenType["Function"] = 1] = "Function";
42
+ InternalTokenType[InternalTokenType["Operator"] = 2] = "Operator";
43
+ InternalTokenType[InternalTokenType["Variable"] = 3] = "Variable";
44
+ InternalTokenType[InternalTokenType["OpeningParenthesis"] = 4] = "OpeningParenthesis";
45
+ InternalTokenType[InternalTokenType["ClosingParenthesis"] = 5] = "ClosingParenthesis";
46
+ InternalTokenType[InternalTokenType["ArgumentSeparator"] = 6] = "ArgumentSeparator";
47
+ InternalTokenType[InternalTokenType["String"] = 7] = "String";
48
+ InternalTokenType[InternalTokenType["Boolean"] = 8] = "Boolean";
49
+ InternalTokenType[InternalTokenType["Null"] = 9] = "Null";
50
+ })(InternalTokenType || (InternalTokenType = {}));
51
+ function getExternalQueue(internal) {
52
+ const external = new Queue();
53
+ while (internal.length > 0) {
54
+ const t = internal.dequeue();
55
+ switch (t.type) {
56
+ case InternalTokenType.Number:
57
+ external.enqueue({ value: t.value, type: TokenType.Number, argCount: t.argCount });
58
+ break;
59
+ case InternalTokenType.Function:
60
+ external.enqueue({ value: t.value, type: TokenType.Function, argCount: t.argCount });
61
+ break;
62
+ case InternalTokenType.Operator:
63
+ external.enqueue({ value: t.value, type: TokenType.Operator, argCount: t.argCount });
64
+ break;
65
+ case InternalTokenType.Variable:
66
+ external.enqueue({ value: t.value, type: TokenType.Variable, argCount: t.argCount });
67
+ break;
68
+ case InternalTokenType.String:
69
+ external.enqueue({ value: t.value, type: TokenType.String, argCount: t.argCount });
70
+ break;
71
+ case InternalTokenType.Boolean:
72
+ external.enqueue({ value: t.value, type: TokenType.Boolean, argCount: t.argCount });
73
+ break;
74
+ case InternalTokenType.Null:
75
+ external.enqueue({ value: t.value, type: TokenType.Null, argCount: t.argCount });
76
+ break;
77
+ default:
78
+ return { errorMessage: `Missing closing parenthesis ")".` };
79
+ }
80
+ }
81
+ return { value: external };
82
+ }
83
+ function incrementArgCount(token) {
84
+ if (!token.argCountIncremented) {
85
+ token.argCount++;
86
+ token.argCountIncremented = true;
87
+ }
88
+ }
89
+ function addOperand(ctx, type) {
90
+ ctx.resultQueue.enqueue({ value: ctx.currentToken, type, argCount: 0, argCountIncremented: false });
91
+ const currentOperators = ctx.operatorStack.peekN(2);
92
+ const op1 = currentOperators[0];
93
+ if (undefined !== op1) {
94
+ incrementArgCount(op1);
95
+ if (op1.argCount === 1) {
96
+ const op2 = currentOperators[1];
97
+ if (undefined !== op2 && op2.argCount !== 0) {
98
+ incrementArgCount(op2);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ const addNumber = (ctx) => {
104
+ addOperand(ctx, InternalTokenType.Number);
105
+ return { value: true };
106
+ };
107
+ const addVariable = (ctx) => {
108
+ ctx = { ...ctx, currentToken: ctx.currentToken.toLowerCase() };
109
+ if (undefined !== ctx.previousToken && isNumber(ctx.previousToken)) {
110
+ addOperator({ ...ctx, currentToken: "*" });
111
+ addOperand({ ...ctx, previousToken: "*" }, InternalTokenType.Variable);
112
+ }
113
+ else {
114
+ addOperand(ctx, InternalTokenType.Variable);
115
+ }
116
+ return { value: true };
117
+ };
118
+ const addFunction = (ctx) => {
119
+ const currentOperator = ctx.operatorStack.peek();
120
+ if (undefined !== currentOperator) {
121
+ incrementArgCount(currentOperator);
122
+ }
123
+ ctx.operatorStack.push({ value: ctx.currentToken, type: InternalTokenType.Function, argCount: 0, argCountIncremented: false });
124
+ return { value: true };
125
+ };
126
+ const addOperator = (ctx) => {
127
+ if (!isSupportedOperator(ctx.currentToken)) {
128
+ return { errorMessage: `Operator "${ctx.currentToken}" is not supported.` };
129
+ }
130
+ const binary = undefined !== ctx.previousToken && "(" !== ctx.previousToken && "," !== ctx.previousToken && !isOperator(ctx.previousToken);
131
+ const unary = !binary;
132
+ const op = unary ? getUnaryOperator(ctx.currentToken) : getBinaryOperator(ctx.currentToken);
133
+ if (unary && undefined === op) {
134
+ return { errorMessage: `Unary "${ctx.currentToken}" is not supported.` };
135
+ }
136
+ const o1 = ctx.currentToken;
137
+ const o1Associativity = getOperatorAssociativity(op);
138
+ const o1Precedence = getOperatorPrecedence(op);
139
+ while (ctx.operatorStack.length > 0) {
140
+ const o2 = ctx.operatorStack.peek();
141
+ if (o2.value === "(") {
142
+ break;
143
+ }
144
+ const o2Unary = o2.argCount === 0;
145
+ const op2 = o2Unary ? getUnaryOperator(o2.value) : getBinaryOperator(o2.value);
146
+ const o2Precedence = getOperatorPrecedence(op2);
147
+ if (!(o2Precedence > o1Precedence || (o2Precedence === o1Precedence && o1Associativity === OperatorAssociativity.Left))) {
148
+ break;
149
+ }
150
+ ctx.resultQueue.enqueue(ctx.operatorStack.pop());
151
+ const currentOperator = ctx.operatorStack.peek();
152
+ if (undefined !== currentOperator) {
153
+ incrementArgCount(currentOperator);
154
+ }
155
+ }
156
+ ctx.operatorStack.push({
157
+ value: o1,
158
+ type: InternalTokenType.Operator,
159
+ argCount: binary ? 1 : 0,
160
+ argCountIncremented: false,
161
+ });
162
+ return { value: true };
163
+ };
164
+ const openParenthesis = (ctx) => {
165
+ if (undefined !== ctx.previousToken) {
166
+ if (InternalTokenType.Number === ctx.previousTokenType || InternalTokenType.ClosingParenthesis === ctx.previousTokenType) {
167
+ addOperator({ ...ctx, currentToken: "*" });
168
+ }
169
+ else if (InternalTokenType.Variable === ctx.previousTokenType) {
170
+ return { errorMessage: `Function "${ctx.previousToken}" is not supported.` };
171
+ }
172
+ }
173
+ const currentOperator = ctx.operatorStack.peek();
174
+ if (undefined !== currentOperator && currentOperator.type !== InternalTokenType.Function) {
175
+ incrementArgCount(currentOperator);
176
+ }
177
+ ctx.operatorStack.push({ value: "(", type: InternalTokenType.OpeningParenthesis, argCount: 0, argCountIncremented: false });
178
+ return { value: true };
179
+ };
180
+ const closeParenthesis = (ctx) => {
181
+ while (ctx.operatorStack.length > 0 && ctx.operatorStack.peek().value !== "(") {
182
+ ctx.resultQueue.enqueue(ctx.operatorStack.pop());
183
+ }
184
+ const leftParenthesis = ctx.operatorStack.pop();
185
+ if (undefined === leftParenthesis) {
186
+ return { errorMessage: `Closing parenthesis ")" found, but the opening parenthesis "(" is missing.` };
187
+ }
188
+ const potentialFnToken = ctx.operatorStack.peek();
189
+ if (undefined !== potentialFnToken && isFunction(potentialFnToken.value)) {
190
+ potentialFnToken.argCount = leftParenthesis.argCount;
191
+ ctx.resultQueue.enqueue(ctx.operatorStack.pop());
192
+ }
193
+ return { value: true };
194
+ };
195
+ const addString = (ctx) => {
196
+ const withoutDelimiters = ctx.currentToken.substring(1, ctx.currentToken.length - 1);
197
+ addOperand({ ...ctx, currentToken: withoutDelimiters }, InternalTokenType.String);
198
+ return { value: true };
199
+ };
200
+ const addBoolean = (ctx) => {
201
+ addOperand({ ...ctx, currentToken: ctx.currentToken.toLowerCase() }, InternalTokenType.Boolean);
202
+ return { value: true };
203
+ };
204
+ const addNull = (ctx) => {
205
+ addOperand({ ...ctx, currentToken: ctx.currentToken.toLowerCase() }, InternalTokenType.Null);
206
+ return { value: true };
207
+ };
208
+ const separateFunctionArgumentSeparator = (ctx) => {
209
+ while (ctx.operatorStack.length > 0 && ctx.operatorStack.peek().value !== "(") {
210
+ ctx.resultQueue.enqueue(ctx.operatorStack.pop());
211
+ const currentOperator = ctx.operatorStack.peek();
212
+ if (undefined !== currentOperator) {
213
+ incrementArgCount(currentOperator);
214
+ }
215
+ }
216
+ const last2Operators = ctx.operatorStack.peekN(2);
217
+ if (last2Operators.length < 2 || last2Operators[0].type !== InternalTokenType.OpeningParenthesis || last2Operators[1].type !== InternalTokenType.Function) {
218
+ return { errorMessage: `Function argument separator "," found outside of a function call.` };
219
+ }
220
+ last2Operators[0].argCountIncremented = false;
221
+ return { value: true };
222
+ };
223
+ function getTokenType(token, nextToken) {
224
+ if (isNumber(token)) {
225
+ return InternalTokenType.Number;
226
+ }
227
+ else if (isStringLiteral(token)) {
228
+ return InternalTokenType.String;
229
+ }
230
+ else if (isBoolean(token)) {
231
+ return InternalTokenType.Boolean;
232
+ }
233
+ else if (isNull(token)) {
234
+ return InternalTokenType.Null;
235
+ }
236
+ else if (isFunction(token) && "(" === nextToken) {
237
+ return InternalTokenType.Function;
238
+ }
239
+ else if (isOperator(token)) {
240
+ return InternalTokenType.Operator;
241
+ }
242
+ else if ("(" === token) {
243
+ return InternalTokenType.OpeningParenthesis;
244
+ }
245
+ else if (")" === token) {
246
+ return InternalTokenType.ClosingParenthesis;
247
+ }
248
+ else if ("," === token) {
249
+ return InternalTokenType.ArgumentSeparator;
250
+ }
251
+ else {
252
+ return InternalTokenType.Variable;
253
+ }
254
+ }
255
+ const tokenInterpreters = new Map([
256
+ [InternalTokenType.Number, addNumber],
257
+ [InternalTokenType.ArgumentSeparator, separateFunctionArgumentSeparator],
258
+ [InternalTokenType.ClosingParenthesis, closeParenthesis],
259
+ [InternalTokenType.Function, addFunction],
260
+ [InternalTokenType.OpeningParenthesis, openParenthesis],
261
+ [InternalTokenType.Operator, addOperator],
262
+ [InternalTokenType.Variable, addVariable],
263
+ [InternalTokenType.String, addString],
264
+ [InternalTokenType.Boolean, addBoolean],
265
+ [InternalTokenType.Null, addNull],
266
+ ]);
267
+ export function convertInfixToPostfix(infix) {
268
+ const resultQueue = new Queue();
269
+ const operatorStack = new Stack();
270
+ for (let index = 0; index < infix.length; index++) {
271
+ const token = infix[index];
272
+ const ctx = {
273
+ resultQueue,
274
+ operatorStack,
275
+ currentToken: token,
276
+ currentTokenType: getTokenType(token, index < infix.length - 1 ? infix[index + 1] : undefined),
277
+ previousToken: index > 0 ? infix[index - 1] : undefined,
278
+ previousTokenType: index > 0 ? getTokenType(infix[index - 1], token) : undefined,
279
+ };
280
+ const fn = tokenInterpreters.get(ctx.currentTokenType);
281
+ const tmpResult = fn(ctx);
282
+ if (undefined === tmpResult.value) {
283
+ return { errorMessage: tmpResult.errorMessage };
284
+ }
285
+ }
286
+ while (operatorStack.length > 0) {
287
+ resultQueue.enqueue(operatorStack.pop());
288
+ const currentOperator = operatorStack.peek();
289
+ if (undefined !== currentOperator) {
290
+ incrementArgCount(currentOperator);
291
+ }
292
+ }
293
+ return getExternalQueue(resultQueue);
294
+ }
295
+ //# sourceMappingURL=InfixToPostfixConverter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InfixToPostfixConverter.js","sourceRoot":"","sources":["../../../src/formula/InfixToPostfixConverter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { isFunction } from \"./FormulaFunctionProvider\";\nimport { getBinaryOperator, getOperatorAssociativity, getOperatorPrecedence, getUnaryOperator, isOperator, isSupportedOperator, OperatorAssociativity } from \"./FormulaOperatorsProvider\";\nimport type { IResult } from \"./IResult\";\nimport { Queue } from \"./Queue\";\nimport { Stack } from \"./Stack\";\nimport { isStringDelimiter } from \"./Utils\";\n\nfunction isNumber(part: string): boolean {\n return !isNaN(Number(part)) || !isNaN(parseFloat(part));\n}\n\nfunction isStringLiteral(token: string): boolean {\n if (token.length < 2) {\n return false;\n }\n\n const firstCharacter = token[0];\n const lastCharacter = token[token.length - 1];\n return firstCharacter === lastCharacter && isStringDelimiter(firstCharacter);\n}\n\nfunction isBoolean(token: string): boolean {\n const lower = token.toLowerCase();\n return lower === \"true\" || lower === \"false\";\n}\n\nfunction isNull(token: string): boolean {\n return token.toLowerCase() === \"null\";\n}\n\nexport enum TokenType {\n Number = 0,\n Function = 1,\n Operator = 2,\n Variable = 3,\n String = 4,\n Boolean = 5,\n Null = 6,\n}\n\nenum InternalTokenType {\n Number = 0,\n Function = 1,\n Operator = 2,\n Variable = 3,\n OpeningParenthesis = 4,\n ClosingParenthesis = 5,\n ArgumentSeparator = 6,\n String = 7,\n Boolean = 8,\n Null = 9,\n}\n\nexport interface Token {\n value: string;\n type: TokenType;\n argCount: number;\n}\n\ninterface InternalToken {\n value: string;\n type: InternalTokenType;\n argCount: number;\n argCountIncremented: boolean;\n}\n\nfunction getExternalQueue(internal: Queue<InternalToken>): IResult<Queue<Token>> {\n const external = new Queue<Token>();\n while (internal.length > 0) {\n const t = internal.dequeue()!;\n\n switch (t.type) {\n case InternalTokenType.Number:\n external.enqueue({ value: t.value, type: TokenType.Number, argCount: t.argCount });\n break;\n case InternalTokenType.Function:\n external.enqueue({ value: t.value, type: TokenType.Function, argCount: t.argCount });\n break;\n case InternalTokenType.Operator:\n external.enqueue({ value: t.value, type: TokenType.Operator, argCount: t.argCount });\n break;\n case InternalTokenType.Variable:\n external.enqueue({ value: t.value, type: TokenType.Variable, argCount: t.argCount });\n break;\n case InternalTokenType.String:\n external.enqueue({ value: t.value, type: TokenType.String, argCount: t.argCount });\n break;\n case InternalTokenType.Boolean:\n external.enqueue({ value: t.value, type: TokenType.Boolean, argCount: t.argCount });\n break;\n case InternalTokenType.Null:\n external.enqueue({ value: t.value, type: TokenType.Null, argCount: t.argCount });\n break;\n default:\n return { errorMessage: `Missing closing parenthesis \")\".` };\n }\n }\n\n return { value: external };\n}\n\ninterface IConverterContext {\n resultQueue: Queue<InternalToken>;\n operatorStack: Stack<InternalToken>;\n currentToken: string;\n currentTokenType: InternalTokenType;\n previousToken?: string;\n previousTokenType?: InternalTokenType;\n}\n\ntype TokenInterpreter = (ctx: IConverterContext) => IResult<boolean>;\n\nfunction incrementArgCount(token: InternalToken) {\n if (!token.argCountIncremented) {\n token.argCount++;\n token.argCountIncremented = true;\n }\n}\n\nfunction addOperand(ctx: IConverterContext, type: InternalTokenType) {\n ctx.resultQueue.enqueue({ value: ctx.currentToken, type, argCount: 0, argCountIncremented: false });\n\n const currentOperators = ctx.operatorStack.peekN(2);\n const op1 = currentOperators[0];\n if (undefined !== op1) {\n incrementArgCount(op1);\n if (op1.argCount === 1) {\n const op2 = currentOperators[1];\n if (undefined !== op2 && op2.argCount !== 0) {\n incrementArgCount(op2);\n }\n }\n }\n}\n\nconst addNumber: TokenInterpreter = (ctx: IConverterContext) => {\n addOperand(ctx, InternalTokenType.Number);\n return { value: true };\n};\n\nconst addVariable: TokenInterpreter = (ctx: IConverterContext) => {\n ctx = { ...ctx, currentToken: ctx.currentToken.toLowerCase() };\n if (undefined !== ctx.previousToken && isNumber(ctx.previousToken)) {\n addOperator({ ...ctx, currentToken: \"*\" });\n addOperand({ ...ctx, previousToken: \"*\" }, InternalTokenType.Variable);\n } else {\n addOperand(ctx, InternalTokenType.Variable);\n }\n return { value: true };\n};\n\nconst addFunction: TokenInterpreter = (ctx: IConverterContext) => {\n const currentOperator = ctx.operatorStack.peek();\n if (undefined !== currentOperator) {\n incrementArgCount(currentOperator);\n }\n\n ctx.operatorStack.push({ value: ctx.currentToken, type: InternalTokenType.Function, argCount: 0, argCountIncremented: false });\n return { value: true };\n};\n\nconst addOperator: TokenInterpreter = (ctx: IConverterContext) => {\n if (!isSupportedOperator(ctx.currentToken)) {\n return { errorMessage: `Operator \"${ctx.currentToken}\" is not supported.` };\n }\n\n const binary = undefined !== ctx.previousToken && \"(\" !== ctx.previousToken && \",\" !== ctx.previousToken && !isOperator(ctx.previousToken);\n const unary = !binary;\n\n const op = unary ? getUnaryOperator(ctx.currentToken) : getBinaryOperator(ctx.currentToken);\n if (unary && undefined === op) {\n return { errorMessage: `Unary \"${ctx.currentToken}\" is not supported.` };\n }\n\n const o1 = ctx.currentToken;\n const o1Associativity = getOperatorAssociativity(op);\n const o1Precedence = getOperatorPrecedence(op);\n while (ctx.operatorStack.length > 0) {\n const o2 = ctx.operatorStack.peek()!;\n\n if (o2.value === \"(\") {\n break;\n }\n\n const o2Unary = o2.argCount === 0;\n const op2 = o2Unary ? getUnaryOperator(o2.value) : getBinaryOperator(o2.value);\n const o2Precedence = getOperatorPrecedence(op2);\n if (!(o2Precedence > o1Precedence || (o2Precedence === o1Precedence && o1Associativity === OperatorAssociativity.Left))) {\n break;\n }\n\n ctx.resultQueue.enqueue(ctx.operatorStack.pop()!);\n\n const currentOperator = ctx.operatorStack.peek();\n if (undefined !== currentOperator) {\n incrementArgCount(currentOperator);\n }\n }\n\n ctx.operatorStack.push({\n value: o1,\n type: InternalTokenType.Operator,\n argCount: binary ? 1 : 0,\n argCountIncremented: false,\n });\n\n return { value: true };\n};\n\nconst openParenthesis: TokenInterpreter = (ctx: IConverterContext) => {\n if (undefined !== ctx.previousToken) {\n if (InternalTokenType.Number === ctx.previousTokenType || InternalTokenType.ClosingParenthesis === ctx.previousTokenType) {\n addOperator({ ...ctx, currentToken: \"*\" });\n } else if (InternalTokenType.Variable === ctx.previousTokenType) {\n return { errorMessage: `Function \"${ctx.previousToken}\" is not supported.` };\n }\n }\n\n const currentOperator = ctx.operatorStack.peek();\n if (undefined !== currentOperator && currentOperator.type !== InternalTokenType.Function) {\n incrementArgCount(currentOperator);\n }\n\n ctx.operatorStack.push({ value: \"(\", type: InternalTokenType.OpeningParenthesis, argCount: 0, argCountIncremented: false });\n return { value: true };\n};\n\nconst closeParenthesis: TokenInterpreter = (ctx: IConverterContext) => {\n while (ctx.operatorStack.length > 0 && ctx.operatorStack.peek()!.value !== \"(\") {\n ctx.resultQueue.enqueue(ctx.operatorStack.pop()!);\n }\n\n const leftParenthesis = ctx.operatorStack.pop();\n if (undefined === leftParenthesis) {\n return { errorMessage: `Closing parenthesis \")\" found, but the opening parenthesis \"(\" is missing.` };\n }\n\n const potentialFnToken = ctx.operatorStack.peek();\n if (undefined !== potentialFnToken && isFunction(potentialFnToken.value)) {\n potentialFnToken.argCount = leftParenthesis.argCount;\n ctx.resultQueue.enqueue(ctx.operatorStack.pop()!);\n }\n\n return { value: true };\n};\n\nconst addString: TokenInterpreter = (ctx: IConverterContext) => {\n const withoutDelimiters = ctx.currentToken.substring(1, ctx.currentToken.length - 1);\n addOperand({ ...ctx, currentToken: withoutDelimiters }, InternalTokenType.String);\n return { value: true };\n};\n\nconst addBoolean: TokenInterpreter = (ctx: IConverterContext) => {\n addOperand({ ...ctx, currentToken: ctx.currentToken.toLowerCase() }, InternalTokenType.Boolean);\n return { value: true };\n};\n\nconst addNull: TokenInterpreter = (ctx: IConverterContext) => {\n addOperand({ ...ctx, currentToken: ctx.currentToken.toLowerCase() }, InternalTokenType.Null);\n return { value: true };\n};\n\nconst separateFunctionArgumentSeparator: TokenInterpreter = (ctx: IConverterContext) => {\n while (ctx.operatorStack.length > 0 && ctx.operatorStack.peek()!.value !== \"(\") {\n ctx.resultQueue.enqueue(ctx.operatorStack.pop()!);\n\n const currentOperator = ctx.operatorStack.peek();\n if (undefined !== currentOperator) {\n incrementArgCount(currentOperator);\n }\n }\n\n const last2Operators = ctx.operatorStack.peekN(2);\n if (last2Operators.length < 2 || last2Operators[0].type !== InternalTokenType.OpeningParenthesis || last2Operators[1].type !== InternalTokenType.Function) {\n return { errorMessage: `Function argument separator \",\" found outside of a function call.` };\n }\n\n last2Operators[0].argCountIncremented = false;\n return { value: true };\n};\n\nfunction getTokenType(token: string, nextToken: string | undefined): InternalTokenType {\n if (isNumber(token)) {\n return InternalTokenType.Number;\n } else if (isStringLiteral(token)) {\n return InternalTokenType.String;\n } else if (isBoolean(token)) {\n return InternalTokenType.Boolean;\n } else if (isNull(token)) {\n return InternalTokenType.Null;\n } else if (isFunction(token) && \"(\" === nextToken) {\n return InternalTokenType.Function;\n } else if (isOperator(token)) {\n return InternalTokenType.Operator;\n } else if (\"(\" === token) {\n return InternalTokenType.OpeningParenthesis;\n } else if (\")\" === token) {\n return InternalTokenType.ClosingParenthesis;\n } else if (\",\" === token) {\n return InternalTokenType.ArgumentSeparator;\n } else {\n return InternalTokenType.Variable;\n }\n}\n\nconst tokenInterpreters: Map<InternalTokenType, TokenInterpreter> = new Map([\n [InternalTokenType.Number, addNumber],\n [InternalTokenType.ArgumentSeparator, separateFunctionArgumentSeparator],\n [InternalTokenType.ClosingParenthesis, closeParenthesis],\n [InternalTokenType.Function, addFunction],\n [InternalTokenType.OpeningParenthesis, openParenthesis],\n [InternalTokenType.Operator, addOperator],\n [InternalTokenType.Variable, addVariable],\n [InternalTokenType.String, addString],\n [InternalTokenType.Boolean, addBoolean],\n [InternalTokenType.Null, addNull],\n]);\n\nexport function convertInfixToPostfix(infix: string[]): IResult<Queue<Token>> {\n const resultQueue = new Queue<InternalToken>();\n const operatorStack = new Stack<InternalToken>();\n\n for (let index = 0; index < infix.length; index++) {\n const token = infix[index];\n\n const ctx: IConverterContext = {\n resultQueue,\n operatorStack,\n currentToken: token,\n currentTokenType: getTokenType(token, index < infix.length - 1 ? infix[index + 1] : undefined),\n previousToken: index > 0 ? infix[index - 1] : undefined,\n previousTokenType: index > 0 ? getTokenType(infix[index - 1], token) : undefined,\n };\n\n const fn = tokenInterpreters.get(ctx.currentTokenType)!;\n\n const tmpResult = fn(ctx);\n if (undefined === tmpResult.value) {\n return { errorMessage: tmpResult.errorMessage };\n }\n }\n\n while (operatorStack.length > 0) {\n resultQueue.enqueue(operatorStack.pop()!);\n\n const currentOperator = operatorStack.peek();\n if (undefined !== currentOperator) {\n incrementArgCount(currentOperator);\n }\n }\n\n return getExternalQueue(resultQueue);\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export declare class InputStream {
2
+ private readonly _stream;
3
+ private _nextIndex;
4
+ private _current;
5
+ constructor(_stream: string);
6
+ get next(): string;
7
+ get undo(): string;
8
+ get current(): string;
9
+ get peek(): string;
10
+ get isEOF(): boolean;
11
+ }
12
+ //# sourceMappingURL=InputStream.d.ts.map
@@ -0,0 +1,32 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export class InputStream {
6
+ constructor(_stream) {
7
+ this._stream = _stream;
8
+ this._nextIndex = 0;
9
+ this._current = "";
10
+ }
11
+ get next() {
12
+ this._current = this.isEOF ? "" : this._stream[this._nextIndex++];
13
+ return this.current;
14
+ }
15
+ get undo() {
16
+ if (this._nextIndex === 0)
17
+ return this.current;
18
+ this._nextIndex--;
19
+ this._current = this._nextIndex === 0 ? "" : this._stream[this._nextIndex - 1];
20
+ return this.current;
21
+ }
22
+ get current() {
23
+ return this._current;
24
+ }
25
+ get peek() {
26
+ return this.isEOF ? "" : this._stream[this._nextIndex];
27
+ }
28
+ get isEOF() {
29
+ return this._nextIndex >= this._stream.length;
30
+ }
31
+ }
32
+ //# sourceMappingURL=InputStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputStream.js","sourceRoot":"","sources":["../../../src/formula/InputStream.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,MAAM,OAAO,WAAW;IAItB,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;QAHpC,eAAU,GAAG,CAAC,CAAC;QACf,aAAQ,GAAG,EAAE,CAAC;IAE0B,CAAC;IAEjD,IAAW,IAAI;QACb,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAW,IAAI;QACb,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC,OAAO,CAAC;QAEtB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAChD,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nexport class InputStream {\n private _nextIndex = 0;\n private _current = \"\";\n\n constructor(private readonly _stream: string) { }\n\n public get next(): string {\n this._current = this.isEOF ? \"\" : this._stream[this._nextIndex++];\n return this.current;\n }\n\n public get undo(): string {\n if (this._nextIndex === 0)\n return this.current;\n\n this._nextIndex--;\n this._current = this._nextIndex === 0 ? \"\" : this._stream[this._nextIndex - 1];\n return this.current;\n }\n\n public get current(): string {\n return this._current;\n }\n\n public get peek(): string {\n return this.isEOF ? \"\" : this._stream[this._nextIndex];\n }\n\n public get isEOF(): boolean {\n return this._nextIndex >= this._stream.length;\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export declare enum ParenthesisState {
2
+ Valid = 0,
3
+ NotClosed = 1,
4
+ NotOpened = 2
5
+ }
6
+ export declare function validateParenthesis(infixFormula: string): ParenthesisState;
7
+ //# sourceMappingURL=ParenthesisValidator.d.ts.map