/* * * (c) COPYRIGHT INRIA, Grif, 1996. * Please first read the full copyright statement in file COPYRIGHT. * */ /* * Warning: * This module is part of the Thot library, which was originally * developed in French. That's why some comments are still in * French, but their translation is in progress and the full module * will be available in English in the next release. * */ /* * Ce programme compile un schema de traduction contenu dans un fichier * de type .T * Il est dirige' par la grammaire du langage de * contenue, sous forme codee, dans le fichier TRANS.GRM. * Il produit un fichier de type .TRA qui sera ensuite utilise' * par le traducteur, pour guider sa traduction. * * Author: V. Quint (INRIA) * */ #include "thot_sys.h" #include "tradef.h" #include "constgrm.h" #include "constmedia.h" #include "consttra.h" #include "typemedia.h" #include "typegrm.h" #include "fileaccess.h" #include "compilmsg.h" #include "tramsg.h" #include "message.h" #include "thotpattern.h" #include "fileaccess.h" #include "thotdir.h" #define THOT_EXPORT #include "compil_tv.h" #include "platform_tv.h" #include "thotcolor.h" #include "thotcolor_tv.h" #include "thotpalette_tv.h" #undef THOT_EXPORT #define THOT_EXPORT extern #include "analsynt_tv.h" int LineNum; /* compteur de lignes */ static PtrSSchema pSSchema; /* pointeur sur le schema de structure */ static PtrSSchema pExtSSchema; /* pointeur sur le schema de structure externe */ static PtrTSchema pTSchema; /* pointeur sur le schema de traduction */ static boolean BuffDef; /* on est dans les declarations de buffers */ static boolean ConstDef; /* on est dans les declaration de constantes */ static boolean ComptDef; /* on est dans les declarations de compteurs */ static boolean VarDef; /* on est dans les declarations de variables */ static boolean InTypeRules; /* on est dans les regles des types */ static boolean InAttrRules; /* on est dans les regles des attributs */ static boolean InPresRules; /* on est dans les regles de la presentation */ static boolean InCondBlock; /* on est dans un bloc conditionnel */ static boolean InCondition; /* on analyse une condition 'If...TRuleBlock' */ static boolean TextTrans; /* on est dans les traductions de texte */ static boolean SymbTrans; /* on est dans les traductions de symbole */ static boolean GraphTrans; /* on est dans les traductions de graphique */ static int CurType; /* numero du type d'element courant */ static int CurAttr; /* numero de l'attribut courant */ static int CurValAttr; /* numero de la valeur d'attribut */ static int CurPres; /* numero de la presentation courante */ static int CurPresVal; /* numero de la valeur courante de la presentation courante */ static boolean ChangeRuleBlock; /* il faut ouvrir un nouveau bloc de regles */ static PtrTRuleBlock CurBlock; /* bloc de regles courant */ static PtrTRule CurTRule; /* current translation SyntacticRule */ static int CurEntry; /* entree courante de la table de traduction de caracteres */ static int ConstIndx; /* indice courant dans le buffer des constantes */ static boolean ExternalSchema; /* TypeIdent est un nom de schema externe */ static Name TypeInGetRule; /* TypeIdent dans la regle Get courante */ static int BeginTypeInGetRule; /* indice du debut du TypeIdent dans la ligne */ static Name TypeWithin; /* TypeIdent dans la condition Within ou */ /* First Within en cours d'analyse */ static int BeginTypeWithin; /* indice du debut de ce TypeIdent dans la */ /* ligne en cours de traitement */ static Name AncestorName; /* 1er TypeIdent dans la regle LevelOrType */ static int BeginAncestorName; /* indice du debut de ce TypeIdent dans la */ /* ligne en cours de traitement */ static boolean Immediately; /* condition Immediately Within */ static boolean Asterisk; /* on a rencontre' "" dans une condition */ static boolean GreaterOrLessSign; /* On a rencontre' un signe > ou < apres */ /* Within ou FirstWithin dans la condition */ /* courante */ static int AttrValSign; /* Signe d'une valeur d'attribut numerique */ static int PresValSign; /* Signe d'une valeur de presentation */ /* numerique */ static int AncestorSign; /* signe du dernier niveau d'ancetre */ /* rencontre' dans un compteur */ static int IndentSign; /* identation sign */ static boolean VarDefinition; static boolean FirstInPair; /* on a rencontre' "First" */ static boolean SecondInPair; /* on a rencontre' "Second" */ #include "platform_f.h" #include "parser_f.h" #include "readstr_f.h" #include "writetra_f.h" #include "fileaccess_f.h" #include "memory_f.h" #include "message_f.h" #include "compilmsg_f.h" #include "registry_f.h" /*---------------------------------------------------------------------- Initialize initialise le schema de traduction en memoire ----------------------------------------------------------------------*/ #ifdef __STDC__ static void Initialize () #else /* __STDC__ */ static void Initialize () #endif /* __STDC__ */ { int i; BuffDef = False; ConstDef = False; ComptDef = False; VarDef = False; InTypeRules = False; InAttrRules = False; InPresRules = False; TextTrans = False; SymbTrans = False; GraphTrans = False; ChangeRuleBlock = False; InCondBlock = False; ConstIndx = 1; CurBlock = NULL; CurTRule = NULL; ExternalSchema = False; InCondition = False; AttrValSign = 1; PresValSign = 1; FirstInPair = False; SecondInPair = False; Asterisk = False; TypeWithin[0] = '\0'; AncestorName[0] = '\0'; GetSchStruct (&pExtSSchema); GetSchStruct (&pSSchema); GetSchTra (&pTSchema); if (pTSchema == NULL || pSSchema == NULL || pExtSSchema == NULL) TtaDisplaySimpleMessage (FATAL, TRA, OUT_OF_MEMORY); /* initialise le schema de traduction */ pTSchema->TsLineLength = 0; /* pas de longueur max des lignes traduites */ strcpy (pTSchema->TsEOL, "\n"); /* caractere fin de ligne par defaut */ strcpy (pTSchema->TsTranslEOL, "\n"); /* fin de ligne a inserer par defaut */ pTSchema->TsNConstants = 0; /* nombre de constantes */ pTSchema->TsNCounters = 0; /* nombre de compteurs */ pTSchema->TsNVariables = 0; /* nombre de variables de traduction */ pTSchema->TsNBuffers = 0; /* nombre de buffers */ pTSchema->TsPictureBuffer = 0; /* pas de buffer pour les images */ for (i = 0; i < MAX_RULES_SSCHEMA; i++) { pTSchema->TsElemTRule[i] = NULL; /* pointeurs sur le debut de la chaine de regles de traduction specifiques a chaque type d'element */ pTSchema->TsInheritAttr[i] = False; } for (i = 0; i < MAX_TRANSL_PRULE; i++) pTSchema->TsPresTRule[i].RtExist = False; pTSchema->TsNTranslAlphabets = 0; /* pas de traduction de texte */ pTSchema->TsSymbolFirst = 0; /* indice de la 1ere regle de traduction de symboles dans la table TsCharTransl */ pTSchema->TsSymbolLast = 0; /* indice de la derniere regle de traduction de symboles dans la meme table */ pTSchema->TsGraphicsFirst = 0; /* indice de la 1ere regle de traduction de graphiques dans la table TsCharTransl */ pTSchema->TsGraphicsLast = 0; /* indice de la derniere regle de traduction de graphiques dans la meme table */ pTSchema->TsNCharTransls = 0; /* nombre total de regles de traduction de caracteres */ } /*---------------------------------------------------------------------- initialise les regles de traduction des attributs ----------------------------------------------------------------------*/ #ifdef __STDC__ static void InitAttrTransl () #else /* __STDC__ */ static void InitAttrTransl () #endif /* __STDC__ */ { int i, j; AttributeTransl *pAttTr; TranslNumAttrCase *pCase; for (i = 0; i < pSSchema->SsNAttributes; i++) { pAttTr = &pTSchema->TsAttrTRule[i]; pAttTr->AtrElemType = 0; /* selon le type de l'attribut */ switch (pSSchema->SsAttribute[i].AttrType) { case AtNumAttr: pAttTr->AtrNCases = 0; for (j = 0; j < MAX_TRANSL_ATTR_CASE; j++) { pCase = &pAttTr->AtrCase[j]; pCase->TaLowerBound = -MAX_INT_ATTR_VAL - 1; /* - infini */ pCase->TaUpperBound = MAX_INT_ATTR_VAL + 1; /* + infini */ pCase->TaTRuleBlock = NULL; } break; case AtTextAttr: pAttTr->AtrTextValue[0] = '\0'; pAttTr->AtrTxtTRuleBlock = NULL; break; case AtReferenceAttr: pAttTr->AtrRefTRuleBlock = NULL; break; case AtEnumAttr: for (j = 0; j <= MAX_ATTR_VAL; j++) pAttTr->AtrEnuTRuleBlock[j] = NULL; break; default: break; } } } /*---------------------------------------------------------------------- EndOfCondition traite le type d'element indique' dans une condition Within ou FirstWithin Le nom du type se trouve dans la variable TypeWithin ----------------------------------------------------------------------*/ #ifdef __STDC__ static void EndOfCondition (PtrSSchema pSS) #else /* __STDC__ */ static void EndOfCondition (pSS) PtrSSchema pSS; #endif /* __STDC__ */ { int i; if (TypeWithin[0] != '\0') /* verifie si le type existe dans le schema de structure */ { i = 0; while (strcmp (TypeWithin, pSS->SsRule[i].SrName) != 0 && i < pSS->SsNRules - 1) i++; if (strcmp (TypeWithin, pSS->SsRule[i].SrName) != 0) /* type inconnu */ CompilerMessage (BeginTypeWithin, TRA, FATAL, BAD_TYPE, inputLine, LineNum); else /* le type existe, il a le numero i */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcElemType = i + 1; TypeWithin[0] = '\0'; /* le nom de type a ete traite' */ } } /*---------------------------------------------------------------------- traite le type d'element indique' dans une clause Ancestor Le nom du type se trouve dans la variable AncestorName. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessAncestorName (PtrSSchema pSS) #else /* __STDC__ */ static void ProcessAncestorName (pSS) PtrSSchema pSS; #endif /* __STDC__ */ { int i; if (AncestorName[0] != '\0') /* verifie si le type existe dans le schema de structure */ { i = 0; while (strcmp (AncestorName, pSS->SsRule[i].SrName) != 0 && i < pSS->SsNRules - 1) i++; if (strcmp (AncestorName, pSS->SsRule[i].SrName) != 0) /* type inconnu */ CompilerMessage (BeginAncestorName, TRA, FATAL, BAD_TYPE, inputLine, LineNum); else /* le type existe, il a le numero i */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendType = i + 1; AncestorName[0] = '\0'; /* le nom de type a ete traite' */ } } /*---------------------------------------------------------------------- traite un nom de regle de presentation passee en parametre ----------------------------------------------------------------------*/ #ifdef __STDC__ static void PresentationName (PRuleType TypeRPres, SyntRuleNum pr, int wi) #else /* __STDC__ */ static void PresentationName (TypeRPres, pr, wi) PRuleType TypeRPres; SyntRuleNum pr; int wi; #endif /* __STDC__ */ { int i, j; PRuleTransl *pPresTrans; TranslNumAttrCase *pCase; if (pr == RULE_TransPres) /* debut des regles de traduction d'une presentation */ { CurPres = TypeRPres + 1; CurPresVal = 0; pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; if (!pPresTrans->RtExist) /* pas encore rencontre' de regles pour cette presentation */ { pPresTrans->RtExist = True; if (TypeRPres == PtSize || TypeRPres == PtIndent || TypeRPres == PtLineSpacing || TypeRPres == PtLineWeight || TypeRPres == PtFillPattern || TypeRPres == PtBackground || TypeRPres == PtForeground) /* Presentation a valeur numerique */ { pPresTrans->RtNCase = 0; for (j = 0; j < MAX_TRANSL_PRES_CASE; j++) { pCase = &pPresTrans->RtCase[j]; pCase->TaLowerBound = -MAX_INT_ATTR_VAL - 1; /* - infini */ pCase->TaUpperBound = MAX_INT_ATTR_VAL + 1; /* + infini */ pCase->TaTRuleBlock = NULL; } } else for (j = 0; j <= MAX_TRANSL_PRES_VAL; j++) { pPresTrans->RtPRuleValue[j] = '\0'; pPresTrans->RtPRuleValueBlock[j] = NULL; } } CurBlock = NULL; CurTRule = NULL; if (TypeRPres == PtSize || TypeRPres == PtIndent || TypeRPres == PtLineSpacing || TypeRPres == PtLineWeight || TypeRPres == PtFillPattern || TypeRPres == PtBackground || TypeRPres == PtForeground) /* Presentation a valeur numerique */ if (pPresTrans->RtNCase >= MAX_TRANSL_PRES_CASE) /* trop de cas pour cette presentation */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_CASES_FOR_PRES_OVERFLOW, inputLine, LineNum); else pPresTrans->RtNCase++; /* un cas de plus */ } else if (pr == RULE_CondOnAscend) /* un nom de presentation dans une condition */ { ProcessAncestorName (pSSchema); i = CurBlock->TbNConditions - 1; CurBlock->TbCondition[i].TcCondition = TcondPRule; CurBlock->TbCondition[i].TcAttr = TypeRPres; if (TypeRPres == PtSize || TypeRPres == PtIndent || TypeRPres == PtLineSpacing || TypeRPres == PtLineWeight || TypeRPres == PtFillPattern || TypeRPres == PtBackground || TypeRPres == PtForeground) /* Presentation a valeur numerique */ { CurBlock->TbCondition[i].TcLowerBound = -MAX_INT_ATTR_VAL - 1; /* -infini */ CurBlock->TbCondition[i].TcUpperBound = MAX_INT_ATTR_VAL + 1; /* infini */ } else CurBlock->TbCondition[i].TcPresValue = '\0'; } } /*---------------------------------------------------------------------- traite le mot-cle' representant une valeur d'une presentation. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void PresentValue (char value, int wi) #else /* __STDC__ */ static void PresentValue (value, wi) char value; int wi; #endif /* __STDC__ */ { int i; PRuleTransl *pPresTrans; if (InCondition) /* valeur d'une presentation dans une condition */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcPresValue = value; else { /* ajoute une nouvelle valeur pour une presentation */ /* cherche la premier entree libre dans les valeurs de la */ /* presentation courante */ pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; i = 0; CurPresVal = 0; do { i++; if (pPresTrans->RtPRuleValue[i] == value) /* deja des regles pour cette valeur */ CompilerMessage (wi, TRA, FATAL, RULES_ALREADY_EXIST_FOR_THAT_VALUE, inputLine, LineNum); else if (pPresTrans->RtPRuleValue[i] == '\0') /* une entree libre, on la prend */ { CurPresVal = i; pPresTrans->RtPRuleValue[i] = value; } } while (CurPresVal == 0 && i <= MAX_TRANSL_PRES_VAL + 1); } } /*---------------------------------------------------------------------- SrceStringGreater ----------------------------------------------------------------------*/ #ifdef __STDC__ static int SrceStringGreater (int framet, int lent, int rank, boolean * equal, SourceString source) #else /* __STDC__ */ static int SrceStringGreater (framet, lent, rank, equal, source) int framet; int lent; int rank; boolean *equal; SourceString source; #endif /* __STDC__ */ { int i, k, s; boolean eq; i = framet; eq = False; while (pTSchema->TsCharTransl[i - 1].StSource[rank] < source[rank] && i <= lent) i++; if (i > lent) s = lent + 1; else if (pTSchema->TsCharTransl[i - 1].StSource[rank] > source[rank]) s = i; else if (source[rank] == '\0') { eq = True; s = i; } else { k = i - 1; while (pTSchema->TsCharTransl[k].StSource[rank] == source[rank]) k++; s = SrceStringGreater (i, k, rank + 1, &eq, source); } *equal = eq; return s; } /*---------------------------------------------------------------------- NewSourceString traite la chaine source d'une nouvelle regle de traduction de caracteres. indx : index dans inputLine du premier caractere de la chaine, len est la longueur de la chaine. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewSourceString (int indx, int len) #else /* __STDC__ */ static void NewSourceString (indx, len) int indx; int len; #endif /* __STDC__ */ { int k; boolean equal; SourceString source; int firstEntry, lastEntry; AlphabetTransl *pAlphTrans; firstEntry = 0; lastEntry = 0; if (TextTrans) /* on est dans les traductions de texte */ { pAlphTrans = &pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 1]; firstEntry = pAlphTrans->AlBegin; lastEntry = pAlphTrans->AlEnd; } else if (SymbTrans) /* on est dans les traductions de symbole */ { firstEntry = pTSchema->TsSymbolFirst; lastEntry = pTSchema->TsSymbolLast; } else if (GraphTrans) /* on est dans les traductions de graphique */ { firstEntry = pTSchema->TsGraphicsFirst; lastEntry = pTSchema->TsGraphicsLast; } if (lastEntry >= MAX_TRANSL_CHAR) /* message 'Table saturee' */ CompilerMessage (1, TRA, FATAL, NO_SPACE_LEFT_IN_TRANSLATION_TABLE, inputLine, LineNum); else /* recupere le parametre 'source' */ { for (k = 0; k <= len - 2; k++) source[k] = inputLine[indx + k - 1]; source[len - 1] = '\0'; CurEntry = SrceStringGreater (firstEntry, lastEntry, 0, &equal, source); if (equal) /* la chaine source est deja dans la table */ CompilerMessage (indx, TRA, FATAL, CANT_RESPECIFY_TRANSLATION, inputLine, LineNum); else /* la chaine source n'est pas dans la table */ { /* on l'insere dans la table */ for (k = lastEntry; k >= CurEntry; k--) pTSchema->TsCharTransl[k] = pTSchema->TsCharTransl[k - 1]; strncpy (pTSchema->TsCharTransl[CurEntry - 1].StSource, source, MAX_SRCE_LEN + 1); if (TextTrans) /* on est dans les traductions de texte */ { pAlphTrans = &pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 1]; pAlphTrans->AlEnd++; } else if (SymbTrans) /* on est dans les traductions de symbole */ pTSchema->TsSymbolLast++; else if (GraphTrans) /* on est dans les traduc. de graphique */ pTSchema->TsGraphicsLast++; pTSchema->TsNCharTransls++; } } } /*---------------------------------------------------------------------- ProcessTargetString traite la chaine cible de la regle de traduction de caracteres en cours de construction. indx: index dans inputLine du premier caractere de la chaine, len est la longueur de la chaine. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessTargetString (int indx, int len) #else /* __STDC__ */ static void ProcessTargetString (indx, len) int indx; int len; #endif /* __STDC__ */ { int k; TargetString target; /* recupere le parametre 'target' */ for (k = 0; k <= len - 2; k++) target[k] = inputLine[indx + k - 1]; target[len - 1] = '\0'; strncpy (pTSchema->TsCharTransl[CurEntry - 1].StTarget, target, MAX_TARGET_LEN + 1); } /*---------------------------------------------------------------------- Cree et initialise un nouveau bloc de regles ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewRuleBlock () #else /* __STDC__ */ static void NewRuleBlock () #endif /* __STDC__ */ { PtrTRuleBlock pBlock; AttributeTransl *pAttrTrans; PRuleTransl *pPresTrans; ChangeRuleBlock = False; if ((pBlock = (PtrTRuleBlock) TtaGetMemory (sizeof (TRuleBlock))) == NULL) TtaDisplaySimpleMessage (FATAL, TRA, OUT_OF_MEMORY); else memset (pBlock, 0, sizeof (TRuleBlock)); /* cree un pBlock */ if (CurBlock == NULL) /* pas de bloc courant, attache ce bloc au schema de traduction */ if (InTypeRules) /* bloc de regles associe' a un type d'element */ pTSchema->TsElemTRule[CurType - 1] = pBlock; else if (InAttrRules) /* bloc de regles associe' a un attribut */ { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; switch (pSSchema->SsAttribute[CurAttr - 1].AttrType) { case AtNumAttr: pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaTRuleBlock = pBlock; break; case AtTextAttr: pAttrTrans->AtrTxtTRuleBlock = pBlock; break; case AtReferenceAttr: pAttrTrans->AtrRefTRuleBlock = pBlock; break; case AtEnumAttr: pAttrTrans->AtrEnuTRuleBlock[CurValAttr] = pBlock; break; default: break; } } else /* bloc de regles associe' a une presentation */ { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; if (CurPres == PtSize + 1 || CurPres == PtIndent + 1 || CurPres == PtLineSpacing + 1 || CurPres == PtLineWeight + 1 || CurPres == PtFillPattern + 1 || CurPres == PtBackground + 1 || CurPres == PtForeground + 1) pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaTRuleBlock = pBlock; else pPresTrans->RtPRuleValueBlock[CurPresVal] = pBlock; } else /* il y a un bloc courant, on chaine le nouveau bloc a celui-la */ CurBlock->TbNextBlock = pBlock; /* le nouveau bloc de regle devient le bloc courant */ CurBlock = pBlock; /* il n'y a plus de regle courante */ CurTRule = NULL; /* initialise le nouveau bloc */ CurBlock->TbNextBlock = NULL; CurBlock->TbFirstTRule = NULL; CurBlock->TbNConditions = 0; } /*---------------------------------------------------------------------- cree une nouvelle regle, la chaine et l'initialise ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewTransRule () #else /* __STDC__ */ static void NewTransRule () #endif /* __STDC__ */ { PtrTRule pTRule; EndOfCondition (pSSchema); InCondition = False; GetTRule (&pTRule); if (pTRule == NULL) TtaDisplaySimpleMessage (FATAL, TRA, OUT_OF_MEMORY); /* cree une nouvelle regle */ if (CurBlock == NULL || ChangeRuleBlock) /* cree un nouveau bloc de regle pour la nouvelle regle */ NewRuleBlock (); /* chaine la nouvelle regle a la regle courante s'il y en a une, ou au */ /* bloc de regle courant sinon */ if (CurTRule == NULL) CurBlock->TbFirstTRule = pTRule; else CurTRule->TrNextTRule = pTRule; /* la nouvelle regle devient la regle courante */ CurTRule = pTRule; /* initialise la regle */ CurTRule->TrNextTRule = NULL; CurTRule->TrOrder = TBefore; } /*---------------------------------------------------------------------- traite le type d'element indique' dans une regle Get. Le nom du type se trouve dans la variable TypeInGetRule. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessTypeName (PtrSSchema pSS) #else /* __STDC__ */ static void ProcessTypeName (pSS) PtrSSchema pSS; #endif /* __STDC__ */ { int i, j; boolean found; SRule *pSRule; if (TypeInGetRule[0] != '\0') /* verifie si le type existe dans le schema de structure */ { i = 1; while (strcmp (TypeInGetRule, pSS->SsRule[i - 1].SrName) != 0 && i < pSS->SsNRules) i++; if (strcmp (TypeInGetRule, pSS->SsRule[i - 1].SrName) != 0) /* type inconnu */ CompilerMessage (BeginTypeInGetRule, TRA, FATAL, BAD_TYPE, inputLine, LineNum); else /* le type existe, il a le numero i */ if (CurTRule->TrType == TCreate || CurTRule->TrType == TWrite) { CurTRule->TrObject = ToReferredElem; CurTRule->TrObjectNum = i; } else /* c'est une regle Get ou Copy */ /* s'agit-il d'un element associe' ? */ { if (CurTRule->TrRelPosition == RpSibling) { j = 0; found = False; do { j++; if (j == i) if (pSS->SsRule[j - 1].SrAssocElem) found = True; else { pSRule = &pSS->SsRule[j - 1]; if (pSRule->SrConstruct == CsList) if (pSS->SsRule[pSRule->SrListItem - 1].SrAssocElem) found = True; } } while (j < pSS->SsNRules && !found); if (found) CurTRule->TrRelPosition = RpAssoc; } CurTRule->TrElemType = i; } TypeInGetRule[0] = '\0'; /* le nom de type a ete traite' */ } } /*---------------------------------------------------------------------- copie le mot traite dans n ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CopyWord (Name n, indLine wi, indLine wl) #else /* __STDC__ */ static void CopyWord (n, wi, wl) Name n; indLine wi; indLine wl; #endif /* __STDC__ */ { if (wl > MAX_NAME_LENGTH - 1) CompilerMessage (wi, TRA, FATAL, MAX_NAME_SIZE_OVERFLOW, inputLine, LineNum); else { strncpy (n, &inputLine[wi - 1], wl); n[wl] = '\0'; } } /*---------------------------------------------------------------------- cree une nouvelle constante ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewConstant (indLine wl, indLine wi) #else /* __STDC__ */ static void NewConstant (wl, wi) indLine wl; indLine wi; #endif /* __STDC__ */ { int i; if (pTSchema->TsNConstants >= MAX_TRANSL_CONST) /* table des constantes saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_CONSTANTS_OVERFLOW, inputLine, LineNum); else /* alloue un nouvelle entree dans la table des const. */ if (ConstIndx + wl > MAX_TRANSL_CONST_LEN) /* plus de place pour les constantes */ CompilerMessage (wi, TRA, FATAL, MAX_CONSTANT_BUFFER_OVERFLOW, inputLine, LineNum); else /* FnCopy le texte de la constante */ { pTSchema->TsNConstants++; pTSchema->TsConstBegin[pTSchema->TsNConstants - 1] = ConstIndx; for (i = 0; i <= wl - 2; i++) pTSchema->TsConstant[ConstIndx + i - 1] = inputLine[wi + i - 1]; ConstIndx += wl; pTSchema->TsConstant[ConstIndx - 2] = '\0'; } } /*---------------------------------------------------------------------- cree un attribut dans une regle Create ou Write ----------------------------------------------------------------------*/ #ifdef __STDC__ static void AttrInCreateOrWrite (int att, SyntRuleNum pr, indLine wi) #else /* __STDC__ */ static void AttrInCreateOrWrite (att, pr, wi) int att; SyntRuleNum pr; indLine wi; #endif /* __STDC__ */ { SRule *pSRule; TranslVariable *pTransVar; boolean ok; int j; /* on refuse les attributs reference */ if (pSSchema->SsAttribute[att - 1].AttrType == AtReferenceAttr) CompilerMessage (wi, TRA, FATAL, REF_ATTR_NOT_ALLOWED, inputLine, LineNum); else if (pr == RULE_Token) { CurTRule->TrObject = ToAttr; CurTRule->TrObjectNum = att; } else if (pr == RULE_CountFunction) /* un nom d'attribut dans une fonction de comptage, apres le mot-cle' */ /* INIT. Seuls les attributs numeriques portant sur l'element racine */ /* du schema de structure sont autorises ici */ if (pSSchema->SsAttribute[att - 1].AttrType != AtNumAttr) /* ce n'est pas un attribut numerique, erreur */ CompilerMessage (wi, TRA, FATAL, EXPECTING_A_NUMERICAL_ATTR, inputLine, LineNum); else /* cherche si l'attribut est un attribut local de la racine */ { ok = False; pSRule = &pSSchema->SsRule[pSSchema->SsRootElem - 1]; j = 1; while (j <= pSRule->SrNLocalAttrs && !ok) if (pSRule->SrLocalAttr[j - 1] == att) ok = True; else j++; if (!ok) /* l'attribut ne porte pas sur la racine */ CompilerMessage (wi, TRA, FATAL, NOT_AN_ATTR_FOR_THE_ROOT_ELEM, inputLine, LineNum); else /* le compteur courant prendra cet attribut comme valeur initiale */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnAttrInit = att; } else if (pr == RULE_Function) /* un nom d'attribut dans une variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* variable trop longue */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else { pTransVar->TrvNItems++; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvType = VtAttrVal; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvItem = att; } } } /*---------------------------------------------------------------------- PatternNum retourne le rang du nom n dans le fichier des patterns de Thot. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int PatternNum (Name n, indLine wi) #else /* __STDC__ */ static int PatternNum (n, wi) Name n; indLine wi; #endif /* __STDC__ */ { int i; boolean ok; /* cherche le nom dans le tableau des trames Thot */ i = 0; ok = False; do if (strcmp (n, Name_patterns[i]) == 0) ok = True; else i++; while (!ok && i < sizeof (Name_patterns) / sizeof (char *)); if (!ok) { CompilerMessage (wi, TRA, FATAL, PATTERN_NOT_FOUND, inputLine, LineNum); i = 0; } return i; } /*---------------------------------------------------------------------- ColorNum retourne le rang du nom n dans le fichier des couleurs de Thot. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int ColorNum (Name n, indLine wi) #else /* __STDC__ */ static int ColorNum (n, wi) Name n; indLine wi; #endif /* __STDC__ */ { int i; i = 0; while (i < MAX_COLOR && strcmp (Name_colors[i], n)) i++; if (i == MAX_COLOR) CompilerMessage (wi, TRA, FATAL, MISSING_COLOR, inputLine, LineNum); return i; } /*---------------------------------------------------------------------- ElementTypeNum si le mot de longueur wl qui commence a l'indice wi du buffer de lecture est un nom de type d'element, retourne le numero de type correspondant, sinon retourne 0. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int ElementTypeNum (indLine wi, indLine wl) #else /* __STDC__ */ static int ElementTypeNum (wi, wl) indLine wi; indLine wl; #endif /* __STDC__ */ { Name n; int i; CopyWord (n, wi, wl); /* verifie si le type existe dans le schema de structure */ i = 1; while (strcmp (n, pSSchema->SsRule[i - 1].SrName) != 0 && i < pSSchema->SsNRules) i++; if (strcmp (n, pSSchema->SsRule[i - 1].SrName) != 0) /* type inconnu */ { CompilerMessage (wi, TRA, FATAL, BAD_TYPE, inputLine, LineNum); i = 0; } return i; } /*---------------------------------------------------------------------- AttributeNum si le mot de longueur wl qui commence a l'indice wi du buffer de lecture est un nom d'attribut, retourne le numero de cet attribut, sinon retourne 0. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int AttributeNum (indLine wi, indLine wl) #else /* __STDC__ */ static int AttributeNum (wi, wl) indLine wi; indLine wl; #endif /* __STDC__ */ { Name n; int i; /* copie dans n l'identificateur */ CopyWord (n, wi, wl); /* verifie si l'attribut existe bien dans le schema de structure */ i = 1; while (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) != 0 && i < pSSchema->SsNAttributes) i++; if (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) != 0) /* attribut inconnu */ i = 0; return i; } /*---------------------------------------------------------------------- ElementTypeInCond si le mot de longueur wl qui commence a l'indice wi du buffer de lecture est un type d'element, traite ce type comme apparaissant dans une condition "if type" ----------------------------------------------------------------------*/ #ifdef __STDC__ static boolean ElementTypeInCond (indLine wi, indLine wl) #else /* __STDC__ */ static boolean ElementTypeInCond (wi, wl) indLine wi; indLine wl; #endif /* __STDC__ */ { int i; i = ElementTypeNum (wi, wl); if (i > 0) /* c'est bien un type d'element */ /* une condition "if type" ne peut s'appliquer qu'a une regle de */ /* traduction d'attribnut */ if (!InAttrRules) CompilerMessage (wi, TRA, FATAL, ONLY_FOR_ATTRS, inputLine, LineNum); else { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondElementType; /* le type existe,il a le numero i*/ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr = i; } return (i > 0); } /*---------------------------------------------------------------------- traite le mot commencant a la position wi dans la ligne courante de longueur wl et de code grammatical c. Si c'est un identif, nb contient son rang dans la table des identificateurs. r est le numero de la regle dans laquelle apparait ce mot. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessToken (indLine wi, indLine wl, SyntacticCode c, SyntacticCode r, int nb, SyntRuleNum pr) #else /* __STDC__ */ static void ProcessToken (wi, wl, c, r, nb, pr) indLine wi; indLine wl; SyntacticCode c; SyntacticCode r; int nb; SyntRuleNum pr; #endif /* __STDC__ */ { int i, k; Name n; boolean InUseRule, InGetRule, InCreateWriteRule; AlphabetTransl *pAlphTrans; TranslVariable *pTransVar; TCounter *pCntr; AttributeTransl *pAttrTrans; TtAttribute *pAttr; TranslNumAttrCase *pCase; PRuleTransl *pPresTrans; i = 1; if (c < 1000) /* symbole intermediaire de la grammaire, erreur */ CompilerMessage (wi, TRA, FATAL, INTERMEDIATE_SYMBOL, inputLine, LineNum); else { if (c < 1100) /* mot-cle court */ switch (c) { case CHR_59: /* ; */ if (r == RULE_RuleA || r == RULE_RuleB) /* fin d'une regle */ { if (CurTRule->TrType == TUse) if (CurType == pSSchema->SsRootElem) if (CurTRule->TrNature == pSSchema->SsRule[CurType - 1].SrName) /* une regle Use pour la racine se termine sans 'For' */ CompilerMessage (wi, TRA, FATAL, FOR_PART_MISSING, inputLine, LineNum); if (CurTRule->TrType == TGet || CurTRule->TrType == TCopy || CurTRule->TrType == TCreate || CurTRule->TrType == TWrite) /* fin d'une regle Get, Copy, Create ou Write */ ProcessTypeName (pSSchema); if (!InAttrRules) if (CurBlock != NULL) if (CurBlock->TbNConditions != 0) if (!InCondBlock) /* fin d'une regle unique dans bloc conditionnel, il */ /* faut ouvrir un nouveau bloc pour la regle suivante */ ChangeRuleBlock = True; } break; case CHR_61: /* = */ break; case CHR_58: /* : */ break; case CHR_40: /* ( */ if (r == RULE_Token) if (!VarDefinition) /* un nom de schema externe va suivre */ if (CurTRule->TrObject != ToReferredElem) CompilerMessage (wi, TRA, FATAL, ONLY_FOR_ELEMS, inputLine, LineNum); else ExternalSchema = True; else /* debut d'une definition de variable */ if (pTSchema->TsNVariables >= MAX_TRANSL_VARIABLE) /* table des variables saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_VARIABLES_OVERFLOW, inputLine, LineNum); else { VarDef = True; pTSchema->TsVariable[pTSchema->TsNVariables++].TrvNItems = 0; /* la regle courante utilise cette variable */ CurTRule->TrObject = ToVariable; CurTRule->TrObjectNum = pTSchema->TsNVariables; } else if (r == RULE_RuleA) ExternalSchema = True; else if (r == RULE_CondOnAscend || r == RULE_LevelOrType) /* On est dans une condition. Un nom de schema externe suit */ ExternalSchema = True; break; case CHR_41: /* ) */ if (r == RULE_Token) /* fin d'une definition de variable */ VarDef = False; break; case CHR_44: /* , */ break; case CHR_62: /* > */ if (r == RULE_GreaterLess) { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRel = RelGreater; GreaterOrLessSign = True; } break; case CHR_43: /* + */ if (r == RULE_IndentSign) /* devant la valeur de l'indentation relative */ IndentSign = 1; break; case CHR_45: /* - */ if (r == RULE_AttrRelat || r == RULE_AttrValue) /* devant une valeur d'attribut numerique */ AttrValSign = -1; else if (r == RULE_PresRelat || r == RULE_PresValue) /* devant une valeur numerique de presentation */ PresValSign = -1; else if (r == RULE_RelAncestorLevel) /* devant le niveau relatif d'un ancetre dans un compteur CntrRank */ AncestorSign = -1; else if (r == RULE_IndentSign) /* devant la valeur de l'indentation relative */ IndentSign = -1; break; case CHR_60: /* < */ if (r == RULE_GreaterLess) { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRel = RelLess; GreaterOrLessSign = True; } break; case CHR_91: /* [ */ break; case CHR_46: /* . */ break; case CHR_93: /* ] */ break; case CHR_42: /* * */ Asterisk = True; break; default: break; } else if (c < 2000) /* mot-cle long */ switch (c) { case KWD_Buffers: /* Buffers */ BuffDef = True; /* on est dans les declarations de buffers */ break; case KWD_Counters: /* Counters */ BuffDef = False; /* fin des declarations de buffers */ ConstDef = False; /* fin des declaration de constantes */ ComptDef = True; /* on est dans les declarations de compteur */ break; case KWD_Const: /* Const */ BuffDef = False; /* fin des declarations de buffers */ ConstDef = True; /* on est dans les declaration de constante */ break; case KWD_Var: /* Var */ BuffDef = False; /* fin des declarations de buffers */ ConstDef = False; /* fin des declaration de constantes */ ComptDef = False; /* fin des declarations de compteurs */ VarDef = True; /* on est dans les declarations de variables */ break; case KWD_Rules: /* Rules */ BuffDef = False; /* fin des declarations de buffers */ ConstDef = False; /* fin des declaration de constantes */ ComptDef = False; /* fin des declarations de compteurs */ VarDef = False; /* fin des declarations de variables */ InTypeRules = True; break; case KWD_Attributes: /* Attributes */ if (r == RULE_TransSchema) /* debut des regles de traduction des attributs */ { InTypeRules = False; InAttrRules = True; } else if (r == RULE_CondOnAscend) /* dans une condition */ { ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondAttributes; } else if (r == RULE_Token) /* ce qu'il faut generer : les attributs de l'element */ CurTRule->TrObject = ToAllAttr; break; case KWD_TextTranslate: /* TextTranslate */ InTypeRules = False; InAttrRules = False; InPresRules = False; TextTrans = True; /* on est dans les traductions de texte */ if (pTSchema->TsNTranslAlphabets >= MAX_TRANSL_ALPHABET) CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_TEXTTRANSLATE_OVERFLOW, inputLine, LineNum); else { pAlphTrans = &pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets++]; pAlphTrans->AlAlphabet = 'L'; /* alphabet latin par defaut */ if (pTSchema->TsNTranslAlphabets == 1) { pAlphTrans->AlBegin = 1; pAlphTrans->AlEnd = 0; } else { pAlphTrans->AlBegin = pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 2].AlEnd + 1; pAlphTrans->AlEnd = pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 2].AlEnd; } } break; case KWD_SymbTranslate: /* SymbTranslate */ InTypeRules = False; InAttrRules = False; InPresRules = False; TextTrans = False; /* fin des traductions de texte */ SymbTrans = True; /* on est dans les traductions de symbole */ if (pTSchema->TsNTranslAlphabets == 0) { pTSchema->TsSymbolFirst = 1; pTSchema->TsSymbolLast = 0; } else { pAlphTrans = &pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 1]; if (pAlphTrans->AlEnd > 0) { pTSchema->TsSymbolFirst = pAlphTrans->AlEnd + 1; pTSchema->TsSymbolLast = pAlphTrans->AlEnd; } else { pTSchema->TsSymbolFirst = 1; pTSchema->TsSymbolLast = 0; } } break; case KWD_GraphTranslate: /* GraphTranslate */ InTypeRules = False; InAttrRules = False; InPresRules = False; TextTrans = False; /* fin des traductions de texte */ SymbTrans = False; /* fin des traductions de symbole */ GraphTrans = True; /* on est dans les traduc. de graphique */ if (pTSchema->TsSymbolLast > 0) { pTSchema->TsGraphicsFirst = pTSchema->TsSymbolLast + 1; pTSchema->TsGraphicsLast = pTSchema->TsSymbolLast; } else if (pTSchema->TsNTranslAlphabets == 0) { pTSchema->TsGraphicsFirst = 1; pTSchema->TsGraphicsLast = 0; } else { pAlphTrans = &pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 1]; if (pAlphTrans->AlEnd > 0) { pTSchema->TsGraphicsFirst = pAlphTrans->AlEnd + 1; pTSchema->TsGraphicsLast = pAlphTrans->AlEnd; } else { pTSchema->TsGraphicsFirst = 1; pTSchema->TsGraphicsLast = 0; } } break; case KWD_End: /* End */ if (r == RULE_SeqOfRules1 && !InAttrRules) { InCondBlock = False; if (CurBlock != NULL) if (CurBlock->TbNConditions != 0) /* fin d'un bloc conditionnel, il faut ouvrir un */ /* nouveau bloc pour la regle suivante */ ChangeRuleBlock = True; } break; case KWD_Rank: /* CntrRank */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnOperation = TCntrRank; pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnAcestorLevel = 0; AncestorSign = 1; break; case KWD_of: /* Of */ break; /* rien */ case KWD_Rlevel: /* CntrRLevel */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnOperation = TCntrRLevel; break; case KWD_Set: /* Set */ if (r == RULE_CountFunction) /* dans une definition de compteur */ { pCntr = &pTSchema->TsCounter[pTSchema->TsNCounters - 1]; pCntr->TnOperation = TCntrSet; pCntr->TnElemType1 = 0; } else if (r == RULE_RuleB) /* instruction de traduction Set */ { NewTransRule (); CurTRule->TrType = TSetCounter; } break; case KWD_On: /* On */ break; /* rien */ case KWD_Add: /* Add */ if (r == RULE_RuleB) /* instruction de traduction Add */ { NewTransRule (); CurTRule->TrType = TAddCounter; } break; case KWD_Picture: /* Picture */ if (pTSchema->TsPictureBuffer != 0) /* un seul buffer image autorise' */ CompilerMessage (wi, TRA, FATAL, CANT_USE_MORE_THAN_ONE_PICTURE_BUFFER, inputLine, LineNum); else /* c'est le buffer courant qui est le buffer image */ pTSchema->TsPictureBuffer = pTSchema->TsNBuffers; break; case KWD_Value: /* Value */ if (r == RULE_Token) if (!InPresRules) CompilerMessage (wi, TRA, FATAL, ONLY_IN_PRES_PART, inputLine, LineNum); /* seulement dans les regles de la presentation */ else CurTRule->TrObject = ToPRuleValue; else if (r == RULE_Function) /* valeur d'un compteur dans une definition de variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtCounter; } break; case KWD_FileDir: /* FileDir */ if (r == RULE_Function) { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtFileDir; } else if (r == RULE_Token) /* generer le nom du directory du fichier de sortie */ CurTRule->TrObject = ToFileDir; break; case KWD_FileName: if (r == RULE_Function) { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtFileName; } else if (r == RULE_Token) /* generer le nom du fichier de sortie */ CurTRule->TrObject = ToFileName; break; case KWD_Extension: if (r == RULE_Function) { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtExtension; } else if (r == RULE_Token) /* generer l'extensiion (suffixe) du fichier de sortie */ CurTRule->TrObject = ToExtension; break; case KWD_RefId: /* RefId */ if (r == RULE_Token) /* generer le label de l'element traduit */ CurTRule->TrObject = ToRefId; else if (r == RULE_VarOrType) /* generer le label de l'element reference' */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle */ /* n'est pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurTRule->TrObject = ToReferredRefId; break; case KWD_PairId: /* PairId */ if (pSSchema->SsRule[CurType - 1].SrConstruct != CsPairedElement) /* l'element auquel s'applique la regle n'est pas une paire */ CompilerMessage (wi, TRA, FATAL, NOT_A_PAIR, inputLine, LineNum); else CurTRule->TrObject = ToPairId; break; case KWD_IN: /* IN */ break; case KWD_Begin: /* Begin */ if (r == RULE_SeqOfRules1) { EndOfCondition (pSSchema); if (!InAttrRules) InCondBlock = True; } break; case KWD_If: /* If */ InCondition = True; NewRuleBlock (); CurBlock->TbNConditions = 1; CurBlock->TbCondition[0].TcNegativeCond = False; CurBlock->TbCondition[0].TcTarget = False; CurBlock->TbCondition[0].TcAscendType = 0; CurBlock->TbCondition[0].TcAscendNature[0] = '\0'; CurBlock->TbCondition[0].TcAscendRelLevel = 0; CurBlock->TbCondition[0].TcCondition = TcondElementType; Immediately = False; Asterisk = False; break; case KWD_And: /* And */ if (CurBlock->TbNConditions >= MAX_TRANSL_COND) /* trop de conditions */ CompilerMessage (wi, TRA, FATAL, TOO_MANY_CONDITIONS, inputLine, LineNum); else { EndOfCondition (pSSchema); i = CurBlock->TbNConditions; CurBlock->TbNConditions++; CurBlock->TbCondition[i].TcNegativeCond = False; CurBlock->TbCondition[i].TcTarget = False; CurBlock->TbCondition[i].TcAscendType = 0; CurBlock->TbCondition[i].TcAscendNature[0] = '\0'; CurBlock->TbCondition[i].TcAscendRelLevel = 0; CurBlock->TbCondition[i].TcCondition = TcondElementType; Immediately = False; Asterisk = False; } break; case KWD_Not: /* Not */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcNegativeCond = True; break; case KWD_Target: /* Target */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle */ /* n'est pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcTarget = True; break; case KWD_First: /* First */ if (r == RULE_FirstSec) FirstInPair = True; else { ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondFirst; } break; case KWD_Second: /* Second */ SecondInPair = True; break; case KWD_Last: /* Last */ ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondLast; break; case KWD_Defined: /* Defined */ if (pSSchema->SsRule[CurType - 1].SrParamElem) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondDefined; else CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_PARAMETERS, inputLine, LineNum); break; case KWD_Refered: /* Refered */ case KWD_Referred: /* Referred */ if (r == RULE_CondOnAscend) /* dans une condition */ { ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondReferred; if (!Asterisk) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRelLevel = -1; } else if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle n'est */ /* pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else if (r == RULE_Token) /* devant un identificateur de variable */ CurTRule->TrReferredObj = True; else if (r == RULE_RelPosition) /* dans une position relative */ CurTRule->TrRelPosition = RpReferred; break; case KWD_FirstRef: /* FirstRef */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle n'est */ /* pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondFirstRef; break; case KWD_LastRef: /* LastRef */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle n'est */ /* pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondLastRef; break; case KWD_ExternalRef: /* ExternalRef */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle n'est */ /* pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondExternalRef; break; case KWD_Immediately: Immediately = True; break; case KWD_Within: /* Within */ ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondWithin; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcImmediatelyWithin = Immediately; Immediately = False; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRel = RelGreater; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendLevel = 0; GreaterOrLessSign = False; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcElemNature[0] = '\0'; TypeWithin[0] = '\0'; break; case KWD_FirstWithin: /* FirstWithin */ ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondFirstWithin; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcImmediatelyWithin = False; Immediately = False; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRel = RelGreater; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendLevel = 0; GreaterOrLessSign = False; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcElemNature[0] = '\0'; TypeWithin[0] = '\0'; break; case KWD_Presentation: /* Presentation */ if (InPresRules) CompilerMessage (wi, TRA, FATAL, FORBIDDEN_IN_PRES_PART, inputLine, LineNum); else if (r == RULE_TransSchema) /* debut des regles de traduction de la presentation */ { InTypeRules = False; InAttrRules = False; InPresRules = True; } else if (r == RULE_CondOnAscend) /* dans une condition */ { ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondPresentation; } else if (r == RULE_Token) /* ce qu'il faut generer */ CurTRule->TrObject = ToAllPRules; break; case KWD_Comment: /* Comment */ if (r == RULE_CondOnAscend) /* dans une condition */ { ProcessAncestorName (pSSchema); CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondComment; } else if (r == RULE_Token) /* ce qu'il faut generer */ CurTRule->TrObject = ToComment; break; case KWD_DocumentName: /* DocumentName */ if (r == RULE_Function) { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtDocumentName; } else if (r == RULE_Token) /* generer le nom du document traduit */ CurTRule->TrObject = ToDocumentName; else if (r == RULE_VarOrType) /* generer le nom du document reference' */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle */ /* n'est pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurTRule->TrObject = ToReferredDocumentName; break; case KWD_DocumentDir: /* DocumentDir */ if (r == RULE_Function) { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else pTransVar->TrvItem[pTransVar->TrvNItems++].TvType = VtDocumentDir; } else if (r == RULE_Token) /* generer le nom du directory du document traduit */ CurTRule->TrObject = ToDocumentDir; else if (r == RULE_VarOrType) /* generer le nom du directory du document reference' */ if ((InTypeRules && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) || (InAttrRules && pSSchema->SsAttribute[CurAttr - 1].AttrType != AtReferenceAttr)) /* l'element ou l'attribut auquel s'applique la regle */ /* n'est pas une reference, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else CurTRule->TrObject = ToReferredDocumentDir; break; case KWD_ARABIC: pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntArabic; break; case KWD_UROMAN: pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntURoman; break; case KWD_LROMAN: pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntLRoman; break; case KWD_UPPERCASE: pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntUppercase; break; case KWD_LOWERCASE: pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntLowercase; break; case KWD_Alphabet: /* Alphabet */ if (CurType != CharString + 1) CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_TEXT_UNITS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondAlphabet; break; case KWD_FirstAttr: /* FirstAttr */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondFirstAttr; break; case KWD_LastAttr: /* LastAttr */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondLastAttr; break; case KWD_Create: /* Create */ NewTransRule (); CurTRule->TrType = TCreate; CurTRule->TrReferredObj = False; CurTRule->TrObjectNature[0] = '\0'; CurTRule->TrFileNameVar = 0; VarDefinition = True; break; case KWD_Get: /* Get */ NewTransRule (); CurTRule->TrType = TGet; CurTRule->TrElemNature[0] = '\0'; CurTRule->TrRelPosition = RpSibling; break; case KWD_Copy: /* Copy */ NewTransRule (); CurTRule->TrType = TCopy; CurTRule->TrElemNature[0] = '\0'; CurTRule->TrRelPosition = RpSibling; break; case KWD_Use: /* Use */ InCondition = False; if (pSSchema->SsRule[CurType - 1].SrConstruct != CsNatureSchema && CurType != pSSchema->SsRootElem) /* l'element auquel s'applique la regle n'est pas une */ /* SyntacticType ni la regle racine, erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_A_DIFFERENT_STRUCT_SCHEM, inputLine, LineNum); else { NewTransRule (); if (CurBlock->TbNConditions != 0) CompilerMessage (wi, TRA, FATAL, MUST_BE_UNCONDITIONAL, inputLine, LineNum); else { CurTRule->TrType = TUse; strncpy (CurTRule->TrNature, pSSchema->SsRule[CurType - 1].SrName, MAX_NAME_LENGTH); } } break; case KWD_For: /* For */ if (CurType != pSSchema->SsRootElem) /* FOR n'est acceptable que pour l'element racine */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_THE_ROOT_ELEM, inputLine, LineNum); break; case KWD_Remove: /* Remove */ NewTransRule (); CurTRule->TrType = TRemove; break; case KWD_Write: /* Write */ NewTransRule (); CurTRule->TrType = TWrite; CurTRule->TrReferredObj = False; CurTRule->TrObjectNature[0] = '\0'; CurTRule->TrFileNameVar = 0; VarDefinition = True; break; case KWD_Read: /* Read */ NewTransRule (); CurTRule->TrType = TRead; break; case KWD_Include: /* Include */ NewTransRule (); CurTRule->TrType = TInclude; break; case KWD_NoTranslation: /* NoTranslation */ NewTransRule (); CurTRule->TrType = TNoTranslation; break; case KWD_NoLineBreak: /* NoLineBreak */ NewTransRule (); CurTRule->TrType = TNoLineBreak; break; case KWD_ChangeMainFile: /* ChangeMainFile */ NewTransRule (); CurTRule->TrType = TChangeMainFile; break; case KWD_Content: /* Content */ CurTRule->TrObject = ToContent; break; case KWD_After: /* After */ CurTRule->TrOrder = TAfter; break; case KWD_Before: /* Before */ CurTRule->TrOrder = TBefore; break; case KWD_Included: /* Included */ CurTRule->TrRelPosition = RpDescend; break; case KWD_Size: PresentationName (PtSize, pr, wi); break; case KWD_Indent: if (r == RULE_PresRule) PresentationName (PtIndent, pr, wi); else if (r == RULE_RuleB) /* instruction de traduction Indent */ { NewTransRule (); CurTRule->TrType = TIndent; CurTRule->TrRelativeIndent = FALSE; CurTRule->TrIndentFileNameVar = 0; IndentSign = 0; } break; case KWD_RemoveFile: /* RemoveFile */ NewTransRule (); CurTRule->TrType = TRemoveFile; break; case KWD_LineSpacing: PresentationName (PtLineSpacing, pr, wi); break; case KWD_Adjust: PresentationName (PtAdjust, pr, wi); break; case KWD_Justify: PresentationName (PtJustify, pr, wi); break; case KWD_Hyphenate: PresentationName (PtHyphenate, pr, wi); break; case KWD_Style: PresentationName (PtStyle, pr, wi); break; case KWD_Font: PresentationName (PtFont, pr, wi); break; case KWD_UnderLine: if (r == RULE_PresRule) PresentationName (PtUnderline, pr, wi); else if (r == RULE_UnderLineVal) PresentValue ('U', wi); break; case KWD_Thickness: PresentationName (PtThickness, pr, wi); break; case KWD_LineStyle: PresentationName (PtLineStyle, pr, wi); break; case KWD_LineWeight: PresentationName (PtLineWeight, pr, wi); break; case KWD_FillPattern: PresentationName (PtFillPattern, pr, wi); break; case KWD_Background: PresentationName (PtBackground, pr, wi); break; case KWD_Foreground: PresentationName (PtForeground, pr, wi); break; case KWD_Left: PresentValue ('L', wi); break; case KWD_Right: PresentValue ('R', wi); break; case KWD_VMiddle: PresentValue ('C', wi); break; case KWD_LeftWithDots: PresentValue ('D', wi); break; case KWD_Yes: PresentValue ('Y', wi); break; case KWD_No: if (r == RULE_UnderLineVal) PresentValue ('N', wi); else PresentValue ('N', wi); break; case KWD_Bold: PresentValue ('B', wi); break; case KWD_Italics: PresentValue ('I', wi); break; case KWD_Roman: PresentValue ('R', wi); break; case KWD_BoldItalics: PresentValue ('G', wi); break; case KWD_BoldOblique: PresentValue ('Q', wi); break; case KWD_Oblique: PresentValue ('O', wi); break; case KWD_Times: PresentValue ('T', wi); break; case KWD_Helvetica: PresentValue ('H', wi); break; case KWD_Courier: PresentValue ('C', wi); break; case KWD_NoUnderline: PresentValue ('N', wi); break; case KWD_Underlined: PresentValue ('U', wi); break; case KWD_Overlined: PresentValue ('O', wi); break; case KWD_CrossedOut: PresentValue ('C', wi); break; case KWD_OverLine: PresentValue ('O', wi); break; case KWD_StrikeOut: PresentValue ('C', wi); break; case KWD_Thick: PresentValue ('N', wi); break; case KWD_Thin: PresentValue ('T', wi); break; case KWD_Solid: PresentValue ('S', wi); break; case KWD_Dashed: PresentValue ('-', wi); break; case KWD_Dotted: PresentValue ('.', wi); break; case KWD_ComputedPage: if (CurType != PageBreak + 1) /* l'element auquel s'applique la regle n'est pas une marque de page */ /* erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_PAGES, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondComputedPage; break; case KWD_StartPage: if (CurType != PageBreak + 1) /* l'element auquel s'applique la regle n'est pas une marque de page */ /* erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_PAGES, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondStartPage; break; case KWD_UserPage: if (CurType != PageBreak + 1) /* l'element auquel s'applique la regle n'est pas une marque de page */ /* erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_PAGES, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondUserPage; break; case KWD_ReminderPage: if (CurType != PageBreak + 1) /* l'element auquel s'applique la regle n'est pas une marque de page */ /* erreur */ CompilerMessage (wi, TRA, FATAL, VALID_ONLY_FOR_PAGES, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondReminderPage; break; case KWD_Empty: CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondEmpty; break; case KWD_Parent: CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRelLevel = 1; break; case KWD_Ancestor: /* rien a faire */ break; default: break; } else /* type de base */ switch (c) { case 3001 /* un nom */ : switch (r) { /* r= numero regle */ case RULE_TypeIdent: /* TypeIdent */ if (pr == RULE_TransSchema) /* nom de la structure generique a laquelle se rapporte */ /* le schema de traduction */ { CopyWord (pTSchema->TsStructName, wi, wl); /* lit le schema de structure compile' */ if (!ReadStructureSchema (pTSchema->TsStructName, pSSchema)) TtaDisplaySimpleMessage (FATAL, TRA, CANT_READ_STRUCT_SCHEM); /* echec lecture du schema de structure */ else if (strcmp (pTSchema->TsStructName, pSSchema->SsName) != 0) CompilerMessage (wi, TRA, FATAL, STRUCT_SCHEM_DOES_NOT_MATCH, inputLine, LineNum); else { pTSchema->TsStructCode = pSSchema->SsCode; InitAttrTransl (); } } else if (pr == RULE_CondOnAscend) { if (CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition == TcondFirstWithin || CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition == TcondWithin) /* dans une condition Within ou FirstWithin */ if (!ExternalSchema) /* nom du type d'element */ { CopyWord (TypeWithin, wi, wl); BeginTypeWithin = wi; } else /* nom d'un schema de structure externe dans une condition */ /* Within ou FirstWithin */ { ExternalSchema = False; /* recupere dans n le nom du schema externe */ CopyWord (n, wi, wl); /* lit le schema de structure externe */ if (!ReadStructureSchema (n, pExtSSchema)) CompilerMessage (wi, TRA, FATAL, CANT_READ_STRUCT_SCHEM, inputLine, LineNum); /* echec lecture du schema */ else /* le schema de structure a ete charge' */ { strncpy (CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcElemNature, n, MAX_NAME_LENGTH); EndOfCondition (pExtSSchema); } } else /* dans une condition "if TYPE" */ ElementTypeInCond (wi, wl); } else if (pr == RULE_LevelOrType) /* un type d'element dans une condition portant sur */ /* un ascendant */ { if (!ExternalSchema) /* nom du type d'element ascendant dans la condition */ { CopyWord (AncestorName, wi, wl); BeginAncestorName = wi; } else /* nom d'un schema de structure externe dans Ascend */ { ExternalSchema = False; /* recupere dans n le nom du schema externe */ CopyWord (n, wi, wl); /* lit le schema de structure externe */ if (!ReadStructureSchema (n, pExtSSchema)) CompilerMessage (wi, TRA, FATAL, CANT_READ_STRUCT_SCHEM, inputLine, LineNum); /* echec lecture du schema */ else /* le schema de structure a ete charge' */ { strncpy (CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendNature, n, MAX_NAME_LENGTH); ProcessAncestorName (pExtSSchema); } } } else { InUseRule = False; InGetRule = False; InCreateWriteRule = (pr == RULE_Token); if (pr == RULE_RuleA) { if (CurTRule->TrType == TUse) InUseRule = True; if (CurTRule->TrType == TGet || CurTRule->TrType == TCopy) InGetRule = True; } if (InUseRule) CopyWord (CurTRule->TrNature, wi, wl); else if (InGetRule || InCreateWriteRule) if (ExternalSchema) /* nom d'un schema de structure externe */ { ExternalSchema = False; CopyWord (n, wi, wl); /* recupere dans n le nom du schema externe */ /* lit le schema de structure externe */ if (!ReadStructureSchema (n, pExtSSchema)) CompilerMessage (wi, TRA, FATAL, CANT_READ_STRUCT_SCHEM, inputLine, LineNum); /* echec lecture du schema */ else /* le schema de structure a ete charge' */ { if (InGetRule) strncpy (CurTRule->TrElemNature, n, MAX_NAME_LENGTH); else strncpy (CurTRule->TrObjectNature, n, MAX_NAME_LENGTH); ProcessTypeName (pExtSSchema); } } else { CopyWord (TypeInGetRule, wi, wl); BeginTypeInGetRule = wi; } else if (pr == RULE_VarOrType) /* dans une regle Create ou Write, apres Refered */ { VarDefinition = False; CopyWord (TypeInGetRule, wi, wl); BeginTypeInGetRule = wi; } else { i = ElementTypeNum (wi, wl); if (i > 0) /* le type existe, il a le numero i */ if (ComptDef) /* dans une declaration de compteur */ { pCntr = &pTSchema->TsCounter[pTSchema->TsNCounters - 1]; if (pCntr->TnOperation == TCntrSet) if (pCntr->TnElemType1 == 0) pCntr->TnElemType1 = i; else pCntr->TnElemType2 = i; else pCntr->TnElemType1 = i; } else /* on n'est pas dans une declaration de compteur */ if (pr == RULE_TransType) /* debut des regles associees a un type */ { if (pSSchema->SsRule[i - 1].SrConstruct == CsPairedElement) /* c'est un element CsPairedElement */ if (!SecondInPair && !FirstInPair) /* le nom du type n'etait pas precede' de First ou Second */ CompilerMessage (wi, TRA, FATAL, MISSING_FIRST_SECOND, inputLine, LineNum); else { if (SecondInPair) /* il s'agit du type suivant */ i++; } else /* ce n'est pas un element CsPairedElement */ if (SecondInPair || FirstInPair) /* le nom du type etait precede' de First ou Second, erreur */ CompilerMessage (wi, TRA, FATAL, NOT_A_PAIR, inputLine, LineNum); if (pTSchema->TsElemTRule[i - 1] != NULL) CompilerMessage (wi, TRA, FATAL, CANT_REDEFINE, inputLine, LineNum); else { CurType = i; CurBlock = NULL; CurTRule = NULL; } FirstInPair = False; SecondInPair = False; } else if (pr == RULE_TransAttr) /* apres un nom d'attribut */ { pTSchema->TsInheritAttr[i - 1] = True; pTSchema->TsAttrTRule[CurAttr - 1].AtrElemType = i; } } } break; case RULE_ConstIdent: /* ConstIdent */ if (ConstDef) /* une definition de constante */ if (Identifier[nb - 1].SrcIdentDefRule != 0) /* nom deja declare' */ CompilerMessage (wi, TRA, FATAL, INVALID_NAME_REDECLARATION, inputLine, LineNum); else if (pTSchema->TsNConstants >= MAX_TRANSL_CONST) /* table des constantes saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_CONSTANTS_OVERFLOW, inputLine, LineNum); else /* alloue un nouvelle entree dans la table des constantes */ { pTSchema->TsNConstants++; Identifier[nb - 1].SrcIdentDefRule = pTSchema->TsNConstants; } else /* utilisation d'une constante */ if (Identifier[nb - 1].SrcIdentDefRule == 0) /* ce nom n'a pas ete declare comme un identificateur */ /* de constante */ if (pr == RULE_Token || pr == RULE_Function) /* s'il vient de la regle Token ou Function, voyons si */ /* ce n'est pas un identificateur d'attribut */ { i = AttributeNum (wi, wl); if (i == 0) CompilerMessage (wi, TRA, FATAL, BAD_ATTR, inputLine, LineNum); else /* l'attribut existe, il a le numero i */ { AttrInCreateOrWrite (i, pr, wi); /* ce nom est maintenant un nom d'attribut */ Identifier[nb - 1].SrcIdentCode = RULE_AttrIdent; } } else /* constante non definie */ CompilerMessage (wi, TRA, FATAL, UNDECLARED_CONSTANT, inputLine, LineNum); else if (VarDef) /* dans une declaration de variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else { pTransVar->TrvItem[pTransVar->TrvNItems].TvType = VtText; pTransVar->TrvItem[pTransVar->TrvNItems].TvItem = Identifier[nb - 1].SrcIdentDefRule; pTransVar->TrvNItems++; } } else if (pr == RULE_Token) /* dans une regle Create ou Write */ { CurTRule->TrObject = ToConst; CurTRule->TrObjectNum = Identifier[nb - 1].SrcIdentDefRule; } break; case RULE_CounterIdent: /* CounterIdent */ if (ComptDef) /* une definition de compteur */ if (Identifier[nb - 1].SrcIdentDefRule != 0) /* nom deja declare' */ CompilerMessage (wi, TRA, FATAL, INVALID_NAME_REDECLARATION, inputLine, LineNum); else if (pTSchema->TsNCounters >= MAX_TRANSL_COUNTER) /* table des compteurs saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_COUNTERS_OVERFLOW, inputLine, LineNum); else /* alloue un nouvelle entree dans la table des compteurs */ { /* a priori ce compteur n'a pas d'operations */ pTSchema->TsCounter[pTSchema->TsNCounters].TnOperation = TCntrNoOp; /* a priori, ce compteur ne sera pas */ /* intialise' par un attribut */ pTSchema->TsCounter[pTSchema->TsNCounters]. TnAttrInit = 0; pTSchema->TsNCounters++; Identifier[nb - 1].SrcIdentDefRule = pTSchema->TsNCounters; } else /* utilisation d'un compteur */ if (Identifier[nb - 1].SrcIdentDefRule == 0) /* compteur non defini */ CompilerMessage (wi, TRA, FATAL, UNDECLARED_COUNTER, inputLine, LineNum); else if (pr == RULE_Function) /* dans une declaration de variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvItem = Identifier[nb - 1].SrcIdentDefRule; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvLength = 0; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvCounterStyle = CntArabic; } else if (pr == RULE_RuleB) /* un compteur dans une instruction Set ou Add */ if (pTSchema->TsCounter[Identifier[nb - 1].SrcIdentDefRule - 1].TnOperation != TCntrNoOp) CompilerMessage (wi, TRA, FATAL, BAD_COUNTER, inputLine, LineNum); else CurTRule->TrCounterNum = Identifier[nb - 1].SrcIdentDefRule; break; case RULE_BufferIdent: /* BufferIdent */ if (BuffDef) /* une definition de buffer */ if (Identifier[nb - 1].SrcIdentDefRule != 0) /* nom deja declare' */ CompilerMessage (wi, TRA, FATAL, INVALID_NAME_REDECLARATION, inputLine, LineNum); else if (pTSchema->TsNBuffers >= MAX_TRANSL_BUFFER) /* table des buffers saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_BUFFERS_OVERFLOW, inputLine, LineNum); else { pTSchema->TsNBuffers++; Identifier[nb - 1].SrcIdentDefRule = pTSchema->TsNBuffers; } else /* utilisation d'un buffer */ if (Identifier[nb - 1].SrcIdentDefRule == 0) /* buffer non defini */ CompilerMessage (wi, TRA, FATAL, UNDECLARED_BUFFER, inputLine, LineNum); else if (VarDef) /* dans une declaration de variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else { pTransVar->TrvItem[pTransVar->TrvNItems].TvType = VtBuffer; pTransVar->TrvItem[pTransVar->TrvNItems].TvItem = Identifier[nb - 1].SrcIdentDefRule; pTransVar->TrvNItems++; } } else if (pr == RULE_RuleA) /* dans une regle Read */ CurTRule->TrBuffer = Identifier[nb - 1].SrcIdentDefRule; else if (pr == RULE_Token) /* dans une regle Create ou Write */ { CurTRule->TrObject = ToBuffer; CurTRule->TrObjectNum = Identifier[nb - 1].SrcIdentDefRule; } else if (pr == RULE_File) { /* dans une regle Include */ CurTRule->TrBufOrConst = ToBuffer; CurTRule->TrInclFile = Identifier[nb - 1].SrcIdentDefRule; } break; case RULE_VariableIdent: /* VariableIdent */ if (VarDef) /* une definition de variable */ if (Identifier[nb - 1].SrcIdentDefRule != 0) /* nom deja declare' */ CompilerMessage (wi, TRA, FATAL, INVALID_NAME_REDECLARATION, inputLine, LineNum); else if (pTSchema->TsNVariables >= MAX_TRANSL_VARIABLE) /* table des variables saturee */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_VARIABLES_OVERFLOW, inputLine, LineNum); else { pTSchema->TsVariable[pTSchema->TsNVariables++].TrvNItems = 0; Identifier[nb - 1].SrcIdentDefRule = pTSchema->TsNVariables; } else if (pr == RULE_Token) /* dans une regle Create ou Write */ if (Identifier[nb - 1].SrcIdentDefRule == 0) /* variable non definie */ CompilerMessage (wi, TRA, FATAL, UNKNOWN_VARIABLE, inputLine, LineNum); else { CurTRule->TrObject = ToVariable; CurTRule->TrObjectNum = Identifier[nb - 1].SrcIdentDefRule; } else if (pr == RULE_VarOrType) /* dans une regle Create ou Write */ { VarDefinition = False; if (Identifier[nb - 1].SrcIdentDefRule == 0) /* variable non definie */ /* c'est peut-etre un nom de type d'element */ { CurTRule->TrObject = ToReferredElem; CopyWord (TypeInGetRule, wi, wl); BeginTypeInGetRule = wi; } else /* la variable est bien definie */ { CurTRule->TrObject = ToVariable; CurTRule->TrObjectNum = Identifier[nb - 1].SrcIdentDefRule; } } else if (pr == RULE_RuleA || pr == RULE_RuleB) if (Identifier[nb - 1].SrcIdentDefRule == 0) /* variable non definie */ CompilerMessage (wi, TRA, FATAL, UNKNOWN_VARIABLE, inputLine, LineNum); else if (CurTRule->TrType == TCreate) /* indication du fichier de sortie dans une regle Create */ CurTRule->TrFileNameVar = Identifier[nb - 1].SrcIdentDefRule; else if (CurTRule->TrType == TChangeMainFile) CurTRule->TrNewFileVar = Identifier[nb - 1].SrcIdentDefRule; else if (CurTRule->TrType == TIndent) CurTRule->TrIndentFileNameVar = Identifier[nb - 1].SrcIdentDefRule; else if (CurTRule->TrType == TRemoveFile) CurTRule->TrNewFileVar = Identifier[nb - 1].SrcIdentDefRule; break; case RULE_AttrIdent: /* AttrIdent */ i = AttributeNum (wi, wl); if (pr == RULE_TransAttr) if (i == 0) CompilerMessage (wi, TRA, FATAL, BAD_ATTR, inputLine, LineNum); else /* l'attribut existe, il a le numero i*/ /* c'est un nom d'attribut auquel on va associer des */ /* regles de traduction */ { CurAttr = i; CurValAttr = 0; /* pas encore rencontre' de valeur */ CurBlock = NULL; CurTRule = NULL; pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; switch (pSSchema->SsAttribute[CurAttr - 1].AttrType) { case AtNumAttr: /* attribut a valeur numerique */ if (pAttrTrans->AtrNCases >= MAX_TRANSL_ATTR_CASE) /* trop de cas pour cet attribut */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_CASES_FOR_ATTR_OVERFLOW, inputLine, LineNum); else pAttrTrans->AtrNCases++; break; case AtTextAttr /* attribut textuel */ : if (pAttrTrans->AtrTxtTRuleBlock != NULL) /* attribut deja rencontre' */ CompilerMessage (wi, TRA, FATAL, RULES_ALREADY_EXIST_FOR_THAT_ATTR, inputLine, LineNum); break; case AtReferenceAttr: if (pAttrTrans->AtrRefTRuleBlock != NULL) /* attribut deja rencontre' */ CompilerMessage (wi, TRA, FATAL, RULES_ALREADY_EXIST_FOR_THAT_ATTR, inputLine, LineNum); break; case AtEnumAttr: break; default: break; } } else if (pr == RULE_CondOnAscend) /* un nom d'attribut dans une condition */ if (i == 0) /* ce n'est pas un attribut connu */ /* c'est peut etre un type d'element*/ { if (ElementTypeInCond (wi, wl)) /* ce nom est maintenant un type */ Identifier[nb - 1].SrcIdentCode = RULE_TypeIdent; } else /* c'est un attribut du schema */ { ProcessAncestorName (pSSchema); if (!Asterisk) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRelLevel = -1; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcCondition = TcondAttr; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr = i; switch (pSSchema->SsAttribute[i - 1].AttrType) { case AtNumAttr: CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = -MAX_INT_ATTR_VAL - 1; /* -infini */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = MAX_INT_ATTR_VAL + 1; /* +infini */ break; case AtTextAttr: CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcTextValue[0] = '\0'; break; case AtReferenceAttr: break; /* rien */ case AtEnumAttr: CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttrValue = 0; break; default: break; } } else if (pr == RULE_Token || pr == RULE_CountFunction || pr == RULE_Function) AttrInCreateOrWrite (i, pr, wi); break; case RULE_AttrValIdent: /* AttrValIdent */ CopyWord (n, wi, wl); /* verifie si cette valeur existe pour l'attribut courant */ if (InCondition) k = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else k = CurAttr; pAttr = &pSSchema->SsAttribute[k - 1]; if (pAttr->AttrType != AtEnumAttr) /* pas un attribut a valeur enumerees */ CompilerMessage (wi, TRA, FATAL, BAD_ATTR_VALUE, inputLine, LineNum); else { i = 1; while (strcmp (n, pAttr->AttrEnumValue[i - 1]) != 0 && i < pAttr->AttrNEnumValues) i++; if (strcmp (n, pAttr->AttrEnumValue[i - 1]) != 0) /* valeur d'attribut incorrecte */ CompilerMessage (wi, TRA, FATAL, BAD_ATTR_VALUE, inputLine, LineNum); else /* la valeur est correcte, elle a le numero i */ if (!InCondition) /* debut des regles de traduction d'un attribut */ if (pTSchema->TsAttrTRule[CurAttr - 1].AtrEnuTRuleBlock[i] != NULL) /* deja des regles pour cette valeur */ CompilerMessage (wi, TRA, FATAL, RULES_ALREADY_EXIST_FOR_THAT_VALUE, inputLine, LineNum); else CurValAttr = i; else /* un nom d'attribut dans une condition */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttrValue = i; } break; case RULE_Alphabet: /* Alphabet */ if (pr == RULE_TSeqOfTransl) /* Deja des regles de traduction pour cet alphabet ? */ { for (i = 0; i < pTSchema->TsNTranslAlphabets - 1; i++) if (pTSchema->TsTranslAlphabet[i].AlAlphabet == inputLine[wi - 1]) CompilerMessage (wi, TRA, FATAL, CANT_REDEFINE_ALPHABET, inputLine, LineNum); if (!error) pTSchema->TsTranslAlphabet[pTSchema->TsNTranslAlphabets - 1]. AlAlphabet = inputLine[wi - 1]; } else if (pr == RULE_CondOnSelf) /* dans une condition */ CurBlock->TbCondition[CurBlock->TbNConditions - 1]. TcAlphabet = inputLine[wi - 1]; break; case RULE_TrSchema: /* TrSchema */ CopyWord (CurTRule->TrTranslSchemaName, wi, wl); break; case RULE_Pattern: /* Pattern */ case RULE_Color: /* Color */ CopyWord (n, wi, wl); /* cherche le numero de cette trame ou de cette couleur */ if (r == RULE_Pattern) k = PatternNum (n, wi); else k = ColorNum (n, wi); if (InCondition) { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; } else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; pCase = &pPresTrans->RtCase[pPresTrans->RtNCase - 1]; pCase->TaUpperBound = k; pCase->TaLowerBound = k; } break; default: break; } break; case 3002: /* un nombre */ k = AsciiToInt (wi, wl); switch (r) /* r= numero de regle */ { case RULE_MaxLineLength: /* MaxLineLength */ pTSchema->TsLineLength = k; break; case RULE_AncestorLevel: /* AncestorLevel */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnAcestorLevel = k * AncestorSign; break; case RULE_IndentVal: /* IndentVal */ if (IndentSign != 0) /* indent value is relative */ { CurTRule->TrRelativeIndent = TRUE; k = k * IndentSign; } CurTRule->TrIndentVal = k; break; case RULE_RelLevel: /* RelLevel */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendLevel = k; if (!GreaterOrLessSign) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRel = RelEquals; break; case RULE_CondRelLevel: /* CondRelLevel */ CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAscendRelLevel = k; break; case RULE_InitValue: /* InitValue */ if (pr == RULE_CountFunction) /* dans une definition de compteur */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnParam1 = k; else if (pr == RULE_RuleB) /* dans une instruction de traduction Set */ CurTRule->TrCounterParam = k; break; case RULE_IncrValue: /* IncrValue */ if (pr == RULE_CountFunction) /* dans une definition de compteur */ pTSchema->TsCounter[pTSchema->TsNCounters - 1].TnParam2 = k; else if (pr == RULE_RuleB) /* dans une instruction de traduction Add */ CurTRule->TrCounterParam = k; break; case RULE_Length: /* Length */ pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; pTransVar->TrvItem[pTransVar->TrvNItems - 1].TvLength = k; break; case RULE_MinVal: /* MinVal */ if (InCondition) i = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else i = CurAttr; if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr || k >= MAX_INT_ATTR_VAL) /* ce n'est pas un attribut numerique */ CompilerMessage (wi, TRA, FATAL, EXPECTING_A_NUMERICAL_ATTR, inputLine, LineNum); else { k = k * AttrValSign + 1; AttrValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaLowerBound = k; } } break; case RULE_MaxVal: /* MaxVal */ if (InCondition) i = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else i = CurAttr; if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr || k >= MAX_INT_ATTR_VAL) /* ce n'est pas un attribut numerique */ CompilerMessage (wi, TRA, FATAL, EXPECTING_A_NUMERICAL_ATTR, inputLine, LineNum); else { k = k * AttrValSign - 1; AttrValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaUpperBound = k; } } break; case RULE_MinInterval: /* MinInterval */ if (InCondition) i = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else i = CurAttr; if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr || k >= MAX_INT_ATTR_VAL) /* ce n'est pas un attribut numerique */ CompilerMessage (wi, TRA, FATAL, EXPECTING_A_NUMERICAL_ATTR, inputLine, LineNum); else { k = k * AttrValSign; AttrValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaLowerBound = k; } } break; case RULE_MaxInterval: /* MaxInterval */ if (InCondition) i = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else i = CurAttr; if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr || k >= MAX_INT_ATTR_VAL) /* ce n'est pas un attribut numerique */ CompilerMessage (wi, TRA, FATAL, EXPECTING_A_NUMERICAL_ATTR, inputLine, LineNum); else { k = k * AttrValSign; AttrValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) if (CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound > k) CompilerMessage (wi, TRA, FATAL, BAD_LIMITS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; if (pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaLowerBound > k) CompilerMessage (wi, TRA, FATAL, BAD_LIMITS, inputLine, LineNum); else pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1].TaUpperBound = k; } } break; case RULE_ValEqual: /* ValEqual */ if (InCondition) i = CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcAttr; else i = CurAttr; if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr || k >= MAX_INT_ATTR_VAL) /* ce n'est pas un attribut numerique */ CompilerMessage (wi, TRA, FATAL, BAD_LIMITS, inputLine, LineNum); else { k = k * AttrValSign; AttrValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; } else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; pCase = &pAttrTrans->AtrCase[pAttrTrans->AtrNCases - 1]; pCase->TaUpperBound = k; pCase->TaLowerBound = pCase->TaUpperBound; } } break; case RULE_MinimumPres: k = k * PresValSign + 1; PresValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaLowerBound = k; } break; case RULE_MaximumPres: k = k * PresValSign - 1; PresValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaUpperBound = k; } break; case RULE_MinIntervalPres: k = k * PresValSign; PresValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaLowerBound = k; } break; case RULE_MaxIntervalPres: k = k * PresValSign; PresValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) if (CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound > k) /* BorneInf > BorneSup !! */ CompilerMessage (wi, TRA, FATAL, BAD_LIMITS, inputLine, LineNum); else CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; if (pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaLowerBound > k) CompilerMessage (wi, TRA, FATAL, BAD_LIMITS, inputLine, LineNum); else pPresTrans->RtCase[pPresTrans->RtNCase - 1].TaUpperBound = k; } break; case RULE_PresVal: k = k * PresValSign; PresValSign = 1; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ if (InCondition) { CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcUpperBound = k; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcLowerBound = k; } else { pPresTrans = &pTSchema->TsPresTRule[CurPres - 1]; pCase = &pPresTrans->RtCase[pPresTrans->RtNCase - 1]; pCase->TaUpperBound = k; pCase->TaLowerBound = k; } break; default: break; } break; case 3003: /* une chaine de caracteres */ switch (r) /* r= numero de regle */ { case RULE_ConstValue: /* ConstValue */ if (ConstIndx + wl > MAX_TRANSL_CONST_LEN) /* plus de place pour les constantes */ CompilerMessage (wi, TRA, FATAL, MAX_CONSTANT_BUFFER_OVERFLOW, inputLine, LineNum); else /* FnCopy le texte de la constante */ { pTSchema->TsConstBegin[pTSchema->TsNConstants - 1] = ConstIndx; for (i = 0; i <= wl - 2; i++) pTSchema->TsConstant[ConstIndx + i - 1] = inputLine[wi + i - 1]; ConstIndx += wl; pTSchema->TsConstant[ConstIndx - 2] = '\0'; } break; case RULE_CharString: /* CharString */ NewConstant (wl, wi); if (!error) if (pr == RULE_Function) /* dans une definition de variable */ { pTransVar = &pTSchema->TsVariable[pTSchema->TsNVariables - 1]; if (pTransVar->TrvNItems >= MAX_TRANSL_VAR_ITEM) /* trop de fonctions */ CompilerMessage (wi, TRA, FATAL, MAX_POSSIBLE_ELEMS_IN_VARIABLE_OVERFLOW, inputLine, LineNum); else { pTransVar->TrvItem[pTransVar->TrvNItems].TvType = VtText; pTransVar->TrvItem[pTransVar->TrvNItems].TvItem = pTSchema->TsNConstants; pTransVar->TrvNItems++; } } else if (pr == RULE_Token) /* dans une regle Create ou Write */ { CurTRule->TrObject = ToConst; CurTRule->TrObjectNum = pTSchema->TsNConstants; } break; case RULE_TextEqual: /* TextEqual */ if (pSSchema->SsAttribute[CurAttr - 1].AttrType != AtTextAttr) /* ce n'est pas un attribut textuel */ CompilerMessage (wi, TRA, FATAL, NOT_A_TEXTUAL_ATTR, inputLine, LineNum); else if (wl > MAX_NAME_LENGTH) /* texte trop long */ CompilerMessage (wi, TRA, FATAL, MAX_NAME_SIZE_OVERFLOW, inputLine, LineNum); else if (InCondition) { for (i = 0; i < wl - 1; i++) CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcTextValue[i] = inputLine[wi + i - 1]; CurBlock->TbCondition[CurBlock->TbNConditions - 1].TcTextValue[wl - 1] = '\0'; } else { pAttrTrans = &pTSchema->TsAttrTRule[CurAttr - 1]; for (i = 0; i < wl - 1; i++) pAttrTrans->AtrTextValue[i] = inputLine[wi + i - 1]; pAttrTrans->AtrTextValue[wl - 1] = '\0'; } break; case RULE_FileName: /* FileName */ NewConstant (wl, wi); if (!error) { CurTRule->TrBufOrConst = ToConst; CurTRule->TrInclFile = pTSchema->TsNConstants; } break; case RULE_Source: /* Source */ if (wl > MAX_SRCE_LEN) /* chaine source trop longue */ CompilerMessage (wi, TRA, FATAL, MAX_STRING_SIZE_OVERFLOW, inputLine, LineNum); else if ((SymbTrans || GraphTrans) && wl > 2) /* dans les traductions de symboles et de graphiques */ /* la chaine source ne peut contenir qu'un caractere */ CompilerMessage (wi + 1, TRA, FATAL, ONLY_ONE_CHARACTER, inputLine, LineNum); else NewSourceString (wi, wl); break; case RULE_Target: /* Target */ if (wl > MAX_TARGET_LEN) /* chaine cible trop longue */ CompilerMessage (wi, TRA, FATAL, MAX_STRING_SIZE_OVERFLOW, inputLine, LineNum); else ProcessTargetString (wi, wl); break; case RULE_LineEndString: /* chaine de fin de ligne */ pTSchema->TsEOL[0] = inputLine[wi - 1]; break; case RULE_LineEndInsertString: /* chaine de fin de ligne */ if (wl <= MAX_NAME_LENGTH) for (i = 0; i < wl - 1; i++) pTSchema->TsTranslEOL[i] = inputLine[wi + i - 1]; pTSchema->TsTranslEOL[i] = '\0'; break; default: break; } break; } } } /*---------------------------------------------------------------------- main ----------------------------------------------------------------------*/ #ifdef __STDC__ int main (int argc, char **argv) #else /* __STDC__ */ int main (argc, argv) int argc; char **argv; #endif /* __STDC__ */ { FILE *infile; boolean fileOK; char fname[200], buffer[200], cmd[800]; char *pwd, *ptr; Name srceFileName; /* nom du fichier a compiler */ indLine wi; /* position du debut du mot courant dans la ligne */ indLine wl; /* longueur du mot courant */ SyntacticType wn; /* SyntacticType du mot courant */ SyntRuleNum r; /* numero de regle */ SyntRuleNum pr; /* numero de la regle precedente */ SyntacticCode c; /* code grammatical du mot trouve */ int nb; /* indice dans Identifier du mot trouve, si c'est un identificateur */ int i; int param; TtaInitializeAppRegistry (argv[0]); i = TtaGetMessageTable ("libdialogue", TMSG_LIB_MSG_MAX); COMPIL = TtaGetMessageTable ("compildialogue", COMP_MSG_MAX); TRA = TtaGetMessageTable ("tradialogue", TRA_MSG_MAX); error = False; /* initialise l'analyseur syntaxique */ InitParser (); InitSyntax ("TRANS.GRM"); if (!error) { /* prepare the cpp command */ strcpy (cmd, "cpp "); param = 1; while (param < argc && argv[param][0] == '-') { /* keep cpp params */ strcat (cmd, argv[param]); strcat (cmd, " "); param++; } /* recupere d'abord le nom du schema a compiler */ if (param >= argc) { TtaDisplaySimpleMessage (FATAL, TRA, MISSING_FILE); exit (1); } strncpy (srceFileName, argv[param], MAX_NAME_LENGTH - 1); srceFileName[MAX_NAME_LENGTH - 1] = '\0'; param++; strcpy (fname, srceFileName); /* check if the name contains a suffix */ ptr = strrchr(fname, '.'); nb = strlen (srceFileName); if (!ptr) /* there is no suffix */ strcat (srceFileName, ".T"); else if (strcmp(ptr, ".T")) { /* it's not the valid suffix */ TtaDisplayMessage (FATAL, TtaGetMessage (TRA, INVALID_FILE), srceFileName); exit (1); } else { /* it's the valid suffix, cut the srcFileName here */ ptr[0] = '\0'; nb -= 2; /* length without the suffix */ } /* add the suffix .SCH in srceFileName */ strcat (fname, ".SCH"); /* does the file to compile exist */ if (TtaFileExist (srceFileName) == 0) TtaDisplaySimpleMessage (FATAL, TRA, MISSING_FILE); else { /* provide the real source file */ TtaFileUnlink (fname); pwd = TtaGetEnvString ("PWD"); i = strlen (cmd); if (pwd != NULL) sprintf (&cmd[i], "-I%s -C %s > %s", pwd, srceFileName, fname); else sprintf (&cmd[i], "-C %s > %s", srceFileName, fname); i = system (cmd); if (i == -1) { /* cpp is not available, copy directely the file */ TtaDisplaySimpleMessage (INFO, TRA, CPP_NOT_FOUND); TtaFileCopy (srceFileName, fname); } infile = TtaReadOpen (fname); if (param == argc) /* the output name is equal to the input name */ /*suppress the suffix ".SCH" */ srceFileName[nb] = '\0'; else /* read the output name */ strncpy (srceFileName, argv[param], MAX_NAME_LENGTH - 1); /* le fichier a compiler est ouvert */ /* acquiert la memoire pour le schema de traduction */ GetSchTra (&pTSchema); if (pTSchema == NULL) TtaDisplaySimpleMessage (FATAL, TRA, OUT_OF_MEMORY); NIdentifiers = 0; /* table des identificateurs vide */ LineNum = 0; Initialize (); /* prepare la generation */ /* lit tout le fichier et fait l'analyse */ fileOK = True; while (fileOK && !error) /* lit une ligne */ { i = 0; do { fileOK = TtaReadByte (infile, &inputLine[i]); i++; } while (i < LINE_LENGTH && inputLine[i - 1] != '\n' && fileOK); /* marque la fin reelle de la ligne */ inputLine[i - 1] = '\0'; /* incremente le compteur de lignes */ LineNum++; if (i >= LINE_LENGTH) CompilerMessage (1, TRA, FATAL, MAX_LINE_SIZE_OVERFLOW, inputLine, LineNum); else if (inputLine[0] == '#') /* cette ligne contient une directive du preprocesseur cpp */ { sscanf (inputLine, "# %d %s", &LineNum, buffer); LineNum--; } else /* traduit les caracteres de la ligne */ { OctalToChar (); /* analyse la ligne */ wi = 1; wl = 0; /* analyse tous les mots de la ligne courante */ do { i = wi + wl; GetNextToken (i, &wi, &wl, &wn); /* mot suivant */ if (wi > 0) /* on a trouve un mot */ { AnalyzeToken (wi, wl, wn, &c, &r, &nb, &pr); /* on analyse le mot */ if (!error) ProcessToken (wi, wl, c, r, nb, pr); /* on le traite */ } } while (wi != 0 && !error); } /* il n'y a plus de mots dans la ligne */ } TtaReadClose (infile); if (!error) ParserEnd (); /* fin d'analyse */ if (!error) { /* remove temporary file */ TtaFileUnlink (fname); /* ecrit le schema compile' dans le fichier de sortie */ /* le directory des schemas est le directory courant */ strcat (srceFileName, ".TRA"); fileOK = WriteTranslationSchema (srceFileName, pTSchema, pSSchema); if (!fileOK) TtaDisplayMessage (FATAL, TtaGetMessage (TRA, CANT_WRITE), srceFileName); } free (pTSchema); free (pSSchema); free (pExtSSchema); } } TtaSaveAppRegistry (); exit (0); }