00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "SentenceReader.h"
00025
00026
00027 #include <iostream>
00028 #include <fstream>
00029 #include <iomanip>
00030
00031
00032 #include "include/unordered_map.h"
00033 #include "text/Utf8Utils.h"
00034
00035
00036 #include "Corpus.h"
00037
00038 using namespace std;
00039 using namespace Tanl::Text;
00040
00041 namespace Tanl {
00042
00043
00044
00045
00046 SentenceReader::SentenceReader(istream* is, Corpus* corpus) :
00047 is(is),
00048 corpus(corpus)
00049 { }
00050
00051 void SentenceReader::reset()
00052 {
00053 line.clear();
00054 }
00055
00056
00057 static RegExp::Pattern reTab("([^ \t\n]+)");
00058
00059 bool SentenceReader::MoveNext()
00060 {
00061 sentence = new Sentence();
00062 vector<char const*>& names = corpus->index.names;
00063 vector<int> preds;
00064 int id = 1;
00065 RegExp::MatchGroups match(2);
00066
00067 while (getline(*is, line) && line.size()) {
00068 Attributes attributes(&corpus->index);
00069 string form;
00070 int head = 0;
00071 string deprel;
00072 int fields = corpus->tokenFields.size();
00073 TokenLinks links;
00074 unordered_map<string, int> linkMap;
00075 int argNo = 0;
00076 int i = 0;
00077 char const* cur = line.c_str();
00078 char const* end = cur + line.size();
00079 while (reTab.match(cur, end, match) > 0) {
00080 TokenField const& tf = corpus->tokenFields[i];
00081 char const* fieldStart = cur + match[1].first;
00082 int fieldLen = match[1].second - match[1].first;
00083 string field(fieldStart, fieldLen);
00084
00085 if (field == tf.default_)
00086 field = "";
00087
00088 if (tf.use != TokenField::ignore) {
00089 if (!tf.link.empty()) {
00090
00091 int head = field.empty() ? -1 : atoi(field.c_str());
00092 if (linkMap.find(tf.link) == linkMap.end()) {
00093
00094 linkMap[tf.link] = links.size();
00095 links.push_back(TokenLink(head));
00096 } else
00097
00098 links[linkMap[tf.link]].head = head;
00099 } else if (!tf.label.empty()) {
00100 if (field.empty())
00101 --argNo;
00102 else {
00103
00104 if (linkMap.find(tf.label) == linkMap.end()) {
00105
00106 linkMap[tf.label] = links.size();
00107
00108 links.push_back(TokenLink(--argNo, field.c_str()));
00109 } else
00110
00111 links[linkMap[tf.label]].label = field;
00112 }
00113 } else {
00114 attributes[i] = field;
00115 # ifdef CONLL08
00116 if (useGold && i == 7 && !attributes[3].empty())
00117 attributes[7] = attributes[3];
00118 # endif
00119 switch (tf.role) {
00120 case TokenField::form:
00121 form = field; break;
00122 case TokenField::predicate:
00123 if (!field.empty())
00124 preds.push_back(id);
00125 break;
00126 }
00127 }
00128 }
00129 i++;
00130 cur += match[0].second;
00131 if (i == fields || cur == end) {
00132
00133 break;
00134 }
00135 }
00136 Token* token = new Token(form, attributes, links);
00137 sentence->push_back(token);
00138 }
00139 if (sentence->empty()) {
00140 delete sentence;
00141 sentence = 0;
00142 return false;
00143 }
00144
00145 for (Sentence::const_iterator sit = sentence->begin();
00146 sit != sentence->end(); ++sit) {
00147 for (TokenLinks::iterator tit = (*sit)->links.begin();
00148 tit != (*sit)->links.end(); ++tit) {
00149 if (tit->head < 0)
00150 tit->head = preds[-tit->head - 1];
00151 }
00152 }
00153 return true;
00154 }
00155
00156 Sentence* SentenceReader::Current()
00157 {
00158 return sentence;
00159 }
00160
00161 }