Skip to content
Snippets Groups Projects
Select Git revision
  • 9089501b53d9496877154b6e874ffd64f943d3dd
  • master default
  • cgnsUnstructured
  • partitioning
  • poppler
  • HighOrderBLCurving
  • gmsh_3_0_4
  • gmsh_3_0_3
  • gmsh_3_0_2
  • gmsh_3_0_1
  • gmsh_3_0_0
  • gmsh_2_16_0
  • gmsh_2_15_0
  • gmsh_2_14_1
  • gmsh_2_14_0
  • gmsh_2_13_2
  • gmsh_2_13_1
  • gmsh_2_12_0
  • gmsh_2_11_0
  • gmsh_2_10_1
  • gmsh_2_10_0
  • gmsh_2_9_3
  • gmsh_2_9_2
  • gmsh_2_9_1
  • gmsh_2_9_0
  • gmsh_2_8_6
26 results

GModelIO_Mesh.cpp

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    ProParser.y 327.18 KiB
    %{
    // GetDP - Copyright (C) 1997-2015 P. Dular, C. Geuzaine
    //
    // See the LICENSE.txt file for license information. Please report all
    // bugs and problems to the public mailing list <getdp@onelab.info>.
    //
    // Contributor(s):
    //   Ruth Sabariego
    //   Johan Gyselinck
    //
    
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>
    #include <math.h>
    #include <time.h>
    #include "GetDPConfig.h"
    #include "GetDPVersion.h"
    #include "ProData.h"
    #include "ProDefine.h"
    #include "ProDefines.h"
    #include "ProParser.h"
    #include "MacroManager.h"
    #include "MallocUtils.h"
    #include "TreeUtils.h"
    #include "Message.h"
    #include "OS.h"
    
    // Global problem structure filled by the parser
    extern struct Problem Problem_S;
    
    // Global parser variables
    std::string getdp_yyname;
    char getdp_yyincludename[256] = "";
    long int getdp_yylinenum = 0;
    int getdp_yycolnum = 0;
    int getdp_yyincludenum = 0;
    int getdp_yyerrorlevel = 0;
    std::string getdp_yystring = "";
    std::map<std::string, std::vector<double> > CommandLineNumbers;
    std::map<std::string, std::vector<std::string> > CommandLineStrings;
    std::map<std::string, std::vector<double> > GetDPNumbers;
    std::map<std::string, std::vector<std::string> > GetDPStrings;
    std::map<std::string, std::map<int, std::vector<double> > > GetDPNumbersMap;
    
    // Static parser variables (accessible only in this file)
    
    int num_include = 0, level_include = 0;
    
    static Tree_T *ConstantTable_L = 0;
    static NameSpaces nameSpaces;
    static std::string struct_name, struct_namespace;
    static int flag_tSTRING_alloc = 0;
    static List_T *ListOfInt_L = 0, *ListOfInt_Save_L = 0;
    static List_T *ListOfPointer_L = 0, *ListOfPointer2_L = 0, *ListOfChar_L = 0;
    static List_T *ListOfFormulation = 0, *ListOfBasisFunction = 0, *ListOfEntityIndex = 0;
    
    static List_T *Operation_L = 0;
    static List_T *Current_BasisFunction_L = 0;
    static List_T *Current_WholeQuantity_L = 0;
    static List_T *Current_System_L = 0;
    static int Num_BasisFunction = 1;
    static int FlagError = 0;
    static int Type_TermOperator = 0, Type_Function = 0, Type_SuppList = 0, Type_SuppList2 = 0;
    static int nb_SuppList, Type_SuppLists[2];
    static List_T *ListsOfRegion[2];
    static int Quantity_TypeOperator = 0, Quantity_Index = 0;
    static int Current_DofIndexInWholeQuantity = 0, Last_DofIndexInWholeQuantity = 0;
    static int Current_NoDofIndexInWholeQuantity = 0;
    static int Current_System = 0, Constraint_Index = 0;
    static int TypeOperatorDofInTrace = 0, DefineQuantityIndexDofInTrace = 0;
    static int ImbricatedLoop = 0, ImbricatedTest = 0;
    static char *StringForParameter = 0;
    
    static int level_Append = 0, index_Append = -1;
    static int level_Append_2 = 0, index_Append_2 = -1; // level 2
    
    #define MAX_RECUR_TESTS 100
    static int statusImbricatedTests[MAX_RECUR_TESTS];
    
    #define MAX_RECUR_LOOPS 100
    static fpos_t FposImbricatedLoopsTab[MAX_RECUR_LOOPS];
    static int LinenoImbricatedLoopsTab[MAX_RECUR_LOOPS];
    static double LoopControlVariablesTab[MAX_RECUR_LOOPS][3];
    static char *LoopControlVariablesNameTab[MAX_RECUR_LOOPS];
    
    static struct Constant               Constant_S, Constant1_S, Constant2_S;
    static struct Expression             Expression_S, *Expression_P;
    static struct ExpressionPerRegion      ExpressionPerRegion_S;
    static struct ExpressionPerRegion2      ExpressionPerRegion2_S;
    static struct Group                  Group_S;
    static struct Constraint             Constraint_S, *Constraint_P;
    static struct ConstraintPerRegion      ConstraintPerRegion_S, *ConstraintPerRegion_P;
    static struct MultiConstraintPerRegion MultiConstraintPerRegion_S;
    static struct JacobianMethod         JacobianMethod_S;
    static struct JacobianCase             JacobianCase_S;
    static struct IntegrationMethod      IntegrationMethod_S;
    static struct IntegrationCase          IntegrationCase_S;
    static struct Quadrature               QuadratureCase_S;
    static struct FunctionSpace          FunctionSpace_S;
    static struct BasisFunction            BasisFunction_S;
    static struct GlobalBasisFunction        GlobalBasisFunction_S;
    static struct SubSpace                 SubSpace_S;
    static struct GlobalQuantity           GlobalQuantity_S;
    static struct ConstraintInFS           ConstraintInFS_S;
    static struct Formulation            Formulation_S;
    static struct DefineQuantity           DefineQuantity_S;
    static struct EquationTerm             EquationTerm_S;
    static struct WholeQuantity            WholeQuantity_S, *WholeQuantity_P;
    static struct GlobalEquationTerm       GlobalEquationTerm_S;
    static struct Resolution             Resolution_S;
    static struct DefineSystem             DefineSystem_S;
    static struct Operation                Operation_S, *Operation_P;
    static struct ChangeOfState            ChangeOfState_S;
    static struct TimeLoopAdaptiveSystem   TimeLoopAdaptiveSystem_S;
    static struct LoopErrorPostOperation   TimeLoopAdaptivePO_S, IterativeLoopPO_S;
    static struct IterativeLoopSystem      IterativeLoopSystem_S;
    static struct PostProcessing         PostProcessing_S, InteractivePostProcessing_S;
    static struct PostQuantity             PostQuantity_S;
    static struct PostQuantityTerm           PostQuantityTerm_S;
    static struct PostOperation          PostOperation_S;
    static struct PostSubOperation         PostSubOperation_S;
    
    static std::map<std::string, std::vector<double> > floatOptions;
    static std::map<std::string, std::vector<std::string> > charOptions;
    static int flag_Enum, member_ValMax;
    
    void init_Options(int member_ValMax_ = 0)
    {
      floatOptions.clear(); charOptions.clear();
      flag_Enum = 0; member_ValMax = member_ValMax_;
    }
    
    // External lexer functions
    void hack_fsetpos();
    void hack_fsetpos_printf();
    int  getdp_yylex();
    
    // Forward function declarations
    void Alloc_ParserVariables();
    int Check_NameOfStructExist(const char *Struct, List_T *List_L, void *data,
                                int (*fcmp)(const void *a, const void *b),
                                int level_Append);
    int  Add_Group(struct Group *Group_P, char *Name, bool Flag_Add,
                   int Flag_Plus, int Num_Index);
    int  Num_Group(struct Group *Group_P, char *Name, int Num_Group);
    void Fill_GroupInitialListFromString(List_T *list, const char *str);
    int  Add_Expression(struct Expression *Expression_P, char *Name, int Flag_Plus);
    bool Is_ExpressionPieceWiseDefined(int index);
    void Pro_DefineQuantityIndex(List_T *WholeQuantity_L,int DefineQuantityIndexEqu,
    			     int *NbrQuantityIndex, int **QuantityIndexTable,
    			     int **QuantityTraceGroupIndexTable);
    void Pro_DefineQuantityIndex_1(List_T *WholeQuantity_L, int TraceGroupIndex);
    void yyerror(const char *s);
    void vyyerror(int level, const char *fmt, ...);
    
    double Treat_Struct_FullName_Float
      (char* c1, char* c2, int type_var = 1, int index = 0,
       double val_default = 0., int type_treat = 0);
    double Treat_Struct_FullName_dot_tSTRING_Float
      (char* c1, char* c2, char* c3, int index = 0,
       double val_default = 0., int type_treat = 0);
    List_T * Treat_Struct_FullName_dot_tSTRING_ListOfFloat
      (char* c1, char* c2, char* c3);
    int Treat_Struct_FullName_dot_tSTRING_Float_getDim
      (char* c1, char* c2, char* c3);
    char* Treat_Struct_FullName_String
      (char* c1, char* c2, int type_var = 1, int index = 0,
       char* val_default = NULL, int type_treat = 0);
    char* Treat_Struct_FullName_dot_tSTRING_String
      (char* c1, char* c2, char* c3, int index = 0,
       char* val_default = NULL, int type_treat = 0);
    List_T * Treat_Struct_FullName_dot_tSTRING_ListOfString
      (char* c1, char* c2, char* c3);
    
    struct doubleXstring{
      double d;
      char *s;
    };
    
    %}
    
    /* ------------------------------------------------------------------ */
    %union {
      char    *c;
      int     i;
      double  d;
      List_T  *l;
      struct TwoInt t ;
      struct TwoChar c2;
    }
    
    %token <i> tINT
    %token <d> tFLOAT
    %token <c> tSTRING tBIGSTR
    
    %type <i>  GroupRHS ReducedGroupRHS
    %type <i>  FunctionForGroup SuppListTypeForGroup
    %type <i>  Expression Printf
    %type <i>  ArgumentsForFunction RecursiveListOfQuantity
    %type <i>  PostQuantitySupport
    %type <l>  IRegion RecursiveListOfRegion Enumeration
    %type <i>  StrCmp NbrRegions CommaFExprOrNothing
    %type <i>  GmshOperation GenerateGroupOperation
    %type <i>  CopyOperation GetOperation
    %type <i>  Append AppendOrNot
    %type <d>  FExpr OneFExpr DefineStruct NameStruct_Arg GetForced_Default
    %type <l>  MultiFExpr ListOfFExpr RecursiveListOfFExpr
    %type <l>  MultiCharExpr RecursiveListOfListOfFExpr
    %type <l>  RecursiveListOfCharExpr Str_BracedRecursiveListOfCharExpr
    %type <l>  BracedOrNotRecursiveListOfCharExpr BracedRecursiveListOfCharExpr
    %type <l>  ParametersForFunction
    %type <l>  ListOfRegion ListOfRegionOrAll SuppListOfRegion
    %type <l>  ConstraintCases IntegrationCases QuadratureCases JacobianCases
    %type <l>  ListOfBasisFunction RecursiveListOfBasisFunction
    %type <l>  ListOfBasisFunctionCoef RecursiveListOfBasisFunctionCoef
    %type <l>  Equations WholeQuantityExpression RecursiveListOfWholeQuantityExpression
    %type <l>  DefineSystems Operation ChangeOfStates
    %type <l>  ListOfFormulation RecursiveListOfFormulation
    %type <l>  ListOfSystem RecursiveListOfSystem
    %type <l>  SubPostQuantities PostSubOperations
    %type <c>  NameForMathFunction NameForFunction CharExpr CharExprNoVar
    %type <c>  StrCat StringIndex String__Index CallArg
    %type <c>  LP RP SendToFile tSTRING_Member GetForcedStr_Default
    %type <t>  Quantity_Def
    %type <l>  TimeLoopAdaptiveSystems TimeLoopAdaptivePOs IterativeLoopSystems
    %type <l>  IterativeLoopPOs
    %type <c2> Struct_FullName
    /* ------------------------------------------------------------------ */
    %token  tEND tDOTS tSCOPE
    %token  tStr tStrList
    %token  tStrCat tSprintf tPrintf tMPI_Printf tRead tPrintConstants
    %token  tStrCmp tStrFind tStrLen
    %token  tStrChoice tStrSub tUpperCase tLowerCase tLowerCaseIn
    %token  tNbrRegions tGetRegion tGetRegions tStringToName tNameToString
    %token  tFor tEndFor tIf tElseIf tElse tEndIf tMacro tReturn tCall tCallTest
    %token  tTest tWhile tParse
    %token  tFlag tExists tFileExists tGetForced tGetForcedStr
    %token  tInclude tLevelInclude
    %token  tConstant tList tListAlt tLinSpace tLogSpace
    %token  tListFromFile
    %token  tChangeCurrentPosition
    %token  tDefineConstant tUndefineConstant tDefineNumber tDefineString
    %token  tDefineStruct tNameStruct tDimNameSpace
    %token  tGetNumber tGetString tSetNumber tSetString
    
    %token  tPi tMPI_Rank tMPI_Size t0D t1D t2D t3D tLevelTest
    %token  tTotalMemory tNumInclude
    %token  tCurrentDirectory tAbsolutePath tDirName tBaseFileName tCurrentFileName
    %token  tGETDP_MAJOR_VERSION tGETDP_MINOR_VERSION tGETDP_PATCH_VERSION
    
    %token  tExp tLog tLog10 tSqrt tSin tAsin tCos tAcos tTan
    %token    tAtan tAtan2 tSinh tCosh tTanh tAtanh tFabs tFloor tCeil tRound tSign
    %token    tFmod tModulo tHypot tRand
    %token    tSolidAngle tTrace tOrder tCrossProduct tDofValue tRational
    %token    tMHTransform tMHBilinear
    
    %token  tAppend
    
    %token  tGroup tDefineGroup tAll tInSupport tMovingBand2D
    
    %token  tDefineFunction tUndefineFunction
    
    %token  tConstraint
    %token    tRegion tSubRegion tSubRegion2 tRegionRef tSubRegionRef
    %token    tFilter tToleranceFactor tCoefficient tValue tTimeFunction
    %token    tBranch tNameOfResolution
    
    %token  tJacobian
    %token      tCase
    
    %token  tMetricTensor
    
    %token  tIntegration
    %token    tType tSubType tCriterion tGeoElement
    %token      tNumberOfPoints tMaxNumberOfPoints
    %token        tNumberOfDivisions tMaxNumberOfDivisions
    %token          tStoppingCriterion
    
    %token  tFunctionSpace
    %token    tName
    %token    tBasisFunction
    %token      tNameOfCoef tFunction tdFunction tSubFunction tSubdFunction tSupport tEntity
    %token    tSubSpace tNameOfBasisFunction
    %token    tGlobalQuantity
    %token      tEntityType tAuto tEntitySubType tNameOfConstraint
    
    %token  tFormulation
    %token    tQuantity
    %token        tNameOfSpace tIndexOfSystem
    %token        tSymmetry
    %token    tGalerkin tdeRham tGlobalTerm tGlobalEquation
    %token        tDt tDtDof tDtDt tDtDtDof tDtDtDtDof tDtDtDtDtDof tDtDtDtDtDtDof
    %token        tJacNL tDtDofJacNL tNeverDt tDtNL tEig
    %token        tAtAnteriorTimeStep tMaxOverTime tFourierSteinmetz
    %token        tIn
    %token        tFull_Matrix
    
    %token  tResolution tHidden
    %token    tDefineSystem
    %token      tNameOfFormulation tNameOfMesh tFrequency tSolver
    %token      tOriginSystem tDestinationSystem
    %token    tOperation tOperationEnd
    %token      tSetTime tSetTimeStep tSetDTime tDTime tSetFrequency
    %token      tFourierTransform tFourierTransformJ
    %token      tCopySolution tCopyRHS tCopyResidual tCopyIncrement tCopyDofs
    %token      tGetNormSolution tGetNormResidual tGetNormRHS tGetNormIncrement
    %token      tOptimizerInitialize tOptimizerUpdate tOptimizerFinalize
    %token      tLanczos tEigenSolve tEigenSolveJac tPerturbation
    %token      tUpdate tUpdateConstraint tBreak tGetResidual tCreateSolution
    %token      tEvaluate tSelectCorrection tAddCorrection tMultiplySolution
    %token      tAddOppositeFullSolution tSolveAgainWithOther tSetGlobalSolverOptions
    
    %token      tTimeLoopTheta tTimeLoopNewmark tTimeLoopRungeKutta tTimeLoopAdaptive
    %token        tTime0 tTimeMax tTheta
    %token        tBeta tGamma
    %token      tIterativeLoop tIterativeLoopN tIterativeLinearSolver
    %token      tNbrMaxIteration tRelaxationFactor
    %token      tIterativeTimeReduction
    %token        tSetCommSelf tSetCommWorld tBarrier tBroadcastFields tBroadcastVariables
    %token      tSleep
    %token      tDivisionCoefficient tChangeOfState
    %token      tChangeOfCoordinates tChangeOfCoordinates2 tSystemCommand tError
    %token        tGmshRead tGmshMerge tGmshOpen tGmshWrite tGmshClearAll
    %token        tDelete tDeleteFile tRenameFile tCreateDir
    %token      tGenerateOnly tGenerateOnlyJac
    %token      tSolveJac_AdaptRelax
    %token      tSaveSolutionExtendedMH tSaveSolutionMHtoTime tSaveSolutionWithEntityNum
    %token      tInitMovingBand2D tMeshMovingBand2D
    %token      tGenerateMHMoving tGenerateMHMovingSeparate tAddMHMoving
    %token      tGenerateGroup tGenerateJacGroup tGenerateRHSGroup
    %token      tGenerateGroupCumulative tGenerateJacGroupCumulative tGenerateRHSGroupCumulative
    %token      tSaveMesh
    %token      tDeformMesh
    %token      tFrequencySpectrum
    %token  tPostProcessing
    %token      tNameOfSystem
    
    %token  tPostOperation
    %token    tNameOfPostProcessing tUsingPost tResampleTime
    %token      tPlot tPrint tPrintGroup tEcho tSendMergeFileRequest tWrite tAdapt
    %token        tOnGlobal tOnRegion tOnElementsOf
    %token        tOnGrid tOnSection tOnPoint tOnLine tOnPlane tOnBox
    %token        tWithArgument
    %token        tFile tDepth tDimension tComma tTimeStep tHarmonicToTime
    %token        tCosineTransform tTimeToHarmonic
    %token        tValueIndex tValueName
    %token        tFormat tHeader tFooter tSkin tSmoothing
    %token        tTarget tSort tIso tNoNewLine tNoTitle tDecomposeInSimplex tChangeOfValues
    %token        tTimeLegend tFrequencyLegend tEigenvalueLegend
    %token        tEvaluationPoints tStoreInRegister tStoreInVariable
    %token        tStoreInField tStoreInMeshBasedField
    %token        tStoreMaxInRegister tStoreMaxXinRegister tStoreMaxYinRegister
    %token        tStoreMaxZinRegister tStoreMinInRegister tStoreMinXinRegister
    %token        tStoreMinYinRegister tStoreMinZinRegister
    %token        tLastTimeStepOnly tAppendTimeStepToFileName tTimeValue tTimeImagValue
    %token        tTimeInterval
    %token        tAppendExpressionToFileName tAppendExpressionFormat
    %token        tOverrideTimeStepValue tNoMesh
    %token        tSendToServer
    %token        tDate tOnelabAction tCodeName tFixRelativePath
    %token        tAppendToExistingFile tAppendStringToFileName
    
    /* ------------------------------------------------------------------ */
    /* Operators (with ascending priority): cf. C language                */
    /*                                                                    */
    /* Notes: - associativity (%left, %right)                             */
    /*        - UNARYPREC is a dummy terminal to resolve ambiguous cases  */
    /*          for + and - (which exist in both unary and binary form)   */
    /* ------------------------------------------------------------------ */
    %right   tDEF
    %right   '?' tDOTS
    %left    tOR
    %left    tAND
    %left    tEQUAL tNOTEQUAL tAPPROXEQUAL
    %left    '<' tLESSOREQUAL '>' tGREATEROREQUAL tLESSLESS tGREATERGREATER
    %left    '+' '-'
    %left    '*' '/' '%' tCROSSPRODUCT
    %left    '|' '&'
    %right   '!' UNARYPREC
    %right   '^'
    %left    '(' ')' '[' ']' '{' '}'
    %left    '~'
    %left    '.'
    %left    '#' '$' tSHOW
    %left    tSCOPE
    /* ------------------------------------------------------------------ */
    
    %start Stats
    
    %%
    
    Stats :
        { Alloc_ParserVariables(); }
        ProblemDefinitions
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  P r o b l e m                                                           */
    /* ------------------------------------------------------------------------ */
    
    
    ProblemDefinitions :
    
        /* none */
      | ProblemDefinitions
        { Formulation_S.DefineQuantity = NULL; }
        ProblemDefinition
     ;
    
    
    ProblemDefinition :
    
        tGroup             '{' Groups             '}'
      | tFunction          '{' Functions          '}'
      | tConstraint        '{' Constraints        '}'
      | tJacobian          '{' JacobianMethods    '}'
      | tIntegration       '{' IntegrationMethods '}'
      | tFunctionSpace     '{' FunctionSpaces     '}'
      | tFormulation       '{' Formulations       '}'
      | tResolution        '{' Resolutions        '}'
      | tPostProcessing    '{' PostProcessings    '}'
      | tPostOperation     '{' PostOperations     '}'
    
      | SeparatePostOperation
    
      | Loop // contains For, EndFor, If, ElseIf, Else, EndIf, Macro, Return, Call, Parse, Affectation
    
      | tInclude CharExpr
        {
          num_include++; level_include++;
          strcpy(getdp_yyincludename, $2); getdp_yyincludenum++; return(0);
        }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  G r o u p                                                               */
    /* ------------------------------------------------------------------------ */
    
    
    Groups :
    
        /* none */
      | Groups Group
     ;
    
    
    Group :
    
        String__Index tDEF ReducedGroupRHS tEND
        { Add_Group(&Group_S, $1, false, 0, 0); }
    
      | String__Index '+' tDEF ReducedGroupRHS tEND
        { Add_Group(&Group_S, $1, true, 0, 0); }
    
      | String__Index tDEF tMovingBand2D '[' IRegion
        {
          int j = 0;
          if(List_Nbr($5) == 1)
            List_Read($5, 0, &j);
          else
            vyyerror(0, "Single region number expected for moving band definition");
          Group_S.InitialList = List_Create(1, 1, sizeof(int));
          List_Add(Group_S.InitialList, &j);
          Group_S.Type = MOVINGBAND2D;
          Group_S.FunctionType = REGION;
          Group_S.InitialSuppList = NULL;
          Group_S.SuppListType = SUPPLIST_NONE;
          Group_S.MovingBand2D = (struct MovingBand2D *)Malloc(sizeof(struct MovingBand2D));
          Group_S.MovingBand2D->PhysNum = j;
        }
        ',' ListOfRegion
        {
          Group_S.MovingBand2D->InitialList1 = $8;
          Group_S.MovingBand2D->ExtendedList1 = NULL;
        }
        ',' ListOfRegion ',' FExpr ']' tEND
        {
          Group_S.MovingBand2D->InitialList2 = $11;
          Group_S.MovingBand2D->Period2 = (int)$13;
          Add_Group(&Group_S, $1, false, 0, 0);
        }
    
      | tDefineGroup '[' DefineGroups ']' tEND
    
      | Loop
     ;
    
    ReducedGroupRHS :
    
        FunctionForGroup '[' ListOfRegionOrAll
        {
          Group_S.FunctionType = $1;
          switch (Group_S.FunctionType) {
          case ELEMENTSOF :  Group_S.Type = ELEMENTLIST;  break;
          default :          Group_S.Type = REGIONLIST;  break;
          }
          Group_S.InitialList = $3;
        }
        SuppListOfRegion ']'
        {
          if (nb_SuppList >=1) {
            Group_S.SuppListType = Type_SuppLists[0];
            Group_S.InitialSuppList = ListsOfRegion[0];
          }
          else {
            Group_S.SuppListType = SUPPLIST_NONE;
            Group_S.InitialSuppList = NULL;
          }
          if (nb_SuppList >=2) {
            Group_S.SuppListType2 = Type_SuppLists[1];
            Group_S.InitialSuppList2 = ListsOfRegion[1];
          }
          else {
            Group_S.SuppListType2 = SUPPLIST_NONE;
            Group_S.InitialSuppList2 = NULL;
          }
          $$ = -1;
        }
    
      /* shortcut: #list ==  Region[ list ] */
      | '#' ListOfRegion
        {
          Group_S.FunctionType = REGION;  Group_S.Type = REGIONLIST;
          Group_S.InitialList = $2;
          Group_S.SuppListType = SUPPLIST_NONE;  Group_S.InitialSuppList = NULL;
          $$ = -1;
        }
     ;
    
    GroupRHS :
    
        ReducedGroupRHS
        {
          $$ = $1;
        }
    
      | String__Index
        {
          int i;
          if(!strcmp($1, "All")) { //+++ Never considered because token tAll exists!
    	$$ = -3;
          }
          else if((i = List_ISearchSeq(Problem_S.Group, $1, fcmp_Group_Name)) >= 0) {
    	List_Read(Problem_S.Group, i, &Group_S); $$ = i;
          }
          else {
    	$$ = -2; vyyerror(0, "Unknown Group: %s", $1);
          }
          Free($1);
        }
    
      | tAll
        {
          $$ = -3;
        }
     ;
    
    FunctionForGroup :
    
        tRegion
        { $$ = REGION; }
    
      | tSTRING
        { $$ = Get_DefineForString(FunctionForGroup_Type, $1, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($1, FunctionForGroup_Type);
    	vyyerror(0, "Unknown type of Function for Group: %s", $1);
          }
          Free($1);
        }
     ;
    
    
    ListOfRegionOrAll :
    
        ListOfRegion   { $$ = $1; }
      | tAll           { $$ = NULL; }
     ;
    
    
    SuppListOfRegion :
    
        /* none */
        { nb_SuppList = 0; /*Type_SuppList = SUPPLIST_NONE;*/  $$ = NULL; }
    
      | SuppListOfRegion Comma SuppListTypeForGroup ListOfRegion
        {
          if (nb_SuppList+1 <= 2) {
            Type_SuppLists[nb_SuppList] = $3; $$ = $4; ListsOfRegion[nb_SuppList] = $4;
            nb_SuppList++;
          }
          else
            vyyerror(0, "More than 2 supplementary lists of Regions not allowed");
        }
    
      | SuppListOfRegion Comma tInSupport String__Index
        {
          if (nb_SuppList+1 <= 2) {
            int i;
            Type_SuppLists[nb_SuppList] = SUPPLIST_INSUPPORT;
            if((i = List_ISearchSeq(Problem_S.Group, $4, fcmp_Group_Name)) >= 0) {
              if(((struct Group *)List_Pointer(Problem_S.Group, i))->Type ==
    	     ELEMENTLIST) {
                $$ = List_Create(1, 5, sizeof(int));
                List_Add($$, &i);
                ListsOfRegion[nb_SuppList] = $$;
              }
              else  vyyerror(0, "Not a Support of Element Type: %s", $4);
            }
            else  vyyerror(0, "Unknown Region for Support: %s", $4);
            Free($4);
            nb_SuppList++;
          }
          else
            vyyerror(0, "More than 2 supplementary lists of Regions not allowed");
        }
     ;
    
    SuppListTypeForGroup :
    
        tSTRING
        { $$ = Get_DefineForString(FunctionForGroup_SuppList, $1, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($1, FunctionForGroup_SuppList);
    	vyyerror(0, "Unknown type of Supplementary Region: %s", $1);
          }
          Free($1);
        }
     ;
    
    
    ListOfRegion :
        IRegion
        {
          $$ = List_Create(((List_Nbr($1) > 0)? List_Nbr($1) : 1), 5, sizeof(int));
          for(int i = 0; i < List_Nbr($1); i++)
    	List_Add($$, (int *)List_Pointer($1, i));
        }
    
      | '{' RecursiveListOfRegion '}'
        { $$ = $2; }
     ;
    
    RecursiveListOfRegion :
    
        // none
        {
          $$ = List_Create(5, 5, sizeof(int));
        }
    
      | RecursiveListOfRegion Comma IRegion
        {
          $$ = $1;
          for(int i = 0; i < List_Nbr($3); i++)
    	List_Add($$, (int *)List_Pointer($3, i));
        }
    
      | RecursiveListOfRegion Comma '-' IRegion
        {
          $$ = $1;
          for(int i = 0; i < List_Nbr($4); i++)
    	List_Suppress($$, (int *)List_Pointer($4, i), fcmp_Integer);
        }
     ;
    
    
    IRegion :
    
        tINT
        {
          List_Reset(ListOfInt_L); List_Add($$ = ListOfInt_L, &($1));
        }
    
      | tINT tDOTS tINT
        {
          List_Reset($$ = ListOfInt_L);
          for(int j = $1; ($1 < $3) ? (j <= $3) : (j >= $3);
    	  ($1 < $3) ? (j += 1) : (j -= 1))
    	List_Add(ListOfInt_L, &j);
        }
    
      | tINT tDOTS tINT tDOTS tINT
        {
          List_Reset($$ = ListOfInt_L);
          if(!$5 || ($1 < $3 && $5 < 0) || ($1 > $3 && $5 > 0)){
    	vyyerror(0, "Wrong increment in '%d : %d : %d'", $1, $3, $5);
    	List_Add(ListOfInt_L, &($1));
          }
          else
    	for(int j = $1; ($5 > 0) ? (j <= $3) : (j >= $3); j += $5)
    	  List_Add($$, &j);
        }
    
      | Struct_FullName
        {
          if ($1.char1) vyyerror(1, "NameSpace '%s' not used yet", $1.char1);
          int i;
          if((i = List_ISearchSeq(Problem_S.Group, $1.char2, fcmp_Group_Name)) < 0) {
    	// Si ce n'est pas un nom de groupe, est-ce un nom de constante ? :
    	Constant_S.Name = $1.char2;
    	if(!Tree_Query(ConstantTable_L, &Constant_S)) {
    	  vyyerror(0, "Unknown Constant: %s", $1.char2);
    	  i = 0;
    	  List_Reset(ListOfInt_L); List_Add($$ = ListOfInt_L, &i);
    	}
    	else
    	  if(Constant_S.Type == VAR_FLOAT) {
    	    i = (int)Constant_S.Value.Float;
    	    List_Reset(ListOfInt_L); List_Add($$ = ListOfInt_L, &i);
    	  }
    	  else if(Constant_S.Type == VAR_LISTOFFLOAT) {
    	    List_Reset($$ = ListOfInt_L);
    	    for(int i = 0; i < List_Nbr(Constant_S.Value.List); i++) {
    	      double d;
    	      List_Read(Constant_S.Value.List, i, &d);
    	      int j = (int)d;
    	      List_Add(ListOfInt_L, &j);
    	    }
    	  }
    	  else {
    	    vyyerror(0, "Unknown type of Constant: %s", $1.char2);
    	    i = 0;
    	    List_Reset(ListOfInt_L); List_Add($$ = ListOfInt_L, &i);
    	  }
          }
          else // Si c'est un nom de groupe :
    	$$ = ((struct Group *)List_Pointer(Problem_S.Group, i))->InitialList;
          Free($1.char1); Free($1.char2);
        }
    
      // (.) used to access all the FExpr syntax
      | '(' FExpr ')'
        {
          int i = (int)$2;
          List_Reset(ListOfInt_L); List_Add($$ = ListOfInt_L, &i);
        }
    
      // (.) used to access all the FExpr syntax
      | '(' MultiFExpr ')'
        {
          List_Reset(ListOfInt_L);
    
          for(int i = 0; i < List_Nbr($2); i++) {
    	double d;
    	List_Read($2, i, &d);
    	int j = (int)d;
    	List_Add(ListOfInt_L, &j);
          }
          $$ = ListOfInt_L;
        }
    
      // deprecated: for backward compatibility only (for Ruth :-)
      | '@' MultiFExpr '@'
        {
          List_Reset(ListOfInt_L);
    
          for(int i = 0; i < List_Nbr($2); i++) {
    	double d;
    	List_Read($2, i, &d);
    	int j = (int)d;
    	List_Add(ListOfInt_L, &j);
          }
          $$ = ListOfInt_L;
        }
    
     ;
    
    ListOfStringsForCharOptions :
    
      /* none */
    
      | tSTRING
        {
          charOptions["Strings"].push_back($1);
          Free($1);
        }
    
      | tINT
        {
          char tmp[128];
          sprintf(tmp, "%d", $1);
          charOptions["Strings"].push_back(tmp);
        }
    
      | ListOfStringsForCharOptions ',' tSTRING
        {
          charOptions["Strings"].push_back($3);
          Free($3);
        }
    
      | ListOfStringsForCharOptions ',' tINT
        {
          char tmp[128];
          sprintf(tmp, "%d", $3);
          charOptions["Strings"].push_back(tmp);
        }
     ;
    
    DefineGroups :
    
        /* none */
    
      | DefineGroups Comma String__Index
        {
          int i;
          if ( (i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) < 0 ) {
    	Group_S.Type = REGIONLIST ; Group_S.FunctionType = REGION ;
    	Group_S.InitialList = List_Create( 5, 5, sizeof(int)) ;
    	Group_S.SuppListType = SUPPLIST_NONE ; Group_S.InitialSuppList = NULL ;
    	i = Add_Group(&Group_S, $3, false, 0, 0) ;
          }
          else  Free($3) ;
        }
    
      | DefineGroups Comma String__Index tDEF '{'
        { floatOptions.clear(); charOptions.clear(); }
        '{' ListOfStringsForCharOptions '}' CharParameterOptionsOrNone '}'
        {
          int i;
          if ( (i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) < 0 ) {
            Group_S.Name = $3; // will be overwritten in Add_Group
    	Group_S.Type = REGIONLIST ; Group_S.FunctionType = REGION ;
    	Group_S.InitialList = List_Create( 5, 5, sizeof(int)) ;
            if(charOptions.count("Strings")){
              std::vector<std::string> vec(charOptions["Strings"]);
              for(unsigned int i = 0; i < vec.size(); i++)
                Fill_GroupInitialListFromString(Group_S.InitialList, vec[i].c_str());
            }
    	Group_S.SuppListType = SUPPLIST_NONE ; Group_S.InitialSuppList = NULL ;
    	i = Add_Group(&Group_S, $3, false, 0, 0) ;
          }
          else  Free($3) ;
        }
    
      | DefineGroups Comma String__Index '{' FExpr '}'
        {
          for (int k = 0 ; k < (int)$5 ; k++) {
    	char tmpstr[256];
    	sprintf(tmpstr, "%s_%d", $3, k+1) ;
    	int i;
    	if ( (i = List_ISearchSeq(Problem_S.Group, tmpstr,
    				  fcmp_Group_Name)) < 0 ) {
    	  Group_S.Type = REGIONLIST ; Group_S.FunctionType = REGION ;
    	  Group_S.SuppListType = SUPPLIST_NONE ; Group_S.InitialSuppList = NULL ;
    	  Group_S.InitialList = List_Create( 5, 5, sizeof(int)) ;
    	  Add_Group(&Group_S, $3, false, 2, k+1) ;
    	}
          }
          Free($3) ;
        }
      ;
    
    
    Comma : /* none */ | ',' ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  F u n c t i o n                                                         */
    /* ------------------------------------------------------------------------ */
    
    Functions :
    
        /* none */
      | Functions Function
     ;
    
    Function :
    
        tDefineFunction '[' DefineFunctions ']' tEND
    
      | String__Index '[' ']' tDEF Expression tEND
        {
          int i;
          if((i = List_ISearchSeq
    	    (Problem_S.Expression, $1, fcmp_Expression_Name)) >= 0) {
    	if(((struct Expression *)List_Pointer(Problem_S.Expression, i))->Type ==
    	    UNDEFINED_EXP) {
    	  Free(((struct Expression *)List_Pointer(Problem_S.Expression, i))->Name);
    	  List_Read (Problem_S.Expression, $5, &Expression_S);
    	  List_Write(Problem_S.Expression,  i, &Expression_S);
    	  ((struct Expression *)List_Pointer(Problem_S.Expression, i))->Name = $1;
    	  List_Pop(Problem_S.Expression);
    	}
    	else  { vyyerror(0, "Redefinition of Function: %s", $1); }
          }
          else {  /* new identifier */
    	Free(((struct Expression *)List_Pointer(Problem_S.Expression, $5))->Name);
    	((struct Expression *)List_Pointer(Problem_S.Expression, $5))->Name = $1;
          }
        }
    
      | String__Index '[' GroupRHS ']' tDEF Expression tEND
        {
          int i;
          if((i = List_ISearchSeq
    	    (Problem_S.Expression, $1, fcmp_Expression_Name)) < 0) {
    	/* Si le nom n'existe pas : */
    	i = List_Nbr(Problem_S.Expression);
    	Expression_S.Type = PIECEWISEFUNCTION;
    	Expression_S.Case.PieceWiseFunction.ExpressionPerRegion =
    	  List_Create(5, 5, sizeof(struct ExpressionPerRegion));
    	Expression_S.Case.PieceWiseFunction.ExpressionIndex_Default = -1;
    	Expression_S.Case.PieceWiseFunction.NumLastRegion = -1;
    	Add_Expression(&Expression_S, $1, 0);
    	Expression_P = (struct Expression*)List_Pointer(Problem_S.Expression, i);
          }
          else {
    	Expression_P = (struct Expression*)List_Pointer(Problem_S.Expression, i);
    	if(Expression_P->Type == UNDEFINED_EXP) {
    	  Expression_P->Type = PIECEWISEFUNCTION;
    	  Expression_P->Case.PieceWiseFunction.ExpressionPerRegion =
    	    List_Create(5, 5, sizeof(struct ExpressionPerRegion));
              Expression_P->Case.PieceWiseFunction.ExpressionIndex_Default = -1;
    	  Expression_P->Case.PieceWiseFunction.NumLastRegion = -1;
    	}
    	else if(Expression_P->Type != PIECEWISEFUNCTION)
    	  vyyerror(0, "Not piece-wise Expression: %s", $1);
    	Free($1);
          }
    
          if($3 >= 0 || $3 == -1) {
    	ExpressionPerRegion_S.ExpressionIndex = $6;
    	for(int i = 0; i < List_Nbr(Group_S.InitialList); i++) {
    	  List_Read(Group_S.InitialList, i, &ExpressionPerRegion_S.RegionIndex);
    
    	  if(List_Search(Expression_P->Case.PieceWiseFunction.ExpressionPerRegion,
    			  &ExpressionPerRegion_S.RegionIndex, fcmp_Integer))
    	    vyyerror(0, "Redefinition of piece-wise Function: %s [%d]",
    		     Expression_P->Name, ExpressionPerRegion_S.RegionIndex);
    	  else
    	    List_Add(Expression_P->Case.PieceWiseFunction.ExpressionPerRegion,
    		     &ExpressionPerRegion_S);
    	}
    	if($3 == -1) { List_Delete(Group_S.InitialList); }
          }
          else if ($3 == -3) // Default Case when GroupRHS is 'All'
            Expression_P->Case.PieceWiseFunction.ExpressionIndex_Default = $6;
    
          else  vyyerror(0, "Bad Group right hand side");
        }
    
      | String__Index '[' GroupRHS
        {
          ListOfInt_Save_L = Group_S.InitialList;
        }
    
        ',' GroupRHS ']' tDEF Expression tEND
        {
          int i;
          if((i = List_ISearchSeq
    	    (Problem_S.Expression, $1, fcmp_Expression_Name)) < 0) {
    	/* Si le nom n'existe pas : */
    	i = List_Nbr(Problem_S.Expression);
    	Expression_S.Type = PIECEWISEFUNCTION2;
    	Expression_S.Case.PieceWiseFunction2.ExpressionPerRegion =
    	  List_Create(25, 50, sizeof(struct ExpressionPerRegion2));
    	Expression_S.Case.PieceWiseFunction2.ExpressionIndex_Default = -1;
    	Expression_S.Case.PieceWiseFunction2.NumLastRegion[0] = -1;
    	Expression_S.Case.PieceWiseFunction2.NumLastRegion[1] = -1;
    	Add_Expression(&Expression_S, $1, 0);
    	Expression_P = (struct Expression*)List_Pointer(Problem_S.Expression, i);
          }
          else {
    	Expression_P = (struct Expression*)List_Pointer(Problem_S.Expression, i);
    	if(Expression_P->Type == UNDEFINED_EXP) {
    	  Expression_P->Type = PIECEWISEFUNCTION2;
    	  Expression_P->Case.PieceWiseFunction2.ExpressionPerRegion =
    	    List_Create(25, 50, sizeof(struct ExpressionPerRegion2));
              Expression_P->Case.PieceWiseFunction2.ExpressionIndex_Default = -1;
    	  Expression_P->Case.PieceWiseFunction2.NumLastRegion[0] = -1;
    	  Expression_P->Case.PieceWiseFunction2.NumLastRegion[1] = -1;
    	}
    	else if(Expression_P->Type != PIECEWISEFUNCTION2)
    	  vyyerror(0, "Not double-piece-wise Expression: %s", $1);
    	Free($1);
          }
    
          if($3 >= 0 || $3 == -1) {
    	ExpressionPerRegion2_S.ExpressionIndex = $9;
    	for(int i = 0; i < List_Nbr(ListOfInt_Save_L); i++) {
              List_Read(ListOfInt_Save_L, i, &ExpressionPerRegion2_S.RegionIndex[0]);
              for(int j = 0; j < List_Nbr(Group_S.InitialList); j++) {
                List_Read(Group_S.InitialList, i, &ExpressionPerRegion2_S.RegionIndex[1]);
    
                if(List_Search(Expression_P->Case.PieceWiseFunction2.ExpressionPerRegion,
                               &ExpressionPerRegion2_S.RegionIndex[0], fcmp_Integer2))
                  vyyerror(0, "Redefinition of piece-wise Function: %s [%d, %d]",
                           Expression_P->Name, ExpressionPerRegion2_S.RegionIndex[0],
                           ExpressionPerRegion2_S.RegionIndex[1]);
                else
                  List_Add(Expression_P->Case.PieceWiseFunction2.ExpressionPerRegion,
                           &ExpressionPerRegion2_S);
              }
            }
    	if($3 == -1) { List_Delete(Group_S.InitialList); }
          }
          else if ($3 == -3 && $6 == -3) // Default Case when GroupRHS is 'All' x2
            Expression_P->Case.PieceWiseFunction2.ExpressionIndex_Default = $9;
    
          else  vyyerror(0, "Bad Group right hand side");
        }
    
      | Loop
     ;
    
    
    DefineFunctions :
    
        /* none */
      | DefineFunctions Comma String__Index
        {
          int i;
          if ( (i = List_ISearchSeq
    	    (Problem_S.Expression, $3, fcmp_Expression_Name)) < 0 ) {
    	Expression_S.Type = UNDEFINED_EXP ;
    	Add_Expression(&Expression_S, $3, 0) ;
          }
          else  Free($3) ;
        }
    
      | DefineFunctions Comma String__Index '{' FExpr '}'
        {
          for (int k = 0 ; k < (int)$5 ; k++) {
    	char tmpstr[256];
    	sprintf(tmpstr, "%s_%d", $3, k+1) ;
    	int i;
    	if ( (i = List_ISearchSeq(Problem_S.Expression, tmpstr,
    				  fcmp_Expression_Name)) < 0 ) {
    	  Expression_S.Type = UNDEFINED_EXP ;
    	  Add_Expression(&Expression_S, tmpstr, 2) ;
    	}
          }
          Free($3) ;
        }
      ;
    
    
    UndefineFunctions :
    
        /* none */
      | UndefineFunctions Comma String__Index
        {
          int i = List_ISearchSeq(Problem_S.Expression, $3, fcmp_Expression_Name);
          if(i >= 0){
            Free(((struct Expression *)List_Pointer(Problem_S.Expression, i))->Name);
            List_PSuppress(Problem_S.Expression, i);
          }
          Free($3) ;
        }
    
    /* ------------------------------------------------------------------------
        E x p r e s s i o n s
       ------------------------------------------------------------------------ */
    
    Expression :
    
      /* expressions constantes: evaluees lors de l'analyse syntaxique */
        tConstant '[' FExpr ']'
        { Expression_S.Type = CONSTANT;  Expression_S.Case.Constant = $3;
          $$ = Add_Expression(&Expression_S, (char*)"Exp_Cst", 1);
        }
    
      /* reutilisation de fonctions deja definies en amont */
      | tFunction '[' tSTRING ']'
        { int i;
          if((i = List_ISearchSeq(Problem_S.Expression, $3, fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Unknown name of Expression: %s", $3);
          Free($3);  $$ = i;
        }
    
      /* whole quantity */
      | { Current_DofIndexInWholeQuantity = -2;
          List_Reset(ListOfPointer_L); List_Reset(ListOfPointer2_L); }
        WholeQuantityExpression
        { Expression_S.Type = WHOLEQUANTITY;  Expression_S.Case.WholeQuantity = $2;
          $$ = Add_Expression(&Expression_S, (char*)"Exp_Fct", 1); }
    
      /* undefined expression (same as DefineFunction, but inline) */
      | '*' '*' '*'
        { Expression_S.Type = UNDEFINED_EXP;
          $$ = Add_Expression(&Expression_S, (char*)"Exp_Undefined", 1);
        }
     ;
    
    ListOfExpression :
    
        /* none */  { List_Reset(ListOfInt_L); }
      /* shift/reduce
      | Expression  { List_Reset(ListOfInt_L);  List_Add(ListOfInt_L, &($1)); }
      */
      | '{' RecursiveListOfExpression '}'
     ;
    
    
    RecursiveListOfExpression :
    
        Expression
        { List_Reset(ListOfInt_L);  List_Add(ListOfInt_L, &($1)); }
    
      | RecursiveListOfExpression ',' Expression
        { List_Add(ListOfInt_L, &($3)); }
     ;
    
    
    WholeQuantityExpression :
    
        { Current_WholeQuantity_L = List_Create(5, 5, sizeof(struct WholeQuantity));
          List_Add(ListOfPointer_L, &Current_WholeQuantity_L);
        }
        WholeQuantity
        { $$ = *((List_T **)List_Pointer(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1));
          List_Pop(ListOfPointer_L);
        }
     ;
    
    RecursiveListOfWholeQuantityExpression :
    
        WholeQuantityExpression
        {
          $$ = List_Create(5, 5, sizeof(List_T*));
          List_Add($$, &$1);
        }
      | RecursiveListOfWholeQuantityExpression ',' WholeQuantityExpression
        {
          List_Add($$, &$3);
        }
     ;
    
    WholeQuantity :
    
        WholeQuantity_Single
    
      |  WholeQuantity '?'
        {
          WholeQuantity_S.Type = WQ_TEST;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
    
          WholeQuantity_P = (struct WholeQuantity*)
    	List_Pointer(Current_WholeQuantity_L, List_Nbr(Current_WholeQuantity_L)-1);
          List_Add(ListOfPointer2_L, &WholeQuantity_P);
          List_Add(ListOfPointer2_L, &WholeQuantity_P);
    
          Current_WholeQuantity_L = List_Create(5, 5, sizeof(struct WholeQuantity));
          List_Add(ListOfPointer_L, &Current_WholeQuantity_L);
        }
        WholeQuantity tDOTS
        {
          WholeQuantity_P =
    	*((struct WholeQuantity**)
    	  List_Pointer(ListOfPointer2_L, List_Nbr(ListOfPointer2_L)-1));
          List_Pop(ListOfPointer2_L);
    
          WholeQuantity_P->Case.Test.WholeQuantity_True =
    	*((List_T **)List_Pointer(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1));
          List_Pop(ListOfPointer_L);
    
          Current_WholeQuantity_L = List_Create(5, 5, sizeof(struct WholeQuantity));
          List_Add(ListOfPointer_L, &Current_WholeQuantity_L);
        }
        WholeQuantity
        {
          WholeQuantity_P =
    	*((struct WholeQuantity**)
    	  List_Pointer(ListOfPointer2_L, List_Nbr(ListOfPointer2_L)-1));
          List_Pop(ListOfPointer2_L);
    
          WholeQuantity_P->Case.Test.WholeQuantity_False =
    	*((List_T **)List_Pointer(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1));
          List_Pop(ListOfPointer_L);
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
        }
    
      | WholeQuantity '*' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_TIME;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_ProductValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tCROSSPRODUCT WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_CROSSPRODUCT;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_CrossProductValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | tCrossProduct '[' WholeQuantity ',' WholeQuantity ']'
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_CROSSPRODUCT;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_CrossProductValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '/' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_DIVIDE;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_DivideValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '+' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_PLUS;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_AddValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '-' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_MINUS;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_SubstractValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '%' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_MODULO;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_ModuloValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '^' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_POWER;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_PowerValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '<' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_LESS;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_LessValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity '>' WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_GREATER;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_GreaterValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tLESSOREQUAL WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_LESSOREQUAL;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_LessOrEqualValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tGREATEROREQUAL WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_GREATEROREQUAL;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_GreaterOrEqualValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tEQUAL WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_EQUAL;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_EqualValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
       | WholeQuantity tNOTEQUAL WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_NOTEQUAL;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_NotEqualValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tAPPROXEQUAL WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_APPROXEQUAL;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_ApproxEqualValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tAND WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_AND;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_AndValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | WholeQuantity tOR WholeQuantity
        { WholeQuantity_S.Type = WQ_BINARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_OR;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_OrValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '$' String__Index tDEF WholeQuantity
        {
          WholeQuantity_S.Type = WQ_SAVENAMEDVALUE;
          WholeQuantity_S.Case.NamedValue.Name = $2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '-' WholeQuantity %prec UNARYPREC
        { WholeQuantity_S.Type = WQ_UNARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_NEG;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_NegValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S); }
    
      | '+' WholeQuantity %prec UNARYPREC
    
      | '!' WholeQuantity
        { WholeQuantity_S.Type = WQ_UNARYOPERATOR;
          WholeQuantity_S.Case.Operator.TypeOperator = OP_NOT;
    #if defined(HAVE_KERNEL)
          WholeQuantity_S.Case.Operator.Function = (void (*)())Cal_NotValue;
    #endif
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S); }
    
      | '<' tChangeCurrentPosition '[' WholeQuantity ']' '>'
        { WholeQuantity_S.Type = WQ_CHANGECURRENTPOSITION ;
    
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S) ;
    
          WholeQuantity_P = (struct WholeQuantity*)
    	List_Pointer(Current_WholeQuantity_L, List_Nbr(Current_WholeQuantity_L)-1);
          List_Add(ListOfPointer2_L, &WholeQuantity_P);
    
          Current_WholeQuantity_L = List_Create( 5, 5, sizeof(struct WholeQuantity)) ;
          List_Add(ListOfPointer_L, &Current_WholeQuantity_L) ;
        }
        '[' WholeQuantity ']'
        {
          WholeQuantity_P =
    	*((struct WholeQuantity**)
    	  List_Pointer(ListOfPointer2_L, List_Nbr(ListOfPointer2_L)-1)) ;
          List_Pop(ListOfPointer2_L) ;
    
          WholeQuantity_P->Case.ChangeCurrentPosition.WholeQuantity =
    	*((List_T **)List_Pointer(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1)) ;
          List_Pop(ListOfPointer_L) ;
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L) ;
        }
     ;
    
    
    WholeQuantity_Single :
    
        '(' WholeQuantity ')'
    
      | OneFExpr
        { WholeQuantity_S.Type = WQ_CONSTANT;
          WholeQuantity_S.Case.Constant = $1;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | NameForFunction ArgumentsForFunction ParametersForFunction
        {
          /* Expression */
    
          int l;
          if((l = List_ISearchSeq(Problem_S.Expression, $1, fcmp_Expression_Name)) >= 0) {
    	WholeQuantity_S.Type = WQ_EXPRESSION;
    	WholeQuantity_S.Case.Expression.Index = l;
    	WholeQuantity_S.Case.Expression.NbrArguments = $2;
    	if($2 < 0)  vyyerror(0, "Uncompatible argument for Function: %s", $1);
          }
    
          /* Built in functions */
    
          else {
    	Get_Function2NbrForString(F_Function, $1, &FlagError,
    				  &WholeQuantity_S.Case.Function.Fct,
    				  &WholeQuantity_S.Case.Function.NbrParameters,
    				  &WholeQuantity_S.Case.Function.NbrArguments);
    	WholeQuantity_S.Case.Function.Active = NULL;
    	if(!FlagError) {
    
    	  /* arguments */
    	  if($2 >= 0) {
    	    if($2 == WholeQuantity_S.Case.Function.NbrArguments) {
    	      WholeQuantity_S.Type = WQ_BUILTINFUNCTION;
    	    }
    	    else if(WholeQuantity_S.Case.Function.NbrArguments == -1  ||
    		     (WholeQuantity_S.Case.Function.NbrArguments == -2)) {
    	      /* && ($2)%2 == 0)) { */
    	      WholeQuantity_S.Type = WQ_BUILTINFUNCTION;
    	      WholeQuantity_S.Case.Function.NbrArguments = $2;
    	    }
    	    else {
    	      vyyerror(0, "Wrong number of arguments for Function '%s' (%d instead of %d)",
    		       $1, $2, WholeQuantity_S.Case.Function.NbrArguments);
    	    }
    	  }
    	  else {
    	    WholeQuantity_S.Type = WQ_EXTERNBUILTINFUNCTION;
    	  }
    
    	  /* parameters */
              WholeQuantity_S.Case.Function.Para = 0;
              WholeQuantity_S.Case.Function.String = StringForParameter;
    	  if(WholeQuantity_S.Case.Function.NbrParameters >= 0 &&
    	      WholeQuantity_S.Case.Function.NbrParameters != List_Nbr($3)) {
    	    vyyerror(0, "Wrong number of parameters for Function '%s' (%d instead of %d)",
    		     $1, List_Nbr($3), WholeQuantity_S.Case.Function.NbrParameters);
    	  }
    	  else if(WholeQuantity_S.Case.Function.NbrParameters == -2 && List_Nbr($3)%2 != 0) {
    	    vyyerror(0, "Wrong number of parameters for Function '%s' (%d is not even)",
    		     $1, List_Nbr($3));
    	  }
    	  else {
    	    WholeQuantity_S.Case.Function.NbrParameters = List_Nbr($3);
    	    if(WholeQuantity_S.Case.Function.NbrParameters > 0) {
    	      WholeQuantity_S.Case.Function.Para =
    		(double *)Malloc
    		(WholeQuantity_S.Case.Function.NbrParameters * sizeof(double));
    	      for(int i = 0; i < WholeQuantity_S.Case.Function.NbrParameters; i++)
    		List_Read($3, i, &WholeQuantity_S.Case.Function.Para[i]);
    	    }
    	  }
    
    	}
    
    	else {
    	  vyyerror(0, "Unknown Function: %s", $1);
    	}
          }
    
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
          List_Delete($3);
          StringForParameter = 0;
        }
    
      | tSTRING Quantity_Def
        { WholeQuantity_S.Type = WQ_OPERATORANDQUANTITY;
          WholeQuantity_S.Case.OperatorAndQuantity.NbrArguments = 0;
          WholeQuantity_S.Case.OperatorAndQuantity.TypeQuantity =
    	Get_DefineForString(QuantityFromFS_Type, $1, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($1, QuantityFromFS_Type);
    	vyyerror(0, "Unknown type of discrete Quantity: %s", $1);
          }
          Free($1);
          WholeQuantity_S.Case.OperatorAndQuantity.TypeOperator = $2.Int1;
          WholeQuantity_S.Case.OperatorAndQuantity.Index = $2.Int2;
    
          switch(WholeQuantity_S.Case.OperatorAndQuantity.TypeQuantity) {
          case QUANTITY_DOF :
    	if(Current_DofIndexInWholeQuantity == -1)
    	  Current_DofIndexInWholeQuantity = List_Nbr(Current_WholeQuantity_L);
    	else if(Current_DofIndexInWholeQuantity == -2)
    	  vyyerror(0, "Dof{} definition out of context");
    	else
    	  vyyerror(0, "More than one Dof definition in Expression");
    	break;
          case QUANTITY_NODOF :
    	if(Current_DofIndexInWholeQuantity == -2)
    	  vyyerror(0, "NoDof definition out of context");
    	else if(Current_NoDofIndexInWholeQuantity == -1)
    	  Current_NoDofIndexInWholeQuantity = List_Nbr(Current_WholeQuantity_L);
    	else
    	  vyyerror(0, "More than one NoDof definition in Expression");
    	break;
          }
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | Quantity_Def
        { WholeQuantity_S.Type = WQ_OPERATORANDQUANTITY;
          WholeQuantity_S.Case.OperatorAndQuantity.NbrArguments = 0;
          WholeQuantity_S.Case.OperatorAndQuantity.TypeQuantity = QUANTITY_SIMPLE;
          WholeQuantity_S.Case.OperatorAndQuantity.TypeOperator = $1.Int1;
          WholeQuantity_S.Case.OperatorAndQuantity.Index = $1.Int2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | Quantity_Def ArgumentsForFunction
        {
          if($2 != 1 && $2 != 2 && $2 != 3 && $2 != 4)
    	vyyerror(0, "Wrong number of arguments for discrete quantity evaluation (%d)", $2);
          WholeQuantity_S.Type = WQ_OPERATORANDQUANTITYEVAL;
          WholeQuantity_S.Case.OperatorAndQuantity.NbrArguments = $2;
          WholeQuantity_S.Case.OperatorAndQuantity.TypeQuantity = QUANTITY_SIMPLE;
          WholeQuantity_S.Case.OperatorAndQuantity.TypeOperator = $1.Int1;
          WholeQuantity_S.Case.OperatorAndQuantity.Index = $1.Int2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | tDt
        { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' WholeQuantityExpression ']'
        { WholeQuantity_S.Type = WQ_TIMEDERIVATIVE;
          WholeQuantity_S.Case.TimeDerivative.WholeQuantity = $4;
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
    
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition out of context");
        }
    
      | tAtAnteriorTimeStep
        { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' WholeQuantityExpression ',' tINT ']'
        { WholeQuantity_S.Type = WQ_ATANTERIORTIMESTEP;
          WholeQuantity_S.Case.AtAnteriorTimeStep.WholeQuantity = $4;
          WholeQuantity_S.Case.AtAnteriorTimeStep.TimeStep = $6;
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
    
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition out of context");
        }
    
      | tMaxOverTime
        { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' WholeQuantityExpression ',' FExpr ',' FExpr ']'
        { WholeQuantity_S.Type = WQ_MAXOVERTIME;
          WholeQuantity_S.Case.MaxOverTime.WholeQuantity = $4;
          WholeQuantity_S.Case.FourierSteinmetz.TimeInit = $6;
          WholeQuantity_S.Case.FourierSteinmetz.TimeFinal = $8;
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
    
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition out of context");
        }
    
      | tFourierSteinmetz
        { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' WholeQuantityExpression ',' FExpr ',' FExpr ',' FExpr ',' FExpr ',' FExpr  ']'
        { WholeQuantity_S.Type = WQ_FOURIERSTEINMETZ;
          WholeQuantity_S.Case.FourierSteinmetz.WholeQuantity = $4;
          WholeQuantity_S.Case.FourierSteinmetz.TimeInit = $6;
          WholeQuantity_S.Case.FourierSteinmetz.TimeFinal = $8;
          WholeQuantity_S.Case.FourierSteinmetz.NbrFrequency = (int)$10;
          WholeQuantity_S.Case.FourierSteinmetz.Exponent_f = $12;
          WholeQuantity_S.Case.FourierSteinmetz.Exponent_b = $14;
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
    
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition out of context");
        }
    
      | tMHTransform
        '[' NameForFunction
         { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' RecursiveListOfWholeQuantityExpression ']' ']' '{' FExpr '}'
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Expression, $3, fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Undefined function '%s' used in MHTransform", $3);
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition cannot be used in MHTransform");
          WholeQuantity_S.Type = WQ_MHTRANSFORM;
          WholeQuantity_S.Case.MHTransform.Index = i;
          WholeQuantity_S.Case.MHTransform.WholeQuantity_L = $6;
          WholeQuantity_S.Case.MHTransform.NbrPoints = (int)$10;
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1, &Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | tMHBilinear
        '[' NameForFunction
         { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' RecursiveListOfWholeQuantityExpression ']' ']' '{' FExpr ',' FExpr '}'
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Expression, $3,fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Undefined function '%s' used in MHBilinear", $3);
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity)
    	vyyerror(0, "Dof{} definition cannot be used in MHBilinear");
          WholeQuantity_S.Type = WQ_MHBILINEAR;
          WholeQuantity_S.Case.MHBilinear.Index = i;
          WholeQuantity_S.Case.MHBilinear.WholeQuantity_L = $6;
          WholeQuantity_S.Case.MHBilinear.NbrPoints = (int)$10;
          WholeQuantity_S.Case.MHBilinear.FreqOffSet = (int)$12;
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1, &Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | tSolidAngle '[' Quantity_Def ']'
        { WholeQuantity_S.Type = WQ_SOLIDANGLE;
          WholeQuantity_S.Case.OperatorAndQuantity.Index = $3.Int2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | tOrder '[' Quantity_Def ']'
        { WholeQuantity_S.Type = WQ_ORDER;
          WholeQuantity_S.Case.OperatorAndQuantity.Index = $3.Int2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | tTrace
        { Last_DofIndexInWholeQuantity = Current_DofIndexInWholeQuantity; }
        '[' WholeQuantityExpression ',' GroupRHS ']'
        { WholeQuantity_S.Type = WQ_TRACE;
          WholeQuantity_S.Case.Trace.WholeQuantity = $4;
          WholeQuantity_S.Case.Trace.InIndex = Num_Group(&Group_S, (char*)"WQ_Trace_In", $6);
    
          if(Group_S.Type != ELEMENTLIST || Group_S.SuppListType != SUPPLIST_CONNECTEDTO)
    	vyyerror(0, "Group for Trace should be of Type 'ElementsOf[x, ConnectedTo y]'");
    
          WholeQuantity_S.Case.Trace.DofIndexInWholeQuantity = -1;
          if(Current_DofIndexInWholeQuantity != Last_DofIndexInWholeQuantity){
    	for(int i = 0; i < List_Nbr($4); i++){
    	  WholeQuantity_P = (struct WholeQuantity*)List_Pointer($4, i);
    	  if(WholeQuantity_P->Type == WQ_OPERATORANDQUANTITY)
    	    if(WholeQuantity_P->Case.OperatorAndQuantity.TypeQuantity == QUANTITY_DOF){
    	      WholeQuantity_S.Case.Trace.DofIndexInWholeQuantity = i;
    	      Current_DofIndexInWholeQuantity = -4;
    	      TypeOperatorDofInTrace = WholeQuantity_P->Case.OperatorAndQuantity.TypeOperator;
    	      DefineQuantityIndexDofInTrace = WholeQuantity_P->Case.OperatorAndQuantity.Index;
    	    }
    	}
    	if(Current_DofIndexInWholeQuantity != -4)
    	  vyyerror(0, "Dof{} definition out of context in Trace operator");
          }
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '<' tSTRING '>' '[' WholeQuantityExpression ']'
        { WholeQuantity_S.Type = WQ_CAST;
          WholeQuantity_S.Case.Cast.WholeQuantity = $5;
          int i;
          if((i = List_ISearchSeq(Formulation_S.DefineQuantity, $2,
    			       fcmp_DefineQuantity_Name)) < 0) {
    	if(!strcmp($2, "Real"))
    	  WholeQuantity_S.Case.Cast.NbrHar = 1;
    	else if(!strcmp($2, "Complex"))
    	  WholeQuantity_S.Case.Cast.NbrHar = 2;
    	else
    	  vyyerror(0, "Unknown Cast: %s", $2);
          }
          else {
    	WholeQuantity_S.Case.Cast.NbrHar = 0;
    	WholeQuantity_S.Case.Cast.FunctionSpaceIndexForType =
    	  ((struct DefineQuantity *)List_Pointer(Formulation_S.DefineQuantity, i))
    	    ->FunctionSpaceIndex;
          }
          Free($2);
    
          List_Read(ListOfPointer_L, List_Nbr(ListOfPointer_L)-1,
    		&Current_WholeQuantity_L);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '$' String__Index
        { WholeQuantity_S.Type = WQ_CURRENTVALUE;
          Get_PointerForString(Current_Value, $2, &FlagError,
    			   (void **)&WholeQuantity_S.Case.CurrentValue.Value);
          if(FlagError){
            WholeQuantity_S.Type = WQ_NAMEDVALUESAVED;
            WholeQuantity_S.Case.NamedValue.Name = $2;
          }
          else{
            Free($2);
          }
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      /* a changer */
      | '$' tTimeStep
        { WholeQuantity_S.Type = WQ_CURRENTVALUE;
          Get_PointerForString(Current_Value, "TimeStep", &FlagError,
    			   (void **)&WholeQuantity_S.Case.CurrentValue.Value);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
      | '$' tDTime
        { WholeQuantity_S.Type = WQ_CURRENTVALUE;
          Get_PointerForString(Current_Value, "DTime", &FlagError,
    			   (void **)&WholeQuantity_S.Case.CurrentValue.Value);
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '$' tINT
        { WholeQuantity_S.Type = WQ_ARGUMENT;
          WholeQuantity_S.Case.Argument.Index = $2;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | WholeQuantity_Single '#' FExpr
        {
          WholeQuantity_S.Type = WQ_SAVEVALUE;
          WholeQuantity_S.Case.SaveValue.Index = (int)$3 - 1;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | '#' FExpr
        {
          WholeQuantity_S.Type = WQ_VALUESAVED;
          WholeQuantity_S.Case.ValueSaved.Index = (int)$2 - 1;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | WholeQuantity_Single tSHOW FExpr
        {
          WholeQuantity_S.Type = WQ_SHOWVALUE;
          WholeQuantity_S.Case.ShowValue.Index = (int)$3;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S);
        }
    
      | StrCmp
        { WholeQuantity_S.Type = WQ_CONSTANT ;
          WholeQuantity_S.Case.Constant = $1 ;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S) ;
        }
    
      | NbrRegions
        { WholeQuantity_S.Type = WQ_CONSTANT ;
          WholeQuantity_S.Case.Constant = $1 ;
          List_Add(Current_WholeQuantity_L, &WholeQuantity_S) ;
        }
     ;
    
    
    ArgumentsForFunction :
    
        '[' '.' ']'                        { $$ = -1; }
      | '[' ']'                            { $$ = 0; }
      | '[' RecursiveListOfQuantity ']'    { $$ = $2; }
     ;
    
    RecursiveListOfQuantity :
    
        WholeQuantity                               { $$ = 1; }
      | RecursiveListOfQuantity ',' WholeQuantity   { $$ = $1 + 1; }
     ;
    
    ParametersForFunction :
    
        /* none */
        { $$ = NULL; }
    
      | '{' RecursiveListOfFExpr '}'
        { $$ = $2; }
    
      | '{' tRegion '[' GroupRHS ']' '}'
        { /* Attention: provisoire. Note: Impossible a mettre dans MultiFExpr
             car conflit avec Affectation dans Group */
          $$ = List_Create(2, 1, sizeof(double));
          double d = (double)Num_Group(&Group_S, (char*)"PA_Region", $4);
          List_Add($$, &d);
        }
    
      | '{' CharExprNoVar '}'
        { $$ = NULL; StringForParameter = $2; }
    
      | '{' '$' String__Index '}'
        { $$ = NULL; StringForParameter = $3; }
     ;
    
    /* ------------------------------------------------------------------------ */
    /*  J a c o b i a n   M e t h o d                                           */
    /* ------------------------------------------------------------------------ */
    
    JacobianMethods :
    
        /* none */
        { if(!Problem_S.JacobianMethod)
    	Problem_S.JacobianMethod =
    	  List_Create(5, 5, sizeof (struct JacobianMethod));
        }
    
      | JacobianMethods  BracedJacobianMethod
     ;
    
    
    BracedJacobianMethod :
    
        '{' JacobianMethod '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.JacobianMethod, index_Append, &JacobianMethod_S);
          else
            List_Add(Problem_S.JacobianMethod, &JacobianMethod_S);
        }
    
      | Loop
     ;
    
    JacobianMethod :
    
        /* none */
        {
          JacobianMethod_S.Name = NULL; JacobianMethod_S.JacobianCase = NULL;
          level_Append = 0;
        }
      | JacobianMethod  JacobianMethodTerm
      | JacobianMethod  Loop
     ;
    
    
    JacobianMethodTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("JacobianMethod", Problem_S.JacobianMethod,
                                    $2, fcmp_JacobianMethod_Name, level_Append);
          if (index_Append<0)
            JacobianMethod_S.Name = $2;
          else{
            List_Read(Problem_S.JacobianMethod, index_Append, &JacobianMethod_S);
            Free($2);
          }
        }
    
      | tCase '{' JacobianCases '}'
        { JacobianMethod_S.JacobianCase = $3; }
     ;
    
    
    JacobianCases :
    
        /* none */
        {
          $$ = JacobianMethod_S.JacobianCase?
            JacobianMethod_S.JacobianCase :
            List_Create(5, 5, sizeof (struct JacobianCase));
        }
      | JacobianCases  '{' JacobianCase '}'
        { List_Add($$ = $1, &JacobianCase_S); }
      | JacobianCases  Loop
     ;
    
    
    JacobianCase :
    
        /* none */
        { JacobianCase_S.RegionIndex = -1;
          JacobianCase_S.TypeJacobian = JACOBIAN_VOL;
          JacobianCase_S.CoefficientIndex = -1; }
    
      | JacobianCase JacobianCaseTerm
     ;
    
    
    JacobianCaseTerm :
    
        tRegion GroupRHS tEND
        {
          if ($2 >=0)
            JacobianCase_S.RegionIndex = Num_Group(&Group_S, (char*)"JA_Region", $2);
          else if ($2 == -3)
            JacobianCase_S.RegionIndex = -1;
        }
    
      | tJacobian String__Index ParametersForFunction tEND
        { JacobianCase_S.TypeJacobian =
    	Get_Define1NbrForString(Jacobian_Type, $2, &FlagError,
    				&JacobianCase_S.NbrParameters);
          if(!FlagError) {
    	if(JacobianCase_S.NbrParameters == -2 && (List_Nbr($3))%2 != 0)
    	  vyyerror(0, "Wrong number of parameters for Jacobian '%s' (%d is not even)",
    		   $2, List_Nbr($3));
    	if(JacobianCase_S.NbrParameters < 0)
    	  JacobianCase_S.NbrParameters = List_Nbr($3);
    	if(List_Nbr($3) == JacobianCase_S.NbrParameters) {
    	  if(JacobianCase_S.NbrParameters) {
    	    JacobianCase_S.Para =
    	      (double *)Malloc(JacobianCase_S.NbrParameters * sizeof(double));
    	    for(int i = 0; i < JacobianCase_S.NbrParameters; i++)
    	      List_Read($3, i, &JacobianCase_S.Para[i]);
    	  }
    	}
    	else
    	  vyyerror(0, "Wrong number of parameters for Jacobian '%s' (%d instead of %d)",
    		   $2, List_Nbr($3), JacobianCase_S.NbrParameters);
          }
          else{
    	Get_Valid_SXD1N($2, Jacobian_Type);
    	vyyerror(0, "Unknown type of Jacobian: %s", $2);
          }
          Free($2);
          List_Delete($3);
        }
    
      | tCoefficient Expression tEND
        { JacobianCase_S.CoefficientIndex = $2; }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  I n t e g r a t i o n   M e t h o d                                     */
    /* ------------------------------------------------------------------------ */
    
    IntegrationMethods :
    
        /* none */
        { if(!Problem_S.IntegrationMethod)
    	Problem_S.IntegrationMethod =
    	  List_Create(5, 5, sizeof(struct IntegrationMethod));
        }
    
      | IntegrationMethods  BracedIntegrationMethod
     ;
    
    BracedIntegrationMethod :
    
        '{' IntegrationMethod '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.IntegrationMethod, index_Append, &IntegrationMethod_S);
          else
            List_Add(Problem_S.IntegrationMethod, &IntegrationMethod_S);
        }
    
      | Loop
     ;
    
    IntegrationMethod :
    
        /* none */
        {
          IntegrationMethod_S.Name = NULL;
          IntegrationMethod_S.IntegrationCase = NULL;
          IntegrationMethod_S.CriterionIndex = -1;
          level_Append = 0;
        }
    
      | IntegrationMethod  IntegrationMethodTerm
      | IntegrationMethod  Loop
     ;
    
    
    IntegrationMethodTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("IntegrationMethod", Problem_S.IntegrationMethod,
                                    $2, fcmp_IntegrationMethod_Name, level_Append);
          if (index_Append<0)
            IntegrationMethod_S.Name = $2;
          else{
            List_Read(Problem_S.IntegrationMethod, index_Append, &IntegrationMethod_S);
            Free($2);
          }
        }
    
      | tCriterion Expression tEND
        { IntegrationMethod_S.CriterionIndex = $2;  }
    
      | tCase '{' IntegrationCases '}'
        { IntegrationMethod_S.IntegrationCase = $3; }
     ;
    
    
    IntegrationCases :
    
        /* none */
        { $$ = IntegrationMethod_S.IntegrationCase?
            IntegrationMethod_S.IntegrationCase :
            List_Create(5, 5, sizeof (struct IntegrationCase));
        }
    
      | IntegrationCases '{' IntegrationCase '}'
        { List_Add($$ = $1, &IntegrationCase_S); }
      | IntegrationCases Loop
     ;
    
    
    IntegrationCase :
    
        /* none */
        {
          IntegrationCase_S.Type = GAUSS;
          IntegrationCase_S.SubType = STANDARD;
        }
    
      | IntegrationCase IntegrationCaseTerm
     ;
    
    
    IntegrationCaseTerm :
    
        tType tSTRING tEND
        { IntegrationCase_S.Type =
    	Get_DefineForString(Integration_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Integration_Type);
    	vyyerror(0, "Unknown type of Integration method: %s", $2);
          }
          Free($2);
        }
    
      | tSubType tSTRING tEND
        { IntegrationCase_S.SubType =
    	Get_DefineForString(Integration_SubType, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Integration_Type);
    	vyyerror(0, "Unknown subtype of Integration method: %s", $2);
          }
          Free($2);
        }
    
      | tCase '{' QuadratureCases '}'
        { IntegrationCase_S.Case = $3; }
     ;
    
    
    QuadratureCases :
    
        /* none */
        { $$ = List_Create(5, 5, sizeof (struct Quadrature)); }
    
      | QuadratureCases  '{' QuadratureCase '}'
        { List_Add($$ = $1, &QuadratureCase_S); }
     ;
    
    
    QuadratureCase :
    
        /* none */
        { QuadratureCase_S.ElementType = TRIANGLE;
          QuadratureCase_S.NumberOfPoints = 4;
          QuadratureCase_S.MaxNumberOfPoints = 4;
          QuadratureCase_S.NumberOfDivisions = 1;
          QuadratureCase_S.MaxNumberOfDivisions = 1;
          QuadratureCase_S.StoppingCriterion = 1.E-4;
          QuadratureCase_S.Function = 0; //FIXME(void (*)())Gauss_Triangle;
        }
    
      | QuadratureCase QuadratureCaseTerm
     ;
    
    
    QuadratureCaseTerm :
    
        tGeoElement tSTRING tEND
        { QuadratureCase_S.ElementType = Get_DefineForString(Element_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Element_Type);
    	vyyerror(0, "Unknown type of Element: %s", $2);
          }
    
          switch(IntegrationCase_S.SubType) {
    
          case STANDARD :
    	switch (IntegrationCase_S.Type) {
    	case GAUSS :
    	  Get_FunctionForDefine
    	    (FunctionForGauss, QuadratureCase_S.ElementType,
    	     &FlagError, (void (**)())&QuadratureCase_S.Function);
    	  break;
    	case GAUSSLEGENDRE :
    	  Get_FunctionForDefine
    	    (FunctionForGaussLegendre, QuadratureCase_S.ElementType,
    	     &FlagError, (void (**)())&QuadratureCase_S.Function);
    	  break;
    	default :
    	  vyyerror(0, "Incompatible type of Integration method");
    	  break;
    	}
    	break;
    
          case SINGULAR :
    	switch (IntegrationCase_S.Type) {
    	case GAUSS :
    	  Get_FunctionForDefine
    	    (FunctionForSingularGauss, QuadratureCase_S.ElementType,
    	     &FlagError, (void (**)())&QuadratureCase_S.Function);
    	  break;
    	default :
    	  vyyerror(0, "Incompatible type of Integration method");
    	  break;
    	}
    	break;
          default :
    	vyyerror(0, "Incompatible type of Integration method");
    	break;
          }
    
          if(FlagError)  vyyerror(0, "Bad type of Integration method for Element: %s", $2);
          Free($2);
        }
    
      | tNumberOfPoints FExpr tEND
        { QuadratureCase_S.NumberOfPoints = (int)$2; }
    
      | tMaxNumberOfPoints FExpr tEND
        { QuadratureCase_S.MaxNumberOfPoints = (int)$2; }
    
      | tNumberOfDivisions FExpr tEND
        { QuadratureCase_S.NumberOfDivisions = (int)$2; }
    
      | tMaxNumberOfDivisions FExpr tEND
        { QuadratureCase_S.MaxNumberOfDivisions = (int)$2; }
    
      | tStoppingCriterion FExpr tEND
        { QuadratureCase_S.StoppingCriterion = $2; }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  C o n s t r a i n t                                                     */
    /* ------------------------------------------------------------------------ */
    
    Constraints :
    
        /* none */
        { if(!Problem_S.Constraint)
    	Problem_S.Constraint = List_Create(20, 20, sizeof (struct Constraint));
        }
    
      | Constraints BracedConstraint
     ;
    
    BracedConstraint :
    
        '{' Constraint '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.Constraint, index_Append, &Constraint_S);
          else
            List_Add(Problem_S.Constraint, &Constraint_S);
        }
    
      | Loop
     ;
    
    Constraint :
    
        /* none */
        { Constraint_S.Name = NULL;
          Constraint_S.Type = ASSIGN;
          Constraint_S.ConstraintPerRegion = NULL;
          Constraint_S.MultiConstraintPerRegion = NULL;
          level_Append = 0;
        }
    
      | Constraint  ConstraintTerm
     ;
    
    
    ConstraintTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("Constraint", Problem_S.Constraint,
                                    $2, fcmp_Constraint_Name, level_Append);
          if (index_Append<0)
            Constraint_S.Name = $2;
          else{
            List_Read(Problem_S.Constraint, index_Append, &Constraint_S);
            Free($2);
          }
        }
    
      | tType tSTRING tEND
        { Constraint_S.Type = Get_DefineForString(Constraint_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Constraint_Type);
    	vyyerror(0, "Unknown type of Constraint: %s", $2);
          }
          Free($2);
        }
    
      | tCase '{' ConstraintCases '}'
        {
          if (Constraint_S.Type == NETWORK)
            vyyerror(0, "Unnamed Case incompatible with Network Type");
          Constraint_S.ConstraintPerRegion = $3;
        }
    
      | tCase tSTRING '{' ConstraintCases '}'
        {
          if (Constraint_S.Type != NETWORK)
            vyyerror(0, "Named Case incompatible with Type (only with Network type)");
    
          if(!Constraint_S.MultiConstraintPerRegion)
    	Constraint_S.MultiConstraintPerRegion =
    	  List_Create(5, 5, sizeof(struct MultiConstraintPerRegion));
    
          MultiConstraintPerRegion_S.Name = $2;
          MultiConstraintPerRegion_S.ConstraintPerRegion = $4;
          MultiConstraintPerRegion_S.Active = NULL;
    
          List_Add(Constraint_S.MultiConstraintPerRegion,
    	       &MultiConstraintPerRegion_S);
        }
    
       | ConstraintTerm Loop
    ;
    
    
    ConstraintCases :
    
        /* none */
        {
          $$ = (Constraint_S.Type != NETWORK && Constraint_S.ConstraintPerRegion)?
            Constraint_S.ConstraintPerRegion :
            List_Create(6, 6, sizeof (struct ConstraintPerRegion));
        }
    
      | ConstraintCases  '{' ConstraintCase '}'
        {
          List_Add($$ = $1, &ConstraintPerRegion_S);
        }
    
      | ConstraintCases Loop
        {
          $$ = $1;
        }
     ;
    
    
    ConstraintCase :
    
        /* none */
        {
          ConstraintPerRegion_S.Type = Constraint_S.Type;
          ConstraintPerRegion_S.RegionIndex = -1;
          ConstraintPerRegion_S.SubRegionIndex = -1;
          ConstraintPerRegion_S.SubRegion2Index = -1;
          ConstraintPerRegion_S.TimeFunctionIndex = -1;
        }
    
      | ConstraintCase ConstraintCaseTerm
     ;
    
    
    ConstraintCaseTerm :
    
        tType tSTRING tEND
        { ConstraintPerRegion_S.Type =
    	Get_DefineForString(Constraint_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Constraint_Type);
    	vyyerror(0, "Unknown type of Constraint: %s", $2);
          }
          Free($2);
        }
    
      | tRegion GroupRHS tEND
        {
          ConstraintPerRegion_S.RegionIndex = Num_Group(&Group_S, (char*)"CO_Region", $2);
        }
    
      | tSubRegion GroupRHS tEND
        {
          ConstraintPerRegion_S.SubRegionIndex =
    	Num_Group(&Group_S, (char*)"CO_SubRegion", $2);
        }
    
      | tSubRegion2 GroupRHS tEND
        {
          ConstraintPerRegion_S.SubRegion2Index =
    	Num_Group(&Group_S, (char*)"CO_SubRegion2", $2);
        }
    
      | tTimeFunction Expression tEND
        {
          ConstraintPerRegion_S.TimeFunctionIndex = $2;
          if(Is_ExpressionPieceWiseDefined($2))
            vyyerror(0, "TimeFunction should never be piece-wise defined");
        }
    
      | tValue Expression tEND
        {
          if(ConstraintPerRegion_S.Type == ASSIGN ||
             ConstraintPerRegion_S.Type == INIT){
    	ConstraintPerRegion_S.Case.Fixed.ExpressionIndex = $2;
    	ConstraintPerRegion_S.Case.Fixed.ExpressionIndex2 = -1;
          }
          else  vyyerror(0, "Value incompatible with Type");
        }
    
      | tValue '[' Expression ',' Expression ']' tEND
        {
          if(ConstraintPerRegion_S.Type == ASSIGN ||
             ConstraintPerRegion_S.Type == INIT){
    	ConstraintPerRegion_S.Case.Fixed.ExpressionIndex = $5;
            ConstraintPerRegion_S.Case.Fixed.ExpressionIndex2 = $3;
          }
          else  vyyerror(0, "Value incompatible with Type");
        }
    
      | tNameOfResolution String__Index tEND
        {
          if(ConstraintPerRegion_S.Type == ASSIGNFROMRESOLUTION ||
    	  ConstraintPerRegion_S.Type == INITFROMRESOLUTION)
    	ConstraintPerRegion_S.Case.Solve.ResolutionName = $2;
          else  vyyerror(0, "NameOfResolution incompatible with Type");
        }
    
      | tBranch '{' OneFExpr Comma OneFExpr '}' tEND
        {
          if(ConstraintPerRegion_S.Type == NETWORK) {
    	ConstraintPerRegion_S.Case.Network.Node1 = (int)$3;
    	ConstraintPerRegion_S.Case.Network.Node2 = (int)$5;
          }
          else  vyyerror(0, "Branch incompatible with Type");
        }
    
      | tBranch '{' '(' FExpr ')' Comma '(' FExpr ')' '}' tEND
        {
          if(ConstraintPerRegion_S.Type == NETWORK) {
    	ConstraintPerRegion_S.Case.Network.Node1 = (int)$4;
    	ConstraintPerRegion_S.Case.Network.Node2 = (int)$8;
          }
          else  vyyerror(0, "Branch incompatible with Type");
        }
    
      | tRegionRef GroupRHS tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.RegionRefIndex =
    	  Num_Group(&Group_S, (char*)"CO_RegionRef", $2);
    	ConstraintPerRegion_S.Case.Link.SubRegionRefIndex = -1;
    
    	ConstraintPerRegion_S.Case.Link.FilterIndex = -1;
    	ConstraintPerRegion_S.Case.Link.FunctionIndex = -1;
    	ConstraintPerRegion_S.Case.Link.CoefIndex = -1;
    	ConstraintPerRegion_S.Case.Link.FilterIndex2 = -1;
    	ConstraintPerRegion_S.Case.Link.FunctionIndex2 = -1;
    	ConstraintPerRegion_S.Case.Link.CoefIndex2 = -1;
    	ConstraintPerRegion_S.Case.Link.ToleranceFactor = 1.e-8;
          }
          else  vyyerror(0, "RegionRef incompatible with Type");
        }
    
      | tSubRegionRef GroupRHS tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX)
    	ConstraintPerRegion_S.Case.Link.SubRegionRefIndex =
    	  Num_Group(&Group_S, (char*)"CO_RegionRef", $2);
          else  vyyerror(0, "SubRegionRef incompatible with Type");
        }
    
      | tFunction Expression tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX)
    	ConstraintPerRegion_S.Case.Link.FunctionIndex = $2;
          else  vyyerror(0, "Function incompatible with Type");
        }
    
      | tCoefficient Expression tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX)
    	ConstraintPerRegion_S.Case.Link.CoefIndex = $2;
          else  vyyerror(0, "Coefficient incompatible with Type");
        }
    
      | tFilter Expression tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.FilterIndex  = $2;
    	ConstraintPerRegion_S.Case.Link.FilterIndex2 = -1;
          }
          else  vyyerror(0, "Filter incompatible with Type");
        }
    
      | tFunction '[' Expression ',' Expression ']' tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.FunctionIndex  = $3;
    	ConstraintPerRegion_S.Case.Link.FunctionIndex2 = $5;
          }
          else  vyyerror(0, "Function incompatible with Type");
        }
    
      | tToleranceFactor FExpr tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.ToleranceFactor  = $2;
          }
          else  vyyerror(0, "ToleranceFactor incompatible with Type");
        }
    
      | tCoefficient '[' Expression ',' Expression ']' tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.CoefIndex  = $3;
    	ConstraintPerRegion_S.Case.Link.CoefIndex2 = $5;
          }
          else  vyyerror(0, "Coefficient incompatible with Type");
        }
    
      | tFilter '[' Expression ',' Expression ']' tEND
        {
          if(ConstraintPerRegion_S.Type == CST_LINK ||
    	  ConstraintPerRegion_S.Type == CST_LINKCPLX) {
    	ConstraintPerRegion_S.Case.Link.FilterIndex  = $3;
    	ConstraintPerRegion_S.Case.Link.FilterIndex2 = $5;
          }
          else  vyyerror(0, "Filter incompatible with Type");
        }
    
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  F u n c t i o n   S p a c e                                             */
    /* ------------------------------------------------------------------------ */
    
    
    FunctionSpaces :
    
        /* none */
        { if(!Problem_S.FunctionSpace)
    	Problem_S.FunctionSpace =
    	  List_Create(10, 5, sizeof (struct FunctionSpace));
        }
    
      | FunctionSpaces  BracedFunctionSpace
     ;
    
    BracedFunctionSpace :
    
        '{' FunctionSpace '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.FunctionSpace, index_Append, &FunctionSpace_S);
          else
            List_Add(Problem_S.FunctionSpace, &FunctionSpace_S);
        }
    
      | Loop
     ;
    
    
    FunctionSpace :
    
        /* none */
        { FunctionSpace_S.Name = NULL; FunctionSpace_S.Type = FORM0;
          FunctionSpace_S.BasisFunction = FunctionSpace_S.SubSpace =
    	FunctionSpace_S.GlobalQuantity = FunctionSpace_S.Constraint = NULL;
          level_Append = 0;
        }
    
      | FunctionSpace  FunctionSpaceTerm
    
      | FunctionSpace  Loop
     ;
    
    
    FunctionSpaceTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("FunctionSpace", Problem_S.FunctionSpace,
                                    $2, fcmp_FunctionSpace_Name, level_Append);
          if (index_Append<0)
            FunctionSpace_S.Name = $2;
          else{
            List_Read(Problem_S.FunctionSpace, index_Append, &FunctionSpace_S);
            Free($2);
          }
        }
    
      | tType tSTRING tEND
        { FunctionSpace_S.Type = Get_DefineForString(Field_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Field_Type);
    	vyyerror(0, "Unknown type of FunctionSpace: %s", $2);
          }
          Free($2);
        }
    
      | tBasisFunction  '{' BasisFunctions '}'
    
      | tSubSpace       '{' SubSpaces '}'
    
      | tGlobalQuantity '{' GlobalQuantities '}'
    
      | tConstraint     '{' ConstraintInFSs '}'
     ;
    
    
    BasisFunctions :
    
        /* none */
        {
          if (!FunctionSpace_S.BasisFunction)
            FunctionSpace_S.BasisFunction =
              List_Create(6, 6, sizeof (struct BasisFunction));
          Current_BasisFunction_L = FunctionSpace_S.BasisFunction;
        }
    
      | BasisFunctions  '{' BasisFunction '}'
        {
          /*
          int i;
          if((i = List_ISearchSeq(FunctionSpace_S.BasisFunction, BasisFunction_S.Name,
                                  fcmp_BasisFunction_Name)) < 0) {
          */
          if(index_Append_2 < 0) {
    	BasisFunction_S.Num = Num_BasisFunction;
    	Num_BasisFunction += (BasisFunction_S.SubFunction)?
    	  List_Nbr(BasisFunction_S.SubFunction) : 1;
          }
          else
            if(!level_Append_2){
              // Region-wise BasisFunction => same Num
              BasisFunction_S.Num =
                ((struct BasisFunction *)
                 List_Pointer(FunctionSpace_S.BasisFunction, index_Append_2))->Num;
            }
    
          if (level_Append_2 && index_Append_2>=0)
            List_Write(FunctionSpace_S.BasisFunction, index_Append_2, &BasisFunction_S);
          else
            List_Add(FunctionSpace_S.BasisFunction, &BasisFunction_S);
        }
    
      | BasisFunctions  Loop
     ;
    
    
    BasisFunction :
    
        /* none */
        {
          BasisFunction_S.Name = NULL;
          BasisFunction_S.NameOfCoef = NULL;
          BasisFunction_S.Num = 0;
          BasisFunction_S.GlobalBasisFunction = NULL;
          BasisFunction_S.Function = NULL;
          BasisFunction_S.dFunction = NULL;
          BasisFunction_S.dInvFunction = NULL;
          BasisFunction_S.dPlusFunction = NULL;
          BasisFunction_S.SubFunction = NULL;
          BasisFunction_S.SubdFunction = NULL;
          BasisFunction_S.SupportIndex = -1;
          BasisFunction_S.EntityIndex  = -1;
          level_Append_2 = (level_Append)? level_Append-1 : 0;
          index_Append_2 = -1;
        }
    
      | BasisFunction  BasisFunctionTerm
     ;
    
    
    BasisFunctionTerm :
    
        Append tEND
        {
          level_Append_2 = $1; index_Append_2 = -1;
        }
    
      | tName String__Index tEND
        {
          index_Append_2 =
            Check_NameOfStructExist("BasisFunction", FunctionSpace_S.BasisFunction,
                                    $2, fcmp_BasisFunction_Name, 1);
          // 1: already defined Name always possible for Region-wise basis functions
          if (index_Append_2<0 || !level_Append_2)
            BasisFunction_S.Name = $2;
          else{
            List_Read(FunctionSpace_S.BasisFunction, index_Append_2, &BasisFunction_S);
            Free($2);
          }
        }
    
      | tNameOfCoef String__Index tEND
        {
          Check_NameOfStructExist("NameOfCoef", Current_BasisFunction_L,
                                  $2, fcmp_BasisFunction_NameOfCoef, 0);
          BasisFunction_S.NameOfCoef = $2; BasisFunction_S.Dimension = 1;
        }
    
      | tFunction tSTRING OptionalParametersForBasisFunction tEND
        {
          Get_3Function3NbrForString
    	(BF_Function, $2, &FlagError,
    	 &BasisFunction_S.Function, &BasisFunction_S.dFunction,
    	 &BasisFunction_S.dInvFunction, &BasisFunction_S.Order,
    	 &BasisFunction_S.ElementType, &BasisFunction_S.Orient);
          if(FlagError){
    	Get_Valid_SX3F3N($2, BF_Function);
    	vyyerror(0, "Unknown Function for BasisFunction: %s", $2);
          }
          Free($2);
        }
    
      | tdFunction '{' tSTRING Comma tSTRING '}' tEND
        {
          void  (*FunctionDummy)();
          int i, j;
          double d;
          Get_3Function3NbrForString
    	(BF_Function, $3, &FlagError,
    	 &BasisFunction_S.dFunction, &FunctionDummy, &FunctionDummy, &d, &i, &j);
          if(FlagError){
    	Get_Valid_SX3F3N($3, BF_Function);
    	vyyerror(0, "Unknown dFunction (1) for BasisFunction: %s", $3);
          }
          Free($3);
          Get_3Function3NbrForString
    	(BF_Function, $5, &FlagError,
    	 &BasisFunction_S.dInvFunction, &FunctionDummy, &FunctionDummy, &d, &i, &j);
          if(FlagError){
    	Get_Valid_SX3F3N($5, BF_Function);
    	vyyerror(0, "Unknown dFunction (2) for BasisFunction: %s", $5);
          }
          Free($5);
        }
    
      | tdFunction '{' tSTRING Comma tSTRING Comma tSTRING '}' tEND
        {
          void  (*FunctionDummy)();
          int i, j;
          double d;
          Get_3Function3NbrForString
    	(BF_Function, $3, &FlagError,
    	 &BasisFunction_S.dFunction, &FunctionDummy, &FunctionDummy, &d, &i, &j);
          if(FlagError){
    	Get_Valid_SX3F3N($3, BF_Function);
    	vyyerror(0, "Unknown dFunction (1) for BasisFunction: %s", $3);
          }
          Free($3);
          Get_3Function3NbrForString
    	(BF_Function, $5, &FlagError,
    	 &BasisFunction_S.dInvFunction, &FunctionDummy, &FunctionDummy, &d, &i, &j);
          if(FlagError){
    	Get_Valid_SX3F3N($5, BF_Function);
    	vyyerror(0, "Unknown dFunction (2) for BasisFunction: %s", $5);
          }
          Free($5);
          Get_3Function3NbrForString
    	(BF_Function, $7, &FlagError,
    	 &BasisFunction_S.dPlusFunction, &FunctionDummy, &FunctionDummy, &d, &i, &j);
          if(FlagError){
    	Get_Valid_SX3F3N($7, BF_Function);
    	vyyerror(0, "Unknown dFunction (3) for BasisFunction: %s", $7);
          }
          Free($7);
        }
    
      | tSubFunction ListOfExpression tEND
        {
          BasisFunction_S.SubFunction = List_Copy(ListOfInt_L);
        }
    
      | tSubdFunction ListOfExpression tEND
        {
          BasisFunction_S.SubdFunction = List_Copy(ListOfInt_L);
        }
    
      | tSupport GroupRHS tEND
        {
          BasisFunction_S.SupportIndex = Num_Group(&Group_S, (char*)"BF_Support", $2);
        }
    
      | tEntity GroupRHS tEND
        {
          BasisFunction_S.EntityIndex = Num_Group(&Group_S, (char*)"BF_Entity", $2);
          if(Group_S.InitialList)
    	List_Sort(Group_S.InitialList, fcmp_Integer);  /* Needed for Global Region */
    
          if(BasisFunction_S.GlobalBasisFunction) { /* Function to be defined before Entity */
    	if(Group_S.FunctionType == GLOBAL) {
    	  if(List_Nbr(BasisFunction_S.GlobalBasisFunction) ==
    	      List_Nbr(Group_S.InitialList)) {
    	    for(int k = 0; k < List_Nbr(Group_S.InitialList); k++)
    	      if(*((int*)List_Pointer(Group_S.InitialList, k)) !=
    		  *((int*)List_Pointer(BasisFunction_S.GlobalBasisFunction, k))) {
    		vyyerror(0, "Bad correspondance between Group and Entity (elements differ)");
    		break;
    	      }
    	  }
    	  else if(List_Nbr(Group_S.InitialList) != 0 ||
    		   GlobalBasisFunction_S.EntityIndex != -1)
    	    vyyerror(0, "Bad correspondance between Group and Entity (#BF %d, #Global %d)",
    		     List_Nbr(BasisFunction_S.GlobalBasisFunction),
    		     List_Nbr(Group_S.InitialList));
    	}
    	else  vyyerror(0, "Bad correspondance between Group and Entity (Entity must be Global)");
          }
        }
     ;
    
    
    OptionalParametersForBasisFunction :
    
        /* none */
    
      | '{' tQuantity tSTRING tEND
            tFormulation String__Index '{' FExpr '}' tEND
            tGroup GroupRHS tEND
            tResolution String__Index '{' FExpr '}' tEND '}'
        {
          int dim = $8;
          if(dim != $17)
            vyyerror(0, "Number of formulations different from number of resolutions");
          if(List_Nbr(Group_S.InitialList) != dim)
            vyyerror(0, "Group sould have %d single regions", dim);
    
          BasisFunction_S.GlobalBasisFunction =
    	List_Create(dim, 1, sizeof(struct GlobalBasisFunction));
    
          for(int k = 0; k < dim; k++) {
            int i;
            List_Read(Group_S.InitialList, k, &i);
            GlobalBasisFunction_S.EntityIndex = i;
    
    	char tmpstr[256];
    	sprintf(tmpstr, "%s_%d", $6, k+1);
    	if((i = List_ISearchSeq(Problem_S.Formulation, tmpstr,
    				 fcmp_Formulation_Name)) >= 0) {
    	  GlobalBasisFunction_S.FormulationIndex = i;
    	  List_Read(Problem_S.Formulation, i, &Formulation_S);
    	  if((i = List_ISearchSeq(Formulation_S.DefineQuantity, $3,
    				   fcmp_DefineQuantity_Name)) >= 0)
    	    GlobalBasisFunction_S.DefineQuantityIndex = i;
    	  else {
    	    vyyerror(0, "Unknown Quantity '%s' in Formulation '%s'", $3,
    		     Formulation_S.Name);
    	    break;
    	  }
    	}
    	else
    	  vyyerror(0, "Unknown Formulation: %s", tmpstr);
    
    	sprintf(tmpstr, "%s_%d", $15, k+1);
    	if((i = List_ISearchSeq(Problem_S.Resolution, tmpstr,
                                    fcmp_Resolution_Name)) >= 0)
    	  GlobalBasisFunction_S.ResolutionIndex = i;
    	else
    	  vyyerror(0, "Unknown Resolution: %s", tmpstr);
    
    	GlobalBasisFunction_S.QuantityStorage = NULL;
    	List_Add(BasisFunction_S.GlobalBasisFunction, &GlobalBasisFunction_S);
          }
          List_Sort(BasisFunction_S.GlobalBasisFunction, fcmp_Integer);
    
          Free($3); Free($6); Free($15);
        }
     ;
    
    
    SubSpaces :
    
        /* none */
        {
          if (!FunctionSpace_S.SubSpace)
            FunctionSpace_S.SubSpace =
              List_Create(6, 6, sizeof (struct SubSpace));
        }
    
      | SubSpaces  '{' SubSpace '}'
        {
          if (level_Append_2 && index_Append_2>=0)
            List_Write(FunctionSpace_S.SubSpace, index_Append_2, &SubSpace_S);
          else
            List_Add(FunctionSpace_S.SubSpace, &SubSpace_S);
        }
    
      | SubSpaces  Loop
     ;
    
    
    SubSpace :
    
        /* none */
        {
          SubSpace_S.Name = NULL; SubSpace_S.BasisFunction  = NULL;
          level_Append_2 = (level_Append)? level_Append-1 : 0;
          index_Append_2 = -1;
        }
    
      | SubSpace  SubSpaceTerm
     ;
    
    
    SubSpaceTerm :
    
        Append tEND
        {
          level_Append_2 = $1; index_Append_2 = -1;
        }
    
      | tName tSTRING tEND
        {
          index_Append_2 =
            Check_NameOfStructExist("SubSpace", FunctionSpace_S.SubSpace,
                                    $2, fcmp_SubSpace_Name, level_Append_2);
          if (index_Append_2<0)
            SubSpace_S.Name = $2;
          else{
            List_Read(FunctionSpace_S.SubSpace, index_Append_2, &SubSpace_S);
            Free($2);
          }
        }
    
      | tNameOfBasisFunction ListOfBasisFunction tEND
        { SubSpace_S.BasisFunction = $2; }
    
      | tNameOfCoef ListOfBasisFunctionCoef tEND
        { SubSpace_S.BasisFunction = $2; }
     ;
    
    
    ListOfBasisFunction :
    
        tSTRING
        {
          $$ = SubSpace_S.BasisFunction?
            SubSpace_S.BasisFunction : List_Create(1, 5, sizeof(int));
          int i;
          if((i = List_ISearchSeq(Current_BasisFunction_L,
    			       $1, fcmp_BasisFunction_Name)) < 0)
    	vyyerror(0, "Unknown BasisFunction: %s", $1);
          else {
    	List_Add($$, &i);
    	int j = i+1;
    	while((i = List_ISearchSeqPartial(Current_BasisFunction_L,
    					  $1, j, fcmp_BasisFunction_Name)) >= 0) {
    	  List_Add($$, &i); j = i+1;  /* for piecewise defined basis functions */
    	}
          }
          Free($1);
        }
    
      | '{' RecursiveListOfBasisFunction '}'
        { $$ = $2; }
     ;
    
    
    RecursiveListOfBasisFunction :
    
        /* none */
        {
          $$ = SubSpace_S.BasisFunction?
            SubSpace_S.BasisFunction : List_Create(5, 5, sizeof(int));
        }
    
      | RecursiveListOfBasisFunction Comma tSTRING
        {
          int i;
          if((i = List_ISearchSeq(Current_BasisFunction_L,
                                  $3, fcmp_BasisFunction_Name)) < 0)
    	vyyerror(0, "Unknown BasisFunction: %s", $3);
          else {
    	List_Add($1, &i);
    	int j = i+1;
    	while((i = List_ISearchSeqPartial(Current_BasisFunction_L,
    					  $3, j, fcmp_BasisFunction_Name)) >= 0) {
    	  List_Add($1, &i); j = i+1;  /* for piecewise defined basis functions */
    	}
          }
          $$ = $1; Free($3);
        }
     ;
    
    
    ListOfBasisFunctionCoef :
    
        tSTRING
        {
          $$ = SubSpace_S.BasisFunction?
            SubSpace_S.BasisFunction : List_Create(1, 5, sizeof(int));
          int i;
          if((i = List_ISearchSeq(Current_BasisFunction_L,
    			       $1, fcmp_BasisFunction_NameOfCoef)) < 0)
    	vyyerror(0, "Unknown BasisFunctionCoef: %s", $1);
          else {
    	List_Add($$, &i);
          }
          Free($1);
        }
    
      | '{' RecursiveListOfBasisFunctionCoef '}'
        { $$ = $2; }
     ;
    
    
    RecursiveListOfBasisFunctionCoef :
    
        /* none */
        {
          $$ = SubSpace_S.BasisFunction?
            SubSpace_S.BasisFunction : List_Create(5, 5, sizeof(int));
        }
    
      | RecursiveListOfBasisFunctionCoef Comma tSTRING
        {
          int i;
          if((i = List_ISearchSeq(Current_BasisFunction_L,
    			       $3, fcmp_BasisFunction_NameOfCoef)) < 0)
    	vyyerror(0, "Unknown BasisFunctionCoef: %s", $3);
          else {
    	List_Add($1, &i);
          }
          $$ = $1; Free($3);
        }
     ;
    
    
    GlobalQuantities :
    
        /* none */
        {
          if (!FunctionSpace_S.GlobalQuantity)
            FunctionSpace_S.GlobalQuantity =
              List_Create(6, 6, sizeof (struct GlobalQuantity));
        }
    
      | GlobalQuantities  '{' GlobalQuantity '}'
        {
          GlobalQuantity_S.Num = Num_BasisFunction++;
          List_Add(FunctionSpace_S.GlobalQuantity, &GlobalQuantity_S);
        }
    
      | GlobalQuantities  Loop
     ;
    
    
    GlobalQuantity :
    
        /* none */
        {
          GlobalQuantity_S.Name = NULL; GlobalQuantity_S.Num  = 0;
          GlobalQuantity_S.Type = ALIASOF; GlobalQuantity_S.ReferenceIndex = -1;
        }
    
      | GlobalQuantity  GlobalQuantityTerm
     ;
    
    
    GlobalQuantityTerm :
    
        tName String__Index tEND
        {
          Check_NameOfStructExist("GlobalQuantity", FunctionSpace_S.GlobalQuantity,
                                  $2, fcmp_GlobalQuantity_Name, 0);
          GlobalQuantity_S.Name = $2;
        }
    
      | tType tSTRING tEND
        {
          GlobalQuantity_S.Type =
    	Get_DefineForString(GlobalQuantity_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, GlobalQuantity_Type);
    	vyyerror(0, "Unknown type of GlobalQuantity: %s", $2);
          }
          Free($2);
        }
    
      | tNameOfCoef String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(FunctionSpace_S.BasisFunction, $2,
    			       fcmp_BasisFunction_NameOfCoef)) < 0)
    	vyyerror(0, "Unknown NameOfCoef: %s", $2);
          else
    	GlobalQuantity_S.ReferenceIndex = i;
          Free($2);
        }
     ;
    
    
    ConstraintInFSs :
    
        /* none */
        {
          if (!FunctionSpace_S.Constraint)
            FunctionSpace_S.Constraint =
              List_Create(6, 6, sizeof (struct ConstraintInFS));
        }
    
      | ConstraintInFSs '{' ConstraintInFS '}'
        {
          Group_S.FunctionType = Type_Function;
          Group_S.SuppListType = Type_SuppList;
          Group_S.SuppListType2 = Type_SuppList2;
          switch (Group_S.FunctionType) {
          case ELEMENTSOF :  Group_S.Type = ELEMENTLIST;  break;
          default :          Group_S.Type = REGIONLIST ;  break;
          }
    
          if(Constraint_Index >= 0) {
    	Constraint_P = (struct Constraint *)
    	  List_Pointer(Problem_S.Constraint, Constraint_Index);
    
    	for(int i = 0; i < List_Nbr(Constraint_P->ConstraintPerRegion); i++) {
    	  ConstraintPerRegion_P = (struct ConstraintPerRegion *)
    	    List_Pointer(Constraint_P->ConstraintPerRegion, i);
    
    	  if(ConstraintPerRegion_P->RegionIndex >= 0) {
    	    Group_S.InitialList =
    	      ((struct Group *)
    	       List_Pointer(Problem_S.Group, ConstraintPerRegion_P->RegionIndex))
    	      ->InitialList;
    	    Group_S.InitialSuppList =
    	      (ConstraintPerRegion_P->SubRegionIndex >= 0)?
    	      ((struct Group *)
    	       List_Pointer(Problem_S.Group,
    			    ConstraintPerRegion_P->SubRegionIndex))
    	      ->InitialList : NULL;
    	    Group_S.InitialSuppList2 =
    	      (ConstraintPerRegion_P->SubRegion2Index >= 0)?
    	      ((struct Group *)
    	       List_Pointer(Problem_S.Group,
    			    ConstraintPerRegion_P->SubRegion2Index))
    	      ->InitialList : NULL;
    	    ConstraintInFS_S.EntityIndex = Add_Group(&Group_S, (char*)"CO_Entity",
                                                         false, 1, 0);
    	    ConstraintInFS_S.ConstraintPerRegion = ConstraintPerRegion_P;
    
    	    List_Add(FunctionSpace_S.Constraint, &ConstraintInFS_S);
    	  }
    	}
          }
        }
    
      | ConstraintInFSs  Loop
     ;
    
    
    ConstraintInFS :
    
        /* none */
        {
          ConstraintInFS_S.QuantityType = LOCALQUANTITY;
          ConstraintInFS_S.ReferenceIndex = -1; ConstraintInFS_S.EntityIndex = -1;
          ConstraintInFS_S.ConstraintPerRegion = NULL;
          ConstraintInFS_S.Active.ResolutionIndex = -1;
          ConstraintInFS_S.Active.Active = NULL;
          Constraint_Index = -1;
          Type_Function = 0;
        }
    
      | ConstraintInFS  ConstraintInFSTerm
     ;
    
    
    ConstraintInFSTerm :
    
        tNameOfCoef String__Index tEND
        {
          int i, index_BF = -1;
          if((i = List_ISearchSeq(FunctionSpace_S.BasisFunction, $2,
                                  fcmp_BasisFunction_NameOfCoef)) < 0) {
    	if((i = List_ISearchSeq(FunctionSpace_S.GlobalQuantity, $2,
                                    fcmp_GlobalQuantity_Name)) < 0)
    	  vyyerror(0, "Unknown NameOfCoef: %s", $2);
    	else {
    	  ConstraintInFS_S.QuantityType   = GLOBALQUANTITY;
    	  ConstraintInFS_S.ReferenceIndex = i;
    
              index_BF =
                ((struct GlobalQuantity *)
                 List_Pointer(FunctionSpace_S.GlobalQuantity, i))->ReferenceIndex;
    	}
          }
          else {
    	ConstraintInFS_S.QuantityType   = LOCALQUANTITY;
    	ConstraintInFS_S.ReferenceIndex = i;
            index_BF = i;
          }
    
          // Auto selection of Type_Function
          int entity_index =
            ((struct BasisFunction *)
             List_Pointer(FunctionSpace_S.BasisFunction, index_BF))->EntityIndex;
          if(entity_index<0)
            vyyerror(0, "Undefined Entity for NameOfCoef %s", $2);
          Type_Function =
            ((struct Group *)List_Pointer(Problem_S.Group, entity_index))->FunctionType;
    
          Free($2);
        }
    
      | tEntityType FunctionForGroup tEND
        { Type_Function = $2; }
    
      | tEntityType tAuto tEND
        {
          // Auto selection already done
        }
    
      | tEntitySubType SuppListTypeForGroup tEND
        { Type_SuppList = $2; Type_SuppList2 = $2; }
    
      | tNameOfConstraint String__Index tEND
        {
          Constraint_Index =
    	List_ISearchSeq(Problem_S.Constraint, $2, fcmp_Constraint_Name);
          if(Constraint_Index < 0)
            vyyerror(1, "Constraint '%s' is not provided", $2);
          Free($2);
        }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  F o r m u l a t i o n                                                   */
    /* ------------------------------------------------------------------------ */
    
    Formulations :
    
        /* none */
        { if(!Problem_S.Formulation)
    	Problem_S.Formulation = List_Create(10, 5, sizeof (struct Formulation));
        }
    
      | Formulations  BracedFormulation
     ;
    
    BracedFormulation :
    
        '{' Formulation '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.Formulation, index_Append, &Formulation_S);
          else
            List_Add(Problem_S.Formulation, &Formulation_S);
        }
    
      | Loop
     ;
    
    
    Formulation :
    
        /* none */
        {
          Formulation_S.Name = NULL; Formulation_S.Type = FEMEQUATION;
          Formulation_S.DefineQuantity = NULL; Formulation_S.Equation = NULL;
          level_Append = 0;
        }
    
      | Formulation  FormulationTerm
    
      | Formulation  Loop
     ;
    
    
    FormulationTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("Formulation", Problem_S.Formulation,
                                    $2, fcmp_Formulation_Name, level_Append);
          if (index_Append<0)
            Formulation_S.Name = $2;
          else{
            List_Read(Problem_S.Formulation, index_Append, &Formulation_S);
            Free($2);
          }
        }
    
      | tType tSTRING tEND
        { Formulation_S.Type =
    	Get_DefineForString(Formulation_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Formulation_Type);
    	vyyerror(0, "Unknown type of Formulation: %s", $2);
          }
          Free($2);
        }
    
      | tQuantity  '{' DefineQuantities '}'
    
      | tSTRING '{' Equations '}'
        {
          if(!Formulation_S.Equation) Formulation_S.Equation = $3;
          Free($1);
        }
     ;
    
    
    DefineQuantities :
        /* none */
        {
          if (!Formulation_S.DefineQuantity)
            Formulation_S.DefineQuantity =
              List_Create(6, 6, sizeof (struct DefineQuantity));
        }
    
      | DefineQuantities  '{' DefineQuantity '}'
        {
          List_Add(Formulation_S.DefineQuantity, &DefineQuantity_S);
        }
    
      | DefineQuantities Loop
     ;
    
    
    DefineQuantity :
    
        /* none */
        { DefineQuantity_S.Name = NULL;
          DefineQuantity_S.Type = LOCALQUANTITY;
          DefineQuantity_S.IndexInFunctionSpace = NULL;
          DefineQuantity_S.FunctionSpaceIndex = -1;
          DefineQuantity_S.DofDataIndex = -1;
          DefineQuantity_S.DofData = NULL;
          DefineQuantity_S.FrequencySpectrum = NULL;
    
          DefineQuantity_S.IntegralQuantity.InIndex = -1;
          DefineQuantity_S.IntegralQuantity.IntegrationMethodIndex = -1;
          DefineQuantity_S.IntegralQuantity.JacobianMethodIndex = -1;
          DefineQuantity_S.IntegralQuantity.Symmetry = 0;
          DefineQuantity_S.IntegralQuantity.WholeQuantity = NULL;
        }
    
      | DefineQuantity DefineQuantityTerm
     ;
    
    
    DefineQuantityTerm :
    
        tName String__Index tEND
        { DefineQuantity_S.Name = $2; }
    
      | tType tGlobalQuantity tEND
        { DefineQuantity_S.Type = GLOBALQUANTITY; }
    
        /* Doit rester tant qu'on ne supprime pas l'association 'Integral <-> tGalerkin' */
      | tType tGalerkin tEND
        { DefineQuantity_S.Type = INTEGRALQUANTITY; }
    
      | tType tSTRING tEND
        { DefineQuantity_S.Type =
    	Get_DefineForString(DefineQuantity_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, DefineQuantity_Type);
    	vyyerror(0, "Unknown type of Quantity: %s", $2);
          }
          Free($2);
        }
    
      | tFrequencySpectrum ListOfFExpr tEND
        { DefineQuantity_S.FrequencySpectrum = $2;
        }
    
      | tNameOfSpace String__Index
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.FunctionSpace, $2,
    			       fcmp_FunctionSpace_Name)) < 0)
    	vyyerror(0, "Unknown FunctionSpace: %s", $2);
          else
    	DefineQuantity_S.FunctionSpaceIndex = i;
        }
        IndexInFunctionSpace tEND
        {
          if(DefineQuantity_S.FunctionSpaceIndex >= 0) {
    	if(DefineQuantity_S.Type == GLOBALQUANTITY &&
    	    !DefineQuantity_S.IndexInFunctionSpace) {
    	  if(DefineQuantity_S.Name) {
    	    List_Read(Problem_S.FunctionSpace,
    		      DefineQuantity_S.FunctionSpaceIndex, &FunctionSpace_S);
    	    int i;
    	    if((i = List_ISearchSeq(FunctionSpace_S.GlobalQuantity,
    				     DefineQuantity_S.Name,
    				     fcmp_GlobalQuantity_Name)) < 0) {
    	      vyyerror(0, "Unknown GlobalQuantity: %s", DefineQuantity_S.Name);
    	    }
    	    else {
    	      DefineQuantity_S.IndexInFunctionSpace = List_Create(1, 1, sizeof(int));
    	      List_Add(DefineQuantity_S.IndexInFunctionSpace, &i);
    	    }
    	  }
    	  else  vyyerror(0, "No Name pre-defined for GlobalQuantity");
    	}
          }
    
        }
    
      | tIndexOfSystem FExpr tEND
        {
          DefineQuantity_S.DofDataIndex = (int)$2;
        }
    
      | '['
        {
          Current_DofIndexInWholeQuantity = -1;
          Current_NoDofIndexInWholeQuantity = -1;
          List_Reset(ListOfPointer_L);
        }
        WholeQuantityExpression ']' tEND
        {
          DefineQuantity_S.IntegralQuantity.WholeQuantity = $3;
          DefineQuantity_S.IntegralQuantity.DofIndexInWholeQuantity =
    	Current_DofIndexInWholeQuantity;
    
          WholeQuantity_P = (struct WholeQuantity*)
    	List_Pointer(DefineQuantity_S.IntegralQuantity.WholeQuantity, 0);
    
          /* Ce qui suit ne suffit pas : il faudrait aussi gerer des
    	Quantity_def sans Dof */
    
          if(Current_DofIndexInWholeQuantity >= 0) {
    	DefineQuantity_S.IntegralQuantity.TypeOperatorDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.TypeOperator;
    	DefineQuantity_S.IntegralQuantity.DefineQuantityIndexDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
    	DefineQuantity_S.FunctionSpaceIndex =
    	  ((struct DefineQuantity*)
    	   List_Pointer(Formulation_S.DefineQuantity,
    			DefineQuantity_S.IntegralQuantity.DefineQuantityIndexDof))->
    	  FunctionSpaceIndex;
          }
          else { /* No Dof{} */
    	DefineQuantity_S.IntegralQuantity.TypeOperatorDof = NOOP;
    	DefineQuantity_S.IntegralQuantity.DefineQuantityIndexDof = -1;
          }
    
          if(Current_NoDofIndexInWholeQuantity >= 0) {
    	DefineQuantity_S.IntegralQuantity.DefineQuantityIndexNoDof =
    	  (WholeQuantity_P+Current_NoDofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
          }
          else { /* No NoDof{} */
    	DefineQuantity_S.IntegralQuantity.DefineQuantityIndexNoDof = -1;
          }
    
          /* Check if the WholeQuantity is a Canonical Form */
    
          DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_NONE;
    
          if(List_Nbr(DefineQuantity_S.IntegralQuantity.WholeQuantity) == 1){
    
    	/* GF_FUNCTION */
    	if((WholeQuantity_P+0)->Type == WQ_BUILTINFUNCTION) {
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+0)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+0)->Case.Function.Para;
    	  }
    
    	  DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF;
    	}
          }
    
          else if(List_Nbr(DefineQuantity_S.IntegralQuantity.WholeQuantity) == 3){
    
    	/* GF_FUNCTION  OPER  DOF */
    	if     ((WholeQuantity_P+0)->Type == WQ_BUILTINFUNCTION     &&
    		 (WholeQuantity_P+1)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR      &&
    		 Current_DofIndexInWholeQuantity == 1) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+0)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+0)->Case.Function.Para;
    	  }
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PSCA_DOF;
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PVEC_DOF;
    	}
    
    	/* DOF OPER GF_FUNCTION */
    	else if((WholeQuantity_P+0)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+1)->Type == WQ_BUILTINFUNCTION     &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR      &&
    		 Current_DofIndexInWholeQuantity == 0) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+1)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+1)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+1)->Case.Function.Para;
    	  }
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PSCA_DOF;/* Scalar Prod Transitive */
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_DOF_PVEC_GF;
    	}
    
    	/* GF_FUNCTION  OPER  EXPR */
    	else if((WholeQuantity_P+0)->Type == WQ_BUILTINFUNCTION &&
    		 (WholeQuantity_P+1)->Type == WQ_EXPRESSION      &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR ) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+0)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+0)->Case.Function.Para;
    	  }
    
    	  DefineQuantity_S.IntegralQuantity.ExpressionIndexForCanonical =
    	    (WholeQuantity_P+1)->Case.Expression.Index;
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PSCA_EXP;
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PVEC_EXP;
    	  /*
    	  DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	    (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	  DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	    (WholeQuantity_P+0)->Case.Function.Para;
    	  */
    	}
    
    	/* EXPR OPER GF_FUNCTION */
    	else if((WholeQuantity_P+0)->Type == WQ_EXPRESSION      &&
    		 (WholeQuantity_P+1)->Type == WQ_BUILTINFUNCTION &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR ) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+1)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+1)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+1)->Case.Function.Para;
    	  }
    
    	  DefineQuantity_S.IntegralQuantity.ExpressionIndexForCanonical =
    	    (WholeQuantity_P+0)->Case.Expression.Index;
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_GF_PSCA_EXP;/* Transitive product */
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	    DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_EXP_PVEC_GF;
    	}
          }
    
          else if(List_Nbr(DefineQuantity_S.IntegralQuantity.WholeQuantity) == 5){
    
    	/* EXPR  OPER  GF_FUNCTION  OPER  DOF */
    	if     ((WholeQuantity_P+0)->Type == WQ_EXPRESSION          &&
    		 (WholeQuantity_P+1)->Type == WQ_BUILTINFUNCTION     &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR      &&
    		 (WholeQuantity_P+3)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+4)->Type == WQ_BINARYOPERATOR      &&
    		 Current_DofIndexInWholeQuantity == 3) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+1)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+1)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+1)->Case.Function.Para;
    	  }
    
    	  DefineQuantity_S.IntegralQuantity.ExpressionIndexForCanonical =
    	    (WholeQuantity_P+0)->Case.Expression.Index;
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME){
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_TIME)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_EXP_TIME_GF_PSCA_DOF;
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_EXP_TIME_GF_PVEC_DOF;
    	  }
    	  else if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT){
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_TIME)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_EXP_PVEC_GF_PSCA_DOF;
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_EXP_PVEC_GF_PVEC_DOF;
    	  }
    	}
    
    	/* FCT OPER  GF_FUNCTION  OPER  DOF */
    	else if((WholeQuantity_P+0)->Type == WQ_BUILTINFUNCTION     &&
    		 (WholeQuantity_P+1)->Type == WQ_BUILTINFUNCTION     &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR      &&
    		 (WholeQuantity_P+3)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+4)->Type == WQ_BINARYOPERATOR      &&
    		 Current_DofIndexInWholeQuantity == 3) {
    
    	  Get_FunctionForFunction(GF_Function,
    				  (WholeQuantity_P+1)->Case.Function.Fct,
    				  &FlagError,
    				  &DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Fct);
    
    	  if(!FlagError){
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.NbrParameters =
    	      (WholeQuantity_P+1)->Case.Function.NbrParameters;
    	    DefineQuantity_S.IntegralQuantity.FunctionForCanonical.Para =
    	      (WholeQuantity_P+1)->Case.Function.Para;
    	  }
    
    	  DefineQuantity_S.IntegralQuantity.AnyFunction.Fct =
    	    (WholeQuantity_P+0)->Case.Function.Fct;
    	  DefineQuantity_S.IntegralQuantity.AnyFunction.NbrParameters =
    	    (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	  DefineQuantity_S.IntegralQuantity.AnyFunction.Para =
    	    (WholeQuantity_P+0)->Case.Function.Para;
    
    	  if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME){
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_TIME)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_FCT_TIME_GF_PSCA_DOF;
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_FCT_TIME_GF_PVEC_DOF;
    	  }
    	  else if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT){
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_TIME)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_FCT_PVEC_GF_PSCA_DOF;
    	    if((WholeQuantity_P+4)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	      DefineQuantity_S.IntegralQuantity.CanonicalWholeQuantity = CWQ_FCT_PVEC_GF_PVEC_DOF;
    	  }
    	}
          }
    
          Pro_DefineQuantityIndex
    	(DefineQuantity_S.IntegralQuantity.WholeQuantity,
    	 -1,
    	 &DefineQuantity_S.IntegralQuantity.NbrQuantityIndex,
    	 &DefineQuantity_S.IntegralQuantity.QuantityIndexTable,
    	 &DefineQuantity_S.IntegralQuantity.QuantityTraceGroupIndexTable);
          if(DefineQuantity_S.IntegralQuantity.NbrQuantityIndex > 1)
    	vyyerror(0, "More than one LocalQuantity in IntegralQuantity");
    
        }
    
      | tIn GroupRHS tEND
        {
          DefineQuantity_S.IntegralQuantity.InIndex = Num_Group(&Group_S, (char*)"IQ_In", $2);
        }
    
      | tIntegration tSTRING tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.IntegrationMethod, $2,
    			       fcmp_IntegrationMethod_Name)) < 0)
    	vyyerror(0, "Unknown Integration method: %s", $2);
          else
    	DefineQuantity_S.IntegralQuantity.IntegrationMethodIndex = i;
          Free($2);
        }
    
      | tJacobian String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.JacobianMethod, $2,
    			       fcmp_JacobianMethod_Name)) < 0)
    	vyyerror(0, "Unknown Jacobian method: %s", $2);
          else
    	DefineQuantity_S.IntegralQuantity.JacobianMethodIndex = i;
          Free($2);
        }
    
      | tSymmetry tINT tEND
        {
          DefineQuantity_S.IntegralQuantity.Symmetry = $2;
        }
     ;
    
    IndexInFunctionSpace :
    
        /* none */
      | '[' String__Index ']'
        {
          if(DefineQuantity_S.FunctionSpaceIndex >= 0) {
    	if(DefineQuantity_S.Type == LOCALQUANTITY) {
    	  int i;
    	  if((i = List_ISearchSeq
    	       (((struct FunctionSpace *)
    		 List_Pointer(Problem_S.FunctionSpace,
    			      DefineQuantity_S.FunctionSpaceIndex))->SubSpace, $2,
    		fcmp_SubSpace_Name)) < 0)
    	    vyyerror(0, "Unknown SubSpace: %s", $2);
    	  else {
    	    DefineQuantity_S.IndexInFunctionSpace =
    	      ((struct SubSpace *)
    	       List_Pointer
    	       (((struct FunctionSpace *)
    		 List_Pointer(Problem_S.FunctionSpace,
    			      DefineQuantity_S.FunctionSpaceIndex))->SubSpace, i))
    		->BasisFunction;
    	  }
    	}
    	else if(DefineQuantity_S.Type == GLOBALQUANTITY) {
    	  List_Read(Problem_S.FunctionSpace,
    		    DefineQuantity_S.FunctionSpaceIndex, &FunctionSpace_S);
    	  int i;
    	  if((i = List_ISearchSeq(FunctionSpace_S.GlobalQuantity,
    				   $2, fcmp_GlobalQuantity_Name)) < 0) {
    	    vyyerror(0, "Unknown GlobalQuantity: %s", $2);
    	  }
    	  else {
    	    DefineQuantity_S.IndexInFunctionSpace = List_Create(1, 1, sizeof(int));
    	    List_Add(DefineQuantity_S.IndexInFunctionSpace, &i);
    	  }
    	}
          }
          Free($2);
        }
     ;
    
    
    Equations :
    
        /* none */
        {
          $$ = Formulation_S.Equation?
            Formulation_S.Equation :
            List_Create(6, 6, sizeof(struct EquationTerm));
        }
    
      | Equations  EquationTerm
        {
          List_Add($$ = $1, &EquationTerm_S);
        }
    
      | Equations  Loop
        {
          $$ = $1;
        }
     ;
    
    
    EquationTerm :
    
        tGalerkin  '{' LocalTerm '}'
        { EquationTerm_S.Type = GALERKIN; }
    
      | tdeRham  '{' LocalTerm '}'
        { EquationTerm_S.Type = DERHAM; }
    
      | tGlobalTerm  '{' GlobalTerm '}'
        { EquationTerm_S.Type = GLOBALTERM; }
    
      | tGlobalEquation  '{' GlobalEquation '}'
        { EquationTerm_S.Type = GLOBALEQUATION; }
     ;
    
    
    GlobalEquation :
    
        /* none */
        {
          EquationTerm_S.Case.GlobalEquation.Type = NETWORK;
          EquationTerm_S.Case.GlobalEquation.ConstraintIndex = -1;
          EquationTerm_S.Case.GlobalEquation.GlobalEquationTerm = NULL;
        }
      | GlobalEquation GlobalEquationTerm
      | GlobalEquation Loop
     ;
    
    GlobalEquationTerm :
    
        tType tSTRING tEND
        { EquationTerm_S.Case.GlobalEquation.Type =
    	Get_DefineForString(Constraint_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Constraint_Type);
    	vyyerror(0, "Unknown type of GlobalEquation: %s", $2);
          }
          Free($2);
        }
    
      | tNameOfConstraint String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Constraint, $2,
    			       fcmp_Constraint_Name)) >= 0)
    	EquationTerm_S.Case.GlobalEquation.ConstraintIndex = i;
          else
    	EquationTerm_S.Case.GlobalEquation.ConstraintIndex = -1;
          Free($2);
        }
    
      | '{' GlobalEquationTermTerm '}'
        {
          if(!EquationTerm_S.Case.GlobalEquation.GlobalEquationTerm)
    	EquationTerm_S.Case.GlobalEquation.GlobalEquationTerm =
    	  List_Create(3, 3, sizeof(struct GlobalEquationTerm));
          List_Add(EquationTerm_S.Case.GlobalEquation.GlobalEquationTerm,
    	       &GlobalEquationTerm_S);
        }
     ;
    
    
    
    GlobalEquationTermTerm :
    
        /* none */
        {
          GlobalEquationTerm_S.DefineQuantityIndexNode = -1;
          GlobalEquationTerm_S.DefineQuantityIndexLoop = -1;
          GlobalEquationTerm_S.DefineQuantityIndexEqu  = -1;
          GlobalEquationTerm_S.InIndex = -1;
        }
      | GlobalEquationTermTerm GlobalEquationTermTermTerm
     ;
    
    GlobalEquationTermTermTerm :
        tSTRING Quantity_Def tEND
        {
          if(!strcmp($1, "Node"))
            GlobalEquationTerm_S.DefineQuantityIndexNode = $2.Int2;
          else if(!strcmp($1, "Loop"))
            GlobalEquationTerm_S.DefineQuantityIndexLoop = $2.Int2;
          else if(!strcmp($1, "Equation"))
            GlobalEquationTerm_S.DefineQuantityIndexEqu  = $2.Int2;
          else
            vyyerror(0, "Unknown global equation term: %s", $1);
          Free($1);
        }
      | tIn GroupRHS tEND
      { GlobalEquationTerm_S.InIndex = Num_Group(&Group_S, (char*)"FO_In", $2); }
     ;
    
    
    
    LocalTerm :
    
        /* none */
        { EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NODT_;
          EquationTerm_S.Case.LocalTerm.Term.TypeOperatorEqu = NOOP;
          EquationTerm_S.Case.LocalTerm.Term.TypeOperatorDof = NOOP;
          EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexEqu = -1;
          EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexDof = -1;
          EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexNoDof = -1;
          EquationTerm_S.Case.LocalTerm.Term.WholeQuantity = NULL;
          EquationTerm_S.Case.LocalTerm.Term.DofIndexInWholeQuantity = -1;
          EquationTerm_S.Case.LocalTerm.Term.DofInTrace = 0;
          EquationTerm_S.Case.LocalTerm.InIndex = -1;
          EquationTerm_S.Case.LocalTerm.SubRegion = -1;
          EquationTerm_S.Case.LocalTerm.IntegrationMethodIndex = -1;
          EquationTerm_S.Case.LocalTerm.MatrixIndex = -1;
          EquationTerm_S.Case.LocalTerm.JacobianMethodIndex = -1;
          EquationTerm_S.Case.LocalTerm.ExpressionIndexForMetricTensor = -1;
          EquationTerm_S.Case.LocalTerm.Active = NULL;
          EquationTerm_S.Case.LocalTerm.Full_Matrix = 0;
        }
    
      | LocalTerm LocalTermTerm
     ;
    
    
    LocalTermTerm  :
    
        TermOperator '['
        {
          EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = Type_TermOperator;
          Current_DofIndexInWholeQuantity = -1;
          Current_NoDofIndexInWholeQuantity = -1;
          List_Reset(ListOfPointer_L);
        }
    
        WholeQuantityExpression
        { EquationTerm_S.Case.LocalTerm.Term.WholeQuantity = $4;
    
          EquationTerm_S.Case.LocalTerm.Term.DofIndexInWholeQuantity =
    	Current_DofIndexInWholeQuantity;
    
          WholeQuantity_P = (struct WholeQuantity*)
    	List_Pointer(EquationTerm_S.Case.LocalTerm.Term.WholeQuantity, 0);
    
          if(Current_DofIndexInWholeQuantity == -4){
    	EquationTerm_S.Case.LocalTerm.Term.DofInTrace = 1;
    	EquationTerm_S.Case.LocalTerm.Term.TypeOperatorDof =
    	  TypeOperatorDofInTrace;
    	EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexDof =
    	  DefineQuantityIndexDofInTrace;
          }
          else if(Current_DofIndexInWholeQuantity >= 0) {
    	EquationTerm_S.Case.LocalTerm.Term.TypeOperatorDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.TypeOperator;
    	EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
          }
          else { /* No Dof{} */
    	EquationTerm_S.Case.LocalTerm.Term.TypeOperatorDof = NOOP;
    	EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexDof = -1;
          }
    
          if(Current_NoDofIndexInWholeQuantity >= 0) {
    	EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexNoDof =
    	  (WholeQuantity_P+Current_NoDofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
          }
          else { /* No NoDof{} */
    	EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexNoDof = -1;
          }
    
          /* Check if the WholeQuantity is a Canonical Form of type 'expr[] * Dof{}'*/
    
          if((List_Nbr(EquationTerm_S.Case.LocalTerm.Term.WholeQuantity) == 3) &&
    	  ((WholeQuantity_P+0)->Type == WQ_EXPRESSION) &&
    	  ((WholeQuantity_P+1)->Type == WQ_OPERATORANDQUANTITY) &&
    	  ((WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR) &&
    	  ((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME) &&
    	  (Current_DofIndexInWholeQuantity == 1)) {
    	EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity =
    	  CWQ_EXP_TIME_DOF;
    	EquationTerm_S.Case.LocalTerm.Term.ExpressionIndexForCanonical =
    	  (WholeQuantity_P+0)->Case.Expression.Index;
          }
          else if((List_Nbr(EquationTerm_S.Case.LocalTerm.Term.WholeQuantity) == 3) &&
    	  ((WholeQuantity_P+0)->Type == WQ_BUILTINFUNCTION) &&
    	  ((WholeQuantity_P+1)->Type == WQ_OPERATORANDQUANTITY) &&
    	  ((WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR) &&
    	  (Current_DofIndexInWholeQuantity == 1)) {
    	if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME)
    	  EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity = CWQ_FCT_TIME_DOF;
    	if((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_CROSSPRODUCT)
    	  EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity = CWQ_FCT_PVEC_DOF;
    
    	EquationTerm_S.Case.LocalTerm.Term.FunctionForCanonical.Fct =
    	  (WholeQuantity_P+0)->Case.Function.Fct;
    	EquationTerm_S.Case.LocalTerm.Term.FunctionForCanonical.NbrParameters =
    	  (WholeQuantity_P+0)->Case.Function.NbrParameters;
    	EquationTerm_S.Case.LocalTerm.Term.FunctionForCanonical.Para =
    	  (WholeQuantity_P+0)->Case.Function.Para;
          }
          else if((List_Nbr(EquationTerm_S.Case.LocalTerm.Term.WholeQuantity) == 1) &&
    	       ((WholeQuantity_P+0)->Type == WQ_OPERATORANDQUANTITY) &&
    	       (Current_DofIndexInWholeQuantity == 0)) {
    	EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity = CWQ_DOF;
          }
          else {
    	EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity = CWQ_NONE;
          }
    
        }
    
        ','  WholeQuantityExpression ']'  tEND
        {
          EquationTerm_S.Case.LocalTerm.Term.TypeOperatorEqu = Quantity_TypeOperator;
          EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexEqu = Quantity_Index;
          EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity_Equ = CWQ_NONE;
    
          WholeQuantity_P = (struct WholeQuantity*) List_Pointer($7, 0);
    
          if(List_Nbr($7) == 1){
    	if((WholeQuantity_P+0)->Type != WQ_OPERATORANDQUANTITY)
    	  vyyerror(0, "Missing Quantity in Equation");
          }
          else if(List_Nbr($7) == 3 &&
    	       ((WholeQuantity_P+0)->Type == WQ_EXPRESSION &&
    		 (WholeQuantity_P+1)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR)) {
            // FIXME: should also add the case (BUILTINFUNCTION OPERATORANDQUANTITY BINARYOPERATOR)
    	EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity_Equ =
    	  CWQ_EXP_TIME_DOF;
    	EquationTerm_S.Case.LocalTerm.Term.ExpressionIndexForCanonical_Equ =
    	  (WholeQuantity_P+0)->Case.Expression.Index;
    	EquationTerm_S.Case.LocalTerm.Term.OperatorTypeForCanonical_Equ =
    	  (WholeQuantity_P+2)->Case.Operator.TypeOperator;
          }
          else if(List_Nbr($7) == 2 &&
    	       ((WholeQuantity_P+0)->Type == WQ_OPERATORANDQUANTITY &&
    		 (WholeQuantity_P+1)->Type == WQ_BUILTINFUNCTION)) {
    	EquationTerm_S.Case.LocalTerm.Term.CanonicalWholeQuantity_Equ =
    	  CWQ_FCT_DOF;
    	EquationTerm_S.Case.LocalTerm.Term.BuiltInFunction_Equ =
    	  (WholeQuantity_P+1)->Case.Function.Fct;
          }
          else{
    	vyyerror(0, "Unrecognized quantity structure in Equation");
          }
    
          Pro_DefineQuantityIndex
    	(EquationTerm_S.Case.LocalTerm.Term.WholeQuantity,
    	 EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexEqu,
    	 &EquationTerm_S.Case.LocalTerm.Term.NbrQuantityIndex,
    	 &EquationTerm_S.Case.LocalTerm.Term.QuantityIndexTable,
    	 &EquationTerm_S.Case.LocalTerm.Term.QuantityTraceGroupIndexTable);
    
          EquationTerm_S.Case.LocalTerm.Term.QuantityIndexPost = 0;
          for(int i = 0; i < EquationTerm_S.Case.LocalTerm.Term.NbrQuantityIndex; i++) {
    	if((EquationTerm_S.Case.LocalTerm.Term.QuantityIndexTable[i] !=
    	     EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexEqu) &&
    	    (EquationTerm_S.Case.LocalTerm.Term.QuantityIndexTable[i] !=
    	     EquationTerm_S.Case.LocalTerm.Term.DefineQuantityIndexDof)) {
    	  EquationTerm_S.Case.LocalTerm.Term.QuantityIndexPost = 1;
    	  break;
    	}
          }
        }
    
      | tIn GroupRHS tEND
        {
          EquationTerm_S.Case.LocalTerm.InIndex = Num_Group(&Group_S, (char*)"FO_In", $2);
        }
    
      | tSubRegion GroupRHS tEND
        {
          EquationTerm_S.Case.LocalTerm.SubRegion = Num_Group(&Group_S, (char*)"FO_In", $2);
        }
    
      | tJacobian String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.JacobianMethod, $2,
    			       fcmp_JacobianMethod_Name)) < 0)
    	vyyerror(0, "Unknown Jacobian method: %s",$2);
          else
    	EquationTerm_S.Case.LocalTerm.JacobianMethodIndex = i;
          Free($2);
        }
    
      | tIntegration String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.IntegrationMethod, $2,
    			       fcmp_IntegrationMethod_Name)) < 0)
    	vyyerror(0, "Unknown Integration method: %s", $2);
          else
    	EquationTerm_S.Case.LocalTerm.IntegrationMethodIndex = i;
          Free($2);
        }
    
      | tFull_Matrix tEND
        {
          EquationTerm_S.Case.LocalTerm.Full_Matrix = 1;
        }
    
      | tSTRING '[' tINT ']' tEND
        { if($3 == 1 || $3 == 2 || $3 == 3)
    	EquationTerm_S.Case.LocalTerm.MatrixIndex = $3;
          else
    	vyyerror(0, "Wrong MatrixIndex: %d", $3);
        }
    
      | tMetricTensor Expression tEND
        {
          EquationTerm_S.Case.LocalTerm.ExpressionIndexForMetricTensor = $2;
        }
    
      | tOrder FExpr tEND
        {
          if(EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative == EIG_){
            if($2 == 1)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = DTDOF_;
            else if($2 == 2)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = DTDTDOF_;
            else if($2 == 3)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = DTDTDTDOF_;
            else if($2 == 4)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = DTDTDTDTDOF_;
            else if($2 == 5)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = DTDTDTDTDTDOF_;
            else
              vyyerror(0, "Order should be >= 1 and <= 5");
          }
          else{
            vyyerror(0, "Order can only be applied with Eig term");
          }
        }
    
      | tRational FExpr tEND
        {
          if(EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative == EIG_){
            if($2 == 1)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG1DOF_;
            else if($2 == 2)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG2DOF_;
            else if($2 == 3)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG3DOF_;
            else if($2 == 4)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG4DOF_;
            else if($2 == 5)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG5DOF_;
            else if($2 == 6)
              EquationTerm_S.Case.LocalTerm.Term.TypeTimeDerivative = NLEIG6DOF_;
            else
              vyyerror(0, "Rational should be >= 1 and <= 6");
          }
          else{
            vyyerror(0, "Rational can only be applied with Eig term");
          }
        }
     ;
    
    
    GlobalTerm :
    
        /* none */
        { EquationTerm_S.Case.GlobalTerm.TypeTimeDerivative = NODT_;
          EquationTerm_S.Case.GlobalTerm.DefineQuantityIndex = -1;
    
          EquationTerm_S.Case.GlobalTerm.Term.TypeTimeDerivative = NODT_;
          EquationTerm_S.Case.GlobalTerm.Term.TypeOperatorEqu = NOOP;
          EquationTerm_S.Case.GlobalTerm.Term.TypeOperatorDof = NOOP;
          EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexEqu = -1;
          EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexDof = -1;
          EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexNoDof = -1;
          EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity = NULL;
          EquationTerm_S.Case.GlobalTerm.Term.DofIndexInWholeQuantity = -1;
          EquationTerm_S.Case.GlobalTerm.InIndex = -1;
          EquationTerm_S.Case.GlobalTerm.SubType = EQ_ST_SELF;
        }
    
      | GlobalTerm  GlobalTermTerm
     ;
    
    
    GlobalTermTerm :
        tIn GroupRHS tEND
        {
          EquationTerm_S.Case.GlobalTerm.InIndex = Num_Group(&Group_S, (char*)"FO_In", $2);
        }
    
      | tSubType tSTRING tEND
        {
          EquationTerm_S.Case.GlobalTerm.SubType =
            Get_DefineForString(Equation_SubType, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Equation_SubType);
    	vyyerror(0, "Unknown sub-type of Equation: %s", $2);
          }
          Free($2);
        }
    
      |  TermOperator '['
        {
          EquationTerm_S.Case.GlobalTerm.Term.TypeTimeDerivative = Type_TermOperator;
          Current_DofIndexInWholeQuantity = -1;
          Current_NoDofIndexInWholeQuantity = -1;
          List_Reset(ListOfPointer_L);
        }
    
        WholeQuantityExpression
        { EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity = $4;
    
          EquationTerm_S.Case.GlobalTerm.Term.DofIndexInWholeQuantity =
    	Current_DofIndexInWholeQuantity;
    
          WholeQuantity_P = (struct WholeQuantity*)
    	List_Pointer(EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity, 0);
    
          if(Current_DofIndexInWholeQuantity >= 0) {
    	EquationTerm_S.Case.GlobalTerm.Term.TypeOperatorDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.TypeOperator;
    	EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexDof =
    	  (WholeQuantity_P+Current_DofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
          }
          else { /* No Dof{} */
    	EquationTerm_S.Case.GlobalTerm.Term.TypeOperatorDof = NOOP;
    	EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexDof = -1;
          }
    
          if(Current_NoDofIndexInWholeQuantity >= 0) {
    	EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexNoDof =
    	  (WholeQuantity_P+Current_NoDofIndexInWholeQuantity)->
    	    Case.OperatorAndQuantity.Index;
          }
          else { /* No NoDof{} */
    	EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexNoDof = -1;
          }
    
          /* Check if the WholeQuantity is a Canonical Form of type 'expr[] * Dof{}'*/
    
          if((List_Nbr(EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity) == 3) &&
    	  ((WholeQuantity_P+0)->Type == WQ_EXPRESSION) &&
    	  ((WholeQuantity_P+1)->Type == WQ_OPERATORANDQUANTITY) &&
    	  ((WholeQuantity_P+2)->Type == WQ_BINARYOPERATOR) &&
    	  ((WholeQuantity_P+2)->Case.Operator.TypeOperator == OP_TIME) &&
    	  (Current_DofIndexInWholeQuantity == 1)) {
    	EquationTerm_S.Case.GlobalTerm.Term.CanonicalWholeQuantity =
    	  CWQ_EXP_TIME_DOF;
    	EquationTerm_S.Case.GlobalTerm.Term.ExpressionIndexForCanonical =
    	  (WholeQuantity_P+0)->Case.Expression.Index;
          }
          else if((List_Nbr(EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity) == 1) &&
    	       ((WholeQuantity_P+0)->Type == WQ_OPERATORANDQUANTITY) &&
    	       (Current_DofIndexInWholeQuantity == 0)) {
    	EquationTerm_S.Case.GlobalTerm.Term.CanonicalWholeQuantity = CWQ_DOF;
          }
          else {
    	EquationTerm_S.Case.GlobalTerm.Term.CanonicalWholeQuantity = CWQ_NONE;
          }
    
        }
    
        ','  Quantity_Def  ']' tEND
        { EquationTerm_S.Case.GlobalTerm.Term.TypeOperatorEqu = $7.Int1;
          EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexEqu = $7.Int2;
    
          Pro_DefineQuantityIndex
    	(EquationTerm_S.Case.GlobalTerm.Term.WholeQuantity,
    	 EquationTerm_S.Case.GlobalTerm.Term.DefineQuantityIndexEqu,
    	 &EquationTerm_S.Case.GlobalTerm.Term.NbrQuantityIndex,
    	 &EquationTerm_S.Case.GlobalTerm.Term.QuantityIndexTable,
    	 &EquationTerm_S.Case.GlobalTerm.Term.QuantityTraceGroupIndexTable);
        }
    
     ;
    
    
    
    TermOperator :
    
        /* none */     { Type_TermOperator = NODT_          ; }
      | tDt            { Type_TermOperator = DT_            ; }
      | tDtDof         { Type_TermOperator = DTDOF_         ; }
      | tDtDt          { Type_TermOperator = DTDT_          ; }
      | tDtDtDof       { Type_TermOperator = DTDTDOF_       ; }
      | tDtDtDtDof     { Type_TermOperator = DTDTDTDOF_     ; }
      | tDtDtDtDtDof   { Type_TermOperator = DTDTDTDTDOF_   ; }
      | tDtDtDtDtDtDof { Type_TermOperator = DTDTDTDTDTDOF_ ; }
      | tJacNL         { Type_TermOperator = JACNL_         ; }
      | tDtDofJacNL    { Type_TermOperator = DTDOFJACNL_    ; }
      | tNeverDt       { Type_TermOperator = NEVERDT_       ; }
      | tDtNL          { Type_TermOperator = DTNL_          ; }
      | tEig           { Type_TermOperator = EIG_           ; }
    
     ;
    
    Quantity_Def :
    
        '{' tSTRING String__Index '}'
        { $$.Int1 = Get_DefineForString(Operator_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, Operator_Type);
    	vyyerror(0, "Unknown Operator for discrete Quantity: %s", $2);
          }
          Free($2);
          int i;
          if((i = List_ISearchSeq(Formulation_S.DefineQuantity, $3,
    			       fcmp_DefineQuantity_Name)) < 0)
    	vyyerror(0, "Unknown discrete Quantity: %s", $3);
          $$.Int2 = i;
    
          /* the following should be suppressed as soon as the test
             function part in the formulations is correctly treated */
          Quantity_TypeOperator = $$.Int1;
          Quantity_Index = $$.Int2;
    
          Free($3);
        }
    
      | '{' String__Index '}'
        { $$.Int1 = NOOP;
          int i;
          if((i = List_ISearchSeq(Formulation_S.DefineQuantity, $2,
    			       fcmp_DefineQuantity_Name)) < 0)
    	vyyerror(0, "Unknown discrete Quantity: %s", $2);
          $$.Int2 = i;
    
          /* the following should be suppressed as soon as the test
             function part in the formulations is correctly treated */
          Quantity_TypeOperator = $$.Int1;
          Quantity_Index = $$.Int2;
    
          Free($2);
        }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  R e s o l u t i o n                                                     */
    /* ------------------------------------------------------------------------ */
    
    Resolutions :
    
        /* none */
        { if(!Problem_S.Resolution)
    	Problem_S.Resolution = List_Create(10, 5, sizeof (struct Resolution));
        }
    
      | Resolutions  BracedResolution
     ;
    
    BracedResolution :
    
        '{' Resolution '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.Resolution, index_Append, &Resolution_S);
          else
            List_Add(Problem_S.Resolution, &Resolution_S);
        }
    
      | Loop
     ;
    
    
    Resolution :
    
        /* none */
        {
          Resolution_S.Name = NULL;
          Resolution_S.Hidden = false;
          Resolution_S.DefineSystem = NULL;
          Resolution_S.Operation = NULL;
          level_Append = 0;
        }
    
      | Resolution  ResolutionTerm
     ;
    
    
    ResolutionTerm :
    
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("Resolution", Problem_S.Resolution,
                                    $2, fcmp_Resolution_Name, level_Append);
          if (index_Append<0)
            Resolution_S.Name = $2;
          else{
            List_Read(Problem_S.Resolution, index_Append, &Resolution_S);
            Free($2);
          }
        }
    
      | tHidden FExpr tEND { Resolution_S.Hidden = $2 ? true : false; }
    
      | tDefineSystem  '{' DefineSystems '}'
        { Resolution_S.DefineSystem = $3; }
    
      | tOperation
        { Operation_L = List_Create(5, 5, sizeof(struct Operation)); }
        '{' Operation '}'
        { Resolution_S.Operation = $4;  List_Delete(Operation_L); }
    
      | Loop
     ;
    
    
    DefineSystems :
        /* none */
        {
          $$ = Current_System_L =
            Resolution_S.DefineSystem?
            Resolution_S.DefineSystem :
            List_Create(6, 6, sizeof (struct DefineSystem));
        }
    
      | DefineSystems  '{' DefineSystem '}'
        {
          int i ;
          if ((i = List_ISearchSeq(Current_System_L, DefineSystem_S.Name, fcmp_DefineSystem_Name)) < 0)
    	List_Add($$ = Current_System_L = $1, &DefineSystem_S) ;
          else
    	List_Write(Current_System_L, i, &DefineSystem_S) ;
        }
    
      | DefineSystems Loop
         {
           $$ = $1;
         }
     ;
    
    
    DefineSystem :
    
        /* none */
        { DefineSystem_S.Name = NULL;
          DefineSystem_S.Type = VAL_REAL;
          DefineSystem_S.FormulationIndex = NULL;
          DefineSystem_S.MeshName = NULL;
          DefineSystem_S.AdaptName = NULL;
          DefineSystem_S.FrequencyValue = NULL;
          DefineSystem_S.SolverDataFileName = NULL;
          DefineSystem_S.OriginSystemIndex = NULL;
          DefineSystem_S.DestinationSystemName = NULL;
          DefineSystem_S.DestinationSystemIndex = -1;
        }
    
      | DefineSystem DefineSystemTerm
     ;
    
    
    DefineSystemTerm :
    
        tName String__Index tEND
        {
          int i;
          if ((i = List_ISearchSeq(Current_System_L, $2, fcmp_DefineSystem_Name)) < 0)
    	DefineSystem_S.Name = $2 ;
          else
    	List_Read(Current_System_L, i, &DefineSystem_S) ;
        }
    
      | tType tSTRING tEND
        { DefineSystem_S.Type = Get_DefineForString(DefineSystem_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, DefineSystem_Type);
    	vyyerror(0, "Unknown type of System: %s", $2);
          }
          Free($2);
        }
    
      | tNameOfFormulation ListOfFormulation tEND
        { DefineSystem_S.FormulationIndex = $2; }
    
      | tNameOfMesh CharExpr tEND
        {
          DefineSystem_S.MeshName = strSave(Fix_RelativePath($2).c_str());
          Free($2);
        }
    
      | tOriginSystem ListOfSystem tEND
        {
          if (!DefineSystem_S.OriginSystemIndex) {
    	DefineSystem_S.OriginSystemIndex = $2 ;
          }
          else {
    	for (int i = 0 ; i < List_Nbr($2) ; i++)
    	  List_Add(DefineSystem_S.OriginSystemIndex, (int *)List_Pointer($2, i) ) ;
          }
        }
    
      | tDestinationSystem String__Index tEND
        {
          DefineSystem_S.DestinationSystemName = $2;
        }
    
      | tFrequency ListOfFExpr tEND
        { DefineSystem_S.FrequencyValue = $2;
          DefineSystem_S.Type = VAL_COMPLEX;
        }
    
      | tSolver CharExpr tEND
        {
          DefineSystem_S.SolverDataFileName = $2;
        }
    
      | Loop
     ;
    
    
    ListOfFormulation :
    
        String__Index
        {
          $$ = List_Create(1, 1, sizeof(int));
          int i;
          if((i = List_ISearchSeq(Problem_S.Formulation, $1, fcmp_Formulation_Name)) < 0)
    	vyyerror(0, "Unknown Formulation: %s", $1);
          else  List_Add($$, &i);
          Free($1);
        }
    
      | '{' RecursiveListOfFormulation '}'
        { $$ = $2; }
     ;
    
    
    RecursiveListOfFormulation :
    
        /* none */
        { $$ = List_Create(2, 2, sizeof(int)); }
    
      | RecursiveListOfFormulation Comma String__Index
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Formulation, $3, fcmp_Formulation_Name)) < 0)
    	vyyerror(0, "Unknown Formulation: %s", $3);
          else
    	List_Add($1, &i);
          $$ = $1; Free($3);
        }
     ;
    
    ListOfSystem :
    
        String__Index
        {
          $$ = List_Create(1, 1, sizeof(int));
          int i;
          if((i = List_ISearchSeq(Current_System_L, $1, fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $1);
          else
    	List_Add($$, &i);
          Free($1);
        }
    
      | '{' RecursiveListOfSystem '}'
        { $$ = $2;  }
     ;
    
    RecursiveListOfSystem :
    
        /* none */
        { $$ = List_Create(2, 2, sizeof(int)); }
    
      | RecursiveListOfSystem Comma String__Index
        {
          int i;
          if((i = List_ISearchSeq(Current_System_L, $3, fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          else
    	List_Add($1, &i);
          $$ = $1; Free($3);
        }
     ;
    
    
    Operation :
        /* none */
        {
          $$ = Resolution_S.Operation?
            Resolution_S.Operation :
            List_Create(6, 6, sizeof (struct Operation));
          Operation_S.Type = OPERATION_NONE;
          Operation_S.DefineSystemIndex = -1;
          Operation_S.Flag = -1;
          List_Add(Operation_L, &Operation_S);
        }
    
      | Operation OperationTerm
        {
          if(((struct Operation*)
    	  List_Pointer(Operation_L, List_Nbr(Operation_L)-1))->Type != OPERATION_NONE){
    	List_Add($$ = $1, (struct Operation*)
    		 List_Pointer(Operation_L, List_Nbr(Operation_L)-1));
          }
        }
     ;
    
    CommaFExprOrNothing :
        { $$ = -1; }
      | ',' FExpr
        { $$ = (int)$2; }
     ;
    
    GmshOperation :
        tGmshRead { $$ = OPERATION_GMSHREAD; }
      | tGmshOpen { $$ = OPERATION_GMSHOPEN; }
      | tGmshMerge { $$ = OPERATION_GMSHMERGE; }
      | tGmshWrite { $$ = OPERATION_GMSHWRITE; }
    
    GenerateGroupOperation :
        tGenerateGroup { $$ = OPERATION_GENERATE; }
      | tGenerateJacGroup { $$ = OPERATION_GENERATEJAC; }
      | tGenerateRHSGroup { $$ = OPERATION_GENERATERHS; }
      | tGenerateGroupCumulative { $$ = OPERATION_GENERATE_CUMULATIVE; }
      | tGenerateJacGroupCumulative { $$ = OPERATION_GENERATEJAC_CUMULATIVE; }
      | tGenerateRHSGroupCumulative { $$ = OPERATION_GENERATERHS_CUMULATIVE; }
    
    CopyOperation :
       tCopySolution { $$ = OPERATION_COPYSOLUTION; }
     | tCopyRHS { $$ = OPERATION_COPYRHS; }
     | tCopyResidual { $$ = OPERATION_COPYRESIDUAL; }
     | tCopyIncrement { $$ = OPERATION_COPYINCREMENT; }
     | tCopyDofs { $$ = OPERATION_COPYDOFS; }
    
    GetOperation :
       tGetResidual { $$ = OPERATION_GETRESIDUAL; }
     | tGetNormSolution { $$ = OPERATION_GETNORMSOLUTION; }
     | tGetNormRHS { $$ = OPERATION_GETNORMRHS; }
     | tGetNormResidual { $$ = OPERATION_GETNORMRESIDUAL; }
     | tGetNormIncrement { $$ = OPERATION_GETNORMINCREMENT; }
    
    OperationTerm :
    
      /* OLD syntax */
    
        tSTRING String__Index tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = Get_DefineForString(Operation_Type, $1, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($1, Operation_Type);
    	vyyerror(0, "Unknown type of Operation: %s", $1);
          }
          Free($1);
    
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $2,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $2);
          Free($2);
          Operation_P->DefineSystemIndex = i;
    
          if(Operation_P->Type == OPERATION_GENERATE ||
             Operation_P->Type == OPERATION_GENERATERHS ||
             Operation_P->Type == OPERATION_GENERATEJAC ||
             Operation_P->Type == OPERATION_GENERATESEPARATE)
    	Operation_P->Case.Generate.GroupIndex = -1;
        }
    
      | tSetTime Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETTIME;
          Operation_P->Case.SetTime.ExpressionIndex = $2;
        }
    
      | tSetTimeStep Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETTIMESTEP;
          Operation_P->Case.SetTime.ExpressionIndex = $2;
        }
    
      | tTimeLoopTheta '{' TimeLoopTheta '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPTHETA;
        }
    
      | tTimeLoopNewmark '{' TimeLoopNewmark '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPNEWMARK;
        }
    
      | tIterativeLoop '{' IterativeLoop '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELOOP;
        }
    
      | tIterativeTimeReduction '{' IterativeTimeReduction '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVETIMEREDUCTION;
        }
    
      /* NEW syntax (function style): Only missing is IterativeTimeReduction */
    
      | tSTRING '[' String__Index CommaFExprOrNothing ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = Get_DefineForString(Operation_Type, $1, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($1, Operation_Type);
    	vyyerror(0, "Unknown type of Operation: %s", $1);
          }
          Free($1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          if(Operation_P->Type == OPERATION_GENERATE ||
             Operation_P->Type == OPERATION_GENERATERHS ||
             Operation_P->Type == OPERATION_GENERATEJAC ||
             Operation_P->Type == OPERATION_GENERATESEPARATE)
    	Operation_P->Case.Generate.GroupIndex = -1;
          Operation_P->Flag = $4;
        }
    
      | tSetTime '[' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETTIME;
          Operation_P->Case.SetTime.ExpressionIndex = $3;
        }
    
      | tSetTimeStep '[' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETTIMESTEP;
          Operation_P->Case.SetTime.ExpressionIndex = $3;
        }
    
      | tSetDTime '[' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETDTIME;
          Operation_P->Case.SetTime.ExpressionIndex = $3;
        }
    
      | tSleep '[' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SLEEP;
          Operation_P->Case.Sleep.ExpressionIndex = $3;
        }
    
      | tSetCommSelf tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETCOMMSELF;
        }
    
      | tSetCommSelf '[' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETCOMMSELF;
        }
    
      | tSetCommWorld tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETCOMMWORLD;
        }
    
      | tSetCommWorld '[' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETCOMMWORLD;
        }
    
      | tBarrier tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BARRIER;
        }
    
      | tBarrier '[' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BARRIER;
        }
    
      | tBroadcastFields '[' ListOfFExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BROADCASTFIELDS;
          Operation_P->Case.BroadcastFields.FieldsToSkip = $3;
        }
    
      | tBroadcastVariables '[' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BROADCASTVARIABLES;
        }
    
      | tBreak tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BREAK;
        }
    
      | tBreak '[' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_BREAK;
        }
    
      | tTest '[' Expression ']' '{' Operation '}'
        {
          List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TEST;
          Operation_P->Case.Test.ExpressionIndex = $3;
          Operation_P->Case.Test.Operation_True = $6;
          Operation_P->Case.Test.Operation_False = NULL;
        }
    
      | tTest '[' Expression ']' '{' Operation '}' '{' Operation '}'
        {
          List_Pop(Operation_L);
          List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TEST;
          Operation_P->Case.Test.ExpressionIndex = $3;
          Operation_P->Case.Test.Operation_True = $6;
          Operation_P->Case.Test.Operation_False = $9;
        }
    
      | tWhile '[' Expression ']' '{' Operation '}'
        {
          List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_WHILE;
          Operation_P->Case.While.ExpressionIndex = $3;
          Operation_P->Case.While.Operation = $6;
        }
    
      | tSetFrequency '[' String__Index ',' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETFREQUENCY;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SetFrequency.ExpressionIndex = $5;
        }
    
      | tGenerateOnly '[' String__Index ',' ListOfFExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_GENERATEONLY;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.GenerateOnly.MatrixIndex_L =
    	List_Create(List_Nbr($5),1,sizeof(int));
    
          for(int i = 0; i < List_Nbr($5); i++){
    	double d;
    	List_Read($5,i,&d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.GenerateOnly.MatrixIndex_L, &j);
          }
          List_Delete($5);
        }
    
      | tGenerateOnlyJac '[' String__Index ',' ListOfFExpr ']' tEND
         { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_GENERATEONLYJAC;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.GenerateOnly.MatrixIndex_L =
    	List_Create(List_Nbr($5),1,sizeof(int));
    
          for(int i = 0; i < List_Nbr($5); i++){
    	double d;
    	List_Read($5,i,&d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.GenerateOnly.MatrixIndex_L, &j);
          }
          List_Delete($5);
        }
    
      | tUpdate '[' String__Index  ']' tEND
        { Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_UPDATE;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
                                   fcmp_DefineSystem_Name)) < 0)
            vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.Update.ExpressionIndex = -1;
        }
    
      | tUpdate '[' String__Index ',' Expression ']' tEND
        { Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_UPDATE;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
                                   fcmp_DefineSystem_Name)) < 0)
            vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.Update.ExpressionIndex = $5;
        }
    
      | tUpdateConstraint '[' String__Index ',' GroupRHS ',' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_UPDATECONSTRAINT;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.UpdateConstraint.GroupIndex =
    	Num_Group(&Group_S, (char*)"OP_UpdateCst", $5);
          Operation_P->Case.UpdateConstraint.Type =
    	Get_DefineForString(Constraint_Type, $7, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($7, Constraint_Type);
    	vyyerror(0, "Unknown type of Constraint: %s", $7);
          }
          Free($7);
        }
    
      | tUpdateConstraint '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_UPDATECONSTRAINT ;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.UpdateConstraint.GroupIndex = -1;
          Operation_P->Case.UpdateConstraint.Type = ASSIGN;
        }
    
      | GetOperation '[' String__Index ',' '$' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = $1;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.GetNorm.VariableName = $6;
          Operation_P->Case.GetNorm.NormType = L2NORM;
          /*
          NormType = Get_DefineForString(ErrorNorm_Type, $xx, &FlagError);
          if(FlagError){
            Get_Valid_SXD($xx, ErrorNorm_Type);
            vyyerror(0, "Unknown error norm type for residual calculation");
          }
          */
        }
    
      | tCreateSolution '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_CREATESOLUTION;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.CreateSolution.CopyFromTimeStep = -1;
        }
    
      | tCreateSolution '[' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_CREATESOLUTION;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.CreateSolution.CopyFromTimeStep = $5;
        }
    
      | tFourierTransform '[' String__Index ',' String__Index ',' ListOfFExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_FOURIERTRANSFORM;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->Case.FourierTransform.DefineSystemIndex[0] = i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $5,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $5);
          Free($5);
          Operation_P->Case.FourierTransform.DefineSystemIndex[1] = i;
          Operation_P->Case.FourierTransform.Frequency = $7;
        }
    
      | tFourierTransformJ '[' String__Index ',' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_FOURIERTRANSFORM2;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->Case.FourierTransform2.DefineSystemIndex[0] = i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $5,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $5);
          Free($5);
          Operation_P->Case.FourierTransform2.DefineSystemIndex[1] = i;
          Operation_P->Case.FourierTransform2.Period = $7;
          Operation_P->Case.FourierTransform2.Period_sofar = 0.;
          Operation_P->Case.FourierTransform2.Scales = NULL;
        }
    
      | tLanczos '[' String__Index ',' FExpr ',' ListOfFExpr ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_LANCZOS;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.Lanczos.Size = (int)$5;
          Operation_P->Case.Lanczos.Save =
    	List_Create(List_Nbr($7), 1, sizeof(int));
          for(int l = 0; l < List_Nbr($7); l++) {
    	double d;
    	List_Read($7, l, &d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.Lanczos.Save, &j);
          }
          List_Delete($7);
          Operation_P->Case.Lanczos.Shift = $9;
        }
    
      | tEigenSolve '[' String__Index ',' FExpr ',' FExpr ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_EIGENSOLVE;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.EigenSolve.NumEigenvalues = (int)$5;
          Operation_P->Case.EigenSolve.Shift_r = $7;
          Operation_P->Case.EigenSolve.Shift_i = $9;
          Operation_P->Case.EigenSolve.FilterExpressionIndex = -1;
          Operation_P->Case.EigenSolve.RationalCoefsNum = 0;
          Operation_P->Case.EigenSolve.RationalCoefsDen = 0;
        }
    
      | tEigenSolve '[' String__Index ',' FExpr ',' FExpr ',' FExpr
                    ',' Expression  ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_EIGENSOLVE;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.EigenSolve.NumEigenvalues = (int)$5;
          Operation_P->Case.EigenSolve.Shift_r = $7;
          Operation_P->Case.EigenSolve.Shift_i = $9;
          Operation_P->Case.EigenSolve.FilterExpressionIndex = $11;
          Operation_P->Case.EigenSolve.RationalCoefsNum = 0;
          Operation_P->Case.EigenSolve.RationalCoefsDen = 0;
        }
    
      | tEigenSolve '[' String__Index ',' FExpr ',' FExpr ',' FExpr
                    ',' Expression ',' '{' RecursiveListOfListOfFExpr '}' ','
                                       '{' RecursiveListOfListOfFExpr '}' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_EIGENSOLVE;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.EigenSolve.NumEigenvalues = (int)$5;
          Operation_P->Case.EigenSolve.Shift_r = $7;
          Operation_P->Case.EigenSolve.Shift_i = $9;
          Operation_P->Case.EigenSolve.FilterExpressionIndex = $11;
          Operation_P->Case.EigenSolve.RationalCoefsNum = $14;
          Operation_P->Case.EigenSolve.RationalCoefsDen = $18;
        }
    
      | tEigenSolveJac '[' String__Index ',' FExpr ',' FExpr ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_EIGENSOLVEJAC;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.EigenSolve.NumEigenvalues = (int)$5;
          Operation_P->Case.EigenSolve.Shift_r = $7;
          Operation_P->Case.EigenSolve.Shift_i = $9;
          Operation_P->Case.EigenSolve.FilterExpressionIndex = -1;
          Operation_P->Case.EigenSolve.RationalCoefsNum = 0;
          Operation_P->Case.EigenSolve.RationalCoefsDen = 0;
        }
    
      | tEvaluate '[' RecursiveListOfExpression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_EVALUATE;
          Operation_P->Case.Evaluate.Expressions = List_Copy(ListOfInt_L);
        }
    
      | tSelectCorrection '[' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_SELECTCORRECTION;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.SelectCorrection.Iteration = (int)$5 ;
        }
    
      | tAddCorrection '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_ADDCORRECTION;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.AddCorrection.Alpha = 1. ;
        }
    
      | tAddCorrection '[' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_ADDCORRECTION;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.AddCorrection.Alpha = $5 ;
        }
    
      | tMultiplySolution '[' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_MULTIPLYSOLUTION;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.MultiplySolution.Alpha = $5 ;
        }
    
      | tAddOppositeFullSolution '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_ADDOPPOSITEFULLSOLUTION;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
        }
    
      | tPerturbation '[' String__Index ',' String__Index ',' String__Index ','
        FExpr ',' ListOfFExpr ',' FExpr ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_PERTURBATION;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $5,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $5);
          Free($5);
          Operation_P->Case.Perturbation.DefineSystemIndex2 = i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $7,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $7);
          Free($7);
          Operation_P->Case.Perturbation.DefineSystemIndex3 = i;
          Operation_P->Case.Perturbation.Size = (int)$9;
          Operation_P->Case.Perturbation.Save =
    	List_Create(List_Nbr($11), 1, sizeof(int));
          for(int l = 0; l < List_Nbr($11); l++) {
    	double d;
    	List_Read($11, l, &d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.Perturbation.Save, &j);
          }
          List_Delete($11);
          Operation_P->Case.Perturbation.Shift = $13;
          Operation_P->Case.Perturbation.PertFreq = (int)$15;
        }
    
      | tTimeLoopTheta '[' FExpr ',' FExpr ',' Expression ',' Expression ']'
                       '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPTHETA;
          Operation_P->Case.TimeLoopTheta.Time0 = $3;
          Operation_P->Case.TimeLoopTheta.TimeMax = $5;
          Operation_P->Case.TimeLoopTheta.DTimeIndex = $7;
          Operation_P->Case.TimeLoopTheta.ThetaIndex = $9;
          Operation_P->Case.TimeLoopTheta.Operation = $12;
        }
    
      | tTimeLoopNewmark '[' FExpr ',' FExpr ',' Expression ',' FExpr ',' FExpr ']'
                         '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPNEWMARK;
          Operation_P->Case.TimeLoopNewmark.Time0 = $3;
          Operation_P->Case.TimeLoopNewmark.TimeMax = $5;
          Operation_P->Case.TimeLoopNewmark.DTimeIndex = $7;
          Operation_P->Case.TimeLoopNewmark.Beta = $9;
          Operation_P->Case.TimeLoopNewmark.Gamma = $11;
          Operation_P->Case.TimeLoopNewmark.Operation = $14;
        }
    
      | tTimeLoopRungeKutta '[' String__Index ',' FExpr ',' FExpr ',' Expression ','
                                ListOfFExpr ',' ListOfFExpr ',' ListOfFExpr ']'  tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPRUNGEKUTTA;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.TimeLoopRungeKutta.Time0 = $5;
          Operation_P->Case.TimeLoopRungeKutta.TimeMax = $7;
          Operation_P->Case.TimeLoopRungeKutta.DTimeIndex = $9;
          Operation_P->Case.TimeLoopRungeKutta.ButcherA = $11;
          Operation_P->Case.TimeLoopRungeKutta.ButcherB = $13;
          Operation_P->Case.TimeLoopRungeKutta.ButcherC = $15;
        }
    
      | tTimeLoopAdaptive '[' FExpr ',' FExpr ',' FExpr ',' FExpr ',' FExpr ',' CharExpr ','
                          ListOfFExpr ',' LTEdefinitions TLAoptions ']'
                          '{' Operation '}' '{' Operation '}'
        {
          List_Pop(Operation_L);
          List_Pop(Operation_L);
          Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_TIMELOOPADAPTIVE;
          Operation_P->Case.TimeLoopAdaptive.Time0 = $3;
          Operation_P->Case.TimeLoopAdaptive.TimeMax = $5;
          Operation_P->Case.TimeLoopAdaptive.DTimeInit = $7;
          Operation_P->Case.TimeLoopAdaptive.DTimeMin = $9;
          Operation_P->Case.TimeLoopAdaptive.DTimeMax = $11;
          Operation_P->Case.TimeLoopAdaptive.Scheme = $13;
          Operation_P->Case.TimeLoopAdaptive.Breakpoints_L = $15;
          Operation_P->Case.TimeLoopAdaptive.Operation = $21;
          Operation_P->Case.TimeLoopAdaptive.OperationEnd = $24;
        }
    
      | tIterativeLoopN '[' FExpr ',' Expression ',' IterativeLoopDefinitions ']'
                        '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELOOPN;
          Operation_P->Case.IterativeLoop.NbrMaxIteration = (int)$3;
          Operation_P->Case.IterativeLoop.RelaxationFactorIndex = $5;
          Operation_P->Case.IterativeLoop.Operation = $10;
        }
    
      | tIterativeLoop  '[' FExpr ',' FExpr ',' Expression ']'
                         '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELOOP;
          Operation_P->Case.IterativeLoop.NbrMaxIteration = (int)$3;
          Operation_P->Case.IterativeLoop.Criterion = $5;
          Operation_P->Case.IterativeLoop.RelaxationFactorIndex = $7;
          Operation_P->Case.IterativeLoop.Flag = 0;
          Operation_P->Case.IterativeLoop.Operation = $10;
        }
    
      | tIterativeLoop  '[' FExpr ',' FExpr ',' Expression ',' FExpr ']'
                         '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELOOP;
          Operation_P->Case.IterativeLoop.NbrMaxIteration = (int)$3;
          Operation_P->Case.IterativeLoop.Criterion = $5;
          Operation_P->Case.IterativeLoop.RelaxationFactorIndex = $7;
          Operation_P->Case.IterativeLoop.Flag = (int)$9;
          Operation_P->Case.IterativeLoop.Operation = $12;
        }
    
      | tIterativeLinearSolver '[' CharExpr ',' CharExpr ',' FExpr ',' FExpr ',' FExpr','
                                   ListOfFExpr',' ListOfFExpr',' ListOfFExpr ']'
                               '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELINEARSOLVER;
          Operation_P->Case.IterativeLinearSolver.OpMatMult = $3;
          Operation_P->Case.IterativeLinearSolver.Type = $5;
          Operation_P->Case.IterativeLinearSolver.Tolerance = $7;
          Operation_P->Case.IterativeLinearSolver.MaxIter = (int)$9;
          Operation_P->Case.IterativeLinearSolver.Restart = (int)$11;
          Operation_P->Case.IterativeLinearSolver.MyFieldTag = $13;
          Operation_P->Case.IterativeLinearSolver.NeighborFieldTag = $15;
          Operation_P->Case.IterativeLinearSolver.DeflationIndices = $17;
          Operation_P->Case.IterativeLinearSolver.Operations_Ax = $20;
          Operation_P->Case.IterativeLinearSolver.Operations_Mx = NULL;
        }
    
      | tIterativeLinearSolver '[' CharExpr ',' CharExpr ',' FExpr ',' FExpr ',' FExpr','
                                   ListOfFExpr',' ListOfFExpr',' ListOfFExpr ']'
                               '{' Operation '}'
                               '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ITERATIVELINEARSOLVER;
          Operation_P->Case.IterativeLinearSolver.OpMatMult = $3;
          Operation_P->Case.IterativeLinearSolver.Type = $5;
          Operation_P->Case.IterativeLinearSolver.Tolerance = $7;
          Operation_P->Case.IterativeLinearSolver.MaxIter = (int)$9;
          Operation_P->Case.IterativeLinearSolver.Restart = (int)$11;
          Operation_P->Case.IterativeLinearSolver.MyFieldTag = $13;
          Operation_P->Case.IterativeLinearSolver.NeighborFieldTag = $15;
          Operation_P->Case.IterativeLinearSolver.DeflationIndices = $17;
          Operation_P->Case.IterativeLinearSolver.Operations_Ax = $20;
          Operation_P->Case.IterativeLinearSolver.Operations_Mx = $23;
        }
    
      | tPrint
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_PRINT;
          Operation_P->Case.Print.Expressions = NULL;
          Operation_P->DefineSystemIndex = -1;
        }
       '[' PrintOperation PrintOperationOptions ']' tEND
    
      | tWrite
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_WRITE;
          Operation_P->Case.Print.Expressions = NULL;
          Operation_P->DefineSystemIndex = -1;
        }
       '[' PrintOperation PrintOperationOptions ']' tEND
    
      | tChangeOfCoordinates '[' GroupRHS ',' Expression ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_CHANGEOFCOORDINATES;
          Operation_P->Case.ChangeOfCoordinates.GroupIndex =
    	Num_Group(&Group_S, (char*)"OP_ChgCoord", $3);
          Operation_P->Case.ChangeOfCoordinates.ExpressionIndex = $5;
          Operation_P->Case.ChangeOfCoordinates.ExpressionIndex2 = -1;
        }
    
      | tChangeOfCoordinates '[' GroupRHS ',' Expression ',' FExpr ',' Expression ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_CHANGEOFCOORDINATES;
          Operation_P->Case.ChangeOfCoordinates.GroupIndex =
    	Num_Group(&Group_S, (char*)"OP_ChgCoord", $3);
          Operation_P->Case.ChangeOfCoordinates.ExpressionIndex = $5;
          Operation_P->Case.ChangeOfCoordinates.NumNode = (int)$7;
          Operation_P->Case.ChangeOfCoordinates.ExpressionIndex2 = $9;
        }
    
      | tPostOperation '[' String__Index ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_POSTOPERATION;
          Operation_P->Case.PostOperation.PostOperations =
    	List_Create(1,1,sizeof(char*));
          List_Add(Operation_P->Case.PostOperation.PostOperations, &$3);
        }
    
      | tSystemCommand '[' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SYSTEMCOMMAND;
          Operation_P->Case.SystemCommand.String = $3;
        }
    
      | tError '[' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_ERROR;
          Operation_P->Case.Error.String = $3;
        }
    
      | GmshOperation '[' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = $1;
          Operation_P->Case.GmshRead.FileName = strSave(Fix_RelativePath($3).c_str());
          Operation_P->Case.GmshRead.ViewTag = -1;
          Free($3);
        }
    
      | GmshOperation '[' CharExpr ',' FExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = $1;
          Operation_P->Case.GmshRead.FileName = strSave(Fix_RelativePath($3).c_str());
          Operation_P->Case.GmshRead.ViewTag = (int)$5;
          Free($3);
        }
    
      | tGmshClearAll tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_GMSHCLEARALL;
        }
    
      | tGmshClearAll '[' ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_GMSHCLEARALL;
        }
    
      | tDeleteFile '[' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_DELETEFILE;
          Operation_P->Case.DeleteFile.FileName = strSave(Fix_RelativePath($3).c_str());
          Free($3);
        }
    
      | tRenameFile '[' CharExpr ',' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_RENAMEFILE;
          Operation_P->Case.RenameFile.OldFileName = strSave(Fix_RelativePath($3).c_str());
          Operation_P->Case.RenameFile.NewFileName = strSave(Fix_RelativePath($5).c_str());
          Free($3);
          Free($5);
        }
    
      | tCreateDir '[' CharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_CREATEDIR;
          Operation_P->Case.CreateDir.DirName = strSave(Fix_RelativePath($3).c_str());
          Free($3);
        }
    
      | tSolveJac_AdaptRelax '[' String__Index ',' ListOfFExpr ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SOLVEJACADAPTRELAX;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SolveJac_AdaptRelax.CheckAll = (int)$7;
          Operation_P->Case.SolveJac_AdaptRelax.Factor_L = $5;
        }
    
      | tSaveSolutionWithEntityNum '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SAVESOLUTION_WITH_ENTITY_NUM;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveSolutionWithEntityNum.GroupIndex = -1;
          Operation_P->Case.SaveSolutionWithEntityNum.SaveFixed = -1;
        }
    
      | tSaveSolutionWithEntityNum '[' String__Index ',' GroupRHS CommaFExprOrNothing ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SAVESOLUTION_WITH_ENTITY_NUM;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveSolutionWithEntityNum.GroupIndex =
            Num_Group(&Group_S, (char*)"OP_SaveSolutionWithEntityNum", $5);
          Operation_P->Case.SaveSolutionWithEntityNum.SaveFixed = ($6 >= 0) ? $6 : 0;
        }
    
      | tSaveSolutionExtendedMH '[' String__Index ',' FExpr ',' CharExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SAVESOLUTIONEXTENDEDMH;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveSolutionExtendedMH.NbrFreq = (int)$5;
          Operation_P->Case.SaveSolutionExtendedMH.ResFile = $7;
        }
    
      | tSaveSolutionMHtoTime '[' String__Index ',' ListOfFExpr ',' CharExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SAVESOLUTIONMHTOTIME;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveSolutionMHtoTime.Time = $5;
          Operation_P->Case.SaveSolutionMHtoTime.ResFile = $7;
        }
    
      | tInitMovingBand2D  '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) < 0)
       	vyyerror(0, "Unknown Group: %s", $3);
          Operation_P->Type = OPERATION_INIT_MOVINGBAND2D;
                Operation_P->Case.Init_MovingBand2D.GroupIndex = i;
          Free($3);
        }
    
      | tMeshMovingBand2D  '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) < 0)
        	vyyerror(0, "Unknown Group: %s", $3);
          Operation_P->Type = OPERATION_MESH_MOVINGBAND2D;
          Operation_P->Case.Mesh_MovingBand2D.GroupIndex = i;
          Free($3);
        }
    
      | tSaveMesh  '[' String__Index ',' GroupRHS ',' CharExpr ',' Expression ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveMesh.GroupIndex = Num_Group(&Group_S, (char*)"OP_SaveMesh", $5);
          Operation_P->Case.SaveMesh.FileName = $7;
          Operation_P->Case.SaveMesh.ExprIndex = $9;
          Operation_P->Type = OPERATION_SAVEMESH;
        }
    
      | tSaveMesh  '[' String__Index ',' GroupRHS ',' CharExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveMesh.GroupIndex = Num_Group(&Group_S, (char*)"OP_SaveMesh", $5);
          Operation_P->Case.SaveMesh.FileName = $7;
          Operation_P->Case.SaveMesh.ExprIndex = -1;
          Operation_P->Type = OPERATION_SAVEMESH;
        }
    
      | tSaveMesh  '[' String__Index ',' GroupRHS ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveMesh.GroupIndex = Num_Group(&Group_S, (char*)"OP_SaveMesh", $5);
          Operation_P->Case.SaveMesh.FileName = 0;
          Operation_P->Case.SaveMesh.ExprIndex = -1;
          Operation_P->Type = OPERATION_SAVEMESH;
        }
    
      | tSaveMesh  '[' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.SaveMesh.GroupIndex = -1;
          Operation_P->Case.SaveMesh.FileName = 0;
          Operation_P->Case.SaveMesh.ExprIndex = -1;
          Operation_P->Type = OPERATION_SAVEMESH;
        }
    
      | tGenerateMHMoving  '[' String__Index ',' String__Index ',' FExpr ',' FExpr ']'
                             '{' Operation '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          if((i = List_ISearchSeq(Problem_S.Group, $5, fcmp_Group_Name)) < 0)
    	vyyerror(0, "Unknown Group: %s", $5);
          Free($5);
          Operation_P->Type = OPERATION_GENERATE_MH_MOVING;
          Operation_P->Case.Generate_MH_Moving.GroupIndex = i;
          Operation_P->Case.Generate_MH_Moving.Period  = $7;
          Operation_P->Case.Generate_MH_Moving.NbrStep = (int)$9;
          Operation_P->Case.Generate_MH_Moving.Operation = $12;
        }
    
      | tGenerateMHMovingSeparate  '[' String__Index ',' String__Index ',' FExpr ',' FExpr ']'
                                      '{' Operation '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          if((i = List_ISearchSeq(Problem_S.Group, $5, fcmp_Group_Name)) < 0)
    	vyyerror(0, "Unknown Group: %s", $5);
          Free($5);
          Operation_P->Type = OPERATION_GENERATE_MH_MOVING_S;
          Operation_P->Case.Generate_MH_Moving_S.GroupIndex = i;
          Operation_P->Case.Generate_MH_Moving_S.Period  = $7;
          Operation_P->Case.Generate_MH_Moving_S.NbrStep = (int)$9;
          Operation_P->Case.Generate_MH_Moving_S.Operation = $12;
        }
    
       | tAddMHMoving  '[' String__Index ']'  tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Type = OPERATION_ADDMHMOVING;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ',' tNameOfMesh CharExpr ','
                         FExpr ',' GroupRHS ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = $8;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = $10;
          Operation_P->Case.DeformMesh.GroupIndex =
            Num_Group(&Group_S, (char*)"OP_DeformMesh", $12);
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ',' tNameOfMesh CharExpr ','
                         FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = $8;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = $10;
          Operation_P->Case.DeformMesh.GroupIndex = -1;
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ',' tNameOfMesh CharExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = $8;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = 1;
          Operation_P->Case.DeformMesh.GroupIndex = -1;
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = NULL;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = 1;
          Operation_P->Case.DeformMesh.GroupIndex = -1;
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = NULL;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = $7;
          Operation_P->Case.DeformMesh.GroupIndex = -1;
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' '{' String__Index ',' String__Index ',' String__Index '}' ',' FExpr ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $6;
          Operation_P->Case.DeformMesh.Quantity2 = $8;
          Operation_P->Case.DeformMesh.Quantity3 = $10;
          Operation_P->Case.DeformMesh.Name_MshFile = NULL;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = $13;
          Operation_P->Case.DeformMesh.GroupIndex = -1;
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | tDeformMesh  '[' String__Index ',' String__Index ',' FExpr ',' GroupRHS ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.DeformMesh.Quantity = $5;
          Operation_P->Case.DeformMesh.Quantity2 = 0;
          Operation_P->Case.DeformMesh.Quantity3 = 0;
          Operation_P->Case.DeformMesh.Name_MshFile = NULL;
          Operation_P->Case.DeformMesh.GeoDataIndex = -1;
          Operation_P->Case.DeformMesh.Factor = $7;
          Operation_P->Case.DeformMesh.GroupIndex =
            Num_Group(&Group_S, (char*)"OP_DeformMesh", $9);
          Operation_P->Type = OPERATION_DEFORMMESH;
        }
    
      | GenerateGroupOperation  '[' String__Index ',' GroupRHS ']'  tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
                                  fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Type = $1;
          Operation_P->Case.Generate.GroupIndex =
            Num_Group(&Group_S, (char*)"OP_GenerateGroup", $5);
        }
    
      | tSolveAgainWithOther '[' String__Index ',' String__Index ']'  tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SOLVEAGAINWITHOTHER;
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
                                  fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3);
          Free($3);
          Operation_P->DefineSystemIndex = i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $5,
                                  fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $5);
          Free($5);
          Operation_P->Case.SolveAgainWithOther.DefineSystemIndex = i;
        }
    
      | tSetGlobalSolverOptions '[' CharExpr ']'  tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = OPERATION_SETGLOBALSOLVEROPTIONS;
          Operation_P->Case.SetGlobalSolverOptions.String = $3;
        }
    
      | CopyOperation '[' String__Index ',' CharExprNoVar ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = $1;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.Copy.useList = 0 ;
          Operation_P->Case.Copy.to = $5 ;
          Operation_P->Case.Copy.from = 0 ;
        }
    
      | CopyOperation '[' String__Index ',' String__Index '(' ')' ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = $1;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $3,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $3) ;
          Free($3) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.Copy.useList = 1 ;
          Operation_P->Case.Copy.to = $5 ;
          Operation_P->Case.Copy.from = 0 ;
        }
    
      | CopyOperation '[' CharExprNoVar ',' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = $1;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $5,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $5) ;
          Free($5) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.Copy.useList = 0 ;
          Operation_P->Case.Copy.to = 0 ;
          Operation_P->Case.Copy.from = $3 ;
        }
    
      | CopyOperation '[' String__Index '(' ')' ',' String__Index ']' tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = $1;
          int i;
          if ((i = List_ISearchSeq(Resolution_S.DefineSystem, $7,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $7) ;
          Free($7) ;
          Operation_P->DefineSystemIndex = i ;
          Operation_P->Case.Copy.useList = 1 ;
          Operation_P->Case.Copy.to = 0 ;
          Operation_P->Case.Copy.from = $3 ;
        }
    
      | tOptimizerInitialize '[' CharExpr ',' CharExpr ','
                                 ListOfFExpr ',' ListOfFExpr ','
                                 CharExpr ',' BracedRecursiveListOfCharExpr ','
                                 CharExpr ',' BracedRecursiveListOfCharExpr ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_OPTIMIZER_INITIALIZE;
          Operation_P->Case.OptimizerInitialize.algorithm = $3;
          Operation_P->Case.OptimizerInitialize.currentPoint = $5;
          Operation_P->Case.OptimizerInitialize.currentPointLowerBounds = $7;
          Operation_P->Case.OptimizerInitialize.currentPointUpperBounds = $9;
          Operation_P->Case.OptimizerInitialize.objective = $11;
          Operation_P->Case.OptimizerInitialize.constraints = $13;
          Operation_P->Case.OptimizerInitialize.objectiveSensitivity = $15;
          Operation_P->Case.OptimizerInitialize.constraintsSensitivity = $17;
        }
    
      | tOptimizerUpdate '[' '$' String__Index ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_OPTIMIZER_UPDATE;
          Operation_P->Case.OptimizerUpdate.residual = $4;
        }
    
      | tOptimizerFinalize '[' ']' tEND
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1) ;
          Operation_P->Type = OPERATION_OPTIMIZER_FINALIZE;
         }
    
      | Loop
        {
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Type = NONE;
        }
     ;
    
    PrintOperation :
        ListOfExpression
        {
          Operation_P->Case.Print.Expressions = List_Copy(ListOfInt_L);
          Operation_P->Case.Print.FormatString = NULL;
        }
    
      | String__Index
        {
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $1,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $1);
          Free($1);
          Operation_P->DefineSystemIndex = i;
          Operation_P->Case.Print.FormatString = NULL;
        }
    
      | tBIGSTR
        {
          Operation_P->Case.Print.Expressions = List_Create(1,1,sizeof(int));
          Operation_P->Case.Print.FormatString = $1;
        }
    
     ;
    
    PrintOperationOptions :
        {
          Operation_P->Case.Print.FileOut = NULL;
          Operation_P->Case.Print.TimeStep = NULL;
          Operation_P->Case.Print.DofNumber = NULL;
        }
      | PrintOperationOptions PrintOperationOption
     ;
    
    PrintOperationOption :
        ',' tFile CharExpr
        { Operation_P->Case.Print.FileOut = $3; }
    
      | ',' tTimeStep ListOfFExpr
        { Operation_P->Case.Print.TimeStep =
    	List_Create(List_Nbr($3), 1, sizeof(int));
          for(int i = 0; i < List_Nbr($3); i++){
    	double d;
    	List_Read($3,i,&d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.Print.TimeStep, &j);
          }
          List_Delete($3);
        }
    
      | ',' tFormat CharExpr
        {
          Operation_P->Case.Print.FormatString = $3;
        }
    
      | ',' ListOfFExpr
        { Operation_P->Case.Print.DofNumber =
    	List_Create(List_Nbr($2), 1, sizeof(int));
          for(int i = 0; i < List_Nbr($2); i++) {
    	double d;
    	List_Read($2, i, &d);
    	int j = (int)d;
    	List_Add(Operation_P->Case.Print.DofNumber, &j);
          }
          List_Delete($2);
        }
    
    ;
    
    TLAoptions :
        /* none */
        {
          Operation_P->Case.TimeLoopAdaptive.LTEtarget = -1.;
          Operation_P->Case.TimeLoopAdaptive.DTimeMaxScal = -1.;
          Operation_P->Case.TimeLoopAdaptive.DTimeScal_NotConverged = -1.;
        }
    
      | ',' FExpr
        {
          Operation_P->Case.TimeLoopAdaptive.LTEtarget = $2;
          Operation_P->Case.TimeLoopAdaptive.DTimeMaxScal = -1.;
          Operation_P->Case.TimeLoopAdaptive.DTimeScal_NotConverged = -1.;
        }
    
      | ',' FExpr ',' FExpr
        {
          Operation_P->Case.TimeLoopAdaptive.LTEtarget = $2;
          Operation_P->Case.TimeLoopAdaptive.DTimeMaxScal = $4;
          Operation_P->Case.TimeLoopAdaptive.DTimeScal_NotConverged = -1.;
        }
    
      | ',' FExpr ',' FExpr ',' FExpr
        {
          Operation_P->Case.TimeLoopAdaptive.LTEtarget = $2;
          Operation_P->Case.TimeLoopAdaptive.DTimeMaxScal = $4;
          Operation_P->Case.TimeLoopAdaptive.DTimeScal_NotConverged = $6;
        }
    
     ;
    
    LTEdefinitions :
        /* none */
        {
          Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopAdaptive.TimeLoopAdaptiveSystems_L = NULL;
          Operation_P->Case.TimeLoopAdaptive.TimeLoopAdaptivePOs_L = NULL;
        }
    
      | LTEdefinitions tDefineSystem '{' TimeLoopAdaptiveSystems '}'
        {
          Operation_P->Case.TimeLoopAdaptive.TimeLoopAdaptiveSystems_L = $4;
        }
    
      | LTEdefinitions tPostOperation '{' TimeLoopAdaptivePOs '}'
        {
          Operation_P->Case.TimeLoopAdaptive.TimeLoopAdaptivePOs_L = $4;
        }
    
     ;
    
    
     TimeLoopAdaptiveSystems :
        /* none */
        {
          $$ = List_Create(4, 4, sizeof(struct TimeLoopAdaptiveSystem));
        }
    
      | TimeLoopAdaptiveSystems '{' String__Index ',' FExpr ',' FExpr  ',' tSTRING '}'
        {
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3, fcmp_DefineSystem_Name)) < 0)
            vyyerror(0, "Unknown System: %s", $3);
          TimeLoopAdaptiveSystem_S.SystemIndex = i;
          TimeLoopAdaptiveSystem_S.SystemLTEreltol = $5;
          TimeLoopAdaptiveSystem_S.SystemLTEabstol = $7;
          TimeLoopAdaptiveSystem_S.NormType = Get_DefineForString(ErrorNorm_Type, $9, &FlagError);
          if(FlagError){
            Get_Valid_SXD($9, ErrorNorm_Type);
            vyyerror(0, "Unknown error norm type of TimeLoopAdaptive system %s", $3);
          }
          TimeLoopAdaptiveSystem_S.NormTypeString = $9;
          List_Add($$ = $1, &TimeLoopAdaptiveSystem_S);
          Free($3);
        }
     ;
    
     TimeLoopAdaptivePOs :
        /* none */
        {
          $$ = List_Create(4, 4, sizeof(struct LoopErrorPostOperation));
        }
    
      | TimeLoopAdaptivePOs '{' String__Index ',' FExpr ',' FExpr  ',' tSTRING '}'
        {
          TimeLoopAdaptivePO_S.PostOperationName = $3;
          TimeLoopAdaptivePO_S.PostOperationReltol = $5;
          TimeLoopAdaptivePO_S.PostOperationAbstol = $7;
          TimeLoopAdaptivePO_S.NormType = Get_DefineForString(ErrorNorm_Type, $9, &FlagError);
          if(FlagError){
            Get_Valid_SXD($9, ErrorNorm_Type);
            vyyerror(0, "Unknown error norm type of TimeLoopAdaptive PostOperation %s", $3);
          }
          TimeLoopAdaptivePO_S.NormTypeString = $9;
          List_Add($$ = $1, &TimeLoopAdaptivePO_S);
        }
     ;
    
    IterativeLoopDefinitions :
        /* none */
        {
          Operation_P = (struct Operation*)
            List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.IterativeLoopSystems_L = NULL;
          Operation_P->Case.IterativeLoop.IterativeLoopPOs_L = NULL;
        }
    
      | IterativeLoopDefinitions tDefineSystem '{' IterativeLoopSystems '}'
        {
          Operation_P->Case.IterativeLoop.IterativeLoopSystems_L = $4;
        }
    
      | IterativeLoopDefinitions tPostOperation '{' IterativeLoopPOs '}'
        {
          Operation_P->Case.IterativeLoop.IterativeLoopPOs_L = $4;
        }
    
     ;
    
    
     IterativeLoopSystems :
         /* none */
        {
          $$ = List_Create(4, 4, sizeof(struct IterativeLoopSystem));
        }
    
      | IterativeLoopSystems '{' String__Index ',' FExpr ',' FExpr  ',' tSTRING  tSTRING '}'
        {
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $3, fcmp_DefineSystem_Name)) < 0)
            vyyerror(0, "Unknown System: %s", $3);
          IterativeLoopSystem_S.SystemIndex = i;
          IterativeLoopSystem_S.SystemILreltol = $5;
          IterativeLoopSystem_S.SystemILabstol = $7;
          IterativeLoopSystem_S.NormOf = Get_DefineForString(NormOf_Type, $9, &FlagError);
          if(FlagError){
            Get_Valid_SXD($3, ChangeOfState_Type);
            vyyerror(0, "Unknown object for error norm of IterativeLoop system: %s", $3);
          }
          IterativeLoopSystem_S.NormOfString = $9;
          IterativeLoopSystem_S.NormType = Get_DefineForString(ErrorNorm_Type, $10, &FlagError);
          if(FlagError){
            Get_Valid_SXD($10, ErrorNorm_Type);
            vyyerror(0, "Unknown error norm type of IterativeLoop system: %s", $3);
          }
          IterativeLoopSystem_S.NormTypeString = $10;
          List_Add($$ = $1, &IterativeLoopSystem_S);
          Free($3);
        }
     ;
    
    
     IterativeLoopPOs :
        /* none */
        {
          $$ = List_Create(4, 4, sizeof(struct LoopErrorPostOperation));
        }
    
      | IterativeLoopPOs '{' String__Index ',' FExpr ',' FExpr  ',' tSTRING '}'
        {
          IterativeLoopPO_S.PostOperationName = $3;
          IterativeLoopPO_S.PostOperationReltol = $5;
          IterativeLoopPO_S.PostOperationAbstol = $7;
          IterativeLoopPO_S.NormType = Get_DefineForString(ErrorNorm_Type, $9, &FlagError);
          if(FlagError){
            Get_Valid_SXD($9, ErrorNorm_Type);
            vyyerror(0, "Unknown error norm type of IterativeLoopN PostOperation %s", $3);
          }
          IterativeLoopPO_S.NormTypeString = $9;
          List_Add($$ = $1, &IterativeLoopPO_S);
        }
     ;
    
    
    /* ------ the following should disapear with the new syntax ------------- */
    
    TimeLoopTheta :
    
        /* none */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.Time0   = 0.;
          Operation_P->Case.TimeLoopTheta.TimeMax = 1.;
          Operation_P->Case.TimeLoopTheta.DTimeIndex = -1;
          Operation_P->Case.TimeLoopTheta.ThetaIndex = -1;
          Operation_P->Case.TimeLoopTheta.Operation = NULL;
        }
    
      | TimeLoopTheta TimeLoopThetaTerm
     ;
    
    
    TimeLoopThetaTerm :
    
        tTime0 FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.Time0   = $2; }
      | tTimeMax FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.TimeMax = $2; }
      | tDTime Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.DTimeIndex = $2; }
      | tTheta Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.ThetaIndex = $2; }
    
      | tOperation  '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopTheta.Operation = $3;
        }
     ;
    
    
    TimeLoopNewmark :
    
        /* none */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.Time0   = 0.;
          Operation_P->Case.TimeLoopNewmark.TimeMax = 1.;
          Operation_P->Case.TimeLoopNewmark.DTimeIndex = -1;
          Operation_P->Case.TimeLoopNewmark.Beta   = 0.25;
          Operation_P->Case.TimeLoopNewmark.Gamma  = 0.5;
          Operation_P->Case.TimeLoopNewmark.Operation = NULL;
        }
    
      | TimeLoopNewmark TimeLoopNewmarkTerm
     ;
    
    
    TimeLoopNewmarkTerm :
    
        tTime0 FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.Time0   = $2; }
      | tTimeMax FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.TimeMax = $2; }
      | tDTime Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.DTimeIndex = $2; }
      | tBeta FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.Beta   = $2; }
      | tGamma FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.Gamma   = $2; }
    
      | tOperation  '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.TimeLoopNewmark.Operation = $3;
        }
     ;
    
    
    IterativeLoop :
    
        /* none */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.NbrMaxIteration  = 20;
          Operation_P->Case.IterativeLoop.Criterion = 1.e-3;
          Operation_P->Case.IterativeLoop.RelaxationFactorIndex = -1;
          Operation_P->Case.IterativeLoop.Flag = 0;
          Operation_P->Case.IterativeLoop.Operation = NULL;
        }
    
      | IterativeLoop IterativeLoopTerm
     ;
    
    IterativeLoopTerm :
    
        tNbrMaxIteration FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.NbrMaxIteration = (int)$2; }
      | tCriterion FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.Criterion = $2; }
      | tRelaxationFactor Expression tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.RelaxationFactorIndex = $2; }
      | tFlag FExpr tEND  /* Attention: phase test */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.Flag = (int)$2; }
      | tOperation  '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeLoop.Operation = $3;
        }
     ;
    
    
    IterativeTimeReduction :
    
        /* none */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.NbrMaxIteration     = 20;
          Operation_P->Case.IterativeTimeReduction.DivisionCoefficient = 2.;
          Operation_P->Case.IterativeTimeReduction.Criterion           = 1.e-3;
          Operation_P->Case.IterativeTimeReduction.Flag                = 0;
          Current_System = Operation_P->DefineSystemIndex              = -1;
          Operation_P->Case.IterativeTimeReduction.ChangeOfState       = NULL;
          Operation_P->Case.IterativeTimeReduction.Operation           = NULL;
          Operation_P->Case.IterativeTimeReduction.OperationEnd        = NULL;
        }
    
      | IterativeTimeReduction IterativeTimeReductionTerm
     ;
    
    IterativeTimeReductionTerm :
    
        tNbrMaxIteration FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.NbrMaxIteration = (int)$2; }
      | tDivisionCoefficient FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.DivisionCoefficient = $2; }
      | tCriterion FExpr tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.Criterion = $2; }
      | tFlag FExpr tEND  /* Attention: phase test */
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.Flag = (int)$2; }
    
      | tDefineSystem String__Index tEND
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          int i;
          if((i = List_ISearchSeq(Resolution_S.DefineSystem, $2,
    			       fcmp_DefineSystem_Name)) < 0)
    	vyyerror(0, "Unknown System: %s", $2);
          Free($2);
          Current_System = Operation_P->DefineSystemIndex = i;
        }
    
      | tChangeOfState  '{' ChangeOfStates '}'
        { Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.ChangeOfState = $3;
        }
    
      | tOperation  '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.Operation = $3;
        }
      | tOperationEnd  '{' Operation '}'
        { List_Pop(Operation_L);
          Operation_P = (struct Operation*)
    	List_Pointer(Operation_L, List_Nbr(Operation_L)-1);
          Operation_P->Case.IterativeTimeReduction.OperationEnd = $3;
        }
     ;
    
    
    ChangeOfStates :
        /* none */
        { $$ = List_Create(3, 3, sizeof (struct ChangeOfState)); }
    
      | ChangeOfStates '{' ChangeOfState '}'
        { List_Add($$ = $1, &ChangeOfState_S); }
     ;
    
    ChangeOfState :
        /* none */
        {
          ChangeOfState_S.Type = CHANGEOFSTATE_CHANGESIGN;
          ChangeOfState_S.QuantityIndex       = -1;
          ChangeOfState_S.FormulationIndex    = -1;
          ChangeOfState_S.InIndex             = -1;
          ChangeOfState_S.Criterion           = 1.e-2;
          ChangeOfState_S.ExpressionIndex = ChangeOfState_S.ExpressionIndex2 = -1;
          ChangeOfState_S.FlagIndex           = -1;
          ChangeOfState_S.ActiveList[0]       = NULL;
          ChangeOfState_S.ActiveList[1]       = NULL;
        }
    
      | ChangeOfState  ChangeOfStateTerm
     ;
    
    ChangeOfStateTerm :
    
        tType tSTRING tEND
        { ChangeOfState_S.Type =
    	Get_DefineForString(ChangeOfState_Type, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, ChangeOfState_Type);
    	vyyerror(0, "Unknown type of ChangeOfState: %s", $2);
          }
          Free($2);
        }
    
      | tQuantity tSTRING tEND
        {
          if(Current_System >= 0) {
    	List_T *ListOfInt_Lnew =
    	  ((struct DefineSystem *)List_Pointer(Resolution_S.DefineSystem,
    					       Current_System))->FormulationIndex;
    	int *ListOfInt_P =(int *)List_Pointer(ListOfInt_Lnew, 0);
    	int i = 0, j;
    	for(j = 0; j < List_Nbr(ListOfInt_Lnew); j++) {
    	  Formulation_S.DefineQuantity =
    	    ((struct Formulation *)
    	     List_Pointer(Problem_S.Formulation, ListOfInt_P[j]))->DefineQuantity;
    	  if((i = List_ISearchSeq(Formulation_S.DefineQuantity, $2,
    				   fcmp_DefineQuantity_Name)) >= 0)
    	    break;
    	}
    	if(j<List_Nbr(ListOfInt_Lnew)) {
    	  ChangeOfState_S.FormulationIndex = ListOfInt_P[j];
    	  ChangeOfState_S.QuantityIndex = i;
    	}
    	else
    	  vyyerror(0, "Unknown discrete Quantity: %s", $2);
          }
          else
    	vyyerror(0, "System undefined for Quantity: %s", $2);
          Free($2);
        }
    
      | tIn GroupRHS tEND
      { ChangeOfState_S.InIndex = Num_Group(&Group_S, (char*)"OP_In", $2); }
    
      | tCriterion FExpr tEND
        { ChangeOfState_S.Criterion = $2; }
    
      | tFunction Expression tEND
        {
          if(ChangeOfState_S.ExpressionIndex < 0)
    	ChangeOfState_S.ExpressionIndex = $2;
          else
    	ChangeOfState_S.ExpressionIndex2 = $2;
        }
    
      | tFlag tSTRING tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Expression, $2, fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Unknown name of expression for Flag: %s", $2);
          Free($2);
          ChangeOfState_S.FlagIndex = i;
        }
     ;
    
    /* ------ end of "the following should disapear with the new syntax" ------ */
    
    
    /* ------------------------------------------------------------------------ */
    /*  P o s t P r o c e s s i n g                                             */
    /* ------------------------------------------------------------------------ */
    
    PostProcessings :
        /* none */
        {
          if(!Problem_S.PostProcessing)
    	Problem_S.PostProcessing =
    	  List_Create(10, 5, sizeof (struct PostProcessing));
        }
    
      | PostProcessings  BracedPostProcessing
     ;
    
    BracedPostProcessing :
    
        '{' PostProcessing '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.PostProcessing, index_Append, &PostProcessing_S);
          else
            List_Add(Problem_S.PostProcessing, &PostProcessing_S);
        }
    
      | Loop
     ;
    
    PostProcessing :
        /* none */
        {
          PostProcessing_S.Name = NULL;
          PostProcessing_S.FormulationIndex = -1;
          PostProcessing_S.OriginSystemIndex = NULL;
          PostProcessing_S.NameOfSystem = NULL;
          PostProcessing_S.PostQuantity = NULL;
          level_Append = 0;
        }
    
      | PostProcessing  PostProcessingTerm
    
      | PostProcessing  Loop
     ;
    
    PostProcessingTerm :
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("PostProcessing", Problem_S.PostProcessing,
                                    $2, fcmp_PostProcessing_Name, level_Append);
          if (index_Append<0)
            PostProcessing_S.Name = $2;
          else{
            List_Read(Problem_S.PostProcessing, index_Append, &PostProcessing_S);
            Free($2);
          }
        }
    
      | tNameOfFormulation String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.Formulation, $2,
    			       fcmp_Formulation_Name)) < 0){
    	vyyerror(0, "Unknown Formulation: %s", $2);
          }
          else {
    	PostProcessing_S.FormulationIndex = i;
    	List_Read(Problem_S.Formulation, i, &Formulation_S);
          }
          Free($2);
        }
    
      | tNameOfSystem String__Index tEND
        {
          PostProcessing_S.NameOfSystem = $2;
        }
    
      | tQuantity  '{' PostQuantities '}'
     ;
    
    
    PostQuantities :
        /* none */
        {
          if (!PostProcessing_S.PostQuantity)
            PostProcessing_S.PostQuantity =
              List_Create(6, 6, sizeof (struct PostQuantity));
        }
    
      | PostQuantities '{' PostQuantity '}'
        {
          if (level_Append_2 && index_Append_2>=0)
            List_Write(PostProcessing_S.PostQuantity, index_Append_2, &PostQuantity_S);
          else
            List_Add(PostProcessing_S.PostQuantity, &PostQuantity_S);
        }
    
      | PostQuantities  Loop
     ;
    
    PostQuantity :
        /* none */
        {
          PostQuantity_S.Name = NULL;
          PostQuantity_S.PostQuantityTerm = NULL;
          level_Append_2 = (level_Append)? level_Append-1 : 0;
          index_Append_2 = -1;
        }
    
      | PostQuantity PostQuantityTerm
     ;
    
    
    PostQuantityTerm :
        Append tEND
        {
          level_Append_2 = $1; index_Append_2 = -1;
        }
    
      | tName String__Index tEND
        {
          index_Append_2 =
            Check_NameOfStructExist("PostQuantity", PostProcessing_S.PostQuantity,
                                    $2, fcmp_PostQuantity_Name, level_Append_2);
          if (index_Append_2<0)
            PostQuantity_S.Name = $2;
          else{
            List_Read(PostProcessing_S.PostQuantity, index_Append_2, &PostQuantity_S);
            Free($2);
          }
        }
    
      | tValue '{' SubPostQuantities '}'
        { PostQuantity_S.PostQuantityTerm = $3; }
    
     ;
    
    SubPostQuantities :
        /* none */
        {
          $$ = PostQuantity_S.PostQuantityTerm?
            PostQuantity_S.PostQuantityTerm :
            List_Create(5, 5, sizeof (struct PostQuantityTerm));
    
          if (level_Append_2 < 0)
            for(int i=0; i<-level_Append_2; i++)
              List_Pop(PostQuantity_S.PostQuantityTerm);
              //+++ TODO: to be refined for clean delete of existing data
        }
    
        /* Doit rester tant qu'on ne supprime pas l'association 'Integral <-> tGalerkin' */
      | SubPostQuantities tGalerkin '{' SubPostQuantity '}'
        {
          PostQuantityTerm_S.EvaluationType = INTEGRAL;
          List_Add($$ = $1, &PostQuantityTerm_S);
        }
    
      | SubPostQuantities tSTRING '{' SubPostQuantity '}'
        {
          PostQuantityTerm_S.EvaluationType =
    	Get_DefineForString(PostQuantityTerm_EvaluationType, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, PostQuantityTerm_EvaluationType);
    	vyyerror(0, "Unknown EvaluationType for PostQuantityTerm: %s", $2);
          }
          Free($2);
          List_Add($$ = $1, &PostQuantityTerm_S);
        }
    
      | SubPostQuantities Loop
        { $$ = $1 ; }
     ;
    
    SubPostQuantity :
        /* none */
        {
          PostQuantityTerm_S.Type = 0;
          PostQuantityTerm_S.TypeTimeDerivative = NODT_;
          PostQuantityTerm_S.WholeQuantity = NULL;
          PostQuantityTerm_S.InIndex = -1;
          PostQuantityTerm_S.SubRegion = -1;
          PostQuantityTerm_S.JacobianMethodIndex = -1;
          PostQuantityTerm_S.IntegrationMethodIndex = -1;
        }
    
      | SubPostQuantity SubPostQuantityTerm
     ;
    
    SubPostQuantityTerm :
        TermOperator '['
        {
          PostQuantityTerm_S.TypeTimeDerivative = Type_TermOperator;
          Current_DofIndexInWholeQuantity = -2;
          List_Reset(ListOfPointer_L);
        }
    
        WholeQuantityExpression ']' tEND
        { PostQuantityTerm_S.WholeQuantity = $4;
    
          Pro_DefineQuantityIndex
    	(PostQuantityTerm_S.WholeQuantity, -1,
    	 &PostQuantityTerm_S.NbrQuantityIndex,
    	 &PostQuantityTerm_S.QuantityIndexTable,
    	 &PostQuantityTerm_S.QuantityTraceGroupIndexTable);
          if(!PostQuantityTerm_S.Type) {
    	PostQuantityTerm_S.Type = 0;
    	for(int i = 0; i < PostQuantityTerm_S.NbrQuantityIndex; i++) {
    	  int j = -1;
    	  if(PostQuantityTerm_S.QuantityIndexTable[i] >= 0)
    	    j = ((struct DefineQuantity *)
    		 List_Pointer
    		 (((struct Formulation *)
    		   List_Pointer(Problem_S.Formulation,
    				PostProcessing_S.FormulationIndex))->DefineQuantity,
    		  PostQuantityTerm_S.QuantityIndexTable[i])) -> Type;
    	  if(PostQuantityTerm_S.Type == 0)
    	    PostQuantityTerm_S.Type = j;
    	  else if(PostQuantityTerm_S.Type != j)
    	    vyyerror(0, "Mixed discrete Quantity types in term (should be split in separate terms)");
    	}
    	if(PostQuantityTerm_S.Type == 0)  PostQuantityTerm_S.Type = LOCALQUANTITY;
          }
    
        }
    
     | tType tSTRING tEND
       { /* force the Type */
         PostQuantityTerm_S.Type =
           Get_DefineForString(DefineQuantity_Type, $2, &FlagError);
         if(FlagError){
           Get_Valid_SXD($2, DefineQuantity_Type);
           vyyerror(0, "Unknown type of Operation: %s", $2);
         }
         Free($2);
       }
    
     | tIn GroupRHS tEND
       {
         PostQuantityTerm_S.InIndex = Num_Group(&Group_S, (char*)"PQ_In", $2);
       }
    
      | tSubRegion GroupRHS tEND
        {
          PostQuantityTerm_S.SubRegion = Num_Group(&Group_S, (char*)"PQ_SR", $2);
        }
    
      | tJacobian String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.JacobianMethod, $2,
    			       fcmp_JacobianMethod_Name)) < 0)
    	vyyerror(0, "Unknown Jacobian method: %s",$2);
          else
    	PostQuantityTerm_S.JacobianMethodIndex = i;
          Free($2);
        }
    
      | tIntegration String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.IntegrationMethod, $2,
    			       fcmp_IntegrationMethod_Name)) < 0)
    	vyyerror(0, "Unknown Integration method: %s",$2);
          else
    	PostQuantityTerm_S.IntegrationMethodIndex = i;
          Free($2);
        }
    
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  P o s t O p e r a t i o n                                               */
    /* ------------------------------------------------------------------------ */
    
    PostOperations :
        /* none */
        {
          if(!Problem_S.PostOperation)
    	Problem_S.PostOperation =
    	  List_Create(10, 5, sizeof (struct PostOperation));
        }
    
      | PostOperations  BracedPostOperation
     ;
    
    BracedPostOperation :
    
        '{' PostOperation '}'
        {
          if (level_Append && index_Append>=0)
            List_Write(Problem_S.PostOperation, index_Append, &PostOperation_S);
          else
            List_Add(Problem_S.PostOperation, &PostOperation_S);
        }
    
      | Loop
     ;
    
    PostOperation :
        /* none */
        {
          PostOperation_S.Name = NULL;
          PostOperation_S.Hidden = false;
          PostOperation_S.Format = FORMAT_GMSH;
          PostOperation_S.PostProcessingIndex = -1;
          PostOperation_S.ResampleTime = false;
          PostOperation_S.TimeValue_L = NULL;
          PostOperation_S.TimeImagValue_L = NULL;
          PostOperation_S.LastTimeStepOnly = 0;
          PostOperation_S.OverrideTimeStepValue = -1;
          PostOperation_S.NoMesh = 0;
          PostOperation_S.CatFile = 0;
          PostOperation_S.PostSubOperation = NULL;
          level_Append = 0;
        }
    
      | PostOperation  PostOperationTerm
     ;
    
    PostOperationTerm :
        Append tEND
        { level_Append = $1; index_Append = -1; }
    
      | tName String__Index tEND
        {
          index_Append =
            Check_NameOfStructExist("PostOperation", Problem_S.PostOperation,
                                    $2, fcmp_PostOperation_Name, level_Append);
          if (index_Append<0)
            PostOperation_S.Name = $2;
          else{
            List_Read(Problem_S.PostOperation, index_Append, &PostOperation_S);
            Free($2);
          }
        }
    
      | tHidden FExpr tEND { PostOperation_S.Hidden = $2 ? true : false; }
    
      | tNameOfPostProcessing String__Index tEND
        {
          int i;
          if((i = List_ISearchSeq(Problem_S.PostProcessing, $2,
    			       fcmp_PostProcessing_Name)) < 0)
    	vyyerror(0, "Unknown PostProcessing: %s", $2);
          else {
    	PostOperation_S.PostProcessingIndex = i;
    	List_Read(Problem_S.PostProcessing, i, &InteractivePostProcessing_S);
          }
          Free($2);
        }
    
      | tFormat tSTRING tEND
        {
          PostOperation_S.Format =
    	Get_DefineForString(PostSubOperation_Format, $2, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($2, PostSubOperation_Format);
    	vyyerror(0, "Unknown PostProcessing Format: %s", $2);
          }
          Free($2);
        }
    
      | tTimeValue ListOfFExpr tEND
        {
          PostOperation_S.TimeValue_L = $2;
        }
    
      | tTimeImagValue ListOfFExpr tEND
        {
          PostOperation_S.TimeImagValue_L = $2;
        }
    
      | tLastTimeStepOnly tEND
        {
          PostOperation_S.LastTimeStepOnly = 1;
        }
    
      | tLastTimeStepOnly FExpr tEND
        {
          PostOperation_S.LastTimeStepOnly = (int)$2;
        }
    
      | tAppendToExistingFile FExpr tEND
        {
          PostOperation_S.CatFile = $2;
        }
    
      | tNoMesh FExpr tEND
        {
          PostOperation_S.NoMesh = $2;
        }
    
      | tOverrideTimeStepValue FExpr tEND
        {
          PostOperation_S.OverrideTimeStepValue = $2;
        }
    
      | tResampleTime '[' FExpr ',' FExpr ',' FExpr ']' tEND
        {
          PostOperation_S.ResampleTime = true;
          PostOperation_S.ResampleTimeStart = $3;
          PostOperation_S.ResampleTimeStop = $5;
          PostOperation_S.ResampleTimeStep = $7;
        }
    
      | tOperation  '{' PostSubOperations '}'
        {
          PostOperation_S.PostSubOperation = $3;
        }
    
      | Loop
     ;
    
    
    SeparatePostOperation :
        tPostOperation AppendOrNot String__Index tUsingPost String__Index
        {
          PostOperation_S.Hidden = false;
          PostOperation_S.Format = FORMAT_GMSH;
          PostOperation_S.PostProcessingIndex = -1;
          PostOperation_S.ResampleTime = false;
          PostOperation_S.TimeValue_L = NULL;
          PostOperation_S.TimeImagValue_L = NULL;
          PostOperation_S.LastTimeStepOnly = 0;
          PostOperation_S.OverrideTimeStepValue = -1;
          PostOperation_S.NoMesh = 0;
          PostOperation_S.CatFile = 0;
          PostOperation_S.PostSubOperation = NULL;
          level_Append = $2; index_Append = -1;
          int i;
          if((i = List_ISearchSeq(Problem_S.PostProcessing, $5,
    			       fcmp_PostProcessing_Name)) < 0)
    	vyyerror(0, "Unknown PostProcessing: %s", $5);
          else {
    	PostOperation_S.PostProcessingIndex = i;
    	List_Read(Problem_S.PostProcessing, i, &InteractivePostProcessing_S);
    	if(!Problem_S.PostOperation)
    	  Problem_S.PostOperation = List_Create(5, 5, sizeof (struct PostOperation));
    
            index_Append =
              Check_NameOfStructExist("PostOperation", Problem_S.PostOperation,
                                      $3, fcmp_PostOperation_Name, level_Append);
            if (index_Append<0)
              PostOperation_S.Name = $3;
            else{
              List_Read(Problem_S.PostOperation, index_Append, &PostOperation_S);
              Free($3);
            }
          }
          Free($5);
        }
        '{' PostSubOperations '}'
        {
          if(!PostOperation_S.PostSubOperation) PostOperation_S.PostSubOperation = $8;
          if(PostOperation_S.PostProcessingIndex >= 0){
            if (level_Append && index_Append>=0)
              List_Write(Problem_S.PostOperation, index_Append, &PostOperation_S);
            else
              List_Add(Problem_S.PostOperation, &PostOperation_S);
          }
        }
     ;
    
    
    PostSubOperations :
        /* none */
        {
          $$ =
            PostOperation_S.PostSubOperation?
            PostOperation_S.PostSubOperation :
            List_Create(5, 5, sizeof (struct PostSubOperation));
        }
    
      | PostSubOperations
        {
          PostSubOperation_S.Format = -1;
          PostSubOperation_S.FileOut = NULL;
          PostSubOperation_S.Depth = 1;
          PostSubOperation_S.Smoothing = 0;
          PostSubOperation_S.Skin = 0;
          PostSubOperation_S.Comma = 0;
          PostSubOperation_S.Dimension = _ALL;
          PostSubOperation_S.Adapt = 0;
          PostSubOperation_S.Target = -1.;
          PostSubOperation_S.HarmonicToTime = 1;
          PostSubOperation_S.TimeToHarmonic = 0;
          PostSubOperation_S.FourierTransform = 0;
          PostSubOperation_S.FrozenTimeStepList = 0;
          PostSubOperation_S.TimeStep_L = List_Create(10,10,sizeof(int));;
          PostSubOperation_S.Frequency_L = List_Create(10,10,sizeof(double));;
          PostSubOperation_S.Value_L = List_Create(10,10,sizeof(double));;
          PostSubOperation_S.Iso = 0;
          PostSubOperation_S.Iso_L = List_Create(10,10,sizeof(double));;
          PostSubOperation_S.Sort = 0;
          PostSubOperation_S.NoNewLine = 0;
          PostSubOperation_S.NoTitle = 0;
          PostSubOperation_S.DecomposeInSimplex = 0;
          PostSubOperation_S.NewCoordinates = 0;
          PostSubOperation_S.NewCoordinatesFile = NULL;
          PostSubOperation_S.ChangeOfCoordinates[0] = -1;
          PostSubOperation_S.ChangeOfCoordinates[1] = -1;
          PostSubOperation_S.ChangeOfCoordinates[2] = -1;
          PostSubOperation_S.ChangeOfValues = NULL;
          PostSubOperation_S.Legend = LEGEND_NONE;
          PostSubOperation_S.LegendPosition[0] = 0.;
          PostSubOperation_S.LegendPosition[1] = 0.;
          PostSubOperation_S.LegendPosition[2] = 0.;
          PostSubOperation_S.EvaluationPoints = NULL;
          PostSubOperation_S.StoreInVariable = NULL;
          PostSubOperation_S.StoreInRegister = -1;
          PostSubOperation_S.StoreMinInRegister = -1;
          PostSubOperation_S.StoreMinXinRegister = -1;
          PostSubOperation_S.StoreMinYinRegister = -1;
          PostSubOperation_S.StoreMinZinRegister = -1;
          PostSubOperation_S.StoreMaxInRegister = -1;
          PostSubOperation_S.StoreMaxXinRegister = -1;
          PostSubOperation_S.StoreMaxYinRegister = -1;
          PostSubOperation_S.StoreMaxZinRegister = -1;
          PostSubOperation_S.StoreInField = -1;
          PostSubOperation_S.StoreInMeshBasedField = -1;
          PostSubOperation_S.LastTimeStepOnly = 0;
          PostSubOperation_S.AppendTimeStepToFileName = 0;
          PostSubOperation_S.AppendExpressionToFileName = -1;
          PostSubOperation_S.AppendExpressionFormat = NULL;
          PostSubOperation_S.AppendStringToFileName = NULL;
          PostSubOperation_S.OverrideTimeStepValue = -1;
          PostSubOperation_S.NoMesh = 0;
          PostSubOperation_S.CatFile = 0;
          PostSubOperation_S.SendToServer = NULL;
          PostSubOperation_S.SendToServerList = NULL;
          PostSubOperation_S.Color = NULL;
          PostSubOperation_S.Units = NULL;
          PostSubOperation_S.Visible = true;
          PostSubOperation_S.Closed = false;
          PostSubOperation_S.ValueIndex = 0;
          PostSubOperation_S.ValueName = NULL;
          PostSubOperation_S.Label = NULL;
          PostSubOperation_S.TimeValue_L = NULL;
          PostSubOperation_S.TimeImagValue_L = NULL;
          PostSubOperation_S.TimeInterval_Flag = 0;
          PostSubOperation_S.TimeInterval[0] = 0.;
          PostSubOperation_S.TimeInterval[1] = 0.;
         }
        PostSubOperation
        {
          if(PostSubOperation_S.Type != POP_NONE) {
    	if(PostSubOperation_S.Format < 0)
    	  PostSubOperation_S.Format = PostOperation_S.Format;
    	if(!PostSubOperation_S.TimeValue_L)
              PostSubOperation_S.TimeValue_L = PostOperation_S.TimeValue_L;
    	if(!PostSubOperation_S.TimeImagValue_L)
              PostSubOperation_S.TimeImagValue_L = PostOperation_S.TimeImagValue_L;
    	if(!PostSubOperation_S.LastTimeStepOnly)
              PostSubOperation_S.LastTimeStepOnly = PostOperation_S.LastTimeStepOnly;
    	if(!PostSubOperation_S.NoMesh)
              PostSubOperation_S.NoMesh = PostOperation_S.NoMesh;
    	if(PostSubOperation_S.OverrideTimeStepValue < 0)
              PostSubOperation_S.OverrideTimeStepValue = PostOperation_S.OverrideTimeStepValue;
    	if(!PostSubOperation_S.CatFile)
              PostSubOperation_S.CatFile = PostOperation_S.CatFile;
    
    	List_Add($$ = $1, &PostSubOperation_S);
          }
        }
     ;
    
    
    PostSubOperation :
    
        tPlot '[' PostQuantitiesToPrint PrintSubType PrintOptions ']' tEND
        {
          vyyerror(0, "Plot has been superseded by Print "
                   "(Plot OnRegion becomes Print OnElementsOf)");
        }
    
      | tPrint '[' PostQuantitiesToPrint PrintSubType PrintOptions ']' tEND
        {
          PostSubOperation_S.Type = POP_PRINT;
        }
    
      | tPrint '[' tBIGSTR ',' ListOfExpression PrintOptions ']' tEND
        {
          PostSubOperation_S.Type = POP_EXPRESSION;
          PostSubOperation_S.Case.Expression.String = $3;
          PostSubOperation_S.Case.Expression.String2 = strSave("unformatted");
          PostSubOperation_S.Case.Expression.Expressions = List_Copy(ListOfInt_L);
          PostSubOperation_S.PostQuantityIndex[0] = -1;
        }
    
      | tPrint '[' ListOfExpression ',' tFormat CharExpr PrintOptions ']' tEND
        {
          PostSubOperation_S.Type = POP_EXPRESSION;
          PostSubOperation_S.Case.Expression.String = $6;
          PostSubOperation_S.Case.Expression.String2 = NULL;
          PostSubOperation_S.Case.Expression.Expressions = List_Copy(ListOfInt_L);
          PostSubOperation_S.PostQuantityIndex[0] = -1;
        }
    
      | tPrint '[' tBIGSTR ',' tStr '[' CharExpr ']' PrintOptions ']' tEND
        {
          PostSubOperation_S.Type = POP_EXPRESSION;
          PostSubOperation_S.Case.Expression.String = $3;
          PostSubOperation_S.Case.Expression.String2 = $7;
          PostSubOperation_S.Case.Expression.Expressions = 0;
          PostSubOperation_S.PostQuantityIndex[0] = -1;
        }
    
      | tEcho '[' CharExpr PrintOptions ']' tEND
        {
          PostSubOperation_S.Type = POP_EXPRESSION;
          PostSubOperation_S.Case.Expression.String = $3;
          PostSubOperation_S.Case.Expression.String2 = NULL;
          PostSubOperation_S.Case.Expression.Expressions = 0;
          PostSubOperation_S.PostQuantityIndex[0] = -1;
        }
    
      | tPrintGroup '[' GroupRHS
        {
          PostSubOperation_S.Type = POP_GROUP;
          PostSubOperation_S.Case.Group.ExtendedGroupIndex =
            Num_Group(&Group_S, (char*)"PO_Group", $3);
          PostSubOperation_S.PostQuantityIndex[0] = -1;
        }
        ',' tIn GroupRHS PrintOptions ']' tEND
        {
          PostSubOperation_S.Case.Group.GroupIndex =
            Num_Group(&Group_S, (char*)"PO_Group", $7);
        }
    
      | tSendMergeFileRequest '[' CharExpr ']' tEND
        {
          PostSubOperation_S.Type = POP_MERGE;
          PostSubOperation_S.FileOut = $3;
        }
    
      | tDeleteFile '[' CharExpr ']' tEND
        {
          PostSubOperation_S.Type = POP_DELETEFILE;
          PostSubOperation_S.FileOut = $3;
        }
    
      | tCreateDir '[' CharExpr ']' tEND
        {
          PostSubOperation_S.Type = POP_CREATEDIR;
          PostSubOperation_S.FileOut = $3;
        }
    
      | Loop
        {
          PostSubOperation_S.Type = POP_NONE;
        }
    
     ;
    
    PostQuantitiesToPrint :
    
        String__Index PostQuantitySupport ','
        {
          int i;
          if((i = List_ISearchSeq(InteractivePostProcessing_S.PostQuantity, $1,
    			       fcmp_PostQuantity_Name)) < 0)
    	vyyerror(0, "Unknown PostProcessing Quantity: %s", $1);
          PostSubOperation_S.PostQuantityIndex[0] = i;
          PostSubOperation_S.PostQuantityIndex[1] = -1;
          PostSubOperation_S.PostQuantitySupport[0] = $2;
          PostSubOperation_S.PostQuantitySupport[1] = -1;
          Free($1);
        }
    
     |  String__Index  PostQuantitySupport Combination tSTRING  PostQuantitySupport ','
        {
          vyyerror(1, "Combined post-quantities are deprecated: use registers instead");
          int i;
          if((i = List_ISearchSeq(InteractivePostProcessing_S.PostQuantity, $1,
    			       fcmp_PostQuantity_Name)) < 0)
    	vyyerror(0, "Unknown PostProcessing Quantity: %s", $1);
          PostSubOperation_S.PostQuantityIndex[0] = i;
          PostSubOperation_S.PostQuantitySupport[0] = $2;
          int j = -1;
          if((j = List_ISearchSeq(InteractivePostProcessing_S.PostQuantity, $4,
    			       fcmp_PostQuantity_Name)) < 0)
    	vyyerror(0, "Unknown PostProcessing Quantity: %s", $4);
          PostSubOperation_S.PostQuantityIndex[1] = j;
          PostSubOperation_S.PostQuantitySupport[1] = $5;
    
          if(($2 < 0 && $5 < 0) || ($2 >= 0 && $5 >= 0)) {
    	vyyerror(0, "Postprocessing Quantities '%s' and '%s' of same type (%s)",
    		 $1, $4, ($2>0)? "with Support":"without Support");
          }
          Free($1); Free($4);
        }
     ;
    
    Combination :
    
        '*' { PostSubOperation_S.CombinationType = MULTIPLICATION; }
      | '/' { PostSubOperation_S.CombinationType = DIVISION; }
      | '+' { PostSubOperation_S.CombinationType = ADDITION; }
      | '-' { PostSubOperation_S.CombinationType = SOUSTRACTION; }
     ;
    
    PostQuantitySupport :
    
        /* none */
        { $$ = -1; }
      | '[' GroupRHS ']'
      { $$ = Num_Group(&Group_S, (char*)"PO_Support", $2); }
     ;
    
    PrintSubType :
    
        tOnGlobal
        {
          PostSubOperation_S.SubType = PRINT_ONREGION;
          PostSubOperation_S.Case.OnRegion.RegionIndex = -1;
        }
    
      | tOnRegion GroupRHS
        {
          PostSubOperation_S.SubType = PRINT_ONREGION;
          PostSubOperation_S.Case.OnRegion.RegionIndex =
    	Num_Group(&Group_S, (char*)"PO_OnRegion", $2);
        }
    
      | tOnElementsOf GroupRHS
        {
          PostSubOperation_S.SubType = PRINT_ONELEMENTSOF;
          PostSubOperation_S.Case.OnRegion.RegionIndex =
    	Num_Group(&Group_S, (char*)"PO_OnElementsOf", $2);
        }
    
      | tOnSection '{' '{' RecursiveListOfFExpr '}'
                       '{' RecursiveListOfFExpr '}'
                       '{' RecursiveListOfFExpr '}' '}'
        {
          PostSubOperation_S.SubType = PRINT_ONSECTION_2D;
          if(List_Nbr($4) != 3 || List_Nbr($7) != 3 || List_Nbr($10) != 3)
    	vyyerror(0, "Expected {3}{3}{3} coordinates, got {%d}{%d}{%d}",
    		 List_Nbr($4), List_Nbr($7), List_Nbr($10));
          else{
    	List_Read($4, 0, &PostSubOperation_S.Case.OnSection.x[0]);
    	List_Read($4, 1, &PostSubOperation_S.Case.OnSection.y[0]);
    	List_Read($4, 2, &PostSubOperation_S.Case.OnSection.z[0]);
    	List_Read($7, 0, &PostSubOperation_S.Case.OnSection.x[1]);
    	List_Read($7, 1, &PostSubOperation_S.Case.OnSection.y[1]);
    	List_Read($7, 2, &PostSubOperation_S.Case.OnSection.z[1]);
    	List_Read($10, 0, &PostSubOperation_S.Case.OnSection.x[2]);
    	List_Read($10, 1, &PostSubOperation_S.Case.OnSection.y[2]);
    	List_Read($10, 2, &PostSubOperation_S.Case.OnSection.z[2]);
          }
          List_Delete($4);
          List_Delete($7);
          List_Delete($10);
        }
    
      | tOnGrid GroupRHS
        {
          PostSubOperation_S.SubType = PRINT_ONGRID;
          PostSubOperation_S.Case.OnRegion.RegionIndex =
    	Num_Group(&Group_S, (char*)"PO_OnGrid", $2);
        }
    
      | tOnGrid '{' Expression ',' Expression ',' Expression '}'
                '{' ListOfFExpr ','  ListOfFExpr ','  ListOfFExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_ONGRID_PARAM;
          PostSubOperation_S.Case.OnParamGrid.ExpressionIndex[0] = $3;
          PostSubOperation_S.Case.OnParamGrid.ExpressionIndex[1] = $5;
          PostSubOperation_S.Case.OnParamGrid.ExpressionIndex[2] = $7;
          PostSubOperation_S.Case.OnParamGrid.ParameterValue[0] = $10;
          PostSubOperation_S.Case.OnParamGrid.ParameterValue[1] = $12;
          PostSubOperation_S.Case.OnParamGrid.ParameterValue[2] = $14;
        }
    
      | tOnPoint '{' RecursiveListOfFExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_ONGRID_0D;
          if(List_Nbr($3) != 3)
    	vyyerror(0, "Expected {3} coordinates, got {%d}", List_Nbr($3));
          else{
    	List_Read($3, 0, &PostSubOperation_S.Case.OnGrid.x[0]);
    	List_Read($3, 1, &PostSubOperation_S.Case.OnGrid.y[0]);
    	List_Read($3, 2, &PostSubOperation_S.Case.OnGrid.z[0]);
          }
          List_Delete($3);
        }
    
      | tOnLine '{' '{' RecursiveListOfFExpr '}'
                    '{' RecursiveListOfFExpr '}' '}'  '{' FExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_ONGRID_1D;
          if(List_Nbr($4) != 3 || List_Nbr($7) != 3)
    	vyyerror(0, "Expected {3}{3} coordinates, got {%d}{%d}",
    		 List_Nbr($4), List_Nbr($7));
          else{
    	List_Read($4, 0, &PostSubOperation_S.Case.OnGrid.x[0]);
    	List_Read($4, 1, &PostSubOperation_S.Case.OnGrid.y[0]);
    	List_Read($4, 2, &PostSubOperation_S.Case.OnGrid.z[0]);
    	List_Read($7, 0, &PostSubOperation_S.Case.OnGrid.x[1]);
    	List_Read($7, 1, &PostSubOperation_S.Case.OnGrid.y[1]);
    	List_Read($7, 2, &PostSubOperation_S.Case.OnGrid.z[1]);
          }
          PostSubOperation_S.Case.OnGrid.n[0] = (int)$11;
          List_Delete($4);
          List_Delete($7);
        }
    
      | tOnPlane '{' '{' RecursiveListOfFExpr '}'
                     '{' RecursiveListOfFExpr '}'
                     '{' RecursiveListOfFExpr '}' '}'  '{' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_ONGRID_2D;
          if(List_Nbr($4) != 3 || List_Nbr($7) != 3 || List_Nbr($10) != 3)
    	vyyerror(0, "Expected {3}{3}{3} coordinates, got {%d}{%d}{%d}",
    		 List_Nbr($4), List_Nbr($7), List_Nbr($10));
          else{
    	List_Read($4, 0, &PostSubOperation_S.Case.OnGrid.x[0]);
    	List_Read($4, 1, &PostSubOperation_S.Case.OnGrid.y[0]);
    	List_Read($4, 2, &PostSubOperation_S.Case.OnGrid.z[0]);
    	List_Read($7, 0, &PostSubOperation_S.Case.OnGrid.x[1]);
    	List_Read($7, 1, &PostSubOperation_S.Case.OnGrid.y[1]);
    	List_Read($7, 2, &PostSubOperation_S.Case.OnGrid.z[1]);
    	List_Read($10, 0, &PostSubOperation_S.Case.OnGrid.x[2]);
    	List_Read($10, 1, &PostSubOperation_S.Case.OnGrid.y[2]);
    	List_Read($10, 2, &PostSubOperation_S.Case.OnGrid.z[2]);
          }
          PostSubOperation_S.Case.OnGrid.n[0] = (int)$14;
          PostSubOperation_S.Case.OnGrid.n[1] = (int)$16;
          List_Delete($4);
          List_Delete($7);
          List_Delete($10);
        }
    
      | tOnBox '{' '{' RecursiveListOfFExpr '}'
                   '{' RecursiveListOfFExpr '}'
                   '{' RecursiveListOfFExpr '}'
                   '{' RecursiveListOfFExpr '}' '}'  '{' FExpr ',' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_ONGRID_3D;
          if(List_Nbr($4) != 3 || List_Nbr($7) != 3 ||
    	 List_Nbr($10) != 3 || List_Nbr($13) != 3)
    	vyyerror(0, "Expected {3}{3}{3}{3} coordinates, got {%d}{%d}{%d}{%d}",
    		 List_Nbr($4), List_Nbr($7), List_Nbr($10), List_Nbr($13));
          else{
    	List_Read($4, 0, &PostSubOperation_S.Case.OnGrid.x[0]);
    	List_Read($4, 1, &PostSubOperation_S.Case.OnGrid.y[0]);
    	List_Read($4, 2, &PostSubOperation_S.Case.OnGrid.z[0]);
    	List_Read($7, 0, &PostSubOperation_S.Case.OnGrid.x[1]);
    	List_Read($7, 1, &PostSubOperation_S.Case.OnGrid.y[1]);
    	List_Read($7, 2, &PostSubOperation_S.Case.OnGrid.z[1]);
    	List_Read($10, 0, &PostSubOperation_S.Case.OnGrid.x[2]);
    	List_Read($10, 1, &PostSubOperation_S.Case.OnGrid.y[2]);
    	List_Read($10, 2, &PostSubOperation_S.Case.OnGrid.z[2]);
    	List_Read($13, 0, &PostSubOperation_S.Case.OnGrid.x[3]);
    	List_Read($13, 1, &PostSubOperation_S.Case.OnGrid.y[3]);
    	List_Read($13, 2, &PostSubOperation_S.Case.OnGrid.z[3]);
          }
          PostSubOperation_S.Case.OnGrid.n[0] = (int)$17;
          PostSubOperation_S.Case.OnGrid.n[1] = (int)$19;
          PostSubOperation_S.Case.OnGrid.n[2] = (int)$21;
          List_Delete($4);
          List_Delete($7);
          List_Delete($10);
          List_Delete($13);
        }
    
      /* should be generalized with a '{' RecursiveListOfFExpr '}' */
      | tOnRegion GroupRHS
        tWithArgument tSTRING '{' FExpr ',' FExpr '}'  '{' FExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_WITHARGUMENT;
    
          PostSubOperation_S.Case.WithArgument.RegionIndex =
    	Num_Group(&Group_S, (char*)"PO_On", $2);
          int i;
    
          if((i = List_ISearchSeq(Problem_S.Expression, $4, fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Unknown Name of Expression: %s", $4);
          Free($4);
    
          PostSubOperation_S.Case.WithArgument.ArgumentIndex = i;
          PostSubOperation_S.Case.WithArgument.x[0] = $6;
          PostSubOperation_S.Case.WithArgument.x[1] = $8;
          PostSubOperation_S.Case.WithArgument.n = (int)$11;
        }
    
      /* Just one value given for interpolating a function */
      | tOnRegion GroupRHS
        tWithArgument tSTRING '{' FExpr '}'
        {
          PostSubOperation_S.SubType = PRINT_WITHARGUMENT;
    
          PostSubOperation_S.Case.WithArgument.RegionIndex =
    	Num_Group(&Group_S, (char*)"PO_On", $2);
          int i;
    
          if((i = List_ISearchSeq(Problem_S.Expression, $4, fcmp_Expression_Name)) < 0)
    	vyyerror(0, "Unknown Name of Expression: %s", $4);
          Free($4);
    
          PostSubOperation_S.Case.WithArgument.ArgumentIndex = i;
          PostSubOperation_S.Case.WithArgument.x[0] = $6;
          PostSubOperation_S.Case.WithArgument.x[1] = $6;
          PostSubOperation_S.Case.WithArgument.n = 0;
        }
     ;
    
    PrintOptions :
        /* none */
        {
        }
      | PrintOptions PrintOption
     ;
    
    PrintOption :
        ',' tFile CharExpr
        {
          PostSubOperation_S.FileOut = $3;
          PostSubOperation_S.CatFile = 0;
        }
      | ',' tFile '>' CharExpr
        {
          PostSubOperation_S.FileOut = $4;
          PostSubOperation_S.CatFile = 1;
        }
      | ',' tFile tGREATERGREATER CharExpr
        {
          PostSubOperation_S.FileOut = $4;
          PostSubOperation_S.CatFile = 2;
        }
      | ',' tAppendToExistingFile FExpr
        {
          PostSubOperation_S.CatFile = $3;
        }
      | ',' tDepth FExpr
        {
          PostSubOperation_S.Depth = (int)$3;
        }
      | ',' tSkin
        {
          PostSubOperation_S.Skin = 1;
        }
      | ',' tSmoothing
        {
          PostSubOperation_S.Smoothing = 1;
        }
      | ',' tSmoothing FExpr
        {
          PostSubOperation_S.Smoothing = (int)$3;
        }
      | ',' tHarmonicToTime FExpr
        {
          PostSubOperation_S.HarmonicToTime = (int)$3;
        }
      | ',' tTimeToHarmonic FExpr
        {
          PostSubOperation_S.TimeToHarmonic = (int)$3;
        }
      | ',' tCosineTransform
        {
          PostSubOperation_S.FourierTransform = 2;
        }
      | ',' tFourierTransform
        {
          PostSubOperation_S.FourierTransform = 1;
        }
      | ',' tFormat tSTRING
        {
          PostSubOperation_S.Format =
    	Get_DefineForString(PostSubOperation_Format, $3, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($3, PostSubOperation_Format);
    	vyyerror(0, "Unknown PostProcessing Format: %s", $3);
          }
          Free($3);
        }
      | ',' tComma
        {
          PostSubOperation_S.Comma = 1;
        }
      | ',' tValueIndex FExpr
        {
          PostSubOperation_S.ValueIndex = $3;
        }
      | ',' tValueName  CharExpr
        {
          PostSubOperation_S.ValueName = $3;
        }
      | ',' tName  CharExpr
        {
          PostSubOperation_S.Label = $3;
        }
      | ',' tDimension FExpr
        {
          if((int)$3 >= 1 && (int)$3 <= 3)
    	PostSubOperation_S.Dimension = (int)$3;
          else
    	vyyerror(0, "Wrong Dimension in Print");
        }
      | ',' tTimeStep ListOfFExpr
        {
          PostSubOperation_S.FrozenTimeStepList = 1;
          for(int i = 0; i < List_Nbr($3); i++){
    	double d;
    	List_Read($3,i,&d);
    	int j = (int)d;
    	List_Add(PostSubOperation_S.TimeStep_L, &j);
          }
          List_Delete($3);
        }
      | ',' tTimeValue ListOfFExpr
        {
          PostSubOperation_S.TimeValue_L = $3;
        }
      | ',' tTimeInterval '{' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.TimeInterval_Flag = 1;
          PostSubOperation_S.TimeInterval[0] = $4;
          PostSubOperation_S.TimeInterval[1] = $6;
        }
      | ',' tTimeImagValue ListOfFExpr
        {
          PostSubOperation_S.TimeImagValue_L = $3;
        }
      | ',' tAdapt tSTRING
        {
          PostSubOperation_S.Adapt =
    	Get_DefineForString(PostSubOperation_AdaptationType, $3, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($3, PostSubOperation_AdaptationType);
    	vyyerror(0, "Unknown Adaptation method: %s", $3);
          }
        }
      | ',' tSort tSTRING
        {
          PostSubOperation_S.Sort =
    	Get_DefineForString(PostSubOperation_SortType, $3, &FlagError);
          if(FlagError){
    	Get_Valid_SXD($3, PostSubOperation_SortType);
    	vyyerror(0, "Unknown Sort method: %s", $3);
          }
        }
      | ',' tTarget FExpr
        {
          if($3 >= 0.)
    	PostSubOperation_S.Target = $3;
          else
    	vyyerror(0, "Bad Target value");
        }
      | ',' tValue ListOfFExpr
        {
          for(int i = 0; i < List_Nbr($3); i++){
    	double d;
    	List_Read($3,i,&d);
    	List_Add(PostSubOperation_S.Value_L, &d);
          }
          List_Delete($3);
        }
      | ',' tIso FExpr
        {
          PostSubOperation_S.Iso = (int)$3;
        }
      | ',' tIso '{' RecursiveListOfFExpr '}'
        {
          PostSubOperation_S.Iso = -1;
          for(int i = 0; i < List_Nbr($4); i++){
    	double d;
    	List_Read($4,i,&d);
    	List_Add(PostSubOperation_S.Iso_L, &d);
          }
          List_Delete($4);
        }
      | ',' tNoNewLine
        {
          PostSubOperation_S.NoNewLine = 1;
        }
      | ',' tNoTitle
        {
          PostSubOperation_S.NoTitle = 1;
        }
      | ',' tDecomposeInSimplex
        {
          PostSubOperation_S.DecomposeInSimplex = 1;
        }
      | ',' tFrequency ListOfFExpr
        {
          for(int i = 0; i < List_Nbr($3); i++){
    	double d;
    	List_Read($3,i,&d);
    	List_Add(PostSubOperation_S.Frequency_L, &d);
          }
          List_Delete($3);
        }
      | ',' tChangeOfCoordinates '{' Expression ',' Expression ',' Expression '}'
        {
          PostSubOperation_S.ChangeOfCoordinates[0] = $4;
          PostSubOperation_S.ChangeOfCoordinates[1] = $6;
          PostSubOperation_S.ChangeOfCoordinates[2] = $8;
        }
      | ',' tChangeOfValues ListOfExpression
        {
          PostSubOperation_S.ChangeOfValues = List_Copy(ListOfInt_L);
        }
      | ',' tTimeLegend
        {
          PostSubOperation_S.Legend = LEGEND_TIME;
          PostSubOperation_S.LegendPosition[0] = 1.e5;
          PostSubOperation_S.LegendPosition[1] = 30.;
          /* (align<<16)|(font<<8)|(fontsize) */
          PostSubOperation_S.LegendPosition[2] = 66574;
        }
      | ',' tTimeLegend '{' FExpr ',' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.Legend = LEGEND_TIME;
          PostSubOperation_S.LegendPosition[0] = $4;
          PostSubOperation_S.LegendPosition[1] = $6;
          PostSubOperation_S.LegendPosition[2] = $8;
        }
      | ',' tFrequencyLegend
        {
          PostSubOperation_S.Legend = LEGEND_FREQUENCY;
          PostSubOperation_S.LegendPosition[0] = 1.e5;
          PostSubOperation_S.LegendPosition[1] = 30.;
          /* (align<<16)|(font<<8)|(fontsize) */
          PostSubOperation_S.LegendPosition[2] = 66574;
        }
      | ',' tFrequencyLegend '{' FExpr ',' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.Legend = LEGEND_FREQUENCY;
          PostSubOperation_S.LegendPosition[0] = $4;
          PostSubOperation_S.LegendPosition[1] = $6;
          PostSubOperation_S.LegendPosition[2] = $8;
        }
      | ',' tEigenvalueLegend
        {
          PostSubOperation_S.Legend = LEGEND_EIGENVALUES;
          PostSubOperation_S.LegendPosition[0] = 1.e5;
          PostSubOperation_S.LegendPosition[1] = 30.;
          /* (align<<16)|(font<<8)|(fontsize) */
          PostSubOperation_S.LegendPosition[2] = 66574;
        }
      | ',' tEigenvalueLegend '{' FExpr ',' FExpr ',' FExpr '}'
        {
          PostSubOperation_S.Legend = LEGEND_EIGENVALUES;
          PostSubOperation_S.LegendPosition[0] = $4;
          PostSubOperation_S.LegendPosition[1] = $6;
          PostSubOperation_S.LegendPosition[2] = $8;
        }
      | ',' tEvaluationPoints '{' RecursiveListOfFExpr '}'
        {
          if(List_Nbr($4)%3 != 0)
    	vyyerror(0, "Expected 3n coordinates, got %d", List_Nbr($4));
          else {
    	PostSubOperation_S.EvaluationPoints = $4;
          }
        }
      | ',' tStoreInVariable '$' String__Index
        {
          PostSubOperation_S.StoreInVariable = $4;
        }
      | ',' tStoreInRegister FExpr
        {
          PostSubOperation_S.StoreInRegister = (int)$3 - 1;
        }
      | ',' tStoreMinInRegister FExpr
        {
          PostSubOperation_S.StoreMinInRegister = (int)$3 - 1;
        }
      | ',' tStoreMinXinRegister FExpr
        {
          PostSubOperation_S.StoreMinXinRegister = (int)$3 - 1;
        }
      | ',' tStoreMinYinRegister FExpr
        {
          PostSubOperation_S.StoreMinYinRegister = (int)$3 - 1;
        }
      | ',' tStoreMinZinRegister FExpr
        {
          PostSubOperation_S.StoreMinZinRegister = (int)$3 - 1;
        }
      | ',' tStoreMaxInRegister FExpr
        {
          PostSubOperation_S.StoreMaxInRegister = (int)$3 - 1;
        }
      | ',' tStoreMaxXinRegister FExpr
        {
          PostSubOperation_S.StoreMaxXinRegister = (int)$3 - 1;
        }
      | ',' tStoreMaxYinRegister FExpr
        {
          PostSubOperation_S.StoreMaxYinRegister = (int)$3 - 1;
        }
      | ',' tStoreMaxZinRegister FExpr
        {
          PostSubOperation_S.StoreMaxZinRegister = (int)$3 - 1;
        }
      | ',' tStoreInField FExpr
        {
          PostSubOperation_S.StoreInField = $3;
        }
      | ',' tStoreInMeshBasedField FExpr
        {
          PostSubOperation_S.StoreInMeshBasedField = $3;
        }
      | ',' tLastTimeStepOnly
        {
          PostSubOperation_S.LastTimeStepOnly = 1;
        }
      | ',' tLastTimeStepOnly FExpr
        {
          PostSubOperation_S.LastTimeStepOnly = (int)$3;
        }
      | ',' tAppendTimeStepToFileName
        {
          PostSubOperation_S.AppendTimeStepToFileName = 1;
        }
      | ',' tAppendTimeStepToFileName FExpr
        {
          PostSubOperation_S.AppendTimeStepToFileName = (int)$3;
        }
      | ',' tAppendExpressionToFileName Expression
        {
          PostSubOperation_S.AppendExpressionToFileName = $3;
        }
      | ',' tAppendExpressionFormat CharExpr
        {
          PostSubOperation_S.AppendExpressionFormat = $3;
        }
      | ',' tAppendStringToFileName CharExpr
        {
          PostSubOperation_S.AppendStringToFileName = $3;
        }
      | ',' tOverrideTimeStepValue FExpr
        {
          PostSubOperation_S.OverrideTimeStepValue = $3;
        }
      | ',' tNoMesh
        {
          PostSubOperation_S.NoMesh = 1;
        }
      | ',' tNoMesh FExpr
        {
          PostSubOperation_S.NoMesh = $3;
        }
      | ',' tSendToServer CharExpr
        {
          PostSubOperation_S.SendToServer = $3;
        }
      | ',' tSendToServer CharExpr '{' RecursiveListOfFExpr '}'
        {
          PostSubOperation_S.SendToServer = $3;
          PostSubOperation_S.SendToServerList = $5;
        }
      | ',' tHidden
        {
          PostSubOperation_S.Visible = false;
        }
      | ',' tHidden FExpr
        {
          PostSubOperation_S.Visible = $3 ? false : true;
        }
      | ',' tSTRING CharExpr
        {
          std::string cat($2), val($3);
          Free($2);
          if(cat == "Units"){
            PostSubOperation_S.Units = $3;
          }
          else if(cat == "Closed"){
            PostSubOperation_S.Closed = (val == "1") ? true : false;
          }
          else if(cat == "Label"){
            PostSubOperation_S.Label = $3;
          }
          else if(cat == "Color"){
            PostSubOperation_S.Color = $3;
          }
          else if(cat == "NewCoordinates"){
            PostSubOperation_S.NewCoordinates = 1;
            PostSubOperation_S.NewCoordinatesFile = $3;
          }
        }
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  L o o p                                                                 */
    /* ------------------------------------------------------------------------ */
    
    CallArg :
        String__Index
        { $$ = $1; }
      | CharExprNoVar
        { $$ = $1; }
     ;
    
    Loop :
    
        tFor '(' FExpr tDOTS FExpr ')'
        {
          LoopControlVariablesTab[ImbricatedLoop][0] = $3;
          LoopControlVariablesTab[ImbricatedLoop][1] = $5;
          LoopControlVariablesTab[ImbricatedLoop][2] = 1.0;
          LoopControlVariablesNameTab[ImbricatedLoop] = (char*)"";
          fgetpos(getdp_yyin, &FposImbricatedLoopsTab[ImbricatedLoop]);
          LinenoImbricatedLoopsTab[ImbricatedLoop] = getdp_yylinenum;
          if($3 > $5)
    	skipUntil("For", "EndFor");
          else
    	ImbricatedLoop++;
          if(ImbricatedLoop > MAX_RECUR_LOOPS-1){
    	vyyerror(0, "Reached maximum number of imbricated loops");
    	ImbricatedLoop = MAX_RECUR_LOOPS-1;
          }
        }
      | tFor '(' FExpr tDOTS FExpr tDOTS FExpr ')'
        {
          LoopControlVariablesTab[ImbricatedLoop][0] = $3;
          LoopControlVariablesTab[ImbricatedLoop][1] = $5;
          LoopControlVariablesTab[ImbricatedLoop][2] = $7;
          LoopControlVariablesNameTab[ImbricatedLoop] = (char*)"";
          fgetpos(getdp_yyin, &FposImbricatedLoopsTab[ImbricatedLoop]);
          LinenoImbricatedLoopsTab[ImbricatedLoop] = getdp_yylinenum;
          if(($7 > 0. && $3 > $5) || ($7 < 0. && $3 < $5))
    	skipUntil("For", "EndFor");
          else
    	ImbricatedLoop++;
          if(ImbricatedLoop > MAX_RECUR_LOOPS-1){
    	vyyerror(0, "Reached maximum number of imbricated loops");
    	ImbricatedLoop = MAX_RECUR_LOOPS-1;
          }
        }
      | tFor String__Index tIn '{' FExpr tDOTS FExpr '}'
        {
          LoopControlVariablesTab[ImbricatedLoop][0] = $5;
          LoopControlVariablesTab[ImbricatedLoop][1] = $7;
          LoopControlVariablesTab[ImbricatedLoop][2] = 1.0;
          LoopControlVariablesNameTab[ImbricatedLoop] = $2;
          Constant_S.Name = $2;
          Constant_S.Type = VAR_FLOAT;
          Constant_S.Value.Float = $5;
          Tree_Replace(ConstantTable_L, &Constant_S);
          fgetpos(getdp_yyin, &FposImbricatedLoopsTab[ImbricatedLoop]);
          /* hack_fsetpos_printf(); */
          LinenoImbricatedLoopsTab[ImbricatedLoop] = getdp_yylinenum;
          if($5 > $7)
    	skipUntil("For", "EndFor");
          else
    	ImbricatedLoop++;
          if(ImbricatedLoop > MAX_RECUR_LOOPS-1){
    	vyyerror(0, "Reached maximum number of imbricated loops");
    	ImbricatedLoop = MAX_RECUR_LOOPS-1;
          }
        }
      | tFor String__Index tIn '{' FExpr tDOTS FExpr tDOTS FExpr '}'
        {
          LoopControlVariablesTab[ImbricatedLoop][0] = $5;
          LoopControlVariablesTab[ImbricatedLoop][1] = $7;
          LoopControlVariablesTab[ImbricatedLoop][2] = $9;
          LoopControlVariablesNameTab[ImbricatedLoop] = $2;
          Constant_S.Name = $2;
          Constant_S.Type = VAR_FLOAT;
          Constant_S.Value.Float = $5;
          Tree_Replace(ConstantTable_L, &Constant_S);
          fgetpos(getdp_yyin, &FposImbricatedLoopsTab[ImbricatedLoop]);
          LinenoImbricatedLoopsTab[ImbricatedLoop] = getdp_yylinenum;
          if(($9 > 0. && $5 > $7) || ($9 < 0. && $5 < $7))
    	skipUntil("For", "EndFor");
          else
    	ImbricatedLoop++;
          if(ImbricatedLoop > MAX_RECUR_LOOPS-1){
    	vyyerror(0, "Reached maximum number of imbricated loops");
    	ImbricatedLoop = MAX_RECUR_LOOPS-1;
          }
        }
      | tEndFor
        {
          if(ImbricatedLoop <= 0){
    	vyyerror(0, "Invalid For/EndFor loop");
    	ImbricatedLoop = 0;
          }
          else{
    	double x0 = LoopControlVariablesTab[ImbricatedLoop-1][0];
    	double x1 = LoopControlVariablesTab[ImbricatedLoop-1][1];
    	double step = LoopControlVariablesTab[ImbricatedLoop-1][2];
    	int do_next = (step > 0.) ? (x0+step <= x1) : (x0+step >= x1);
    	if(do_next){
    	  LoopControlVariablesTab[ImbricatedLoop-1][0] +=
    	    LoopControlVariablesTab[ImbricatedLoop-1][2];
    	  if(strlen(LoopControlVariablesNameTab[ImbricatedLoop-1])){
    	    Constant_S.Name = LoopControlVariablesNameTab[ImbricatedLoop-1];
    	    Constant_S.Type = VAR_FLOAT;
    	    Constant_S.Value.Float = LoopControlVariablesTab[ImbricatedLoop-1][0];
    	    if(!Tree_Search(ConstantTable_L, &Constant_S))
    	      vyyerror(0, "Unknown For/EndFor loop control variable %s", Constant_S.Name);
    	    Tree_Replace(ConstantTable_L, &Constant_S);
    	  }
    	  fsetpos(getdp_yyin, &FposImbricatedLoopsTab[ImbricatedLoop-1]);
    	  /* fsetpos() seems to position the file just after the For
    	     but with one additional character (the one after EndFor)
    	     at the beginning.  I do not understand why there is such
    	     a mixing of two separate data. hack_fsetpos() removes the
    	     useless additional character. */
    	  hack_fsetpos();
    	  /* hack_fsetpos_printf(); */
    	  getdp_yylinenum = LinenoImbricatedLoopsTab[ImbricatedLoop-1];
    	}
    	else{
    	  ImbricatedLoop--;
    	}
          }
        }
      | tMacro tSTRING
        {
          if(!MacroManager::Instance()->createMacro
             (std::string($2), getdp_yyin, getdp_yyname, getdp_yylinenum + 1))
            vyyerror(0, "Redefinition of macro '%s'", $2);
          skipUntil(NULL, "Return");
          Free($2);
        }
      | tMacro CharExprNoVar
        {
          if(!MacroManager::Instance()->createMacro
             (std::string($2), getdp_yyin, getdp_yyname, getdp_yylinenum + 0))
            vyyerror(0, "Redefinition of macro '%s'", $2);
          skipUntil(NULL, "Return");
          Free($2);
        }
      | tReturn
        {
          if(!MacroManager::Instance()->leaveMacro
             (&getdp_yyin, getdp_yyname, getdp_yylinenum))
    	vyyerror(0, "Error while exiting macro");
        }
      | tMacro LP CharExpr ',' CharExpr RP tEND
        {
          if(!MacroManager::Instance()->createStringMacro($3, $5))
            vyyerror(0, "Redefinition of macro '%s'", $2);
          Free($3);
          Free($5);
        }
      | tCall CallArg tEND
        {
          if(!MacroManager::Instance()->enterMacro
             (std::string($2), &getdp_yyin, getdp_yyname, getdp_yylinenum)){
            if(!MacroManager::Instance()->enterStringMacro(std::string($2)))
              vyyerror(0, "Unknown macro '%s'", $2);
          }
          Free($2);
        }
      | tCallTest '(' FExpr ')' CallArg tEND
        {
          if($3){
            if(!MacroManager::Instance()->enterMacro
               (std::string($5), &getdp_yyin, getdp_yyname, getdp_yylinenum)){
              if(!MacroManager::Instance()->enterStringMacro(std::string($5)))
                vyyerror(0, "Unknown macro '%s'", $5);
            }
          }
          Free($5);
        }
      | tIf '(' FExpr ')'
        {
          ImbricatedTest++;
          if(ImbricatedTest > MAX_RECUR_TESTS-1){
            vyyerror(0, "Reached maximum number of imbricated tests");
            ImbricatedTest = MAX_RECUR_TESTS-1;
          }
    
          if($3){
            // Current test is true
            statusImbricatedTests[ImbricatedTest] = 1;
          }
          else{
            statusImbricatedTests[ImbricatedTest] = 0;
            // Go after the next ElseIf or Else or EndIf
            int type_until2 = 0;
            skipUntil_test("If", "EndIf", "ElseIf", 4, &type_until2);
            if(!type_until2) ImbricatedTest--; // EndIf reached
          }
        }
      | tElseIf '(' FExpr ')'
        {
          if(ImbricatedTest > 0){
            if (statusImbricatedTests[ImbricatedTest]){
              // Last test (If or ElseIf) was true, thus go after EndIf (out of If EndIf)
              skipUntil("If", "EndIf");
              ImbricatedTest--;
            }
            else{
              // Previous test(s) (If and ElseIf) not yet true
              if($3){
                statusImbricatedTests[ImbricatedTest] = 1;
              }
              else{
                // Current test still not true: statusImbricatedTests[ImbricatedTest] = 0;
                // Go after the next ElseIf or Else or EndIf
                int type_until2 = 0;
                skipUntil_test("If", "EndIf", "ElseIf", 4, &type_until2);
                if(!type_until2) ImbricatedTest--;
              }
            }
          }
          else{
            Message::Error("Orphan ElseIf");
          }
        }
      | tElse
        {
          if(ImbricatedTest > 0){
            if(statusImbricatedTests[ImbricatedTest]){
              skipUntil("If", "EndIf");
              ImbricatedTest--;
            }
          }
          else{
            Message::Error("Orphan Else");
          }
        }
      | tEndIf
        {
          ImbricatedTest--;
          if(ImbricatedTest < 0)
            vyyerror(1, "Orphan EndIf");
        }
      | tParse LP CharExpr RP tEND
        {
          getdp_yystring = $3;
          Free($3);
        }
      | Affectation
     ;
    
    
    /* ------------------------------------------------------------------------ */
    /*  C o n s t a n t   E x p r e s s i o n s  (FExpr)                        */
    /* ------------------------------------------------------------------------ */
    
    Printf :
       tPrintf { $$ = 3; }
     | tMPI_Printf { $$ = -3; }
    ;
    
    SendToFile :
        '>'
        {
          $$ = (char*)"w";
        }
      | tGREATERGREATER
        {
          $$ = (char*)"a";
        }
    ;
    
    Affectation :
    
        tDefineConstant '[' DefineConstants ']' tEND
    
      | tUndefineConstant '[' UndefineConstants ']' tEND
    
      | tUndefineFunction '[' UndefineFunctions ']' tEND
    
      | DefineStruct tEND
    
      | tSetNumber LP CharExpr ',' FExpr RP tEND
        {
          Message::SetOnelabNumber($3, $5);
          Free($3);
        }
    
      | tSetString LP CharExpr ',' CharExpr RP tEND
        {
          Message::SetOnelabString($3, $5);
          Free($3);
          Free($5);
        }
    
      | tDelete String__Index tEND
        {
          Constant_S.Name = $2;
          // FIXME: leak if constant is list or char; all Tree_Replace functions
          // below also leak; correct fix is to replace all of this with a std::map
          // like in Gmsh
          Tree_Suppress(ConstantTable_L, &Constant_S);
          Free($2);
        }
    
      | tDelete '[' String__Index ']' tEND
        {
          Constant_S.Name = $3;
          // FIXME: leak if constant is list or char; all Tree_Replace functions
          // below also leak; correct fix is to replace all of this with a std::map
          // like in Gmsh
          Tree_Suppress(ConstantTable_L, &Constant_S);
          Free($3);
        }
    
      | tDelete tDefineStruct tEND
        {
          nameSpaces.clear();
        }
    
      | String__Index tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          if(List_Nbr($3) == 1){
    	Constant_S.Type = VAR_FLOAT;
    	List_Read($3, 0, &Constant_S.Value.Float);
    	List_Delete($3);
          }
          else{
    	Constant_S.Type = VAR_LISTOFFLOAT;
    	Constant_S.Value.List = $3;
          }
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | String__Index '(' ')' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant_S.Type = VAR_LISTOFFLOAT;
          Constant_S.Value.List = $5;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | String__Index '(' RecursiveListOfFExpr ')' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c && (c->Type == VAR_LISTOFFLOAT)){
            if(List_Nbr($3) == List_Nbr($6)){
              for(int i = 0; i < List_Nbr($3); i++){
                double d;
                List_Read($3, i, &d);
                int idx = (int)d;
                if(idx >= 0 && idx < List_Nbr(c->Value.List)){
                  double *pd = (double*)List_Pointer(c->Value.List, idx);
                  double d2 = *(double*)List_Pointer($6, i);
                  *pd = d2;
                }
                else
                  vyyerror(0, "Index %d out of range", idx);
              }
            }
            else
              vyyerror(0, "Bad list sizes for affectation %d != %d", List_Nbr($3), List_Nbr($6));
          }
          else
    	vyyerror(0, "Unknown list Constant: %s", $1);
          List_Delete($3);
          List_Delete($6);
        }
    
      | String__Index '(' RecursiveListOfFExpr ')' '+' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c && (c->Type == VAR_LISTOFFLOAT)){
            if(List_Nbr($3) == List_Nbr($7)){
              for(int i = 0; i < List_Nbr($3); i++){
                double d;
                List_Read($3, i, &d);
                int idx = (int)d;
                if(idx >= 0 && idx < List_Nbr(c->Value.List)){
                  double *pd = (double*)List_Pointer(c->Value.List, idx);
                  double d2 = *(double*)List_Pointer($7, i);
                  *pd += d2;
                }
                else
                  vyyerror(0, "Index %d out of range", idx);
              }
            }
            else
              vyyerror(0, "Bad list sizes (%d, %d) for += operation", List_Nbr($3), List_Nbr($7));
          }
          else
    	vyyerror(0, "Unknown list Constant: %s", $1);
          List_Delete($3);
          List_Delete($7);
        }
    
      | String__Index '(' RecursiveListOfFExpr ')' '-' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c && (c->Type == VAR_LISTOFFLOAT)){
            if(List_Nbr($3) == List_Nbr($7)){
              for(int i = 0; i < List_Nbr($3); i++){
                double d;
                List_Read($3, i, &d);
                int idx = (int)d;
                if(idx >= 0 && idx < List_Nbr(c->Value.List)){
                  double *pd = (double*)List_Pointer(c->Value.List, idx);
                  double d2 = *(double*)List_Pointer($7, i);
                  *pd -= d2;
                }
                else
                  vyyerror(0, "Index %d out of range", idx);
              }
            }
            else
              vyyerror(0, "Bad list sizes (%d, %d) for -= operation", List_Nbr($3), List_Nbr($7));
          }
          else
    	vyyerror(0, "Unknown list Constant: %s", $1);
          List_Delete($3);
          List_Delete($7);
        }
    
      | String__Index '+' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c){
            if(c->Type == VAR_FLOAT && List_Nbr($4) == 1){
              double d;
              List_Read($4, 0, &d);
              c->Value.Float += d;
            }
            else if(c->Type == VAR_LISTOFFLOAT){
              for(int i = 0; i < List_Nbr($4); i++)
                List_Add(c->Value.List, List_Pointer($4, i));
            }
            else
              vyyerror(0, "Cannot append list to float");
          }
          else
    	vyyerror(0, "Unknown Constant: %s", $1);
          List_Delete($4);
        }
    
      | String__Index '(' ')' '+' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c){
            if(c->Type == VAR_LISTOFFLOAT){
              for(int i = 0; i < List_Nbr($6); i++)
                List_Add(c->Value.List, List_Pointer($6, i));
            }
            else
              vyyerror(0, "Cannot append list to float");
          }
          else
    	vyyerror(0, "Unknown Constant: %s", $1);
          List_Delete($6);
        }
    
      | String__Index '-' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c){
            if(c->Type == VAR_FLOAT && List_Nbr($4) == 1){
              double d;
              List_Read($4, 0, &d);
              c->Value.Float -= d;
            }
            else if(c->Type == VAR_LISTOFFLOAT){
              std::vector<double> tmp;
              for(int i = 0; i < List_Nbr(c->Value.List); i++){
                double d;
                List_Read(c->Value.List, i, &d);
                tmp.push_back(d);
              }
              for(int i = 0; i < List_Nbr($4); i++){
                double d;
                List_Read($4, i, &d);
                std::vector<double>::iterator it = std::find(tmp.begin(), tmp.end(), d);
                if(it != tmp.end()) tmp.erase(it);
              }
              List_Reset(c->Value.List);
              for(unsigned int i = 0; i < tmp.size(); i++)
                List_Add(c->Value.List, &tmp[i]);
            }
            else
              vyyerror(0, "Cannot erase list from float");
          }
          else
    	vyyerror(0, "Unknown Constant: %s", $1);
          List_Delete($4);
        }
    
      | String__Index '(' ')' '-' tDEF ListOfFExpr tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c){
            if(c->Type == VAR_LISTOFFLOAT){
              std::vector<double> tmp;
              for(int i = 0; i < List_Nbr(c->Value.List); i++){
                double d;
                List_Read(c->Value.List, i, &d);
                tmp.push_back(d);
              }
              for(int i = 0; i < List_Nbr($6); i++){
                double d;
                List_Read($6, i, &d);
                std::vector<double>::iterator it = std::find(tmp.begin(), tmp.end(), d);
                if(it != tmp.end()) tmp.erase(it);
              }
              List_Reset(c->Value.List);
              for(unsigned int i = 0; i < tmp.size(); i++)
                List_Add(c->Value.List, &tmp[i]);
            }
            else
              vyyerror(0, "Cannot erase list from float");
          }
          else
    	vyyerror(0, "Unknown Constant: %s", $1);
          List_Delete($6);
        }
    
      | String__Index tDEF CharExprNoVar tEND
        {
          Constant_S.Name = $1; Constant_S.Type = VAR_CHAR;
          Constant_S.Value.Char = $3;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | String__Index '(' ')' tDEF tStr '[' ']' tEND
        {
          Constant_S.Name = $1;
          Constant_S.Type = VAR_LISTOFCHAR;
          Constant_S.Value.List = List_Create(20, 20, sizeof(char*));
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | String__Index '(' ')' tDEF tStr LP BracedOrNotRecursiveListOfCharExpr RP tEND
        {
          Constant_S.Name = $1;
          Constant_S.Type = VAR_LISTOFCHAR;
          Constant_S.Value.List = $7;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | String__Index '(' ')' '+' tDEF tStr LP BracedOrNotRecursiveListOfCharExpr RP tEND
        {
          Constant_S.Name = $1;
          Constant *c = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
          if(c){
            if(c->Type == VAR_LISTOFCHAR){
              for(int i = 0; i < List_Nbr($8); i++)
                List_Add(c->Value.List, List_Pointer($8, i));
            }
            else
              vyyerror(0, "Cannot append string to non-list of strings");
          }
          else
    	vyyerror(0, "Unknown Constant: %s", $1);
          List_Delete($8);
        }
    
      | Printf LP CharExprNoVar RP tEND
        {
          Message::Direct($1, $3);
        }
    
      | Printf LP CharExprNoVar RP SendToFile CharExpr tEND
        {
          std::string tmp = Fix_RelativePath($6);
          FILE *fp = FOpen(tmp.c_str(), $5);
          if(!fp){
    	vyyerror(0, "Unable to open file '%s'", tmp.c_str());
          }
          else{
    	fprintf(fp, "%s\n", $3);
    	fclose(fp);
          }
          Free($3);
          Free($6);
        }
    
      | Printf String__Index tEND
        {
          Constant_S.Name = $2;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
    	vyyerror(0, "Unknown Constant: %s", $2);
          else
    	if(Constant_S.Type != VAR_LISTOFFLOAT)
              Message::Direct($1, "%s: %g", $2, Constant_S.Value.Float);
    	else
              Message::Direct($1, "%s: Dimension %d", $2, List_Nbr(Constant_S.Value.List));
    	  for(int i = 0; i < List_Nbr(Constant_S.Value.List); i++) {
    	    double d;
    	    List_Read(Constant_S.Value.List, i, &d);
                Message::Direct($1, " (%d) %g", i, d);
    	  }
        }
    
      | Printf '#' tEND
        {
          Message::Direct($1, "Line number: %d", getdp_yylinenum);
        }
    
      | Printf LP CharExprNoVar ',' RecursiveListOfFExpr RP tEND
        {
          char tmpstr[256];
          int i = Print_ListOfDouble($3, $5, tmpstr);
          if(i < 0)
    	vyyerror(0, "Too few arguments in Printf");
          else if(i > 0)
    	vyyerror(0, "Too many arguments (%d) in Printf", i);
          else
    	Message::Direct($1, tmpstr);
          Free($3);
          List_Delete($5);
        }
    
      | Printf LP CharExprNoVar ',' RecursiveListOfFExpr RP SendToFile CharExpr tEND
        {
          std::string tmp = Fix_RelativePath($8);
          FILE *fp = FOpen(tmp.c_str(), $7);
          if(!fp){
    	vyyerror(0, "Unable to open file '%s'", tmp.c_str());
          }
          else{
            char tmpstr[256];
            int i = Print_ListOfDouble($3, $5, tmpstr);
            if(i < 0)
              vyyerror(0, "Too few arguments in Printf");
            else if(i > 0)
              vyyerror(0, "Too many arguments (%d) in Printf", i);
            else
              fprintf(fp, "%s\n", $3);
    	fclose(fp);
          }
          Free($3);
          Free($8);
          List_Delete($5);
        }
    
      | tError '(' CharExpr ')' tEND
        {
          Message::Error($3);
          Free($3);
        }
    
      // deprectated
      | tRead '(' String__Index ')' tEND
        {
          Message::Info("? ");
          char tmpstr[256];
          fgets(tmpstr, sizeof(tmpstr), stdin);
          Constant_S.Value.Float = atof(tmpstr);
          Constant_S.Name = $3;
          Constant_S.Type = VAR_FLOAT;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | tRead '[' String__Index ']' tEND
        {
          Message::Info("? ");
          char tmpstr[256];
          fgets(tmpstr, sizeof(tmpstr), stdin);
          Constant_S.Value.Float = atof(tmpstr);
          Constant_S.Name = $3;
          Constant_S.Type = VAR_FLOAT;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      // deprectated
      | tRead '(' String__Index ')' '[' FExpr ']' tEND
        {
          Message::Info("[<return>=%g] ? ",$6);
          char tmpstr[256];
          fgets(tmpstr, sizeof(tmpstr), stdin);
    
          if(!strcmp(tmpstr,"\n"))
    	Constant_S.Value.Float = $6;
          else
    	Constant_S.Value.Float = atof(tmpstr);
          Constant_S.Name = $3;
          Constant_S.Type = VAR_FLOAT;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | tRead '[' String__Index ',' FExpr '}' tEND
        {
          Message::Info("[<return>=%g] ? ",$5);
          char tmpstr[256];
          fgets(tmpstr, sizeof(tmpstr), stdin);
    
          if(!strcmp(tmpstr,"\n"))
    	Constant_S.Value.Float = $5;
          else
    	Constant_S.Value.Float = atof(tmpstr);
          Constant_S.Name = $3;
          Constant_S.Type = VAR_FLOAT;
          Tree_Replace(ConstantTable_L, &Constant_S);
        }
    
      | tPrintConstants tEND
        {
          Print_Constants();
        }
    ;
    
    Enumeration :
        FExpr tDEF CharExpr
        {
          $$ = List_Create(20,20,sizeof(doubleXstring));
          doubleXstring v = {$1, $3};
          List_Add($$, &v);
        }
      | Enumeration ',' FExpr tDEF CharExpr
        {
          doubleXstring v = {$3, $5};
          List_Add($$, &v);
        }
      | MultiFExpr tDEF String__Index '(' ')'
        {
          $$ = List_Create(20,20,sizeof(doubleXstring));
          int n = List_Nbr($1);
          Constant_S.Name = $3;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
    	vyyerror(0, "Unknown Constant: %s", $3);
          else{
    	if(Constant_S.Type == VAR_LISTOFCHAR){
              int m = List_Nbr(Constant_S.Value.List);
              if(n == m){
                for(int i = 0; i < n; i++){
                  double d;
                  List_Read($1, i, &d);
                  char *s;
                  List_Read(Constant_S.Value.List, i, &s);
                  doubleXstring v = {d, strSave(s)};
                  List_Add($$, &v);
                }
              }
              else{
                vyyerror(0, "Size mismatch in enumeration: %d != %d", n, m);
              }
            }
    	else{
              vyyerror(0, "Enumeration requires list of strings");
            }
          }
          List_Delete($1);
        }
      ;
    
    FloatParameterOptionsOrNone :
        // none
      | ',' FloatParameterOptions
     ;
    
    FloatParameterOptionsOrNone_NoComma :
        // none
      | FloatParameterOptions
     ;
    
    FloatParameterOptions :
        FloatParameterOption
      | FloatParameterOptions ',' FloatParameterOption
     ;
    
    FloatParameterOption :
    
        tSTRING ListOfFExpr
        {
          std::string key($1);
          for(int i = 0; i < List_Nbr($2); i++){
            double v;
            List_Read($2, i, &v);
            floatOptions[key].push_back(v);
            if (flag_Enum && !i) { member_ValMax = (int)v; }
          }
          Free($1);
          List_Delete($2);
        }
    
      | tSTRING
        {
          std::string key($1);
          double v;
          if (!flag_Enum) {
            v = 1.;
            if (key == "Enum") flag_Enum = 1;
          }
          else
            v = (double)++member_ValMax;
          floatOptions[key].push_back(v);
          Free($1);
        }
    
      | tSTRING '{' Enumeration '}'
        {
          std::string key($1);
          for(int i = 0; i < List_Nbr($3); i++){
            doubleXstring v;
            List_Read($3, i, &v);
            floatOptions[key].push_back(v.d);
            charOptions[key].push_back(v.s);
          }
          Free($1);
          for(int i = 0; i < List_Nbr($3); i++)
            Free(((doubleXstring*)List_Pointer($3, i))->s);
          List_Delete($3);
        }
    
      | tSTRING CharExprNoVar
        {
          std::string key($1);
          std::string val($2);
          charOptions[key].push_back(val);
          Free($1);
          Free($2);
        }
    
      | tSTRING Str_BracedRecursiveListOfCharExpr
        {
          std::string key($1);
          for(int i = 0; i < List_Nbr($2); i++){
            char *v;
            List_Read($2, i, &v);
            charOptions[key].push_back(v);
          }
          Free($1);
          List_Delete($2);
        }
    
      | tName CharExprNoVar
        {
          std::string key("Name");
          std::string val($2);
          charOptions[key].push_back(val);
          Free($2);
        }
    
      | tType ListOfFExpr
        {
          std::string key("Type");
          for(int i = 0; i < List_Nbr($2); i++){
            double v;
            List_Read($2, i, &v);
            floatOptions[key].push_back(v);
          }
          List_Delete($2);
        }
     ;
    
    CharParameterOptionsOrNone :
        // none
      | ',' CharParameterOptions
     ;
    
    CharParameterOptions :
        CharParameterOption
      | CharParameterOptions ',' CharParameterOption
     ;
    
    CharParameterOption :
    
        tSTRING FExpr
        {
          std::string key($1);
          double val = $2;
          floatOptions[key].push_back(val);
          Free($1);
        }
    
      | tSTRING CharExprNoVar
        {
          std::string key($1);
          std::string val($2);
          charOptions[key].push_back(val);
          Free($1);
          Free($2);
        }
    
      | tName CharExprNoVar // Name is already a reserved GetDP keyword
        {
          std::string key("Name");
          std::string val($2);
          charOptions[key].push_back(val);
          Free($2);
        }
    
      | tMacro CharExprNoVar // Macro is already a reserved GetDP keyword
        {
          std::string key("Macro");
          std::string val($2);
          charOptions[key].push_back(val);
          Free($2);
        }
    
      | tSTRING BracedRecursiveListOfCharExpr
        {
          std::string key($1);
          for(int i = 0; i < List_Nbr($2); i++){
            char *s;
            List_Read($2, i, &s);
            std::string val(s);
            Free(s);
            charOptions[key].push_back(val);
          }
          Free($1);
          List_Delete($2);
        }
    
      | tSTRING Str_BracedRecursiveListOfCharExpr
        {
          std::string key($1);
          for(int i = 0; i < List_Nbr($2); i++){
            char *s;
            List_Read($2, i, &s);
            std::string val(s);
            Free(s);
            charOptions[key].push_back(val);
          }
          Free($1);
          List_Delete($2);
        }
     ;
    
    DefineConstants :
    
        /* none */
      | DefineConstants Comma String__Index
        { Constant_S.Name = $3; Constant_S.Type = VAR_FLOAT;
          init_Options();
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.Float = 0.;
    	Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
      | DefineConstants Comma String__Index '{' FExpr '}'
        {
          Constant_S.Type = VAR_FLOAT ;
          init_Options();
          for (int k = 0 ; k < (int)$5 ; k++) {
    	char tmpstr[256];
    	sprintf(tmpstr, "%s_%d", $3, k+1) ;
    	Constant_S.Name = tmpstr ;
    	if (!Tree_Search(ConstantTable_L, &Constant_S)) {
    	  Constant_S.Name = strSave(tmpstr);
              Constant_S.Value.Float = 0. ;
    	  Tree_Replace(ConstantTable_L, &Constant_S) ;
    	}
          }
          Free($3) ;
        }
      | DefineConstants Comma String__Index tDEF FExpr
        {
          Constant_S.Name = $3; Constant_S.Type = VAR_FLOAT;
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.Float = $5;
    	Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
      | DefineConstants Comma String__Index '(' ')' tDEF '{' '}'
        {
          Constant_S.Name = $3; Constant_S.Type = VAR_LISTOFFLOAT;
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.List = List_Create(2,20,sizeof(double));
    	Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
      | DefineConstants Comma String__Index tDEF '{' ListOfFExpr
        { init_Options(); }
        FloatParameterOptionsOrNone '}'
        {
          Constant_S.Name = $3;
          if(List_Nbr($6) == 1){
            Constant_S.Type = VAR_FLOAT;
            if(!Tree_Search(ConstantTable_L, &Constant_S)){
              double d;
              List_Read($6, 0, &d);
              Constant_S.Value.Float = d;
              Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
              Tree_Replace(ConstantTable_L, &Constant_S);
            }
            List_Delete($6);
          }
          else{
    	vyyerror(1, "List notation should be used to define list '%s()'", $3);
            Constant_S.Type = VAR_LISTOFFLOAT;
            if(!Tree_Search(ConstantTable_L, &Constant_S)){
              Constant_S.Value.List = $6;
              Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
              Tree_Replace(ConstantTable_L, &Constant_S);
            }
          }
        }
      | DefineConstants Comma String__Index '(' ')' tDEF '{' ListOfFExpr
        { init_Options(); }
        FloatParameterOptionsOrNone '}'
        {
          Constant_S.Name = $3;
          Constant_S.Type = VAR_LISTOFFLOAT;
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.List = $8;
            Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
            Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
      | DefineConstants Comma String__Index tDEF CharExprNoVar
        {
          Constant_S.Name = $3; Constant_S.Type = VAR_CHAR;
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.Char = $5;
    	Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
      | DefineConstants Comma String__Index tDEF '{' CharExprNoVar
        { init_Options(); }
        CharParameterOptionsOrNone '}'
        {
          Constant_S.Name = $3; Constant_S.Type = VAR_CHAR;
          if(!Tree_Search(ConstantTable_L, &Constant_S)){
            Constant_S.Value.Char = $6;
            Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
    	Tree_Replace(ConstantTable_L, &Constant_S);
          }
        }
     ;
    
    UndefineConstants :
    
        /* none */
      | UndefineConstants Comma CharExprNoVar
        {
          // undefine the onelab parameter
          std::string name($3);
          Message::UndefineOnelabParameter(name);
          Free($3);
        }
    
      | UndefineConstants Comma String__Index
        {
          // undefine the onelab parameter and the getdp constant
          std::string name($3);
          Message::UndefineOnelabParameter(name);
          Constant_S.Name = $3;
          Tree_Suppress(ConstantTable_L, &Constant_S);
          Free($3);
        }
    
    
    /* Ce bricolage affreux (?) est necessaire pour permettre la meme
       syntaxe dans les expressions constantes et dans les whole_expressions */
    
    NameForMathFunction :
        tExp     { $$ = (char*)"Exp";    }
      | tLog     { $$ = (char*)"Log";    }
      | tLog10   { $$ = (char*)"Log10";  }
      | tSqrt    { $$ = (char*)"Sqrt";   }
      | tSin     { $$ = (char*)"Sin";    }
      | tAsin    { $$ = (char*)"Asin";   }
      | tCos     { $$ = (char*)"Cos";    }
      | tAcos    { $$ = (char*)"Acos";   }
      | tTan     { $$ = (char*)"Tan";    }
      | tAtan    { $$ = (char*)"Atan";   }
      | tAtan2   { $$ = (char*)"Atan2";  }
      | tSinh    { $$ = (char*)"Sinh";   }
      | tCosh    { $$ = (char*)"Cosh";   }
      | tTanh    { $$ = (char*)"Tanh";   }
      | tAtanh   { $$ = (char*)"Atanh";  }
      | tFabs    { $$ = (char*)"Fabs";   }
      | tFloor   { $$ = (char*)"Floor";  }
      | tCeil    { $$ = (char*)"Ceil";   }
      | tRound   { $$ = (char*)"Round";  }
      | tSign    { $$ = (char*)"Sign";   }
      | tFmod    { $$ = (char*)"Fmod";   }
      | tModulo  { $$ = (char*)"Modulo"; }
      | tHypot   { $$ = (char*)"Hypot";  }
      | tRand    { $$ = (char*)"Rand";   }
     ;
    
    NameForFunction :
        NameForMathFunction { $$ = $1; }
      | String__Index       { $$ = $1; }
     ;
    
    FExpr :
        OneFExpr                         { $$ = $1;          }
      | '(' FExpr ')'                    { $$ = $2;          }
      | '-' FExpr %prec UNARYPREC        { $$ = -$2;         }
      | '!' FExpr                        { $$ = !$2;         }
      | FExpr '-' FExpr                  { $$ = $1 - $3;     }
      | FExpr '+' FExpr                  { $$ = $1 + $3;     }
      | FExpr '*' FExpr                  { $$ = $1 * $3;     }
      | FExpr '|' FExpr                  { $$ = (int)$1 | (int)$3;     }
      | FExpr '&' FExpr                  { $$ = (int)$1 & (int)$3;     }
      | FExpr '/' FExpr                  { $$ = $1 / $3;     }
      | FExpr '%' FExpr                  { $$ = (int)$1 % (int)$3;  }
      | FExpr '^' FExpr                  { $$ = pow($1,$3);  }
      | FExpr '<' FExpr                  { $$ = $1 < $3;     }
      | FExpr '>' FExpr                  { $$ = $1 > $3;     }
      | FExpr tLESSOREQUAL FExpr         { $$ = $1 <= $3;    }
      | FExpr tGREATEROREQUAL FExpr      { $$ = $1 >= $3;    }
      | FExpr tEQUAL FExpr               { $$ = $1 == $3;    }
      | FExpr tNOTEQUAL FExpr            { $$ = $1 != $3;    }
      | FExpr tAND FExpr                 { $$ = $1 && $3;    }
      | FExpr tOR FExpr                  { $$ = $1 || $3;    }
      | FExpr tGREATERGREATER FExpr      { $$ = ((int)$1 >> (int)$3);  }
      | FExpr tLESSLESS FExpr            { $$ = ((int)$1 << (int)$3);  }
      | tExp    '[' FExpr ']'            { $$ = exp($3);      }
      | tLog    '[' FExpr ']'            { $$ = log($3);      }
      | tLog10  '[' FExpr ']'            { $$ = log10($3);    }
      | tSqrt   '[' FExpr ']'            { $$ = sqrt($3);     }
      | tSin    '[' FExpr ']'            { $$ = sin($3);      }
      | tAsin   '[' FExpr ']'            { $$ = asin($3);     }
      | tCos    '[' FExpr ']'            { $$ = cos($3);      }
      | tAcos   '[' FExpr ']'            { $$ = acos($3);     }
      | tTan    '[' FExpr ']'            { $$ = tan($3);      }
      | tAtan   '[' FExpr ']'            { $$ = atan($3);     }
      | tAtan2  '[' FExpr ',' FExpr ']'  { $$ = atan2($3,$5); }
      | tSinh   '[' FExpr ']'            { $$ = sinh($3);     }
      | tCosh   '[' FExpr ']'            { $$ = cosh($3);     }
      | tTanh   '[' FExpr ']'            { $$ = tanh($3);     }
      | tAtanh  '[' FExpr ']'            { $$ = atanh($3);    }
      | tFabs   '[' FExpr ']'            { $$ = fabs($3);     }
      | tFloor  '[' FExpr ']'            { $$ = floor($3);    }
      | tCeil   '[' FExpr ']'            { $$ = ceil($3);     }
      | tRound  '[' FExpr ']'            { $$ = floor($3 + 0.5);    }
      | tSign   '[' FExpr ']'            { $$ = (($3 > 0.) ? 1. : ($3 < 0.) ? -1. : 0.); }
      | tFmod   '[' FExpr ',' FExpr ']'  { $$ = fmod($3,$5);  }
      | tModulo '[' FExpr ',' FExpr ']'  { $$ = fmod($3,$5);  }
      | tHypot  '[' FExpr ',' FExpr ']'  { $$ = sqrt($3*$3+$5*$5);  }
      | tRand   '[' FExpr ']'  { $$ = $3 * (double)rand() / (double)RAND_MAX;  }
    
      | FExpr '?' FExpr tDOTS FExpr      { $$ = $1? $3 : $5; }
    
      | StrCmp                           { $$ = $1; }
    
      | NbrRegions                       { $$ = $1; }
    
      | FExpr '#' { Message::Direct("Value (line %ld) --> %.16g", getdp_yylinenum, $1); }
     ;
    
    OneFExpr :
    
        tFLOAT    { $$ = $1; }
      | tINT      { $$ = (double)$1; }
      | tPi       { $$ = 3.1415926535897932; }
      | t0D       { $$ = (double)_0D; }
      | t1D       { $$ = (double)_1D; }
      | t2D       { $$ = (double)_2D; }
      | t3D       { $$ = (double)_3D; }
      | tMPI_Rank { $$ = Message::GetCommRank(); }
      | tMPI_Size { $$ = Message::GetCommSize(); }
      | tGETDP_MAJOR_VERSION { $$ = GETDP_MAJOR_VERSION; }
      | tGETDP_MINOR_VERSION { $$ = GETDP_MINOR_VERSION; }
      | tGETDP_PATCH_VERSION { $$ = GETDP_PATCH_VERSION; }
      | tTotalMemory { $$ = GetTotalRam(); }
    
      | tLevelTest { $$ = (double)ImbricatedTest; }
      | tNumInclude { $$ = (double)num_include; }
      | tLevelInclude { $$ = (double)level_include; }
    //  | tLevelInclude { $$ = (double)getdp_yyincludenum; }
    
      | tDefineNumber '[' FExpr
        { init_Options(); }
        FloatParameterOptionsOrNone ']'
        {
          Constant_S.Name = (char*)""; Constant_S.Type = VAR_FLOAT;
          Constant_S.Value.Float = $3;
          Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
          $$ = Constant_S.Value.Float;
        }
    
      | DefineStruct
        { $$ = $1; }
    
      | Struct_FullName '.' tSTRING_Member
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float($1.char1, $1.char2, $3);
        }
    
      | Struct_FullName '.' tSTRING_Member '(' FExpr ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float($1.char1, $1.char2, $3, (int)$5);
        }
    
      | tGetNumber LP CharExpr RP
        {
          $$ = Message::GetOnelabNumber($3, 0.);
          Free($3);
        }
    
      | tGetNumber LP CharExpr ',' FExpr  RP
        {
          $$ = Message::GetOnelabNumber($3, $5);
          Free($3);
        }
    
      | Struct_FullName
        {
          $$ = Treat_Struct_FullName_Float($1.char1, $1.char2);
        }
    
      | '#' Struct_FullName '(' ')'
        {
          if ($2.char1) vyyerror(1, "NameSpace '%s' not used yet", $2.char1);
          Constant_S.Name = $2.char2;
          int ret = 0;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
    	vyyerror(0, "Unknown Constant: %s", $2.char2);
          else{
    	if(Constant_S.Type == VAR_LISTOFFLOAT ||
               Constant_S.Type == VAR_LISTOFCHAR)
              ret = List_Nbr(Constant_S.Value.List);
    	else if(Constant_S.Type == VAR_FLOAT)
              ret = 1;
            else
              vyyerror(0, "Float Constant needed: %s", $2.char2);
          }
          $$ = ret;
          Free($2.char1); Free($2.char2);
        }
    
      | '#' Struct_FullName '.' tSTRING_Member '(' ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float_getDim($2.char1, $2.char2, $4);
        }
    
      | tDimNameSpace LP String__Index RP
        {
          std::string struct_namespace($3);
          $$ = (double)nameSpaces[struct_namespace].size();
          Free($3);
        }
      | tDimNameSpace LP RP
        {
          std::string struct_namespace(std::string(""));
          $$ = (double)nameSpaces[struct_namespace].size();
        }
    
      | Struct_FullName '(' FExpr ')'
        {
          $$ = Treat_Struct_FullName_Float($1.char1, $1.char2, 2, (int)$3);
        }
    
      | tExists LP Struct_FullName RP
        {
          $$ = Treat_Struct_FullName_Float($3.char1, $3.char2, 1, 0, 0., 1);
        }
    
      | tExists LP Struct_FullName '.' tSTRING_Member RP
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float($3.char1, $3.char2, $5, 0, 0., 1);
        }
    
      | tExists LP String__Index '[' ']' RP
        {
          if(List_ISearchSeq(Problem_S.Expression, $3, fcmp_Expression_Name) >= 0)
            $$ = 1;
          else
            $$ = 0;
          Free($3);
        }
    
      | tGetForced LP Struct_FullName GetForced_Default RP
        {
          $$ = Treat_Struct_FullName_Float($3.char1, $3.char2, 1, 0, $4, 2);
        }
    
      | tGetForced LP Struct_FullName '.' tSTRING_Member GetForced_Default RP
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float($3.char1, $3.char2, $5, 0, $6, 2);
        }
      | tGetForced LP Struct_FullName '(' FExpr ')' GetForced_Default RP
        {
          $$ = Treat_Struct_FullName_Float($3.char1, $3.char2, 2, (int)$5, $7, 2);
        }
    
      | tGetForced LP Struct_FullName '.' tSTRING_Member '(' FExpr ')' GetForced_Default RP
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_Float($3.char1, $3.char2, $5, (int)$7, $9, 2);
        }
    
      | tFileExists LP CharExpr RP
        {
          std::string tmp = Fix_RelativePath($3).c_str();
          $$ = !StatusFile(tmp);
          Free($3);
        }
    ;
    
    GetForced_Default :
        // none
        { $$ = 0.; }
      | ',' FExpr
        { $$ = $2;}
    ;
    
    GetForcedStr_Default :
        // none
        { $$ = NULL; }
      | ',' CharExpr
        { $$ = $2;}
    ;
    
    DefineStruct :
        tDefineStruct Struct_FullName AppendOrNot
        {
          std::string struct_namespace($2.char1? $2.char1 : std::string("")),
            struct_name($2.char2);
          init_Options
            (nameSpaces.getMember_ValMax(struct_namespace, struct_name));
        }
        '[' FloatParameterOptionsOrNone_NoComma ']'
        {
          std::string struct_namespace($2.char1? $2.char1 : std::string("")),
            struct_name($2.char2);
          Free($2.char1); Free($2.char2);
          int tag_out;
          if (nameSpaces.defStruct(struct_namespace, struct_name,
                                   floatOptions, charOptions,
                                   tag_out, member_ValMax, $3))
            vyyerror(0, "Redefinition of Struct '%s::%s'",
                     struct_namespace.c_str(), struct_name.c_str());
          $$ = (double)tag_out;
        }
    ;
    
    Struct_FullName :
        String__Index
        { $$.char1 = NULL; $$.char2 = $1; }
      | String__Index tSCOPE String__Index
        { $$.char1 = $1; $$.char2 = $3; }
    ;
    
    tSTRING_Member :
        tSTRING
        { $$ = $1; flag_tSTRING_alloc = 1; }
      | tType
        { $$ = (char*)"Type"; flag_tSTRING_alloc = 0; }
    ;
    
    RecursiveListOfListOfFExpr :
        ListOfFExpr
        {
          $$ = List_Create(2, 1, sizeof(List_T*));
          List_Add($$, &($1));
        }
      | RecursiveListOfListOfFExpr ',' ListOfFExpr
        {
          List_Add($$, &($3));
        }
    ;
    
    ListOfFExpr :
        '{' '}'
        { $$ = List_Create(20,20,sizeof(double)); }
    
      | FExpr
        {
          $$ = List_Create(1,10,sizeof(double));
          List_Add($$, &($1));
        }
    
      | MultiFExpr
        { $$ = $1; }
    
      | '{' RecursiveListOfFExpr '}'
        { $$ = $2; }
    
      | '-' '{' RecursiveListOfFExpr '}'
        {
          $$ = $3;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	(*pd) = - (*pd);
          }
        }
    
      | FExpr '*' '{' RecursiveListOfFExpr '}'
        {
          $$ = $4;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	(*pd) *= $1;
          }
        }
    /*++++D
      | FExpr '+' '{' RecursiveListOfFExpr '}'
        {
          $$ = $4;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	(*pd) += $1;
          }
        }
    */
    ;
    
    
    RecursiveListOfFExpr :
    
        FExpr
        {
          $$ = List_Create(20,20,sizeof(double));
          List_Add($$, &($1));
        }
    
      | MultiFExpr
        { $$ = $1; }
    
      | RecursiveListOfFExpr ',' FExpr
        { List_Add($$, &($3)); }
    
      | RecursiveListOfFExpr ',' MultiFExpr
        {
          for(int i = 0; i < List_Nbr($3); i++){
    	double d;
    	List_Read($3, i, &d);
    	List_Add($$, &d);
          }
          List_Delete($3);
        }
     ;
    
    MultiFExpr :
    
        '-' MultiFExpr %prec UNARYPREC
        {
          $$ = $2;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	*pd *= -1.0;
          }
        }
    
      | FExpr '*' MultiFExpr
        {
          $$ = $3;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	*pd *= $1;
          }
        }
    
      | FExpr '+' MultiFExpr
        {
          $$ = $3;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	*pd += $1;
          }
        }
    
      | FExpr '/' MultiFExpr
        {
          $$ = $3;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	if(*pd) *pd = $1 / *pd;
          }
        }
    
      | MultiFExpr '/' FExpr
        {
          $$ = $1;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	if($3) *pd /= $3;
          }
        }
    
      | MultiFExpr '^' FExpr
        {
          $$ = $1;
          for(int i = 0; i < List_Nbr($$); i++){
    	double *pd = (double*)List_Pointer($$, i);
    	*pd = pow(*pd, $3);
          }
        }
    
      | MultiFExpr '+' MultiFExpr
        {
          $$ = $1;
          if(List_Nbr($$) == List_Nbr($3)){
            for(int i = 0; i < List_Nbr($$); i++){
              double *pd = (double*)List_Pointer($$, i);
              double d = *(double*)List_Pointer($3, i);
              *pd += d;
            }
          }
          else
            vyyerror(0, "Wrong list sizes %d != %d", List_Nbr($$), List_Nbr($3));
          List_Delete($3);
        }
    
      | MultiFExpr '-' MultiFExpr
        {
          $$ = $1;
          if(List_Nbr($$) == List_Nbr($3)){
            for(int i = 0; i < List_Nbr($$); i++){
              double *pd = (double*)List_Pointer($$, i);
              double d = *(double*)List_Pointer($3, i);
              *pd -= d;
            }
          }
          else
            vyyerror(0, "Wrong list sizes %d != %d", List_Nbr($$), List_Nbr($3));
          List_Delete($3);
        }
    
      | MultiFExpr '*' MultiFExpr
        {
          $$ = $1;
          if(List_Nbr($$) == List_Nbr($3)){
            for(int i = 0; i < List_Nbr($$); i++){
              double *pd = (double*)List_Pointer($$, i);
              double d = *(double*)List_Pointer($3, i);
              *pd *= d;
            }
          }
          else
            vyyerror(0, "Wrong list sizes %d != %d", List_Nbr($$), List_Nbr($3));
          List_Delete($3);
        }
    
      | MultiFExpr '/' MultiFExpr
        {
          $$ = $1;
          if(List_Nbr($$) == List_Nbr($3)){
            for(int i = 0; i < List_Nbr($$); i++){
              double *pd = (double*)List_Pointer($$, i);
              double d = *(double*)List_Pointer($3, i);
              if(d) *pd /= d;
            }
          }
          else
            vyyerror(0, "Wrong list sizes %d != %d", List_Nbr($$), List_Nbr($3));
          List_Delete($3);
        }
    
      | FExpr tDOTS FExpr
        {
          $$ = List_Create(20,20,sizeof(double));
          for(double d = $1; ($1 < $3) ? (d <= $3) : (d >= $3);
    	  ($1 < $3) ? (d += 1.) : (d -= 1.))
    	List_Add($$, &d);
        }
    
      | FExpr tDOTS FExpr tDOTS FExpr
        {
          $$ = List_Create(20,20,sizeof(double));
          if(!$5 || ($1<$3 && $5<0) || ($1>$3 && $5>0)){
    	vyyerror(0, "Wrong increment in '%g : %g : %g'", $1, $3, $5);
    	List_Add($$, &($1));
          }
          else
    	for(double d = $1; ($5 > 0) ? (d <= $3) : (d >= $3); d += $5)
    	  List_Add($$, &d);
        }
    
      | tGetRegions '[' GroupRHS ']'
        {
          $$ = List_Create(List_Nbr(Group_S.InitialList),20,sizeof(double));
          int j;
          for(int k = 0; k < List_Nbr(Group_S.InitialList); k++) {
            List_Read(Group_S.InitialList, k, &j);
            double d = (double)j;
            List_Add($$, &d);
          }
        }
    
      | Struct_FullName '(' ')'
        {
          if ($1.char1) vyyerror(1, "NameSpace '%s' not used yet", $1.char1);
          $$ = List_Create(20,20,sizeof(double));
          Constant_S.Name = $1.char2;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
            vyyerror(0, "Unknown Constant: %s", $1.char2);
          else
            if(Constant_S.Type != VAR_LISTOFFLOAT)
              // vyyerror(0, "Multi value Constant needed: %s", $1.char2);
              List_Add($$, &Constant_S.Value.Float);
            else
              for(int i = 0; i < List_Nbr(Constant_S.Value.List); i++) {
                double d;
                List_Read(Constant_S.Value.List, i, &d);
                List_Add($$, &d);
              }
          Free($1.char1); Free($1.char2);
        }
    
      | Struct_FullName '(' '{' RecursiveListOfFExpr '}' ')'
        {
          if ($1.char1) vyyerror(1, "NameSpace '%s' not used yet", $1.char1);
          $$ = List_Create(20,20,sizeof(double));
          Constant_S.Name = $1.char2;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
    	vyyerror(0, "Unknown Constant: %s", $1.char2);
          else
    	if(Constant_S.Type != VAR_LISTOFFLOAT)
    	  vyyerror(0, "Multi value Constant needed: %s", $1.char2);
    	else
    	  for(int i = 0; i < List_Nbr($4); i++) {
                int j = (int)(*(double*)List_Pointer($4, i));
    	    if(j >= 0 && j < List_Nbr(Constant_S.Value.List)){
    	      double d;
    	      List_Read(Constant_S.Value.List, j, &d);
    	      List_Add($$, &d);
    	    }
    	    else{
                  vyyerror(0, "Index %d out of range", j);
    	      double d = 0.;
    	      List_Add($$, &d);
    	    }
    	  }
          List_Delete($4);
          Free($1.char1); Free($1.char2);
        }
    
      | Struct_FullName '.' tSTRING_Member '(' ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_ListOfFloat($1.char1, $1.char2, $3);
        }
    
      // same as tSTRING '(' ')'
      | tList '[' String__Index ']'
        {
          $$ = List_Create(20,20,sizeof(double));
          Constant_S.Name = $3;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
    	vyyerror(0, "Unknown Constant: %s", $3);
          else
    	if(Constant_S.Type != VAR_LISTOFFLOAT)
    	  vyyerror(0, "Multi value Constant needed: %s", $3);
    	else
    	  for(int i = 0; i < List_Nbr(Constant_S.Value.List); i++) {
    	    double d;
    	    List_Read(Constant_S.Value.List, i, &d);
    	    List_Add($$, &d);
    	  }
        }
    
      | tList '[' MultiFExpr ']'
        {
          $$ = $3;
        }
    
      | tList '[' '{' RecursiveListOfFExpr '}' ']'
        {
          $$ = $4;
        }
    
      | tListAlt '[' String__Index ',' String__Index ']'
        {
          $$ = List_Create(20,20,sizeof(double));
          Constant1_S.Name = $3; Constant2_S.Name = $5;
          if(!Tree_Query(ConstantTable_L, &Constant1_S)) {
    	vyyerror(0, "Unknown Constant: %s", $3);
          }
          else
    	if(Constant1_S.Type != VAR_LISTOFFLOAT) {
    	  vyyerror(0, "Multi value Constant needed: %s", $3);
    	}
    	else {
    	  if(!Tree_Query(ConstantTable_L, &Constant2_S)) {
    	    vyyerror(0, "Unknown Constant: %s", $5);
    	  }
    	  else
    	    if(Constant2_S.Type != VAR_LISTOFFLOAT) {
    	      vyyerror(0, "Multi value Constant needed: %s", $5);
    	    }
    	    else {
    	      if(List_Nbr(Constant1_S.Value.List) !=
                     List_Nbr(Constant2_S.Value.List)) {
    		vyyerror(0, "Different dimensions of Multi value Constants: "
    			 "%s {%d}, %s {%d}",
    			 $3, List_Nbr(Constant1_S.Value.List),
    			 $5, List_Nbr(Constant2_S.Value.List));
    	      }
    	      else {
    		for(int i = 0; i < List_Nbr(Constant1_S.Value.List); i++) {
    		  double d;
    		  List_Read(Constant1_S.Value.List, i, &d);
    		  List_Add($$, &d);
    		  List_Read(Constant2_S.Value.List, i, &d);
    		  List_Add($$, &d);
    		}
    	      }
    	    }
    	}
          Free($3); Free($5);
        }
    
      | tListAlt '[' MultiFExpr ',' MultiFExpr ']'
        {
          $$ = List_Create(20,20,sizeof(double));
          if(List_Nbr($3) != List_Nbr($5)) {
            vyyerror(0, "Different dimensions of lists: %d != %d",
                     List_Nbr($3), List_Nbr($5));
          }
          else {
            for(int i = 0; i < List_Nbr($3); i++) {
              double d;
              List_Read($3, i, &d);
              List_Add($$, &d);
              List_Read($5, i, &d);
              List_Add($$, &d);
            }
          }
          List_Delete($3);
          List_Delete($5);
        }
    
      | tLinSpace '[' FExpr ',' FExpr ',' FExpr ']'
        {
          $$ = List_Create(20,20,sizeof(double));
          for(int i = 0; i < (int)$7; i++) {
    	double d = $3 + ($5-$3)*(double)i/($7-1);
    	List_Add($$, &d);
          }
        }
    
      | tLogSpace '[' FExpr ',' FExpr ',' FExpr ']'
        {
          $$ = List_Create(20,20,sizeof(double));
          for(int i = 0; i < (int)$7; i++) {
    	double d = pow(10,$3 + ($5-$3)*(double)i/($7-1));
    	List_Add($$, &d);
          }
        }
    
      | tListFromFile '[' CharExpr ']'
        {
          Message::Barrier();
          FILE *File;
          $$ = List_Create(100, 100, sizeof(double));
          if(!(File = FOpen(Fix_RelativePath($3).c_str(), "rb"))){
            vyyerror(1, "Could not open file '%s'", $3);
          }
          else{
    	double d;
    	while(!feof(File)){
              int ret = fscanf(File, "%lf", &d);
    	  if(ret == 1){
    	    List_Add($$, &d);
              }
              else if(ret == EOF){
                break;
              }
              else{
                char dummy[1024];
                fscanf(File, "%s", dummy);
                vyyerror(1, "Ignoring '%s' in file '%s'", dummy, $3);
              }
            }
    	fclose(File);
          }
          Free($3);
        }
     ;
    
    StringIndex :
    
        tSTRING '~' '{' FExpr '}'
        {
          char tmpstr[256];
          sprintf(tmpstr, "_%d", (int)$4);
          $$ = (char *)Malloc((strlen($1)+strlen(tmpstr)+1)*sizeof(char));
          strcpy($$, $1); strcat($$, tmpstr);
          Free($1);
        }
    
      | StringIndex '~' '{' FExpr '}'
        {
          char tmpstr[256];
          sprintf(tmpstr, "_%d", (int)$4);
          $$ = (char *)Malloc((strlen($1)+strlen(tmpstr)+1)*sizeof(char)) ;
          strcpy($$, $1) ; strcat($$, tmpstr) ;
          Free($1);
        }
    
      | tStringToName '[' CharExpr ']' '~' '{' FExpr '}'
        {
          char tmpstr[256];
          sprintf(tmpstr, "_%d", (int)$7);
          $$ = (char *)Malloc((strlen($3)+strlen(tmpstr)+1)*sizeof(char));
          strcpy($$, $3); strcat($$, tmpstr);
          Free($3);
        }
     ;
    
    String__Index :
    
        tSTRING
        { $$ = $1; }
    
      | StringIndex
        { $$ = $1; }
    
      // Create a name from any string
      | tStringToName '[' CharExpr ']'
        { $$ = $3; }
     ;
    
    CharExprNoVar :
        tBIGSTR
        { $$ = $1; }
    
      | tNameToString '[' String__Index ']'
        { $$ = $3; }
    
      | StrCat
        {
          $$ = $1;
        }
    
      | tUpperCase '[' CharExpr ']'
        {
          int i = 0;
          while ($3[i]) {
            $3[i] = toupper($3[i]);
            i++;
          }
          $$ = $3;
        }
    
      | tLowerCase '[' CharExpr ']'
        {
          int i = 0;
          while ($3[i]) {
            $3[i] = tolower($3[i]);
            i++;
          }
          $$ = $3;
        }
    
      | tLowerCaseIn '[' CharExpr ']'
        {
          int i=0;
          while ($3[i]) {
            if (i > 0 && $3[i-1] != '_')
              $3[i] = tolower($3[i]);
            i++;
          }
          $$ = $3;
        }
    
      | tStr LP RecursiveListOfCharExpr RP
        {
          int size = 1;
          for(int i = 0; i < List_Nbr($3); i++){
            char *s;
            List_Read($3, i, &s);
            size += strlen(s) + 1;
          }
          $$ = (char*)Malloc(size * sizeof(char));
          $$[0] = '\0';
          for(int i = 0; i < List_Nbr($3); i++){
            char *s;
            List_Read($3, i, &s);
            strcat($$, s);
            Free(s);//FIXME: DONE with added function strEmpty()
            if(i != List_Nbr($3) - 1) strcat($$, "\n");
          }
          List_Delete($3);
        }
    
      | tStrChoice LP FExpr ',' CharExpr ',' CharExpr RP
        {
          if($3){
            $$ = $5;
            Free($7);
          }
          else{
            $$ = $7;
            Free($5);
          }
        }
    
      | tStrSub LP CharExpr ',' FExpr ',' FExpr RP
        {
          std::string in = $3;
          std::string out = in.substr((int)$5, (int)$7);
          $$ = (char *)Malloc((out.size() + 1) * sizeof(char));
          strcpy($$, out.c_str());
          Free($3);
        }
    
      | tStrSub LP CharExpr ',' FExpr RP
        {
          std::string in = $3;
          std::string out = in.substr((int)$5, std::string::npos);
          $$ = (char *)Malloc((out.size() + 1) * sizeof(char));
          strcpy($$, out.c_str());
          Free($3);
        }
    
      | tSprintf LP CharExpr RP
        {
          $$ = $3;
        }
    
      | tSprintf LP CharExpr ',' RecursiveListOfFExpr RP
        {
          char tmpstr[256];
          int i = Print_ListOfDouble($3,$5,tmpstr);
          if(i<0){
    	vyyerror(0, "Too few arguments in Sprintf");
    	$$ = $3;
          }
          else if(i>0){
    	vyyerror(0, "Too many arguments (%d) in Sprintf", i);
    	$$ = $3;
          }
          else{
    	$$ = (char*)Malloc((strlen(tmpstr)+1)*sizeof(char));
    	strcpy($$, tmpstr);
    	Free($3);
          }
          List_Delete($5);
        }
    
      | tDate
        {
          time_t date_info;
          time(&date_info);
          $$ = (char *)Malloc((strlen(ctime(&date_info))+1)*sizeof(char));
          strcpy($$, ctime(&date_info));
          $$[strlen($$)-1] = 0;
        }
    
      | tDate LP CharExpr RP
        {
          char str_date[80];
          time_t rawtime;
          struct tm * timeinfo;
    
          time (&rawtime);
          timeinfo = localtime (&rawtime);
          strftime (str_date, 80, $3, timeinfo);
          $$ = (char *)Malloc((strlen(str_date)+1)*sizeof(char));
          strcpy($$, str_date);
        }
    
      | tOnelabAction
        {
          std::string action = Message::GetOnelabAction();
          $$ = (char *)Malloc(action.size() + 1);
          strcpy($$, action.c_str());
        }
    
      | tCodeName
        {
          $$ = strSave((char*)"GetDP");
        }
    
      | tCurrentFileName
        {
          $$ = strSave(getdp_yyname.c_str());
        }
    
      | tCurrentDirectory
        {
          std::string tmp = GetDirName(GetFullPath(getdp_yyname));
          $$ = (char*)Malloc((tmp.size() + 1) * sizeof(char));
          strcpy($$, tmp.c_str());
        }
    
      | tAbsolutePath LP CharExpr RP
        {
          $$ = strSave(GetFullPath($3).c_str());
          Free($3);
        }
    
      | tDirName LP CharExpr RP
        {
          $$ = strSave(GetDirName($3).c_str());
          Free($3);
        }
    
      | tBaseFileName
        {
          $$ = strSave(GetBaseName(getdp_yyname).c_str());
        }
    
      | tFixRelativePath LP CharExpr RP
        {
          $$ = strSave(Fix_RelativePath($3).c_str());
          Free($3);
        }
    
      | tDefineString '[' CharExprNoVar
        { init_Options(); }
        CharParameterOptionsOrNone ']'
        {
          Constant_S.Name = (char*)""; Constant_S.Type = VAR_CHAR;
          Constant_S.Value.Char = $3;
          Message::ExchangeOnelabParameter(&Constant_S, floatOptions, charOptions);
          $$ = strSave(Constant_S.Value.Char);
          Free($3);
        }
    
      | tGetString LP CharExpr RP
        {
          $$ = strSave(Message::GetOnelabString($3, "").c_str());
          Free($3);
        }
    
      | tGetString LP CharExpr ',' CharExpr  RP
        {
          $$ = strSave(Message::GetOnelabString($3, $5).c_str());
          Free($3);
          Free($5);
        }
    
        //+++ No need to extend to Struct_FullName (a Tag is not a String), but...
      | tGetForcedStr '(' Struct_FullName GetForcedStr_Default ')'
        {
          $$ = Treat_Struct_FullName_String(NULL, $3.char2, 1, 0, $4, 2);
        }
    
      | tGetForcedStr '(' Struct_FullName '.' tSTRING_Member GetForcedStr_Default ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_String($3.char1, $3.char2, $5, 0, $6, 2);
        }
    
      | tNameStruct LP NameStruct_Arg RP
        {
          const std::string * key_struct = NULL;
          switch (nameSpaces.get_key_struct_from_tag(struct_namespace,
                                                     (int)$3, key_struct)) {
          case 0:
            $$ = strSave(key_struct->c_str());
            break;
          case 1:
            vyyerror(1, "Unknown NameSpace '%s' of Struct", struct_namespace.c_str());
            $$ = strEmpty();
            break;
          case 2:
            vyyerror(1, "Unknown Struct of Tag %d", (int)$3);
            $$ = strEmpty();
            break;
          default:
            $$ = strEmpty();
            break;
          }
        }
    ;
    
    NameStruct_Arg :
        '#' FExpr
        { struct_namespace = std::string(""); $$ = $2; }
      | String__Index tSCOPE '#' FExpr
        { struct_namespace = $1; Free($1); $$ = $4; }
    ;
    
    
    CharExpr :
    
        CharExprNoVar
        { $$ = $1; }
    
      | Struct_FullName
        {
          if ($1.char1) vyyerror(1, "NameSpace '%s' not used yet", $1.char1);
          // No need to extend to Struct_FullName (a Tag is not a String)
          $$ = Treat_Struct_FullName_String(NULL, $1.char2);
        }
    
      | Struct_FullName '(' FExpr ')'
        {
          $$ = Treat_Struct_FullName_String($1.char1, $1.char2, 2, (int)$3);
        }
    
      | Struct_FullName '.' tSTRING_Member
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_String($1.char1, $1.char2, $3);
        }
    
      | Struct_FullName '.' tSTRING_Member '(' FExpr ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_String($1.char1, $1.char2, $3, (int)$5);
        }
    ;
    
    Str_BracedRecursiveListOfCharExpr :
        tStr LP BracedRecursiveListOfCharExpr RP
        { $$ = $3; }
     ;
    
    BracedOrNotRecursiveListOfCharExpr :
        RecursiveListOfCharExpr
        { $$ = $1; }
      | BracedRecursiveListOfCharExpr
        { $$ = $1; }
     ;
    
    BracedRecursiveListOfCharExpr :
        '{' RecursiveListOfCharExpr '}'
        { $$ = $2; }
     ;
    
    RecursiveListOfCharExpr :
        CharExpr
        {
          $$ = List_Create(20,20,sizeof(char*));
          List_Add($$, &($1));
        }
      | MultiCharExpr
        { $$ = $1; }
      | RecursiveListOfCharExpr ',' CharExpr
        { List_Add($$, &($3)); }
      | RecursiveListOfCharExpr ',' MultiCharExpr
        {
          for(int i = 0; i < List_Nbr($3); i++){
    	char* c;
    	List_Read($3, i, &c);
    	List_Add($$, &c);
          }
          List_Delete($3);
        }
     ;
    
    MultiCharExpr :
        Struct_FullName '(' ')'
        {
          if ($1.char1) vyyerror(1, "NameSpace '%s' not used yet", $1.char1);
          $$ = List_Create(20,20,sizeof(char *));
          Constant_S.Name = $1.char2;
          if(!Tree_Query(ConstantTable_L, &Constant_S))
            vyyerror(0, "Unknown Constant: %s", $1.char2);
          else
            if(Constant_S.Type != VAR_LISTOFCHAR)
              // vyyerror(0, "Multi string Constant needed: %s", $1.char2);
              List_Add($$, &Constant_S.Value.Char);
            else
              for(int i = 0; i < List_Nbr(Constant_S.Value.List); i++) {
                char * c;
                List_Read(Constant_S.Value.List, i, &c);
                List_Add($$, &c);
              }
          Free($1.char1); Free($1.char2);
        }
      | Struct_FullName '.' tSTRING_Member '(' ')'
        {
          $$ = Treat_Struct_FullName_dot_tSTRING_ListOfString($1.char1, $1.char2, $3);
        }
    ;
    
    
    // these are for compatibility with the syntax in Gmsh (parentheses instead of
    // square brackets)
    
    LP : '(' { $$ = (char*)"("; } | '[' { $$ = (char*)"["; } ;
    RP : ')' { $$ = (char*)")"; } | ']' { $$ = (char*)"]"; } ;
    
    StrCat :
    
        tStrCat LP RecursiveListOfCharExpr RP
        {
          int size = 1;
          for(int i = 0; i < List_Nbr($3); i++){
            char *s;
            List_Read($3, i, &s);
            size += strlen(s) + 1;
          }
          $$ = (char*)Malloc(size * sizeof(char));
          $$[0] = '\0';
          for(int i = 0; i < List_Nbr($3); i++){
            char *s;
            List_Read($3, i, &s);
            strcat($$, s);
            Free(s);
          }
          List_Delete($3);
        }
     ;
    
    StrCmp :
    
        tStrCmp LP CharExpr ',' CharExpr RP
        {
          if ($3 != NULL && $5 != NULL) {
    	$$ = strcmp($3, $5);
          }
          else {
    	vyyerror(0, "Undefined argument for StrCmp function") ;  $$ = 1 ;
          }
          Free($3);
          Free($5);
        }
      | tStrLen LP CharExpr RP
        {
          if ($3 != NULL) {
    	$$ = strlen($3);
          }
          else {
    	vyyerror(0, "Undefined argument for StrLen function") ;  $$ = 0 ;
          }
          Free($3);
        }
      | tStrFind LP CharExpr ',' CharExpr RP
        {
          std::string s($3), substr($5);
          if(s.find(substr) != std::string::npos)
            $$ = 1.;
          else
            $$ = 0.;
          Free($3);
          Free($5);
        }
      ;
    
    NbrRegions :
    
        tNbrRegions '[' ']'
        {
          int n = 0;
          for(int i = 0; i < List_Nbr(Problem_S.Group); i++) {
    	n += List_Nbr(((struct Group *)List_Pointer(Problem_S.Group, i))
    		      ->InitialList) ;
          }
          $$ = n;
        }
      | tNbrRegions '[' String__Index ']'
        {
          int i;
          if ( (i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) >= 0 ) {
    	$$ = List_Nbr(((struct Group *)List_Pointer(Problem_S.Group, i))
    		      ->InitialList) ;
          }
          else {
    	vyyerror(0, "Unknown Group: %s", $3) ;  $$ = 0 ;
          }
        }
      | tGetRegion '[' String__Index ',' FExpr ']'
        {
          int i, j, indexInGroup;
          indexInGroup = (int)$5;
          if ( (i = List_ISearchSeq(Problem_S.Group, $3, fcmp_Group_Name)) >= 0 ) {
            if (indexInGroup >= 1 &&
                indexInGroup <= List_Nbr(((struct Group *)List_Pointer(Problem_S.Group, i))
                                         ->InitialList)) {
              List_Read(((struct Group *)List_Pointer(Problem_S.Group, i))->InitialList,
                        indexInGroup-1, &j) ;
              $$ = j;
            }
            else {
              vyyerror(0, "GetRegion: Index out of range [1..%d]",
                       List_Nbr(((struct Group *)List_Pointer(Problem_S.Group, i))
                                ->InitialList)) ;
              $$ = 0 ;
            }
          }
          else {
    	vyyerror(0, "Unknown Group: %s", $3) ;  $$ = 0 ;
          }
        }
      ;
    
    Append :
        tAppend
        { $$ = 99; } // Default: max level
      | tAppend FExpr
        { $$ = (int)$2; }
      ;
    
    AppendOrNot :
        /* none */
        { $$ = 0; }
      | '(' Append ')'
        { $$ = $2; }
      ;
    
    %%
    
    // This is a hack... Bison redefines 'const' if !__cplusplus and !__STDC__
    #ifdef const
    #undef const
    #endif
    
    void Alloc_ParserVariables()
    {
      if(!ConstantTable_L) {
        ConstantTable_L = Tree_Create(sizeof(struct Constant), fcmp_Constant);
        for(std::map<std::string, std::vector<double> >::iterator it =
              CommandLineNumbers.begin(); it != CommandLineNumbers.end(); it++){
          std::vector<double> &v(it->second);
          Constant_S.Name = strSave(it->first.c_str());
          if(v.size() == 1){
            Message::Info("Adding number %s = %g", it->first.c_str(), v[0]);
            Constant_S.Type = VAR_FLOAT;
            Constant_S.Value.Float = v[0];
          }
          else{
            Message::Info("Adding list of numbers %s", it->first.c_str());
            Constant_S.Type = VAR_LISTOFFLOAT;
            Constant_S.Value.List = List_Create(v.size(), 1, sizeof(double));
            for(unsigned int i = 0; i < v.size(); i ++)
              List_Add(Constant_S.Value.List, &v[i]);
          }
          Tree_Add(ConstantTable_L, &Constant_S);
        }
        for(std::map<std::string, std::vector<std::string> >::iterator it = CommandLineStrings.begin();
            it != CommandLineStrings.end(); it++){
          std::vector<std::string> &v(it->second);
          Constant_S.Name = strSave(it->first.c_str());
          if(v.size() == 1){
            Message::Info("Adding string %s = \"%s\"", it->first.c_str(), v[0].c_str());
            Constant_S.Type = VAR_CHAR;
            Constant_S.Value.Char = strSave(v[0].c_str());
          }
          else{
            Message::Info("Adding list of strings %s", it->first.c_str());
            Constant_S.Type = VAR_LISTOFCHAR;
            Constant_S.Value.List = List_Create(v.size(), 1, sizeof(char*));
            for(unsigned int i = 0; i < v.size(); i ++)
              List_Add(Constant_S.Value.List, strSave(v[i].c_str()));
          }
          Tree_Add(ConstantTable_L, &Constant_S);
        }
    
        ListOfInt_L     = List_Create(20, 10, sizeof(int));
        ListOfPointer_L = List_Create(10, 10, sizeof(void *));
        ListOfPointer2_L= List_Create(10, 10, sizeof(void *));
        ListOfChar_L    = List_Create(128, 128, sizeof(char));
        ListOfFormulation   = List_Create(5,5, sizeof(int));
        ListOfBasisFunction = List_Create(5,5, sizeof(List_T *));
        ListOfEntityIndex   = List_Create(5,5, sizeof(int));
      }
    }
    
    void Free_ParserVariables()
    {
      List_T *tmp = Tree2List(ConstantTable_L);
      for(int i = 0; i < List_Nbr(tmp); i++){
        Constant *Constant_P = (struct Constant*)List_Pointer(tmp, i);
        std::string name = Constant_P->Name;
        switch(Constant_P->Type){
        case VAR_FLOAT:
          if(!GetDPNumbers.count(name))
            GetDPNumbers[name] = std::vector<double>(1, Constant_P->Value.Float);
          break;
        case VAR_LISTOFFLOAT:
          if(!GetDPNumbers.count(name)){
            std::vector<double> v;
            for(int j = 0; j < List_Nbr(Constant_P->Value.List); j++){
              double d;
              List_Read(Constant_P->Value.List, j, &d);
              v.push_back(d);
            }
            GetDPNumbers[name] = v;
          }
          break;
        case VAR_CHAR:
          if(!GetDPStrings.count(name))
            GetDPStrings[name] = std::vector<std::string>(1, Constant_P->Value.Char);
          break;
        case VAR_LISTOFCHAR:
          if(!GetDPStrings.count(name)){
            std::vector<std::string> v;
            for(int j = 0; j < List_Nbr(Constant_P->Value.List); j++){
              char *s;
              List_Read(Constant_P->Value.List, j, &s);
              v.push_back(s);
            }
            GetDPStrings[name] = v;
          }
          break;
        }
      }
      List_Delete(tmp);
    
      Tree_Delete(ConstantTable_L); ConstantTable_L = 0;
      List_Delete(ListOfInt_L); ListOfInt_L = 0;
      List_Delete(ListOfPointer_L); ListOfPointer_L = 0;
      List_Delete(ListOfPointer2_L); ListOfPointer2_L = 0;
      List_Delete(ListOfChar_L); ListOfChar_L = 0;
      List_Delete(ListOfFormulation); ListOfFormulation = 0;
      List_Delete(ListOfBasisFunction); ListOfBasisFunction = 0;
      List_Delete(ListOfEntityIndex); ListOfEntityIndex = 0;
      getdp_yyname = "";
      strcpy(getdp_yyincludename, "");
      getdp_yylinenum = 0;
      getdp_yycolnum = 0;
      getdp_yyincludenum = 0;
      getdp_yyerrorlevel = 0;
      CommandLineNumbers.clear();
      CommandLineStrings.clear();
      Num_BasisFunction = 1;
      num_include = 0; level_include = 0;
    }
    
    /*  A d d _ G r o u p   &   C o .  */
    
    int  Add_Group(struct Group *Group_P, char *Name, bool Flag_Add,
                   int Flag_Plus, int Num_Index)
    {
      if(!Problem_S.Group)
        Problem_S.Group = List_Create(50, 50, sizeof (struct Group));
    
      char tmpstr[256];
      switch (Flag_Plus) {
      case 1 :
        sprintf(tmpstr, "_%s_%d", Name, List_Nbr(Problem_S.Group));
        Group_P->Name = strSave(tmpstr);
        break;
      case 2 :
        sprintf(tmpstr, "%s_%d", Name, Num_Index);
        Group_P->Name = strSave(tmpstr);
        break;
      default :
        Group_P->Name = Name;
      }
    
      int i;
      if((i = List_ISearchSeq(Problem_S.Group, Group_P->Name, fcmp_Group_Name)) < 0) {
        i = Group_P->Num = List_Nbr(Problem_S.Group);
        Group_P->ExtendedList = Group_P->ExtendedSuppList = Group_P->ExtendedSuppList2 = NULL;
        List_Add(Problem_S.Group, Group_P);
      }
      else if(Flag_Add) {
        List_T *InitialList = ((struct Group *)List_Pointer(Problem_S.Group, i))->InitialList;
        for(int j = 0; j < List_Nbr(Group_P->InitialList); j++) {
          List_Add(InitialList, (int *)List_Pointer(Group_P->InitialList, j));
        }
      }
      else  List_Write(Problem_S.Group, i, Group_P);
    
      return i;
    }
    
    int  Num_Group(struct Group *Group_P, char *Name, int Num_Group)
    {
      if     (Num_Group >= 0)   /* OK */;
      else if(Num_Group == -1)  Num_Group = Add_Group(Group_P, Name, false, 1, 0);
      else                      vyyerror(0, "Bad Group right hand side");
    
      return Num_Group;
    }
    
    void Fill_GroupInitialListFromString(List_T *list, const char *str)
    {
      bool found = false;
    
      // try to find a group with name "str"
      for(int i = 0; i < List_Nbr(Problem_S.Group); i++){
        struct Group *Group_P = (struct Group*)List_Pointer(Problem_S.Group, i);
        if(!strcmp(str, Group_P->Name)){
          List_Copy(Group_P->InitialList, list);
          found = true;
          break;
        }
      }
    
      // try to find a constant with name "str"
      Constant_S.Name = (char*)str;
      Constant *Constant_P = (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
      if(Constant_P){
        switch(Constant_P->Type){
        case VAR_FLOAT:
          {
            int num = (int)Constant_P->Value.Float;
            List_Add(list, &num);
          }
          found = true;
          break;
        case VAR_LISTOFFLOAT:
          for(int j = 0; j < List_Nbr(Constant_P->Value.List); j++){
            double d;
            List_Read(Constant_P->Value.List, j, &d);
            int num = (int)d;
            List_Add(list, &num);
          }
          found = true;
          break;
        }
      }
    
      // if not, try to convert "str" to an integer
      if(!found){
        int num = atoi(str);
        if(num > 0){
          List_Add(list, &num);
          found = true;
        }
      }
    
      if(!found) vyyerror(0, "Unknown Group '%s'", str);
    }
    
    /*  A d d _ E x p r e s s i o n   */
    
    int  Add_Expression(struct Expression *Expression_P,
    		    char *Name, int Flag_Plus)
    {
      if(!Problem_S.Expression)
        Problem_S.Expression = List_Create(50, 50, sizeof (struct Expression));
    
      switch (Flag_Plus) {
      case 1 :
        char tmpstr[256];
        sprintf(tmpstr, "_%s_%d", Name, List_Nbr(Problem_S.Expression)) ;
        Expression_P->Name = strSave(tmpstr) ;
        break ;
      case 2 :
        Expression_P->Name = strSave(Name) ;
        break ;
      default :
        Expression_P->Name = Name ;
      }
    
      int  i;
      if((i = List_ISearchSeq
           (Problem_S.Expression, Name, fcmp_Expression_Name)) < 0) {
        i = List_Nbr(Problem_S.Expression);
        List_Add(Problem_S.Expression, Expression_P);
      }
      else  List_Write(Problem_S.Expression, i, Expression_P);
    
      return i;
    }
    
    bool Is_ExpressionPieceWiseDefined(int index)
    {
      struct Expression *e = (struct Expression *)List_Pointer(Problem_S.Expression, index);
      if(e->Type == PIECEWISEFUNCTION)
        return true;
      else if(e->Type == WHOLEQUANTITY){
        for(int i = 0; i < List_Nbr(e->Case.WholeQuantity); i++){
          struct WholeQuantity *w = (struct WholeQuantity *)List_Pointer(e->Case.WholeQuantity, i);
          if(w->Type == WQ_EXPRESSION)
            return Is_ExpressionPieceWiseDefined(w->Case.Expression.Index);
        }
      }
      return false;
    }
    
    /*  L i s t e   I n d e x   d e s   D e f i n e Q u a n t i t y  */
    
    void  Pro_DefineQuantityIndex_1(List_T *WholeQuantity_L, int TraceGroupIndex,
                                    std::vector<std::pair<int, int> > &pairs)
    {
      struct WholeQuantity *WholeQuantity_P;
    
      WholeQuantity_P = (List_Nbr(WholeQuantity_L) > 0)?
        (struct WholeQuantity*)List_Pointer(WholeQuantity_L, 0) : NULL;
    
      for(int i = 0; i < List_Nbr(WholeQuantity_L); i++)
        switch ((WholeQuantity_P+i)->Type) {
        case WQ_OPERATORANDQUANTITY :
        case WQ_OPERATORANDQUANTITYEVAL :
        case WQ_SOLIDANGLE :
        case WQ_ORDER :
          {
            std::pair<int, int> p((WholeQuantity_P+i)->Case.OperatorAndQuantity.Index,
                                  TraceGroupIndex);
            if(std::find(pairs.begin(), pairs.end(), p) == pairs.end())
              pairs.push_back(p);
          }
          break;
        case WQ_MHTRANSFORM  :
          for(int j = 0; j < List_Nbr((WholeQuantity_P+i)->Case.MHTransform.WholeQuantity_L); j++){
            List_T *WQ; List_Read((WholeQuantity_P+i)->Case.MHTransform.WholeQuantity_L, j, &WQ);
            Pro_DefineQuantityIndex_1(WQ, TraceGroupIndex, pairs);
          }
          break;
        case WQ_MHBILINEAR  :
          for(int j = 0; j < List_Nbr((WholeQuantity_P+i)->Case.MHBilinear.WholeQuantity_L); j++){
            List_T *WQ; List_Read((WholeQuantity_P+i)->Case.MHBilinear.WholeQuantity_L, j, &WQ);
            Pro_DefineQuantityIndex_1(WQ, TraceGroupIndex, pairs);
          }
          break;
        case WQ_TIMEDERIVATIVE :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.TimeDerivative.WholeQuantity, TraceGroupIndex, pairs);
          break;
        case WQ_ATANTERIORTIMESTEP :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.AtAnteriorTimeStep.WholeQuantity, TraceGroupIndex, pairs);
          break;
        case WQ_MAXOVERTIME :
        case WQ_FOURIERSTEINMETZ :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.AtAnteriorTimeStep.WholeQuantity, TraceGroupIndex, pairs);
          break;
        case WQ_CAST :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.Cast.WholeQuantity, TraceGroupIndex, pairs);
          break;
        case WQ_TRACE :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.Trace.WholeQuantity,
    	 (WholeQuantity_P+i)->Case.Trace.InIndex, pairs);
          break;
        case WQ_TEST :
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.Test.WholeQuantity_True, TraceGroupIndex, pairs);
          Pro_DefineQuantityIndex_1
    	((WholeQuantity_P+i)->Case.Test.WholeQuantity_False, TraceGroupIndex, pairs);
          break;
        }
      std::sort(pairs.begin(), pairs.end());
    }
    
    void  Pro_DefineQuantityIndex(List_T *WholeQuantity_L,
    			      int DefineQuantityIndexEqu,
    			      int *NbrQuantityIndex, int **QuantityIndexTable,
    			      int **QuantityTraceGroupIndexTable)
    {
      std::vector<std::pair<int, int> > pairs;
    
      /* special case for the Equ part (right of the comma)
         FIXME: change this when we allow a full WholeQuantity expression
         there */
      Pro_DefineQuantityIndex_1(WholeQuantity_L, -1, pairs);
    
      if(DefineQuantityIndexEqu >= 0){
        std::pair<int, int> p(DefineQuantityIndexEqu, -1);
        pairs.push_back(p);
      }
    
      *NbrQuantityIndex = pairs.size();
      *QuantityIndexTable = (int *)Malloc(pairs.size() * sizeof(int));
      *QuantityTraceGroupIndexTable = (int *)Malloc(pairs.size() * sizeof(int));
      for(unsigned int i = 0; i < pairs.size(); i++){
        (*QuantityIndexTable)[i] = pairs[i].first;
        (*QuantityTraceGroupIndexTable)[i] = pairs[i].second;
      }
    }
    
    /* C h e c k _ N a m e O f S t r u c t N o t E x i s t   */
    
    int  Check_NameOfStructExist(const char *Struct, List_T *List_L, void *data,
                                 int (*fcmp)(const void *a, const void *b),
                                 int level_Append)
    {
      int i;
      if((i=List_ISearchSeq(List_L, data, fcmp)) >= 0 && !level_Append)
        vyyerror(0, "Redefinition of %s %s", Struct, (char*)data);
      return i;
    }
    
    
    /* P r i n t _ C o n s t a n t  */
    
    int Print_ListOfDouble(char *format, List_T *list, char *buffer)
    {
      // if format does not contain formatting characters, dump the list (useful for
      // quick debugging of lists)
      int numFormats = 0;
      for(unsigned int i = 0; i < strlen(format); i++)
        if(format[i] == '%') numFormats++;
      if(!numFormats){
        strcpy(buffer, format);
        for(int i = 0; i < List_Nbr(list); i++){
          double d;
          List_Read(list, i, &d);
          char tmp[256];
          sprintf(tmp, " [%d]%g", i, d);
          strcat(buffer, tmp);
        }
        return 0;
      }
    
      char tmp1[256], tmp2[256];
      int j = 0, k = 0;
      buffer[j] = '\0';
    
      while(j < (int)strlen(format) && format[j] != '%') j++;
      strncpy(buffer, format, j);
      buffer[j] = '\0';
      for(int i = 0; i < List_Nbr(list); i++){
        k = j;
        j++;
        if(j < (int)strlen(format)){
          if(format[j] == '%'){
    	strcat(buffer, "%");
    	j++;
          }
          while(j < (int)strlen(format) && format[j] != '%') j++;
          if(k != j){
    	strncpy(tmp1, &(format[k]), j-k);
    	tmp1[j-k] = '\0';
    	sprintf(tmp2, tmp1, *(double*)List_Pointer(list, i));
    	strcat(buffer, tmp2);
          }
        }
        else
          return List_Nbr(list) - i;
      }
      if(j != (int)strlen(format))
        return -1;
      return 0;
    }
    
    void Print_Constants()
    {
      struct Constant *Constant_P;
    
      Message::Check("Constants:\n");
    
      List_T *tmp = Tree2List(ConstantTable_L);
    
      for(int i = 0; i < List_Nbr(tmp); i++){
        Constant_P = (struct Constant*)List_Pointer(tmp, i);
        switch(Constant_P->Type){
        case VAR_FLOAT:
          Message::Check("%s = %g;\n", Constant_P->Name, Constant_P->Value.Float);
          break;
        case VAR_LISTOFFLOAT:
          {
            std::string str(Constant_P->Name);
            str += "() = {";
            for(int j = 0; j < List_Nbr(Constant_P->Value.List); j++){
              if(j) str += ",";
              double d;
              List_Read(Constant_P->Value.List, j, &d);
              char tmp[32];
              sprintf(tmp, "%g", d);
              str += tmp;
            }
            str += "};\n";
            Message::Check(str.c_str());
          }
          break;
        case VAR_CHAR:
          Message::Check("%s = \"%s\";\n", Constant_P->Name, Constant_P->Value.Char);
          break;
        case VAR_LISTOFCHAR:
          {
            std::string str(Constant_P->Name);
            str += "() = Str[{";
            for(int j = 0; j < List_Nbr(Constant_P->Value.List); j++){
              if(j) str += ",";
              char *s;
              List_Read(Constant_P->Value.List, j, &s);
              str += std::string("\"") + s + std::string("\"");
            }
            str += "}];\n";
            Message::Check(str.c_str());
          }
          break;
        }
      }
    
      List_Delete(tmp);
      Print_Struct();
    }
    
    void Print_Struct()
    {
      std::vector<std::string> strs;
      nameSpaces.sprint(strs);
      for(unsigned int i = 0; i < strs.size(); i++)
        Message::Check(strs[i].c_str());
    }
    
    Constant *Get_ParserConstant(char *name)
    {
      Constant_S.Name = name;
      return (Constant*)Tree_PQuery(ConstantTable_L, &Constant_S);
    }
    
    /*  E r r o r   h a n d l i n g  */
    
    void yyerror(const char *s)
    {
      extern char *getdp_yytext;
      Message::Error("'%s', line %ld : %s (%s)", getdp_yyname.c_str(),
                     getdp_yylinenum, s, getdp_yytext);
      getdp_yyerrorlevel = 1;
    }
    
    void vyyerror(int level, const char *fmt, ...)
    {
      char str[256];
      va_list args;
      va_start(args, fmt);
      vsprintf(str, fmt, args);
      va_end(args);
      if(level == 0){
        Message::Error("'%s', line %ld : %s", getdp_yyname.c_str(),
                       getdp_yylinenum, str);
        getdp_yyerrorlevel = 1;
      }
      else{
        Message::Warning("'%s', line %ld : %s", getdp_yyname.c_str(),
                         getdp_yylinenum, str);
      }
    }
    
    //
    double Treat_Struct_FullName_Float
    (char* c1, char* c2, int type_var, int index, double val_default, int type_treat)
    {
      double out;
      Constant_S.Name = c2;
      if(!c1 && Tree_Query(ConstantTable_L, &Constant_S)) {
        if (type_treat == 1) out = 1.; // Exists (type_treat == 1)
        else { // Get (0) or GetForced (2)
          if (type_var == 1) {
            if(Constant_S.Type == VAR_FLOAT)
              out = Constant_S.Value.Float;
            else {
              out = val_default;
              if (type_treat == 0)
                vyyerror(0, "Single value Constant needed: %s", struct_name.c_str());
            }
          }
          else if (type_var == 2) {
            if(Constant_S.Type == VAR_LISTOFFLOAT) {
              if(index >= 0 && index < List_Nbr(Constant_S.Value.List))
                List_Read(Constant_S.Value.List, index, &out);
              else {
                out = val_default;
                if (type_treat == 0)
                  vyyerror(0, "Index %d out of range", index);
              }
            }
            else {
              out = val_default;
              if (type_treat == 0)
                vyyerror(0, "Multi value Constant needed: %s", struct_name.c_str());
            }
          }
          else {
            out = val_default;
          }
        }
      }
      else {
        if (type_var == 1) {
          std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
          if(nameSpaces.getTag(struct_namespace, struct_name, out)) {
            out = val_default;
            if (type_treat == 0) vyyerror(0, "Unknown Constant: %s", struct_name.c_str());
          }
        }
        else {
          out = val_default;
          if (type_treat == 0) vyyerror(0, "Unknown Constant: %s(.)", c2);
        }
      }
      Free(c1); Free(c2);
      return out;
    }
    
    double Treat_Struct_FullName_dot_tSTRING_Float
    (char* c1, char* c2, char* c3, int index, double val_default, int type_treat)
    {
      double out;
      std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
      std::string key_member(c3);
      switch (nameSpaces.getMember
              (struct_namespace, struct_name, key_member, out, index)) {
      case 0:
        if (type_treat == 1) out = 1.; // Exists (type_treat == 1)
        break;
      case 1:
        out = val_default;
        if (type_treat == 0)
          vyyerror(0, "Unknown Struct: %s", struct_name.c_str());
        break;
      case 2:
        if (type_treat != 0) {
          const std::string * out_dummy = NULL;
          out = (nameSpaces.getMember
                 (struct_namespace, struct_name, key_member, out_dummy))?
            val_default : 1.;
        }
        else {
          out = val_default;
          if (type_treat == 0)
            vyyerror(0, "Unknown member '%s' of Struct %s", c3, struct_name.c_str());
        }
        break;
      case 3:
        out = val_default;
        if (type_treat == 0)
          vyyerror(0, "Index %d out of range", index);
        break;
      }
      Free(c1); Free(c2);
      if (flag_tSTRING_alloc) Free(c3);
      return out;
    }
    
    List_T * Treat_Struct_FullName_dot_tSTRING_ListOfFloat
    (char* c1, char* c2, char* c3)
    {
      List_T * out, * val_default = NULL;
      const std::vector<double> * out_vector; double val_;
      std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
      std::string key_member(c3);
      switch (nameSpaces.getMember_Vector
              (struct_namespace, struct_name, key_member, out_vector)) {
      case 0:
        out = List_Create(out_vector->size(), 1, sizeof(double));
        for(unsigned int i = 0; i < out_vector->size(); i++) {
          val_ = out_vector->at(i);
          List_Add(out, &val_);
        }
        break;
      case 1:
        vyyerror(0, "Unknown Struct: %s", struct_name.c_str());
        out = val_default;
        break;
      case 2:
        out = val_default;
        vyyerror(0, "Unknown member '%s' of Struct %s", c3, struct_name.c_str());
        break;
      }
      Free(c1); Free(c2);
      if (flag_tSTRING_alloc) Free(c3);
      return out;
    }
    
    int Treat_Struct_FullName_dot_tSTRING_Float_getDim
    (char* c1, char* c2, char* c3)
    {
      int out;
      std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
      std::string key_member(c3);
      switch (nameSpaces.getMember_Dim
              (struct_namespace, struct_name, key_member, out)) {
      case 0:
        break;
      case 1:
        out = 0;
        vyyerror(0, "Unknown Struct: %s", struct_name.c_str());
        break;
      case 2:
        out = 0;
        vyyerror(0, "Unknown member '%s' of Struct %s", c3, struct_name.c_str());
        break;
      }
      Free(c1); Free(c2);
      if (flag_tSTRING_alloc) Free(c3);
      return out;
    }
    
    char * Treat_Struct_FullName_String
    (char* c1, char* c2, int type_var, int index, char * val_default, int type_treat)
    {
      const char * out = NULL;
      Constant_S.Name = c2;
      if(!c1 && Tree_Query(ConstantTable_L, &Constant_S)) {
        if (type_var == 1) {
          if(Constant_S.Type == VAR_CHAR)
            out = Constant_S.Value.Char;
          else {
            out = val_default;
            if (type_treat == 0)
              vyyerror(0, "String Constant needed: %s", c2);
          }
        }
        else if (type_var == 2) {
          if(Constant_S.Type == VAR_LISTOFCHAR) {
            if(index >= 0 && index < List_Nbr(Constant_S.Value.List))
              List_Read(Constant_S.Value.List, index, &out);
            else {
              out = val_default;
              vyyerror(0, "Index %d out of range", index);
            }
          }
          else {
            out = val_default;
            if (type_treat == 0)
              vyyerror(0, "List of string Constant needed: %s", struct_name.c_str());
          }
        }
        else {
          out = val_default;
        }
      }
      else  {
        out = val_default;
        if (type_treat == 0)
          vyyerror(0, "Unknown Constant: %s", c2);
      }
      char* out_c = strSave(out);
      Free(c1); Free(c2);
      return out_c;
    }
    
    char* Treat_Struct_FullName_dot_tSTRING_String
    (char* c1, char* c2, char* c3, int index, char * val_default, int type_treat)
    {
      std::string string_default(val_default? val_default : std::string(""));
      const std::string * out = NULL;
      std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
      std::string key_member(c3);
      switch (nameSpaces.getMember
              (struct_namespace, struct_name, key_member, out, index)) {
      case 0:
        break;
      case 1:
        out = &string_default;
        if (type_treat == 0)
          vyyerror(0, "Unknown Struct: %s", struct_name.c_str());
        break;
      case 2:
        out = &string_default;
        if (type_treat == 0)
          vyyerror(0, "Unknown member '%s' of Struct %s", c3, struct_name.c_str());
        break;
      case 3:
        out = &string_default;
        if (type_treat == 0)
          vyyerror(0, "Index %d out of range", index);
        break;
      }
      char* out_c = strSave(out->c_str());
      Free(c1); Free(c2);
      if (flag_tSTRING_alloc) Free(c3);
      return out_c;
    }
    
    List_T * Treat_Struct_FullName_dot_tSTRING_ListOfString
    (char* c1, char* c2, char* c3)
    {
      List_T * out, * val_default = NULL;
      const std::vector<std::string> * out_vector; char * val_;
      std::string struct_namespace(c1? c1 : std::string("")), struct_name(c2);
      std::string key_member(c3);
      switch (nameSpaces.getMember_Vector
              (struct_namespace, struct_name, key_member, out_vector)) {
      case 0:
        out = List_Create(out_vector->size(), 1, sizeof(char *));
        for(unsigned int i = 0; i < out_vector->size(); i++) {
          val_ = strSave(out_vector->at(i).c_str());
          List_Add(out, &val_);
        }
        break;
      case 1:
        vyyerror(0, "Unknown Struct: %s", struct_name.c_str());
        out = val_default;
        break;
      case 2:
        out = val_default;
        vyyerror(0, "Unknown member '%s' of Struct %s", c3, struct_name.c_str());
        break;
      }
      Free(c1); Free(c2);
      if (flag_tSTRING_alloc) Free(c3);
      return out;
    }