coco c6cf38a: lexer: refactored @balancedString

This commit is contained in:
Jeremy Ashkenas 2010-11-15 23:59:52 -05:00
parent eb959b3879
commit ee6f24b48a
2 changed files with 37 additions and 54 deletions

View File

@ -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;
for (_i = 0, _len = delimited.length; _i < _len; _i++) { case stack[stack.length - 1][1]:
pair = delimited[_i]; stack.pop();
open = pair[0], close = pair[1]; if (!stack.length) {
if (levels.length && starts(str, close, i) && last(levels) === pair) { return str.slice(0, i + 1);
levels.pop();
i += close.length - 1;
if (!levels.length) {
i += 1;
}
break;
}
if (starts(str, open, i)) {
levels.push(pair);
i += open.length - 1;
break;
} }
continue;
}
for (_i = 0, _len = delimited.length; _i < _len; _i++) {
pair = delimited[_i];
if ((open = pair[0]) === str.substr(i, open.length)) {
stack.push(pair);
i += open.length - 1;
break;
} }
} }
if (!levels.length) {
break;
}
i += 1;
} }
if (levels.length) { throw new Error("unterminated " + (stack.pop()[0]) + " on line " + (this.line + 1));
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;

View File

@ -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 i += open.length - 1
break break
if starts str, open, i throw new Error "unterminated #{ stack.pop()[0] } on line #{ @line + 1 }"
levels.push(pair)
i += open.length - 1
break
break if not levels.length
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.