source: trunk/src/contentmodel.c @ 4225

Last change on this file since 4225 was 111, checked in by cameron, 11 years ago

Consolidation of error handling: xml_error.c

File size: 5.4 KB
Line 
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"
9#include "xml_error.h"
10
11CM_Any::CM_Any(): ContentModel() {
12        cm_type = cm_Any;
13}
14
15CM_Empty::CM_Empty() : ContentModel() {
16        cm_type = cm_Empty;
17}
18
19CM_Mixed::CM_Mixed() : ContentModel() {
20        cm_type = cm_Mixed;
21}
22
23CM_RegExp::CM_RegExp() : ContentModel() {
24        cm_type = cm_RegExp;
25}
26
27CRE_Star::CRE_Star(Content_RE * s) : Content_RE() {
28        subCM = s;
29        matches_empty = true;
30}
31
32CRE_Plus::CRE_Plus(Content_RE * s) : Content_RE() {
33        subCM = s;
34        matches_empty = s->matches_empty;
35}
36
37CRE_Opt::CRE_Opt(Content_RE * s) : Content_RE() {
38        subCM = s;
39        matches_empty = true;
40}
41CRE_Name::CRE_Name(int id) : Content_RE() {
42        elemID = id;
43        matches_empty = false;
44}
45
46CRE_Seq::CRE_Seq() : Content_RE() {
47}
48
49CRE_Choice::CRE_Choice() : Content_RE() {
50}
51
52void 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}
61void 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
69void 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) {
76                        ContentModelError();                   
77                }
78                subCM->follow_map[j->first]=j->second;
79        }
80        subCM->Set_Follow_Map(transition_map);
81}
82
83void 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) {
89                        ContentModelError();
90                }
91                subCM->follow_map[j->first]=j->second;
92        }
93        subCM->Set_Follow_Map(transition_map);
94}
95
96void 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
101void 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
108void 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) {
115                                ContentModelError();
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) {
124                                        ContentModelError();
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
136void 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
144int CRE_Name :: Set_IDs(int ID_base) {
145        stateID = ++ID_base;
146        return stateID;
147}
148
149int 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
157int 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
165int CRE_Star :: Set_IDs(int ID_base) {
166        return subCM->Set_IDs(ID_base);
167}
168
169int CRE_Plus :: Set_IDs(int ID_base) {
170        return subCM->Set_IDs(ID_base);
171}
172
173int CRE_Opt :: Set_IDs(int ID_base) {
174        return subCM->Set_IDs(ID_base);
175}
176
177
178void CRE_Name :: Set_First_Map() {
179        first_map[elemID]=stateID;
180}
181
182
183void 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) {
196//                      ContentModelError();
197//              }
198                if (!(subCMs[i]->matches_empty)){
199                        return;
200                }
201        }
202}
203
204void 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) {
215//                      ContentModelError();
216//              }
217        }
218}
219
220void CRE_Star :: Set_First_Map() {
221        subCM->Set_First_Map();
222        first_map=subCM->first_map;
223}
224
225void CRE_Plus :: Set_First_Map() {
226        subCM->Set_First_Map();
227        first_map=subCM->first_map;
228}
229
230void 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       
Note: See TracBrowser for help on using the repository browser.