Author: [EMAIL PROTECTED]
Date: Fri Nov 14 13:45:53 2008
New Revision: 762
Modified:
branches/experimental/regexp2000/src/ast.cc
branches/experimental/regexp2000/src/ast.h
branches/experimental/regexp2000/src/jsregexp.cc
branches/experimental/regexp2000/src/jsregexp.h
branches/experimental/regexp2000/src/parser.cc
branches/experimental/regexp2000/test/cctest/test-regexp.cc
Log:
Replaced atom and character class nodes by text nodes that contain a
sequence of each.
Modified: branches/experimental/regexp2000/src/ast.cc
==============================================================================
--- branches/experimental/regexp2000/src/ast.cc (original)
+++ branches/experimental/regexp2000/src/ast.cc Fri Nov 14 13:45:53 2008
@@ -187,21 +187,21 @@
void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \
return visitor->Visit##Name(this, data); \
}
-FOR_EACH_REG_EXP_NODE_TYPE(MAKE_ACCEPT)
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
#undef MAKE_ACCEPT
#define MAKE_CONVERSION(Name) \
RegExp##Name* RegExpTree::As##Name() { \
return NULL; \
}
- FOR_EACH_REG_EXP_NODE_TYPE(MAKE_CONVERSION)
+ FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CONVERSION)
#undef MAKE_CONVERSION
#define MAKE_CONVERSION(Name) \
RegExp##Name* RegExp##Name::As##Name() { \
return this; \
}
-FOR_EACH_REG_EXP_NODE_TYPE(MAKE_CONVERSION)
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CONVERSION)
#undef MAKE_CONVERSION
RegExpEmpty RegExpEmpty::kInstance;
@@ -218,7 +218,7 @@
void VisitCharacterRange(CharacterRange that);
SmartPointer<const char> ToString() { return stream_.ToCString(); }
#define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void*
data);
- FOR_EACH_REG_EXP_NODE_TYPE(MAKE_CASE)
+ FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
#undef MAKE_CASE
private:
StringStream* stream() { return &stream_; }
@@ -304,6 +304,21 @@
void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
stream()->Add("'%w'", that->data());
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitText(RegExpText* that, void* data) {
+ if (that->elements()->length() == 1) {
+ that->elements()->at(0).data.u_atom->Accept(this, data);
+ } else {
+ stream()->Add("(!");
+ for (int i = 0; i < that->elements()->length(); i++) {
+ stream()->Add(" ");
+ that->elements()->at(i).data.u_atom->Accept(this, data);
+ }
+ stream()->Add(")");
+ }
return NULL;
}
Modified: branches/experimental/regexp2000/src/ast.h
==============================================================================
--- branches/experimental/regexp2000/src/ast.h (original)
+++ branches/experimental/regexp2000/src/ast.h Fri Nov 14 13:45:53 2008
@@ -1191,24 +1191,6 @@
// Regular expressions
-#define FOR_EACH_REG_EXP_NODE_TYPE(VISIT) \
- VISIT(Disjunction) \
- VISIT(Alternative) \
- VISIT(Assertion) \
- VISIT(CharacterClass) \
- VISIT(Atom) \
- VISIT(Quantifier) \
- VISIT(Capture) \
- VISIT(Lookahead) \
- VISIT(Backreference) \
- VISIT(Empty)
-
-
-#define FORWARD_DECLARE(Name) class RegExp##Name;
-FOR_EACH_REG_EXP_NODE_TYPE(FORWARD_DECLARE)
-#undef FORWARD_DECLARE
-
-
class RegExpTree: public ZoneObject {
public:
virtual ~RegExpTree() { }
@@ -1216,9 +1198,11 @@
virtual RegExpNode* ToNode(RegExpCompiler* compiler,
RegExpNode* on_success,
RegExpNode* on_failure) = 0;
+ virtual bool IsTextElement() { return false; }
+ virtual void AppendToText(RegExpText* text);
SmartPointer<const char> ToString();
#define MAKE_ASTYPE(Name) virtual RegExp##Name* As##Name();
- FOR_EACH_REG_EXP_NODE_TYPE(MAKE_ASTYPE)
+ FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
#undef MAKE_ASTYPE
};
@@ -1252,6 +1236,23 @@
};
+class RegExpText: public RegExpTree {
+ public:
+ RegExpText() : elements_(2) { }
+ virtual void* Accept(RegExpVisitor* visitor, void* data);
+ virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+ RegExpNode* on_success,
+ RegExpNode* on_failure);
+ virtual RegExpText* AsText();
+ virtual bool IsTextElement() { return true; }
+ virtual void AppendToText(RegExpText* text);
+ void AddElement(TextElement elm) { elements_.Add(elm); }
+ ZoneList<TextElement>* elements() { return &elements_; }
+ private:
+ ZoneList<TextElement> elements_;
+};
+
+
class RegExpAssertion: public RegExpTree {
public:
enum Type {
@@ -1285,6 +1286,8 @@
RegExpNode* on_success,
RegExpNode* on_failure);
virtual RegExpCharacterClass* AsCharacterClass();
+ virtual bool IsTextElement() { return true; }
+ virtual void AppendToText(RegExpText* text);
ZoneList<CharacterRange>* ranges() { return ranges_; }
bool is_negated() { return is_negated_; }
private:
@@ -1301,6 +1304,8 @@
RegExpNode* on_success,
RegExpNode* on_failure);
virtual RegExpAtom* AsAtom();
+ virtual bool IsTextElement() { return true; }
+ virtual void AppendToText(RegExpText* text);
Vector<const uc16> data() { return data_; }
private:
Vector<const uc16> data_;
@@ -1426,7 +1431,7 @@
virtual ~RegExpVisitor() { }
#define MAKE_CASE(Name) \
virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
- FOR_EACH_REG_EXP_NODE_TYPE(MAKE_CASE)
+ FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
#undef MAKE_CASE
};
Modified: branches/experimental/regexp2000/src/jsregexp.cc
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.cc (original)
+++ branches/experimental/regexp2000/src/jsregexp.cc Fri Nov 14 13:45:53
2008
@@ -788,6 +788,42 @@
// New regular expression engine
+void RegExpTree::AppendToText(RegExpText* text) {
+ UNREACHABLE();
+}
+
+
+void RegExpAtom::AppendToText(RegExpText* text) {
+ text->AddElement(TextElement::Atom(this));
+}
+
+
+void RegExpCharacterClass::AppendToText(RegExpText* text) {
+ text->AddElement(TextElement::CharClass(this));
+}
+
+
+void RegExpText::AppendToText(RegExpText* text) {
+ for (int i = 0; i < elements()->length(); i++)
+ text->AddElement(elements()->at(i));
+}
+
+
+TextElement TextElement::Atom(RegExpAtom* atom) {
+ TextElement result = TextElement(ATOM);
+ result.data.u_atom = atom;
+ return result;
+}
+
+
+TextElement TextElement::CharClass(
+ RegExpCharacterClass* char_class) {
+ TextElement result = TextElement(CHAR_CLASS);
+ result.data.u_char_class = char_class;
+ return result;
+}
+
+
class RegExpCompiler {
public:
explicit RegExpCompiler(int capture_count);
@@ -1136,7 +1172,7 @@
} else {
stream()->Add("|");
}
- stream()->Add("{%k-%k|{", from, from, entry.to());
+ stream()->Add("{\\%k-\\%k|{", from, entry.to());
OutSet* out_set = entry.out_set();
int priority = 0;
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
@@ -1170,10 +1206,33 @@
}
-void DotPrinter::VisitAtom(AtomNode* that) {
- stream()->Add(" n%p [label=\"'%w'\", shape=doubleoctagon];\n",
- that,
- that->data());
+void DotPrinter::VisitText(TextNode* that) {
+ stream()->Add(" n%p [label=\"", that);
+ for (int i = 0; i < that->elements()->length(); i++) {
+ if (i > 0) stream()->Add(" ");
+ TextElement elm = that->elements()->at(i);
+ switch (elm.type) {
+ case TextElement::ATOM: {
+ stream()->Add("'%w'", elm.data.u_atom->data());
+ break;
+ }
+ case TextElement::CHAR_CLASS: {
+ RegExpCharacterClass* node = elm.data.u_char_class;
+ stream()->Add("[");
+ if (node->is_negated())
+ stream()->Add("^");
+ for (int j = 0; j < node->ranges()->length(); j++) {
+ CharacterRange range = node->ranges()->at(j);
+ stream()->Add("%k-%k", range.from(), range.to());
+ }
+ stream()->Add("]");
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ stream()->Add("\", shape=box, peripheries=2];\n");
stream()->Add(" n%p -> n%p;\n", that, that->on_success());
Visit(that->on_success());
PrintOnFailure(that, that->on_failure());
@@ -1196,39 +1255,24 @@
}
-void DotPrinter::VisitCharacterClass(CharacterClassNode* that) {
- stream()->Add(" n%p [label=\"[", that);
- if (that->is_negated())
- stream()->Add("^");
- for (int i = 0; i < that->ranges()->length(); i++) {
- CharacterRange range = that->ranges()->at(i);
- stream()->Add("%k-%k", range.from(), range.to());
- }
- stream()->Add("]\"];\n");
- stream()->Add(" n%p -> n%p;\n", that, that->on_success());
- Visit(that->on_success());
- PrintOnFailure(that, that->on_failure());
-}
-
-
void DotPrinter::VisitAction(ActionNode* that) {
stream()->Add(" n%p [", that);
switch (that->type_) {
case ActionNode::STORE_REGISTER:
- stream()->Add("label=\"$%i:=%i\", shape=box",
+ stream()->Add("label=\"$%i:=%i\", shape=octagon",
that->data_.u_store_register.reg,
that->data_.u_store_register.value);
break;
case ActionNode::INCREMENT_REGISTER:
- stream()->Add("label=\"$%i++\", shape=box",
+ stream()->Add("label=\"$%i++\", shape=octagon",
that->data_.u_increment_register.reg);
break;
case ActionNode::STORE_POSITION:
- stream()->Add("label=\"$%i:=$pos\", shape=box",
+ stream()->Add("label=\"$%i:=$pos\", shape=octagon",
that->data_.u_position_register.reg);
break;
case ActionNode::RESTORE_POSITION:
- stream()->Add("label=\"$pos:=$%i\", shape=box",
+ stream()->Add("label=\"$pos:=$%i\", shape=octagon",
that->data_.u_position_register.reg);
break;
case ActionNode::BEGIN_SUBMATCH:
@@ -1300,17 +1344,25 @@
RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success,
RegExpNode* on_failure) {
- return new AtomNode(data(), on_success, on_failure);
+ ZoneList<TextElement>* elms = new ZoneList<TextElement>(1);
+ elms->Add(TextElement::Atom(this));
+ return new TextNode(elms, on_success, on_failure);
+}
+
+
+RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
+ RegExpNode* on_success,
+ RegExpNode* on_failure) {
+ return new TextNode(elements(), on_success, on_failure);
}
RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success,
RegExpNode* on_failure) {
- return new CharacterClassNode(ranges(),
- is_negated(),
- on_success,
- on_failure);
+ ZoneList<TextElement>* elms = new ZoneList<TextElement>(1);
+ elms->Add(TextElement::CharClass(this));
+ return new TextNode(elms, on_success, on_failure);
}
@@ -1566,7 +1618,7 @@
AddClassNegated(kDigitRanges, kDigitRangeCount, ranges);
break;
case '.':
- ranges->Add(CharacterRange(0x0000, 0xFFFF));
+ ranges->Add(CharacterRange::Everything());
break;
default:
UNREACHABLE();
@@ -1742,7 +1794,7 @@
}
-void Analysis::VisitAtom(AtomNode* that) {
+void Analysis::VisitText(TextNode* that) {
EnsureAnalyzed(that->on_success());
EnsureAnalyzed(that->on_failure());
}
@@ -1778,18 +1830,12 @@
}
-void Analysis::VisitCharacterClass(CharacterClassNode* that) {
- EnsureAnalyzed(that->on_success());
- EnsureAnalyzed(that->on_failure());
-}
-
-
// -------------------------------------------------------------------
// Dispatch table construction
void DispatchTableConstructor::VisitEnd(EndNode* that) {
- // nothing to do
+ AddRange(CharacterRange::Everything());
}
@@ -1866,21 +1912,29 @@
}
-void DispatchTableConstructor::VisitCharacterClass(CharacterClassNode*
that) {
- ZoneList<CharacterRange>* ranges = that->ranges();
- if (that->is_negated()) {
- AddInverse(ranges);
- } else {
- for (int i = 0; i < ranges->length(); i++) {
- AddRange(ranges->at(i));
+void DispatchTableConstructor::VisitText(TextNode* that) {
+ TextElement elm = that->elements()->at(0);
+ switch (elm.type) {
+ case TextElement::ATOM: {
+ uc16 c = elm.data.u_atom->data()[0];
+ AddRange(CharacterRange(c, c));
+ break;
+ }
+ case TextElement::CHAR_CLASS: {
+ RegExpCharacterClass* tree = elm.data.u_char_class;
+ ZoneList<CharacterRange>* ranges = tree->ranges();
+ if (tree->is_negated()) {
+ AddInverse(ranges);
+ } else {
+ for (int i = 0; i < ranges->length(); i++)
+ AddRange(ranges->at(i));
+ }
+ break;
+ }
+ default: {
+ UNIMPLEMENTED();
}
}
-}
-
-
-void DispatchTableConstructor::VisitAtom(AtomNode* that) {
- uc16 c = that->data()[0];
- AddRange(CharacterRange(c, c));
}
Modified: branches/experimental/regexp2000/src/jsregexp.h
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.h (original)
+++ branches/experimental/regexp2000/src/jsregexp.h Fri Nov 14 13:45:53 2008
@@ -191,6 +191,9 @@
ASSERT(from <= to);
return CharacterRange(from, to);
}
+ static inline CharacterRange Everything() {
+ return CharacterRange(0, 0xFFFF);
+ }
bool Contains(uc16 i) { return from_ <= i && i <= to_; }
uc16 from() const { return from_; }
void set_from(uc16 value) { from_ = value; }
@@ -389,11 +392,44 @@
#define FOR_EACH_NODE_TYPE(VISIT) \
VISIT(End) \
- VISIT(Atom) \
VISIT(Action) \
VISIT(Choice) \
VISIT(Backreference) \
- VISIT(CharacterClass)
+ VISIT(Text)
+
+
+#define FOR_EACH_REG_EXP_TREE_TYPE(VISIT) \
+ VISIT(Disjunction) \
+ VISIT(Alternative) \
+ VISIT(Assertion) \
+ VISIT(CharacterClass) \
+ VISIT(Atom) \
+ VISIT(Quantifier) \
+ VISIT(Capture) \
+ VISIT(Lookahead) \
+ VISIT(Backreference) \
+ VISIT(Empty) \
+ VISIT(Text)
+
+
+#define FORWARD_DECLARE(Name) class RegExp##Name;
+FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE)
+#undef FORWARD_DECLARE
+
+
+class TextElement {
+ public:
+ enum Type {UNINITIALIZED, ATOM, CHAR_CLASS};
+ TextElement() : type(UNINITIALIZED) { }
+ TextElement(Type t) : type(t) { }
+ static TextElement Atom(RegExpAtom* atom);
+ static TextElement CharClass(RegExpCharacterClass* char_class);
+ Type type;
+ union {
+ RegExpAtom* u_atom;
+ RegExpCharacterClass* u_char_class;
+ } data;
+};
class NodeInfo {
@@ -486,21 +522,21 @@
};
-class AtomNode: public SeqRegExpNode {
+class TextNode: public SeqRegExpNode {
public:
- AtomNode(Vector<const uc16> data,
+ TextNode(ZoneList<TextElement>* elms,
RegExpNode* on_success,
RegExpNode* on_failure)
: SeqRegExpNode(on_success),
on_failure_(on_failure),
- data_(data) { }
+ elms_(elms) { }
virtual void Accept(NodeVisitor* visitor);
- Vector<const uc16> data() { return data_; }
- RegExpNode* on_failure() { return on_failure_; }
virtual bool Emit(RegExpCompiler* compiler) { return false; }
+ RegExpNode* on_failure() { return on_failure_; }
+ ZoneList<TextElement>* elements() { return elms_; }
private:
RegExpNode* on_failure_;
- Vector<const uc16> data_;
+ ZoneList<TextElement>* elms_;
};
@@ -523,31 +559,6 @@
RegExpNode* on_failure_;
int start_reg_;
int end_reg_;
-};
-
-
-class CharacterClassNode: public SeqRegExpNode {
- public:
- CharacterClassNode(ZoneList<CharacterRange>* ranges,
- bool is_negated,
- RegExpNode* on_success,
- RegExpNode* on_failure)
- : SeqRegExpNode(on_success),
- on_failure_(on_failure),
- ranges_(ranges),
- is_negated_(is_negated ) { }
- virtual void Accept(NodeVisitor* visitor);
- ZoneList<CharacterRange>* ranges() { return ranges_; }
- bool is_negated() { return is_negated_; }
- RegExpNode* on_failure() { return on_failure_; }
- virtual bool Emit(RegExpCompiler* compiler) { return false; }
- static void AddInverseToTable(ZoneList<CharacterRange>* ranges,
- DispatchTable* table,
- int index);
- private:
- RegExpNode* on_failure_;
- ZoneList<CharacterRange>* ranges_;
- bool is_negated_;
};
Modified: branches/experimental/regexp2000/src/parser.cc
==============================================================================
--- branches/experimental/regexp2000/src/parser.cc (original)
+++ branches/experimental/regexp2000/src/parser.cc Fri Nov 14 13:45:53 2008
@@ -256,10 +256,28 @@
T* RemoveLast() {
ASSERT(last_ != NULL);
T* result = last_;
- last_ = NULL;
+ if (list_ != NULL && list_->length() > 0)
+ last_ = list_->RemoveLast();
+ else
+ last_ = NULL;
return result;
}
+ T* Get(int i) {
+ ASSERT(0 <= i && i < length());
+ if (list_ == NULL) {
+ ASSERT_EQ(0, i);
+ return last_;
+ } else {
+ if (i == list_->length()) {
+ ASSERT(last_ != NULL);
+ return last_;
+ } else {
+ return list_->at(i);
+ }
+ }
+ }
+
void Clear() {
list_ = NULL;
last_ = NULL;
@@ -294,17 +312,19 @@
// "Adds" an empty expression. Does nothing except consume a
// following quantifier
void AddEmpty();
- void AddAtom(RegExpTree* tree);
+ void AddTerm(RegExpTree* tree);
void AddAssertion(RegExpTree* tree);
void NewAlternative(); // '|'
void AddQuantifierToAtom(int min, int max, bool is_greedy);
RegExpTree* ToRegExp();
private:
void FlushCharacters();
+ void FlushText();
bool FlushTerms();
bool pending_empty_;
ZoneList<uc16>* characters_;
BufferedZoneList<RegExpTree, 2> terms_;
+ BufferedZoneList<RegExpTree, 2> text_;
BufferedZoneList<RegExpTree, 2> alternatives_;
#ifdef DEBUG
enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
@@ -328,12 +348,29 @@
if (characters_ != NULL) {
RegExpTree* atom = new RegExpAtom(characters_->ToConstVector());
characters_ = NULL;
- terms_.Add(atom);
+ text_.Add(atom);
LAST(ADD_ATOM);
}
}
+void RegExpBuilder::FlushText() {
+ FlushCharacters();
+ int num_text = text_.length();
+ if (num_text == 0) {
+ return;
+ } else if (num_text == 1) {
+ terms_.Add(text_.last());
+ } else {
+ RegExpText* text = new RegExpText();
+ for (int i = 0; i < num_text; i++)
+ text_.Get(i)->AppendToText(text);
+ terms_.Add(text);
+ }
+ text_.Clear();
+}
+
+
void RegExpBuilder::AddCharacter(uc16 c) {
pending_empty_ = false;
if (characters_ == NULL) {
@@ -349,15 +386,20 @@
}
-void RegExpBuilder::AddAtom(RegExpTree* atom) {
- FlushCharacters();
- terms_.Add(atom);
+void RegExpBuilder::AddTerm(RegExpTree* term) {
+ if (term->IsTextElement()) {
+ FlushCharacters();
+ text_.Add(term);
+ } else {
+ FlushText();
+ terms_.Add(term);
+ }
LAST(ADD_ATOM);
}
void RegExpBuilder::AddAssertion(RegExpTree* assert) {
- FlushCharacters();
+ FlushText();
terms_.Add(assert);
LAST(ADD_ASSERT);
}
@@ -371,7 +413,7 @@
bool RegExpBuilder::FlushTerms() {
- FlushCharacters();
+ FlushText();
int num_terms = terms_.length();
if (num_terms == 0) {
return false;
@@ -415,11 +457,16 @@
int num_chars = char_vector.length();
if (num_chars > 1) {
Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
- terms_.Add(new RegExpAtom(prefix));
+ text_.Add(new RegExpAtom(prefix));
char_vector = char_vector.SubVector(num_chars - 1, num_chars);
}
characters_ = NULL;
atom = new RegExpAtom(char_vector);
+ FlushText();
+ } else if (text_.length() > 0) {
+ ASSERT(last_added_ == ADD_ATOM);
+ atom = text_.RemoveLast();
+ FlushText();
} else if (terms_.length() > 0) {
ASSERT(last_added_ == ADD_ATOM);
atom = terms_.RemoveLast();
@@ -3585,17 +3632,17 @@
ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
CharacterRange::AddClassEscape('.', ranges);
RegExpTree* atom = new RegExpCharacterClass(ranges, false);
- builder.AddAtom(atom);
+ builder.AddTerm(atom);
break;
}
case '(': {
RegExpTree* atom = ParseGroup(CHECK_OK);
- builder.AddAtom(atom);
+ builder.AddTerm(atom);
break;
}
case '[': {
RegExpTree* atom = ParseCharacterClass(CHECK_OK);
- builder.AddAtom(atom);
+ builder.AddTerm(atom);
break;
}
// Atom ::
@@ -3625,7 +3672,7 @@
ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
CharacterRange::AddClassEscape(c, ranges);
RegExpTree* atom = new RegExpCharacterClass(ranges, false);
- builder.AddAtom(atom);
+ builder.AddTerm(atom);
goto has_read_atom; // Avoid setting has_character_escapes_.
}
case '1': case '2': case '3': case '4': case '5': case '6':
@@ -3639,7 +3686,7 @@
goto has_read_atom;
}
RegExpTree* atom = new RegExpBackreference(capture);
- builder.AddAtom(atom);
+ builder.AddTerm(atom);
goto has_read_atom; // Avoid setting has_character_escapes_.
}
uc32 first_digit = next();
Modified: branches/experimental/regexp2000/test/cctest/test-regexp.cc
==============================================================================
--- branches/experimental/regexp2000/test/cctest/test-regexp.cc (original)
+++ branches/experimental/regexp2000/test/cctest/test-regexp.cc Fri Nov 14
13:45:53 2008
@@ -174,6 +174,7 @@
CHECK_PARSE_EQ("\\x3z", "'x3z'");
CHECK_PARSE_EQ("\\u0034", "'\x34'");
CHECK_PARSE_EQ("\\u003z", "'u003z'");
+ CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))");
CHECK_ESCAPES("a", false);
CHECK_ESCAPES("a|b", false);
@@ -219,7 +220,7 @@
}
TEST(ParserRegression) {
- CHECK_PARSE_EQ("[A-Z$-][x]", "(: [A-Z $ -] [x])");
+ CHECK_PARSE_EQ("[A-Z$-][x]", "(! [A-Z $ -] [x])");
}
static void ExpectError(const char* input,
@@ -707,5 +708,5 @@
TEST(Graph) {
- Execute("a|(b|c)|d", "", true);
+ Execute("fo[ob]ar|[ba]z|x[yz]*", "", true);
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---