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 |