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

Side by Side Diff: src/ast/ast.cc

Issue 1565183002: [regexp] move regexp parser into own files. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix test compile Created 4 years, 11 months 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 unified diff | Download patch
« no previous file with comments | « src/ast/ast.h ('k') | src/heap/heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast.h" 5 #include "src/ast/ast.h"
6 6
7 #include <cmath> // For isfinite. 7 #include <cmath> // For isfinite.
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins.h" 9 #include "src/builtins.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 // The variable statement visiting code may pass NULL expressions 791 // The variable statement visiting code may pass NULL expressions
792 // to this code. Maybe this should be handled by introducing an 792 // to this code. Maybe this should be handled by introducing an
793 // undefined expression or literal? Revisit this code if this 793 // undefined expression or literal? Revisit this code if this
794 // changes 794 // changes
795 Expression* expression = expressions->at(i); 795 Expression* expression = expressions->at(i);
796 if (expression != NULL) Visit(expression); 796 if (expression != NULL) Visit(expression);
797 } 797 }
798 } 798 }
799 799
800 800
801 // ----------------------------------------------------------------------------
802 // Regular expressions
803
804 #define MAKE_ACCEPT(Name) \
805 void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \
806 return visitor->Visit##Name(this, data); \
807 }
808 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
809 #undef MAKE_ACCEPT
810
811 #define MAKE_TYPE_CASE(Name) \
812 RegExp##Name* RegExpTree::As##Name() { \
813 return NULL; \
814 } \
815 bool RegExpTree::Is##Name() { return false; }
816 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
817 #undef MAKE_TYPE_CASE
818
819 #define MAKE_TYPE_CASE(Name) \
820 RegExp##Name* RegExp##Name::As##Name() { \
821 return this; \
822 } \
823 bool RegExp##Name::Is##Name() { return true; }
824 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
825 #undef MAKE_TYPE_CASE
826
827
828 static Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
829 Interval result = Interval::Empty();
830 for (int i = 0; i < children->length(); i++)
831 result = result.Union(children->at(i)->CaptureRegisters());
832 return result;
833 }
834
835
836 Interval RegExpAlternative::CaptureRegisters() {
837 return ListCaptureRegisters(nodes());
838 }
839
840
841 Interval RegExpDisjunction::CaptureRegisters() {
842 return ListCaptureRegisters(alternatives());
843 }
844
845
846 Interval RegExpLookaround::CaptureRegisters() {
847 return body()->CaptureRegisters();
848 }
849
850
851 Interval RegExpCapture::CaptureRegisters() {
852 Interval self(StartRegister(index()), EndRegister(index()));
853 return self.Union(body()->CaptureRegisters());
854 }
855
856
857 Interval RegExpQuantifier::CaptureRegisters() {
858 return body()->CaptureRegisters();
859 }
860
861
862 bool RegExpAssertion::IsAnchoredAtStart() {
863 return assertion_type() == RegExpAssertion::START_OF_INPUT;
864 }
865
866
867 bool RegExpAssertion::IsAnchoredAtEnd() {
868 return assertion_type() == RegExpAssertion::END_OF_INPUT;
869 }
870
871
872 bool RegExpAlternative::IsAnchoredAtStart() {
873 ZoneList<RegExpTree*>* nodes = this->nodes();
874 for (int i = 0; i < nodes->length(); i++) {
875 RegExpTree* node = nodes->at(i);
876 if (node->IsAnchoredAtStart()) { return true; }
877 if (node->max_match() > 0) { return false; }
878 }
879 return false;
880 }
881
882
883 bool RegExpAlternative::IsAnchoredAtEnd() {
884 ZoneList<RegExpTree*>* nodes = this->nodes();
885 for (int i = nodes->length() - 1; i >= 0; i--) {
886 RegExpTree* node = nodes->at(i);
887 if (node->IsAnchoredAtEnd()) { return true; }
888 if (node->max_match() > 0) { return false; }
889 }
890 return false;
891 }
892
893
894 bool RegExpDisjunction::IsAnchoredAtStart() {
895 ZoneList<RegExpTree*>* alternatives = this->alternatives();
896 for (int i = 0; i < alternatives->length(); i++) {
897 if (!alternatives->at(i)->IsAnchoredAtStart())
898 return false;
899 }
900 return true;
901 }
902
903
904 bool RegExpDisjunction::IsAnchoredAtEnd() {
905 ZoneList<RegExpTree*>* alternatives = this->alternatives();
906 for (int i = 0; i < alternatives->length(); i++) {
907 if (!alternatives->at(i)->IsAnchoredAtEnd())
908 return false;
909 }
910 return true;
911 }
912
913
914 bool RegExpLookaround::IsAnchoredAtStart() {
915 return is_positive() && type() == LOOKAHEAD && body()->IsAnchoredAtStart();
916 }
917
918
919 bool RegExpCapture::IsAnchoredAtStart() {
920 return body()->IsAnchoredAtStart();
921 }
922
923
924 bool RegExpCapture::IsAnchoredAtEnd() {
925 return body()->IsAnchoredAtEnd();
926 }
927
928
929 // Convert regular expression trees to a simple sexp representation.
930 // This representation should be different from the input grammar
931 // in as many cases as possible, to make it more difficult for incorrect
932 // parses to look as correct ones which is likely if the input and
933 // output formats are alike.
934 class RegExpUnparser final : public RegExpVisitor {
935 public:
936 RegExpUnparser(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {}
937 void VisitCharacterRange(CharacterRange that);
938 #define MAKE_CASE(Name) void* Visit##Name(RegExp##Name*, void* data) override;
939 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
940 #undef MAKE_CASE
941 private:
942 std::ostream& os_;
943 Zone* zone_;
944 };
945
946
947 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
948 os_ << "(|";
949 for (int i = 0; i < that->alternatives()->length(); i++) {
950 os_ << " ";
951 that->alternatives()->at(i)->Accept(this, data);
952 }
953 os_ << ")";
954 return NULL;
955 }
956
957
958 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
959 os_ << "(:";
960 for (int i = 0; i < that->nodes()->length(); i++) {
961 os_ << " ";
962 that->nodes()->at(i)->Accept(this, data);
963 }
964 os_ << ")";
965 return NULL;
966 }
967
968
969 void RegExpUnparser::VisitCharacterRange(CharacterRange that) {
970 os_ << AsUC16(that.from());
971 if (!that.IsSingleton()) {
972 os_ << "-" << AsUC16(that.to());
973 }
974 }
975
976
977
978 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
979 void* data) {
980 if (that->is_negated()) os_ << "^";
981 os_ << "[";
982 for (int i = 0; i < that->ranges(zone_)->length(); i++) {
983 if (i > 0) os_ << " ";
984 VisitCharacterRange(that->ranges(zone_)->at(i));
985 }
986 os_ << "]";
987 return NULL;
988 }
989
990
991 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
992 switch (that->assertion_type()) {
993 case RegExpAssertion::START_OF_INPUT:
994 os_ << "@^i";
995 break;
996 case RegExpAssertion::END_OF_INPUT:
997 os_ << "@$i";
998 break;
999 case RegExpAssertion::START_OF_LINE:
1000 os_ << "@^l";
1001 break;
1002 case RegExpAssertion::END_OF_LINE:
1003 os_ << "@$l";
1004 break;
1005 case RegExpAssertion::BOUNDARY:
1006 os_ << "@b";
1007 break;
1008 case RegExpAssertion::NON_BOUNDARY:
1009 os_ << "@B";
1010 break;
1011 }
1012 return NULL;
1013 }
1014
1015
1016 void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
1017 os_ << "'";
1018 Vector<const uc16> chardata = that->data();
1019 for (int i = 0; i < chardata.length(); i++) {
1020 os_ << AsUC16(chardata[i]);
1021 }
1022 os_ << "'";
1023 return NULL;
1024 }
1025
1026
1027 void* RegExpUnparser::VisitText(RegExpText* that, void* data) {
1028 if (that->elements()->length() == 1) {
1029 that->elements()->at(0).tree()->Accept(this, data);
1030 } else {
1031 os_ << "(!";
1032 for (int i = 0; i < that->elements()->length(); i++) {
1033 os_ << " ";
1034 that->elements()->at(i).tree()->Accept(this, data);
1035 }
1036 os_ << ")";
1037 }
1038 return NULL;
1039 }
1040
1041
1042 void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
1043 os_ << "(# " << that->min() << " ";
1044 if (that->max() == RegExpTree::kInfinity) {
1045 os_ << "- ";
1046 } else {
1047 os_ << that->max() << " ";
1048 }
1049 os_ << (that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
1050 that->body()->Accept(this, data);
1051 os_ << ")";
1052 return NULL;
1053 }
1054
1055
1056 void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
1057 os_ << "(^ ";
1058 that->body()->Accept(this, data);
1059 os_ << ")";
1060 return NULL;
1061 }
1062
1063
1064 void* RegExpUnparser::VisitLookaround(RegExpLookaround* that, void* data) {
1065 os_ << "(";
1066 os_ << (that->type() == RegExpLookaround::LOOKAHEAD ? "->" : "<-");
1067 os_ << (that->is_positive() ? " + " : " - ");
1068 that->body()->Accept(this, data);
1069 os_ << ")";
1070 return NULL;
1071 }
1072
1073
1074 void* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
1075 void* data) {
1076 os_ << "(<- " << that->index() << ")";
1077 return NULL;
1078 }
1079
1080
1081 void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
1082 os_ << '%';
1083 return NULL;
1084 }
1085
1086
1087 std::ostream& RegExpTree::Print(std::ostream& os, Zone* zone) { // NOLINT
1088 RegExpUnparser unparser(os, zone);
1089 Accept(&unparser, NULL);
1090 return os;
1091 }
1092
1093
1094 RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
1095 : alternatives_(alternatives) {
1096 DCHECK(alternatives->length() > 1);
1097 RegExpTree* first_alternative = alternatives->at(0);
1098 min_match_ = first_alternative->min_match();
1099 max_match_ = first_alternative->max_match();
1100 for (int i = 1; i < alternatives->length(); i++) {
1101 RegExpTree* alternative = alternatives->at(i);
1102 min_match_ = Min(min_match_, alternative->min_match());
1103 max_match_ = Max(max_match_, alternative->max_match());
1104 }
1105 }
1106
1107
1108 static int IncreaseBy(int previous, int increase) {
1109 if (RegExpTree::kInfinity - previous < increase) {
1110 return RegExpTree::kInfinity;
1111 } else {
1112 return previous + increase;
1113 }
1114 }
1115
1116 RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
1117 : nodes_(nodes) {
1118 DCHECK(nodes->length() > 1);
1119 min_match_ = 0;
1120 max_match_ = 0;
1121 for (int i = 0; i < nodes->length(); i++) {
1122 RegExpTree* node = nodes->at(i);
1123 int node_min_match = node->min_match();
1124 min_match_ = IncreaseBy(min_match_, node_min_match);
1125 int node_max_match = node->max_match();
1126 max_match_ = IncreaseBy(max_match_, node_max_match);
1127 }
1128 }
1129
1130
1131 CaseClause::CaseClause(Zone* zone, Expression* label, 801 CaseClause::CaseClause(Zone* zone, Expression* label,
1132 ZoneList<Statement*>* statements, int pos) 802 ZoneList<Statement*>* statements, int pos)
1133 : Expression(zone, pos), 803 : Expression(zone, pos),
1134 label_(label), 804 label_(label),
1135 statements_(statements), 805 statements_(statements),
1136 compare_type_(Type::None(zone)) {} 806 compare_type_(Type::None(zone)) {}
1137 807
1138 808
1139 uint32_t Literal::Hash() { 809 uint32_t Literal::Hash() {
1140 return raw_value()->IsString() 810 return raw_value()->IsString()
1141 ? raw_value()->AsString()->hash() 811 ? raw_value()->AsString()->hash()
1142 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); 812 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber()));
1143 } 813 }
1144 814
1145 815
1146 // static 816 // static
1147 bool Literal::Match(void* literal1, void* literal2) { 817 bool Literal::Match(void* literal1, void* literal2) {
1148 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); 818 const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
1149 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); 819 const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
1150 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || 820 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) ||
1151 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); 821 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
1152 } 822 }
1153 823
1154 824
1155 } // namespace internal 825 } // namespace internal
1156 } // namespace v8 826 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.h ('k') | src/heap/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698