Pratt.cpp
Go to the documentation of this file.
1 #include "Pratt.hpp"
2 
3 #include <functional>
4 
5 namespace iv
6 {
7 
8 Pratt::Pratt( Instance * inst ) :
9  cm( inst, this, "Pratt" ),
10  inst( inst ),
11  lex( nullptr ),
12  _root( nullptr ),
13  value_name( -1 )
14 {
15 }
16 
18 {
19  this->clear();
20 }
21 
23 {
24  return this->inst;
25 }
26 
28 {
29  this->operators.erase( "" );
30  for( std::string const & op : this->operators )
31  lex->DefineOperator( op.c_str() );
32 }
33 
35 {
36  this->clear();
37  this->lex = lex;
38  this->_root = this->expr( 0, "" );
39  if( this->lex->Failed() )
40  this->clear();
41  this->lex = nullptr;
42 }
43 
45 {
46  return this->_root;
47 }
48 
50 {
51  std::function< void( Expression const * ) > del = [ &del ]( Expression const * expr )
52  {
53  if( !expr )
54  return;
55 
56  auto * unary = expr->ToUnary();
57  if( unary )
58  del( unary->child );
59 
60  auto * binary = expr->ToBinary();
61  if( binary )
62  {
63  del( binary->left );
64  del( binary->right );
65  }
66 
67  delete expr;
68  };
69 
70  del( this->_root );
71 }
72 
73 void Pratt::def_value( int name )
74 {
75  this->value_name = name;
76 }
77 
78 void Pratt::def_unary( int name, int precedence, const char * op_left, bool child_mandatory, const char * op_right, bool phantom )
79 {
80  Def * def = new Def;
81  def->name = name;
82  def->precedence = precedence;
83  def->unary = true;
84  def->phantom = phantom;
85  def->op_left = op_left;
86  def->child_mandatory = child_mandatory;
87  def->op_middle = "";
88  def->right_child_mandatory = false;
89  def->op_right = op_right;
90 
91  // checks and inserts
92  if( def->op_left.size() )
93  {
94  if( this->defs_prefix.count( def->op_left ) )
95  {
96  this->cm.warning( SRC_INFO, "Can not define unary operation. An operation with the same prefix operand '", def->op_left, "' already exists." );
97  delete def;
98  return;
99  }
100 
101  this->defs_prefix[ def->op_left ] = def;
102  }
103  else if( def->op_right.size() )
104  {
105  if( this->defs_nonprefix.count( def->op_right ) )
106  {
107  this->cm.warning( SRC_INFO, "Can not define unary operation. An operation with the same non-prefix operand '", def->op_right, "' already exists." );
108  delete def;
109  return;
110  }
111 
112  if( !child_mandatory )
113  {
114  if( this->defs_prefix.count( def->op_right ) )
115  {
116  this->cm.warning( SRC_INFO, "Can not define unary operation. An operation with the same prefix operand '", def->op_right, "' already exists. Consider making child expression mandatory for this operation (it will not colide with prefix operations)." );
117  delete def;
118  return;
119  }
120 
121  this->defs_prefix[ def->op_right ] = def;
122  }
123 
124  this->defs_nonprefix[ def->op_right ] = def;
125  }
126  else
127  {
128  this->cm.warning( SRC_INFO, "Can not define unary operation. Neither prefix nor postfix operator is specified." );
129  delete def;
130  return;
131  }
132 
133  this->defs.insert( def );
134 
135  this->operators.insert( op_left );
136  this->operators.insert( op_right );
137 }
138 
139 void Pratt::def_binary( int name, int precedence, const char * op_left, bool left_child_mandatory, const char * op_middle, bool right_child_mandatory, const char * op_right )
140 {
141  Def * def = new Def;
142  def->name = name;
143  def->precedence = precedence;
144  def->unary = false;
145  def->phantom = false;
146  def->op_left = op_left;
147  def->child_mandatory = left_child_mandatory;
148  def->op_middle = op_middle;
149  def->right_child_mandatory = right_child_mandatory;
150  def->op_right = op_right;
151 
152  if( def->op_middle.empty() )
153  {
154  this->cm.warning( SRC_INFO, "Can not define binary operation. Infix operator is not specified." );
155  delete def;
156  return;
157  }
158 
159  if( def->op_left.size() )
160  {
161  if( this->defs_prefix.count( def->op_left ) )
162  {
163  this->cm.warning( SRC_INFO, "Can not define binary operation. An operation with the same prefix operand '", def->op_left, "' already exists." );
164  delete def;
165  return;
166  }
167 
168  this->defs_prefix[ def->op_left ] = def;
169  }
170  else
171  {
172  if( this->defs_nonprefix.count( def->op_middle ) )
173  {
174  this->cm.warning( SRC_INFO, "Can not define binary operation. An operation with the same non-prefix operand '", def->op_middle, "' already exists." );
175  delete def;
176  return;
177  }
178 
179  if( !def->child_mandatory )
180  {
181  if( this->defs_prefix.count( def->op_middle ) )
182  {
183  this->cm.warning( SRC_INFO, "Can not define binary operation. An operation with the same prefix operand '", def->op_middle, "' already exists. Consider making left child expression mandatory for this operation (it will not colide with prefix operations)." );
184  delete def;
185  return;
186  }
187 
188  this->defs_prefix[ def->op_middle ] = def;
189  }
190 
191  this->defs_nonprefix[ def->op_middle ] = def;
192  }
193 
194  this->defs.insert( def );
195 
196  this->operators.insert( op_left );
197  this->operators.insert( op_middle );
198  this->operators.insert( op_right );
199 }
200 
201 Pratt::Expression * Pratt::expr( int precedence, const char * terminator )
202 {
203  if( this->lex->Failed() )
204  return nullptr;
205 
206  if( this->lex->IsNext( Lex::Operator ) )
207  {
208  std::string next = this->lex->GetNextTokenValue();
209  if( next == terminator )
210  {
211  return nullptr;
212  }
213  else if( this->defs_prefix.count( next ) )
214  { // prefix operator
215  int line = this->lex->GetLine();
216  int column = this->lex->GetColumn();
217 
218  this->lex->Accept( Lex::Operator );
219  Def * def = this->defs_prefix.at( next );
220  if( def->unary )
221  {
222  if( def->op_left.size() )
223  { // unary prefix operator
224  Expression * child;
225  if( def->op_right.size() )
226  child = this->expr( -1, def->op_right.c_str() );
227  else
228  child = this->expr( precedence, terminator );
229 
230  if( def->child_mandatory && !child )
231  {
232  this->lex->LogicFail( SS()<<"Pratt error: Unary operator '"<<next<<"' is missing an operand."<<SS::c_str() );
233  return nullptr;
234  }
235 
236  if( def->op_right.size() )
237  this->lex->AcceptOperator( def->op_right.c_str() );
238 
239  if( def->phantom )
240  {
241  return child;
242  }
243  else
244  {
245  Unary * unary = new Unary;
246  unary->line = line;
247  unary->column = column;
248  unary->name = def->name;
249  unary->child = child;
250  return unary;
251  }
252  }
253  else
254  { // unary postfix operator without child
255  if( def->child_mandatory )
256  {
257  this->lex->LogicFail( SS()<<"Pratt error: Code error: Unary operator '"<<next<<"' is in defs_prefix but it has empty op_left and mandatory child."<<SS::c_str() );
258  return nullptr;
259  }
260 
261  if( def->phantom )
262  {
263  return nullptr;
264  }
265  else
266  {
267  Unary * unary = new Unary;
268  unary->line = line;
269  unary->column = column;
270  unary->name = def->name;
271  unary->child = nullptr;
272  return unary;
273  }
274  }
275  }
276  else
277  {
278  if( def->op_left.size() )
279  { // binary prefix operator
280  // read child_left (op_middle is mandatory)
281  Expression * child_left = this->expr( -1, def->op_middle.c_str() );
282 
283  if( def->child_mandatory && !child_left )
284  {
285  this->lex->LogicFail( SS()<<"Pratt error: Binary operator '"<<next<<"' is missing left operand."<<SS::c_str() );
286  return nullptr;
287  }
288 
289  // read op_middle
290  this->lex->AcceptOperator( def->op_middle.c_str() );
291 
292  // read child_right
293  Expression * child_right;
294  if( def->op_right.size() )
295  child_right = this->expr( -1, def->op_right.c_str() );
296  else
297  child_right = this->expr( precedence, terminator );
298 
299  if( def->right_child_mandatory && !child_right )
300  {
301  this->lex->LogicFail( SS()<<"Pratt error: Binary operator '"<<next<<"' is missing right operand."<<SS::c_str() );
302  return nullptr;
303  }
304 
305  // accept right operator
306  if( def->op_right.size() )
307  this->lex->AcceptOperator( def->op_right.c_str() );
308 
309  // return Expression
310  Binary * binary = new Binary;
311  binary->line = line;
312  binary->column = column;
313  binary->name = def->name;
314  binary->left = child_left;
315  binary->right = child_right;
316  return binary;
317  }
318  else
319  { // binary postfix operator without left child
320  if( def->child_mandatory )
321  {
322  this->lex->LogicFail( SS()<<"Pratt error: Code error: Binary operator '"<<next<<"' is in defs_prefix but it has empty op_left and mandatory child."<<SS::c_str() );
323  return nullptr;
324  }
325 
326  // read child_right
327  Expression * child_right;
328  if( def->op_right.size() )
329  child_right = this->expr( -1, def->op_right.c_str() );
330  else
331  child_right = this->expr( precedence, terminator );
332 
333  if( def->right_child_mandatory && !child_right )
334  {
335  this->lex->LogicFail( SS()<<"Pratt error: Binary operator '"<<next<<"' is missing right operand."<<SS::c_str() );
336  return nullptr;
337  }
338 
339  // accept right operator
340  if( def->op_right.size() )
341  this->lex->AcceptOperator( def->op_right.c_str() );
342 
343  // return Expression
344  Binary * binary = new Binary;
345  binary->line = line;
346  binary->column = column;
347  binary->name = def->name;
348  binary->left = nullptr;
349  binary->right = child_right;
350  return binary;
351  }
352  }
353  }
354  else
355  { // terminate
356  return nullptr;
357  }
358  }
359  else if( this->lex->IsNext( Lex::Eof ) )
360  { // terminate
361  return nullptr;
362  }
363  else
364  { // value
365  // read value
366  Value * value = new Value;
367  value->line = this->lex->GetLine();
368  value->column = this->lex->GetColumn();
369  value->name = this->value_name;
370  value->token = this->lex->GetNextToken();
371  value->token_str = this->lex->GetNextTokenValue();
372 
373  this->lex->Accept( this->lex->GetNextToken() );
374 
375  Expression * top = value;
376 
377  // check next operator (non-prefix)
378  while( !this->lex->Failed() && this->lex->IsNext( Lex::Operator ) )
379  {
380  std::string next = this->lex->GetNextTokenValue();
381 
382  if( next == terminator )
383  break;
384 
385  if( !this->defs_nonprefix.count( next ) )
386  break;
387 
388  Def * def = this->defs_nonprefix.at( next );
389  if( def->precedence <= precedence )
390  break;
391 
392  // accept operator
393  int line = this->lex->GetLine();
394  int column = this->lex->GetColumn();
395  this->lex->Accept( Lex::Operator );
396 
397  if( def->unary )
398  { // unary non-prefix operator
399  if( def->phantom )
400  {
401  ; // keep 'top' as it is
402  }
403  else
404  {
405  Unary * unary = new Unary;
406  unary->line = line;
407  unary->column = column;
408  unary->name = def->name;
409  unary->child = top;
410  top = unary;
411  }
412  }
413  else
414  { // binary non-prefix operator
415  // read right expression
416  Expression * child_right;
417  if( def->op_right.size() )
418  child_right = this->expr( -1, def->op_right.c_str() );
419  else
420  child_right = this->expr( precedence, terminator );
421 
422  if( def->right_child_mandatory && !child_right )
423  {
424  this->lex->LogicFail( SS()<<"Pratt error: Binary operator '"<<next<<"' is missing right operand."<<SS::c_str() );
425  continue;
426  }
427 
428  if( def->op_right.size() )
429  this->lex->AcceptOperator( def->op_right.c_str() );
430 
431  // create expression
432  Binary * binary = new Binary;
433  binary->line = line;
434  binary->column = column;
435  binary->name = def->name;
436  binary->left = top;
437  binary->right = child_right;
438  top = binary;
439  }
440  }
441 
442  return top;
443  }
444 }
445 
446 }