SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Parser.h
Go to the documentation of this file.
1 //
2 // For more information, please see: http://software.sci.utah.edu
3 //
4 // The MIT License
5 //
6 // Copyright (c) 2009 Scientific Computing and Imaging Institute,
7 // University of Utah.
8 //
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 //
28 
29 #ifndef CORE_PARSER_PARSER_H
30 #define CORE_PARSER_PARSER_H 1
31 
32 #include <Core/Utils/StringUtil.h>
33 #include <Core/Thread/Mutex.h>
34 #include <map>
35 #include <list>
36 
37 // Include files needed for Windows
38 #include <Core/Parser/share.h>
39 
40 namespace SCIRun {
41 
42 // The parser builds a tree based on three different classes
43 // ParserNode : This class is a piece of an expression. The ParserNode
44 // class marks: functions, variables, constants, and string
45 // constants. This are currently the pieces that are supported
46 // ParserTree : This class is the toplevel class of an expression. It binds
47 // the output variable with the tree of nodes that describe
48 // how a variable is computed.
49 // ParserProgram: This class simply binds a series of expressions together.
50 // ParserVariable: A variable for the the parser program. This class contains
51 // the names of the variables that are defined at the start of the
52 // program and which need to be defined at the end of the program
53 // ParserFunctionCatalog: This class contains a list of functions that are
54 // available, and hence is used for validating the program
55 
56 class ParserNode;
57 class ParserTree;
58 class ParserProgram;
59 class ParserVariable;
60 class ParserFunction;
61 class ParserFunctionCatalog;
62 class ParserScriptFunction;
64 
65 // We use handles (Note these are not thread safe hence constrain them
66 // to one thread) for memory management
67 
68 typedef boost::shared_ptr<ParserNode> ParserNodeHandle;
69 typedef boost::shared_ptr<ParserTree> ParserTreeHandle;
70 typedef boost::shared_ptr<ParserProgram> ParserProgramHandle;
71 typedef boost::shared_ptr<ParserVariable> ParserVariableHandle;
72 typedef boost::shared_ptr<ParserFunctionCatalog> ParserFunctionCatalogHandle;
73 typedef boost::shared_ptr<ParserScriptFunction> ParserScriptFunctionHandle;
74 typedef boost::shared_ptr<ParserScriptVariable> ParserScriptVariableHandle;
75 
76 // Define the four classes of parser components
77 
78 enum {
83 };
84 
85 // This piece of the code defines the types the parser recognizes
86 // Define variable types that are used to validate and to predict
87 // output types.
88 
89 
90 // This part defines the attributes of the variables
91 
92 enum {
93  // A sequence denotes a vectorized variable, hence when this flag is set
94  // the function will apply the function to an array, instead of a single variable
96  // Simple variable this is the default
98  // Reserved for numerical constants
100  // Internal marker to mark which variables are actually used to compute the output
102  // Internal marker telling an output is optional
104 };
105 
107  public:
108  // In order to use handles, we need to add reference counting
109  int ref_cnt;
110 
111  public:
112  ParserVariable(std::string name, std::string type) :
113  ref_cnt(0),
114  name_(name),
115  type_(type),
116  flags_(SCRIPT_SINGLE_VAR_E)
117  {}
118 
119  ParserVariable(std::string name, std::string type, int flags) :
120  ref_cnt(0),
121  name_(name),
122  type_(type),
123  flags_(flags)
124  {
125  // Default is a single variable
126  // Currently one can choose between a sequence or a single
127  if (flags == 0) flags_ = SCRIPT_SINGLE_VAR_E;
128  }
129 
130 
131  // Retrieve the type of the variable
132  std::string get_type() { return (type_); }
133  //Set the type of the variable
134  void set_type(std::string type) { type_ = type; }
135 
136  // Retrieve the flags of the variable
137  int get_flags() { return (flags_); }
138 
139  // Get the name of the variable
140  std::string get_name() { return (name_); }
141 
142  private:
143  // The name of the variable
144  std::string name_;
145 
146  // The type of the variable
147  std::string type_;
148 
149  // Flags that guide the parser
150  int flags_;
151 };
152 
153 typedef boost::shared_ptr<class ParserFunction> ParserFunctionHandle;
154 
156 {
157  public:
158  ParserNode(int kind, const std::string& value) :
159  kind_(kind),
160  type_("U"),
161  value_(value)
162  {}
163 
164  ParserNode(int kind, const std::string& value, const std::string& type) :
165  kind_(kind),
166  type_(type),
167  value_(value)
168  {}
169 
170  // Retrieve the kind of the node (this is function, constant, string, etc)
171  int get_kind() { return (kind_); }
172 
173  // Retrieve the type of the node (this is the return type of the variable)
174  std::string get_type() { return (type_); }
175 
176  // Retrieve the value of the value
177  std::string get_value() { return (value_); }
178 
179  // Set the value of the node
180  void set_value(const std::string& value) { value_ = value; }
181 
182  // Get a pointer to one of the arguments of a function
183  ParserNodeHandle get_arg(size_t j) { return args_[j]; }
184 
185  // Set the argument to a sub tree
186  void set_arg(size_t j, ParserNodeHandle handle)
187  {
188  if (j >= args_.size()) args_.resize(j+1);
189  args_[j] = handle;
190  }
191 
192  // Set the argument to a sub tree (using pointers)
193  void set_arg(size_t j, ParserNode* ptr)
194  {
195  if (j >= args_.size()) args_.resize(j+1);
196  args_[j].reset(ptr);
197  }
198 
199  // Set a copy to the function pointer, this is used later by the interpreter
200  void set_function(ParserFunctionHandle func) { function_ = func; }
201  // Retrieve the function pointer
202  ParserFunctionHandle get_function() { return (function_); }
203 
204  // Set the type of the node (this is used by the validator)
205  void set_type(const std::string& type) { type_ = type; }
206 
207  // Retrieve the number of arguments a function has
208  size_t num_args() { return (args_.size()); }
209 
210  // For debugging
211  void print(int level) const;
212 
213  private:
214  // Define the kind of the node, this can be a constant, a variable, or
215  // a function.
216  int kind_;
217 
218  // The return type of this node, this is used in the second pass
219  // where expressions are validated
220  std::string type_;
221 
222  // The name of the variable or the function, the constant scalar value,
223  // or the contents of a parsed string
224  std::string value_;
225 
226  // Pieces for functions
227  // Argument trees of the function arguments
228  std::vector<ParserNodeHandle> args_;
229  // Pointer to where the function is
230  ParserFunctionHandle function_;
231 };
232 
233 
235  public:
236  // In order to use handles, we need to add reference counting
237  int ref_cnt;
238 
239  public:
240  // Constructor
241  ParserTree(const std::string& varname, ParserNodeHandle expression) :
242  ref_cnt(0),
243  varname_(varname),
244  expression_(expression),
245  type_("U")
246  {}
247 
248  // Retrieve the name of the variable that needs to be assigned
249  std::string get_varname() { return (varname_); }
250 
251  // Retrieve the tree for computing the expression
252  ParserNodeHandle get_expression_tree() { return expression_; }
253  // Set expression tree
254  void set_expression_tree(ParserNodeHandle handle) { expression_ = handle; }
255 
256  // Set the final output type of the expression
257  void set_type(const std::string& type) { type_ = type; }
258 
259  // Retrieve final output type
260  const std::string& get_type() { return (type_); }
261 
262  // For debugging
263  void print() const;
264 
265  private:
266  // The name of the variable that needs to be assigned
267  std::string varname_;
268 
269  // The tree of functions that need to be called to compute this variable
270  ParserNodeHandle expression_;
271 
272  // Return type of the expression
273  std::string type_;
274 };
275 
276 
277 typedef std::map<std::string,ParserVariableHandle> ParserVariableList;
278 
280  public:
281  // In order to use handles, we need to add reference counting
282  int ref_cnt;
283 
284  public:
285  ParserProgram() : ref_cnt(0) {}
286 
287  // Add an expression to a program: this is a combination of the raw
288  // unparsed program code and the expression tree
289  void add_expression(const std::string& expression_string,
290  ParserTreeHandle expression_tree)
291  {
292  std::pair<std::string,ParserTreeHandle> expression(expression_string,expression_tree);
293  expressions_.push_back(expression);
294  }
295 
296  // Retrieve an expression from a program
297  // This gets one expression in unparsed and parsed form from the program
298  void get_expression(int expression_num,
299  std::string& expression_string,
300  ParserTreeHandle& expression_handle)
301  {
302  expression_string = expressions_[expression_num].first;
303  expression_handle = expressions_[expression_num].second;
304  }
305 
306  void get_expression(int expression_num,
307  ParserTreeHandle& expression_handle)
308  {
309  expression_handle = expressions_[expression_num].second;
310  }
311 
312  // Retrieve the number of expressions in the program
313  size_t num_expressions() { return (expressions_.size()); }
314 
315 
316  // Add an input variable to the program
317  void add_input_variable(const std::string& name, const std::string& type = "U", int flags = 0)
318  {
319  input_variables_[name].reset(new ParserVariable(name,type,flags));
320  }
321 
322  // Add an output variable to the program
323  void add_output_variable(const std::string& name, const std::string& type = "U", int flags = 0)
324  {
325  output_variables_[name].reset(new ParserVariable(name,type,flags));
326  }
327 
329  {
330  var_list = input_variables_;
331  }
332 
334  {
335  var_list = output_variables_;
336  }
337 
339  void set_catalog(ParserFunctionCatalogHandle catalog) { catalog_ = catalog;}
340 
341 
342  // Insert the variables
343  void add_const_var(ParserScriptVariableHandle& handle);
344  void add_single_var(ParserScriptVariableHandle& handle);
345  void add_sequential_var(ParserScriptVariableHandle& handle);
346 
347  void add_const_function(ParserScriptFunctionHandle& handle);
348  void add_single_function(ParserScriptFunctionHandle& handle);
349  void add_sequential_function(ParserScriptFunctionHandle& handle);
350 
351 
352  // Get the variables that need to be assigned
353  size_t num_const_variables();
354  size_t num_single_variables();
355  size_t num_sequential_variables();
356 
357  bool get_const_variable(size_t j,ParserScriptVariableHandle& handle);
358  bool get_single_variable(size_t j,ParserScriptVariableHandle& handle);
359  bool get_sequential_variable(size_t j,ParserScriptVariableHandle& handle);
360 
361  // Get the functions that need to be assigned
362  size_t num_const_functions();
363  size_t num_single_functions();
364  size_t num_sequential_functions();
365 
366  bool get_const_function(size_t j,ParserScriptFunctionHandle& handle);
367  bool get_single_function(size_t j,ParserScriptFunctionHandle& handle);
368  bool get_sequential_function(size_t j,ParserScriptFunctionHandle& handle);
369 
370 
371  // For debugging
372  void print() const;
373 
374  private:
375  // Short cut to the parser function catalog
377 
378  // The list of expressions, we store both the raw expression as well as the
379  // parsed version in order to effectively report back to user which expression
380  // is faulty. As the parsed version is harder to read, the raw version is kept.
381  std::vector<std::pair<std::string,ParserTreeHandle> > expressions_;
382 
383  // List of variables that exist when the program starts. This contains the
384  // list of variables the program can use, without them being defined in one
385  // of the expressions
386  ParserVariableList input_variables_;
387 
388  // List of output variables that need to be generated as they are required
389  // by the rest of the program. These variables need to be defined at the
390  // end of the program
391  ParserVariableList output_variables_;
392 
393  // The next series of variables represent the next stage of the parser
394  // In this stage everything is a variable or a function, and we have two
395  // lists of constants one for double constants and one for string constants
396 
397  std::vector<ParserScriptVariableHandle> const_variables_;
398  std::vector<ParserScriptVariableHandle> single_variables_;
399  std::vector<ParserScriptVariableHandle> sequential_variables_;
400 
401  std::vector<ParserScriptFunctionHandle> const_functions_;
402  std::vector<ParserScriptFunctionHandle> single_functions_;
403  std::vector<ParserScriptFunctionHandle> sequential_functions_;
404 };
405 
406 enum {
407  // Define a function as sequential it will be evaluated for each instance in
408  // the sequence. This one is used for functions without parameters like rand
409  // so they trigger for each case
413  // Variables are symmetric, this will tell the optimizer that the order of
414  // variables is not of interest
416 };
417 
418 
420 {
421  public:
422  ParserFunction(const std::string& function_id, const std::string& type) :
423  function_id_(function_id),
424  function_type_(type) {}
425 
426  ParserFunction(const std::string& function_id,const std::string& type, int fflags) :
427  function_id_(function_id),
428  function_type_(type),
429  function_flags_(fflags) {}
430 
431  // Virtual destructor so we can do dynamic casts on this class
432  virtual ~ParserFunction() {}
433 
434  // Retrieve the function ID string
435  const std::string& get_function_id() const { return (function_id_); }
436  // Retrieve the function return type
437 
438  const std::string& get_return_type() const { return (function_type_); }
439  // Retrieve the function flags
440  int get_flags() const { return (function_flags_); }
441 
442  private:
443  // The ID of the function, which is the name plus arguments in one string
444  std::string function_id_;
445 
446  // The return type of the function
447  std::string function_type_;
448 
449  // Flags define properties of this function
450  int function_flags_;
451 };
452 
453 // The list of functions
454 typedef std::map<std::string,ParserFunctionHandle> ParserFunctionList;
455 
456 // The ParserFunctionCatalog servers two purposes:
457 // - Tell the parser which functions are valid
458 // - Tell the parser what the return type is of each function call
459 
461 {
462  public:
464 
465  // Add definitions of functions to the list
466  // Various calls with different amounts of arguments
467  void add_function(ParserFunctionHandle function);
468 
469  // Retrieve a function from the data base
470  bool find_function(const std::string& function_id,
471  ParserFunctionHandle& function);
472 
473  // For debugging
474  void print() const;
475  private:
476 
477  // List of functions and their return type
478  ParserFunctionList functions_;
479  Core::Thread::Mutex lock_;
480 };
481 
482 
483 // In the end we build script of how to compute the
484 // results
485 
486 enum {
492 };
493 
495 {
496  public:
497  ParserScriptFunction(const std::string& name, ParserFunctionHandle function) :
498  name_(name), flags_(0), function_(function) {}
499 
500  // Get the name of the function
501  const std::string& get_name() const { return (name_); }
502 
503  // Get the number of input variables this function depends on
504  size_t num_input_vars() const { return (input_variables_.size()); }
505 
507  {
508  if (j < input_variables_.size()) return (input_variables_[j]);
509  return (ParserScriptVariableHandle(0));
510  }
511 
512  void set_input_var(size_t j, ParserScriptVariableHandle& handle)
513  {
514  if (j >= input_variables_.size()) input_variables_.resize(j+1);
515  input_variables_[j] = handle;
516  }
517 
518  ParserScriptVariableHandle get_output_var() const { return (output_variable_); }
519  void set_output_var(ParserScriptVariableHandle& handle) { output_variable_ = handle; }
520 
521  ParserFunctionHandle get_function() const { return (function_); }
522 
523  int get_flags() const { return (flags_); }
524  void set_flags(int flags) { flags_ |= flags; }
525  void clear_flags() { flags_ = 0; }
526 
527  // For debugging
528  void print() const;
529 
530  private:
531  // The name of the function
532  std::string name_;
533 
534  // Flags that describe whether this is a single or sequential call
535  int flags_;
536 
537  // Pointer to the function information block
538  ParserFunctionHandle function_;
539 
540  // Input variables in the function depends on
541  std::vector<ParserScriptVariableHandle> input_variables_;
542 
543  // Output variable
544  ParserScriptVariableHandle output_variable_;
545 };
546 
547 
549 
550  public:
551  // Create input variable
552  ParserScriptVariable(const std::string& name, const std::string& uname, const std::string& type, int flags) :
553  kind_(SCRIPT_INPUT_E),
554  type_(type),
555  flags_(flags),
556  name_(name),
557  uname_(uname),
558  scalar_value_(0.0),
559  var_number_(0)
560  {}
561 
562  // Create output variable
563  ParserScriptVariable(const std::string& uname, const std::string& type, int flags) :
564  kind_(SCRIPT_VARIABLE_E),
565  type_(type),
566  flags_(flags),
567  uname_(uname),
568  scalar_value_(0.0),
569  var_number_(0)
570  {}
571 
572  // Create scalar const variable
573  ParserScriptVariable(const std::string& uname,
574  double value) :
576  type_("S"),
577  flags_(SCRIPT_CONST_VAR_E),
578  uname_(uname),
579  scalar_value_(value),
580  var_number_(0)
581  {}
582 
583  // Create string const variable
584  ParserScriptVariable(const std::string& uname,
585  const std::string& value) :
587  type_("A"),
588  flags_(SCRIPT_CONST_VAR_E),
589  uname_(uname),
590  scalar_value_(0.0),
591  string_value_(value),
592  var_number_(0)
593  {}
594 
595 
596  // Set/get parent
597  void set_parent(ParserScriptFunctionHandle& handle) { parent_ = handle; }
598  ParserScriptFunctionHandle get_parent() const { return (parent_); }
599 
600  // Get kind of the variable
601  int get_kind() const { return (kind_); }
602  void set_kind(int kind) { kind_ = kind; }
603 
604  const std::string& get_type() const { return (type_); }
605  void set_type(const std::string& type) { type_ = type; }
606 
607  // Get/set flags of the variable
608  int get_flags() const { return (flags_); }
609  void set_flags(int flags) { flags_ |= flags; }
610  void clear_flags() { flags_ = 0; }
611 
612  void set_const_var() { flags_ |= SCRIPT_CONST_VAR_E; }
613  void set_single_var() { flags_ |= SCRIPT_SINGLE_VAR_E; }
615 
616  bool is_const_var() const { return (flags_ & SCRIPT_CONST_VAR_E) != 0; }
617  bool is_single_var() const { return (flags_ & SCRIPT_SINGLE_VAR_E) != 0; }
618  bool is_sequential_var() const { return (flags_ & SCRIPT_SEQUENTIAL_VAR_E) != 0; }
619 
620  // Get the name and the unique name
621  const std::string& get_name() const { return (name_); }
622  void set_name(const std::string& name) { name_ = name; }
623 
624  const std::string& get_uname() const { return (uname_); }
625  void set_uname(const std::string& uname) { uname_ = uname; }
626 
627 
628  // Get the constant values
629  double get_scalar_value() const { return (scalar_value_); }
630  const std::string& get_string_value() const { return (string_value_); }
631 
632  // Dependence of this variable
633  void compute_dependence();
634 
635  const std::string& get_dependence() const { return (dependence_); }
636  void clear_dependence() { dependence_.clear(); }
637 
638  int get_var_number() const { return (var_number_); }
639  void set_var_number(int var_number) { var_number_ = var_number; }
640 
641  // For debugging
642  void print() const;
643 
644  private:
645  // The function that created this variable
647 
648  // The kind of variable
649  int kind_;
650 
651  // The type of the variable
652  std::string type_;
653 
654  // The flags for sequential/single/constant
655  int flags_;
656 
657  // Name of the variable for input and output variables
658  std::string name_;
659 
660  // Unique name of the variable
661  std::string uname_;
662 
663  std::string dependence_;
664 
665  // For const scalar/string variables
666  double scalar_value_;
667  std::string string_value_;
668 
669  int var_number_;
670 };
671 
672 
673 //-----------------------------------------------------------------------------
674 // Below the code for the parser starts
675 // The parser takes a piece of raw code and analyzes its contents and creates
676 // a program tree that splits the pieces of the expression in the right
677 // hierarchical order.
678 
679 
681 
682  // Classes for storing the operator information
683  class BinaryOperator {
684  public:
685  std::string operator_;
686  std::string funname_;
687  int priority_;
688  };
689 
690  class UnaryOperator {
691  public:
692  std::string operator_;
693  std::string funname_;
694  };
695 
696  public:
697  Parser();
698 
699  bool parse(ParserProgramHandle& program,
700  std::string& expressions,
701  std::string& error);
702 
703  bool add_input_variable(ParserProgramHandle& program,
704  const std::string& name,
705  const std::string& type,
706  int flags = 0);
707 
708  bool add_output_variable(ParserProgramHandle& program,
709  const std::string& name,
710  const std::string& type = "U",
711  int flags = 0);
712 
713  bool add_output_variable(ParserProgramHandle program,
714  const std::string& name);
715 
716  bool get_input_variable_type(ParserProgramHandle program,
717  const std::string& name, std::string& type);
718 
719  bool get_output_variable_type(ParserProgramHandle program,
720  const std::string& name, std::string& type);
721 
722 
723  bool get_input_variable_type(ParserProgramHandle program,
724  const std::string& name,
725  std::string& type,
726  int& flags);
727 
728  bool get_output_variable_type(ParserProgramHandle program,
729  const std::string& name,
730  std::string& type,
731  int& flags);
732 
733 
734  bool validate(ParserProgramHandle program,
736  std::string& error);
737 
738  bool optimize(ParserProgramHandle program,
739  std::string& error);
740 
741  //--------------------------------------------------------------------------
742  // Setup of parser
743 
744  // These functions add or overload the function names of default operators
745  // and even add additional operators if a new one is specified.
746 
747  // These functions are intended for customizing the parser
748  // NOTE OPERATOR NAMES CURRENTLY CANNOT BE LONGER THAN TWO CHARACTERS
749  // IF LONGER OPERATOR NAMES ARE NEEDED THE CODE SHOULD BE UPGRADED
750  void add_binary_operator(const std::string& op, const std::string& funname, int priority);
751  void add_unary_pre_operator(const std::string& op, const std::string& funname);
752  void add_unary_post_operator(const std::string& op, const std::string& funname);
753 
754  // Mark special variable names as constants
755  void add_numerical_constant(const std::string& name,double val);
756 
757  private:
758  // Get an expression from the program code. Expressions are read sequentially
759  // and this function will modify the input and remove the first expression.
760  bool scan_expression(std::string& expressions,
761  std::string& expression);
762 
763 
764  // This function breaks down an expression into two components
765  // The part to the left of the equal sign
766  // The part to the right of the equal sign
767  // The variable name is checked to see whether it is valid
768  // The expression part is not parsed by this function that is done separately
769  bool split_expression(std::string& expression,
770  std::string& varname,
771  std::string& vartree);
772 
773  // Parse the parts on the right hand side of the equal sign of the expression
774  bool parse_expression_tree(std::string& expression,
775  ParserNodeHandle& ehandle,
776  std::string& error);
777 
778 
779  // Scan whether the string starts with a sub expression, i.e. '( ..... )'
780  bool scan_sub_expression(std::string& expression, std::string& subexpression);
781 
782  // Scan whether the string starts with a subs assignment expression, i.e. '[ ..... ]'
783  bool scan_subs_expression(std::string& expression, std::string& subexpression);
784 
785 
786  // Scan for a numeric constant at the start of the string
787  // A numeric constant must start with a number
788  // Numbers like 0x12 077 1.23E-8 etc should all be detected by this
789  // function. It strips out the number and returns that piece of the string
790  bool scan_constant_value(std::string& expression, std::string& value);
791 
792  // Scan for a variable name at the start of the string
793  // A variable name should start with a-zA-Z or _ and can have
794  // numbers for the second character and further.
795  // It should not contain any spaces.
796  // This function checks as well if the name is followed by spaces and '('
797  // If so it is not a variable name, but a function name
798  // This function strips out the variable name out of expression and
799  // returns in var_name
800  bool scan_variable_name(std::string& expression, std::string& var_name);
801 
802  // Scan for a string. A srting is a piece of code between quotes e.g. "foo"
803  // This function should recognize most escape characters in the string and
804  // will translate them as well
805  bool scan_constant_string(std::string& expression, std::string& str);
806 
807  // Scan for a function. A function starts with a variable name, but is
808  // followed by optional spaces and then (...,....,...), which is the
809  // argument list. This function should scan for those argument lists
810  bool scan_function(std::string& expression, std::string& function);
811 
812  // Scan for the equal sign, this is used to parse expressions
813  // Each expression should contain one
814  bool scan_equal_sign(std::string& expression);
815 
816  // Split a string with code for a function into the function name and into
817  // its arguments
818  void split_function(std::string& expression,
819  std::string& fun_name,
820  std::vector<std::string>& fun_args);
821 
822  // Split a string with code for a subs function into its arguments
823  void split_subs(std::string& expression,
824  std::vector<std::string>& start_args,
825  std::vector<std::string>& step_args,
826  std::vector<std::string>& end_args,
827  std::string& varname);
828 
829 
830  // Check for syntax errors in the code
831  bool check_syntax(std::string& expression, std::string& error);
832 
833 
834  // Scan whether the expression starts with a binary operator
835  bool scan_binary_operator(std::string& expression,
836  std::string& binary_operator);
837 
838  // Scan whether the expression starts with an unary operator
839  bool scan_pre_unary_operator(std::string& expression,
840  std::string& unary_operator);
841 
842  // Scan whether the expression starts with an unary operator
843  bool scan_post_unary_operator(std::string& expression,
844  std::string& unary_operator);
845 
846  // Get the functionname of the unary operator
847  // The name that should be in the FunctionCatalog
848  bool get_unary_function_name(std::string& unary_operator,
849  std::string& fun_name);
850 
851  // Get the functionname of the binary operator
852  // The name that should be in the FunctionCatalog
853  bool get_binary_function_name(std::string& binary_operator,
854  std::string& fun_name);
855 
856  // Binary operators need a priority in which they are evaluated
857  // This one returns the priority of each operator
858  bool get_binary_priority(std::string& binary_operator, int& priority);
859 
860 
861  //------------------------------------------------------------
862  // General functions for parsing text
863  // Remove a parentices pair at the start and end of the string
864  bool remove_global_parentices(std::string& expression);
865 
866  // Remove // and /* comments from the expression
867  void remove_comments(std::string& expression);
868 
869 
870  //------------------------------------------------------------
871  // Sub functions for validation
872  bool recursive_validate(ParserNodeHandle handle,
874  ParserVariableList& var_list,
875  std::string& error,
876  std::string& expression);
877 
878 
879  //------------------------------------------------------------
880  // Sub functions for optimization
881  void optimize_mark_used(ParserScriptFunctionHandle& fhandle);
882 
883  bool optimize_process_node(ParserNodeHandle& nhandle,
884  std::list<ParserScriptVariableHandle>& variables,
885  std::map<std::string,ParserScriptVariableHandle>& named_variables,
886  std::list<ParserScriptFunctionHandle>& functions,
888  int& cnt,
889  std::string& error);
890 
891  private:
892  // List of supported binary operators e.g. + - * /
893  std::map<std::string,BinaryOperator> binary_operators_;
894  // List of pre unary opertors e.g. + - ! ~
895  std::map<std::string,UnaryOperator> unary_pre_operators_;
896  // List of post unary opertors e.g. '
897  std::map<std::string,UnaryOperator> unary_post_operators_;
898 
899  // List of numerical constants, e.g. nan, inf, false, true etc.
900  std::map<std::string,double> numerical_constants_;
901 
902 };
903 
904 }
905 
906 #endif
Definition: Parser.h:488
ParserFunction(const std::string &function_id, const std::string &type)
Definition: Parser.h:422
void get_input_variables(ParserVariableList &var_list)
Definition: Parser.h:328
int get_kind()
Definition: Parser.h:171
void clear_flags()
Definition: Parser.h:525
Definition: Parser.h:491
Definition: Parser.h:279
int get_flags() const
Definition: Parser.h:440
std::string get_varname()
Definition: Parser.h:249
void set_arg(size_t j, ParserNode *ptr)
Definition: Parser.h:193
void clear_dependence()
Definition: Parser.h:636
Definition: Parser.h:411
boost::shared_ptr< ParserFunctionCatalog > ParserFunctionCatalogHandle
Definition: Parser.h:72
int get_flags()
Definition: Parser.h:137
const std::string & get_name() const
Definition: Parser.h:501
size_t num_args()
Definition: Parser.h:208
Definition: Parser.h:234
void get_output_variables(ParserVariableList &var_list)
Definition: Parser.h:333
void set_flags(int flags)
Definition: Parser.h:609
std::string get_type()
Definition: Parser.h:174
Definition: Parser.h:494
boost::shared_ptr< ParserNode > ParserNodeHandle
Definition: Parser.h:63
void print() const
Definition: Parser.cc:230
Definition: Parser.h:680
void get_expression(int expression_num, ParserTreeHandle &expression_handle)
Definition: Parser.h:306
void get_expression(int expression_num, std::string &expression_string, ParserTreeHandle &expression_handle)
Definition: Parser.h:298
ParserTree(const std::string &varname, ParserNodeHandle expression)
Definition: Parser.h:241
ParserScriptVariableHandle get_output_var() const
Definition: Parser.h:518
void set_type(const std::string &type)
Definition: Parser.h:257
const std::string & get_type() const
Definition: Parser.h:604
#define SCISHARE
Definition: share.h:39
void set_const_var()
Definition: Parser.h:612
void set_type(std::string type)
Definition: Parser.h:134
Definition: Mutex.h:43
const std::string & get_name() const
Definition: Parser.h:621
const std::string & get_uname() const
Definition: Parser.h:624
void add_input_variable(const std::string &name, const std::string &type="U", int flags=0)
Definition: Parser.h:317
Definition: Parser.h:103
int ref_cnt
Definition: Parser.h:109
const std::string & get_type()
Definition: Parser.h:260
void set_type(const std::string &type)
Definition: Parser.h:205
ParserNode(int kind, const std::string &value)
Definition: Parser.h:158
int get_kind() const
Definition: Parser.h:601
int ref_cnt
Definition: Parser.h:237
ParserFunction(const std::string &function_id, const std::string &type, int fflags)
Definition: Parser.h:426
std::map< std::string, ParserVariableHandle > ParserVariableList
Definition: Parser.h:277
boost::shared_ptr< ParserScriptVariable > ParserScriptVariableHandle
Definition: Parser.h:74
double get_scalar_value() const
Definition: Parser.h:629
Definition: Parser.h:490
ParserScriptVariable(const std::string &uname, const std::string &type, int flags)
Definition: Parser.h:563
void add_output_variable(const std::string &name, const std::string &type="U", int flags=0)
Definition: Parser.h:323
Definition: Parser.h:106
void set_catalog(ParserFunctionCatalogHandle catalog)
Definition: Parser.h:339
int get_flags() const
Definition: Parser.h:608
std::string get_name()
Definition: Parser.h:140
size_t num_expressions()
Definition: Parser.h:313
Definition: Parser.h:412
const char * name[]
Definition: BoostGraphExampleTests.cc:87
void set_single_var()
Definition: Parser.h:613
void set_output_var(ParserScriptVariableHandle &handle)
Definition: Parser.h:519
int get_flags() const
Definition: Parser.h:523
int ref_cnt
Definition: Parser.h:282
size_t num_input_vars() const
Definition: Parser.h:504
const std::string & get_return_type() const
Definition: Parser.h:438
void set_sequential_var()
Definition: Parser.h:614
ParserScriptVariable(const std::string &name, const std::string &uname, const std::string &type, int flags)
Definition: Parser.h:552
Definition: Parser.h:95
ParserVariable(std::string name, std::string type)
Definition: Parser.h:112
Definition: Parser.h:460
void clear_flags()
Definition: Parser.h:610
Definition: Parser.h:79
const std::string & get_function_id() const
Definition: Parser.h:435
ParserNodeHandle get_expression_tree()
Definition: Parser.h:252
boost::shared_ptr< ParserProgram > ParserProgramHandle
Definition: Parser.h:70
bool is_const_var() const
Definition: Parser.h:616
ParserFunctionHandle get_function() const
Definition: Parser.h:521
const std::string & get_string_value() const
Definition: Parser.h:630
Definition: Parser.h:155
ParserNode(int kind, const std::string &value, const std::string &type)
Definition: Parser.h:164
void set_type(const std::string &type)
Definition: Parser.h:605
void set_expression_tree(ParserNodeHandle handle)
Definition: Parser.h:254
ParserProgram()
Definition: Parser.h:285
void set_parent(ParserScriptFunctionHandle &handle)
Definition: Parser.h:597
Definition: Parser.h:101
boost::shared_ptr< class ParserFunction > ParserFunctionHandle
Definition: Parser.h:153
std::string get_type()
Definition: Parser.h:132
Definition: Parser.h:415
void set_value(const std::string &value)
Definition: Parser.h:180
void compute_dependence()
Definition: Parser.cc:261
Definition: Parser.h:80
void set_input_var(size_t j, ParserScriptVariableHandle &handle)
Definition: Parser.h:512
void set_function(ParserFunctionHandle func)
Definition: Parser.h:200
Definition: Parser.h:489
void print() const
Definition: Parser.cc:218
std::string get_value()
Definition: Parser.h:177
const std::string & get_dependence() const
Definition: Parser.h:635
bool is_single_var() const
Definition: Parser.h:617
void set_var_number(int var_number)
Definition: Parser.h:639
Definition: Parser.h:81
ParserFunctionHandle get_function()
Definition: Parser.h:202
ParserScriptVariable(const std::string &uname, double value)
Definition: Parser.h:573
ParserNodeHandle get_arg(size_t j)
Definition: Parser.h:183
bool is_sequential_var() const
Definition: Parser.h:618
Definition: Parser.h:410
void set_flags(int flags)
Definition: Parser.h:524
void set_kind(int kind)
Definition: Parser.h:602
ParserScriptFunctionHandle get_parent() const
Definition: Parser.h:598
void add_expression(const std::string &expression_string, ParserTreeHandle expression_tree)
Definition: Parser.h:289
ParserScriptVariableHandle get_input_var(size_t j) const
Definition: Parser.h:506
boost::shared_ptr< ParserScriptFunction > ParserScriptFunctionHandle
Definition: Parser.h:73
Definition: Parser.h:548
std::map< std::string, ParserFunctionHandle > ParserFunctionList
Definition: Parser.h:454
int get_var_number() const
Definition: Parser.h:638
Definition: Parser.h:82
void set_uname(const std::string &uname)
Definition: Parser.h:625
ParserFunctionCatalogHandle get_catalog()
Definition: Parser.h:338
void set_arg(size_t j, ParserNodeHandle handle)
Definition: Parser.h:186
ParserScriptFunction(const std::string &name, ParserFunctionHandle function)
Definition: Parser.h:497
ParserVariable(std::string name, std::string type, int flags)
Definition: Parser.h:119
ParserScriptVariable(const std::string &uname, const std::string &value)
Definition: Parser.h:584
boost::shared_ptr< ParserVariable > ParserVariableHandle
Definition: Parser.h:71
Definition: Parser.h:419
Definition: Parser.h:99
virtual ~ParserFunction()
Definition: Parser.h:432
Definition: Parser.h:97
void set_name(const std::string &name)
Definition: Parser.h:622
boost::shared_ptr< ParserTree > ParserTreeHandle
Definition: Parser.h:69
Definition: Parser.h:487