Top  Previous  Next

Code generation > Supporting code > CTT_Guard


template <class char_type, class plugin_type> class CTT_Guard


At the beginning of every production the constructor of an instance of the class CTT_Guard takes care that a stack is updated which consists of the scanners - more exactly: pointers to scanners - which has to be tested at the end of the call of a production.When leaving the function, the destructor of CTT_Guard actualizes the stack again, by removing the last added scanner. The destructor is used since other instructions wouldn't be executed any more after a return instruction.


The first template parameter either can be char or wchar_t. The second template parameter is either  CTT_ParseStatePlugin or a type derived from it.





The code produced by the TextTransformer shall be portable, i.e. it shall work on different systems and with different c++ compilers. Because Microsoft Visual Express C++ behaves differently than other compilers, it is required to include the complete code of a production into a try-catch block - by means of two macros - so that the call of the destructor is actually carried out at the desired time.


#define ENTER_GUARD(number, production) \

  GUARD Guard = ProductionBegin(xState, xiScannerIndex, xiSkipScannerIndex, xeLS, number, production); \

  try {


(ENTER_CONST_GUARD and ENTER_LA_GUARD are corresponding macros for const parsers and lookaheads.)


#define EXIT_GUARD(number, returnvalue) \

       } \

  catch (...) { \

     if(xiScannerIndex > -2) \

        throw; \

  } \

  Guard.StayAlive(); \

  return returnvalue;



An "optimization" takes care in Visual express C++ that the CTT_Guard variable is destroyed again immediately after its creation. To keep the variable at life up to the moment, where the production is left, the Microsoft compiler must be led to believe that the variable would be needed again. Therefore the otherwise useless StayAlive function of the CTT_Guard class is called after the catch-block. This function only will be passed, when the production doesn't return a value. Otherwise the return is already carried out within the try-catch block. If an exception is actually catched, it is thrown again in any case. The condition:


if(xiScannerIndex > -2)


is always true, as result of the code generator. However, for the compiler the StayAlive call seems to be reachable.


Without the last line of the macro the code wouldn't compile.


return returnvalue;


If the production doesn't return a value, returnvalue remains empty. If the production, however, returns a value, a default value must be known for the return type although the line is actually never executed. This value can therefore be arbitrary as long as it matches the corresponding return type. For the interpreter code the return value is generated automatically. But if a return type is defined in code only for the export a default value must be given. This can be done in the field for the return type by appending a slash and the value. E.g.::


{_ CProduktion* _}/NULL



This page belongs to the TextTransformer Documentation

Home  Content  German