/**********************************************************************/ /* ** F R A A S I T . C ** */ #include #include #include #include #include "dhk.h" /**********************************************************************/ int alkumerkki ( /* 0 = alkumerkki„ ei l”ytynyt, 1 = alkumerkki l”ytyi */ char *jono, /* Merkkijono, josta etsit„„n */ char merkki /* Etsitt„v„ merkki */ ) { if (jono[0] == merkki ) { memmove(&jono[0],&jono[1],strlen(jono)); return 1; } return 0; } /*--------------------------------------------------------------------*/ char *palanen( /* Osoitin merkkijonon palaseen */ char *jono ,/* s P„tkitt„v„ jono, turmeltuu! */ char *erottimet ,/* s Merkit joiden kohdalla katkaistaan */ int *jaljella /* t Paljonko jonoa on viel„ j„ljell„ (-1 loppu)*/ ) { static char *st; static int p1, p2, pit; if (jono) { /* 1. kutsukerta, alustetaan apumuuttujat */ st = jono; pit = strlen(jono); p1 = 0; } else p1 = p2+1; /* Muilla kerroilla jatketaan siit„ mihin viim. j„„tiin */ if (p1 > pit) { *jaljella = -1; return st+pit; /* Tyhj„ merkkijono, kun osoitetaan jonon null-tavuun */ } p2 = p1+strcspn(st+p1, erottimet); st[p2] = 0; *jaljella = pit-p2; return st+p1; } /*--------------------------------------------------------------------*/ int tee_tilaa( /* 0 = ok, -1 = tila loppui taulukosta tai indeksi v„„rin */ fraasi_taulu ftaulu, /* fraasitaulukko */ int indeksi /* k„sitelt„v„n alkion indeksi */ ) { int j; int suurin_indeksi; if (indeksi>MAX_LUOKKANIMIKKEITA) return -1; /* Etsit„„n viimeinen k„yt”ss„ oleva taulukon alkio */ /* Viimeist„ k„yt”ss„ olevaa indeksi„ voitaisiin tosin */ /* s„ilytt„„ my”s jossain muuttujassa. */ suurin_indeksi=indeksi; while ((suurin_indeksi < MAX_LUOKKANIMIKKEITA ) && (ftaulu[suurin_indeksi].r != 0)) suurin_indeksi++; for (j=suurin_indeksi; j>indeksi; ftaulu[j] = ftaulu[--j]); return 0; } /*--------------------------------------------------------------------*/ int hae_paikka( /* Palauttaa indeksin vapaaseen paikkaan ftaulussa */ fraasi_taulu ftaulu, /* Fraasitaulukko */ int *ss, /* Suhteellisesti sijoittuvien fraasien alkukohta */ int *sts, /* Suht. tekstin j„lkeen sijoittuvien fraasien alkukohta */ int j /* Merkkeja j„ljell„ luokkanimikkeessa (koordinaatit) */ ) { char *rkoordinaatti, *skoordinaatti; int rk=0, sk=1, indeksi = 0; if (j==0) { /* suhteellisesti sijoittuva */ indeksi = *sts; /* Lis„t„„n suhteellisesti sijoittuvien loppuun */ tee_tilaa(ftaulu, indeksi); ftaulu[indeksi].r = -1; /* Merkit„„n k„ytetyksi */ (*sts)++; /* Kasvatetaan suht. tekstin j„lk. sij. alkukohtaa yhdell„ */ return indeksi; } rkoordinaatti = palanen(NULL, erotinmerkki, &j); if (alkumerkki(rkoordinaatti,'+')) { /* suhteellisesti tekstin j„lkeen sijoittuva = lis„t„„n loppuun */ indeksi = *sts; while ((ftaulu[indeksi].r != 0) && (indeksi= *ss) break; indeksi++; } skoordinaatti = palanen(NULL, erotinmerkki, &j); if (j==0) { /* Mukana my”s sarakekoordinaatti */ sscanf(skoordinaatti, "%d", &sk); if (sk > ftaulu[indeksi].s) indeksi++; } /* Jos kahdella fraasilla on sama rivi- ja sarakekoordinaatti */ /* j„lkimm„inen korvaa edellisen. Muutoin tehd„„n tilaa taulukkoon. */ if (((ftaulu[indeksi].r<1)) || ((ftaulu[indeksi].r != rk) || (ftaulu[indeksi].s != sk))) { tee_tilaa(ftaulu,indeksi); (*ss)++; /* Kasvatetaan suht. sij. alkukohtaa yhdell„ */ (*sts)++; /* Kasvatetaan suht. tekstin j„lk. sij. alkukohtaa yhdell„ */ } ftaulu[indeksi].r = rk; if (j==0) ftaulu[indeksi].s = sk; return indeksi; } /*--------------------------------------------------------------------*/ /* Varoitus: Aliohjelma ei sulje tiedostoa ft */ int lue_luokkanimike( /* Palautetaan alkion indeksi */ /* -1 = tiedosto loppu */ FILE *ft, /* Fraasitiedosto */ fraasi_taulu ftaulu, /* Osoittimet fraasilistojen alkuun */ int *ss, /* Suht. sij. fraasien alkukohta */ int *sts /* Suht. tekstin j„lkeen sij. alkukohta */ ) { int j; /* Merkkej„ j„ljell„ merkkijonossa */ int indeksi; /* Paikka, johon alkio lis„t„„n */ rivityyppi rivi,apurivi; /* Tiedoston rivi */ char *pala; /* Pala merkkijonosta rivi */ tunnus_solmu *t_solmu; /* Osoitin listan tunnussolmuun */ lista_alkio *l_alkio; /* Osoitin tavalliseen lista_alkioon */ /* T„m„ rivi sis„lt„„ luokkanimikkeen */ fgets(rivi, RIVINPITUUS, ft); if (feof(ft)) return -1; do { fgets(apurivi, RIVINPITUUS, ft); if (feof(ft)) return -1; } while (strstr(apurivi,"--") != apurivi); rivi[strlen(rivi)-1] = 0; /* Lis„t„„n merkkijonon loppumerkki */ pala = strdup(palanen(rivi,erotinmerkki,&j)); t_solmu = T_ALLOC; l_alkio = L_ALLOC; t_solmu->seuraava = l_alkio; t_solmu->esivalittu = l_alkio; /* Oletus */ t_solmu->vari = GREEN; l_alkio->pituus = 1; l_alkio->mjono = pala; l_alkio->seuraava = NULL; indeksi = hae_paikka(ftaulu, ss, sts, j); ftaulu[indeksi].tsolmu = t_solmu; return indeksi; } /*--------------------------------------------------------------------*/ /* Aliohjelma lukee parametrina tuodusta tiedostosta rivej„ seuraavaan*/ /* tyhj„„n riviin saakka. Rivit yhdistet„„n yhteen merkkitaulukkoon. */ int lue_1_fraasi( /* 0 = jatkuu, 1 = viimeinen fraasi */ FILE *ft, /* Fraasitiedosto */ pitka_merkkijono pmjono, /* Apumuuttuja, johon fraasi luetaan */ int *pituus_rivia /* Fraasin pituus rivein„ */ ) { rivityyppi rivi, apurivi; pmjono[0]=0; *pituus_rivia = 0; fgets(rivi,RIVINPITUUS,ft); rivi[strlen(rivi)-1]=0; while (strstr(rivi,"--") != rivi) { if ((strstr(rivi,"=="))==rivi) return 1; else { fgets(apurivi,RIVINPITUUS,ft); apurivi[strlen(apurivi)-1]=0; } if ((strstr(apurivi,"==")!=apurivi) && (strstr(apurivi,"--")!=apurivi)) { rivi[strlen(rivi)] = VALIMERKKI; } (*pituus_rivia)++; strcat(pmjono,rivi); strcpy(rivi,apurivi); } return 0; } /*--------------------------------------------------------------------*/ void lue_fraasit(FILE *ft, /* fraasitiedosto */ fraasi_taulu ftaulu, /* fraasitaulukko */ int indeksi /* k„sitelt„v„n fraasilistan indeksi taulukossa */ ) { pitka_merkkijono pmjono; lista_alkio *l_alkio_1, *l_alkio_2; tunnus_solmu *t_solmu; int pituus_rivia; /* Fraasin pituus rivein„ */ int loppu; t_solmu = ftaulu[indeksi].tsolmu; t_solmu->seuraava->edellinen=NULL; /* 2 suuntainen linkitys */ do { loppu = lue_1_fraasi(ft,pmjono,&pituus_rivia); for (l_alkio_1 = t_solmu->seuraava; l_alkio_1->seuraava; l_alkio_1 = l_alkio_1->seuraava); l_alkio_2 = L_ALLOC; /* Onko esivalittu */ if (alkumerkki(pmjono,'@')) { t_solmu->esivalittu = l_alkio_2; t_solmu->vari = YELLOW; ftaulu[indeksi].p = pituus_rivia; } l_alkio_1->seuraava = l_alkio_2; l_alkio_2->edellinen = l_alkio_1; l_alkio_2->pituus = pituus_rivia; l_alkio_2->mjono = strdup(pmjono); l_alkio_2->seuraava = NULL; } while (!loppu); } /*--------------------------------------------------------------------*/ void aseta_rivinumerot(fraasi_taulu ftaulu, int ss) { int rivinro,i; if (ss==0) rivinro=1; else rivinro=ftaulu[ss-1].r + ftaulu[ss-1].p; for (i=ss; ftaulu[i].r==-1; i++) { ftaulu[i].r=rivinro; rivinro+=ftaulu[i].p; if (i==MAX_LUOKKANIMIKKEITA) break; } } /*--------------------------------------------------------------------*/ void lue_fraasitiedosto( tlista_os *t_osoitin, /* Osoitin valittuun luokkanimikkeeseen */ fraasi_taulu ftaulu /* Osoittimet fraasilistojen alkuun */ ) { FILE *ft; /* Fraasitiedosto */ int i; /* fraasi_taulun indeksit */ int ss = 0; /* Suht. sij. fraasien alkukohta */ int sts = 0; /* Suht. tekstin j„lkeen sij. fraasien alkukohta */ rivityyppi rivi; /* Tiedoston rivi */ char c; /* Alustetaan taulukko */ for (i=0; i < MAX_LUOKKANIMIKKEITA; i++) { ftaulu[i].r=0; ftaulu[i].p=1; ftaulu[i].s=1; } t_osoitin++; while (*t_osoitin) { ft = fopen((*t_osoitin),"rt"); if (!ft) { printf("Virhe: Tiedostoa %s ei l”ydy!\n",*t_osoitin); printf("Jatketaanko (K/E):"); c=getch(); printf("\n"); if (strchr(KYLLA,c)) clearerr(ft); else { clrscr(); exit(0); } } else { do { fgets(rivi, RIVINPITUUS, ft); if (feof(ft)) goto loppu; } while (strstr(rivi,"==") != rivi); while ((i=lue_luokkanimike(ft,ftaulu,&ss,&sts)) >= 0) lue_fraasit(ft,ftaulu,i); } loppu: t_osoitin++; fclose(ft); } aseta_rivinumerot(ftaulu, ss); } /*--------------------------------------------------------------------*/