2#include "expression_processor.h"
3#include "ph_processor.h"
8#include <cgv/utils/tokenizer.h>
9#include <cgv/utils/convert.h>
16 bool check_cyclic_reference(
const variant* v)
18 std::vector<const variant*> s;
22 if (v->get_type() == REFERENCE_VALUE)
23 v1 = v->get_reference();
24 else if (v->get_type() == NAME_VALUE)
25 v1 = find_variable(v->get_name());
29 for (
unsigned i = 0; i < s.size(); ++i) {
39 expression_processor::expression_processor()
46 debug_evaluate =
false;
51 unsigned int expression_processor::get_nr_comma_separated_expressions(
52 std::vector<expr_stack_entry>& expression_stack,
53 std::vector<ExpressionPart>& parenthesis_stack,
54 std::stack<variant>& value_stack)
const
56 unsigned int i = (
unsigned int)expression_stack.size();
61 if (value_stack.size() <= expression_stack.back().first)
63 while (parenthesis_stack[i] == EP_COMMA) {
72 ExpressionPart expression_processor::find_last_parenthesis(std::vector<expr_stack_entry>& expression_stack,
73 std::vector<ExpressionPart>& parenthesis_stack)
const
75 unsigned int i = (
unsigned int)expression_stack.size();
79 while (parenthesis_stack[i] == EP_COMMA) {
84 return parenthesis_stack[i];
87 bool expression_processor::parse(
const token& input_token)
89 expression_tokens.clear();
91 std::vector<token> input_tokens;
92 bite_all(
tokenizer(input_token).set_sep(std::string(operator_characters) +
"()[],",
false).
93 set_skip(
"\"'",
"\"'"), input_tokens);
96 for (i = 0; i < input_tokens.size(); ++i) {
97 const token& tok = input_tokens[i];
98 if (*tok.begin ==
'"' || *tok.begin ==
'\'') {
100 expression_tokens.push_back(expression_token(tok, v));
102 std::cout << i <<
" : string token '" << v.get_str() <<
"'" << std::endl;
105 expression_tokens.push_back(expression_token(tok, EP_OPEN));
107 std::cout << i <<
" : open token" << std::endl;
110 expression_tokens.push_back(expression_token(tok, EP_CLOSE));
112 std::cout << i <<
" : close token" << std::endl;
115 expression_tokens.push_back(expression_token(tok, EP_LIST_OPEN));
117 std::cout << i <<
" : open list token" << std::endl;
120 expression_tokens.push_back(expression_token(tok, EP_LIST_CLOSE));
122 std::cout << i <<
" : close list token" << std::endl;
125 expression_tokens.push_back(expression_token(tok, EP_COMMA));
127 std::cout << i <<
" : comma token" << std::endl;
130 OperatorType ot = OT_LAST;
132 if (tok.size() == 1 &&
is_element(*tok.begin, operator_characters)) {
135 if (i + 1 < input_tokens.size() && input_tokens[i + 1].size() == 1 &&
136 is_element(*input_tokens[i + 1].begin, operator_characters)) {
140 op_tok.end = input_tokens[i].end;
146 expression_tokens.push_back(expression_token(op_tok, ot));
148 std::cout << i <<
" : operator " << get_operator_word(ot) << std::endl;
156 bool considered_dot =
false;
157 bool considered_exp =
false;
158 bool considered_sign =
false;
159 while (j < input_tokens.size()) {
160 bool can_extend =
true;
161 for (
const char* p = dbl_tok.end; p < input_tokens[j].end; ++p) {
162 if (!considered_dot && *p ==
'.')
163 considered_dot =
true;
164 else if (!considered_exp && (*p ==
'E' || *p ==
'e'))
165 considered_exp =
true;
166 else if (!considered_sign && (*p ==
'+' || *p ==
'-'))
167 considered_sign =
true;
168 else if (*p <
'0' || *p >
'9') {
174 dbl_tok.end = input_tokens[j].end;
180 bool rather_int = !considered_dot && !considered_exp && !considered_sign;
181 if (!rather_int && dbl_tok[0] >=
'0' && dbl_tok[0] <=
'9' &&
is_double(
to_string(dbl_tok), d)) {
183 expression_tokens.push_back(expression_token(dbl_tok, variant(d)));
185 std::cout << i <<
"-" << j - 1 <<
" : double tokens = " << d << std::endl;
189 expression_tokens.push_back(expression_token(tok, variant(vi)));
191 std::cout << i <<
" : int token = " << vi << std::endl;
195 expression_tokens.push_back(expression_token(tok, v));
197 std::cout << i <<
" : variable >" <<
to_string(tok) <<
"< = " <<
198 v.get_str() << std::endl;
206 void expression_processor::prepare()
209 issued_error =
false;
216 void expression_processor::extract_begins(std::vector<unsigned>& begins,
unsigned i0,
unsigned ie)
const
219 ie = (unsigned)expression_tokens.size();
221 if (expression_tokens.size() > i0)
222 begins.push_back(i0);
223 for (
unsigned i = i0; i < ie; ++i) {
224 const expression_token& et = expression_tokens[i];
240 if (parenthesis == 0 && i + 1 < ie)
241 begins.push_back(i + 1);
247 int expression_processor::classify_call(
unsigned closing_i)
const
249 unsigned opening_i = closing_i - 1;
250 unsigned parenthesis = 1;
252 const expression_token& et = expression_tokens[opening_i];
267 if (parenthesis == 0)
271 std::vector<unsigned> begins;
272 extract_begins(begins, opening_i + 1, closing_i);
273 unsigned nr_special = 0;
274 for (
unsigned i = 0; i < begins.size(); ++i) {
275 unsigned j = begins[i];
276 if (expression_tokens[j].ep != EP_OPERATOR || expression_tokens[j].ot != OT_MAP_DOWN)
279 if (j >= expression_tokens.size() || expression_tokens[j].ep != EP_VALUE || expression_tokens[j].value.get_type() != NAME_VALUE)
282 if (j >= expression_tokens.size() || expression_tokens[j].ep != EP_OPERATOR || (expression_tokens[j].ot != OT_ASSIGN && expression_tokens[j].ot != OT_ASSIGN_REF))
286 if (nr_special == begins.size())
293 bool expression_processor::assign_func_decl(
const std::vector<variant>& values)
const
295 std::vector<unsigned> begins;
296 extract_begins(begins);
297 if (values.size() > begins.size()) {
298 last_error =
"function called with more parameters than declared by the function";
299 last_error_token = expression_tokens.back();
302 for (
unsigned i = 0; i < values.size(); ++i) {
303 variant& v = ref_variable(expression_tokens[begins[i] + 1].value.get_name(),
true);
305 if (check_cyclic_reference(&v)) {
306 last_error =
"a call to this function generated cyclic reference to variable ";
308 last_error += v.get_name();
309 last_error +=
". Make sure to use map down operator <:";
311 last_error += v.get_name();
312 last_error +=
" to mark special function call syntax in the function call referenced in the next error message.";
313 last_error_token = expression_tokens.back();
321 bool expression_processor::is_func_decl()
const
323 std::vector<unsigned> begins;
324 extract_begins(begins);
325 for (
unsigned i = 0; i < begins.size(); ++i) {
326 unsigned j = begins[i];
327 if (expression_tokens[j].ep != EP_OPERATOR || expression_tokens[j].ot != OT_MAP_UP) {
328 last_error =
"function declaration expression must be a comma separated list of expressions of the form ':>var_name=...' or ':>var_name=&...' (:> missing)";
329 last_error_token = expression_tokens[j];
333 if (j >= expression_tokens.size() || expression_tokens[j].ep != EP_VALUE || expression_tokens[j].value.get_type() != NAME_VALUE) {
334 last_error =
"function declaration expression must be a comma separated list of expressions of the form ':>var_name=...' or ':>var_name=&...' (var_name missing)";
335 if (j < expression_tokens.size())
336 last_error_token = expression_tokens[j];
338 last_error_token = expression_tokens.back();
342 if (j >= expression_tokens.size() || expression_tokens[j].ep != EP_OPERATOR || (expression_tokens[j].ot != OT_ASSIGN && expression_tokens[j].ot != OT_ASSIGN_REF)) {
343 last_error =
"function declaration expression must be a comma separated list of expressions of the form ':>var_name=...' or ':>var_name=&...' (= or =& missing)";
344 if (j < expression_tokens.size())
345 last_error_token = expression_tokens[j];
347 last_error_token = expression_tokens.back();
356 if (expression_tokens.size() == 0)
361 std::vector<expr_stack_entry> expression_stack;
363 std::vector<ExpressionPart> parenthesis_stack;
365 std::stack<variant> value_stack;
367 std::stack<OperatorType> operator_stack;
369 bool left_of_operand =
true;
371 for (i = 0; i < expression_tokens.size(); ++i) {
375 if (left_of_operand) {
376 value_stack.push(et.value);
377 left_of_operand =
false;
380 last_error =
"two successive values in expression without operator";
381 last_error_token = expression_tokens[i];
387 if (get_operator_arity(et.ot) == 2 && left_of_operand && et.ot == OT_SUB)
390 if (get_operator_arity(et.ot) == 2 && left_of_operand && et.ot == OT_BINARY_MAP)
391 et.ot = OT_UNARY_MAP;
393 if (get_operator_arity(et.ot) == 1) {
394 if (get_operator_location(et.ot) == OL_PREFIX) {
395 if (left_of_operand) {
396 operator_stack.push(et.ot);
399 last_error = std::string(
"unary prefix operator ") +
400 get_operator_word(et.ot) +
401 " cannot follow operand";
402 last_error_token = expression_tokens[i];
407 if (left_of_operand) {
408 last_error = std::string(
"unary postfix operator ") +
409 get_operator_word(et.ot) +
410 " cannot preceed operand";
411 last_error_token = expression_tokens[i];
415 operator_stack.push(et.ot);
420 if (left_of_operand) {
421 last_error = std::string(
"binary operator ") +
422 get_operator_word(et.ot) +
423 " is missing left argument";
424 last_error_token = expression_tokens[i];
428 if (!compress_stack_validate(get_operator_priority(et.ot), expression_stack, parenthesis_stack, value_stack, operator_stack))
430 operator_stack.push(et.ot);
431 left_of_operand =
true;
437 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
438 if (left_of_operand) {
439 parenthesis_stack.push_back(EP_OPEN);
442 if (!compress_stack_validate(get_operator_priority(OT_MAP_UP), expression_stack, parenthesis_stack, value_stack, operator_stack))
444 expression_tokens[i].ep = EP_FUNC;
445 parenthesis_stack.push_back(EP_FUNC);
446 left_of_operand =
true;
451 ExpressionPart last_parenthesis = find_last_parenthesis(expression_stack, parenthesis_stack);
452 if (last_parenthesis == EP_OPEN && left_of_operand) {
453 last_error =
"closing paranthesis cannot init term";
454 last_error_token = expression_tokens[i];
457 if (last_parenthesis != EP_OPEN && last_parenthesis != EP_FUNC) {
458 last_error =
"wrongly or not matched parenthesis )";
459 last_error_token = expression_tokens[i];
462 if (!left_of_operand) {
463 if (!compress_stack_validate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
464 last_error_token = expression_tokens[i];
467 if ((last_parenthesis != EP_FUNC) && (value_stack.size() <= expression_stack.back().first)) {
468 last_error =
"no resulting value in expression";
469 last_error_token = expression_tokens[i];
473 while (get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack) > 1) {
474 variant tmp = value_stack.top();
477 value_stack.push(tmp);
478 expression_stack.pop_back();
479 parenthesis_stack.pop_back();
481 if (last_parenthesis == EP_FUNC)
485 left_of_operand =
false;
486 expression_stack.pop_back();
487 parenthesis_stack.pop_back();
492 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
494 parenthesis_stack.push_back(EP_LIST_OPEN);
496 if (!compress_stack_validate(get_operator_priority(OT_MAP_UP), expression_stack, parenthesis_stack, value_stack, operator_stack))
498 expression_tokens[i].ep = EP_LIST_ACCESS;
499 parenthesis_stack.push_back(EP_LIST_ACCESS);
500 left_of_operand =
true;
505 if (left_of_operand) {
506 if (i == 0 || expression_tokens[i - 1].ep != EP_LIST_OPEN) {
507 last_error =
"closing paranthesis ] cannot init a term";
508 last_error_token = expression_tokens[i];
511 left_of_operand =
false;
513 ExpressionPart last_parenthesis = find_last_parenthesis(expression_stack, parenthesis_stack);
514 if (last_parenthesis != EP_LIST_OPEN &&
515 last_parenthesis != EP_LIST_ACCESS) {
516 last_error =
"wrongly or not matched parenthesis ]";
517 last_error_token = expression_tokens[i];
520 if (!compress_stack_validate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
521 last_error_token = expression_tokens[i];
524 if (last_parenthesis == EP_LIST_OPEN) {
525 unsigned int n = get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack);
528 std::vector<variant> tmp;
531 for (i = 0; i < n; ++i) {
532 tmp[n - i - 1] = value_stack.top();
534 expression_stack.pop_back();
535 parenthesis_stack.pop_back();
537 for (i = 0; i < n; ++i)
538 v.append_to_list(tmp[i]);
541 expression_stack.pop_back();
542 parenthesis_stack.pop_back();
547 unsigned int n = get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack);
549 last_error =
"list access only with exactly one value allowed";
550 last_error_token = expression_tokens[i];
554 expression_stack.pop_back();
555 parenthesis_stack.pop_back();
556 if (value_stack.empty()) {
557 last_error =
"applied list access operator to empty value stack";
558 last_error_token = expression_tokens[i];
567 if (left_of_operand) {
568 last_error =
"comma cannot init a term";
569 last_error_token = expression_tokens[i];
572 if (!compress_stack_validate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
573 last_error_token = expression_tokens[i];
576 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
577 parenthesis_stack.push_back(EP_COMMA);
578 left_of_operand =
true;
582 if (!compress_stack_validate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack))
584 if (value_stack.empty()) {
585 last_error =
"expression did not yield a value";
586 last_error_token =
token(expression_tokens.front().begin, expression_tokens.back().end);
589 if (!allow_several_values && value_stack.size() > 1) {
590 last_error =
"expression yielded more than one value";
591 last_error_token =
token(expression_tokens.front().begin, expression_tokens.back().end);
600 if (expression_tokens.size() == 0) {
607 std::vector<expr_stack_entry> expression_stack;
609 std::vector<ExpressionPart> parenthesis_stack;
611 std::stack<variant> value_stack;
613 std::stack<OperatorType> operator_stack;
616 bool empty_func_arg =
false;
617 for (i = 0; i < expression_tokens.size(); ++i) {
621 value_stack.push(et.value);
622 empty_func_arg =
false;
625 empty_func_arg =
false;
626 if (get_operator_arity(et.ot) == 1) {
627 operator_stack.push(et.ot);
630 compress_stack_evaluate(get_operator_priority(et.ot), expression_stack, parenthesis_stack, value_stack, operator_stack);
631 operator_stack.push(et.ot);
635 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
636 parenthesis_stack.push_back(EP_OPEN);
639 compress_stack_evaluate(get_operator_priority(OT_MAP_UP), expression_stack, parenthesis_stack, value_stack, operator_stack);
640 empty_func_arg =
true;
641 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
642 parenthesis_stack.push_back(EP_FUNC);
643 if (value_stack.top().is_name() || value_stack.top().is_str() || value_stack.top().is_func()) {
645 if (value_stack.top().is_func())
646 func_var = &value_stack.top().
ref_value();
648 std::string func_name = (value_stack.top().is_str() ? value_stack.top().get_str() : value_stack.top().get_name());
649 func_var = &ref_variable(func_name);
653 push_namespace(0, func.ns);
654 ref_variable(
"return",
true);
656 if (func.ph_proc->commands[func.block_begin - 1].expressions.size() == 2) {
657 ph_proc->swap_output(*func.ph_proc);
660 if (!ep.issued_error) {
661 ph_proc->error(ep.last_error, ep.last_error_token);
662 ep.issued_error =
true;
664 ph_proc->swap_output(*func.ph_proc);
665 last_error =
"previous error was generated while evaluating this expression";
666 last_error_token = expression_tokens[i];
670 ph_proc->swap_output(*func.ph_proc);
671 if (func.ph_proc->exit_code != 0) {
672 ph_proc->exit_code = func.ph_proc->exit_code;
676 goto_parent_namespace();
679 last_error =
"function call on variable not of type func";
680 last_error_token = expression_tokens[i];
686 last_error =
"function call on non name or string expression";
687 last_error_token = expression_tokens[i];
694 ExpressionPart last_parenthesis = find_last_parenthesis(expression_stack, parenthesis_stack);
695 if (last_parenthesis != EP_FUNC) {
696 if (!compress_stack_evaluate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
697 last_error_token = expression_tokens[i];
702 while (get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack) > 1) {
703 variant tmp = value_stack.top();
706 value_stack.push(tmp);
707 expression_stack.pop_back();
708 parenthesis_stack.pop_back();
710 expression_stack.pop_back();
711 parenthesis_stack.pop_back();
714 std::vector<variant> arguments;
715 if (!empty_func_arg) {
716 if (!compress_stack_evaluate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
717 last_error_token = expression_tokens[i];
721 unsigned argc = get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack);
722 int cc = classify_call(i);
724 last_error =
"error calling a function mixing special and standard syntax";
725 last_error_token = et;
730 arguments.resize(argc);
731 for (
unsigned i = 0; i < argc; ++i) {
732 arguments[argc - 1 - i] = value_stack.top();
733 if (arguments[argc - 1 - i].get_type() == NAME_VALUE) {
734 arguments[argc - 1 - i] =
variant(&ref_variable(arguments[argc - 1 - i].get_name()));
737 expression_stack.pop_back();
738 parenthesis_stack.pop_back();
742 for (
unsigned i = 0; i < argc; ++i) {
744 expression_stack.pop_back();
745 parenthesis_stack.pop_back();
750 expression_stack.pop_back();
751 parenthesis_stack.pop_back();
753 if (value_stack.top().is_name() || value_stack.top().is_str() || value_stack.top().is_func()) {
755 if (value_stack.top().is_func())
756 func_var = &value_stack.top().
ref_value();
758 std::string func_name = (value_stack.top().is_str() ? value_stack.top().get_str() : value_stack.top().get_name());
759 variant* func_var = &ref_variable(func_name);
762 goto_child_namespace();
764 ph_proc->swap_output(*func.ph_proc);
765 if (arguments.size() > 0 && func.ph_proc->commands[func.block_begin - 1].expressions.size() == 2) {
767 if (!ep.assign_func_decl(arguments)) {
768 func.ph_proc->error(ep.get_last_error(), ep.get_last_error_token());
769 ph_proc->swap_output(*func.ph_proc);
770 last_error =
"error appeared in the following function call:";
771 last_error_token = et;
776 else if (arguments.size() > 0) {
777 ph_proc->swap_output(*func.ph_proc);
778 last_error =
"error calling a function without arguments passing values";
779 last_error_token = et;
783 if (!func.ph_proc->process(func.block_begin, func.block_end)) {
784 ph_proc->swap_output(*func.ph_proc);
785 last_error =
"error in function call";
786 last_error_token = expression_tokens[i];
790 ph_proc->swap_output(*func.ph_proc);
792 value_stack.push(ref_variable(
"return",
true));
796 last_error =
"function call on variable not of type proc";
797 last_error_token = expression_tokens[i];
803 last_error =
"function call on non name or string expression";
804 last_error_token = expression_tokens[i];
809 empty_func_arg =
false;
813 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
814 parenthesis_stack.push_back(EP_LIST_OPEN);
817 compress_stack_evaluate(get_operator_priority(OT_MAP_UP), expression_stack, parenthesis_stack, value_stack, operator_stack);
818 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
819 parenthesis_stack.push_back(EP_LIST_ACCESS);
823 ExpressionPart last_parenthesis = find_last_parenthesis(expression_stack, parenthesis_stack);
824 if (!compress_stack_evaluate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
825 last_error_token = expression_tokens[i];
829 if (last_parenthesis == EP_LIST_OPEN) {
830 unsigned int n = get_nr_comma_separated_expressions(expression_stack, parenthesis_stack, value_stack);
833 std::vector<variant> tmp;
836 for (i = 0; i < n; ++i) {
837 tmp[n - i - 1] = value_stack.top();
839 expression_stack.pop_back();
840 parenthesis_stack.pop_back();
842 for (i = 0; i < n; ++i)
843 v.append_to_list(tmp[i].get_value());
846 expression_stack.pop_back();
847 parenthesis_stack.pop_back();
852 variant var_idx = value_stack.top();
854 expression_stack.pop_back();
855 parenthesis_stack.pop_back();
856 if (value_stack.top().is_map()) {
857 std::string var_name;
861 value_stack.push(var_name);
867 last_error =
"map access key evaluate to name or string";
868 last_error_token = expression_tokens[i];
873 if (value_stack.top().is_reference()) {
874 tmp =
variant(&value_stack.top().ref_element(var_name));
879 value_stack.push(tmp);
884 if (value_stack.top().is_list()) {
886 idx += (int)value_stack.top().get_size();
887 if (idx < 0 || idx >= (
int)value_stack.top().get_size()) {
888 last_error =
"list access with index ";
889 last_error +=
to_string(idx) +
" out of valid range [0," +
890 to_string(value_stack.top().get_size()) +
"]";
891 last_error_token = expression_tokens[i];
896 if (value_stack.top().is_reference()) {
897 tmp =
variant(&value_stack.top().ref_element(idx));
902 value_stack.push(tmp);
904 else if (value_stack.top().is_str()) {
905 int n = (int)value_stack.top().
get_str().size();
908 if (idx < 0 || idx >= n) {
909 last_error =
"string access with index ";
910 last_error +=
to_string(idx) +
" out of valid range [" +
912 last_error_token = expression_tokens[i];
916 variant tmp(std::string(1, value_stack.top().get_str()[idx]));
918 value_stack.push(tmp);
921 last_error =
"applied list access operator to non list type";
922 last_error_token = expression_tokens[i];
931 if (!compress_stack_evaluate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
932 last_error_token = expression_tokens[i];
936 expression_stack.push_back(expr_stack_entry((
unsigned int)value_stack.size(), (
unsigned int)operator_stack.size()));
937 parenthesis_stack.push_back(EP_COMMA);
941 if (!compress_stack_evaluate(-1, expression_stack, parenthesis_stack, value_stack, operator_stack)) {
942 last_error_token =
token(expression_tokens.front().begin, expression_tokens.back().end);
946 result = value_stack.top();
948 std::cout <<
"expression evaluated to " << result.
get_str() << std::endl;
952 bool expression_processor::compress_stack_evaluate(
int priority, std::vector<expr_stack_entry>& expression_stack,
953 std::vector<ExpressionPart>& parenthesis_stack,
954 std::stack<variant>& value_stack, std::stack<OperatorType>& operator_stack)
956 while (!found_error && !operator_stack.empty()) {
957 OperatorType ot = operator_stack.top();
958 if (priority > get_operator_priority(ot))
960 if (priority == get_operator_priority(ot) &&
961 get_operator_precedence(ot) == OP_RIGHT)
963 switch (get_operator_arity(ot)) {
965 if (!expression_stack.empty() && operator_stack.size() <= expression_stack.back().second)
967 if (!value_stack.top().unary_check_defined(operator_stack.top())) {
968 last_error = std::string(
"applied unary operator ") +
969 get_operator_word(operator_stack.top()) +
" to undefined value";
972 else if (!value_stack.top().is_unary_applicable(operator_stack.top())) {
973 last_error = std::string(
"could not apply unary operator ") +
974 get_operator_word(ot);
978 value_stack.top().apply_unary(operator_stack.top());
979 if (check_cyclic_reference(&value_stack.top())) {
980 last_error = std::string(
"generated cyclic reference");
984 std::cout <<
"applied unary operator " << get_operator_word(operator_stack.top()) << std::endl;
986 operator_stack.pop();
989 if (!expression_stack.empty() && operator_stack.size() <= expression_stack.back().second)
992 variant v2 = value_stack.top();
994 if (!value_stack.top().is_binary_applicable(operator_stack.top(), v2)) {
995 last_error = std::string(
"could not apply binary operator ") +
996 get_operator_word(ot);
999 if (!value_stack.top().binary_check_defined(operator_stack.top(), v2)) {
1000 last_error = std::string(
"applied binary operator ") +
1001 get_operator_word(operator_stack.top()) +
" to undefined value";
1004 value_stack.top().apply_binary(operator_stack.top(), v2);
1005 if (check_cyclic_reference(&value_stack.top())) {
1006 last_error = std::string(
"generated cyclic reference");
1010 std::cout <<
"applied binary operator " << get_operator_word(operator_stack.top()) << std::endl;
1011 operator_stack.pop();
1016 return !found_error;
1019 bool expression_processor::compress_stack_validate(
int priority, std::vector<expr_stack_entry>& expression_stack,
1020 std::vector<ExpressionPart>& parenthesis_stack,
1021 std::stack<variant>& value_stack, std::stack<OperatorType>& operator_stack)
1023 while (!operator_stack.empty()) {
1024 OperatorType ot = operator_stack.top();
1025 if (priority > get_operator_priority(ot))
1027 if (priority == get_operator_priority(ot) &&
1028 get_operator_precedence(ot) == OP_RIGHT)
1030 switch (get_operator_arity(ot)) {
1032 if (!expression_stack.empty() && operator_stack.size() <= expression_stack.back().second)
1034 if (value_stack.empty()) {
1035 last_error = std::string(
"no value to apply unary operator ") +
1036 get_operator_word(ot);
1039 operator_stack.pop();
1042 if (!expression_stack.empty() && operator_stack.size() <= expression_stack.back().second)
1044 if (value_stack.size() < 2) {
1045 last_error = std::string(
"no 2 values to apply binary operator ") +
1046 get_operator_word(ot);
1050 variant v2 = value_stack.top();
1052 operator_stack.pop();
1060 const std::string& expression_processor::get_last_error()
const
1065 const token& expression_processor::get_last_error_token()
const
1067 return last_error_token;
bool evaluate(variant &result, ph_processor *ph_proc)
bool validate(bool allow_several_values=false)
the pre header processor parses a pre header file and converts it to a header file or uses the inform...
std::string get_str() const
lookup names and follow references and convert to string
const std::string & get_element_name(unsigned int i) const
return the name of the i-th element in a map
bool is_int() const
lookup names and follow references and return whether variant is int
int get_int() const
lookup names and follow references and convert to int: undef ... -1, bool ... 0 or 1,...
func_type & ref_func()
access to func value
bool is_func() const
lookup names and follow references and return whether variant is func
variant & ref_value()
lookup names and follow references and return reference to the reached variant
const variant & get_element(unsigned int i) const
return a const reference to the i-th element in a list or map
bool is_str() const
lookup names and follow references and return whether variant is string
the tokenizer allows to split text into tokens in a convenient way.
namespace that holds tools that dont fit any other namespace
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
std::string interpret_special(const std::string &s)
interprets the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?,...
bool is_integer(const char *begin, const char *end, int &value)
check if the text range (begin,end( defines an integer value. If yes, store the value in the passed r...
void bite_all(tokenizer &t, std::vector< token > &result)
bite all tokens into a token vector
bool is_double(const char *begin, const char *end, double &value)
check if the text range (begin,end( defines a double value. If yes, store the value in the passed ref...
bool is_element(char c, const std::string &s)
check if char c arises in string s
Helper functions to process strings.
representation of a token in a text by two pointers begin and end, that point to the first character ...