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