Reranker Framework (ReFr)
Reranking framework for structure prediction and discriminative language modeling
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
environment-impl.C
Go to the documentation of this file.
1 // Copyright 2012, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // -----------------------------------------------------------------------------
30 //
31 //
35 
36 #include "environment-impl.H"
37 #include "factory.H"
38 
39 namespace reranker {
40 
42  debug_ = debug;
43 
44  // Set up VarMap instances for each of the primitive types and their vectors.
45  var_map_["bool"] = new VarMap<bool>("bool", this);
46  var_map_["int"] = new VarMap<int>("int", this);
47  var_map_["double"] = new VarMap<double>("double", this);
48  var_map_["string"] = new VarMap<string>("string", this);
49  var_map_["bool[]"] = new VarMap<vector<bool> >("bool[]", this);
50  var_map_["int[]"] = new VarMap<vector<int> >("int[]", this);
51  var_map_["double[]"] = new VarMap<vector<double> >("double[]", this);
52  var_map_["string[]"] = new VarMap<vector<string> >("string[]", this);
53 
54  // Set up VarMap instances for each of the Factory-constructible types
55  // and their vectors.
57  factory_it != FactoryContainer::end(); ++factory_it) {
58  unordered_set<string> registered;
59  (*factory_it)->CollectRegistered(registered);
60  string base_name = (*factory_it)->BaseName();
61 
62  // Create type-specific VarMap from the Factory and add to var_map_.
63  VarMapBase *obj_var_map = (*factory_it)->CreateVarMap(this);
64  var_map_[obj_var_map->Name()] = obj_var_map;
65 
66  if (debug_ >= 2) {
67  cerr << "Environment: created VarMap for " << obj_var_map->Name()
68  << endl;
69  }
70 
71  // Create VarMap for vectors of shared_object of T and add to var_map_.
72  VarMapBase *obj_vector_var_map = (*factory_it)->CreateVectorVarMap(this);
73  var_map_[obj_vector_var_map->Name()] = obj_vector_var_map;
74 
75  if (debug_ >= 2) {
76  cerr << "Environment: created VarMap for " << obj_vector_var_map->Name()
77  << endl;
78  }
79 
80  for (unordered_set<string>::const_iterator it = registered.begin();
81  it != registered.end(); ++it) {
82  const string &concrete_type_name = *it;
83 
84  unordered_map<string, string>::const_iterator concrete_to_factory_it =
85  concrete_to_factory_type_.find(concrete_type_name);
86  if (concrete_to_factory_it != concrete_to_factory_type_.end()) {
87  // Warn user that there are two entries for the same concrete type
88  // (presumably due to different abstract factory types).
89  cerr << "Environment: WARNING: trying to override existing "
90  << "concrete-to-factory type mapping ["
91  << concrete_type_name << " --> " << concrete_to_factory_it->second
92  << "] with [" << concrete_type_name << " --> " << base_name
93  << endl;
94  }
95  concrete_to_factory_type_[concrete_type_name] = base_name;
96 
97  if (debug_ >= 2) {
98  cerr << "Environment: associating concrete typename "
99  << concrete_type_name
100  << " with factory for " << base_name << endl;
101  }
102  }
103  }
104 }
105 
106 void
107 EnvironmentImpl::ReadAndSet(const string &varname, StreamTokenizer &st,
108  const string type) {
109  bool is_vector =
111  st.Peek() == "{";
112 
113  if (is_vector) {
114  // Consume open brace.
115  st.Next();
116  } else if (st.PeekTokenType() == StreamTokenizer::RESERVED_CHAR ||
118  st.Peek() != "true" && st.Peek() != "false" &&
119  st.Peek() != "nullptr" && st.Peek() != "NULL")) {
120  ostringstream err_ss;
121  err_ss << "Environment: error: expected literal or Factory-constructible "
122  << "type but found token \"" << st.Peek() << "\" of type "
124  throw std::runtime_error(err_ss.str());
125  }
126 
127  string next_tok = st.Peek();
128  bool is_object_type = false;
129 
130  string inferred_type = InferType(varname, st, is_vector, &is_object_type);
131 
132  if (debug_ >= 1) {
133  cerr << "Environment::ReadAndSet: next_tok=\"" << next_tok
134  << "\"; explicit type=\"" << type << "\"; "
135  << "inferred_type=\"" << inferred_type << "\"" << endl;
136  }
137 
138  if (type == "" && inferred_type == "") {
139  ostringstream err_ss;
140  err_ss << "Environment: error: no explicit type specifier and could not "
141  << "infer type for variable " << varname;
142  throw std::runtime_error(err_ss.str());
143  }
144  if (type != "" && inferred_type != "" && type != inferred_type) {
145  ostringstream err_ss;
146  err_ss << "Environment: error: explicit type " << type
147  << " and inferred type " << inferred_type
148  << " disagree for variable " << varname;
149  throw std::runtime_error(err_ss.str());
150  }
151 
152  // If no explicit type specifier, then the inferred_type is the type.
153  string varmap_type = type == "" ? inferred_type : type;
154 
155  // Check that varmap_type is a key in var_map_.
156  var_map_[varmap_type]->ReadAndSet(varname, st);
157  types_[varname] = varmap_type;
158 }
159 
160 string
161 EnvironmentImpl::InferType(const string &varname,
162  const StreamTokenizer &st, bool is_vector,
163  bool *is_object_type) {
164  *is_object_type = false;
165  string next_tok = st.Peek();
166  switch (st.PeekTokenType()) {
168  if (next_tok == "true" || next_tok == "false") {
169  return is_vector ? "bool[]" : "bool";
170  } else {
171  return "";
172  }
173  break;
175  return is_vector ? "string[]" : "string";
176  break;
178  {
179  // If a token is a NUMBER, it is a double iff it contains a
180  // decimal point.
181  size_t dot_pos = next_tok.find('.');
182  if (dot_pos != string::npos) {
183  return is_vector ? "double[]" : "double";
184  } else {
185  return is_vector ? "int[]" : "int";
186  }
187  }
188  break;
190  {
191  string type = "";
192 
193  // Find out if next_tok is a concrete typename or a variable.
194  unordered_map<string, string>::const_iterator factory_type_it =
195  concrete_to_factory_type_.find(next_tok);
196  unordered_map<string, string>::const_iterator var_type_it =
197  types_.find(next_tok);
198  if (factory_type_it != concrete_to_factory_type_.end()) {
199  // Set type to be abstract factory type.
200  if (debug_ >= 1) {
201  cerr << "Environment::InferType: concrete type is " << next_tok
202  << "; mapping to abstract Factory type "
203  << factory_type_it->second << endl;
204  }
205  type = factory_type_it->second;
206  *is_object_type = true;
207  type = is_vector ? type + "[]" : type;
208 
209  if (debug_ >= 1) {
210  cerr << "Environment::InferType: type "
211  << (is_vector ? "is" : "isn't")
212  << " a vector, so final inferred type is " << type << endl;
213  }
214  } else if (var_type_it != types_.end()) {
215  // Could be a variable, in which case we need not only to return
216  // the variable's type, but also set is_object_type and is_vector
217  // based on the variable's type string.
218  string append = is_vector ? "[]" : "";
219  type = var_type_it->second + append;
220  if (debug_ >= 1) {
221  cerr << "Environment::InferType: found variable "
222  << var_type_it->first << " of type " << var_type_it->second
223  << "; type is " << type << endl;
224  }
225  } else {
226  ostringstream err_ss;
227  err_ss << "Environment: error: token " << next_tok
228  << " is neither a variable nor a concrete object typename";
229  throw std::runtime_error(err_ss.str());
230  }
231  return type;
232  }
233  break;
234  default:
235  return "";
236  }
237  return "";
238 }
239 
240 void
243 }
244 
245 } // namespace reranker
A container to hold the mapping between named variables of a specific type and their values...
Definition: environment.H:256
static iterator begin()
Definition: factory.H:325
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
virtual void ReadAndSet(const string &varname, StreamTokenizer &st, const string type)
Sets the specified variable to the value obtained from the following tokens available from the specif...
A base class for a mapping from variables of a specific type to their values.
Definition: environment.H:65
virtual void PrintFactories(ostream &os) const
Prints out a human-readable string with the names of all abstract base types and their concrete imple...
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
static void Print(ostream &os)
Prints the base typenames for all factories along with a list of all concrete subtypes those factorie...
Definition: factory.H:343
string Next()
Returns the next token in the token stream.
EnvironmentImpl(int debug=0)
Constructs a new, empty environment.
Provides an environment for variables and their values, either primitive or Factory-constructible obj...
static iterator end()
Definition: factory.H:332
vector< FactoryBase * >::iterator iterator
Definition: factory.H:298
string Peek() const
Returns the next token that would be returned by the Next method.
virtual const string & Name() const
Returns the type name of the variables of this instance.
Definition: environment.H:85
Provides a generic dynamic object factory.
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.