Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(979)

Unified Diff: src/ast.cc

Issue 12427: Merge regexp2000 back into bleeding_edge (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/ast.cc
===================================================================
--- src/ast.cc (revision 830)
+++ src/ast.cc (working copy)
@@ -29,6 +29,7 @@
#include "ast.h"
#include "scopes.h"
+#include "string-stream.h"
namespace v8 { namespace internal {
@@ -179,4 +180,204 @@
}
+// ----------------------------------------------------------------------------
+// Regular expressions
+
+#define MAKE_ACCEPT(Name) \
+ void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \
+ return visitor->Visit##Name(this, data); \
+ }
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
+#undef MAKE_ACCEPT
+
+#define MAKE_TYPE_CASE(Name) \
+ RegExp##Name* RegExpTree::As##Name() { \
+ return NULL; \
+ } \
+ bool RegExpTree::Is##Name() { return false; }
+ FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
Mads Ager (chromium) 2008/11/25 21:09:41 Do not indent this line.
Erik Corry 2008/11/26 12:18:36 Fixed.
+#undef MAKE_TYPE_CASE
+
+#define MAKE_TYPE_CASE(Name) \
+ RegExp##Name* RegExp##Name::As##Name() { \
+ return this; \
+ } \
+ bool RegExp##Name::Is##Name() { return true; }
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
+#undef MAKE_TYPE_CASE
+
+RegExpEmpty RegExpEmpty::kInstance;
+
+
+// Convert regular expression trees to a simple sexp representation.
+// This representation should be different from the input grammar
+// in as many cases as possible, to make it more difficult for incorrect
+// parses to look as correct ones which is likely if the input and
+// output formats are alike.
+class RegExpUnparser: public RegExpVisitor {
+ public:
+ RegExpUnparser();
+ 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_TREE_TYPE(MAKE_CASE)
+#undef MAKE_CASE
+ private:
+ StringStream* stream() { return &stream_; }
+ HeapStringAllocator alloc_;
+ StringStream stream_;
+};
+
+
+RegExpUnparser::RegExpUnparser() : stream_(&alloc_) {
+}
+
+
+void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
+ stream()->Add("(|");
+ for (int i = 0; i < that->alternatives()->length(); i++) {
+ stream()->Add(" ");
+ that->alternatives()->at(i)->Accept(this, data);
+ }
+ stream()->Add(")");
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
+ stream()->Add("(:");
+ for (int i = 0; i < that->nodes()->length(); i++) {
+ stream()->Add(" ");
+ that->nodes()->at(i)->Accept(this, data);
+ }
+ stream()->Add(")");
+ return NULL;
+}
+
+
+void RegExpUnparser::VisitCharacterRange(CharacterRange that) {
+ stream()->Add("%k", that.from());
+ if (!that.IsSingleton()) {
+ stream()->Add("-%k", that.to());
+ }
+}
+
+
+
+void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
+ void* data) {
+ if (that->is_negated())
+ stream()->Add("^");
+ stream()->Add("[");
+ for (int i = 0; i < that->ranges()->length(); i++) {
+ if (i > 0) stream()->Add(" ");
+ VisitCharacterRange(that->ranges()->at(i));
+ }
+ stream()->Add("]");
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
+ switch (that->type()) {
+ case RegExpAssertion::START_OF_INPUT:
+ stream()->Add("@^i");
+ break;
+ case RegExpAssertion::END_OF_INPUT:
+ stream()->Add("@$i");
+ break;
+ case RegExpAssertion::START_OF_LINE:
+ stream()->Add("@^l");
+ break;
+ case RegExpAssertion::END_OF_LINE:
+ stream()->Add("@$l");
+ break;
+ case RegExpAssertion::BOUNDARY:
+ stream()->Add("@b");
+ break;
+ case RegExpAssertion::NON_BOUNDARY:
+ stream()->Add("@B");
+ break;
+ }
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
+ stream()->Add("'");
+ Vector<const uc16> chardata = that->data();
+ for (int i = 0; i < chardata.length(); i++) {
+ stream()->Add("%k", chardata[i]);
+ }
+ stream()->Add("'");
+ 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;
+}
+
+
+void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
+ stream()->Add("(# %i ", that->min());
+ if (that->max() == RegExpQuantifier::kInfinity) {
+ stream()->Add("- ");
+ } else {
+ stream()->Add("%i ", that->max());
+ }
+ stream()->Add(that->is_greedy() ? "g " : "n ");
+ that->body()->Accept(this, data);
+ stream()->Add(")");
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
+ stream()->Add("(^ ");
+ that->body()->Accept(this, data);
+ stream()->Add(")");
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
+ stream()->Add("(-> ");
+ stream()->Add(that->is_positive() ? "+ " : "- ");
+ that->body()->Accept(this, data);
+ stream()->Add(")");
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
+ void* data) {
+ stream()->Add("(<- %i)", that->index());
+ return NULL;
+}
+
+
+void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
+ stream()->Put('%');
+ return NULL;
+}
+
+
+SmartPointer<const char> RegExpTree::ToString() {
+ RegExpUnparser unparser;
+ Accept(&unparser, NULL);
+ return unparser.ToString();
+}
+
+
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698