[106] | 1 | /* contentmodel.c - Content Models from !ELEMENT declarations. |
---|
| 2 | Copyright (c) 2008, Robert D. Cameron and Dan Lin. |
---|
| 3 | Licensed to the public under the Open Software License 3.0. |
---|
| 4 | Licensed to International Characters, Inc., under the Academic |
---|
| 5 | Free License 3.0. |
---|
| 6 | */ |
---|
| 7 | |
---|
| 8 | #include "contentmodel.h" |
---|
[111] | 9 | #include "xml_error.h" |
---|
[106] | 10 | |
---|
| 11 | CM_Any::CM_Any(): ContentModel() { |
---|
| 12 | cm_type = cm_Any; |
---|
| 13 | } |
---|
| 14 | |
---|
| 15 | CM_Empty::CM_Empty() : ContentModel() { |
---|
| 16 | cm_type = cm_Empty; |
---|
| 17 | } |
---|
| 18 | |
---|
| 19 | CM_Mixed::CM_Mixed() : ContentModel() { |
---|
| 20 | cm_type = cm_Mixed; |
---|
| 21 | } |
---|
| 22 | |
---|
| 23 | CM_RegExp::CM_RegExp() : ContentModel() { |
---|
| 24 | cm_type = cm_RegExp; |
---|
| 25 | } |
---|
| 26 | |
---|
| 27 | CRE_Star::CRE_Star(Content_RE * s) : Content_RE() { |
---|
| 28 | subCM = s; |
---|
| 29 | matches_empty = true; |
---|
| 30 | } |
---|
| 31 | |
---|
| 32 | CRE_Plus::CRE_Plus(Content_RE * s) : Content_RE() { |
---|
| 33 | subCM = s; |
---|
| 34 | matches_empty = s->matches_empty; |
---|
| 35 | } |
---|
| 36 | |
---|
| 37 | CRE_Opt::CRE_Opt(Content_RE * s) : Content_RE() { |
---|
| 38 | subCM = s; |
---|
| 39 | matches_empty = true; |
---|
| 40 | } |
---|
| 41 | CRE_Name::CRE_Name(int id) : Content_RE() { |
---|
| 42 | elemID = id; |
---|
| 43 | matches_empty = false; |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | CRE_Seq::CRE_Seq() : Content_RE() { |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | CRE_Choice::CRE_Choice() : Content_RE() { |
---|
| 50 | } |
---|
| 51 | |
---|
| 52 | void CRE_Seq :: Compile() { |
---|
| 53 | matches_empty = true; |
---|
| 54 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 55 | if (!(subCMs[i]->matches_empty)){ |
---|
| 56 | matches_empty = false; |
---|
| 57 | return; |
---|
| 58 | } |
---|
| 59 | } |
---|
| 60 | } |
---|
| 61 | void CRE_Name :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 62 | /* printf("stateID: %d\n",stateID); |
---|
| 63 | for(int i=0;i<follow_map.size();i++) |
---|
| 64 | printf("%d ",follow_map[i]); |
---|
| 65 | printf("\n");*/ |
---|
| 66 | transition_map[stateID] = follow_map; |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | void CRE_Star :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 70 | hash_map<int, int >::iterator j; |
---|
| 71 | for (j=follow_map.begin(); j!=follow_map.end(); j++) { |
---|
| 72 | subCM->follow_map[j->first]=j->second; |
---|
| 73 | } |
---|
| 74 | for (j=subCM->first_map.begin(); j!=subCM->first_map.end(); j++) { |
---|
| 75 | if (subCM->follow_map[j->first] != 0) { |
---|
[111] | 76 | ContentModelError(); |
---|
[106] | 77 | } |
---|
| 78 | subCM->follow_map[j->first]=j->second; |
---|
| 79 | } |
---|
| 80 | subCM->Set_Follow_Map(transition_map); |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | void CRE_Plus :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 84 | hash_map<int, int >::iterator j; |
---|
| 85 | for (j=follow_map.begin(); j!=follow_map.end(); j++) |
---|
| 86 | subCM->follow_map[j->first]=j->second; |
---|
| 87 | for (j=subCM->first_map.begin(); j!=subCM->first_map.end(); j++) { |
---|
| 88 | if (subCM->follow_map[j->first] != 0) { |
---|
[111] | 89 | ContentModelError(); |
---|
[106] | 90 | } |
---|
| 91 | subCM->follow_map[j->first]=j->second; |
---|
| 92 | } |
---|
| 93 | subCM->Set_Follow_Map(transition_map); |
---|
| 94 | } |
---|
| 95 | |
---|
| 96 | void CRE_Opt :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 97 | subCM->follow_map = follow_map; |
---|
| 98 | subCM->Set_Follow_Map(transition_map); |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | void CRE_Choice :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 102 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 103 | subCMs[i]->follow_map = follow_map; |
---|
| 104 | subCMs[i]->Set_Follow_Map(transition_map); |
---|
| 105 | } |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | void CRE_Seq :: Set_Follow_Map(symbol_set_t * transition_map) { |
---|
| 109 | hash_map<int, int >::iterator itr; |
---|
| 110 | subCMs[subCMs.size()-1]->follow_map = follow_map; |
---|
| 111 | for (int i=subCMs.size()-1; i >= 1; i--) { |
---|
| 112 | // Set the follow_map for item i-1 to include first_map for i; |
---|
| 113 | for (itr=subCMs[i]->first_map.begin(); itr!=subCMs[i]->first_map.end(); itr++) { |
---|
| 114 | if (subCMs[i-1]->follow_map[itr->first] != 0) { |
---|
[111] | 115 | ContentModelError(); |
---|
[106] | 116 | } |
---|
| 117 | subCMs[i-1]->follow_map[itr->first]=itr->second; |
---|
| 118 | } |
---|
| 119 | // If item i matches empty, set follow_map for item i-1 to include |
---|
| 120 | // follow_map for i. |
---|
| 121 | if (subCMs[i]->matches_empty) { |
---|
| 122 | for (itr=subCMs[i]->follow_map.begin(); itr!=subCMs[i]->follow_map.end(); itr++) { |
---|
| 123 | if (subCMs[i-1]->follow_map[itr->first] != 0) { |
---|
[111] | 124 | ContentModelError(); |
---|
[106] | 125 | } |
---|
| 126 | subCMs[i-1]->follow_map[itr->first]=itr->second; |
---|
| 127 | } |
---|
| 128 | } |
---|
| 129 | } |
---|
| 130 | for (int j = 0; j < subCMs.size(); j++) |
---|
| 131 | subCMs[j]->Set_Follow_Map(transition_map); |
---|
| 132 | } |
---|
| 133 | |
---|
| 134 | |
---|
| 135 | |
---|
| 136 | void CRE_Choice :: Compile() { |
---|
| 137 | matches_empty = false; |
---|
| 138 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 139 | if (subCMs[i]->matches_empty) |
---|
| 140 | matches_empty = true; |
---|
| 141 | } |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | int CRE_Name :: Set_IDs(int ID_base) { |
---|
| 145 | stateID = ++ID_base; |
---|
| 146 | return stateID; |
---|
| 147 | } |
---|
| 148 | |
---|
| 149 | int CRE_Seq :: Set_IDs(int ID_base) { |
---|
| 150 | int b = ID_base; |
---|
| 151 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 152 | b = subCMs[i]->Set_IDs(b); |
---|
| 153 | } |
---|
| 154 | return b; |
---|
| 155 | } |
---|
| 156 | |
---|
| 157 | int CRE_Choice :: Set_IDs(int ID_base) { |
---|
| 158 | int b = ID_base; |
---|
| 159 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 160 | b = subCMs[i]->Set_IDs(b); |
---|
| 161 | } |
---|
| 162 | return b; |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | int CRE_Star :: Set_IDs(int ID_base) { |
---|
| 166 | return subCM->Set_IDs(ID_base); |
---|
| 167 | } |
---|
| 168 | |
---|
| 169 | int CRE_Plus :: Set_IDs(int ID_base) { |
---|
| 170 | return subCM->Set_IDs(ID_base); |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | int CRE_Opt :: Set_IDs(int ID_base) { |
---|
| 174 | return subCM->Set_IDs(ID_base); |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | |
---|
| 178 | void CRE_Name :: Set_First_Map() { |
---|
| 179 | first_map[elemID]=stateID; |
---|
| 180 | } |
---|
| 181 | |
---|
| 182 | |
---|
| 183 | void CRE_Seq :: Set_First_Map() { |
---|
| 184 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 185 | subCMs[i]->Set_First_Map(); |
---|
| 186 | } |
---|
| 187 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 188 | int fm_size = first_map.size(); |
---|
| 189 | symbol_set_t s_i = subCMs[i]->first_map; |
---|
| 190 | int s_i_size = s_i.size(); |
---|
| 191 | |
---|
| 192 | hash_map<int, int >::iterator j; |
---|
| 193 | for (j=s_i.begin(); j!=s_i.end(); j++) first_map[j->first]=j->second; |
---|
| 194 | |
---|
| 195 | // if (first_map.size() < fm_size + s_i_size) { |
---|
[111] | 196 | // ContentModelError(); |
---|
[106] | 197 | // } |
---|
| 198 | if (!(subCMs[i]->matches_empty)){ |
---|
| 199 | return; |
---|
| 200 | } |
---|
| 201 | } |
---|
| 202 | } |
---|
| 203 | |
---|
| 204 | void CRE_Choice :: Set_First_Map() { |
---|
| 205 | for(int i=0; i< subCMs.size(); i++){ |
---|
| 206 | subCMs[i]->Set_First_Map(); |
---|
| 207 | int fm_size = first_map.size(); |
---|
| 208 | symbol_set_t s_i = subCMs[i]->first_map; |
---|
| 209 | int s_i_size = s_i.size(); |
---|
| 210 | |
---|
| 211 | hash_map<int, int >::iterator j; |
---|
| 212 | for (j=s_i.begin(); j!=s_i.end(); j++) first_map[j->first]=j->second; |
---|
| 213 | |
---|
| 214 | // if (first_map.size() < fm_size + s_i_size) { |
---|
[111] | 215 | // ContentModelError(); |
---|
[106] | 216 | // } |
---|
| 217 | } |
---|
| 218 | } |
---|
| 219 | |
---|
| 220 | void CRE_Star :: Set_First_Map() { |
---|
| 221 | subCM->Set_First_Map(); |
---|
| 222 | first_map=subCM->first_map; |
---|
| 223 | } |
---|
| 224 | |
---|
| 225 | void CRE_Plus :: Set_First_Map() { |
---|
| 226 | subCM->Set_First_Map(); |
---|
| 227 | first_map=subCM->first_map; |
---|
| 228 | } |
---|
| 229 | |
---|
| 230 | void CRE_Opt :: Set_First_Map() { |
---|
| 231 | subCM->Set_First_Map(); |
---|
| 232 | first_map=subCM->first_map; |
---|
| 233 | } |
---|
| 234 | |
---|
| 235 | |
---|
| 236 | |
---|
| 237 | |
---|
| 238 | |
---|
| 239 | |
---|
| 240 | |
---|
| 241 | |
---|
| 242 | |
---|
| 243 | |
---|