Index: src/ast.h |
diff --git a/src/ast.h b/src/ast.h |
index 14f71a6cc28bfb03e95f2f767c97cce90727542d..63568c2265f563e66b7f7821be6b8d188c69d869 100644 |
--- a/src/ast.h |
+++ b/src/ast.h |
@@ -119,7 +119,7 @@ class RegExpCharacterClass; |
class RegExpCompiler; |
class RegExpDisjunction; |
class RegExpEmpty; |
-class RegExpLookahead; |
+class RegExpLookaround; |
class RegExpQuantifier; |
class RegExpText; |
@@ -2832,7 +2832,11 @@ class RegExpVisitor BASE_EMBEDDED { |
class RegExpTree : public ZoneObject { |
public: |
+ enum ReadDirection { READ_FORWARD, READ_BACKWARD }; |
+ |
static const int kInfinity = kMaxInt; |
+ explicit RegExpTree(ReadDirection read_direction) |
+ : read_direction_(read_direction) {} |
virtual ~RegExpTree() {} |
virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; |
virtual RegExpNode* ToNode(RegExpCompiler* compiler, |
@@ -2852,12 +2856,19 @@ class RegExpTree : public ZoneObject { |
virtual bool Is##Name(); |
FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) |
#undef MAKE_ASTYPE |
+ |
+ ReadDirection read_direction() const { return read_direction_; } |
+ bool read_backward() const { return read_direction_ == READ_BACKWARD; } |
+ |
+ protected: |
+ ReadDirection read_direction_; |
}; |
class RegExpDisjunction final : public RegExpTree { |
public: |
- explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); |
+ RegExpDisjunction(ZoneList<RegExpTree*>* alternatives, |
+ ReadDirection read_direction); |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpDisjunction* AsDisjunction() override; |
@@ -2880,7 +2891,7 @@ class RegExpDisjunction final : public RegExpTree { |
class RegExpAlternative final : public RegExpTree { |
public: |
- explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); |
+ RegExpAlternative(ZoneList<RegExpTree*>* nodes, ReadDirection read_direction); |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpAlternative* AsAlternative() override; |
@@ -2908,7 +2919,8 @@ class RegExpAssertion final : public RegExpTree { |
BOUNDARY, |
NON_BOUNDARY |
}; |
- explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { } |
+ RegExpAssertion(AssertionType type, ReadDirection read_direction) |
+ : RegExpTree(read_direction), assertion_type_(type) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpAssertion* AsAssertion() override; |
@@ -2948,12 +2960,11 @@ class CharacterSet final BASE_EMBEDDED { |
class RegExpCharacterClass final : public RegExpTree { |
public: |
- RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated) |
- : set_(ranges), |
- is_negated_(is_negated) { } |
- explicit RegExpCharacterClass(uc16 type) |
- : set_(type), |
- is_negated_(false) { } |
+ RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated, |
+ ReadDirection read_direction) |
+ : RegExpTree(read_direction), set_(ranges), is_negated_(is_negated) {} |
+ RegExpCharacterClass(uc16 type, ReadDirection read_direction) |
+ : RegExpTree(read_direction), set_(type), is_negated_(false) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpCharacterClass* AsCharacterClass() override; |
@@ -2989,7 +3000,8 @@ class RegExpCharacterClass final : public RegExpTree { |
class RegExpAtom final : public RegExpTree { |
public: |
- explicit RegExpAtom(Vector<const uc16> data) : data_(data) { } |
+ RegExpAtom(Vector<const uc16> data, ReadDirection read_direction) |
+ : RegExpTree(read_direction), data_(data) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpAtom* AsAtom() override; |
@@ -3007,7 +3019,8 @@ class RegExpAtom final : public RegExpTree { |
class RegExpText final : public RegExpTree { |
public: |
- explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {} |
+ RegExpText(Zone* zone, ReadDirection read_direction) |
+ : RegExpTree(read_direction), elements_(2, zone), length_(0) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpText* AsText() override; |
@@ -3030,8 +3043,10 @@ class RegExpText final : public RegExpTree { |
class RegExpQuantifier final : public RegExpTree { |
public: |
enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE }; |
- RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body) |
- : body_(body), |
+ RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body, |
+ ReadDirection read_direction) |
+ : RegExpTree(read_direction), |
+ body_(body), |
min_(min), |
max_(max), |
min_match_(min * body->min_match()), |
@@ -3075,8 +3090,8 @@ class RegExpQuantifier final : public RegExpTree { |
class RegExpCapture final : public RegExpTree { |
public: |
- explicit RegExpCapture(RegExpTree* body, int index) |
- : body_(body), index_(index) { } |
+ explicit RegExpCapture(int index) |
+ : RegExpTree(READ_FORWARD), body_(NULL), index_(index) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
static RegExpNode* ToNode(RegExpTree* body, |
@@ -3088,9 +3103,18 @@ class RegExpCapture final : public RegExpTree { |
bool IsAnchoredAtEnd() override; |
Interval CaptureRegisters() override; |
bool IsCapture() override; |
- int min_match() override { return body_->min_match(); } |
- int max_match() override { return body_->max_match(); } |
+ // If body_ is not yet set, the capture is back referenced but not parsed yet. |
+ // In the ordinary case, nothing has been captured yet, so the back reference |
+ // must have the length 0. |
+ // If the back reference is inside a lookbehind, effectively making it a |
+ // forward reference, we return 0 since lookbehinds have a length of 0. |
+ int min_match() override { return body_ ? body_->min_match() : 0; } |
+ int max_match() override { return body_ ? body_->max_match() : 0; } |
RegExpTree* body() { return body_; } |
+ void set_body(RegExpTree* body) { body_ = body; } |
+ void set_read_direction(ReadDirection read_direction) { |
+ read_direction_ = read_direction; |
+ } |
int index() { return index_; } |
static int StartRegister(int index) { return index * 2; } |
static int EndRegister(int index) { return index * 2 + 1; } |
@@ -3101,22 +3125,21 @@ class RegExpCapture final : public RegExpTree { |
}; |
-class RegExpLookahead final : public RegExpTree { |
+class RegExpLookaround final : public RegExpTree { |
public: |
- RegExpLookahead(RegExpTree* body, |
- bool is_positive, |
- int capture_count, |
- int capture_from) |
- : body_(body), |
+ RegExpLookaround(RegExpTree* body, bool is_positive, int capture_count, |
+ int capture_from, ReadDirection read_direction) |
+ : RegExpTree(read_direction), |
+ body_(body), |
is_positive_(is_positive), |
capture_count_(capture_count), |
- capture_from_(capture_from) { } |
+ capture_from_(capture_from) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
- RegExpLookahead* AsLookahead() override; |
+ RegExpLookaround* AsLookaround() override; |
Interval CaptureRegisters() override; |
- bool IsLookahead() override; |
+ bool IsLookaround() override; |
bool IsAnchoredAtStart() override; |
int min_match() override { return 0; } |
int max_match() override { return 0; } |
@@ -3135,8 +3158,8 @@ class RegExpLookahead final : public RegExpTree { |
class RegExpBackReference final : public RegExpTree { |
public: |
- explicit RegExpBackReference(RegExpCapture* capture) |
- : capture_(capture) { } |
+ RegExpBackReference(RegExpCapture* capture, ReadDirection read_direction) |
+ : RegExpTree(read_direction), capture_(capture) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpBackReference* AsBackReference() override; |
@@ -3152,7 +3175,7 @@ class RegExpBackReference final : public RegExpTree { |
class RegExpEmpty final : public RegExpTree { |
public: |
- RegExpEmpty() { } |
+ RegExpEmpty() : RegExpTree(READ_FORWARD) {} |
void* Accept(RegExpVisitor* visitor, void* data) override; |
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
RegExpEmpty* AsEmpty() override; |