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