1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef ADC_CPP_CALLF_HXX
25 #define ADC_CPP_CALLF_HXX
26
27 // USED SERVICES
28
29
30
31
32 /** This represents a function to be called, if a specific kind of token
33 arrives in the semantic parser.
34
35 @descr This class is only to be used as member of PeStatus<PE>.
36 @template PE
37 The owning ParseEnvironment.
38 @see PeStatus, ParseEnvironment
39 */
40 template <class PE>
41 class CallFunction
42 {
43 public:
44 typedef void (PE::*F_Tok)(const char *);
45
46 CallFunction(
47 F_Tok i_f2Call,
48 INT16 i_nTokType );
49
50 F_Tok GetF() const;
51 INT16 TokType() const;
52
53 private:
54 // DATA
55 F_Tok f2Call;
56 INT16 nTokType;
57 };
58
59
60 /** One state within a ParseEnvironment.
61
62 @template PE
63 The owning ParseEnvironment.
64 */
65 template <class PE>
66 class PeStatus
67 {
68 public:
69 typedef typename CallFunction<PE>::F_Tok F_Tok;
70
71 PeStatus(
72 PE & i_rMyPE,
73 uintt i_nSize,
74 F_Tok * i_pFuncArray,
75 INT16 * i_pTokTypeArray,
76 F_Tok i_pDefault );
77 virtual ~PeStatus();
78
79 virtual void Call_Handler(
80 INT16 i_nTokTypeId,
81 const char * i_sTokenText ) const;
82
83 private:
84 bool CheckForCall(
85 uintt i_nPos,
86 INT16 i_nTokTypeId,
87 const char * i_sTokenText ) const;
88
89 PE * pMyPE;
90 std::vector< CallFunction<PE> >
91 aBranches;
92 F_Tok fDefault;
93 };
94
95
96 template <class PE>
97 class PeStatusArray
98 {
99 public:
100 typedef typename PE::E_State State;
101
102 PeStatusArray();
103 void InsertState(
104 State i_ePosition,
105 DYN PeStatus<PE> & let_drState );
106 ~PeStatusArray();
107
108 const PeStatus<PE> &
109 operator[](
110 State i_ePosition ) const;
111
112 void SetCur(
113 State i_eCurState );
114 const PeStatus<PE> &
115 Cur() const;
116
117 private:
118 DYN PeStatus<PE> * aStati[PE::size_of_states];
119 State eState;
120 };
121
122
123
124 // IMPLEMENTATION
125
126
127 // CallFunction
128
129 template <class PE>
CallFunction(F_Tok i_f2Call,INT16 i_nTokType)130 CallFunction<PE>::CallFunction( F_Tok i_f2Call,
131 INT16 i_nTokType )
132 : f2Call(i_f2Call),
133 nTokType(i_nTokType)
134 {
135 }
136
137 template <class PE>
138 inline typename CallFunction<PE>::F_Tok
GetF() const139 CallFunction<PE>::GetF() const
140 {
141 return f2Call;
142 }
143
144 template <class PE>
145 inline INT16
TokType() const146 CallFunction<PE>::TokType() const
147 {
148 return nTokType;
149 }
150
151
152
153 // PeStatus
154
155 template <class PE>
PeStatus(PE & i_rMyPE,uintt i_nSize,F_Tok * i_pFuncArray,INT16 * i_pTokTypeArray,F_Tok i_fDefault)156 PeStatus<PE>::PeStatus( PE & i_rMyPE,
157 uintt i_nSize,
158 F_Tok * i_pFuncArray,
159 INT16 * i_pTokTypeArray,
160 F_Tok i_fDefault )
161 : pMyPE(&i_rMyPE),
162 fDefault(i_fDefault)
163 {
164 aBranches.reserve(i_nSize);
165 for ( uintt i = 0; i < i_nSize; ++i )
166 {
167 // csv_assert(i > 0 ? i_pTokTypeArray[i] > i_pTokTypeArray[i-1] : true);
168 aBranches.push_back( CallFunction<PE>( i_pFuncArray[i], i_pTokTypeArray[i]) );
169 } // end for
170 }
171
172 template <class PE>
~PeStatus()173 PeStatus<PE>::~PeStatus()
174 {
175
176 }
177
178 template <class PE>
179 void
Call_Handler(INT16 i_nTokTypeId,const char * i_sTokenText) const180 PeStatus<PE>::Call_Handler( INT16 i_nTokTypeId,
181 const char * i_sTokenText ) const
182 {
183 uintt nSize = aBranches.size();
184 uintt nPos = nSize / 2;
185
186 if ( i_nTokTypeId < aBranches[nPos].TokType() )
187 {
188 for ( --nPos; intt(nPos) >= 0; --nPos )
189 {
190 if (CheckForCall(nPos, i_nTokTypeId, i_sTokenText))
191 return;
192 }
193 }
194 else
195 {
196 for ( ; nPos < nSize; ++nPos )
197 {
198 if (CheckForCall(nPos, i_nTokTypeId, i_sTokenText))
199 return;
200 }
201 }
202
203 (pMyPE->*fDefault)(i_sTokenText);
204 }
205
206 template <class PE>
207 bool
CheckForCall(uintt i_nPos,INT16 i_nTokTypeId,const char * i_sTokenText) const208 PeStatus<PE>::CheckForCall( uintt i_nPos,
209 INT16 i_nTokTypeId,
210 const char * i_sTokenText ) const
211 {
212 if ( aBranches[i_nPos].TokType() == i_nTokTypeId )
213 {
214 (pMyPE->*aBranches[i_nPos].GetF())(i_sTokenText);
215 return true;
216 }
217 return false;
218 }
219
220 // PeStatusArray
221
222 template <class PE>
PeStatusArray()223 PeStatusArray<PE>::PeStatusArray()
224 : eState(PE::size_of_states)
225 {
226 memset(aStati, 0, sizeof aStati);
227 }
228
229 template <class PE>
230 void
InsertState(State i_ePosition,DYN PeStatus<PE> & let_drState)231 PeStatusArray<PE>::InsertState( State i_ePosition,
232 DYN PeStatus<PE> & let_drState )
233 {
234 csv_assert(aStati[i_ePosition] == 0);
235 aStati[i_ePosition] = &let_drState;
236 }
237
238 template <class PE>
~PeStatusArray()239 PeStatusArray<PE>::~PeStatusArray()
240 {
241 int i_max = PE::size_of_states;
242 for (int i = 0; i < i_max; i++)
243 {
244 delete aStati[i];
245 } // end for
246 }
247
248 template <class PE>
249 inline const PeStatus<PE> &
operator [](State i_ePosition) const250 PeStatusArray<PE>::operator[]( State i_ePosition ) const
251 {
252 csv_assert( uintt(i_ePosition) < PE::size_of_states );
253 csv_assert( aStati[i_ePosition] != 0 );
254 return *aStati[i_ePosition];
255 }
256
257 template <class PE>
258 inline void
SetCur(State i_eCurState)259 PeStatusArray<PE>::SetCur( State i_eCurState )
260 {
261 eState = i_eCurState;
262 }
263
264
265 template <class PE>
266 const PeStatus<PE> &
Cur() const267 PeStatusArray<PE>::Cur() const
268 {
269 return (*this)[eState];
270 }
271
272 #define SEMPARSE_CREATE_STATUS(penv, state, default_function) \
273 pStati->InsertState( state, \
274 *new PeStatus<penv>( \
275 *this, \
276 sizeof( stateT_##state ) / sizeof (INT16), \
277 stateF_##state, \
278 stateT_##state, \
279 &penv::default_function ) )
280
281
282 #endif
283
284