/* interpretation sur une liste de token deja accumulee */ #include #include #include "assert.h" #include #include "proto.h" void tokrec_inilec (TOKEN_LIST *toklist) { toklist->curlec[0] = toklist->first; toklist->poslec = 0; } /* Avance de 1 dans une liste de token (même niveau) Retourne -1 si pas de suivant */ int tokrec_next (TOKEN_LIST *toklist) { int poslec = toklist->poslec; TOKEN_ITEM *item = toklist->curlec[poslec]; int ok = -1; toklist->curlec[poslec] = item->next; if (item->next!=NULL){ ok = 0; } return ok; } void tokrec_recule (TOKEN_LIST *toklist) { int poslec = toklist->poslec; TOKEN_ITEM *item = toklist->curlec[poslec]; TOKEN_ITEM *pt; if (poslec > 0){ pt = toklist->curlec[poslec-1]->sous; }else{ pt = toklist->first; } if (pt != item){ while (pt != NULL && pt->next != item) pt = pt->next; assert (pt!=NULL); } toklist->curlec[poslec] = pt; } /* Sélectionne la sous-liste associé au token courant. Retourne -1 si pas de sous-liste. */ int tokrec_descend(TOKEN_LIST *toklist) { TOKEN_ITEM *item = toklist->curlec[toklist->poslec]; int ok = -1; if (item->sous != NULL){ int poslec = ++toklist->poslec; ok = 0; toklist->curlec[poslec] = item->sous; } return ok; } void tokrec_monte (TOKEN_LIST *toklist) { assert (toklist->poslec>0); toklist->poslec--; } void tokrec_insert ( TOKEN_LIST *toklist, TOKEN *token) { TOKEN_ITEM *newt = (TOKEN_ITEM*) malloc_err (sizeof(TOKEN_ITEM),1); int poslec = toklist->poslec; TOKEN_ITEM *item = toklist->curlec[poslec]; TOKEN_ITEM *prec; assert (newt!=NULL); newt->tok = *token; newt->sous = NULL; newt->next = item; tokrec_recule (toklist); prec = toklist->curlec[poslec]; if (prec == item){ /* item etait le premier */ if (poslec>0){ toklist->curlec[poslec-1]->sous = newt; }else{ toklist->first = newt; } }else{ prec->next = newt; } toklist->curlec[poslec] = newt; } /* retourne token ou NULL si fin de liste pour ce niveau */ TOKEN *tokrec_get (TOKEN_LIST *toklist) { TOKEN_ITEM *item = toklist->curlec[toklist->poslec]; if (item != NULL){ return (&item->tok); } return (NULL); } /* Fonction récursive pour balayer la liste de token et trouve longueur */ static int near tokrec_getlentxt0(TOKEN_LIST *toklist) { int ret = 0; TOKEN *tok; while ((tok = tokrec_get (toklist))!=NULL){ ret += strlen(token_txt(tok)) + 1; if (tok->type == TOK_OPNPAR){ if (tokrec_descend (toklist) != -1){ ret += tokrec_getlentxt0(toklist); tokrec_monte (toklist); } } tokrec_next (toklist); } return ret; } /* Calcul la longueur total de tous les tokens dans la liste. Cette fonction est utilisé pour déterminer (rapidement) si on doit générer un prototype avec un argument par ligne ou tous les arguments sur la même lignes. Calcul un espace entre chaque token. La longueur obtenu est donc plus grande que réelle. Il faudrait utilisée token_needsep() pour être exacte. Le résultat est tout de même plaisant même si un peu arbitraire. tokl pointera à la fin de la liste. */ int tokrec_getlentxt (TOKEN_LIST *toklist) { tokrec_inilec (toklist); return tokrec_getlentxt0(toklist); }