| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast.h" | 5 #include "src/ast.h" |
| 6 | 6 |
| 7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
| 8 #include "src/builtins.h" | 8 #include "src/builtins.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 } | 792 } |
| 793 | 793 |
| 794 | 794 |
| 795 // Convert regular expression trees to a simple sexp representation. | 795 // Convert regular expression trees to a simple sexp representation. |
| 796 // This representation should be different from the input grammar | 796 // This representation should be different from the input grammar |
| 797 // in as many cases as possible, to make it more difficult for incorrect | 797 // in as many cases as possible, to make it more difficult for incorrect |
| 798 // parses to look as correct ones which is likely if the input and | 798 // parses to look as correct ones which is likely if the input and |
| 799 // output formats are alike. | 799 // output formats are alike. |
| 800 class RegExpUnparser V8_FINAL : public RegExpVisitor { | 800 class RegExpUnparser V8_FINAL : public RegExpVisitor { |
| 801 public: | 801 public: |
| 802 explicit RegExpUnparser(Zone* zone); | 802 RegExpUnparser(OStream& os, Zone* zone) : os_(os), zone_(zone) {} |
| 803 void VisitCharacterRange(CharacterRange that); | 803 void VisitCharacterRange(CharacterRange that); |
| 804 SmartArrayPointer<const char> ToString() { return stream_.ToCString(); } | |
| 805 #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, \ | 804 #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, \ |
| 806 void* data) V8_OVERRIDE; | 805 void* data) V8_OVERRIDE; |
| 807 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) | 806 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) |
| 808 #undef MAKE_CASE | 807 #undef MAKE_CASE |
| 809 private: | 808 private: |
| 810 StringStream* stream() { return &stream_; } | 809 OStream& os_; |
| 811 HeapStringAllocator alloc_; | |
| 812 StringStream stream_; | |
| 813 Zone* zone_; | 810 Zone* zone_; |
| 814 }; | 811 }; |
| 815 | 812 |
| 816 | 813 |
| 817 RegExpUnparser::RegExpUnparser(Zone* zone) : stream_(&alloc_), zone_(zone) { | |
| 818 } | |
| 819 | |
| 820 | |
| 821 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) { | 814 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) { |
| 822 stream()->Add("(|"); | 815 os_ << "(|"; |
| 823 for (int i = 0; i < that->alternatives()->length(); i++) { | 816 for (int i = 0; i < that->alternatives()->length(); i++) { |
| 824 stream()->Add(" "); | 817 os_ << " "; |
| 825 that->alternatives()->at(i)->Accept(this, data); | 818 that->alternatives()->at(i)->Accept(this, data); |
| 826 } | 819 } |
| 827 stream()->Add(")"); | 820 os_ << ")"; |
| 828 return NULL; | 821 return NULL; |
| 829 } | 822 } |
| 830 | 823 |
| 831 | 824 |
| 832 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) { | 825 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) { |
| 833 stream()->Add("(:"); | 826 os_ << "(:"; |
| 834 for (int i = 0; i < that->nodes()->length(); i++) { | 827 for (int i = 0; i < that->nodes()->length(); i++) { |
| 835 stream()->Add(" "); | 828 os_ << " "; |
| 836 that->nodes()->at(i)->Accept(this, data); | 829 that->nodes()->at(i)->Accept(this, data); |
| 837 } | 830 } |
| 838 stream()->Add(")"); | 831 os_ << ")"; |
| 839 return NULL; | 832 return NULL; |
| 840 } | 833 } |
| 841 | 834 |
| 842 | 835 |
| 843 void RegExpUnparser::VisitCharacterRange(CharacterRange that) { | 836 void RegExpUnparser::VisitCharacterRange(CharacterRange that) { |
| 844 stream()->Add("%k", that.from()); | 837 os_ << AsUC16(that.from()); |
| 845 if (!that.IsSingleton()) { | 838 if (!that.IsSingleton()) { |
| 846 stream()->Add("-%k", that.to()); | 839 os_ << "-" << AsUC16(that.to()); |
| 847 } | 840 } |
| 848 } | 841 } |
| 849 | 842 |
| 850 | 843 |
| 851 | 844 |
| 852 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that, | 845 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that, |
| 853 void* data) { | 846 void* data) { |
| 854 if (that->is_negated()) | 847 if (that->is_negated()) os_ << "^"; |
| 855 stream()->Add("^"); | 848 os_ << "["; |
| 856 stream()->Add("["); | |
| 857 for (int i = 0; i < that->ranges(zone_)->length(); i++) { | 849 for (int i = 0; i < that->ranges(zone_)->length(); i++) { |
| 858 if (i > 0) stream()->Add(" "); | 850 if (i > 0) os_ << " "; |
| 859 VisitCharacterRange(that->ranges(zone_)->at(i)); | 851 VisitCharacterRange(that->ranges(zone_)->at(i)); |
| 860 } | 852 } |
| 861 stream()->Add("]"); | 853 os_ << "]"; |
| 862 return NULL; | 854 return NULL; |
| 863 } | 855 } |
| 864 | 856 |
| 865 | 857 |
| 866 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) { | 858 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) { |
| 867 switch (that->assertion_type()) { | 859 switch (that->assertion_type()) { |
| 868 case RegExpAssertion::START_OF_INPUT: | 860 case RegExpAssertion::START_OF_INPUT: |
| 869 stream()->Add("@^i"); | 861 os_ << "@^i"; |
| 870 break; | 862 break; |
| 871 case RegExpAssertion::END_OF_INPUT: | 863 case RegExpAssertion::END_OF_INPUT: |
| 872 stream()->Add("@$i"); | 864 os_ << "@$i"; |
| 873 break; | 865 break; |
| 874 case RegExpAssertion::START_OF_LINE: | 866 case RegExpAssertion::START_OF_LINE: |
| 875 stream()->Add("@^l"); | 867 os_ << "@^l"; |
| 876 break; | 868 break; |
| 877 case RegExpAssertion::END_OF_LINE: | 869 case RegExpAssertion::END_OF_LINE: |
| 878 stream()->Add("@$l"); | 870 os_ << "@$l"; |
| 879 break; | 871 break; |
| 880 case RegExpAssertion::BOUNDARY: | 872 case RegExpAssertion::BOUNDARY: |
| 881 stream()->Add("@b"); | 873 os_ << "@b"; |
| 882 break; | 874 break; |
| 883 case RegExpAssertion::NON_BOUNDARY: | 875 case RegExpAssertion::NON_BOUNDARY: |
| 884 stream()->Add("@B"); | 876 os_ << "@B"; |
| 885 break; | 877 break; |
| 886 } | 878 } |
| 887 return NULL; | 879 return NULL; |
| 888 } | 880 } |
| 889 | 881 |
| 890 | 882 |
| 891 void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) { | 883 void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) { |
| 892 stream()->Add("'"); | 884 os_ << "'"; |
| 893 Vector<const uc16> chardata = that->data(); | 885 Vector<const uc16> chardata = that->data(); |
| 894 for (int i = 0; i < chardata.length(); i++) { | 886 for (int i = 0; i < chardata.length(); i++) { |
| 895 stream()->Add("%k", chardata[i]); | 887 os_ << AsUC16(chardata[i]); |
| 896 } | 888 } |
| 897 stream()->Add("'"); | 889 os_ << "'"; |
| 898 return NULL; | 890 return NULL; |
| 899 } | 891 } |
| 900 | 892 |
| 901 | 893 |
| 902 void* RegExpUnparser::VisitText(RegExpText* that, void* data) { | 894 void* RegExpUnparser::VisitText(RegExpText* that, void* data) { |
| 903 if (that->elements()->length() == 1) { | 895 if (that->elements()->length() == 1) { |
| 904 that->elements()->at(0).tree()->Accept(this, data); | 896 that->elements()->at(0).tree()->Accept(this, data); |
| 905 } else { | 897 } else { |
| 906 stream()->Add("(!"); | 898 os_ << "(!"; |
| 907 for (int i = 0; i < that->elements()->length(); i++) { | 899 for (int i = 0; i < that->elements()->length(); i++) { |
| 908 stream()->Add(" "); | 900 os_ << " "; |
| 909 that->elements()->at(i).tree()->Accept(this, data); | 901 that->elements()->at(i).tree()->Accept(this, data); |
| 910 } | 902 } |
| 911 stream()->Add(")"); | 903 os_ << ")"; |
| 912 } | 904 } |
| 913 return NULL; | 905 return NULL; |
| 914 } | 906 } |
| 915 | 907 |
| 916 | 908 |
| 917 void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) { | 909 void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) { |
| 918 stream()->Add("(# %i ", that->min()); | 910 os_ << "(# " << that->min() << " "; |
| 919 if (that->max() == RegExpTree::kInfinity) { | 911 if (that->max() == RegExpTree::kInfinity) { |
| 920 stream()->Add("- "); | 912 os_ << "- "; |
| 921 } else { | 913 } else { |
| 922 stream()->Add("%i ", that->max()); | 914 os_ << that->max() << " "; |
| 923 } | 915 } |
| 924 stream()->Add(that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n "); | 916 os_ << (that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n "); |
| 925 that->body()->Accept(this, data); | 917 that->body()->Accept(this, data); |
| 926 stream()->Add(")"); | 918 os_ << ")"; |
| 927 return NULL; | 919 return NULL; |
| 928 } | 920 } |
| 929 | 921 |
| 930 | 922 |
| 931 void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) { | 923 void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) { |
| 932 stream()->Add("(^ "); | 924 os_ << "(^ "; |
| 933 that->body()->Accept(this, data); | 925 that->body()->Accept(this, data); |
| 934 stream()->Add(")"); | 926 os_ << ")"; |
| 935 return NULL; | 927 return NULL; |
| 936 } | 928 } |
| 937 | 929 |
| 938 | 930 |
| 939 void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) { | 931 void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) { |
| 940 stream()->Add("(-> "); | 932 os_ << "(-> " << (that->is_positive() ? "+ " : "- "); |
| 941 stream()->Add(that->is_positive() ? "+ " : "- "); | |
| 942 that->body()->Accept(this, data); | 933 that->body()->Accept(this, data); |
| 943 stream()->Add(")"); | 934 os_ << ")"; |
| 944 return NULL; | 935 return NULL; |
| 945 } | 936 } |
| 946 | 937 |
| 947 | 938 |
| 948 void* RegExpUnparser::VisitBackReference(RegExpBackReference* that, | 939 void* RegExpUnparser::VisitBackReference(RegExpBackReference* that, |
| 949 void* data) { | 940 void* data) { |
| 950 stream()->Add("(<- %i)", that->index()); | 941 os_ << "(<- " << that->index() << ")"; |
| 951 return NULL; | 942 return NULL; |
| 952 } | 943 } |
| 953 | 944 |
| 954 | 945 |
| 955 void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) { | 946 void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) { |
| 956 stream()->Put('%'); | 947 os_ << '%'; |
| 957 return NULL; | 948 return NULL; |
| 958 } | 949 } |
| 959 | 950 |
| 960 | 951 |
| 961 SmartArrayPointer<const char> RegExpTree::ToString(Zone* zone) { | 952 OStream& RegExpTree::Print(OStream& os, Zone* zone) { // NOLINT |
| 962 RegExpUnparser unparser(zone); | 953 RegExpUnparser unparser(os, zone); |
| 963 Accept(&unparser, NULL); | 954 Accept(&unparser, NULL); |
| 964 return unparser.ToString(); | 955 return os; |
| 965 } | 956 } |
| 966 | 957 |
| 967 | 958 |
| 968 RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) | 959 RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) |
| 969 : alternatives_(alternatives) { | 960 : alternatives_(alternatives) { |
| 970 ASSERT(alternatives->length() > 1); | 961 ASSERT(alternatives->length() > 1); |
| 971 RegExpTree* first_alternative = alternatives->at(0); | 962 RegExpTree* first_alternative = alternatives->at(0); |
| 972 min_match_ = first_alternative->min_match(); | 963 min_match_ = first_alternative->min_match(); |
| 973 max_match_ = first_alternative->max_match(); | 964 max_match_ = first_alternative->max_match(); |
| 974 for (int i = 1; i < alternatives->length(); i++) { | 965 for (int i = 1; i < alternatives->length(); i++) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 SNPrintF(buffer, "%d", Smi::cast(*value())->value()); | 1123 SNPrintF(buffer, "%d", Smi::cast(*value())->value()); |
| 1133 str = arr; | 1124 str = arr; |
| 1134 } else { | 1125 } else { |
| 1135 str = DoubleToCString(value()->Number(), buffer); | 1126 str = DoubleToCString(value()->Number(), buffer); |
| 1136 } | 1127 } |
| 1137 return isolate_->factory()->NewStringFromAsciiChecked(str); | 1128 return isolate_->factory()->NewStringFromAsciiChecked(str); |
| 1138 } | 1129 } |
| 1139 | 1130 |
| 1140 | 1131 |
| 1141 } } // namespace v8::internal | 1132 } } // namespace v8::internal |
| OLD | NEW |