coco c6cf38a: lexer: refactored @balancedString
This commit is contained in:
parent
eb959b3879
commit
ee6f24b48a
46
lib/lexer.js
46
lib/lexer.js
|
@ -459,42 +459,32 @@
|
||||||
throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||||
};
|
};
|
||||||
Lexer.prototype.balancedString = function(str, delimited, options) {
|
Lexer.prototype.balancedString = function(str, delimited, options) {
|
||||||
var close, i, levels, open, pair, slen, _i, _len;
|
var i, open, pair, stack, _i, _len, _to;
|
||||||
options == null && (options = {});
|
options == null && (options = {});
|
||||||
levels = [];
|
stack = [delimited[0]];
|
||||||
i = 0;
|
for (i = 1, _to = str.length - 1; 1 <= _to ? i <= _to : i >= _to; 1 <= _to ? i++ : i--) {
|
||||||
slen = str.length;
|
switch (str.charAt(i)) {
|
||||||
while (i < slen) {
|
case '\\':
|
||||||
if (levels.length && str.charAt(i) === '\\') {
|
i++;
|
||||||
i += 1;
|
continue;
|
||||||
} else {
|
break;
|
||||||
|
case stack[stack.length - 1][1]:
|
||||||
|
stack.pop();
|
||||||
|
if (!stack.length) {
|
||||||
|
return str.slice(0, i + 1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (_i = 0, _len = delimited.length; _i < _len; _i++) {
|
for (_i = 0, _len = delimited.length; _i < _len; _i++) {
|
||||||
pair = delimited[_i];
|
pair = delimited[_i];
|
||||||
open = pair[0], close = pair[1];
|
if ((open = pair[0]) === str.substr(i, open.length)) {
|
||||||
if (levels.length && starts(str, close, i) && last(levels) === pair) {
|
stack.push(pair);
|
||||||
levels.pop();
|
|
||||||
i += close.length - 1;
|
|
||||||
if (!levels.length) {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (starts(str, open, i)) {
|
|
||||||
levels.push(pair);
|
|
||||||
i += open.length - 1;
|
i += open.length - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!levels.length) {
|
throw new Error("unterminated " + (stack.pop()[0]) + " on line " + (this.line + 1));
|
||||||
break;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
if (levels.length) {
|
|
||||||
throw SyntaxError("Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1));
|
|
||||||
}
|
|
||||||
return i && str.slice(0, i);
|
|
||||||
};
|
};
|
||||||
Lexer.prototype.interpolateString = function(str, options) {
|
Lexer.prototype.interpolateString = function(str, options) {
|
||||||
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _this;
|
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _this;
|
||||||
|
|
|
@ -398,29 +398,22 @@ exports.Lexer = class Lexer
|
||||||
# contents of the string. This method allows us to have strings within
|
# contents of the string. This method allows us to have strings within
|
||||||
# interpolations within strings, ad infinitum.
|
# interpolations within strings, ad infinitum.
|
||||||
balancedString: (str, delimited, options = {}) ->
|
balancedString: (str, delimited, options = {}) ->
|
||||||
levels = []
|
stack = [delimited[0]]
|
||||||
i = 0
|
for i from 1 to str.length - 1
|
||||||
slen = str.length
|
switch str.charAt i
|
||||||
while i < slen
|
when '\\'
|
||||||
if levels.length and str.charAt(i) is '\\'
|
i++
|
||||||
i += 1
|
continue
|
||||||
else
|
when stack[stack.length - 1][1]
|
||||||
for pair in delimited
|
stack.pop()
|
||||||
[open, close] = pair
|
return str.slice 0, i + 1 unless stack.length
|
||||||
if levels.length and starts(str, close, i) and last(levels) is pair
|
continue
|
||||||
levels.pop()
|
for pair in delimited when (open = pair[0]) is str.substr i, open.length
|
||||||
i += close.length - 1
|
stack.push pair
|
||||||
i += 1 unless levels.length
|
|
||||||
break
|
|
||||||
if starts str, open, i
|
|
||||||
levels.push(pair)
|
|
||||||
i += open.length - 1
|
i += open.length - 1
|
||||||
break
|
break
|
||||||
break if not levels.length
|
throw new Error "unterminated #{ stack.pop()[0] } on line #{ @line + 1 }"
|
||||||
i += 1
|
|
||||||
if levels.length
|
|
||||||
throw SyntaxError "Unterminated #{levels.pop()[0]} starting on line #{@line + 1}"
|
|
||||||
i and str.slice 0, i
|
|
||||||
|
|
||||||
# Expand variables and expressions inside double-quoted strings using
|
# Expand variables and expressions inside double-quoted strings using
|
||||||
# Ruby-like notation for substitution of arbitrary expressions.
|
# Ruby-like notation for substitution of arbitrary expressions.
|
||||||
|
|
Loading…
Reference in New Issue