@jbrowse/jexl 2.3.1
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.
- package/CHANGELOG.md +222 -0
- package/LICENSE.txt +19 -0
- package/README.md +216 -0
- package/dist/Expression.d.ts +38 -0
- package/dist/Expression.js +75 -0
- package/dist/Expression.js.map +1 -0
- package/dist/Jexl.d.ts +148 -0
- package/dist/Jexl.js +208 -0
- package/dist/Jexl.js.map +1 -0
- package/dist/Lexer.d.ts +130 -0
- package/dist/Lexer.js +321 -0
- package/dist/Lexer.js.map +1 -0
- package/dist/PromiseSync.d.ts +13 -0
- package/dist/PromiseSync.js +80 -0
- package/dist/PromiseSync.js.map +1 -0
- package/dist/evaluator/Evaluator.d.ts +92 -0
- package/dist/evaluator/Evaluator.js +153 -0
- package/dist/evaluator/Evaluator.js.map +1 -0
- package/dist/evaluator/handlers.d.ts +111 -0
- package/dist/evaluator/handlers.js +216 -0
- package/dist/evaluator/handlers.js.map +1 -0
- package/dist/grammar.d.ts +25 -0
- package/dist/grammar.js +179 -0
- package/dist/grammar.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +1 -0
- package/dist/parser/Parser.d.ts +112 -0
- package/dist/parser/Parser.js +233 -0
- package/dist/parser/Parser.js.map +1 -0
- package/dist/parser/handlers.d.ts +112 -0
- package/dist/parser/handlers.js +302 -0
- package/dist/parser/handlers.js.map +1 -0
- package/dist/parser/states.d.ts +47 -0
- package/dist/parser/states.js +195 -0
- package/dist/parser/states.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/esm/Expression.d.ts +38 -0
- package/esm/Expression.js +70 -0
- package/esm/Expression.js.map +1 -0
- package/esm/Jexl.d.ts +148 -0
- package/esm/Jexl.js +202 -0
- package/esm/Jexl.js.map +1 -0
- package/esm/Lexer.d.ts +130 -0
- package/esm/Lexer.js +319 -0
- package/esm/Lexer.js.map +1 -0
- package/esm/PromiseSync.d.ts +13 -0
- package/esm/PromiseSync.js +78 -0
- package/esm/PromiseSync.js.map +1 -0
- package/esm/evaluator/Evaluator.d.ts +92 -0
- package/esm/evaluator/Evaluator.js +118 -0
- package/esm/evaluator/Evaluator.js.map +1 -0
- package/esm/evaluator/handlers.d.ts +111 -0
- package/esm/evaluator/handlers.js +202 -0
- package/esm/evaluator/handlers.js.map +1 -0
- package/esm/grammar.d.ts +25 -0
- package/esm/grammar.js +175 -0
- package/esm/grammar.js.map +1 -0
- package/esm/index.d.ts +5 -0
- package/esm/index.js +9 -0
- package/esm/index.js.map +1 -0
- package/esm/parser/Parser.d.ts +112 -0
- package/esm/parser/Parser.js +198 -0
- package/esm/parser/Parser.js.map +1 -0
- package/esm/parser/handlers.d.ts +112 -0
- package/esm/parser/handlers.js +280 -0
- package/esm/parser/handlers.js.map +1 -0
- package/esm/parser/states.d.ts +47 -0
- package/esm/parser/states.js +159 -0
- package/esm/parser/states.js.map +1 -0
- package/esm/types.d.ts +77 -0
- package/esm/types.js +6 -0
- package/esm/types.js.map +1 -0
- package/package.json +67 -0
- package/src/Expression.ts +95 -0
- package/src/Jexl.ts +232 -0
- package/src/Lexer.ts +344 -0
- package/src/PromiseSync.ts +86 -0
- package/src/evaluator/Evaluator.ts +153 -0
- package/src/evaluator/handlers.ts +226 -0
- package/src/grammar.ts +200 -0
- package/src/index.ts +10 -0
- package/src/parser/Parser.ts +235 -0
- package/src/parser/handlers.ts +309 -0
- package/src/parser/states.ts +177 -0
- package/src/types.ts +107 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Jexl
|
|
3
|
+
* Copyright 2020 Tom Shawver
|
|
4
|
+
*/
|
|
5
|
+
import * as handlers from "./handlers.js";
|
|
6
|
+
import { states } from "./states.js";
|
|
7
|
+
/**
|
|
8
|
+
* The Parser is a state machine that converts tokens from the {@link Lexer}
|
|
9
|
+
* into an Abstract Syntax Tree (AST), capable of being evaluated in any
|
|
10
|
+
* context by the {@link Evaluator}. The Parser expects that all tokens
|
|
11
|
+
* provided to it are legal and typed properly according to the grammar, but
|
|
12
|
+
* accepts that the tokens may still be in an invalid order or in some other
|
|
13
|
+
* unparsable configuration that requires it to throw an Error.
|
|
14
|
+
* @param {{}} grammar The grammar object to use to parse Jexl strings
|
|
15
|
+
* @param {string} [prefix] A string prefix to prepend to the expression string
|
|
16
|
+
* for error messaging purposes. This is useful for when a new Parser is
|
|
17
|
+
* instantiated to parse an subexpression, as the parent Parser's
|
|
18
|
+
* expression string thus far can be passed for a more user-friendly
|
|
19
|
+
* error message.
|
|
20
|
+
* @param {{}} [stopMap] A mapping of token types to any truthy value. When the
|
|
21
|
+
* token type is encountered, the parser will return the mapped value
|
|
22
|
+
* instead of boolean false.
|
|
23
|
+
*/
|
|
24
|
+
class Parser {
|
|
25
|
+
constructor(grammar, lexer, prefix, stopMap) {
|
|
26
|
+
this._grammar = grammar;
|
|
27
|
+
this._lexer = lexer;
|
|
28
|
+
this._state = 'expectOperand';
|
|
29
|
+
this._tree = null;
|
|
30
|
+
this._exprStr = prefix || '';
|
|
31
|
+
this._relative = false;
|
|
32
|
+
this._stopMap = stopMap || {};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Processes a new token into the AST and manages the transitions of the state
|
|
36
|
+
* machine.
|
|
37
|
+
* @param {{type: <string>}} token A token object, as provided by the
|
|
38
|
+
* {@link Lexer#tokenize} function.
|
|
39
|
+
* @throws {Error} if a token is added when the Parser has been marked as
|
|
40
|
+
* complete by {@link #complete}, or if an unexpected token type is added.
|
|
41
|
+
* @returns {boolean|*} the stopState value if this parser encountered a token
|
|
42
|
+
* in the stopState mapb false if tokens can continue.
|
|
43
|
+
*/
|
|
44
|
+
addToken(token) {
|
|
45
|
+
if (this._state === 'complete') {
|
|
46
|
+
throw new Error('Cannot add a new token to a completed Parser');
|
|
47
|
+
}
|
|
48
|
+
const state = states[this._state];
|
|
49
|
+
const startExpr = this._exprStr;
|
|
50
|
+
this._exprStr += token.raw;
|
|
51
|
+
if (state.subHandler) {
|
|
52
|
+
if (!this._subParser) {
|
|
53
|
+
this._startSubExpression(startExpr);
|
|
54
|
+
}
|
|
55
|
+
const stopState = this._subParser.addToken(token);
|
|
56
|
+
if (stopState) {
|
|
57
|
+
this._endSubExpression();
|
|
58
|
+
if (this._parentStop) {
|
|
59
|
+
return stopState;
|
|
60
|
+
}
|
|
61
|
+
this._state = stopState;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (state.tokenTypes?.[token.type]) {
|
|
65
|
+
const typeOpts = state.tokenTypes[token.type];
|
|
66
|
+
let handleFunc = handlers[token.type];
|
|
67
|
+
if (typeOpts.handler) {
|
|
68
|
+
handleFunc = typeOpts.handler;
|
|
69
|
+
}
|
|
70
|
+
if (handleFunc) {
|
|
71
|
+
handleFunc.call(this, token);
|
|
72
|
+
}
|
|
73
|
+
if (typeOpts.toState) {
|
|
74
|
+
this._state = typeOpts.toState;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (this._stopMap[token.type]) {
|
|
78
|
+
return this._stopMap[token.type];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throw new Error(`Token ${token.raw} (${token.type}) unexpected in expression: ${this._exprStr}`);
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Processes an array of tokens iteratively through the {@link #addToken}
|
|
87
|
+
* function.
|
|
88
|
+
* @param {Array<{type: <string>}>} tokens An array of tokens, as provided by
|
|
89
|
+
* the {@link Lexer#tokenize} function.
|
|
90
|
+
*/
|
|
91
|
+
addTokens(tokens) {
|
|
92
|
+
tokens.forEach((token) => this.addToken(token));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Marks this Parser instance as completed and retrieves the full AST.
|
|
96
|
+
* @returns {{}|null} a full expression tree, ready for evaluation by the
|
|
97
|
+
* {@link Evaluator#eval} function, or null if no tokens were passed to
|
|
98
|
+
* the parser before complete was called
|
|
99
|
+
* @throws {Error} if the parser is not in a state where it's legal to end
|
|
100
|
+
* the expression, indicating that the expression is incomplete
|
|
101
|
+
*/
|
|
102
|
+
complete() {
|
|
103
|
+
if (this._cursor && !states[this._state].completable) {
|
|
104
|
+
throw new Error(`Unexpected end of expression: ${this._exprStr}`);
|
|
105
|
+
}
|
|
106
|
+
if (this._subParser) {
|
|
107
|
+
this._endSubExpression();
|
|
108
|
+
}
|
|
109
|
+
if (this._sequenceExpressions) {
|
|
110
|
+
this._sequenceExpressions.push(this._tree);
|
|
111
|
+
const sequence = {
|
|
112
|
+
type: 'SequenceExpression',
|
|
113
|
+
expressions: this._sequenceExpressions
|
|
114
|
+
};
|
|
115
|
+
this._state = 'complete';
|
|
116
|
+
return sequence;
|
|
117
|
+
}
|
|
118
|
+
this._state = 'complete';
|
|
119
|
+
return this._cursor ? this._tree : null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Indicates whether the expression tree contains a relative path identifier.
|
|
123
|
+
* @returns {boolean} true if a relative identifier exists false otherwise.
|
|
124
|
+
*/
|
|
125
|
+
isRelative() {
|
|
126
|
+
return this._relative;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Ends a subexpression by completing the subParser and passing its result
|
|
130
|
+
* to the subHandler configured in the current state.
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
_endSubExpression() {
|
|
134
|
+
states[this._state].subHandler.call(this, this._subParser.complete());
|
|
135
|
+
this._subParser = undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Places a new tree node at the current position of the cursor (to the 'right'
|
|
139
|
+
* property) and then advances the cursor to the new node. This function also
|
|
140
|
+
* handles setting the parent of the new node.
|
|
141
|
+
* @param {{type: <string>}} node A node to be added to the AST
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
_placeAtCursor(node) {
|
|
145
|
+
if (!this._cursor) {
|
|
146
|
+
this._tree = node;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
;
|
|
150
|
+
this._cursor.right = node;
|
|
151
|
+
this._setParent(node, this._cursor);
|
|
152
|
+
}
|
|
153
|
+
this._cursor = node;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Places a tree node before the current position of the cursor, replacing
|
|
157
|
+
* the node that the cursor currently points to. This should only be called in
|
|
158
|
+
* cases where the cursor is known to exist, and the provided node already
|
|
159
|
+
* contains a pointer to what's at the cursor currently.
|
|
160
|
+
* @param {{type: <string>}} node A node to be added to the AST
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
_placeBeforeCursor(node) {
|
|
164
|
+
this._cursor = this._cursor?._parent;
|
|
165
|
+
this._placeAtCursor(node);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sets the parent of a node by creating a non-enumerable _parent property
|
|
169
|
+
* that points to the supplied parent argument.
|
|
170
|
+
* @param {{type: <string>}} node A node of the AST on which to set a new
|
|
171
|
+
* parent
|
|
172
|
+
* @param {{type: <string>}} parent An existing node of the AST to serve as the
|
|
173
|
+
* parent of the new node
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_setParent(node, parent) {
|
|
177
|
+
Object.defineProperty(node, '_parent', {
|
|
178
|
+
value: parent,
|
|
179
|
+
writable: true
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Prepares the Parser to accept a subexpression by (re)instantiating the
|
|
184
|
+
* subParser.
|
|
185
|
+
* @param {string} [exprStr] The expression string to prefix to the new Parser
|
|
186
|
+
* @private
|
|
187
|
+
*/
|
|
188
|
+
_startSubExpression(exprStr) {
|
|
189
|
+
let endStates = states[this._state].endStates;
|
|
190
|
+
if (!endStates) {
|
|
191
|
+
this._parentStop = true;
|
|
192
|
+
endStates = this._stopMap;
|
|
193
|
+
}
|
|
194
|
+
this._subParser = new Parser(this._grammar, this._lexer, exprStr, endStates);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export default Parser;
|
|
198
|
+
//# sourceMappingURL=Parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/parser/Parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { AstNode, Token } from '../types.ts';
|
|
2
|
+
import type Parser from './Parser.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Handles a subexpression that's used to define a transform argument's value.
|
|
5
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
6
|
+
*/
|
|
7
|
+
export declare function argVal(this: Parser, ast: AstNode | null): void;
|
|
8
|
+
/**
|
|
9
|
+
* Handles new array literals by adding them as a new node in the AST,
|
|
10
|
+
* initialized with an empty array.
|
|
11
|
+
*/
|
|
12
|
+
export declare function arrayStart(this: Parser): void;
|
|
13
|
+
/**
|
|
14
|
+
* Handles a subexpression representing an element of an array literal.
|
|
15
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
16
|
+
*/
|
|
17
|
+
export declare function arrayVal(this: Parser, ast: AstNode | null): void;
|
|
18
|
+
/**
|
|
19
|
+
* Handles tokens of type 'binaryOp', indicating an operation that has two
|
|
20
|
+
* inputs: a left side and a right side.
|
|
21
|
+
* @param {{type: <string>}} token A token object
|
|
22
|
+
*/
|
|
23
|
+
export declare function binaryOp(this: Parser, token: Token): void;
|
|
24
|
+
/**
|
|
25
|
+
* Handles successive nodes in an identifier chain. More specifically, it
|
|
26
|
+
* sets values that determine how the following identifier gets placed in the
|
|
27
|
+
* AST.
|
|
28
|
+
*/
|
|
29
|
+
export declare function dot(this: Parser): void;
|
|
30
|
+
/**
|
|
31
|
+
* Handles a subexpression used for filtering an array returned by an
|
|
32
|
+
* identifier chain.
|
|
33
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
34
|
+
*/
|
|
35
|
+
export declare function filter(this: Parser, ast: AstNode | null): void;
|
|
36
|
+
/**
|
|
37
|
+
* Handles identifier tokens when used to indicate the name of a function to
|
|
38
|
+
* be called.
|
|
39
|
+
* @param {{type: <string>}} token A token object
|
|
40
|
+
*/
|
|
41
|
+
export declare function functionCall(this: Parser): void;
|
|
42
|
+
/**
|
|
43
|
+
* Handles identifier tokens by adding them as a new node in the AST.
|
|
44
|
+
* @param {{type: <string>}} token A token object
|
|
45
|
+
*/
|
|
46
|
+
export declare function identifier(this: Parser, token: Token): void;
|
|
47
|
+
/**
|
|
48
|
+
* Handles literal values, such as strings, booleans, and numerics, by adding
|
|
49
|
+
* them as a new node in the AST.
|
|
50
|
+
* @param {{type: <string>}} token A token object
|
|
51
|
+
*/
|
|
52
|
+
export declare function literal(this: Parser, token: Token): void;
|
|
53
|
+
/**
|
|
54
|
+
* Handles template string tokens by parsing their interpolation expressions
|
|
55
|
+
* and creating a TemplateLiteral AST node.
|
|
56
|
+
* @param {{type: <string>}} token A token object
|
|
57
|
+
*/
|
|
58
|
+
export declare function templateString(this: Parser, token: Token): void;
|
|
59
|
+
/**
|
|
60
|
+
* Queues a new object literal key to be written once a value is collected.
|
|
61
|
+
* @param {{type: <string>}} token A token object
|
|
62
|
+
*/
|
|
63
|
+
export declare function objKey(this: Parser, token: Token): void;
|
|
64
|
+
/**
|
|
65
|
+
* Handles new object literals by adding them as a new node in the AST,
|
|
66
|
+
* initialized with an empty object.
|
|
67
|
+
*/
|
|
68
|
+
export declare function objStart(this: Parser): void;
|
|
69
|
+
/**
|
|
70
|
+
* Handles an object value by adding its AST to the queued key on the object
|
|
71
|
+
* literal node currently at the cursor.
|
|
72
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
73
|
+
*/
|
|
74
|
+
export declare function objVal(this: Parser, ast: AstNode | null): void;
|
|
75
|
+
/**
|
|
76
|
+
* Handles traditional subexpressions, delineated with the groupStart and
|
|
77
|
+
* groupEnd elements.
|
|
78
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
79
|
+
*/
|
|
80
|
+
export declare function subExpression(this: Parser, ast: AstNode | null): void;
|
|
81
|
+
/**
|
|
82
|
+
* Handles a completed alternate subexpression of a ternary operator.
|
|
83
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
84
|
+
*/
|
|
85
|
+
export declare function ternaryEnd(this: Parser, ast: AstNode | null): void;
|
|
86
|
+
/**
|
|
87
|
+
* Handles a completed consequent subexpression of a ternary operator.
|
|
88
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
89
|
+
*/
|
|
90
|
+
export declare function ternaryMid(this: Parser, ast: AstNode | null): void;
|
|
91
|
+
/**
|
|
92
|
+
* Handles the start of a new ternary expression by encapsulating the entire
|
|
93
|
+
* AST in a ConditionalExpression node, and using the existing tree as the
|
|
94
|
+
* test element.
|
|
95
|
+
*/
|
|
96
|
+
export declare function ternaryStart(this: Parser): void;
|
|
97
|
+
/**
|
|
98
|
+
* Handles identifier tokens when used to indicate the name of a transform to
|
|
99
|
+
* be applied.
|
|
100
|
+
* @param {{type: <string>}} token A token object
|
|
101
|
+
*/
|
|
102
|
+
export declare function transform(this: Parser, token: Token): void;
|
|
103
|
+
/**
|
|
104
|
+
* Handles token of type 'unaryOp', indicating that the operation has only
|
|
105
|
+
* one input: a right side.
|
|
106
|
+
* @param {{type: <string>}} token A token object
|
|
107
|
+
*/
|
|
108
|
+
export declare function unaryOp(this: Parser, token: Token): void;
|
|
109
|
+
/**
|
|
110
|
+
* Handles semicolon separator between expressions
|
|
111
|
+
*/
|
|
112
|
+
export declare function semicolon(this: Parser): void;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Jexl
|
|
3
|
+
* Copyright 2020 Tom Shawver
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Handles a subexpression that's used to define a transform argument's value.
|
|
7
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
8
|
+
*/
|
|
9
|
+
export function argVal(ast) {
|
|
10
|
+
if (ast) {
|
|
11
|
+
;
|
|
12
|
+
this._cursor.args.push(ast);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Handles new array literals by adding them as a new node in the AST,
|
|
17
|
+
* initialized with an empty array.
|
|
18
|
+
*/
|
|
19
|
+
export function arrayStart() {
|
|
20
|
+
this._placeAtCursor({
|
|
21
|
+
type: 'ArrayLiteral',
|
|
22
|
+
value: []
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Handles a subexpression representing an element of an array literal.
|
|
27
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
28
|
+
*/
|
|
29
|
+
export function arrayVal(ast) {
|
|
30
|
+
if (ast) {
|
|
31
|
+
;
|
|
32
|
+
this._cursor.value.push(ast);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Handles tokens of type 'binaryOp', indicating an operation that has two
|
|
37
|
+
* inputs: a left side and a right side.
|
|
38
|
+
* @param {{type: <string>}} token A token object
|
|
39
|
+
*/
|
|
40
|
+
export function binaryOp(token) {
|
|
41
|
+
if (token.value === '=') {
|
|
42
|
+
if (this._cursor?.type !== 'Identifier') {
|
|
43
|
+
throw new Error('Left side of assignment must be a variable name');
|
|
44
|
+
}
|
|
45
|
+
const node = {
|
|
46
|
+
type: 'AssignmentExpression',
|
|
47
|
+
operator: '=',
|
|
48
|
+
left: this._cursor
|
|
49
|
+
};
|
|
50
|
+
this._cursor = this._cursor._parent;
|
|
51
|
+
this._placeAtCursor(node);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const precedence = this._grammar.elements[token.value].precedence || 0;
|
|
55
|
+
let parent = this._cursor?._parent;
|
|
56
|
+
while (parent &&
|
|
57
|
+
parent.operator &&
|
|
58
|
+
this._grammar.elements[parent.operator].precedence >= precedence) {
|
|
59
|
+
this._cursor = parent;
|
|
60
|
+
parent = parent._parent;
|
|
61
|
+
}
|
|
62
|
+
const node = {
|
|
63
|
+
type: 'BinaryExpression',
|
|
64
|
+
operator: token.value,
|
|
65
|
+
left: this._cursor
|
|
66
|
+
};
|
|
67
|
+
this._setParent(this._cursor, node);
|
|
68
|
+
this._cursor = parent;
|
|
69
|
+
this._placeAtCursor(node);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handles successive nodes in an identifier chain. More specifically, it
|
|
73
|
+
* sets values that determine how the following identifier gets placed in the
|
|
74
|
+
* AST.
|
|
75
|
+
*/
|
|
76
|
+
export function dot() {
|
|
77
|
+
const isBinaryExprWithRight = (node) => node.type === 'BinaryExpression' && node.right;
|
|
78
|
+
this._nextIdentEncapsulate =
|
|
79
|
+
this._cursor &&
|
|
80
|
+
this._cursor.type !== 'UnaryExpression' &&
|
|
81
|
+
(this._cursor.type !== 'BinaryExpression' ||
|
|
82
|
+
isBinaryExprWithRight(this._cursor));
|
|
83
|
+
this._nextIdentRelative = !this._cursor || !this._nextIdentEncapsulate;
|
|
84
|
+
if (this._nextIdentRelative) {
|
|
85
|
+
this._relative = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Handles a subexpression used for filtering an array returned by an
|
|
90
|
+
* identifier chain.
|
|
91
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
92
|
+
*/
|
|
93
|
+
export function filter(ast) {
|
|
94
|
+
this._placeBeforeCursor({
|
|
95
|
+
type: 'FilterExpression',
|
|
96
|
+
expr: ast,
|
|
97
|
+
relative: this._subParser.isRelative(),
|
|
98
|
+
subject: this._cursor
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handles identifier tokens when used to indicate the name of a function to
|
|
103
|
+
* be called.
|
|
104
|
+
* @param {{type: <string>}} token A token object
|
|
105
|
+
*/
|
|
106
|
+
export function functionCall() {
|
|
107
|
+
this._placeBeforeCursor({
|
|
108
|
+
type: 'FunctionCall',
|
|
109
|
+
name: this._cursor.value,
|
|
110
|
+
args: [],
|
|
111
|
+
pool: 'functions'
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Handles identifier tokens by adding them as a new node in the AST.
|
|
116
|
+
* @param {{type: <string>}} token A token object
|
|
117
|
+
*/
|
|
118
|
+
export function identifier(token) {
|
|
119
|
+
const node = {
|
|
120
|
+
type: 'Identifier',
|
|
121
|
+
value: token.value
|
|
122
|
+
};
|
|
123
|
+
if (this._nextIdentEncapsulate) {
|
|
124
|
+
node.from = this._cursor;
|
|
125
|
+
this._placeBeforeCursor(node);
|
|
126
|
+
this._nextIdentEncapsulate = false;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
if (this._nextIdentRelative) {
|
|
130
|
+
node.relative = true;
|
|
131
|
+
this._nextIdentRelative = false;
|
|
132
|
+
}
|
|
133
|
+
this._placeAtCursor(node);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Handles literal values, such as strings, booleans, and numerics, by adding
|
|
138
|
+
* them as a new node in the AST.
|
|
139
|
+
* @param {{type: <string>}} token A token object
|
|
140
|
+
*/
|
|
141
|
+
export function literal(token) {
|
|
142
|
+
this._placeAtCursor({
|
|
143
|
+
type: 'Literal',
|
|
144
|
+
value: token.value
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handles template string tokens by parsing their interpolation expressions
|
|
149
|
+
* and creating a TemplateLiteral AST node.
|
|
150
|
+
* @param {{type: <string>}} token A token object
|
|
151
|
+
*/
|
|
152
|
+
export function templateString(token) {
|
|
153
|
+
const parts = [];
|
|
154
|
+
for (const part of token.value) {
|
|
155
|
+
if (part.type === 'static') {
|
|
156
|
+
parts.push({
|
|
157
|
+
type: 'static',
|
|
158
|
+
value: this._lexer._unescapeTemplateString(part.value)
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
const subTokens = this._lexer.tokenize(part.value);
|
|
163
|
+
const subParser = new this.constructor(this._grammar, this._lexer);
|
|
164
|
+
subParser.addTokens(subTokens);
|
|
165
|
+
const subAst = subParser.complete();
|
|
166
|
+
if (!subAst) {
|
|
167
|
+
throw new Error('Empty interpolation in template string');
|
|
168
|
+
}
|
|
169
|
+
parts.push({
|
|
170
|
+
type: 'expression',
|
|
171
|
+
value: subAst
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
this._placeAtCursor({
|
|
176
|
+
type: 'TemplateLiteral',
|
|
177
|
+
parts: parts
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Queues a new object literal key to be written once a value is collected.
|
|
182
|
+
* @param {{type: <string>}} token A token object
|
|
183
|
+
*/
|
|
184
|
+
export function objKey(token) {
|
|
185
|
+
this._curObjKey = token.value;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Handles new object literals by adding them as a new node in the AST,
|
|
189
|
+
* initialized with an empty object.
|
|
190
|
+
*/
|
|
191
|
+
export function objStart() {
|
|
192
|
+
this._placeAtCursor({
|
|
193
|
+
type: 'ObjectLiteral',
|
|
194
|
+
value: {}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Handles an object value by adding its AST to the queued key on the object
|
|
199
|
+
* literal node currently at the cursor.
|
|
200
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
201
|
+
*/
|
|
202
|
+
export function objVal(ast) {
|
|
203
|
+
;
|
|
204
|
+
this._cursor.value[this._curObjKey] = ast;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Handles traditional subexpressions, delineated with the groupStart and
|
|
208
|
+
* groupEnd elements.
|
|
209
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
210
|
+
*/
|
|
211
|
+
export function subExpression(ast) {
|
|
212
|
+
this._placeAtCursor(ast);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Handles a completed alternate subexpression of a ternary operator.
|
|
216
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
217
|
+
*/
|
|
218
|
+
export function ternaryEnd(ast) {
|
|
219
|
+
;
|
|
220
|
+
this._cursor.alternate = ast;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Handles a completed consequent subexpression of a ternary operator.
|
|
224
|
+
* @param {{type: <string>}} ast The subexpression tree
|
|
225
|
+
*/
|
|
226
|
+
export function ternaryMid(ast) {
|
|
227
|
+
;
|
|
228
|
+
this._cursor.consequent = ast;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Handles the start of a new ternary expression by encapsulating the entire
|
|
232
|
+
* AST in a ConditionalExpression node, and using the existing tree as the
|
|
233
|
+
* test element.
|
|
234
|
+
*/
|
|
235
|
+
export function ternaryStart() {
|
|
236
|
+
this._tree = {
|
|
237
|
+
type: 'ConditionalExpression',
|
|
238
|
+
test: this._tree
|
|
239
|
+
};
|
|
240
|
+
this._cursor = this._tree;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Handles identifier tokens when used to indicate the name of a transform to
|
|
244
|
+
* be applied.
|
|
245
|
+
* @param {{type: <string>}} token A token object
|
|
246
|
+
*/
|
|
247
|
+
export function transform(token) {
|
|
248
|
+
this._placeBeforeCursor({
|
|
249
|
+
type: 'FunctionCall',
|
|
250
|
+
name: token.value,
|
|
251
|
+
args: [this._cursor],
|
|
252
|
+
pool: 'transforms'
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Handles token of type 'unaryOp', indicating that the operation has only
|
|
257
|
+
* one input: a right side.
|
|
258
|
+
* @param {{type: <string>}} token A token object
|
|
259
|
+
*/
|
|
260
|
+
export function unaryOp(token) {
|
|
261
|
+
this._placeAtCursor({
|
|
262
|
+
type: 'UnaryExpression',
|
|
263
|
+
operator: token.value
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Handles semicolon separator between expressions
|
|
268
|
+
*/
|
|
269
|
+
export function semicolon() {
|
|
270
|
+
if (!this._sequenceExpressions) {
|
|
271
|
+
this._sequenceExpressions = [this._tree];
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
this._sequenceExpressions.push(this._tree);
|
|
275
|
+
}
|
|
276
|
+
this._tree = null;
|
|
277
|
+
this._cursor = null;
|
|
278
|
+
this._state = 'expectOperand';
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/parser/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AstNode } from '../types.ts';
|
|
2
|
+
import type Parser from './Parser.ts';
|
|
3
|
+
interface TokenTypeOptions {
|
|
4
|
+
toState?: string;
|
|
5
|
+
handler?: (this: Parser, ...args: any[]) => void;
|
|
6
|
+
}
|
|
7
|
+
interface StateDefinition {
|
|
8
|
+
tokenTypes?: Record<string, TokenTypeOptions>;
|
|
9
|
+
subHandler?: (this: Parser, ast: AstNode | null) => void;
|
|
10
|
+
endStates?: Record<string, string>;
|
|
11
|
+
completable?: boolean;
|
|
12
|
+
}
|
|
13
|
+
type States = Record<string, StateDefinition>;
|
|
14
|
+
/**
|
|
15
|
+
* A mapping of all states in the finite state machine to a set of instructions
|
|
16
|
+
* for handling or transitioning into other states. Each state can be handled
|
|
17
|
+
* in one of two schemes: a tokenType map, or a subHandler.
|
|
18
|
+
*
|
|
19
|
+
* Standard expression elements are handled through the tokenType object. This
|
|
20
|
+
* is an object map of all legal token types to encounter in this state (and
|
|
21
|
+
* any unexpected token types will generate a thrown error) to an options
|
|
22
|
+
* object that defines how they're handled. The available options are:
|
|
23
|
+
*
|
|
24
|
+
* {string} toState: The name of the state to which to transition
|
|
25
|
+
* immediately after handling this token
|
|
26
|
+
* {string} handler: The handler function to call when this token type is
|
|
27
|
+
* encountered in this state. If omitted, the default handler
|
|
28
|
+
* matching the token's "type" property will be called. If the handler
|
|
29
|
+
* function does not exist, no call will be made and no error will be
|
|
30
|
+
* generated. This is useful for tokens whose sole purpose is to
|
|
31
|
+
* transition to other states.
|
|
32
|
+
*
|
|
33
|
+
* States that consume a subexpression should define a subHandler, the
|
|
34
|
+
* function to be called with an expression tree argument when the
|
|
35
|
+
* subexpression is complete. Completeness is determined through the
|
|
36
|
+
* endStates object, which maps tokens on which an expression should end to the
|
|
37
|
+
* state to which to transition once the subHandler function has been called.
|
|
38
|
+
*
|
|
39
|
+
* Additionally, any state in which it is legal to mark the AST as completed
|
|
40
|
+
* should have a 'completable' property set to boolean true. Attempting to
|
|
41
|
+
* call {@link Parser#complete} in any state without this property will result
|
|
42
|
+
* in a thrown Error.
|
|
43
|
+
*
|
|
44
|
+
* @type {{}}
|
|
45
|
+
*/
|
|
46
|
+
export declare const states: States;
|
|
47
|
+
export {};
|