Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 279f39c502e1aed0a672bab4f62cc0ccc41cfcd6..22efbac101d7586efeac9efcd826f9c2f7b67e1f 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -5193,7 +5193,6 @@ |
in_(in), |
current_(kEndMarker), |
next_pos_(0), |
- captures_started_(0), |
capture_count_(0), |
has_more_(true), |
multiline_(multiline), |
@@ -5297,26 +5296,25 @@ |
// Atom Quantifier |
RegExpTree* RegExpParser::ParseDisjunction() { |
// Used to store current state while parsing subexpressions. |
- RegExpParserState initial_state(NULL, INITIAL, RegExpLookaround::LOOKAHEAD, 0, |
- zone()); |
- RegExpParserState* state = &initial_state; |
+ RegExpParserState initial_state(NULL, INITIAL, 0, zone()); |
+ RegExpParserState* stored_state = &initial_state; |
// Cache the builder in a local variable for quick access. |
RegExpBuilder* builder = initial_state.builder(); |
while (true) { |
switch (current()) { |
case kEndMarker: |
- if (state->IsSubexpression()) { |
+ if (stored_state->IsSubexpression()) { |
// Inside a parenthesized group when hitting end of input. |
ReportError(CStrVector("Unterminated group") CHECK_FAILED); |
} |
- DCHECK_EQ(INITIAL, state->group_type()); |
+ DCHECK_EQ(INITIAL, stored_state->group_type()); |
// Parsing completed successfully. |
return builder->ToRegExp(); |
case ')': { |
- if (!state->IsSubexpression()) { |
+ if (!stored_state->IsSubexpression()) { |
ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); |
} |
- DCHECK_NE(INITIAL, state->group_type()); |
+ DCHECK_NE(INITIAL, stored_state->group_type()); |
Advance(); |
// End disjunction parsing and convert builder content to new single |
@@ -5325,27 +5323,27 @@ |
int end_capture_index = captures_started(); |
- int capture_index = state->capture_index(); |
- SubexpressionType group_type = state->group_type(); |
+ int capture_index = stored_state->capture_index(); |
+ SubexpressionType group_type = stored_state->group_type(); |
+ |
+ // Restore previous state. |
+ stored_state = stored_state->previous_state(); |
+ builder = stored_state->builder(); |
// Build result of subexpression. |
if (group_type == CAPTURE) { |
- RegExpCapture* capture = GetCapture(capture_index); |
- capture->set_body(body); |
+ RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); |
+ captures_->at(capture_index - 1) = capture; |
body = capture; |
} else if (group_type != GROUPING) { |
- DCHECK(group_type == POSITIVE_LOOKAROUND || |
- group_type == NEGATIVE_LOOKAROUND); |
- bool is_positive = (group_type == POSITIVE_LOOKAROUND); |
- body = new (zone()) RegExpLookaround( |
- body, is_positive, end_capture_index - capture_index, capture_index, |
- state->lookaround_type()); |
- } |
- |
- // Restore previous state. |
- state = state->previous_state(); |
- builder = state->builder(); |
- |
+ DCHECK(group_type == POSITIVE_LOOKAHEAD || |
+ group_type == NEGATIVE_LOOKAHEAD); |
+ bool is_positive = (group_type == POSITIVE_LOOKAHEAD); |
+ body = new(zone()) RegExpLookahead(body, |
+ is_positive, |
+ end_capture_index - capture_index, |
+ capture_index); |
+ } |
builder->AddAtom(body); |
// For compatability with JSC and ES3, we allow quantifiers after |
// lookaheads, and break in all cases. |
@@ -5392,7 +5390,6 @@ |
} |
case '(': { |
SubexpressionType subexpr_type = CAPTURE; |
- RegExpLookaround::Type lookaround_type = state->lookaround_type(); |
Advance(); |
if (current() == '?') { |
switch (Next()) { |
@@ -5400,41 +5397,29 @@ |
subexpr_type = GROUPING; |
break; |
case '=': |
- lookaround_type = RegExpLookaround::LOOKAHEAD; |
- subexpr_type = POSITIVE_LOOKAROUND; |
+ subexpr_type = POSITIVE_LOOKAHEAD; |
break; |
case '!': |
- lookaround_type = RegExpLookaround::LOOKAHEAD; |
- subexpr_type = NEGATIVE_LOOKAROUND; |
+ subexpr_type = NEGATIVE_LOOKAHEAD; |
break; |
- case '<': |
- if (FLAG_harmony_regexp_lookbehind) { |
- Advance(); |
- lookaround_type = RegExpLookaround::LOOKBEHIND; |
- if (Next() == '=') { |
- subexpr_type = POSITIVE_LOOKAROUND; |
- break; |
- } else if (Next() == '!') { |
- subexpr_type = NEGATIVE_LOOKAROUND; |
- break; |
- } |
- } |
- // Fall through. |
default: |
ReportError(CStrVector("Invalid group") CHECK_FAILED); |
break; |
} |
Advance(2); |
} else { |
- if (captures_started_ >= kMaxCaptures) { |
+ if (captures_ == NULL) { |
+ captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone()); |
+ } |
+ if (captures_started() >= kMaxCaptures) { |
ReportError(CStrVector("Too many captures") CHECK_FAILED); |
} |
- captures_started_++; |
+ captures_->Add(NULL, zone()); |
} |
// Store current state and begin new disjunction parsing. |
- state = new (zone()) RegExpParserState( |
- state, subexpr_type, lookaround_type, captures_started_, zone()); |
- builder = state->builder(); |
+ stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type, |
+ captures_started(), zone()); |
+ builder = stored_state->builder(); |
continue; |
} |
case '[': { |
@@ -5477,15 +5462,16 @@ |
case '7': case '8': case '9': { |
int index = 0; |
if (ParseBackReferenceIndex(&index)) { |
- if (state->IsInsideCaptureGroup(index)) { |
- // The backreference is inside the capture group it refers to. |
- // Nothing can possibly have been captured yet. |
+ RegExpCapture* capture = NULL; |
+ if (captures_ != NULL && index <= captures_->length()) { |
+ capture = captures_->at(index - 1); |
+ } |
+ if (capture == NULL) { |
builder->AddEmpty(); |
- } else { |
- RegExpCapture* capture = GetCapture(index); |
- RegExpTree* atom = new (zone()) RegExpBackReference(capture); |
- builder->AddAtom(atom); |
+ break; |
} |
+ RegExpTree* atom = new(zone()) RegExpBackReference(capture); |
+ builder->AddAtom(atom); |
break; |
} |
uc32 first_digit = Next(); |
@@ -5746,34 +5732,6 @@ |
} |
-RegExpCapture* RegExpParser::GetCapture(int index) { |
- // The index for the capture groups are one-based. Its index in the list is |
- // zero-based. |
- int know_captures = |
- is_scanned_for_captures_ ? capture_count_ : captures_started_; |
- DCHECK(index <= know_captures); |
- if (captures_ == NULL) { |
- captures_ = new (zone()) ZoneList<RegExpCapture*>(know_captures, zone()); |
- } |
- while (captures_->length() < know_captures) { |
- captures_->Add(new (zone()) RegExpCapture(captures_->length() + 1), zone()); |
- } |
- return captures_->at(index - 1); |
-} |
- |
- |
-bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(int index) { |
- for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) { |
- if (s->group_type() != CAPTURE) continue; |
- // Return true if we found the matching capture index. |
- if (index == s->capture_index()) return true; |
- // Abort if index is larger than what has been parsed up till this state. |
- if (index > s->capture_index()) return false; |
- } |
- return false; |
-} |
- |
- |
// QuantifierPrefix :: |
// { DecimalDigits } |
// { DecimalDigits , } |
@@ -6105,7 +6063,7 @@ |
ranges->Add(CharacterRange::Everything(), zone()); |
is_negated = !is_negated; |
} |
- return new (zone()) RegExpCharacterClass(ranges, is_negated); |
+ return new(zone()) RegExpCharacterClass(ranges, is_negated); |
} |