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