Updated source code from upstream SVN
[svmtool++.git] / src / swindow.cc
blob767b9c817938f6ab31b25c947fe680a4770dab34
1 /*
2 * Copyright (C) 2004 Jesus Gimenez, Lluis Marquez and Senen Moya
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "swindow.h"
21 #include "hash.h"
22 #include "nodo.h"
23 #include "list.h"
24 #include "dict.h"
25 #include "weight.h"
26 #include "er.h"
27 #include "common.h"
28 #include "marks.h"
29 #include <sys/types.h>
30 #include <cassert>
31 #include <regex.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sstream>
36 #include <limits>
37 #include <set>
39 #define MAX_SENTENCE_LENGTH 1000
40 #define MAX_LINE_LENGTH 4096
42 /*****************************************************************
43 * Feature Generation
44 *****************************************************************/
46 void swindow::winPushStartWithLowerFeature(const std::string& wrd, std::stack<std::string>&pila)
48 int startlower=0;
50 //Comienza por Minuscula?
51 if (erLookRegExp2(&erStartLower,wrd))
53 startlower = 1;
55 std::ostringstream feat;
56 feat << START_LOWER_MARK<<":"<<startlower;
58 pila.push(feat.str());
62 void swindow::winPushStartWithNumberFeature(const std::string& wrd, std::stack<std::string>&pila)
64 int startnumber=0;
66 //Comienza por Numero?
67 if (erLookRegExp2(&erStartNumber,wrd))
69 startnumber = 1;
71 //mod Correcting dynamic memory errors
72 std::ostringstream feat;
73 feat << START_NUMBER_MARK<<":" << startnumber;
75 pila.push(feat.str());
79 void swindow::winPushSuffixFeature(const std::string& wrd, std::stack<std::string>& pila,int longitud)
81 //Obtenemos la longitud de la palabra
83 std::ostringstream feat;
84 int len = wrd.size();
85 std::ostringstream suf;
86 //int a=0;
88 for (int i=len-longitud; i<=len-1; i++)
90 if (i>=0) suf<<wrd[i];
91 else suf<<"~";
95 feat<<SUFFIX_MARK<<longitud<<":"<<suf.str();
96 pila.push(feat.str());
100 * void winPushPreffixFeatures ( std::string wrd, struct std::stack *pila, int longitud)
101 * esta funcion creara las "features" para la palabra desconocida
102 * <wrd> y las apilara en en el parametro <pila>
104 void swindow::winPushPrefixFeature(const std::string& wrd, std::stack<std::string>& pila, int longitud)
106 //Obtenemos la longitud de la palabra
107 std::ostringstream feat;
108 int len = wrd.size();
109 std::ostringstream pref;
111 for (int i=0; i<longitud; i++)
113 if (len > i) pref<<wrd[i];
114 else /*if (i > len-1 )*/ pref<<"~";
117 feat<<PREFIX_MARK<<longitud<<":"<<pref.str();
118 pila.push(feat.str());
122 void swindow::winPushStartWithCapFeature(const std::string& wrd, std::stack<std::string>&pila)
124 int startcap=0;
126 //Comienza por Mayuscula?
127 if (erLookRegExp2(&erStartCap,wrd))
129 startcap = 1;
130 //mod Correcting dynamic memory errors
131 //std::string feat = new char[strlen(START_CAPITAL_MARK)+4];
132 std::ostringstream feat;
134 feat << START_CAPITAL_MARK<<":"<<startcap;
135 pila.push(feat.str());
139 void swindow::winPushAllUpFeature(const std::string& wrd, std::stack<std::string>& pila)
141 int allup=0;
143 //Esta toda la palabra en mayusculas?
144 if (erLookRegExp2(&erAllUp,wrd))
146 allup = 1;
148 //mod Correcting dynamic memory errors
149 //std::string feat = new char[4];
150 std::ostringstream feat;
152 feat << ALL_UPPER_MARK<<":"<<allup;
153 pila.push(feat.str());
157 void swindow::winPushAllLowFeature(const std::string& wrd, std::stack<std::string>& pila)
159 int alllow = 0;
160 //Esta toda la palabra en minusculas?
161 if (erLookRegExp2(&erAllLow,wrd))
163 alllow = 1;
165 //mod Correcting dynamic memory errors
166 //std::string feat = new char[4];
167 std::ostringstream feat;
169 feat << ALL_LOWER_MARK<<":"<<alllow;
170 pila.push(feat.str());
174 void swindow::winPushContainCapFeature(const std::string& wrd, std::stack<std::string>& pila)
176 int containcap = 0;
177 if (erLookRegExp2(&erContainCap,wrd))
179 containcap = 1;
181 //mod Correcting dynamic memory errors
182 //std::string feat = new char[4];
183 std::ostringstream feat;
185 feat << CONTAIN_CAP_MARK<<":"<<containcap;
186 pila.push(feat.str());
190 void swindow::winPushContainCapsFeature(const std::string& wrd, std::stack<std::string>& pila)
192 int containcaps = 0;
193 if (erLookRegExp2(&erContainCaps,wrd))
195 containcaps = 1;
197 //mod Correcting dynamic memory errors
198 //std::string feat;
199 std::ostringstream feat;
201 feat << CONTAIN_CAPS_MARK <<":"<<containcaps;
202 pila.push(feat.str());
206 void swindow::winPushContainPeriodFeature(const std::string& wrd, std::stack<std::string>& pila)
208 int containperiod = 0;
209 //Contiene un punto?
210 if (erLookRegExp2(&erContainPeriod,wrd))
212 containperiod = 1;
213 std::stringstream feat;
214 feat << CONTAIN_PERIOD_MARK<<":"<<containperiod;
215 pila.push(feat.str());
219 void swindow::winPushContainCommaFeature(const std::string& wrd, std::stack<std::string>& pila)
221 int containcomma = 0;
222 //Contiene un punto?
223 if (erLookRegExp2(&erContainComma,wrd))
225 containcomma = 1;
226 std::ostringstream feat;
227 feat << CONTAIN_COMMA_MARK<<":"<<containcomma;
228 pila.push(feat.str());
232 void swindow::winPushContainNumFeature(const std::string& wrd, std::stack<std::string>& pila)
234 int containnum = 0;
235 //Contiene un numero?
236 if (erLookRegExp2(&erContainNum,wrd))
238 containnum = 1;
240 std::ostringstream feat;
241 //mod
242 //sprintf(feat,"CN:%d",containnum);
243 feat << CONTAIN_NUMBER_MARK<<":"<<containnum;
244 pila.push(feat.str());
248 void swindow::winPushMultiwordFeature(const std::string& wrd, std::stack<std::string>& pila)
250 int multiword = 0;
251 //Es una palabra multiple?
252 if (erLookRegExp2(&erMultiWord,wrd))
254 multiword = 1;
256 //mod Correcting dynamic memory errors
257 //std::string feat = new char[6];
258 //sprintf(feat,"MW:%d",multiword);
259 std::ostringstream feat;
260 feat << MULTIWORD_MARK<<":"<<multiword;
262 pila.push(feat.str());
266 void swindow::winPushLetterFeature(const std::string& wrd, std::stack<std::string>&pila, int where, int position)
268 std::ostringstream feature;
270 if (COUNTING_FROM_END==where)
272 feature<<CHAR_Z_MARK << position<<":"<<wrd[wrd.size()-position];
274 else
276 feature<<CHAR_A_MARK<<position<<":"<<wrd[position-1];
279 pila.push(feature.str());
282 void swindow::winPushLenghtFeature(const std::string& wrd, std::stack<std::string>& pila)
284 //Obtenemos la longitud de la palabra
285 int len = wrd.size();
287 //Longitud de la palabra
288 //mod Correcting dynamic memory errors
289 //std::string feat = new char[4];
290 std::ostringstream feat;
292 feat <<LENGTH_MARK<< ":"<<len;
293 pila.push(feat.str());
297 * void winPushSwnFeature (struct std::stack *pila)
298 * Recibe como parametro <pila>, donde se apilara la "feature"
299 * Swn.Swn es el elemento final de frase que puede ser
300 * ! ? o .
302 void swindow::winPushSwnFeature(std::stack<std::string>& pila)
304 std::string feature = "Swn:";
305 feature += ".";
306 pila.push(feature);
311 * void winPushAmbiguityFeature(void *ptr, dictionary *d, std::stack *pila, int direction)
312 * Genera el atributo que representa la ambiguedad de una palabra.
313 * Recibe como parametros:
314 * ptr, que es un puntero a un nodo de la lista de atributos (nodo_feature_list)
315 * aunque se recibe como un void*.
316 * d, es el diccionario con el que estamos trabajarando
317 * pila,es la pila donde apilaremos el atributo generado
318 * direction, es la direccion en que estamos recorriendo el corpus (LEFT_TO_RIGHT
319 * o RIGHT_TO_LEFT).
321 void swindow::winPushAmbiguityFeature(void* ptr, dictionary* d, std::stack<std::string>& pila, int direction)
323 std::ostringstream value;
324 nodo_feature_list *p = (nodo_feature_list *)ptr;
325 nodo *pn;
326 int *num;
327 infoDict *pInfoDict;
330 num = *p->l.getIndex();
331 value << p->mark << *num << ":";
332 pn = get(*num, direction);
333 if (pn!=NULL)
335 dataDict* w = d->getElement(pn->wrd);
336 if ((long)w!=HASH_FAIL)
338 simpleList<infoDict*>& list = d->getElementMaybe(w);
339 int numMaybe = d->getElementNumMaybe(w);
340 bool ret = true;
341 while (ret)
343 pInfoDict = *list.getIndex();
344 numMaybe--;
345 if (numMaybe>0) value << pInfoDict->pos << "~";
346 else value << pInfoDict->pos;
347 ret=list.next();
349 list.setFirst();
351 else value << "UNKNOWN"; //is unknown word
353 else value << EMPTY_POS;
355 pila.push(value.str());
360 * void winPushMFTFeature(void *ptr, dictionary *d, std::stack *pila, int direction)
361 * Genera el atributo con la "Most Frequent Tag", la etiqueta mas frecuente.
362 * Recibe como parametros:
363 * ptr, que es un puntero a un nodo de la lista de atributos (nodo_feature_list)
364 * aunque se recibe como un void*.
365 * d, es el diccionario con el que estamos trabajarando
366 * pila,es la pila donde apilaremos el atributo generado
367 * direction, es la direccion en que estamos recorriendo el corpus (LEFT_TO_RIGHT
368 * o RIGHT_TO_LEFT).
370 void swindow::winPushMFTFeature(void* ptr, dictionary* d, std::stack<std::string>& pila, int direction)
372 std::string value;
373 std::string mft;
374 nodo_feature_list *p = (nodo_feature_list *)ptr;
375 nodo *pn;
376 int *num,max=0;
377 infoDict *pInfoDict;
379 num = *p->l.getIndex();
380 value = p->mark;
381 value += *num + ":";
382 pn = get(*num, direction);
383 if (pn!=NULL)
385 dataDict* w = d->getElement(pn->wrd);
386 if ((long)w!=HASH_FAIL)
388 simpleList<infoDict*>& list = d->getElementMaybe(w);
389 int numMaybe = d->getElementNumMaybe(w);
390 bool ret = true;
391 while (ret)
393 pInfoDict = *list.getIndex();
394 numMaybe--;
395 if (pInfoDict->num>max) mft = pInfoDict->pos;
396 ret=list.next();
398 list.setFirst();
399 value += mft;
401 else value += "UNKNOWN"; //is unknown word
403 else value += EMPTY_POS;
405 pila.push(value);
410 * void winPushMaybeFeature(void *ptr, dictionary *d, std::stack *pila, int direction)
411 * Genera tantos atributos "maybe" como posibles POS pueda tener la palabra, y los
412 * apila en <pila>.
413 * Recibe como parametros:
414 * ptr, que es un puntero a un nodo de la lista de atributos (nodo_feature_list)
415 * aunque se recibe como un void*.
416 * d, es el diccionario con el que estamos trabajarando
417 * pila,es la pila donde apilaremos el atributo generado
418 * direction, es la direccion en que estamos recorriendo el corpus (LEFT_TO_RIGHT
419 * o RIGHT_TO_LEFT).
421 void swindow::winPushMaybeFeature(void* ptr, dictionary* d, std::stack<std::string>& pila, int direction)
423 std::string value;
424 std::ostringstream txt;
425 nodo_feature_list *p = (nodo_feature_list *)ptr;
426 nodo *pn;
427 int *num;
428 infoDict *pInfoDict;
430 num = *p->l.getIndex();
431 txt << p->mark << *num << "~";
432 pn = get(*num, direction);
433 if (pn!=NULL)
435 dataDict* w = d->getElement(pn->wrd);
437 if ((long)w!=HASH_FAIL)
439 simpleList<infoDict*>& list = d->getElementMaybe(w);
440 bool ret = true;
441 while (ret)
443 std::string feature;
444 pInfoDict = *list.getIndex();
445 feature += txt.str() + pInfoDict->pos + ":1";
446 pila.push(feature);
447 ret=list.next();
449 list.setFirst();
451 else
453 std::string feature;
454 feature += txt.str() + "UNKNOWN:1";
455 pila.push(feature);
458 else
460 std::string feature;
461 feature += txt.str() + EMPTY_POS + ":1";
462 pila.push(feature);
468 * void winPushPosFeature(void *ptr, dictionary *d, std::stack *pila, int direction)
469 * Genera un atributo con la POS de algunos elementos de la ventana.
470 * Recibe como parametros:
471 * ptr, que es un puntero a un nodo de la lista de atributos (nodo_feature_list)
472 * aunque se recibe como un void*.
473 * d, es el diccionario con el que estamos trabajarando
474 * pila,es la pila donde apilaremos el atributo generado
475 * direction, es la direccion en que estamos recorriendo el corpus (LEFT_TO_RIGHT
476 * o RIGHT_TO_LEFT).
478 void swindow::winPushPosFeature(void* ptr, dictionary* d, std::stack<std::string>& pila, int direction)
480 std::string value;
481 std::string txt;
482 nodo_feature_list *p = (nodo_feature_list *)ptr;
483 nodo *pn;
484 infoDict *pInfoDict;
485 std::string feature;
487 int *num;
489 bool end = false;
490 while (!end)
492 num = *p->l.getIndex();
494 pn = get(*num, direction);
496 if (pn==NULL) txt = EMPTY_POS;
497 else if ( (pn->pos == EMPTY) || (*num==0) ) //AKI3
500 dataDict* w = d->getElement(pn->wrd);
502 if ((long)w!=HASH_FAIL)
504 simpleList<infoDict*>& list = d->getElementMaybe(w);
505 int numMaybe = d->getElementNumMaybe(w);
507 txt = EMPTY;
508 bool ret = true;
509 while ( ret )
511 pInfoDict = *list.getIndex();
512 numMaybe--;
513 if (numMaybe>0) txt += pInfoDict->pos + "_";
514 else txt += pInfoDict->pos;
515 ret=list.next();
517 list.setFirst();
519 else txt = "UNKNOWN"; //is unknown word
521 else txt = pn->pos; //AKI3
523 if (value.empty()) value = txt; //AKI3
524 else value += "~" + txt;
526 end = !p->l.next();
528 p->l.setFirst();
530 feature = ":" + value;
531 //std::cerr << feature << std::endl;
532 pila.push(feature);
536 * void winPushPOSFeature(void *ptr, dictionary *d, std::stack *pila, int direction)
537 * Genera un atributo con la palabra de algunos elementos de la ventana.
538 * Recibe como parametros:
539 * ptr, que es un puntero a un nodo de la lista de atributos (nodo_feature_list)
540 * aunque se recibe como un void*.
541 * d, es el diccionario con el que estamos trabajarando
542 * pila,es la pila donde apilaremos el atributo generado
543 * direction, es la direccion en que estamos recorriendo el corpus (LEFT_TO_RIGHT
544 * o RIGHT_TO_LEFT).
546 void swindow::winPushWordFeature(void* ptr, dictionary* /*d*/, std::stack<std::string>& pila, int direction)
548 std::string value;
549 std::ostringstream name;
550 std::string txt;
551 nodo_feature_list *p = (nodo_feature_list *)ptr;
552 nodo *pn=NULL;
554 int *num = *p->l.getIndex();
555 pn = get(*num, direction);
557 if (pn==NULL) value = EMPTY_WORD;
558 else value = pn->wrd;
559 name << std::string(p->mark) << *num;
561 while (p->l.next())
563 num = *p->l.getIndex();
564 name << "," << *num;
566 pn = get(*num, direction);
568 if (pn==NULL) txt = EMPTY_WORD;
569 else txt = pn->wrd;
570 value += "~" + txt;
572 p->l.setFirst();
573 name << ":" << value;
575 pila.push(name.str());
579 /****************************************************************************/
582 int swindow::sentenceLength()
584 //Retorna el número de palabras que tiene la frase cargada en este objeto
585 return this->numObj;
589 * void deleteList()
590 * Elimina todas las palabras existentes en la ventana
591 * Retorna el número de elementos que poseia la ventana
593 void swindow::deleteList()
595 // std::cerr << "swindow::deleteList " << numObj << " elements" << std::endl;
596 if (first==0) return;
598 int i = 0;
599 while (first->next!=0)
601 i++;
602 // std::cerr << "swindow::deleteList delete " << i << "th element: " << &(first->strScores) << " " << first->strScores << std::endl;
603 assert(first->next->previous == first);
604 first = first->next;
605 delete first->previous;
607 i++;
608 if ( last != 0 )
610 // std::cerr << "swindow::deleteList delete " << i << "th element" << std::endl;
611 delete last;
614 first=0;
615 last=0;
616 index=0;
617 numObj=0;
621 void swindow::init(dictionary* dic)
623 if(m_output != NULL)
624 iniGeneric(dic);
627 int swindow::iniGeneric(dictionary* dic)
629 posBegin = posIndex;
630 posEnd = posIndex;
632 int ret = iniList(dic);
633 endWin = last;
634 if (ret>=0) readSentence(dic);
636 if (ret==-1) return -1;
637 else if (ret==0) posEnd = posIndex+last->ord;
638 else posEnd=posIndex+ret;
640 beginWin = first;
642 return ret;
645 int swindow::iniList(dictionary* dic)
647 int j=0,ret=1;
649 for(j=posIndex; ((j<lengthWin) && (ret>=0)); j++) ret = readInput(dic);
651 //ret >1 correct
652 // 0 if end of sentence
653 // -1 if there aren't words
654 // -2 if end of file
655 if (ret>=0) ret=j-posIndex-1;
657 return ret;
660 void swindow::setWindow(const std::vector<nodo*>& user_window) {
661 this->user_window = user_window;
665 /****************************************************************************/
667 int swindow::readSentence(dictionary* dic)
669 int ret=1;
670 while (ret>=0) ret = readInput(dic);
671 return ret;
675 int swindow::readInput(dictionary* dic) {
676 std::string word, comment;
677 std::set<std::string> tagset;
679 int ret;
680 while((ret = m_reader.parseWord(word, tagset, comment)) == 1);
681 nodo* node = m_reader.buildNode(word, comment);
683 winAdd(node);
684 if(!tagset.empty()) dic->addBackupEntry(word, tagset);
686 return ret;
690 /****************************************************************************/
692 void swindow::winAdd(nodo *aux)
694 // add the node in the software window
695 if(numObj == 0)
697 first = aux;
698 last = aux;
699 index = aux;
701 else
703 aux->previous = last;
704 last->next = aux;
705 last = aux;
708 numObj++;
712 /****************************************************************************/
714 swindow::~swindow()
716 // deleteList();
719 swindow::swindow(istream& in, std::ostream* output, dictionary* dic) : m_output(output), m_reader(in),
720 first(0), last(0), numObj(0),index(0),beginWin(0),endWin(0),posBegin(0),posEnd(0)
722 lengthWin = 7;
723 posIndex = 3;
725 init(dic);
728 swindow::swindow(int lengthWin, dictionary *dic): m_output(NULL), m_reader(),
729 first(0), last(0), numObj(0), beginWin(0), endWin(0), posBegin(0), posEnd(lengthWin)
731 this->lengthWin = lengthWin;
732 posIndex = 2;
733 init(dic);
736 swindow::swindow(istream& in, int number, int position, std::ostream* output, dictionary* dic) : m_output(output), m_reader(in),
737 first(0), last(0), numObj(0),index(0),beginWin(0),endWin(0),posBegin(0),posEnd(0)
740 if ((number<3) || (number<=position))
741 { fprintf(stderr,"\nWindow Length can not be first or last element.\nLength should be greater than \"Interest Point Position\" or 3.\n");
742 exit(0);
745 lengthWin = number;
746 posIndex = position-1;
748 init(dic);
751 swindow::swindow(istream& in, int number, std::ostream* output, dictionary* dic) : m_output(output), m_reader(in),
752 first(0), last(0), numObj(0),index(0),beginWin(0),endWin(0),posBegin(0),posEnd(0)
755 lengthWin = number;
756 posIndex = number/2;
758 init(dic);
761 /****************************************************************************/
763 /* Move Interest Point to next element */
764 bool swindow::next()
766 bool ret = false;
767 if (endWin->next!=0) ret=true;
769 if ((index==0) || (index->next==0)) return false;
770 if ((posIndex>=posEnd) && (!ret)) return false;
772 if ((posIndex<posEnd) && (!ret)) posEnd--;
773 if ((posEnd==lengthWin-1) && (ret)) endWin = endWin->next;
775 if (posBegin==0) beginWin = beginWin->next;
776 else if ((posIndex>=posBegin) && (posBegin>0)) posBegin--;
778 index = index->next;
779 return true;
782 /****************************************************************************/
784 /* Move Interest Point to previous element */
785 bool swindow::previous()
787 if ((index==NULL) || (index->previous==NULL)) return false;
789 if ((posBegin==0) && (beginWin->previous!=NULL)) beginWin = beginWin->previous;
790 else if (posIndex>posBegin) posBegin++;
792 if (posEnd<lengthWin-1) posEnd++;
793 else endWin = endWin->previous;
795 index = index->previous;
796 return true;
799 /****************************************************************************/
801 /* Get Interest Point */
802 nodo *swindow::getIndex()
804 return index;
807 /****************************************************************************/
809 nodo *swindow::get(int position, int direction)
811 if (direction==2) position = -position;
812 if ( ((position<0) && (posIndex+position+1<posBegin))
813 || ((position>0) && (posIndex+position>posEnd)) )
814 return NULL;
816 if(!user_window.empty())
817 return get_user(position);
818 else
819 return get_intern(position);
822 // position must be valid, ie. "in the window"
823 nodo *swindow::get_user(int position)
825 return user_window[position+2];
828 nodo *swindow::get_intern(int position)
830 nodo *aux=index;
831 int i=0;
833 if (position == 0) return index;
835 while (i!=position)
837 if (position>0)
838 { i++;
839 if (aux->next != NULL) aux = aux->next;
840 else return NULL;
842 else
843 { i--;
844 if (aux->previous != NULL) aux = aux->previous;
845 else return NULL;
849 return aux;
853 /****************************************************************************/
855 int swindow::show(int showScoresFlag, int showComments)
857 std::string wrd;
859 if (first==NULL) return 0;
861 nodo *actual = first;
863 while(actual != NULL) {
864 *m_output << actual->realWrd << " " << actual->pos;
866 if ( showScoresFlag == TRUE && !actual->strScores.empty() ) {
867 *m_output << " " << actual->strScores;
870 if ( showComments == TRUE && !actual->comment.empty() ) {
871 *m_output << " " << actual->comment;
874 *m_output << std::endl;
876 actual = actual->next;
879 return 0;
882 /****************************************************************************/
884 void swindow::putLengthWin(int l)
886 lengthWin = l;
889 /****************************************************************************/
891 void swindow::putIndex(int i)
893 posIndex = i;
896 /****************************************************************************/
899 * Modifica el valor de los pesos para una palabra
900 * Si:
901 * action = 0 --> Pone el peso máximo (put max score)
902 * action = 1 --> Inicializa los pesos (reset values)
903 * action = 2 --> Restaura el valor de la vuelta anterior(last lap value)
905 int swindow::winMaterializePOSValues(int action)
907 if (first==NULL) return 0;
909 int inicio=1;
910 weight_node_t *w,max;
911 nodo *actual=first;
913 while (actual!=NULL)
916 switch (action)
918 case 0: //PUT MAX
919 inicio = 1;
920 while(!actual->stackScores.empty())
922 w = actual->stackScores.top();
923 actual->stackScores.pop();
925 if (inicio || w->data>max.data)
927 max.data=w->data;
928 max.pos = w->pos;
929 inicio = 0;
931 delete w;
933 actual->weight=max.data;
934 actual->pos = max.pos;
935 //Added for 2 laps tagging
936 actual->weightOld=max.data;
937 actual->posOld = max.pos;
938 break;
939 case 1: //RESET VALUES
940 actual->pos = "";
941 actual->weight=0;
942 break;
943 case 2: //PUT OLD
944 actual->pos = actual->posOld;
945 actual->weight=actual->weightOld;
946 break;
948 actual=actual->next;
950 return 0;
953 /****************************************************************************/
956 * int winExistUnkWord(int direction, dictionary *d)
957 * Esta funcion comprueba si hay parabras desconocidas.
958 * En caso de que el parametro direction sea:
959 * LEFT_TO_RIGHT - mira si hay desconocidas a la
960 * derecha del punto de interes de la ventana.
961 * RIGHT_TO_LEFT - mira si hay desconocidas a la izquierda
962 * del punto de interes de la ventana.
963 * Esta funcion devuelve:
964 * un entero >=0, si no hay desconocidas
965 * -1, si hay desconocidas
967 int swindow::winExistUnkWord(int direction, dictionary *d)
969 nodo *aux=index;
970 int ret=0,i=posIndex;
972 if (index==NULL) return 1;
973 aux = index;
975 while (ret>=0)
977 switch (direction)
979 case LEFT_TO_RIGHT:
980 if (aux->next==NULL || aux==endWin) ret=-1;
981 else aux = aux->next;
982 if ((long)d->getElement(aux->wrd)==HASH_FAIL) return -1;
983 i++;
984 break;
985 case RIGHT_TO_LEFT:
986 if (aux->previous==NULL || aux==beginWin) ret=-1;
987 else aux = aux->previous;
988 if ((long)d->getElement(aux->wrd)==HASH_FAIL) return -1;
989 i--;
990 break;
993 return 0;