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> 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 139 CallFunction<PE>::GetF() const 140 { 141 return f2Call; 142 } 143 144 template <class PE> 145 inline INT16 146 CallFunction<PE>::TokType() const 147 { 148 return nTokType; 149 } 150 151 152 153 // PeStatus 154 155 template <class PE> 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> 173 PeStatus<PE>::~PeStatus() 174 { 175 176 } 177 178 template <class PE> 179 void 180 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 208 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> 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 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> 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> & 250 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 259 PeStatusArray<PE>::SetCur( State i_eCurState ) 260 { 261 eState = i_eCurState; 262 } 263 264 265 template <class PE> 266 const PeStatus<PE> & 267 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