1 |
|
2 | // @ts-nocheck
|
3 |
|
4 | /* parser generated by jison 0.6.1-215 */
|
5 |
|
6 | /*
|
7 | * Returns a Parser object of the following structure:
|
8 | *
|
9 | * Parser: {
|
10 | * yy: {} The so-called "shared state" or rather the *source* of it;
|
11 | * the real "shared state" `yy` passed around to
|
12 | * the rule actions, etc. is a derivative/copy of this one,
|
13 | * not a direct reference!
|
14 | * }
|
15 | *
|
16 | * Parser.prototype: {
|
17 | * yy: {},
|
18 | * EOF: 1,
|
19 | * TERROR: 2,
|
20 | *
|
21 | * trace: function(errorMessage, ...),
|
22 | *
|
23 | * JisonParserError: function(msg, hash),
|
24 | *
|
25 | * quoteName: function(name),
|
26 | * Helper function which can be overridden by user code later on: put suitable
|
27 | * quotes around literal IDs in a description string.
|
28 | *
|
29 | * originalQuoteName: function(name),
|
30 | * The basic quoteName handler provided by JISON.
|
31 | * `cleanupAfterParse()` will clean up and reset `quoteName()` to reference this function
|
32 | * at the end of the `parse()`.
|
33 | *
|
34 | * describeSymbol: function(symbol),
|
35 | * Return a more-or-less human-readable description of the given symbol, when
|
36 | * available, or the symbol itself, serving as its own 'description' for lack
|
37 | * of something better to serve up.
|
38 | *
|
39 | * Return NULL when the symbol is unknown to the parser.
|
40 | *
|
41 | * symbols_: {associative list: name ==> number},
|
42 | * terminals_: {associative list: number ==> name},
|
43 | * nonterminals: {associative list: rule-name ==> {associative list: number ==> rule-alt}},
|
44 | * terminal_descriptions_: (if there are any) {associative list: number ==> description},
|
45 | * productions_: [...],
|
46 | *
|
47 | * performAction: function parser__performAction(yytext, yyleng, yylineno, yyloc, yystate, yysp, yyvstack, yylstack, yystack, yysstack),
|
48 | *
|
49 | * The function parameters and `this` have the following value/meaning:
|
50 | * - `this` : reference to the `yyval` internal object, which has members (`$` and `_$`)
|
51 | * to store/reference the rule value `$$` and location info `@$`.
|
52 | *
|
53 | * One important thing to note about `this` a.k.a. `yyval`: every *reduce* action gets
|
54 | * to see the same object via the `this` reference, i.e. if you wish to carry custom
|
55 | * data from one reduce action through to the next within a single parse run, then you
|
56 | * may get nasty and use `yyval` a.k.a. `this` for storing you own semi-permanent data.
|
57 | *
|
58 | * `this.yy` is a direct reference to the `yy` shared state object.
|
59 | *
|
60 | * `%parse-param`-specified additional `parse()` arguments have been added to this `yy`
|
61 | * object at `parse()` start and are therefore available to the action code via the
|
62 | * same named `yy.xxxx` attributes (where `xxxx` represents a identifier name from
|
63 | * the %parse-param` list.
|
64 | *
|
65 | * - `yytext` : reference to the lexer value which belongs to the last lexer token used
|
66 | * to match this rule. This is *not* the look-ahead token, but the last token
|
67 | * that's actually part of this rule.
|
68 | *
|
69 | * Formulated another way, `yytext` is the value of the token immediately preceeding
|
70 | * the current look-ahead token.
|
71 | * Caveats apply for rules which don't require look-ahead, such as epsilon rules.
|
72 | *
|
73 | * - `yyleng` : ditto as `yytext`, only now for the lexer.yyleng value.
|
74 | *
|
75 | * - `yylineno`: ditto as `yytext`, only now for the lexer.yylineno value.
|
76 | *
|
77 | * - `yyloc` : ditto as `yytext`, only now for the lexer.yylloc lexer token location info.
|
78 | *
|
79 | * WARNING: since jison 0.4.18-186 this entry may be NULL/UNDEFINED instead
|
80 | * of an empty object when no suitable location info can be provided.
|
81 | *
|
82 | * - `yystate` : the current parser state number, used internally for dispatching and
|
83 | * executing the action code chunk matching the rule currently being reduced.
|
84 | *
|
85 | * - `yysp` : the current state stack position (a.k.a. 'stack pointer')
|
86 | *
|
87 | * This one comes in handy when you are going to do advanced things to the parser
|
88 | * stacks, all of which are accessible from your action code (see the next entries below).
|
89 | *
|
90 | * Also note that you can access this and other stack index values using the new double-hash
|
91 | * syntax, i.e. `##$ === ##0 === yysp`, while `##1` is the stack index for all things
|
92 | * related to the first rule term, just like you have `$1`, `@1` and `#1`.
|
93 | * This is made available to write very advanced grammar action rules, e.g. when you want
|
94 | * to investigate the parse state stack in your action code, which would, for example,
|
95 | * be relevant when you wish to implement error diagnostics and reporting schemes similar
|
96 | * to the work described here:
|
97 | *
|
98 | * + Pottier, F., 2016. Reachability and error diagnosis in LR(1) automata.
|
99 | * In Journées Francophones des Languages Applicatifs.
|
100 | *
|
101 | * + Jeffery, C.L., 2003. Generating LR syntax error messages from examples.
|
102 | * ACM Transactions on Programming Languages and Systems (TOPLAS), 25(5), pp.631–640.
|
103 | *
|
104 | * - `yyrulelength`: the current rule's term count, i.e. the number of entries occupied on the stack.
|
105 | *
|
106 | * This one comes in handy when you are going to do advanced things to the parser
|
107 | * stacks, all of which are accessible from your action code (see the next entries below).
|
108 | *
|
109 | * - `yyvstack`: reference to the parser value stack. Also accessed via the `$1` etc.
|
110 | * constructs.
|
111 | *
|
112 | * - `yylstack`: reference to the parser token location stack. Also accessed via
|
113 | * the `@1` etc. constructs.
|
114 | *
|
115 | * WARNING: since jison 0.4.18-186 this array MAY contain slots which are
|
116 | * UNDEFINED rather than an empty (location) object, when the lexer/parser
|
117 | * action code did not provide a suitable location info object when such a
|
118 | * slot was filled!
|
119 | *
|
120 | * - `yystack` : reference to the parser token id stack. Also accessed via the
|
121 | * `#1` etc. constructs.
|
122 | *
|
123 | * Note: this is a bit of a **white lie** as we can statically decode any `#n` reference to
|
124 | * its numeric token id value, hence that code wouldn't need the `yystack` but *you* might
|
125 | * want access this array for your own purposes, such as error analysis as mentioned above!
|
126 | *
|
127 | * Note that this stack stores the current stack of *tokens*, that is the sequence of
|
128 | * already parsed=reduced *nonterminals* (tokens representing rules) and *terminals*
|
129 | * (lexer tokens *shifted* onto the stack until the rule they belong to is found and
|
130 | * *reduced*.
|
131 | *
|
132 | * - `yysstack`: reference to the parser state stack. This one carries the internal parser
|
133 | * *states* such as the one in `yystate`, which are used to represent
|
134 | * the parser state machine in the *parse table*. *Very* *internal* stuff,
|
135 | * what can I say? If you access this one, you're clearly doing wicked things
|
136 | *
|
137 | * - `...` : the extra arguments you specified in the `%parse-param` statement in your
|
138 | * grammar definition file.
|
139 | *
|
140 | * table: [...],
|
141 | * State transition table
|
142 | * ----------------------
|
143 | *
|
144 | * index levels are:
|
145 | * - `state` --> hash table
|
146 | * - `symbol` --> action (number or array)
|
147 | *
|
148 | * If the `action` is an array, these are the elements' meaning:
|
149 | * - index [0]: 1 = shift, 2 = reduce, 3 = accept
|
150 | * - index [1]: GOTO `state`
|
151 | *
|
152 | * If the `action` is a number, it is the GOTO `state`
|
153 | *
|
154 | * defaultActions: {...},
|
155 | *
|
156 | * parseError: function(str, hash, ExceptionClass),
|
157 | * yyError: function(str, ...),
|
158 | * yyRecovering: function(),
|
159 | * yyErrOk: function(),
|
160 | * yyClearIn: function(),
|
161 | *
|
162 | * constructParseErrorInfo: function(error_message, exception_object, expected_token_set, is_recoverable),
|
163 | * Helper function **which will be set up during the first invocation of the `parse()` method**.
|
164 | * Produces a new errorInfo 'hash object' which can be passed into `parseError()`.
|
165 | * See it's use in this parser kernel in many places; example usage:
|
166 | *
|
167 | * var infoObj = parser.constructParseErrorInfo('fail!', null,
|
168 | * parser.collect_expected_token_set(state), true);
|
169 | * var retVal = parser.parseError(infoObj.errStr, infoObj, parser.JisonParserError);
|
170 | *
|
171 | * originalParseError: function(str, hash, ExceptionClass),
|
172 | * The basic `parseError` handler provided by JISON.
|
173 | * `cleanupAfterParse()` will clean up and reset `parseError()` to reference this function
|
174 | * at the end of the `parse()`.
|
175 | *
|
176 | * options: { ... parser %options ... },
|
177 | *
|
178 | * parse: function(input[, args...]),
|
179 | * Parse the given `input` and return the parsed value (or `true` when none was provided by
|
180 | * the root action, in which case the parser is acting as a *matcher*).
|
181 | * You MAY use the additional `args...` parameters as per `%parse-param` spec of this grammar:
|
182 | * these extra `args...` are added verbatim to the `yy` object reference as member variables.
|
183 | *
|
184 | * WARNING:
|
185 | * Parser's additional `args...` parameters (via `%parse-param`) MAY conflict with
|
186 | * any attributes already added to `yy` by the jison run-time;
|
187 | * when such a collision is detected an exception is thrown to prevent the generated run-time
|
188 | * from silently accepting this confusing and potentially hazardous situation!
|
189 | *
|
190 | * The lexer MAY add its own set of additional parameters (via the `%parse-param` line in
|
191 | * the lexer section of the grammar spec): these will be inserted in the `yy` shared state
|
192 | * object and any collision with those will be reported by the lexer via a thrown exception.
|
193 | *
|
194 | * cleanupAfterParse: function(resultValue, invoke_post_methods, do_not_nuke_errorinfos),
|
195 | * Helper function **which will be set up during the first invocation of the `parse()` method**.
|
196 | * This helper API is invoked at the end of the `parse()` call, unless an exception was thrown
|
197 | * and `%options no-try-catch` has been defined for this grammar: in that case this helper MAY
|
198 | * be invoked by calling user code to ensure the `post_parse` callbacks are invoked and
|
199 | * the internal parser gets properly garbage collected under these particular circumstances.
|
200 | *
|
201 | * yyMergeLocationInfo: function(first_index, last_index, first_yylloc, last_yylloc, dont_look_back),
|
202 | * Helper function **which will be set up during the first invocation of the `parse()` method**.
|
203 | * This helper API can be invoked to calculate a spanning `yylloc` location info object.
|
204 | *
|
205 | * Note: %epsilon rules MAY specify no `first_index` and `first_yylloc`, in which case
|
206 | * this function will attempt to obtain a suitable location marker by inspecting the location stack
|
207 | * backwards.
|
208 | *
|
209 | * For more info see the documentation comment further below, immediately above this function's
|
210 | * implementation.
|
211 | *
|
212 | * lexer: {
|
213 | * yy: {...}, A reference to the so-called "shared state" `yy` once
|
214 | * received via a call to the `.setInput(input, yy)` lexer API.
|
215 | * EOF: 1,
|
216 | * ERROR: 2,
|
217 | * JisonLexerError: function(msg, hash),
|
218 | * parseError: function(str, hash, ExceptionClass),
|
219 | * setInput: function(input, [yy]),
|
220 | * input: function(),
|
221 | * unput: function(str),
|
222 | * more: function(),
|
223 | * reject: function(),
|
224 | * less: function(n),
|
225 | * pastInput: function(n),
|
226 | * upcomingInput: function(n),
|
227 | * showPosition: function(),
|
228 | * test_match: function(regex_match_array, rule_index, ...),
|
229 | * next: function(...),
|
230 | * lex: function(...),
|
231 | * begin: function(condition),
|
232 | * pushState: function(condition),
|
233 | * popState: function(),
|
234 | * topState: function(),
|
235 | * _currentRules: function(),
|
236 | * stateStackSize: function(),
|
237 | * cleanupAfterLex: function()
|
238 | *
|
239 | * options: { ... lexer %options ... },
|
240 | *
|
241 | * performAction: function(yy, yy_, $avoiding_name_collisions, YY_START, ...),
|
242 | * rules: [...],
|
243 | * conditions: {associative list: name ==> set},
|
244 | * }
|
245 | * }
|
246 | *
|
247 | *
|
248 | * token location info (@$, _$, etc.): {
|
249 | * first_line: n,
|
250 | * last_line: n,
|
251 | * first_column: n,
|
252 | * last_column: n,
|
253 | * range: [start_number, end_number]
|
254 | * (where the numbers are indexes into the input string, zero-based)
|
255 | * }
|
256 | *
|
257 | * ---
|
258 | *
|
259 | * The `parseError` function receives a 'hash' object with these members for lexer and
|
260 | * parser errors:
|
261 | *
|
262 | * {
|
263 | * text: (matched text)
|
264 | * token: (the produced terminal token, if any)
|
265 | * token_id: (the produced terminal token numeric ID, if any)
|
266 | * line: (yylineno)
|
267 | * loc: (yylloc)
|
268 | * }
|
269 | *
|
270 | * parser (grammar) errors will also provide these additional members:
|
271 | *
|
272 | * {
|
273 | * expected: (array describing the set of expected tokens;
|
274 | * may be UNDEFINED when we cannot easily produce such a set)
|
275 | * state: (integer (or array when the table includes grammar collisions);
|
276 | * represents the current internal state of the parser kernel.
|
277 | * can, for example, be used to pass to the `collect_expected_token_set()`
|
278 | * API to obtain the expected token set)
|
279 | * action: (integer; represents the current internal action which will be executed)
|
280 | * new_state: (integer; represents the next/planned internal state, once the current
|
281 | * action has executed)
|
282 | * recoverable: (boolean: TRUE when the parser MAY have an error recovery rule
|
283 | * available for this particular error)
|
284 | * state_stack: (array: the current parser LALR/LR internal state stack; this can be used,
|
285 | * for instance, for advanced error analysis and reporting)
|
286 | * value_stack: (array: the current parser LALR/LR internal `$$` value stack; this can be used,
|
287 | * for instance, for advanced error analysis and reporting)
|
288 | * location_stack: (array: the current parser LALR/LR internal location stack; this can be used,
|
289 | * for instance, for advanced error analysis and reporting)
|
290 | * yy: (object: the current parser internal "shared state" `yy`
|
291 | * as is also available in the rule actions; this can be used,
|
292 | * for instance, for advanced error analysis and reporting)
|
293 | * lexer: (reference to the current lexer instance used by the parser)
|
294 | * parser: (reference to the current parser instance)
|
295 | * }
|
296 | *
|
297 | * while `this` will reference the current parser instance.
|
298 | *
|
299 | * When `parseError` is invoked by the lexer, `this` will still reference the related *parser*
|
300 | * instance, while these additional `hash` fields will also be provided:
|
301 | *
|
302 | * {
|
303 | * lexer: (reference to the current lexer instance which reported the error)
|
304 | * }
|
305 | *
|
306 | * When `parseError` is invoked by the parser due to a **JavaScript exception** being fired
|
307 | * from either the parser or lexer, `this` will still reference the related *parser*
|
308 | * instance, while these additional `hash` fields will also be provided:
|
309 | *
|
310 | * {
|
311 | * exception: (reference to the exception thrown)
|
312 | * }
|
313 | *
|
314 | * Please do note that in the latter situation, the `expected` field will be omitted as
|
315 | * this type of failure is assumed not to be due to *parse errors* but rather due to user
|
316 | * action code in either parser or lexer failing unexpectedly.
|
317 | *
|
318 | * ---
|
319 | *
|
320 | * You can specify parser options by setting / modifying the `.yy` object of your Parser instance.
|
321 | * These options are available:
|
322 | *
|
323 | * ### options which are global for all parser instances
|
324 | *
|
325 | * Parser.pre_parse: function(yy)
|
326 | * optional: you can specify a pre_parse() function in the chunk following
|
327 | * the grammar, i.e. after the last `%%`.
|
328 | * Parser.post_parse: function(yy, retval, parseInfo) { return retval; }
|
329 | * optional: you can specify a post_parse() function in the chunk following
|
330 | * the grammar, i.e. after the last `%%`. When it does not return any value,
|
331 | * the parser will return the original `retval`.
|
332 | *
|
333 | * ### options which can be set up per parser instance
|
334 | *
|
335 | * yy: {
|
336 | * pre_parse: function(yy)
|
337 | * optional: is invoked before the parse cycle starts (and before the first
|
338 | * invocation of `lex()`) but immediately after the invocation of
|
339 | * `parser.pre_parse()`).
|
340 | * post_parse: function(yy, retval, parseInfo) { return retval; }
|
341 | * optional: is invoked when the parse terminates due to success ('accept')
|
342 | * or failure (even when exceptions are thrown).
|
343 | * `retval` contains the return value to be produced by `Parser.parse()`;
|
344 | * this function can override the return value by returning another.
|
345 | * When it does not return any value, the parser will return the original
|
346 | * `retval`.
|
347 | * This function is invoked immediately before `parser.post_parse()`.
|
348 | *
|
349 | * parseError: function(str, hash, ExceptionClass)
|
350 | * optional: overrides the default `parseError` function.
|
351 | * quoteName: function(name),
|
352 | * optional: overrides the default `quoteName` function.
|
353 | * }
|
354 | *
|
355 | * parser.lexer.options: {
|
356 | * pre_lex: function()
|
357 | * optional: is invoked before the lexer is invoked to produce another token.
|
358 | * `this` refers to the Lexer object.
|
359 | * post_lex: function(token) { return token; }
|
360 | * optional: is invoked when the lexer has produced a token `token`;
|
361 | * this function can override the returned token value by returning another.
|
362 | * When it does not return any (truthy) value, the lexer will return
|
363 | * the original `token`.
|
364 | * `this` refers to the Lexer object.
|
365 | *
|
366 | * ranges: boolean
|
367 | * optional: `true` ==> token location info will include a .range[] member.
|
368 | * flex: boolean
|
369 | * optional: `true` ==> flex-like lexing behaviour where the rules are tested
|
370 | * exhaustively to find the longest match.
|
371 | * backtrack_lexer: boolean
|
372 | * optional: `true` ==> lexer regexes are tested in order and for invoked;
|
373 | * the lexer terminates the scan when a token is returned by the action code.
|
374 | * xregexp: boolean
|
375 | * optional: `true` ==> lexer rule regexes are "extended regex format" requiring the
|
376 | * `XRegExp` library. When this `%option` has not been specified at compile time, all lexer
|
377 | * rule regexes have been written as standard JavaScript RegExp expressions.
|
378 | * }
|
379 | */
|
380 |
|
381 |
|
382 |
|
383 | var parser = (function () {
|
384 |
|
385 |
|
386 | // See also:
|
387 | // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508
|
388 | // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility
|
389 | // with userland code which might access the derived class in a 'classic' way.
|
390 | function JisonParserError(msg, hash) {
|
391 | Object.defineProperty(this, 'name', {
|
392 | enumerable: false,
|
393 | writable: false,
|
394 | value: 'JisonParserError'
|
395 | });
|
396 |
|
397 | if (msg == null) msg = '???';
|
398 |
|
399 | Object.defineProperty(this, 'message', {
|
400 | enumerable: false,
|
401 | writable: true,
|
402 | value: msg
|
403 | });
|
404 |
|
405 | this.hash = hash;
|
406 |
|
407 | var stacktrace;
|
408 | if (hash && hash.exception instanceof Error) {
|
409 | var ex2 = hash.exception;
|
410 | this.message = ex2.message || msg;
|
411 | stacktrace = ex2.stack;
|
412 | }
|
413 | if (!stacktrace) {
|
414 | if (Error.hasOwnProperty('captureStackTrace')) { // V8/Chrome engine
|
415 | Error.captureStackTrace(this, this.constructor);
|
416 | } else {
|
417 | stacktrace = (new Error(msg)).stack;
|
418 | }
|
419 | }
|
420 | if (stacktrace) {
|
421 | Object.defineProperty(this, 'stack', {
|
422 | enumerable: false,
|
423 | writable: false,
|
424 | value: stacktrace
|
425 | });
|
426 | }
|
427 | }
|
428 |
|
429 | if (typeof Object.setPrototypeOf === 'function') {
|
430 | Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);
|
431 | } else {
|
432 | JisonParserError.prototype = Object.create(Error.prototype);
|
433 | }
|
434 | JisonParserError.prototype.constructor = JisonParserError;
|
435 | JisonParserError.prototype.name = 'JisonParserError';
|
436 |
|
437 |
|
438 |
|
439 |
|
440 | // helper: reconstruct the productions[] table
|
441 | function bp(s) {
|
442 | var rv = [];
|
443 | var p = s.pop;
|
444 | var r = s.rule;
|
445 | for (var i = 0, l = p.length; i < l; i++) {
|
446 | rv.push([
|
447 | p[i],
|
448 | r[i]
|
449 | ]);
|
450 | }
|
451 | return rv;
|
452 | }
|
453 |
|
454 |
|
455 |
|
456 | // helper: reconstruct the defaultActions[] table
|
457 | function bda(s) {
|
458 | var rv = {};
|
459 | var d = s.idx;
|
460 | var g = s.goto;
|
461 | for (var i = 0, l = d.length; i < l; i++) {
|
462 | var j = d[i];
|
463 | rv[j] = g[i];
|
464 | }
|
465 | return rv;
|
466 | }
|
467 |
|
468 |
|
469 |
|
470 | // helper: reconstruct the 'goto' table
|
471 | function bt(s) {
|
472 | var rv = [];
|
473 | var d = s.len;
|
474 | var y = s.symbol;
|
475 | var t = s.type;
|
476 | var a = s.state;
|
477 | var m = s.mode;
|
478 | var g = s.goto;
|
479 | for (var i = 0, l = d.length; i < l; i++) {
|
480 | var n = d[i];
|
481 | var q = {};
|
482 | for (var j = 0; j < n; j++) {
|
483 | var z = y.shift();
|
484 | switch (t.shift()) {
|
485 | case 2:
|
486 | q[z] = [
|
487 | m.shift(),
|
488 | g.shift()
|
489 | ];
|
490 | break;
|
491 |
|
492 | case 0:
|
493 | q[z] = a.shift();
|
494 | break;
|
495 |
|
496 | default:
|
497 | // type === 1: accept
|
498 | q[z] = [
|
499 | 3
|
500 | ];
|
501 | }
|
502 | }
|
503 | rv.push(q);
|
504 | }
|
505 | return rv;
|
506 | }
|
507 |
|
508 |
|
509 |
|
510 | // helper: runlength encoding with increment step: code, length: step (default step = 0)
|
511 | // `this` references an array
|
512 | function s(c, l, a) {
|
513 | a = a || 0;
|
514 | for (var i = 0; i < l; i++) {
|
515 | this.push(c);
|
516 | c += a;
|
517 | }
|
518 | }
|
519 |
|
520 | // helper: duplicate sequence from *relative* offset and length.
|
521 | // `this` references an array
|
522 | function c(i, l) {
|
523 | i = this.length - i;
|
524 | for (l += i; i < l; i++) {
|
525 | this.push(this[i]);
|
526 | }
|
527 | }
|
528 |
|
529 | // helper: unpack an array using helpers and data, all passed in an array argument 'a'.
|
530 | function u(a) {
|
531 | var rv = [];
|
532 | for (var i = 0, l = a.length; i < l; i++) {
|
533 | var e = a[i];
|
534 | // Is this entry a helper function?
|
535 | if (typeof e === 'function') {
|
536 | i++;
|
537 | e.apply(rv, a[i]);
|
538 | } else {
|
539 | rv.push(e);
|
540 | }
|
541 | }
|
542 | return rv;
|
543 | }
|
544 |
|
545 |
|
546 | var parser = {
|
547 | // Code Generator Information Report
|
548 | // ---------------------------------
|
549 | //
|
550 | // Options:
|
551 | //
|
552 | // default action mode: ............. ["classic","merge"]
|
553 | // test-compile action mode: ........ "parser:*,lexer:*"
|
554 | // try..catch: ...................... true
|
555 | // default resolve on conflict: ..... true
|
556 | // on-demand look-ahead: ............ false
|
557 | // error recovery token skip maximum: 3
|
558 | // yyerror in parse actions is: ..... NOT recoverable,
|
559 | // yyerror in lexer actions and other non-fatal lexer are:
|
560 | // .................................. NOT recoverable,
|
561 | // debug grammar/output: ............ false
|
562 | // has partial LR conflict upgrade: true
|
563 | // rudimentary token-stack support: false
|
564 | // parser table compression mode: ... 2
|
565 | // export debug tables: ............. false
|
566 | // export *all* tables: ............. false
|
567 | // module type: ..................... commonjs
|
568 | // parser engine type: .............. lalr
|
569 | // output main() in the module: ..... true
|
570 | // has user-specified main(): ....... false
|
571 | // has user-specified require()/import modules for main():
|
572 | // .................................. false
|
573 | // number of expected conflicts: .... 0
|
574 | //
|
575 | //
|
576 | // Parser Analysis flags:
|
577 | //
|
578 | // no significant actions (parser is a language matcher only):
|
579 | // .................................. false
|
580 | // uses yyleng: ..................... false
|
581 | // uses yylineno: ................... false
|
582 | // uses yytext: ..................... false
|
583 | // uses yylloc: ..................... false
|
584 | // uses ParseError API: ............. false
|
585 | // uses YYERROR: .................... false
|
586 | // uses YYRECOVERING: ............... false
|
587 | // uses YYERROK: .................... false
|
588 | // uses YYCLEARIN: .................. false
|
589 | // tracks rule values: .............. true
|
590 | // assigns rule values: ............. true
|
591 | // uses location tracking: .......... true
|
592 | // assigns location: ................ true
|
593 | // uses yystack: .................... false
|
594 | // uses yysstack: ................... false
|
595 | // uses yysp: ....................... true
|
596 | // uses yyrulelength: ............... false
|
597 | // uses yyMergeLocationInfo API: .... true
|
598 | // has error recovery: .............. false
|
599 | // has error reporting: ............. false
|
600 | //
|
601 | // --------- END OF REPORT -----------
|
602 |
|
603 | trace: function no_op_trace() { },
|
604 | JisonParserError: JisonParserError,
|
605 | yy: {},
|
606 | options: {
|
607 | type: "lalr",
|
608 | hasPartialLrUpgradeOnConflict: true,
|
609 | errorRecoveryTokenDiscardCount: 3,
|
610 | caseInsensitive: true
|
611 | },
|
612 | symbols_: {
|
613 | "$accept": 0,
|
614 | "$end": 1,
|
615 | "ADD": 6,
|
616 | "ANGLE": 13,
|
617 | "CALC": 3,
|
618 | "DIV": 9,
|
619 | "EOF": 1,
|
620 | "FREQ": 15,
|
621 | "FUNCTION": 11,
|
622 | "LENGTH": 12,
|
623 | "LPAREN": 4,
|
624 | "MUL": 8,
|
625 | "NUMBER": 10,
|
626 | "PERCENTAGE": 17,
|
627 | "RES": 16,
|
628 | "RPAREN": 5,
|
629 | "SUB": 7,
|
630 | "TIME": 14,
|
631 | "UNKNOWN": 18,
|
632 | "css_value": 23,
|
633 | "error": 2,
|
634 | "expression": 19,
|
635 | "function": 22,
|
636 | "math_expression": 20,
|
637 | "value": 21
|
638 | },
|
639 | terminals_: {
|
640 | 1: "EOF",
|
641 | 2: "error",
|
642 | 3: "CALC",
|
643 | 4: "LPAREN",
|
644 | 5: "RPAREN",
|
645 | 6: "ADD",
|
646 | 7: "SUB",
|
647 | 8: "MUL",
|
648 | 9: "DIV",
|
649 | 10: "NUMBER",
|
650 | 11: "FUNCTION",
|
651 | 12: "LENGTH",
|
652 | 13: "ANGLE",
|
653 | 14: "TIME",
|
654 | 15: "FREQ",
|
655 | 16: "RES",
|
656 | 17: "PERCENTAGE",
|
657 | 18: "UNKNOWN"
|
658 | },
|
659 | TERROR: 2,
|
660 | EOF: 1,
|
661 |
|
662 | // internals: defined here so the object *structure* doesn't get modified by parse() et al,
|
663 | // thus helping JIT compilers like Chrome V8.
|
664 | originalQuoteName: null,
|
665 | originalParseError: null,
|
666 | cleanupAfterParse: null,
|
667 | constructParseErrorInfo: null,
|
668 | yyMergeLocationInfo: null,
|
669 |
|
670 | __reentrant_call_depth: 0, // INTERNAL USE ONLY
|
671 | __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup
|
672 | __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup
|
673 |
|
674 | // APIs which will be set up depending on user action code analysis:
|
675 | //yyRecovering: 0,
|
676 | //yyErrOk: 0,
|
677 | //yyClearIn: 0,
|
678 |
|
679 | // Helper APIs
|
680 | // -----------
|
681 |
|
682 | // Helper function which can be overridden by user code later on: put suitable quotes around
|
683 | // literal IDs in a description string.
|
684 | quoteName: function parser_quoteName(id_str) {
|
685 | return '"' + id_str + '"';
|
686 | },
|
687 |
|
688 | // Return the name of the given symbol (terminal or non-terminal) as a string, when available.
|
689 | //
|
690 | // Return NULL when the symbol is unknown to the parser.
|
691 | getSymbolName: function parser_getSymbolName(symbol) {
|
692 | if (this.terminals_[symbol]) {
|
693 | return this.terminals_[symbol];
|
694 | }
|
695 |
|
696 | // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up.
|
697 | //
|
698 | // An example of this may be where a rule's action code contains a call like this:
|
699 | //
|
700 | // parser.getSymbolName(#$)
|
701 | //
|
702 | // to obtain a human-readable name of the current grammar rule.
|
703 | var s = this.symbols_;
|
704 | for (var key in s) {
|
705 | if (s[key] === symbol) {
|
706 | return key;
|
707 | }
|
708 | }
|
709 | return null;
|
710 | },
|
711 |
|
712 | // Return a more-or-less human-readable description of the given symbol, when available,
|
713 | // or the symbol itself, serving as its own 'description' for lack of something better to serve up.
|
714 | //
|
715 | // Return NULL when the symbol is unknown to the parser.
|
716 | describeSymbol: function parser_describeSymbol(symbol) {
|
717 | if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) {
|
718 | return this.terminal_descriptions_[symbol];
|
719 | }
|
720 | else if (symbol === this.EOF) {
|
721 | return 'end of input';
|
722 | }
|
723 | var id = this.getSymbolName(symbol);
|
724 | if (id) {
|
725 | return this.quoteName(id);
|
726 | }
|
727 | return null;
|
728 | },
|
729 |
|
730 | // Produce a (more or less) human-readable list of expected tokens at the point of failure.
|
731 | //
|
732 | // The produced list may contain token or token set descriptions instead of the tokens
|
733 | // themselves to help turning this output into something that easier to read by humans
|
734 | // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*,
|
735 | // expected terminals and nonterminals is produced.
|
736 | //
|
737 | // The returned list (array) will not contain any duplicate entries.
|
738 | collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) {
|
739 | var TERROR = this.TERROR;
|
740 | var tokenset = [];
|
741 | var check = {};
|
742 | // Has this (error?) state been outfitted with a custom expectations description text for human consumption?
|
743 | // If so, use that one instead of the less palatable token set.
|
744 | if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) {
|
745 | return [
|
746 | this.state_descriptions_[state]
|
747 | ];
|
748 | }
|
749 | for (var p in this.table[state]) {
|
750 | p = +p;
|
751 | if (p !== TERROR) {
|
752 | var d = do_not_describe ? p : this.describeSymbol(p);
|
753 | if (d && !check[d]) {
|
754 | tokenset.push(d);
|
755 | check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries.
|
756 | }
|
757 | }
|
758 | }
|
759 | return tokenset;
|
760 | },
|
761 | productions_: bp({
|
762 | pop: u([
|
763 | 19,
|
764 | s,
|
765 | [20, 11],
|
766 | 21,
|
767 | 22,
|
768 | s,
|
769 | [23, 7]
|
770 | ]),
|
771 | rule: u([
|
772 | 2,
|
773 | 4,
|
774 | s,
|
775 | [3, 4],
|
776 | 2,
|
777 | 2,
|
778 | 3,
|
779 | s,
|
780 | [1, 12]
|
781 | ])
|
782 | }),
|
783 | performAction: function parser__PerformAction(yyloc, yystate /* action[1] */, yysp, yyvstack, yylstack) {
|
784 |
|
785 | /* this == yyval */
|
786 |
|
787 | // the JS engine itself can go and remove these statements when `yy` turns out to be unused in any action code!
|
788 | var yy = this.yy;
|
789 | var yyparser = yy.parser;
|
790 | var yylexer = yy.lexer;
|
791 |
|
792 |
|
793 |
|
794 | switch (yystate) {
|
795 | case 0:
|
796 | /*! Production:: $accept : expression $end */
|
797 |
|
798 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,-,-,LT,LA,-,-):
|
799 | this.$ = yyvstack[yysp - 1];
|
800 | this._$ = yylstack[yysp - 1];
|
801 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,-,-,LT,LA,-,-)
|
802 | break;
|
803 |
|
804 | case 1:
|
805 | /*! Production:: expression : math_expression EOF */
|
806 |
|
807 | // default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-):
|
808 | this.$ = yyvstack[yysp - 1];
|
809 | this._$ = yyparser.yyMergeLocationInfo(yysp - 1, yysp);
|
810 | // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-)
|
811 |
|
812 |
|
813 | return yyvstack[yysp - 1];
|
814 | break;
|
815 |
|
816 | case 2:
|
817 | /*! Production:: math_expression : CALC LPAREN math_expression RPAREN */
|
818 |
|
819 | // default action (generated by JISON mode classic/merge :: 4,VT,VA,VU,-,LT,LA,-,-):
|
820 | this._$ = yyparser.yyMergeLocationInfo(yysp - 3, yysp);
|
821 | // END of default action (generated by JISON mode classic/merge :: 4,VT,VA,VU,-,LT,LA,-,-)
|
822 |
|
823 |
|
824 | this.$ = yyvstack[yysp - 1];
|
825 | this.$.source.start = { index: yylstack[yysp - 3].range[0] };
|
826 | this.$.source.end = { index: yylstack[yysp].range[1] };
|
827 | break;
|
828 |
|
829 | case 3:
|
830 | /*! Production:: math_expression : math_expression ADD math_expression */
|
831 | case 4:
|
832 | /*! Production:: math_expression : math_expression SUB math_expression */
|
833 | case 5:
|
834 | /*! Production:: math_expression : math_expression MUL math_expression */
|
835 | case 6:
|
836 | /*! Production:: math_expression : math_expression DIV math_expression */
|
837 |
|
838 | // default action (generated by JISON mode classic/merge :: 3,VT,VA,VU,-,LT,LA,-,-):
|
839 | this._$ = yyparser.yyMergeLocationInfo(yysp - 2, yysp);
|
840 | // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,VU,-,LT,LA,-,-)
|
841 |
|
842 |
|
843 | this.$ = {
|
844 | type: 'MathExpression', operator: yyvstack[yysp - 1], left: yyvstack[yysp - 2], right: yyvstack[yysp],
|
845 | source: {
|
846 | start: yyvstack[yysp - 2].source.start, end: yyvstack[yysp].source.end,
|
847 | operator: { start: { index: yylstack[yysp - 1].range[0] }, end: { index: yylstack[yysp - 1].range[1] } }
|
848 | }
|
849 | };
|
850 | break;
|
851 |
|
852 | case 7:
|
853 | /*! Production:: math_expression : SUB math_expression */
|
854 |
|
855 | // default action (generated by JISON mode classic/merge :: 2,VT,VA,VU,-,LT,LA,-,-):
|
856 | this._$ = yyparser.yyMergeLocationInfo(yysp - 1, yysp);
|
857 | // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,VU,-,LT,LA,-,-)
|
858 |
|
859 |
|
860 | if (yylstack[yysp - 1].range[1] !== yyvstack[yysp].source.start.index) {
|
861 | throw new Error('Unexpected spaces was found between sign and value');
|
862 | }
|
863 | if (typeof yyvstack[yysp].value !== 'number') {
|
864 | throw new Error('Unexpected sign');
|
865 | }
|
866 | if (yyvstack[yysp].sign) {
|
867 | throw new Error('Unexpected continuous sign');
|
868 | }
|
869 | this.$ = yyvstack[yysp];
|
870 | this.$.sign = '-'
|
871 | this.$.value = -yyvstack[yysp].value;
|
872 | this.$.source.start.index = yylstack[yysp - 1].range[0];
|
873 | break;
|
874 |
|
875 | case 8:
|
876 | /*! Production:: math_expression : ADD math_expression */
|
877 |
|
878 | // default action (generated by JISON mode classic/merge :: 2,VT,VA,VU,-,LT,LA,-,-):
|
879 | this._$ = yyparser.yyMergeLocationInfo(yysp - 1, yysp);
|
880 | // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,VU,-,LT,LA,-,-)
|
881 |
|
882 |
|
883 | if (yylstack[yysp - 1].range[1] !== yyvstack[yysp].source.start.index) {
|
884 | throw new Error('Unexpected spaces was found between sign and value');
|
885 | }
|
886 | if (typeof yyvstack[yysp].value !== 'number') {
|
887 | throw new Error('Unexpected sign');
|
888 | }
|
889 | if (yyvstack[yysp].sign) {
|
890 | throw new Error('Unexpected continuous sign');
|
891 | }
|
892 | this.$ = yyvstack[yysp];
|
893 | this.$.sign = '+'
|
894 | this.$.source.start.index = yylstack[yysp - 1].range[0];
|
895 | break;
|
896 |
|
897 | case 9:
|
898 | /*! Production:: math_expression : LPAREN math_expression RPAREN */
|
899 |
|
900 | // default action (generated by JISON mode classic/merge :: 3,VT,VA,VU,-,LT,LA,-,-):
|
901 | this._$ = yyparser.yyMergeLocationInfo(yysp - 2, yysp);
|
902 | // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,VU,-,LT,LA,-,-)
|
903 |
|
904 |
|
905 | this.$ = yyvstack[yysp - 1];
|
906 | this.$.source.start = { index: yylstack[yysp - 2].range[0] };
|
907 | this.$.source.end = { index: yylstack[yysp].range[1] };
|
908 | break;
|
909 |
|
910 | case 10:
|
911 | /*! Production:: math_expression : function */
|
912 | case 11:
|
913 | /*! Production:: math_expression : css_value */
|
914 | case 12:
|
915 | /*! Production:: math_expression : value */
|
916 |
|
917 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
918 | this._$ = yylstack[yysp];
|
919 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
920 |
|
921 |
|
922 | this.$ = yyvstack[yysp];
|
923 | break;
|
924 |
|
925 | case 13:
|
926 | /*! Production:: value : NUMBER */
|
927 |
|
928 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
929 | this._$ = yylstack[yysp];
|
930 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
931 |
|
932 |
|
933 | this.$ = { type: 'Value', value: parseFloat(yyvstack[yysp]), source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
934 | break;
|
935 |
|
936 | case 14:
|
937 | /*! Production:: function : FUNCTION */
|
938 |
|
939 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
940 | this._$ = yylstack[yysp];
|
941 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
942 |
|
943 |
|
944 | this.$ = { type: 'Function', value: yyvstack[yysp], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
945 | break;
|
946 |
|
947 | case 15:
|
948 | /*! Production:: css_value : LENGTH */
|
949 |
|
950 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
951 | this._$ = yylstack[yysp];
|
952 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
953 |
|
954 |
|
955 | this.$ = { type: 'LengthValue', value: parseFloat(yyvstack[yysp]), unit: /[a-z]+/i.exec(yyvstack[yysp])[0], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
956 | break;
|
957 |
|
958 | case 16:
|
959 | /*! Production:: css_value : ANGLE */
|
960 |
|
961 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
962 | this._$ = yylstack[yysp];
|
963 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
964 |
|
965 |
|
966 | this.$ = { type: 'AngleValue', value: parseFloat(yyvstack[yysp]), unit: /[a-z]+/i.exec(yyvstack[yysp])[0], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
967 | break;
|
968 |
|
969 | case 17:
|
970 | /*! Production:: css_value : TIME */
|
971 |
|
972 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
973 | this._$ = yylstack[yysp];
|
974 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
975 |
|
976 |
|
977 | this.$ = { type: 'TimeValue', value: parseFloat(yyvstack[yysp]), unit: /[a-z]+/i.exec(yyvstack[yysp])[0], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
978 | break;
|
979 |
|
980 | case 18:
|
981 | /*! Production:: css_value : FREQ */
|
982 |
|
983 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
984 | this._$ = yylstack[yysp];
|
985 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
986 |
|
987 |
|
988 | this.$ = { type: 'FrequencyValue', value: parseFloat(yyvstack[yysp]), unit: /[a-z]+/i.exec(yyvstack[yysp])[0], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
989 | break;
|
990 |
|
991 | case 19:
|
992 | /*! Production:: css_value : RES */
|
993 |
|
994 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
995 | this._$ = yylstack[yysp];
|
996 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
997 |
|
998 |
|
999 | this.$ = { type: 'ResolutionValue', value: parseFloat(yyvstack[yysp]), unit: /[a-z]+/i.exec(yyvstack[yysp])[0], source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
1000 | break;
|
1001 |
|
1002 | case 20:
|
1003 | /*! Production:: css_value : PERCENTAGE */
|
1004 |
|
1005 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
1006 | this._$ = yylstack[yysp];
|
1007 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
1008 |
|
1009 |
|
1010 | this.$ = { type: 'PercentageValue', value: parseFloat(yyvstack[yysp]), unit: '%', source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
1011 | break;
|
1012 |
|
1013 | case 21:
|
1014 | /*! Production:: css_value : UNKNOWN */
|
1015 |
|
1016 | // default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-):
|
1017 | this._$ = yylstack[yysp];
|
1018 | // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-)
|
1019 |
|
1020 |
|
1021 | this.$ = { type: 'UnknownValue', value: yyvstack[yysp], unit: '', source: { start: { index: yylstack[yysp].range[0] }, end: { index: yylstack[yysp].range[1] } } };
|
1022 | break;
|
1023 |
|
1024 | }
|
1025 | },
|
1026 | table: bt({
|
1027 | len: u([
|
1028 | 18,
|
1029 | 1,
|
1030 | 5,
|
1031 | 1,
|
1032 | s,
|
1033 | [17, 3],
|
1034 | s,
|
1035 | [0, 13],
|
1036 | s,
|
1037 | [17, 5],
|
1038 | 0,
|
1039 | 0,
|
1040 | 5,
|
1041 | 6,
|
1042 | 6,
|
1043 | c,
|
1044 | [5, 3],
|
1045 | 0,
|
1046 | 0
|
1047 | ]),
|
1048 | symbol: u([
|
1049 | 3,
|
1050 | 4,
|
1051 | 6,
|
1052 | 7,
|
1053 | s,
|
1054 | [10, 14, 1],
|
1055 | 1,
|
1056 | 1,
|
1057 | s,
|
1058 | [6, 4, 1],
|
1059 | 4,
|
1060 | c,
|
1061 | [25, 13],
|
1062 | c,
|
1063 | [24, 4],
|
1064 | c,
|
1065 | [17, 119],
|
1066 | s,
|
1067 | [5, 5, 1],
|
1068 | 1,
|
1069 | c,
|
1070 | [6, 11],
|
1071 | c,
|
1072 | [5, 5]
|
1073 | ]),
|
1074 | type: u([
|
1075 | s,
|
1076 | [2, 13],
|
1077 | s,
|
1078 | [0, 5],
|
1079 | 1,
|
1080 | s,
|
1081 | [2, 19],
|
1082 | s,
|
1083 | [0, 4],
|
1084 | c,
|
1085 | [17, 132],
|
1086 | s,
|
1087 | [2, 9]
|
1088 | ]),
|
1089 | state: u([
|
1090 | 1,
|
1091 | 2,
|
1092 | 9,
|
1093 | 7,
|
1094 | 8,
|
1095 | 25,
|
1096 | c,
|
1097 | [4, 3],
|
1098 | 26,
|
1099 | c,
|
1100 | [4, 3],
|
1101 | 27,
|
1102 | c,
|
1103 | [4, 3],
|
1104 | 28,
|
1105 | c,
|
1106 | [4, 3],
|
1107 | 29,
|
1108 | c,
|
1109 | [4, 3],
|
1110 | 30,
|
1111 | c,
|
1112 | [4, 3],
|
1113 | 31,
|
1114 | c,
|
1115 | [4, 3],
|
1116 | 32,
|
1117 | c,
|
1118 | [4, 3]
|
1119 | ]),
|
1120 | mode: u([
|
1121 | s,
|
1122 | [1, 128],
|
1123 | s,
|
1124 | [2, 4],
|
1125 | c,
|
1126 | [6, 8],
|
1127 | s,
|
1128 | [1, 5]
|
1129 | ]),
|
1130 | goto: u([
|
1131 | 3,
|
1132 | 6,
|
1133 | 5,
|
1134 | 4,
|
1135 | 18,
|
1136 | s,
|
1137 | [10, 8, 1],
|
1138 | s,
|
1139 | [19, 6, 1],
|
1140 | c,
|
1141 | [19, 13],
|
1142 | c,
|
1143 | [13, 91],
|
1144 | 33,
|
1145 | c,
|
1146 | [110, 4],
|
1147 | s,
|
1148 | [3, 4],
|
1149 | 22,
|
1150 | 23,
|
1151 | s,
|
1152 | [4, 4],
|
1153 | 22,
|
1154 | 23,
|
1155 | 34,
|
1156 | c,
|
1157 | [17, 4]
|
1158 | ])
|
1159 | }),
|
1160 | defaultActions: bda({
|
1161 | idx: u([
|
1162 | s,
|
1163 | [7, 13, 1],
|
1164 | 25,
|
1165 | 26,
|
1166 | 30,
|
1167 | 31,
|
1168 | 33,
|
1169 | 34
|
1170 | ]),
|
1171 | goto: u([
|
1172 | 10,
|
1173 | 11,
|
1174 | 12,
|
1175 | s,
|
1176 | [14, 8, 1],
|
1177 | 13,
|
1178 | 1,
|
1179 | 7,
|
1180 | 8,
|
1181 | 5,
|
1182 | 6,
|
1183 | 9,
|
1184 | 2
|
1185 | ])
|
1186 | }),
|
1187 | parseError: function parseError(str, hash, ExceptionClass) {
|
1188 | if (hash.recoverable) {
|
1189 | if (typeof this.trace === 'function') {
|
1190 | this.trace(str);
|
1191 | }
|
1192 | hash.destroy(); // destroy... well, *almost*!
|
1193 | } else {
|
1194 | if (typeof this.trace === 'function') {
|
1195 | this.trace(str);
|
1196 | }
|
1197 | if (!ExceptionClass) {
|
1198 | ExceptionClass = this.JisonParserError;
|
1199 | }
|
1200 | throw new ExceptionClass(str, hash);
|
1201 | }
|
1202 | },
|
1203 | parse: function parse(input) {
|
1204 | var self = this;
|
1205 | var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)
|
1206 | var sstack = new Array(128); // state stack: stores states (column storage)
|
1207 |
|
1208 | var vstack = new Array(128); // semantic value stack
|
1209 | var lstack = new Array(128); // location stack
|
1210 | var table = this.table;
|
1211 | var sp = 0; // 'stack pointer': index into the stacks
|
1212 | var yyloc;
|
1213 |
|
1214 |
|
1215 |
|
1216 |
|
1217 | var symbol = 0;
|
1218 |
|
1219 |
|
1220 |
|
1221 | var TERROR = this.TERROR;
|
1222 | var EOF = this.EOF;
|
1223 | var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;
|
1224 | var NO_ACTION = [0, 35 /* === table.length :: ensures that anyone using this new state will fail dramatically! */];
|
1225 |
|
1226 | var lexer;
|
1227 | if (this.__lexer__) {
|
1228 | lexer = this.__lexer__;
|
1229 | } else {
|
1230 | lexer = this.__lexer__ = Object.create(this.lexer);
|
1231 | }
|
1232 |
|
1233 | var sharedState_yy = {
|
1234 | parseError: undefined,
|
1235 | quoteName: undefined,
|
1236 | lexer: undefined,
|
1237 | parser: undefined,
|
1238 | pre_parse: undefined,
|
1239 | post_parse: undefined,
|
1240 | pre_lex: undefined,
|
1241 | post_lex: undefined // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!
|
1242 | };
|
1243 |
|
1244 | var ASSERT;
|
1245 | if (typeof assert !== 'function') {
|
1246 | ASSERT = function JisonAssert(cond, msg) {
|
1247 | if (!cond) {
|
1248 | throw new Error('assertion failed: ' + (msg || '***'));
|
1249 | }
|
1250 | };
|
1251 | } else {
|
1252 | ASSERT = assert;
|
1253 | }
|
1254 |
|
1255 | this.yyGetSharedState = function yyGetSharedState() {
|
1256 | return sharedState_yy;
|
1257 | };
|
1258 |
|
1259 |
|
1260 | // shallow clone objects, straight copy of simple `src` values
|
1261 | // e.g. `lexer.yytext` MAY be a complex value object,
|
1262 | // rather than a simple string/value.
|
1263 | function shallow_copy(src) {
|
1264 | if (typeof src === 'object') {
|
1265 | var dst = {};
|
1266 | for (var k in src) {
|
1267 | if (Object.prototype.hasOwnProperty.call(src, k)) {
|
1268 | dst[k] = src[k];
|
1269 | }
|
1270 | }
|
1271 | return dst;
|
1272 | }
|
1273 | return src;
|
1274 | }
|
1275 | function shallow_copy_noclobber(dst, src) {
|
1276 | for (var k in src) {
|
1277 | if (typeof dst[k] === 'undefined' && Object.prototype.hasOwnProperty.call(src, k)) {
|
1278 | dst[k] = src[k];
|
1279 | }
|
1280 | }
|
1281 | }
|
1282 | function copy_yylloc(loc) {
|
1283 | var rv = shallow_copy(loc);
|
1284 | if (rv && rv.range) {
|
1285 | rv.range = rv.range.slice(0);
|
1286 | }
|
1287 | return rv;
|
1288 | }
|
1289 |
|
1290 | // copy state
|
1291 | shallow_copy_noclobber(sharedState_yy, this.yy);
|
1292 |
|
1293 | sharedState_yy.lexer = lexer;
|
1294 | sharedState_yy.parser = this;
|
1295 |
|
1296 |
|
1297 |
|
1298 |
|
1299 |
|
1300 |
|
1301 | // Does the shared state override the default `parseError` that already comes with this instance?
|
1302 | if (typeof sharedState_yy.parseError === 'function') {
|
1303 | this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {
|
1304 | if (!ExceptionClass) {
|
1305 | ExceptionClass = this.JisonParserError;
|
1306 | }
|
1307 | return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);
|
1308 | };
|
1309 | } else {
|
1310 | this.parseError = this.originalParseError;
|
1311 | }
|
1312 |
|
1313 | // Does the shared state override the default `quoteName` that already comes with this instance?
|
1314 | if (typeof sharedState_yy.quoteName === 'function') {
|
1315 | this.quoteName = function quoteNameAlt(id_str) {
|
1316 | return sharedState_yy.quoteName.call(this, id_str);
|
1317 | };
|
1318 | } else {
|
1319 | this.quoteName = this.originalQuoteName;
|
1320 | }
|
1321 |
|
1322 | // set up the cleanup function; make it an API so that external code can re-use this one in case of
|
1323 | // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which
|
1324 | // case this parse() API method doesn't come with a `finally { ... }` block any more!
|
1325 | //
|
1326 | // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,
|
1327 | // or else your `sharedState`, etc. references will be *wrong*!
|
1328 | this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {
|
1329 | var rv;
|
1330 |
|
1331 | if (invoke_post_methods) {
|
1332 | var hash;
|
1333 |
|
1334 | if (sharedState_yy.post_parse || this.post_parse) {
|
1335 | // create an error hash info instance: we re-use this API in a **non-error situation**
|
1336 | // as this one delivers all parser internals ready for access by userland code.
|
1337 | hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);
|
1338 | }
|
1339 |
|
1340 | if (sharedState_yy.post_parse) {
|
1341 | rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);
|
1342 | if (typeof rv !== 'undefined') resultValue = rv;
|
1343 | }
|
1344 | if (this.post_parse) {
|
1345 | rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);
|
1346 | if (typeof rv !== 'undefined') resultValue = rv;
|
1347 | }
|
1348 |
|
1349 | // cleanup:
|
1350 | if (hash && hash.destroy) {
|
1351 | hash.destroy();
|
1352 | }
|
1353 | }
|
1354 |
|
1355 | if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.
|
1356 |
|
1357 | // clean up the lingering lexer structures as well:
|
1358 | if (lexer.cleanupAfterLex) {
|
1359 | lexer.cleanupAfterLex(do_not_nuke_errorinfos);
|
1360 | }
|
1361 |
|
1362 | // prevent lingering circular references from causing memory leaks:
|
1363 | if (sharedState_yy) {
|
1364 | sharedState_yy.lexer = undefined;
|
1365 | sharedState_yy.parser = undefined;
|
1366 | if (lexer.yy === sharedState_yy) {
|
1367 | lexer.yy = undefined;
|
1368 | }
|
1369 | }
|
1370 | sharedState_yy = undefined;
|
1371 | this.parseError = this.originalParseError;
|
1372 | this.quoteName = this.originalQuoteName;
|
1373 |
|
1374 | // nuke the vstack[] array at least as that one will still reference obsoleted user values.
|
1375 | // To be safe, we nuke the other internal stack columns as well...
|
1376 | stack.length = 0; // fastest way to nuke an array without overly bothering the GC
|
1377 | sstack.length = 0;
|
1378 | lstack.length = 0;
|
1379 | vstack.length = 0;
|
1380 | sp = 0;
|
1381 |
|
1382 | // nuke the error hash info instances created during this run.
|
1383 | // Userland code must COPY any data/references
|
1384 | // in the error hash instance(s) it is more permanently interested in.
|
1385 | if (!do_not_nuke_errorinfos) {
|
1386 | for (var i = this.__error_infos.length - 1; i >= 0; i--) {
|
1387 | var el = this.__error_infos[i];
|
1388 | if (el && typeof el.destroy === 'function') {
|
1389 | el.destroy();
|
1390 | }
|
1391 | }
|
1392 | this.__error_infos.length = 0;
|
1393 |
|
1394 |
|
1395 | }
|
1396 |
|
1397 | return resultValue;
|
1398 | };
|
1399 |
|
1400 | // merge yylloc info into a new yylloc instance.
|
1401 | //
|
1402 | // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.
|
1403 | //
|
1404 | // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which
|
1405 | // case these override the corresponding first/last indexes.
|
1406 | //
|
1407 | // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search
|
1408 | // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)
|
1409 | // yylloc info.
|
1410 | //
|
1411 | // Note: epsilon rule's yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.
|
1412 | this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {
|
1413 | var i1 = first_index | 0,
|
1414 | i2 = last_index | 0;
|
1415 | var l1 = first_yylloc,
|
1416 | l2 = last_yylloc;
|
1417 | var rv;
|
1418 |
|
1419 | // rules:
|
1420 | // - first/last yylloc entries override first/last indexes
|
1421 |
|
1422 | if (!l1) {
|
1423 | if (first_index != null) {
|
1424 | for (var i = i1; i <= i2; i++) {
|
1425 | l1 = lstack[i];
|
1426 | if (l1) {
|
1427 | break;
|
1428 | }
|
1429 | }
|
1430 | }
|
1431 | }
|
1432 |
|
1433 | if (!l2) {
|
1434 | if (last_index != null) {
|
1435 | for (var i = i2; i >= i1; i--) {
|
1436 | l2 = lstack[i];
|
1437 | if (l2) {
|
1438 | break;
|
1439 | }
|
1440 | }
|
1441 | }
|
1442 | }
|
1443 |
|
1444 | // - detect if an epsilon rule is being processed and act accordingly:
|
1445 | if (!l1 && first_index == null) {
|
1446 | // epsilon rule span merger. With optional look-ahead in l2.
|
1447 | if (!dont_look_back) {
|
1448 | for (var i = (i1 || sp) - 1; i >= 0; i--) {
|
1449 | l1 = lstack[i];
|
1450 | if (l1) {
|
1451 | break;
|
1452 | }
|
1453 | }
|
1454 | }
|
1455 | if (!l1) {
|
1456 | if (!l2) {
|
1457 | // when we still don't have any valid yylloc info, we're looking at an epsilon rule
|
1458 | // without look-ahead and no preceding terms and/or `dont_look_back` set:
|
1459 | // in that case we ca do nothing but return NULL/UNDEFINED:
|
1460 | return undefined;
|
1461 | } else {
|
1462 | // shallow-copy L2: after all, we MAY be looking
|
1463 | // at unconventional yylloc info objects...
|
1464 | rv = shallow_copy(l2);
|
1465 | if (rv.range) {
|
1466 | // shallow copy the yylloc ranges info to prevent us from modifying the original arguments' entries:
|
1467 | rv.range = rv.range.slice(0);
|
1468 | }
|
1469 | return rv;
|
1470 | }
|
1471 | } else {
|
1472 | // shallow-copy L1, then adjust first col/row 1 column past the end.
|
1473 | rv = shallow_copy(l1);
|
1474 | rv.first_line = rv.last_line;
|
1475 | rv.first_column = rv.last_column;
|
1476 | if (rv.range) {
|
1477 | // shallow copy the yylloc ranges info to prevent us from modifying the original arguments' entries:
|
1478 | rv.range = rv.range.slice(0);
|
1479 | rv.range[0] = rv.range[1];
|
1480 | }
|
1481 |
|
1482 | if (l2) {
|
1483 | // shallow-mixin L2, then adjust last col/row accordingly.
|
1484 | shallow_copy_noclobber(rv, l2);
|
1485 | rv.last_line = l2.last_line;
|
1486 | rv.last_column = l2.last_column;
|
1487 | if (rv.range && l2.range) {
|
1488 | rv.range[1] = l2.range[1];
|
1489 | }
|
1490 | }
|
1491 | return rv;
|
1492 | }
|
1493 | }
|
1494 |
|
1495 | if (!l1) {
|
1496 | l1 = l2;
|
1497 | l2 = null;
|
1498 | }
|
1499 | if (!l1) {
|
1500 | return undefined;
|
1501 | }
|
1502 |
|
1503 | // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking
|
1504 | // at unconventional yylloc info objects...
|
1505 | rv = shallow_copy(l1);
|
1506 |
|
1507 | // first_line: ...,
|
1508 | // first_column: ...,
|
1509 | // last_line: ...,
|
1510 | // last_column: ...,
|
1511 | if (rv.range) {
|
1512 | // shallow copy the yylloc ranges info to prevent us from modifying the original arguments' entries:
|
1513 | rv.range = rv.range.slice(0);
|
1514 | }
|
1515 |
|
1516 | if (l2) {
|
1517 | shallow_copy_noclobber(rv, l2);
|
1518 | rv.last_line = l2.last_line;
|
1519 | rv.last_column = l2.last_column;
|
1520 | if (rv.range && l2.range) {
|
1521 | rv.range[1] = l2.range[1];
|
1522 | }
|
1523 | }
|
1524 |
|
1525 | return rv;
|
1526 | };
|
1527 |
|
1528 | // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,
|
1529 | // or else your `lexer`, `sharedState`, etc. references will be *wrong*!
|
1530 | this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {
|
1531 | var pei = {
|
1532 | errStr: msg,
|
1533 | exception: ex,
|
1534 | text: lexer.match,
|
1535 | value: lexer.yytext,
|
1536 | token: this.describeSymbol(symbol) || symbol,
|
1537 | token_id: symbol,
|
1538 | line: lexer.yylineno,
|
1539 | loc: copy_yylloc(lexer.yylloc),
|
1540 | expected: expected,
|
1541 | recoverable: recoverable,
|
1542 | state: state,
|
1543 | action: action,
|
1544 | new_state: newState,
|
1545 | symbol_stack: stack,
|
1546 | state_stack: sstack,
|
1547 | value_stack: vstack,
|
1548 | location_stack: lstack,
|
1549 | stack_pointer: sp,
|
1550 | yy: sharedState_yy,
|
1551 | lexer: lexer,
|
1552 | parser: this,
|
1553 |
|
1554 | // and make sure the error info doesn't stay due to potential
|
1555 | // ref cycle via userland code manipulations.
|
1556 | // These would otherwise all be memory leak opportunities!
|
1557 | //
|
1558 | // Note that only array and object references are nuked as those
|
1559 | // constitute the set of elements which can produce a cyclic ref.
|
1560 | // The rest of the members is kept intact as they are harmless.
|
1561 | destroy: function destructParseErrorInfo() {
|
1562 | // remove cyclic references added to error info:
|
1563 | // info.yy = null;
|
1564 | // info.lexer = null;
|
1565 | // info.value = null;
|
1566 | // info.value_stack = null;
|
1567 | // ...
|
1568 | var rec = !!this.recoverable;
|
1569 | for (var key in this) {
|
1570 | if (this.hasOwnProperty(key) && typeof key === 'object') {
|
1571 | this[key] = undefined;
|
1572 | }
|
1573 | }
|
1574 | this.recoverable = rec;
|
1575 | }
|
1576 | };
|
1577 | // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!
|
1578 | this.__error_infos.push(pei);
|
1579 | return pei;
|
1580 | };
|
1581 |
|
1582 |
|
1583 |
|
1584 |
|
1585 |
|
1586 |
|
1587 |
|
1588 |
|
1589 |
|
1590 |
|
1591 |
|
1592 |
|
1593 |
|
1594 | function getNonTerminalFromCode(symbol) {
|
1595 | var tokenName = self.getSymbolName(symbol);
|
1596 | if (!tokenName) {
|
1597 | tokenName = symbol;
|
1598 | }
|
1599 | return tokenName;
|
1600 | }
|
1601 |
|
1602 |
|
1603 | function stdLex() {
|
1604 | var token = lexer.lex();
|
1605 | // if token isn't its numeric value, convert
|
1606 | if (typeof token !== 'number') {
|
1607 | token = self.symbols_[token] || token;
|
1608 | }
|
1609 |
|
1610 | return token || EOF;
|
1611 | }
|
1612 |
|
1613 | function fastLex() {
|
1614 | var token = lexer.fastLex();
|
1615 | // if token isn't its numeric value, convert
|
1616 | if (typeof token !== 'number') {
|
1617 | token = self.symbols_[token] || token;
|
1618 | }
|
1619 |
|
1620 | return token || EOF;
|
1621 | }
|
1622 |
|
1623 | var lex = stdLex;
|
1624 |
|
1625 |
|
1626 | var state, action, r, t;
|
1627 | var yyval = {
|
1628 | $: true,
|
1629 | _$: undefined,
|
1630 | yy: sharedState_yy
|
1631 | };
|
1632 | var p;
|
1633 | var yyrulelen;
|
1634 | var this_production;
|
1635 | var newState;
|
1636 | var retval = false;
|
1637 |
|
1638 |
|
1639 | try {
|
1640 | this.__reentrant_call_depth++;
|
1641 |
|
1642 | lexer.setInput(input, sharedState_yy);
|
1643 |
|
1644 | // NOTE: we *assume* no lexer pre/post handlers are set up *after*
|
1645 | // this initial `setInput()` call: hence we can now check and decide
|
1646 | // whether we'll go with the standard, slower, lex() API or the
|
1647 | // `fast_lex()` one:
|
1648 | if (typeof lexer.canIUse === 'function') {
|
1649 | var lexerInfo = lexer.canIUse();
|
1650 | if (lexerInfo.fastLex && typeof fastLex === 'function') {
|
1651 | lex = fastLex;
|
1652 | }
|
1653 | }
|
1654 |
|
1655 | yyloc = lexer.yylloc;
|
1656 | lstack[sp] = yyloc;
|
1657 | vstack[sp] = null;
|
1658 | sstack[sp] = 0;
|
1659 | stack[sp] = 0;
|
1660 | ++sp;
|
1661 |
|
1662 |
|
1663 |
|
1664 |
|
1665 |
|
1666 | if (this.pre_parse) {
|
1667 | this.pre_parse.call(this, sharedState_yy);
|
1668 | }
|
1669 | if (sharedState_yy.pre_parse) {
|
1670 | sharedState_yy.pre_parse.call(this, sharedState_yy);
|
1671 | }
|
1672 |
|
1673 | newState = sstack[sp - 1];
|
1674 | for (;;) {
|
1675 | // retrieve state number from top of stack
|
1676 | state = newState; // sstack[sp - 1];
|
1677 |
|
1678 | // use default actions if available
|
1679 | if (this.defaultActions[state]) {
|
1680 | action = 2;
|
1681 | newState = this.defaultActions[state];
|
1682 | } else {
|
1683 | // The single `==` condition below covers both these `===` comparisons in a single
|
1684 | // operation:
|
1685 | //
|
1686 | // if (symbol === null || typeof symbol === 'undefined') ...
|
1687 | if (!symbol) {
|
1688 | symbol = lex();
|
1689 | }
|
1690 | // read action for current state and first input
|
1691 | t = (table[state] && table[state][symbol]) || NO_ACTION;
|
1692 | newState = t[1];
|
1693 | action = t[0];
|
1694 |
|
1695 |
|
1696 |
|
1697 |
|
1698 |
|
1699 |
|
1700 |
|
1701 |
|
1702 |
|
1703 |
|
1704 |
|
1705 | // handle parse error
|
1706 | if (!action) {
|
1707 | var errStr;
|
1708 | var errSymbolDescr = (this.describeSymbol(symbol) || symbol);
|
1709 | var expected = this.collect_expected_token_set(state);
|
1710 |
|
1711 | // Report error
|
1712 | if (typeof lexer.yylineno === 'number') {
|
1713 | errStr = 'Parse error on line ' + (lexer.yylineno + 1) + ': ';
|
1714 | } else {
|
1715 | errStr = 'Parse error: ';
|
1716 | }
|
1717 | if (typeof lexer.showPosition === 'function') {
|
1718 | errStr += '\n' + lexer.showPosition(79 - 10, 10) + '\n';
|
1719 | }
|
1720 | if (expected.length) {
|
1721 | errStr += 'Expecting ' + expected.join(', ') + ', got unexpected ' + errSymbolDescr;
|
1722 | } else {
|
1723 | errStr += 'Unexpected ' + errSymbolDescr;
|
1724 | }
|
1725 | // we cannot recover from the error!
|
1726 | p = this.constructParseErrorInfo(errStr, null, expected, false);
|
1727 | r = this.parseError(p.errStr, p, this.JisonParserError);
|
1728 | if (typeof r !== 'undefined') {
|
1729 | retval = r;
|
1730 | }
|
1731 | break;
|
1732 | }
|
1733 |
|
1734 |
|
1735 | }
|
1736 |
|
1737 |
|
1738 |
|
1739 |
|
1740 |
|
1741 |
|
1742 |
|
1743 |
|
1744 |
|
1745 |
|
1746 | switch (action) {
|
1747 | // catch misc. parse failures:
|
1748 | default:
|
1749 | // this shouldn't happen, unless resolve defaults are off
|
1750 | if (action instanceof Array) {
|
1751 | p = this.constructParseErrorInfo('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol, null, null, false);
|
1752 | r = this.parseError(p.errStr, p, this.JisonParserError);
|
1753 | if (typeof r !== 'undefined') {
|
1754 | retval = r;
|
1755 | }
|
1756 | break;
|
1757 | }
|
1758 | // Another case of better safe than sorry: in case state transitions come out of another error recovery process
|
1759 | // or a buggy LUT (LookUp Table):
|
1760 | p = this.constructParseErrorInfo('Parsing halted. No viable error recovery approach available due to internal system failure.', null, null, false);
|
1761 | r = this.parseError(p.errStr, p, this.JisonParserError);
|
1762 | if (typeof r !== 'undefined') {
|
1763 | retval = r;
|
1764 | }
|
1765 | break;
|
1766 |
|
1767 | // shift:
|
1768 | case 1:
|
1769 | stack[sp] = symbol;
|
1770 | vstack[sp] = lexer.yytext;
|
1771 | lstack[sp] = copy_yylloc(lexer.yylloc);
|
1772 | sstack[sp] = newState; // push state
|
1773 |
|
1774 | ++sp;
|
1775 | symbol = 0;
|
1776 |
|
1777 |
|
1778 |
|
1779 |
|
1780 | // Pick up the lexer details for the current symbol as that one is not 'look-ahead' any more:
|
1781 |
|
1782 |
|
1783 |
|
1784 | yyloc = lexer.yylloc;
|
1785 | continue;
|
1786 |
|
1787 | // reduce:
|
1788 | case 2:
|
1789 |
|
1790 |
|
1791 |
|
1792 | this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...
|
1793 | yyrulelen = this_production[1];
|
1794 |
|
1795 |
|
1796 |
|
1797 |
|
1798 |
|
1799 |
|
1800 |
|
1801 |
|
1802 |
|
1803 |
|
1804 | r = this.performAction.call(yyval, yyloc, newState, sp - 1, vstack, lstack);
|
1805 |
|
1806 | if (typeof r !== 'undefined') {
|
1807 | retval = r;
|
1808 | break;
|
1809 | }
|
1810 |
|
1811 | // pop off stack
|
1812 | sp -= yyrulelen;
|
1813 |
|
1814 | // don't overwrite the `symbol` variable: use a local var to speed things up:
|
1815 | var ntsymbol = this_production[0]; // push nonterminal (reduce)
|
1816 | stack[sp] = ntsymbol;
|
1817 | vstack[sp] = yyval.$;
|
1818 | lstack[sp] = yyval._$;
|
1819 | // goto new state = table[STATE][NONTERMINAL]
|
1820 | newState = table[sstack[sp - 1]][ntsymbol];
|
1821 | sstack[sp] = newState;
|
1822 | ++sp;
|
1823 |
|
1824 |
|
1825 |
|
1826 |
|
1827 |
|
1828 |
|
1829 |
|
1830 |
|
1831 |
|
1832 | continue;
|
1833 |
|
1834 | // accept:
|
1835 | case 3:
|
1836 | if (sp !== -2) {
|
1837 | retval = true;
|
1838 | // Return the `$accept` rule's `$$` result, if available.
|
1839 | //
|
1840 | // Also note that JISON always adds this top-most `$accept` rule (with implicit,
|
1841 | // default, action):
|
1842 | //
|
1843 | // $accept: <startSymbol> $end
|
1844 | // %{ $$ = $1; @$ = @1; %}
|
1845 | //
|
1846 | // which, combined with the parse kernel's `$accept` state behaviour coded below,
|
1847 | // will produce the `$$` value output of the <startSymbol> rule as the parse result,
|
1848 | // IFF that result is *not* `undefined`. (See also the parser kernel code.)
|
1849 | //
|
1850 | // In code:
|
1851 | //
|
1852 | // %{
|
1853 | // @$ = @1; // if location tracking support is included
|
1854 | // if (typeof $1 !== 'undefined')
|
1855 | // return $1;
|
1856 | // else
|
1857 | // return true; // the default parse result if the rule actions don't produce anything
|
1858 | // %}
|
1859 | sp--;
|
1860 | if (typeof vstack[sp] !== 'undefined') {
|
1861 | retval = vstack[sp];
|
1862 | }
|
1863 | }
|
1864 | break;
|
1865 | }
|
1866 |
|
1867 | // break out of loop: we accept or fail with error
|
1868 | break;
|
1869 | }
|
1870 | } catch (ex) {
|
1871 | // report exceptions through the parseError callback too, but keep the exception intact
|
1872 | // if it is a known parser or lexer error which has been thrown by parseError() already:
|
1873 | if (ex instanceof this.JisonParserError) {
|
1874 | throw ex;
|
1875 | }
|
1876 | else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) {
|
1877 | throw ex;
|
1878 | }
|
1879 |
|
1880 | p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false);
|
1881 | retval = false;
|
1882 | r = this.parseError(p.errStr, p, this.JisonParserError);
|
1883 | if (typeof r !== 'undefined') {
|
1884 | retval = r;
|
1885 | }
|
1886 | } finally {
|
1887 | retval = this.cleanupAfterParse(retval, true, true);
|
1888 | this.__reentrant_call_depth--;
|
1889 | } // /finally
|
1890 |
|
1891 | return retval;
|
1892 | }
|
1893 | };
|
1894 | parser.originalParseError = parser.parseError;
|
1895 | parser.originalQuoteName = parser.quoteName;
|
1896 | /* lexer generated by jison-lex 0.6.1-215 */
|
1897 |
|
1898 | /*
|
1899 | * Returns a Lexer object of the following structure:
|
1900 | *
|
1901 | * Lexer: {
|
1902 | * yy: {} The so-called "shared state" or rather the *source* of it;
|
1903 | * the real "shared state" `yy` passed around to
|
1904 | * the rule actions, etc. is a direct reference!
|
1905 | *
|
1906 | * This "shared context" object was passed to the lexer by way of
|
1907 | * the `lexer.setInput(str, yy)` API before you may use it.
|
1908 | *
|
1909 | * This "shared context" object is passed to the lexer action code in `performAction()`
|
1910 | * so userland code in the lexer actions may communicate with the outside world
|
1911 | * and/or other lexer rules' actions in more or less complex ways.
|
1912 | *
|
1913 | * }
|
1914 | *
|
1915 | * Lexer.prototype: {
|
1916 | * EOF: 1,
|
1917 | * ERROR: 2,
|
1918 | *
|
1919 | * yy: The overall "shared context" object reference.
|
1920 | *
|
1921 | * JisonLexerError: function(msg, hash),
|
1922 | *
|
1923 | * performAction: function lexer__performAction(yy, yyrulenumber, YY_START),
|
1924 | *
|
1925 | * The function parameters and `this` have the following value/meaning:
|
1926 | * - `this` : reference to the `lexer` instance.
|
1927 | * `yy_` is an alias for `this` lexer instance reference used internally.
|
1928 | *
|
1929 | * - `yy` : a reference to the `yy` "shared state" object which was passed to the lexer
|
1930 | * by way of the `lexer.setInput(str, yy)` API before.
|
1931 | *
|
1932 | * Note:
|
1933 | * The extra arguments you specified in the `%parse-param` statement in your
|
1934 | * **parser** grammar definition file are passed to the lexer via this object
|
1935 | * reference as member variables.
|
1936 | *
|
1937 | * - `yyrulenumber` : index of the matched lexer rule (regex), used internally.
|
1938 | *
|
1939 | * - `YY_START`: the current lexer "start condition" state.
|
1940 | *
|
1941 | * parseError: function(str, hash, ExceptionClass),
|
1942 | *
|
1943 | * constructLexErrorInfo: function(error_message, is_recoverable),
|
1944 | * Helper function.
|
1945 | * Produces a new errorInfo 'hash object' which can be passed into `parseError()`.
|
1946 | * See it's use in this lexer kernel in many places; example usage:
|
1947 | *
|
1948 | * var infoObj = lexer.constructParseErrorInfo('fail!', true);
|
1949 | * var retVal = lexer.parseError(infoObj.errStr, infoObj, lexer.JisonLexerError);
|
1950 | *
|
1951 | * options: { ... lexer %options ... },
|
1952 | *
|
1953 | * lex: function(),
|
1954 | * Produce one token of lexed input, which was passed in earlier via the `lexer.setInput()` API.
|
1955 | * You MAY use the additional `args...` parameters as per `%parse-param` spec of the **lexer** grammar:
|
1956 | * these extra `args...` are added verbatim to the `yy` object reference as member variables.
|
1957 | *
|
1958 | * WARNING:
|
1959 | * Lexer's additional `args...` parameters (via lexer's `%parse-param`) MAY conflict with
|
1960 | * any attributes already added to `yy` by the **parser** or the jison run-time;
|
1961 | * when such a collision is detected an exception is thrown to prevent the generated run-time
|
1962 | * from silently accepting this confusing and potentially hazardous situation!
|
1963 | *
|
1964 | * cleanupAfterLex: function(do_not_nuke_errorinfos),
|
1965 | * Helper function.
|
1966 | *
|
1967 | * This helper API is invoked when the **parse process** has completed: it is the responsibility
|
1968 | * of the **parser** (or the calling userland code) to invoke this method once cleanup is desired.
|
1969 | *
|
1970 | * This helper may be invoked by user code to ensure the internal lexer gets properly garbage collected.
|
1971 | *
|
1972 | * setInput: function(input, [yy]),
|
1973 | *
|
1974 | *
|
1975 | * input: function(),
|
1976 | *
|
1977 | *
|
1978 | * unput: function(str),
|
1979 | *
|
1980 | *
|
1981 | * more: function(),
|
1982 | *
|
1983 | *
|
1984 | * reject: function(),
|
1985 | *
|
1986 | *
|
1987 | * less: function(n),
|
1988 | *
|
1989 | *
|
1990 | * pastInput: function(n),
|
1991 | *
|
1992 | *
|
1993 | * upcomingInput: function(n),
|
1994 | *
|
1995 | *
|
1996 | * showPosition: function(),
|
1997 | *
|
1998 | *
|
1999 | * test_match: function(regex_match_array, rule_index),
|
2000 | *
|
2001 | *
|
2002 | * next: function(),
|
2003 | *
|
2004 | *
|
2005 | * begin: function(condition),
|
2006 | *
|
2007 | *
|
2008 | * pushState: function(condition),
|
2009 | *
|
2010 | *
|
2011 | * popState: function(),
|
2012 | *
|
2013 | *
|
2014 | * topState: function(),
|
2015 | *
|
2016 | *
|
2017 | * _currentRules: function(),
|
2018 | *
|
2019 | *
|
2020 | * stateStackSize: function(),
|
2021 | *
|
2022 | *
|
2023 | * performAction: function(yy, yy_, yyrulenumber, YY_START),
|
2024 | *
|
2025 | *
|
2026 | * rules: [...],
|
2027 | *
|
2028 | *
|
2029 | * conditions: {associative list: name ==> set},
|
2030 | * }
|
2031 | *
|
2032 | *
|
2033 | * token location info (`yylloc`): {
|
2034 | * first_line: n,
|
2035 | * last_line: n,
|
2036 | * first_column: n,
|
2037 | * last_column: n,
|
2038 | * range: [start_number, end_number]
|
2039 | * (where the numbers are indexes into the input string, zero-based)
|
2040 | * }
|
2041 | *
|
2042 | * ---
|
2043 | *
|
2044 | * The `parseError` function receives a 'hash' object with these members for lexer errors:
|
2045 | *
|
2046 | * {
|
2047 | * text: (matched text)
|
2048 | * token: (the produced terminal token, if any)
|
2049 | * token_id: (the produced terminal token numeric ID, if any)
|
2050 | * line: (yylineno)
|
2051 | * loc: (yylloc)
|
2052 | * recoverable: (boolean: TRUE when the parser MAY have an error recovery rule
|
2053 | * available for this particular error)
|
2054 | * yy: (object: the current parser internal "shared state" `yy`
|
2055 | * as is also available in the rule actions; this can be used,
|
2056 | * for instance, for advanced error analysis and reporting)
|
2057 | * lexer: (reference to the current lexer instance used by the parser)
|
2058 | * }
|
2059 | *
|
2060 | * while `this` will reference the current lexer instance.
|
2061 | *
|
2062 | * When `parseError` is invoked by the lexer, the default implementation will
|
2063 | * attempt to invoke `yy.parser.parseError()`; when this callback is not provided
|
2064 | * it will try to invoke `yy.parseError()` instead. When that callback is also not
|
2065 | * provided, a `JisonLexerError` exception will be thrown containing the error
|
2066 | * message and `hash`, as constructed by the `constructLexErrorInfo()` API.
|
2067 | *
|
2068 | * Note that the lexer's `JisonLexerError` error class is passed via the
|
2069 | * `ExceptionClass` argument, which is invoked to construct the exception
|
2070 | * instance to be thrown, so technically `parseError` will throw the object
|
2071 | * produced by the `new ExceptionClass(str, hash)` JavaScript expression.
|
2072 | *
|
2073 | * ---
|
2074 | *
|
2075 | * You can specify lexer options by setting / modifying the `.options` object of your Lexer instance.
|
2076 | * These options are available:
|
2077 | *
|
2078 | * (Options are permanent.)
|
2079 | *
|
2080 | * yy: {
|
2081 | * parseError: function(str, hash, ExceptionClass)
|
2082 | * optional: overrides the default `parseError` function.
|
2083 | * }
|
2084 | *
|
2085 | * lexer.options: {
|
2086 | * pre_lex: function()
|
2087 | * optional: is invoked before the lexer is invoked to produce another token.
|
2088 | * `this` refers to the Lexer object.
|
2089 | * post_lex: function(token) { return token; }
|
2090 | * optional: is invoked when the lexer has produced a token `token`;
|
2091 | * this function can override the returned token value by returning another.
|
2092 | * When it does not return any (truthy) value, the lexer will return
|
2093 | * the original `token`.
|
2094 | * `this` refers to the Lexer object.
|
2095 | *
|
2096 | * WARNING: the next set of options are not meant to be changed. They echo the abilities of
|
2097 | * the lexer as per when it was compiled!
|
2098 | *
|
2099 | * ranges: boolean
|
2100 | * optional: `true` ==> token location info will include a .range[] member.
|
2101 | * flex: boolean
|
2102 | * optional: `true` ==> flex-like lexing behaviour where the rules are tested
|
2103 | * exhaustively to find the longest match.
|
2104 | * backtrack_lexer: boolean
|
2105 | * optional: `true` ==> lexer regexes are tested in order and for invoked;
|
2106 | * the lexer terminates the scan when a token is returned by the action code.
|
2107 | * xregexp: boolean
|
2108 | * optional: `true` ==> lexer rule regexes are "extended regex format" requiring the
|
2109 | * `XRegExp` library. When this %option has not been specified at compile time, all lexer
|
2110 | * rule regexes have been written as standard JavaScript RegExp expressions.
|
2111 | * }
|
2112 | */
|
2113 |
|
2114 |
|
2115 | var lexer = function() {
|
2116 | /**
|
2117 | * See also:
|
2118 | * http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508
|
2119 | * but we keep the prototype.constructor and prototype.name assignment lines too for compatibility
|
2120 | * with userland code which might access the derived class in a 'classic' way.
|
2121 | *
|
2122 | * @public
|
2123 | * @constructor
|
2124 | * @nocollapse
|
2125 | */
|
2126 | function JisonLexerError(msg, hash) {
|
2127 | Object.defineProperty(this, 'name', {
|
2128 | enumerable: false,
|
2129 | writable: false,
|
2130 | value: 'JisonLexerError'
|
2131 | });
|
2132 |
|
2133 | if (msg == null)
|
2134 | msg = '???';
|
2135 |
|
2136 | Object.defineProperty(this, 'message', {
|
2137 | enumerable: false,
|
2138 | writable: true,
|
2139 | value: msg
|
2140 | });
|
2141 |
|
2142 | this.hash = hash;
|
2143 | var stacktrace;
|
2144 |
|
2145 | if (hash && hash.exception instanceof Error) {
|
2146 | var ex2 = hash.exception;
|
2147 | this.message = ex2.message || msg;
|
2148 | stacktrace = ex2.stack;
|
2149 | }
|
2150 |
|
2151 | if (!stacktrace) {
|
2152 | if (Error.hasOwnProperty('captureStackTrace')) {
|
2153 | // V8
|
2154 | Error.captureStackTrace(this, this.constructor);
|
2155 | } else {
|
2156 | stacktrace = new Error(msg).stack;
|
2157 | }
|
2158 | }
|
2159 |
|
2160 | if (stacktrace) {
|
2161 | Object.defineProperty(this, 'stack', {
|
2162 | enumerable: false,
|
2163 | writable: false,
|
2164 | value: stacktrace
|
2165 | });
|
2166 | }
|
2167 | }
|
2168 |
|
2169 | if (typeof Object.setPrototypeOf === 'function') {
|
2170 | Object.setPrototypeOf(JisonLexerError.prototype, Error.prototype);
|
2171 | } else {
|
2172 | JisonLexerError.prototype = Object.create(Error.prototype);
|
2173 | }
|
2174 |
|
2175 | JisonLexerError.prototype.constructor = JisonLexerError;
|
2176 | JisonLexerError.prototype.name = 'JisonLexerError';
|
2177 |
|
2178 | var lexer = {
|
2179 |
|
2180 | // Code Generator Information Report
|
2181 | // ---------------------------------
|
2182 | //
|
2183 | // Options:
|
2184 | //
|
2185 | // backtracking: .................... false
|
2186 | // location.ranges: ................. false
|
2187 | // location line+column tracking: ... true
|
2188 | //
|
2189 | //
|
2190 | // Forwarded Parser Analysis flags:
|
2191 | //
|
2192 | // uses yyleng: ..................... false
|
2193 | // uses yylineno: ................... false
|
2194 | // uses yytext: ..................... false
|
2195 | // uses yylloc: ..................... false
|
2196 | // uses lexer values: ............... true / true
|
2197 | // location tracking: ............... true
|
2198 | // location assignment: ............. true
|
2199 | //
|
2200 | //
|
2201 | // Lexer Analysis flags:
|
2202 | //
|
2203 | // uses yyleng: ..................... ???
|
2204 | // uses yylineno: ................... ???
|
2205 | // uses yytext: ..................... ???
|
2206 | // uses yylloc: ..................... ???
|
2207 | // uses ParseError API: ............. ???
|
2208 | // uses yyerror: .................... ???
|
2209 | // uses location tracking & editing: ???
|
2210 | // uses more() API: ................. ???
|
2211 | // uses unput() API: ................ ???
|
2212 | // uses reject() API: ............... ???
|
2213 | // uses less() API: ................. ???
|
2214 | // uses display APIs pastInput(), upcomingInput(), showPosition():
|
2215 | // ............................. ???
|
2216 | // uses describeYYLLOC() API: ....... ???
|
2217 | //
|
2218 | // --------- END OF REPORT -----------
|
2219 |
|
2220 | EOF: 1,
|
2221 | ERROR: 2,
|
2222 |
|
2223 | // JisonLexerError: JisonLexerError, /// <-- injected by the code generator
|
2224 |
|
2225 | // options: {}, /// <-- injected by the code generator
|
2226 |
|
2227 | // yy: ..., /// <-- injected by setInput()
|
2228 |
|
2229 | __currentRuleSet__: null, /// INTERNAL USE ONLY: internal rule set cache for the current lexer state
|
2230 |
|
2231 | __error_infos: [], /// INTERNAL USE ONLY: the set of lexErrorInfo objects created since the last cleanup
|
2232 | __decompressed: false, /// INTERNAL USE ONLY: mark whether the lexer instance has been 'unfolded' completely and is now ready for use
|
2233 | done: false, /// INTERNAL USE ONLY
|
2234 | _backtrack: false, /// INTERNAL USE ONLY
|
2235 | _input: '', /// INTERNAL USE ONLY
|
2236 | _more: false, /// INTERNAL USE ONLY
|
2237 | _signaled_error_token: false, /// INTERNAL USE ONLY
|
2238 | conditionStack: [], /// INTERNAL USE ONLY; managed via `pushState()`, `popState()`, `topState()` and `stateStackSize()`
|
2239 | match: '', /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks input which has been matched so far for the lexer token under construction. `match` is identical to `yytext` except that this one still contains the matched input string after `lexer.performAction()` has been invoked, where userland code MAY have changed/replaced the `yytext` value entirely!
|
2240 | matched: '', /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks entire input which has been matched so far
|
2241 | matches: false, /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks RE match result for last (successful) match attempt
|
2242 | yytext: '', /// ADVANCED USE ONLY: tracks input which has been matched so far for the lexer token under construction; this value is transferred to the parser as the 'token value' when the parser consumes the lexer token produced through a call to the `lex()` API.
|
2243 | offset: 0, /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks the 'cursor position' in the input string, i.e. the number of characters matched so far
|
2244 | yyleng: 0, /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: length of matched input for the token under construction (`yytext`)
|
2245 | yylineno: 0, /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: 'line number' at which the token under construction is located
|
2246 | yylloc: null, /// READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks location info (lines + columns) for the token under construction
|
2247 |
|
2248 | /**
|
2249 | * INTERNAL USE: construct a suitable error info hash object instance for `parseError`.
|
2250 | *
|
2251 | * @public
|
2252 | * @this {RegExpLexer}
|
2253 | */
|
2254 | constructLexErrorInfo: function lexer_constructLexErrorInfo(msg, recoverable, show_input_position) {
|
2255 | msg = '' + msg;
|
2256 |
|
2257 | // heuristic to determine if the error message already contains a (partial) source code dump
|
2258 | // as produced by either `showPosition()` or `prettyPrintRange()`:
|
2259 | if (show_input_position == undefined) {
|
2260 | show_input_position = !(msg.indexOf('\n') > 0 && msg.indexOf('^') > 0);
|
2261 | }
|
2262 |
|
2263 | if (this.yylloc && show_input_position) {
|
2264 | if (typeof this.prettyPrintRange === 'function') {
|
2265 | var pretty_src = this.prettyPrintRange(this.yylloc);
|
2266 |
|
2267 | if (!/\n\s*$/.test(msg)) {
|
2268 | msg += '\n';
|
2269 | }
|
2270 |
|
2271 | msg += '\n Erroneous area:\n' + this.prettyPrintRange(this.yylloc);
|
2272 | } else if (typeof this.showPosition === 'function') {
|
2273 | var pos_str = this.showPosition();
|
2274 |
|
2275 | if (pos_str) {
|
2276 | if (msg.length && msg[msg.length - 1] !== '\n' && pos_str[0] !== '\n') {
|
2277 | msg += '\n' + pos_str;
|
2278 | } else {
|
2279 | msg += pos_str;
|
2280 | }
|
2281 | }
|
2282 | }
|
2283 | }
|
2284 |
|
2285 | /** @constructor */
|
2286 | var pei = {
|
2287 | errStr: msg,
|
2288 | recoverable: !!recoverable,
|
2289 | text: this.match, // This one MAY be empty; userland code should use the `upcomingInput` API to obtain more text which follows the 'lexer cursor position'...
|
2290 | token: null,
|
2291 | line: this.yylineno,
|
2292 | loc: this.yylloc,
|
2293 | yy: this.yy,
|
2294 | lexer: this,
|
2295 |
|
2296 | /**
|
2297 | * and make sure the error info doesn't stay due to potential
|
2298 | * ref cycle via userland code manipulations.
|
2299 | * These would otherwise all be memory leak opportunities!
|
2300 | *
|
2301 | * Note that only array and object references are nuked as those
|
2302 | * constitute the set of elements which can produce a cyclic ref.
|
2303 | * The rest of the members is kept intact as they are harmless.
|
2304 | *
|
2305 | * @public
|
2306 | * @this {LexErrorInfo}
|
2307 | */
|
2308 | destroy: function destructLexErrorInfo() {
|
2309 | // remove cyclic references added to error info:
|
2310 | // info.yy = null;
|
2311 | // info.lexer = null;
|
2312 | // ...
|
2313 | var rec = !!this.recoverable;
|
2314 |
|
2315 | for (var key in this) {
|
2316 | if (this.hasOwnProperty(key) && typeof key === 'object') {
|
2317 | this[key] = undefined;
|
2318 | }
|
2319 | }
|
2320 |
|
2321 | this.recoverable = rec;
|
2322 | }
|
2323 | };
|
2324 |
|
2325 | // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!
|
2326 | this.__error_infos.push(pei);
|
2327 |
|
2328 | return pei;
|
2329 | },
|
2330 |
|
2331 | /**
|
2332 | * handler which is invoked when a lexer error occurs.
|
2333 | *
|
2334 | * @public
|
2335 | * @this {RegExpLexer}
|
2336 | */
|
2337 | parseError: function lexer_parseError(str, hash, ExceptionClass) {
|
2338 | if (!ExceptionClass) {
|
2339 | ExceptionClass = this.JisonLexerError;
|
2340 | }
|
2341 |
|
2342 | if (this.yy) {
|
2343 | if (this.yy.parser && typeof this.yy.parser.parseError === 'function') {
|
2344 | return this.yy.parser.parseError.call(this, str, hash, ExceptionClass) || this.ERROR;
|
2345 | } else if (typeof this.yy.parseError === 'function') {
|
2346 | return this.yy.parseError.call(this, str, hash, ExceptionClass) || this.ERROR;
|
2347 | }
|
2348 | }
|
2349 |
|
2350 | throw new ExceptionClass(str, hash);
|
2351 | },
|
2352 |
|
2353 | /**
|
2354 | * method which implements `yyerror(str, ...args)` functionality for use inside lexer actions.
|
2355 | *
|
2356 | * @public
|
2357 | * @this {RegExpLexer}
|
2358 | */
|
2359 | yyerror: function yyError(str /*, ...args */) {
|
2360 | var lineno_msg = '';
|
2361 |
|
2362 | if (this.yylloc) {
|
2363 | lineno_msg = ' on line ' + (this.yylineno + 1);
|
2364 | }
|
2365 |
|
2366 | var p = this.constructLexErrorInfo(
|
2367 | 'Lexical error' + lineno_msg + ': ' + str,
|
2368 | this.options.lexerErrorsAreRecoverable
|
2369 | );
|
2370 |
|
2371 | // Add any extra args to the hash under the name `extra_error_attributes`:
|
2372 | var args = Array.prototype.slice.call(arguments, 1);
|
2373 |
|
2374 | if (args.length) {
|
2375 | p.extra_error_attributes = args;
|
2376 | }
|
2377 |
|
2378 | return this.parseError(p.errStr, p, this.JisonLexerError) || this.ERROR;
|
2379 | },
|
2380 |
|
2381 | /**
|
2382 | * final cleanup function for when we have completed lexing the input;
|
2383 | * make it an API so that external code can use this one once userland
|
2384 | * code has decided it's time to destroy any lingering lexer error
|
2385 | * hash object instances and the like: this function helps to clean
|
2386 | * up these constructs, which *may* carry cyclic references which would
|
2387 | * otherwise prevent the instances from being properly and timely
|
2388 | * garbage-collected, i.e. this function helps prevent memory leaks!
|
2389 | *
|
2390 | * @public
|
2391 | * @this {RegExpLexer}
|
2392 | */
|
2393 | cleanupAfterLex: function lexer_cleanupAfterLex(do_not_nuke_errorinfos) {
|
2394 | // prevent lingering circular references from causing memory leaks:
|
2395 | this.setInput('', {});
|
2396 |
|
2397 | // nuke the error hash info instances created during this run.
|
2398 | // Userland code must COPY any data/references
|
2399 | // in the error hash instance(s) it is more permanently interested in.
|
2400 | if (!do_not_nuke_errorinfos) {
|
2401 | for (var i = this.__error_infos.length - 1; i >= 0; i--) {
|
2402 | var el = this.__error_infos[i];
|
2403 |
|
2404 | if (el && typeof el.destroy === 'function') {
|
2405 | el.destroy();
|
2406 | }
|
2407 | }
|
2408 |
|
2409 | this.__error_infos.length = 0;
|
2410 | }
|
2411 |
|
2412 | return this;
|
2413 | },
|
2414 |
|
2415 | /**
|
2416 | * clear the lexer token context; intended for internal use only
|
2417 | *
|
2418 | * @public
|
2419 | * @this {RegExpLexer}
|
2420 | */
|
2421 | clear: function lexer_clear() {
|
2422 | this.yytext = '';
|
2423 | this.yyleng = 0;
|
2424 | this.match = '';
|
2425 |
|
2426 | // - DO NOT reset `this.matched`
|
2427 | this.matches = false;
|
2428 |
|
2429 | this._more = false;
|
2430 | this._backtrack = false;
|
2431 | var col = (this.yylloc ? this.yylloc.last_column : 0);
|
2432 |
|
2433 | this.yylloc = {
|
2434 | first_line: this.yylineno + 1,
|
2435 | first_column: col,
|
2436 | last_line: this.yylineno + 1,
|
2437 | last_column: col,
|
2438 | range: [this.offset, this.offset]
|
2439 | };
|
2440 | },
|
2441 |
|
2442 | /**
|
2443 | * resets the lexer, sets new input
|
2444 | *
|
2445 | * @public
|
2446 | * @this {RegExpLexer}
|
2447 | */
|
2448 | setInput: function lexer_setInput(input, yy) {
|
2449 | this.yy = yy || this.yy || {};
|
2450 |
|
2451 | // also check if we've fully initialized the lexer instance,
|
2452 | // including expansion work to be done to go from a loaded
|
2453 | // lexer to a usable lexer:
|
2454 | if (!this.__decompressed) {
|
2455 | // step 1: decompress the regex list:
|
2456 | var rules = this.rules;
|
2457 |
|
2458 | for (var i = 0, len = rules.length; i < len; i++) {
|
2459 | var rule_re = rules[i];
|
2460 |
|
2461 | // compression: is the RE an xref to another RE slot in the rules[] table?
|
2462 | if (typeof rule_re === 'number') {
|
2463 | rules[i] = rules[rule_re];
|
2464 | }
|
2465 | }
|
2466 |
|
2467 | // step 2: unfold the conditions[] set to make these ready for use:
|
2468 | var conditions = this.conditions;
|
2469 |
|
2470 | for (var k in conditions) {
|
2471 | var spec = conditions[k];
|
2472 | var rule_ids = spec.rules;
|
2473 | var len = rule_ids.length;
|
2474 | var rule_regexes = new Array(len + 1); // slot 0 is unused; we use a 1-based index approach here to keep the hottest code in `lexer_next()` fast and simple!
|
2475 | var rule_new_ids = new Array(len + 1);
|
2476 |
|
2477 | for (var i = 0; i < len; i++) {
|
2478 | var idx = rule_ids[i];
|
2479 | var rule_re = rules[idx];
|
2480 | rule_regexes[i + 1] = rule_re;
|
2481 | rule_new_ids[i + 1] = idx;
|
2482 | }
|
2483 |
|
2484 | spec.rules = rule_new_ids;
|
2485 | spec.__rule_regexes = rule_regexes;
|
2486 | spec.__rule_count = len;
|
2487 | }
|
2488 |
|
2489 | this.__decompressed = true;
|
2490 | }
|
2491 |
|
2492 | this._input = input || '';
|
2493 | this.clear();
|
2494 | this._signaled_error_token = false;
|
2495 | this.done = false;
|
2496 | this.yylineno = 0;
|
2497 | this.matched = '';
|
2498 | this.conditionStack = ['INITIAL'];
|
2499 | this.__currentRuleSet__ = null;
|
2500 |
|
2501 | this.yylloc = {
|
2502 | first_line: 1,
|
2503 | first_column: 0,
|
2504 | last_line: 1,
|
2505 | last_column: 0,
|
2506 | range: [0, 0]
|
2507 | };
|
2508 |
|
2509 | this.offset = 0;
|
2510 | return this;
|
2511 | },
|
2512 |
|
2513 | /**
|
2514 | * edit the remaining input via user-specified callback.
|
2515 | * This can be used to forward-adjust the input-to-parse,
|
2516 | * e.g. inserting macro expansions and alike in the
|
2517 | * input which has yet to be lexed.
|
2518 | * The behaviour of this API contrasts the `unput()` et al
|
2519 | * APIs as those act on the *consumed* input, while this
|
2520 | * one allows one to manipulate the future, without impacting
|
2521 | * the current `yyloc` cursor location or any history.
|
2522 | *
|
2523 | * Use this API to help implement C-preprocessor-like
|
2524 | * `#include` statements, etc.
|
2525 | *
|
2526 | * The provided callback must be synchronous and is
|
2527 | * expected to return the edited input (string).
|
2528 | *
|
2529 | * The `cpsArg` argument value is passed to the callback
|
2530 | * as-is.
|
2531 | *
|
2532 | * `callback` interface:
|
2533 | * `function callback(input, cpsArg)`
|
2534 | *
|
2535 | * - `input` will carry the remaining-input-to-lex string
|
2536 | * from the lexer.
|
2537 | * - `cpsArg` is `cpsArg` passed into this API.
|
2538 | *
|
2539 | * The `this` reference for the callback will be set to
|
2540 | * reference this lexer instance so that userland code
|
2541 | * in the callback can easily and quickly access any lexer
|
2542 | * API.
|
2543 | *
|
2544 | * When the callback returns a non-string-type falsey value,
|
2545 | * we assume the callback did not edit the input and we
|
2546 | * will using the input as-is.
|
2547 | *
|
2548 | * When the callback returns a non-string-type value, it
|
2549 | * is converted to a string for lexing via the `"" + retval`
|
2550 | * operation. (See also why: http://2ality.com/2012/03/converting-to-string.html
|
2551 | * -- that way any returned object's `toValue()` and `toString()`
|
2552 | * methods will be invoked in a proper/desirable order.)
|
2553 | *
|
2554 | * @public
|
2555 | * @this {RegExpLexer}
|
2556 | */
|
2557 | editRemainingInput: function lexer_editRemainingInput(callback, cpsArg) {
|
2558 | var rv = callback.call(this, this._input, cpsArg);
|
2559 |
|
2560 | if (typeof rv !== 'string') {
|
2561 | if (rv) {
|
2562 | this._input = '' + rv;
|
2563 | }
|
2564 | // else: keep `this._input` as is.
|
2565 | } else {
|
2566 | this._input = rv;
|
2567 | }
|
2568 |
|
2569 | return this;
|
2570 | },
|
2571 |
|
2572 | /**
|
2573 | * consumes and returns one char from the input
|
2574 | *
|
2575 | * @public
|
2576 | * @this {RegExpLexer}
|
2577 | */
|
2578 | input: function lexer_input() {
|
2579 | if (!this._input) {
|
2580 | //this.done = true; -- don't set `done` as we want the lex()/next() API to be able to produce one custom EOF token match after this anyhow. (lexer can match special <<EOF>> tokens and perform user action code for a <<EOF>> match, but only does so *once*)
|
2581 | return null;
|
2582 | }
|
2583 |
|
2584 | var ch = this._input[0];
|
2585 | this.yytext += ch;
|
2586 | this.yyleng++;
|
2587 | this.offset++;
|
2588 | this.match += ch;
|
2589 | this.matched += ch;
|
2590 |
|
2591 | // Count the linenumber up when we hit the LF (or a stand-alone CR).
|
2592 | // On CRLF, the linenumber is incremented when you fetch the CR or the CRLF combo
|
2593 | // and we advance immediately past the LF as well, returning both together as if
|
2594 | // it was all a single 'character' only.
|
2595 | var slice_len = 1;
|
2596 |
|
2597 | var lines = false;
|
2598 |
|
2599 | if (ch === '\n') {
|
2600 | lines = true;
|
2601 | } else if (ch === '\r') {
|
2602 | lines = true;
|
2603 | var ch2 = this._input[1];
|
2604 |
|
2605 | if (ch2 === '\n') {
|
2606 | slice_len++;
|
2607 | ch += ch2;
|
2608 | this.yytext += ch2;
|
2609 | this.yyleng++;
|
2610 | this.offset++;
|
2611 | this.match += ch2;
|
2612 | this.matched += ch2;
|
2613 | this.yylloc.range[1]++;
|
2614 | }
|
2615 | }
|
2616 |
|
2617 | if (lines) {
|
2618 | this.yylineno++;
|
2619 | this.yylloc.last_line++;
|
2620 | this.yylloc.last_column = 0;
|
2621 | } else {
|
2622 | this.yylloc.last_column++;
|
2623 | }
|
2624 |
|
2625 | this.yylloc.range[1]++;
|
2626 | this._input = this._input.slice(slice_len);
|
2627 | return ch;
|
2628 | },
|
2629 |
|
2630 | /**
|
2631 | * unshifts one char (or an entire string) into the input
|
2632 | *
|
2633 | * @public
|
2634 | * @this {RegExpLexer}
|
2635 | */
|
2636 | unput: function lexer_unput(ch) {
|
2637 | var len = ch.length;
|
2638 | var lines = ch.split(/(?:\r\n?|\n)/g);
|
2639 | this._input = ch + this._input;
|
2640 | this.yytext = this.yytext.substr(0, this.yytext.length - len);
|
2641 | this.yyleng = this.yytext.length;
|
2642 | this.offset -= len;
|
2643 | this.match = this.match.substr(0, this.match.length - len);
|
2644 | this.matched = this.matched.substr(0, this.matched.length - len);
|
2645 |
|
2646 | if (lines.length > 1) {
|
2647 | this.yylineno -= lines.length - 1;
|
2648 | this.yylloc.last_line = this.yylineno + 1;
|
2649 |
|
2650 | // Get last entirely matched line into the `pre_lines[]` array's
|
2651 | // last index slot; we don't mind when other previously
|
2652 | // matched lines end up in the array too.
|
2653 | var pre = this.match;
|
2654 |
|
2655 | var pre_lines = pre.split(/(?:\r\n?|\n)/g);
|
2656 |
|
2657 | if (pre_lines.length === 1) {
|
2658 | pre = this.matched;
|
2659 | pre_lines = pre.split(/(?:\r\n?|\n)/g);
|
2660 | }
|
2661 |
|
2662 | this.yylloc.last_column = pre_lines[pre_lines.length - 1].length;
|
2663 | } else {
|
2664 | this.yylloc.last_column -= len;
|
2665 | }
|
2666 |
|
2667 | this.yylloc.range[1] = this.yylloc.range[0] + this.yyleng;
|
2668 | this.done = false;
|
2669 | return this;
|
2670 | },
|
2671 |
|
2672 | /**
|
2673 | * cache matched text and append it on next action
|
2674 | *
|
2675 | * @public
|
2676 | * @this {RegExpLexer}
|
2677 | */
|
2678 | more: function lexer_more() {
|
2679 | this._more = true;
|
2680 | return this;
|
2681 | },
|
2682 |
|
2683 | /**
|
2684 | * signal the lexer that this rule fails to match the input, so the
|
2685 | * next matching rule (regex) should be tested instead.
|
2686 | *
|
2687 | * @public
|
2688 | * @this {RegExpLexer}
|
2689 | */
|
2690 | reject: function lexer_reject() {
|
2691 | if (this.options.backtrack_lexer) {
|
2692 | this._backtrack = true;
|
2693 | } else {
|
2694 | // when the `parseError()` call returns, we MUST ensure that the error is registered.
|
2695 | // We accomplish this by signaling an 'error' token to be produced for the current
|
2696 | // `.lex()` run.
|
2697 | var lineno_msg = '';
|
2698 |
|
2699 | if (this.yylloc) {
|
2700 | lineno_msg = ' on line ' + (this.yylineno + 1);
|
2701 | }
|
2702 |
|
2703 | var p = this.constructLexErrorInfo(
|
2704 | 'Lexical error' + lineno_msg + ': You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).',
|
2705 | false
|
2706 | );
|
2707 |
|
2708 | this._signaled_error_token = this.parseError(p.errStr, p, this.JisonLexerError) || this.ERROR;
|
2709 | }
|
2710 |
|
2711 | return this;
|
2712 | },
|
2713 |
|
2714 | /**
|
2715 | * retain first n characters of the match
|
2716 | *
|
2717 | * @public
|
2718 | * @this {RegExpLexer}
|
2719 | */
|
2720 | less: function lexer_less(n) {
|
2721 | return this.unput(this.match.slice(n));
|
2722 | },
|
2723 |
|
2724 | /**
|
2725 | * return (part of the) already matched input, i.e. for error
|
2726 | * messages.
|
2727 | *
|
2728 | * Limit the returned string length to `maxSize` (default: 20).
|
2729 | *
|
2730 | * Limit the returned string to the `maxLines` number of lines of
|
2731 | * input (default: 1).
|
2732 | *
|
2733 | * Negative limit values equal *unlimited*.
|
2734 | *
|
2735 | * @public
|
2736 | * @this {RegExpLexer}
|
2737 | */
|
2738 | pastInput: function lexer_pastInput(maxSize, maxLines) {
|
2739 | var past = this.matched.substring(0, this.matched.length - this.match.length);
|
2740 |
|
2741 | if (maxSize < 0)
|
2742 | maxSize = past.length;
|
2743 | else if (!maxSize)
|
2744 | maxSize = 20;
|
2745 |
|
2746 | if (maxLines < 0)
|
2747 | maxLines = past.length; // can't ever have more input lines than this!
|
2748 | else if (!maxLines)
|
2749 | maxLines = 1;
|
2750 |
|
2751 | // `substr` anticipation: treat \r\n as a single character and take a little
|
2752 | // more than necessary so that we can still properly check against maxSize
|
2753 | // after we've transformed and limited the newLines in here:
|
2754 | past = past.substr(-maxSize * 2 - 2);
|
2755 |
|
2756 | // now that we have a significantly reduced string to process, transform the newlines
|
2757 | // and chop them, then limit them:
|
2758 | var a = past.replace(/\r\n|\r/g, '\n').split('\n');
|
2759 |
|
2760 | a = a.slice(-maxLines);
|
2761 | past = a.join('\n');
|
2762 |
|
2763 | // When, after limiting to maxLines, we still have too much to return,
|
2764 | // do add an ellipsis prefix...
|
2765 | if (past.length > maxSize) {
|
2766 | past = '...' + past.substr(-maxSize);
|
2767 | }
|
2768 |
|
2769 | return past;
|
2770 | },
|
2771 |
|
2772 | /**
|
2773 | * return (part of the) upcoming input, i.e. for error messages.
|
2774 | *
|
2775 | * Limit the returned string length to `maxSize` (default: 20).
|
2776 | *
|
2777 | * Limit the returned string to the `maxLines` number of lines of input (default: 1).
|
2778 | *
|
2779 | * Negative limit values equal *unlimited*.
|
2780 | *
|
2781 | * > ### NOTE ###
|
2782 | * >
|
2783 | * > *"upcoming input"* is defined as the whole of the both
|
2784 | * > the *currently lexed* input, together with any remaining input
|
2785 | * > following that. *"currently lexed"* input is the input
|
2786 | * > already recognized by the lexer but not yet returned with
|
2787 | * > the lexer token. This happens when you are invoking this API
|
2788 | * > from inside any lexer rule action code block.
|
2789 | * >
|
2790 | *
|
2791 | * @public
|
2792 | * @this {RegExpLexer}
|
2793 | */
|
2794 | upcomingInput: function lexer_upcomingInput(maxSize, maxLines) {
|
2795 | var next = this.match;
|
2796 |
|
2797 | if (maxSize < 0)
|
2798 | maxSize = next.length + this._input.length;
|
2799 | else if (!maxSize)
|
2800 | maxSize = 20;
|
2801 |
|
2802 | if (maxLines < 0)
|
2803 | maxLines = maxSize; // can't ever have more input lines than this!
|
2804 | else if (!maxLines)
|
2805 | maxLines = 1;
|
2806 |
|
2807 | // `substring` anticipation: treat \r\n as a single character and take a little
|
2808 | // more than necessary so that we can still properly check against maxSize
|
2809 | // after we've transformed and limited the newLines in here:
|
2810 | if (next.length < maxSize * 2 + 2) {
|
2811 | next += this._input.substring(0, maxSize * 2 + 2); // substring is faster on Chrome/V8
|
2812 | }
|
2813 |
|
2814 | // now that we have a significantly reduced string to process, transform the newlines
|
2815 | // and chop them, then limit them:
|
2816 | var a = next.replace(/\r\n|\r/g, '\n').split('\n');
|
2817 |
|
2818 | a = a.slice(0, maxLines);
|
2819 | next = a.join('\n');
|
2820 |
|
2821 | // When, after limiting to maxLines, we still have too much to return,
|
2822 | // do add an ellipsis postfix...
|
2823 | if (next.length > maxSize) {
|
2824 | next = next.substring(0, maxSize) + '...';
|
2825 | }
|
2826 |
|
2827 | return next;
|
2828 | },
|
2829 |
|
2830 | /**
|
2831 | * return a string which displays the character position where the
|
2832 | * lexing error occurred, i.e. for error messages
|
2833 | *
|
2834 | * @public
|
2835 | * @this {RegExpLexer}
|
2836 | */
|
2837 | showPosition: function lexer_showPosition(maxPrefix, maxPostfix) {
|
2838 | var pre = this.pastInput(maxPrefix).replace(/\s/g, ' ');
|
2839 | var c = new Array(pre.length + 1).join('-');
|
2840 | return pre + this.upcomingInput(maxPostfix).replace(/\s/g, ' ') + '\n' + c + '^';
|
2841 | },
|
2842 |
|
2843 | /**
|
2844 | * return an YYLLOC info object derived off the given context (actual, preceding, following, current).
|
2845 | * Use this method when the given `actual` location is not guaranteed to exist (i.e. when
|
2846 | * it MAY be NULL) and you MUST have a valid location info object anyway:
|
2847 | * then we take the given context of the `preceding` and `following` locations, IFF those are available,
|
2848 | * and reconstruct the `actual` location info from those.
|
2849 | * If this fails, the heuristic is to take the `current` location, IFF available.
|
2850 | * If this fails as well, we assume the sought location is at/around the current lexer position
|
2851 | * and then produce that one as a response. DO NOTE that these heuristic/derived location info
|
2852 | * values MAY be inaccurate!
|
2853 | *
|
2854 | * NOTE: `deriveLocationInfo()` ALWAYS produces a location info object *copy* of `actual`, not just
|
2855 | * a *reference* hence all input location objects can be assumed to be 'constant' (function has no side-effects).
|
2856 | *
|
2857 | * @public
|
2858 | * @this {RegExpLexer}
|
2859 | */
|
2860 | deriveLocationInfo: function lexer_deriveYYLLOC(actual, preceding, following, current) {
|
2861 | var loc = {
|
2862 | first_line: 1,
|
2863 | first_column: 0,
|
2864 | last_line: 1,
|
2865 | last_column: 0,
|
2866 | range: [0, 0]
|
2867 | };
|
2868 |
|
2869 | if (actual) {
|
2870 | loc.first_line = actual.first_line | 0;
|
2871 | loc.last_line = actual.last_line | 0;
|
2872 | loc.first_column = actual.first_column | 0;
|
2873 | loc.last_column = actual.last_column | 0;
|
2874 |
|
2875 | if (actual.range) {
|
2876 | loc.range[0] = actual.range[0] | 0;
|
2877 | loc.range[1] = actual.range[1] | 0;
|
2878 | }
|
2879 | }
|
2880 |
|
2881 | if (loc.first_line <= 0 || loc.last_line < loc.first_line) {
|
2882 | // plan B: heuristic using preceding and following:
|
2883 | if (loc.first_line <= 0 && preceding) {
|
2884 | loc.first_line = preceding.last_line | 0;
|
2885 | loc.first_column = preceding.last_column | 0;
|
2886 |
|
2887 | if (preceding.range) {
|
2888 | loc.range[0] = actual.range[1] | 0;
|
2889 | }
|
2890 | }
|
2891 |
|
2892 | if ((loc.last_line <= 0 || loc.last_line < loc.first_line) && following) {
|
2893 | loc.last_line = following.first_line | 0;
|
2894 | loc.last_column = following.first_column | 0;
|
2895 |
|
2896 | if (following.range) {
|
2897 | loc.range[1] = actual.range[0] | 0;
|
2898 | }
|
2899 | }
|
2900 |
|
2901 | // plan C?: see if the 'current' location is useful/sane too:
|
2902 | if (loc.first_line <= 0 && current && (loc.last_line <= 0 || current.last_line <= loc.last_line)) {
|
2903 | loc.first_line = current.first_line | 0;
|
2904 | loc.first_column = current.first_column | 0;
|
2905 |
|
2906 | if (current.range) {
|
2907 | loc.range[0] = current.range[0] | 0;
|
2908 | }
|
2909 | }
|
2910 |
|
2911 | if (loc.last_line <= 0 && current && (loc.first_line <= 0 || current.first_line >= loc.first_line)) {
|
2912 | loc.last_line = current.last_line | 0;
|
2913 | loc.last_column = current.last_column | 0;
|
2914 |
|
2915 | if (current.range) {
|
2916 | loc.range[1] = current.range[1] | 0;
|
2917 | }
|
2918 | }
|
2919 | }
|
2920 |
|
2921 | // sanitize: fix last_line BEFORE we fix first_line as we use the 'raw' value of the latter
|
2922 | // or plan D heuristics to produce a 'sensible' last_line value:
|
2923 | if (loc.last_line <= 0) {
|
2924 | if (loc.first_line <= 0) {
|
2925 | loc.first_line = this.yylloc.first_line;
|
2926 | loc.last_line = this.yylloc.last_line;
|
2927 | loc.first_column = this.yylloc.first_column;
|
2928 | loc.last_column = this.yylloc.last_column;
|
2929 | loc.range[0] = this.yylloc.range[0];
|
2930 | loc.range[1] = this.yylloc.range[1];
|
2931 | } else {
|
2932 | loc.last_line = this.yylloc.last_line;
|
2933 | loc.last_column = this.yylloc.last_column;
|
2934 | loc.range[1] = this.yylloc.range[1];
|
2935 | }
|
2936 | }
|
2937 |
|
2938 | if (loc.first_line <= 0) {
|
2939 | loc.first_line = loc.last_line;
|
2940 | loc.first_column = 0; // loc.last_column;
|
2941 | loc.range[1] = loc.range[0];
|
2942 | }
|
2943 |
|
2944 | if (loc.first_column < 0) {
|
2945 | loc.first_column = 0;
|
2946 | }
|
2947 |
|
2948 | if (loc.last_column < 0) {
|
2949 | loc.last_column = (loc.first_column > 0 ? loc.first_column : 80);
|
2950 | }
|
2951 |
|
2952 | return loc;
|
2953 | },
|
2954 |
|
2955 | /**
|
2956 | * return a string which displays the lines & columns of input which are referenced
|
2957 | * by the given location info range, plus a few lines of context.
|
2958 | *
|
2959 | * This function pretty-prints the indicated section of the input, with line numbers
|
2960 | * and everything!
|
2961 | *
|
2962 | * This function is very useful to provide highly readable error reports, while
|
2963 | * the location range may be specified in various flexible ways:
|
2964 | *
|
2965 | * - `loc` is the location info object which references the area which should be
|
2966 | * displayed and 'marked up': these lines & columns of text are marked up by `^`
|
2967 | * characters below each character in the entire input range.
|
2968 | *
|
2969 | * - `context_loc` is the *optional* location info object which instructs this
|
2970 | * pretty-printer how much *leading* context should be displayed alongside
|
2971 | * the area referenced by `loc`. This can help provide context for the displayed
|
2972 | * error, etc.
|
2973 | *
|
2974 | * When this location info is not provided, a default context of 3 lines is
|
2975 | * used.
|
2976 | *
|
2977 | * - `context_loc2` is another *optional* location info object, which serves
|
2978 | * a similar purpose to `context_loc`: it specifies the amount of *trailing*
|
2979 | * context lines to display in the pretty-print output.
|
2980 | *
|
2981 | * When this location info is not provided, a default context of 1 line only is
|
2982 | * used.
|
2983 | *
|
2984 | * Special Notes:
|
2985 | *
|
2986 | * - when the `loc`-indicated range is very large (about 5 lines or more), then
|
2987 | * only the first and last few lines of this block are printed while a
|
2988 | * `...continued...` message will be printed between them.
|
2989 | *
|
2990 | * This serves the purpose of not printing a huge amount of text when the `loc`
|
2991 | * range happens to be huge: this way a manageable & readable output results
|
2992 | * for arbitrary large ranges.
|
2993 | *
|
2994 | * - this function can display lines of input which whave not yet been lexed.
|
2995 | * `prettyPrintRange()` can access the entire input!
|
2996 | *
|
2997 | * @public
|
2998 | * @this {RegExpLexer}
|
2999 | */
|
3000 | prettyPrintRange: function lexer_prettyPrintRange(loc, context_loc, context_loc2) {
|
3001 | loc = this.deriveLocationInfo(loc, context_loc, context_loc2);
|
3002 | const CONTEXT = 3;
|
3003 | const CONTEXT_TAIL = 1;
|
3004 | const MINIMUM_VISIBLE_NONEMPTY_LINE_COUNT = 2;
|
3005 | var input = this.matched + this._input;
|
3006 | var lines = input.split('\n');
|
3007 | var l0 = Math.max(1, (context_loc ? context_loc.first_line : loc.first_line - CONTEXT));
|
3008 | var l1 = Math.max(1, (context_loc2 ? context_loc2.last_line : loc.last_line + CONTEXT_TAIL));
|
3009 | var lineno_display_width = 1 + Math.log10(l1 | 1) | 0;
|
3010 | var ws_prefix = new Array(lineno_display_width).join(' ');
|
3011 | var nonempty_line_indexes = [];
|
3012 |
|
3013 | var rv = lines.slice(l0 - 1, l1 + 1).map(function injectLineNumber(line, index) {
|
3014 | var lno = index + l0;
|
3015 | var lno_pfx = (ws_prefix + lno).substr(-lineno_display_width);
|
3016 | var rv = lno_pfx + ': ' + line;
|
3017 | var errpfx = new Array(lineno_display_width + 1).join('^');
|
3018 | var offset = 2 + 1;
|
3019 | var len = 0;
|
3020 |
|
3021 | if (lno === loc.first_line) {
|
3022 | offset += loc.first_column;
|
3023 |
|
3024 | len = Math.max(
|
3025 | 2,
|
3026 | ((lno === loc.last_line ? loc.last_column : line.length)) - loc.first_column + 1
|
3027 | );
|
3028 | } else if (lno === loc.last_line) {
|
3029 | len = Math.max(2, loc.last_column + 1);
|
3030 | } else if (lno > loc.first_line && lno < loc.last_line) {
|
3031 | len = Math.max(2, line.length + 1);
|
3032 | }
|
3033 |
|
3034 | if (len) {
|
3035 | var lead = new Array(offset).join('.');
|
3036 | var mark = new Array(len).join('^');
|
3037 | rv += '\n' + errpfx + lead + mark;
|
3038 |
|
3039 | if (line.trim().length > 0) {
|
3040 | nonempty_line_indexes.push(index);
|
3041 | }
|
3042 | }
|
3043 |
|
3044 | rv = rv.replace(/\t/g, ' ');
|
3045 | return rv;
|
3046 | });
|
3047 |
|
3048 | // now make sure we don't print an overly large amount of error area: limit it
|
3049 | // to the top and bottom line count:
|
3050 | if (nonempty_line_indexes.length > 2 * MINIMUM_VISIBLE_NONEMPTY_LINE_COUNT) {
|
3051 | var clip_start = nonempty_line_indexes[MINIMUM_VISIBLE_NONEMPTY_LINE_COUNT - 1] + 1;
|
3052 | var clip_end = nonempty_line_indexes[nonempty_line_indexes.length - MINIMUM_VISIBLE_NONEMPTY_LINE_COUNT] - 1;
|
3053 | var intermediate_line = new Array(lineno_display_width + 1).join(' ') + ' (...continued...)';
|
3054 | intermediate_line += '\n' + new Array(lineno_display_width + 1).join('-') + ' (---------------)';
|
3055 | rv.splice(clip_start, clip_end - clip_start + 1, intermediate_line);
|
3056 | }
|
3057 |
|
3058 | return rv.join('\n');
|
3059 | },
|
3060 |
|
3061 | /**
|
3062 | * helper function, used to produce a human readable description as a string, given
|
3063 | * the input `yylloc` location object.
|
3064 | *
|
3065 | * Set `display_range_too` to TRUE to include the string character index position(s)
|
3066 | * in the description if the `yylloc.range` is available.
|
3067 | *
|
3068 | * @public
|
3069 | * @this {RegExpLexer}
|
3070 | */
|
3071 | describeYYLLOC: function lexer_describe_yylloc(yylloc, display_range_too) {
|
3072 | var l1 = yylloc.first_line;
|
3073 | var l2 = yylloc.last_line;
|
3074 | var c1 = yylloc.first_column;
|
3075 | var c2 = yylloc.last_column;
|
3076 | var dl = l2 - l1;
|
3077 | var dc = c2 - c1;
|
3078 | var rv;
|
3079 |
|
3080 | if (dl === 0) {
|
3081 | rv = 'line ' + l1 + ', ';
|
3082 |
|
3083 | if (dc <= 1) {
|
3084 | rv += 'column ' + c1;
|
3085 | } else {
|
3086 | rv += 'columns ' + c1 + ' .. ' + c2;
|
3087 | }
|
3088 | } else {
|
3089 | rv = 'lines ' + l1 + '(column ' + c1 + ') .. ' + l2 + '(column ' + c2 + ')';
|
3090 | }
|
3091 |
|
3092 | if (yylloc.range && display_range_too) {
|
3093 | var r1 = yylloc.range[0];
|
3094 | var r2 = yylloc.range[1] - 1;
|
3095 |
|
3096 | if (r2 <= r1) {
|
3097 | rv += ' {String Offset: ' + r1 + '}';
|
3098 | } else {
|
3099 | rv += ' {String Offset range: ' + r1 + ' .. ' + r2 + '}';
|
3100 | }
|
3101 | }
|
3102 |
|
3103 | return rv;
|
3104 | },
|
3105 |
|
3106 | /**
|
3107 | * test the lexed token: return FALSE when not a match, otherwise return token.
|
3108 | *
|
3109 | * `match` is supposed to be an array coming out of a regex match, i.e. `match[0]`
|
3110 | * contains the actually matched text string.
|
3111 | *
|
3112 | * Also move the input cursor forward and update the match collectors:
|
3113 | *
|
3114 | * - `yytext`
|
3115 | * - `yyleng`
|
3116 | * - `match`
|
3117 | * - `matches`
|
3118 | * - `yylloc`
|
3119 | * - `offset`
|
3120 | *
|
3121 | * @public
|
3122 | * @this {RegExpLexer}
|
3123 | */
|
3124 | test_match: function lexer_test_match(match, indexed_rule) {
|
3125 | var token, lines, backup, match_str, match_str_len;
|
3126 |
|
3127 | if (this.options.backtrack_lexer) {
|
3128 | // save context
|
3129 | backup = {
|
3130 | yylineno: this.yylineno,
|
3131 |
|
3132 | yylloc: {
|
3133 | first_line: this.yylloc.first_line,
|
3134 | last_line: this.yylloc.last_line,
|
3135 | first_column: this.yylloc.first_column,
|
3136 | last_column: this.yylloc.last_column,
|
3137 | range: this.yylloc.range.slice(0)
|
3138 | },
|
3139 |
|
3140 | yytext: this.yytext,
|
3141 | match: this.match,
|
3142 | matches: this.matches,
|
3143 | matched: this.matched,
|
3144 | yyleng: this.yyleng,
|
3145 | offset: this.offset,
|
3146 | _more: this._more,
|
3147 | _input: this._input,
|
3148 |
|
3149 | //_signaled_error_token: this._signaled_error_token,
|
3150 | yy: this.yy,
|
3151 |
|
3152 | conditionStack: this.conditionStack.slice(0),
|
3153 | done: this.done
|
3154 | };
|
3155 | }
|
3156 |
|
3157 | match_str = match[0];
|
3158 | match_str_len = match_str.length;
|
3159 |
|
3160 | // if (match_str.indexOf('\n') !== -1 || match_str.indexOf('\r') !== -1) {
|
3161 | lines = match_str.split(/(?:\r\n?|\n)/g);
|
3162 |
|
3163 | if (lines.length > 1) {
|
3164 | this.yylineno += lines.length - 1;
|
3165 | this.yylloc.last_line = this.yylineno + 1;
|
3166 | this.yylloc.last_column = lines[lines.length - 1].length;
|
3167 | } else {
|
3168 | this.yylloc.last_column += match_str_len;
|
3169 | }
|
3170 |
|
3171 | // }
|
3172 | this.yytext += match_str;
|
3173 |
|
3174 | this.match += match_str;
|
3175 | this.matched += match_str;
|
3176 | this.matches = match;
|
3177 | this.yyleng = this.yytext.length;
|
3178 | this.yylloc.range[1] += match_str_len;
|
3179 |
|
3180 | // previous lex rules MAY have invoked the `more()` API rather than producing a token:
|
3181 | // those rules will already have moved this `offset` forward matching their match lengths,
|
3182 | // hence we must only add our own match length now:
|
3183 | this.offset += match_str_len;
|
3184 |
|
3185 | this._more = false;
|
3186 | this._backtrack = false;
|
3187 | this._input = this._input.slice(match_str_len);
|
3188 |
|
3189 | // calling this method:
|
3190 | //
|
3191 | // function lexer__performAction(yy, yyrulenumber, YY_START) {...}
|
3192 | token = this.performAction.call(
|
3193 | this,
|
3194 | this.yy,
|
3195 | indexed_rule,
|
3196 | this.conditionStack[this.conditionStack.length - 1] /* = YY_START */
|
3197 | );
|
3198 |
|
3199 | // otherwise, when the action codes are all simple return token statements:
|
3200 | //token = this.simpleCaseActionClusters[indexed_rule];
|
3201 |
|
3202 | if (this.done && this._input) {
|
3203 | this.done = false;
|
3204 | }
|
3205 |
|
3206 | if (token) {
|
3207 | return token;
|
3208 | } else if (this._backtrack) {
|
3209 | // recover context
|
3210 | for (var k in backup) {
|
3211 | this[k] = backup[k];
|
3212 | }
|
3213 |
|
3214 | this.__currentRuleSet__ = null;
|
3215 | return false; // rule action called reject() implying the next rule should be tested instead.
|
3216 | } else if (this._signaled_error_token) {
|
3217 | // produce one 'error' token as `.parseError()` in `reject()`
|
3218 | // did not guarantee a failure signal by throwing an exception!
|
3219 | token = this._signaled_error_token;
|
3220 |
|
3221 | this._signaled_error_token = false;
|
3222 | return token;
|
3223 | }
|
3224 |
|
3225 | return false;
|
3226 | },
|
3227 |
|
3228 | /**
|
3229 | * return next match in input
|
3230 | *
|
3231 | * @public
|
3232 | * @this {RegExpLexer}
|
3233 | */
|
3234 | next: function lexer_next() {
|
3235 | if (this.done) {
|
3236 | this.clear();
|
3237 | return this.EOF;
|
3238 | }
|
3239 |
|
3240 | if (!this._input) {
|
3241 | this.done = true;
|
3242 | }
|
3243 |
|
3244 | var token, match, tempMatch, index;
|
3245 |
|
3246 | if (!this._more) {
|
3247 | this.clear();
|
3248 | }
|
3249 |
|
3250 | var spec = this.__currentRuleSet__;
|
3251 |
|
3252 | if (!spec) {
|
3253 | // Update the ruleset cache as we apparently encountered a state change or just started lexing.
|
3254 | // The cache is set up for fast lookup -- we assume a lexer will switch states much less often than it will
|
3255 | // invoke the `lex()` token-producing API and related APIs, hence caching the set for direct access helps
|
3256 | // speed up those activities a tiny bit.
|
3257 | spec = this.__currentRuleSet__ = this._currentRules();
|
3258 |
|
3259 | // Check whether a *sane* condition has been pushed before: this makes the lexer robust against
|
3260 | // user-programmer bugs such as https://github.com/zaach/jison-lex/issues/19
|
3261 | if (!spec || !spec.rules) {
|
3262 | var lineno_msg = '';
|
3263 |
|
3264 | if (this.options.trackPosition) {
|
3265 | lineno_msg = ' on line ' + (this.yylineno + 1);
|
3266 | }
|
3267 |
|
3268 | var p = this.constructLexErrorInfo(
|
3269 | 'Internal lexer engine error' + lineno_msg + ': The lex grammar programmer pushed a non-existing condition name "' + this.topState() + '"; this is a fatal error and should be reported to the application programmer team!',
|
3270 | false
|
3271 | );
|
3272 |
|
3273 | // produce one 'error' token until this situation has been resolved, most probably by parse termination!
|
3274 | return this.parseError(p.errStr, p, this.JisonLexerError) || this.ERROR;
|
3275 | }
|
3276 | }
|
3277 |
|
3278 | var rule_ids = spec.rules;
|
3279 | var regexes = spec.__rule_regexes;
|
3280 | var len = spec.__rule_count;
|
3281 |
|
3282 | // Note: the arrays are 1-based, while `len` itself is a valid index,
|
3283 | // hence the non-standard less-or-equal check in the next loop condition!
|
3284 | for (var i = 1; i <= len; i++) {
|
3285 | tempMatch = this._input.match(regexes[i]);
|
3286 |
|
3287 | if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
3288 | match = tempMatch;
|
3289 | index = i;
|
3290 |
|
3291 | if (this.options.backtrack_lexer) {
|
3292 | token = this.test_match(tempMatch, rule_ids[i]);
|
3293 |
|
3294 | if (token !== false) {
|
3295 | return token;
|
3296 | } else if (this._backtrack) {
|
3297 | match = undefined;
|
3298 | continue; // rule action called reject() implying a rule MISmatch.
|
3299 | } else {
|
3300 | // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
|
3301 | return false;
|
3302 | }
|
3303 | } else if (!this.options.flex) {
|
3304 | break;
|
3305 | }
|
3306 | }
|
3307 | }
|
3308 |
|
3309 | if (match) {
|
3310 | token = this.test_match(match, rule_ids[index]);
|
3311 |
|
3312 | if (token !== false) {
|
3313 | return token;
|
3314 | }
|
3315 |
|
3316 | // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
|
3317 | return false;
|
3318 | }
|
3319 |
|
3320 | if (!this._input) {
|
3321 | this.done = true;
|
3322 | this.clear();
|
3323 | return this.EOF;
|
3324 | } else {
|
3325 | var lineno_msg = '';
|
3326 |
|
3327 | if (this.options.trackPosition) {
|
3328 | lineno_msg = ' on line ' + (this.yylineno + 1);
|
3329 | }
|
3330 |
|
3331 | var p = this.constructLexErrorInfo(
|
3332 | 'Lexical error' + lineno_msg + ': Unrecognized text.',
|
3333 | this.options.lexerErrorsAreRecoverable
|
3334 | );
|
3335 |
|
3336 | var pendingInput = this._input;
|
3337 | var activeCondition = this.topState();
|
3338 | var conditionStackDepth = this.conditionStack.length;
|
3339 | token = this.parseError(p.errStr, p, this.JisonLexerError) || this.ERROR;
|
3340 |
|
3341 | if (token === this.ERROR) {
|
3342 | // we can try to recover from a lexer error that `parseError()` did not 'recover' for us
|
3343 | // by moving forward at least one character at a time IFF the (user-specified?) `parseError()`
|
3344 | // has not consumed/modified any pending input or changed state in the error handler:
|
3345 | if (!this.matches && // and make sure the input has been modified/consumed ...
|
3346 | pendingInput === this._input && // ...or the lexer state has been modified significantly enough
|
3347 | // to merit a non-consuming error handling action right now.
|
3348 | activeCondition === this.topState() && conditionStackDepth === this.conditionStack.length) {
|
3349 | this.input();
|
3350 | }
|
3351 | }
|
3352 |
|
3353 | return token;
|
3354 | }
|
3355 | },
|
3356 |
|
3357 | /**
|
3358 | * return next match that has a token
|
3359 | *
|
3360 | * @public
|
3361 | * @this {RegExpLexer}
|
3362 | */
|
3363 | lex: function lexer_lex() {
|
3364 | var r;
|
3365 |
|
3366 | // allow the PRE/POST handlers set/modify the return token for maximum flexibility of the generated lexer:
|
3367 | if (typeof this.pre_lex === 'function') {
|
3368 | r = this.pre_lex.call(this, 0);
|
3369 | }
|
3370 |
|
3371 | if (typeof this.options.pre_lex === 'function') {
|
3372 | // (also account for a userdef function which does not return any value: keep the token as is)
|
3373 | r = this.options.pre_lex.call(this, r) || r;
|
3374 | }
|
3375 |
|
3376 | if (this.yy && typeof this.yy.pre_lex === 'function') {
|
3377 | // (also account for a userdef function which does not return any value: keep the token as is)
|
3378 | r = this.yy.pre_lex.call(this, r) || r;
|
3379 | }
|
3380 |
|
3381 | while (!r) {
|
3382 | r = this.next();
|
3383 | }
|
3384 |
|
3385 | if (this.yy && typeof this.yy.post_lex === 'function') {
|
3386 | // (also account for a userdef function which does not return any value: keep the token as is)
|
3387 | r = this.yy.post_lex.call(this, r) || r;
|
3388 | }
|
3389 |
|
3390 | if (typeof this.options.post_lex === 'function') {
|
3391 | // (also account for a userdef function which does not return any value: keep the token as is)
|
3392 | r = this.options.post_lex.call(this, r) || r;
|
3393 | }
|
3394 |
|
3395 | if (typeof this.post_lex === 'function') {
|
3396 | // (also account for a userdef function which does not return any value: keep the token as is)
|
3397 | r = this.post_lex.call(this, r) || r;
|
3398 | }
|
3399 |
|
3400 | return r;
|
3401 | },
|
3402 |
|
3403 | /**
|
3404 | * return next match that has a token. Identical to the `lex()` API but does not invoke any of the
|
3405 | * `pre_lex()` nor any of the `post_lex()` callbacks.
|
3406 | *
|
3407 | * @public
|
3408 | * @this {RegExpLexer}
|
3409 | */
|
3410 | fastLex: function lexer_fastLex() {
|
3411 | var r;
|
3412 |
|
3413 | while (!r) {
|
3414 | r = this.next();
|
3415 | }
|
3416 |
|
3417 | return r;
|
3418 | },
|
3419 |
|
3420 | /**
|
3421 | * return info about the lexer state that can help a parser or other lexer API user to use the
|
3422 | * most efficient means available. This API is provided to aid run-time performance for larger
|
3423 | * systems which employ this lexer.
|
3424 | *
|
3425 | * @public
|
3426 | * @this {RegExpLexer}
|
3427 | */
|
3428 | canIUse: function lexer_canIUse() {
|
3429 | var rv = {
|
3430 | fastLex: !(typeof this.pre_lex === 'function' || typeof this.options.pre_lex === 'function' || this.yy && typeof this.yy.pre_lex === 'function' || this.yy && typeof this.yy.post_lex === 'function' || typeof this.options.post_lex === 'function' || typeof this.post_lex === 'function') && typeof this.fastLex === 'function'
|
3431 | };
|
3432 |
|
3433 | return rv;
|
3434 | },
|
3435 |
|
3436 | /**
|
3437 | * backwards compatible alias for `pushState()`;
|
3438 | * the latter is symmetrical with `popState()` and we advise to use
|
3439 | * those APIs in any modern lexer code, rather than `begin()`.
|
3440 | *
|
3441 | * @public
|
3442 | * @this {RegExpLexer}
|
3443 | */
|
3444 | begin: function lexer_begin(condition) {
|
3445 | return this.pushState(condition);
|
3446 | },
|
3447 |
|
3448 | /**
|
3449 | * activates a new lexer condition state (pushes the new lexer
|
3450 | * condition state onto the condition stack)
|
3451 | *
|
3452 | * @public
|
3453 | * @this {RegExpLexer}
|
3454 | */
|
3455 | pushState: function lexer_pushState(condition) {
|
3456 | this.conditionStack.push(condition);
|
3457 | this.__currentRuleSet__ = null;
|
3458 | return this;
|
3459 | },
|
3460 |
|
3461 | /**
|
3462 | * pop the previously active lexer condition state off the condition
|
3463 | * stack
|
3464 | *
|
3465 | * @public
|
3466 | * @this {RegExpLexer}
|
3467 | */
|
3468 | popState: function lexer_popState() {
|
3469 | var n = this.conditionStack.length - 1;
|
3470 |
|
3471 | if (n > 0) {
|
3472 | this.__currentRuleSet__ = null;
|
3473 | return this.conditionStack.pop();
|
3474 | } else {
|
3475 | return this.conditionStack[0];
|
3476 | }
|
3477 | },
|
3478 |
|
3479 | /**
|
3480 | * return the currently active lexer condition state; when an index
|
3481 | * argument is provided it produces the N-th previous condition state,
|
3482 | * if available
|
3483 | *
|
3484 | * @public
|
3485 | * @this {RegExpLexer}
|
3486 | */
|
3487 | topState: function lexer_topState(n) {
|
3488 | n = this.conditionStack.length - 1 - Math.abs(n || 0);
|
3489 |
|
3490 | if (n >= 0) {
|
3491 | return this.conditionStack[n];
|
3492 | } else {
|
3493 | return 'INITIAL';
|
3494 | }
|
3495 | },
|
3496 |
|
3497 | /**
|
3498 | * (internal) determine the lexer rule set which is active for the
|
3499 | * currently active lexer condition state
|
3500 | *
|
3501 | * @public
|
3502 | * @this {RegExpLexer}
|
3503 | */
|
3504 | _currentRules: function lexer__currentRules() {
|
3505 | if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
|
3506 | return this.conditions[this.conditionStack[this.conditionStack.length - 1]];
|
3507 | } else {
|
3508 | return this.conditions['INITIAL'];
|
3509 | }
|
3510 | },
|
3511 |
|
3512 | /**
|
3513 | * return the number of states currently on the stack
|
3514 | *
|
3515 | * @public
|
3516 | * @this {RegExpLexer}
|
3517 | */
|
3518 | stateStackSize: function lexer_stateStackSize() {
|
3519 | return this.conditionStack.length;
|
3520 | },
|
3521 |
|
3522 | options: {
|
3523 | trackPosition: true,
|
3524 | caseInsensitive: true
|
3525 | },
|
3526 |
|
3527 | JisonLexerError: JisonLexerError,
|
3528 |
|
3529 | performAction: function lexer__performAction(yy, yyrulenumber, YY_START) {
|
3530 | var yy_ = this;
|
3531 | var YYSTATE = YY_START;
|
3532 |
|
3533 | switch (yyrulenumber) {
|
3534 | case 0:
|
3535 | /*! Conditions:: INITIAL */
|
3536 | /*! Rule:: \s+ */
|
3537 | /* skip whitespace */
|
3538 | break;
|
3539 |
|
3540 | case 7:
|
3541 | /*! Conditions:: INITIAL */
|
3542 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)em\b */
|
3543 | return 12; // em
|
3544 |
|
3545 | break;
|
3546 |
|
3547 | case 8:
|
3548 | /*! Conditions:: INITIAL */
|
3549 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)ex\b */
|
3550 | return 12; // ex
|
3551 |
|
3552 | break;
|
3553 |
|
3554 | case 9:
|
3555 | /*! Conditions:: INITIAL */
|
3556 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)ch\b */
|
3557 | return 12; // ch
|
3558 |
|
3559 | break;
|
3560 |
|
3561 | case 10:
|
3562 | /*! Conditions:: INITIAL */
|
3563 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)rem\b */
|
3564 | return 12; // rem
|
3565 |
|
3566 | break;
|
3567 |
|
3568 | case 11:
|
3569 | /*! Conditions:: INITIAL */
|
3570 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)vw\b */
|
3571 | return 12; // vw
|
3572 |
|
3573 | break;
|
3574 |
|
3575 | case 12:
|
3576 | /*! Conditions:: INITIAL */
|
3577 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)vh\b */
|
3578 | return 12; // vh
|
3579 |
|
3580 | break;
|
3581 |
|
3582 | case 13:
|
3583 | /*! Conditions:: INITIAL */
|
3584 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)vmin\b */
|
3585 | return 12; // vmin
|
3586 |
|
3587 | break;
|
3588 |
|
3589 | case 14:
|
3590 | /*! Conditions:: INITIAL */
|
3591 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)vmax\b */
|
3592 | return 12; // vmax
|
3593 |
|
3594 | break;
|
3595 |
|
3596 | case 15:
|
3597 | /*! Conditions:: INITIAL */
|
3598 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)vm\b */
|
3599 | return 12; // vm (non-standard name)
|
3600 |
|
3601 | break;
|
3602 |
|
3603 | case 16:
|
3604 | /*! Conditions:: INITIAL */
|
3605 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)px\b */
|
3606 | return 12; // px
|
3607 |
|
3608 | break;
|
3609 |
|
3610 | case 17:
|
3611 | /*! Conditions:: INITIAL */
|
3612 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)mm\b */
|
3613 | return 12; // mm
|
3614 |
|
3615 | break;
|
3616 |
|
3617 | case 18:
|
3618 | /*! Conditions:: INITIAL */
|
3619 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)cm\b */
|
3620 | return 12; // cm
|
3621 |
|
3622 | break;
|
3623 |
|
3624 | case 19:
|
3625 | /*! Conditions:: INITIAL */
|
3626 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)in\b */
|
3627 | return 12; // in
|
3628 |
|
3629 | break;
|
3630 |
|
3631 | case 20:
|
3632 | /*! Conditions:: INITIAL */
|
3633 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)pt\b */
|
3634 | return 12; // pt
|
3635 |
|
3636 | break;
|
3637 |
|
3638 | case 21:
|
3639 | /*! Conditions:: INITIAL */
|
3640 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)pc\b */
|
3641 | return 12; // pc
|
3642 |
|
3643 | break;
|
3644 |
|
3645 | case 22:
|
3646 | /*! Conditions:: INITIAL */
|
3647 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)Q\b */
|
3648 | return 12; // Q
|
3649 |
|
3650 | break;
|
3651 |
|
3652 | case 23:
|
3653 | /*! Conditions:: INITIAL */
|
3654 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)fr\b */
|
3655 | return 12; // fr
|
3656 |
|
3657 | break;
|
3658 |
|
3659 | case 24:
|
3660 | /*! Conditions:: INITIAL */
|
3661 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)deg\b */
|
3662 | return 13; // deg
|
3663 |
|
3664 | break;
|
3665 |
|
3666 | case 25:
|
3667 | /*! Conditions:: INITIAL */
|
3668 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)grad\b */
|
3669 | return 13; // grad
|
3670 |
|
3671 | break;
|
3672 |
|
3673 | case 26:
|
3674 | /*! Conditions:: INITIAL */
|
3675 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)turn\b */
|
3676 | return 13; // turn
|
3677 |
|
3678 | break;
|
3679 |
|
3680 | case 27:
|
3681 | /*! Conditions:: INITIAL */
|
3682 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)rad\b */
|
3683 | return 13; // rad
|
3684 |
|
3685 | break;
|
3686 |
|
3687 | case 28:
|
3688 | /*! Conditions:: INITIAL */
|
3689 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)s\b */
|
3690 | return 14; // s
|
3691 |
|
3692 | break;
|
3693 |
|
3694 | case 29:
|
3695 | /*! Conditions:: INITIAL */
|
3696 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)ms\b */
|
3697 | return 14; // ms
|
3698 |
|
3699 | break;
|
3700 |
|
3701 | case 30:
|
3702 | /*! Conditions:: INITIAL */
|
3703 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)Hz\b */
|
3704 | return 15; // Hz
|
3705 |
|
3706 | break;
|
3707 |
|
3708 | case 31:
|
3709 | /*! Conditions:: INITIAL */
|
3710 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)kHz\b */
|
3711 | return 15; // kHz
|
3712 |
|
3713 | break;
|
3714 |
|
3715 | case 32:
|
3716 | /*! Conditions:: INITIAL */
|
3717 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)dpi\b */
|
3718 | return 16; // dpi
|
3719 |
|
3720 | break;
|
3721 |
|
3722 | case 33:
|
3723 | /*! Conditions:: INITIAL */
|
3724 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)dpcm\b */
|
3725 | return 16; // dpcm
|
3726 |
|
3727 | break;
|
3728 |
|
3729 | case 34:
|
3730 | /*! Conditions:: INITIAL */
|
3731 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)dppx\b */
|
3732 | return 16; // dppm
|
3733 |
|
3734 | break;
|
3735 |
|
3736 | case 39:
|
3737 | /*! Conditions:: INITIAL */
|
3738 | /*! Rule:: #\{([\s\S]*?)\} */
|
3739 | return 18; // scss variable
|
3740 |
|
3741 | break;
|
3742 |
|
3743 | case 40:
|
3744 | /*! Conditions:: INITIAL */
|
3745 | /*! Rule:: @\{([\s\S]*?)\} */
|
3746 | return 18; // less variable
|
3747 |
|
3748 | break;
|
3749 |
|
3750 | default:
|
3751 | return this.simpleCaseActionClusters[yyrulenumber];
|
3752 | }
|
3753 | },
|
3754 |
|
3755 | simpleCaseActionClusters: {
|
3756 | /*! Conditions:: INITIAL */
|
3757 | /*! Rule:: (-(webkit|moz)-)?calc\b */
|
3758 | 1: 3,
|
3759 |
|
3760 | /*! Conditions:: INITIAL */
|
3761 | /*! Rule:: [a-z][a-z0-9-]*\s*\((?:(?:"(?:\\.|[^\"\\])*"|'(?:\\.|[^\'\\])*')|\([^)]*\)|[^\(\)]*)*\) */
|
3762 | 2: 11,
|
3763 |
|
3764 | /*! Conditions:: INITIAL */
|
3765 | /*! Rule:: \* */
|
3766 | 3: 8,
|
3767 |
|
3768 | /*! Conditions:: INITIAL */
|
3769 | /*! Rule:: \/ */
|
3770 | 4: 9,
|
3771 |
|
3772 | /*! Conditions:: INITIAL */
|
3773 | /*! Rule:: \+ */
|
3774 | 5: 6,
|
3775 |
|
3776 | /*! Conditions:: INITIAL */
|
3777 | /*! Rule:: - */
|
3778 | 6: 7,
|
3779 |
|
3780 | /*! Conditions:: INITIAL */
|
3781 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)% */
|
3782 | 35: 17,
|
3783 |
|
3784 | /*! Conditions:: INITIAL */
|
3785 | /*! Rule:: ([0-9]+(\.[0-9]+)?|\.[0-9]+)\b */
|
3786 | 36: 10,
|
3787 |
|
3788 | /*! Conditions:: INITIAL */
|
3789 | /*! Rule:: \( */
|
3790 | 37: 4,
|
3791 |
|
3792 | /*! Conditions:: INITIAL */
|
3793 | /*! Rule:: \) */
|
3794 | 38: 5,
|
3795 |
|
3796 | /*! Conditions:: INITIAL */
|
3797 | /*! Rule:: \S[^\s()*\/+-]* */
|
3798 | 41: 18,
|
3799 |
|
3800 | /*! Conditions:: INITIAL */
|
3801 | /*! Rule:: $ */
|
3802 | 42: 1
|
3803 | },
|
3804 |
|
3805 | rules: [
|
3806 | /* 0: */ /^(?:\s+)/i,
|
3807 | /* 1: */ /^(?:(-(webkit|moz)-)?calc\b)/i,
|
3808 | /* 2: */ /^(?:[a-z][\d\-a-z]*\s*\((?:(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|\([^)]*\)|[^()]*)*\))/i,
|
3809 | /* 3: */ /^(?:\*)/i,
|
3810 | /* 4: */ /^(?:\/)/i,
|
3811 | /* 5: */ /^(?:\+)/i,
|
3812 | /* 6: */ /^(?:-)/i,
|
3813 | /* 7: */ /^(?:(\d+(\.\d+)?|\.\d+)em\b)/i,
|
3814 | /* 8: */ /^(?:(\d+(\.\d+)?|\.\d+)ex\b)/i,
|
3815 | /* 9: */ /^(?:(\d+(\.\d+)?|\.\d+)ch\b)/i,
|
3816 | /* 10: */ /^(?:(\d+(\.\d+)?|\.\d+)rem\b)/i,
|
3817 | /* 11: */ /^(?:(\d+(\.\d+)?|\.\d+)vw\b)/i,
|
3818 | /* 12: */ /^(?:(\d+(\.\d+)?|\.\d+)vh\b)/i,
|
3819 | /* 13: */ /^(?:(\d+(\.\d+)?|\.\d+)vmin\b)/i,
|
3820 | /* 14: */ /^(?:(\d+(\.\d+)?|\.\d+)vmax\b)/i,
|
3821 | /* 15: */ /^(?:(\d+(\.\d+)?|\.\d+)vm\b)/i,
|
3822 | /* 16: */ /^(?:(\d+(\.\d+)?|\.\d+)px\b)/i,
|
3823 | /* 17: */ /^(?:(\d+(\.\d+)?|\.\d+)mm\b)/i,
|
3824 | /* 18: */ /^(?:(\d+(\.\d+)?|\.\d+)cm\b)/i,
|
3825 | /* 19: */ /^(?:(\d+(\.\d+)?|\.\d+)in\b)/i,
|
3826 | /* 20: */ /^(?:(\d+(\.\d+)?|\.\d+)pt\b)/i,
|
3827 | /* 21: */ /^(?:(\d+(\.\d+)?|\.\d+)pc\b)/i,
|
3828 | /* 22: */ /^(?:(\d+(\.\d+)?|\.\d+)Q\b)/i,
|
3829 | /* 23: */ /^(?:(\d+(\.\d+)?|\.\d+)fr\b)/i,
|
3830 | /* 24: */ /^(?:(\d+(\.\d+)?|\.\d+)deg\b)/i,
|
3831 | /* 25: */ /^(?:(\d+(\.\d+)?|\.\d+)grad\b)/i,
|
3832 | /* 26: */ /^(?:(\d+(\.\d+)?|\.\d+)turn\b)/i,
|
3833 | /* 27: */ /^(?:(\d+(\.\d+)?|\.\d+)rad\b)/i,
|
3834 | /* 28: */ /^(?:(\d+(\.\d+)?|\.\d+)s\b)/i,
|
3835 | /* 29: */ /^(?:(\d+(\.\d+)?|\.\d+)ms\b)/i,
|
3836 | /* 30: */ /^(?:(\d+(\.\d+)?|\.\d+)Hz\b)/i,
|
3837 | /* 31: */ /^(?:(\d+(\.\d+)?|\.\d+)kHz\b)/i,
|
3838 | /* 32: */ /^(?:(\d+(\.\d+)?|\.\d+)dpi\b)/i,
|
3839 | /* 33: */ /^(?:(\d+(\.\d+)?|\.\d+)dpcm\b)/i,
|
3840 | /* 34: */ /^(?:(\d+(\.\d+)?|\.\d+)dppx\b)/i,
|
3841 | /* 35: */ /^(?:(\d+(\.\d+)?|\.\d+)%)/i,
|
3842 | /* 36: */ /^(?:(\d+(\.\d+)?|\.\d+)\b)/i,
|
3843 | /* 37: */ /^(?:\()/i,
|
3844 | /* 38: */ /^(?:\))/i,
|
3845 | /* 39: */ /^(?:#\{([\s\S]*?)\})/i,
|
3846 | /* 40: */ /^(?:@\{([\s\S]*?)\})/i,
|
3847 | /* 41: */ /^(?:\S[^\s()*\/+-]*)/i,
|
3848 | /* 42: */ /^(?:$)/i
|
3849 | ],
|
3850 |
|
3851 | conditions: {
|
3852 | 'INITIAL': {
|
3853 | rules: [
|
3854 | 0,
|
3855 | 1,
|
3856 | 2,
|
3857 | 3,
|
3858 | 4,
|
3859 | 5,
|
3860 | 6,
|
3861 | 7,
|
3862 | 8,
|
3863 | 9,
|
3864 | 10,
|
3865 | 11,
|
3866 | 12,
|
3867 | 13,
|
3868 | 14,
|
3869 | 15,
|
3870 | 16,
|
3871 | 17,
|
3872 | 18,
|
3873 | 19,
|
3874 | 20,
|
3875 | 21,
|
3876 | 22,
|
3877 | 23,
|
3878 | 24,
|
3879 | 25,
|
3880 | 26,
|
3881 | 27,
|
3882 | 28,
|
3883 | 29,
|
3884 | 30,
|
3885 | 31,
|
3886 | 32,
|
3887 | 33,
|
3888 | 34,
|
3889 | 35,
|
3890 | 36,
|
3891 | 37,
|
3892 | 38,
|
3893 | 39,
|
3894 | 40,
|
3895 | 41,
|
3896 | 42
|
3897 | ],
|
3898 |
|
3899 | inclusive: true
|
3900 | }
|
3901 | }
|
3902 | };
|
3903 |
|
3904 | return lexer;
|
3905 | }();
|
3906 | parser.lexer = lexer;
|
3907 |
|
3908 |
|
3909 |
|
3910 | function Parser() {
|
3911 | this.yy = {};
|
3912 | }
|
3913 | Parser.prototype = parser;
|
3914 | parser.Parser = Parser;
|
3915 |
|
3916 | return new Parser();
|
3917 | })();
|
3918 |
|
3919 |
|
3920 |
|
3921 |
|
3922 | if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
3923 | exports.parser = parser;
|
3924 | exports.Parser = parser.Parser;
|
3925 | exports.parse = function () {
|
3926 | return parser.parse.apply(parser, arguments);
|
3927 | };
|
3928 |
|
3929 | }
|