Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2017-12-21 19:07:57 +0300
committerbubnikv <bubnikv@gmail.com>2017-12-21 19:07:57 +0300
commit1eef6d35525514a8df4c07cd3fa1cc40783aa15a (patch)
tree92efb6647259fb801ce90bc103455ea3a184fadc /xs/src/libslic3r
parentf5160b7a72dcb9305e6220a88092e3bd1032387e (diff)
Improved error reporting of the PlaceholderParser.
Diffstat (limited to 'xs/src/libslic3r')
-rw-r--r--xs/src/libslic3r/PlaceholderParser.cpp59
1 files changed, 50 insertions, 9 deletions
diff --git a/xs/src/libslic3r/PlaceholderParser.cpp b/xs/src/libslic3r/PlaceholderParser.cpp
index bcd011da2..b91f4c99c 100644
--- a/xs/src/libslic3r/PlaceholderParser.cpp
+++ b/xs/src/libslic3r/PlaceholderParser.cpp
@@ -3,6 +3,7 @@
#include <ctime>
#include <iomanip>
#include <sstream>
+#include <map>
#ifdef _MSC_VER
#include <stdlib.h> // provides **_environ
#else
@@ -520,6 +521,9 @@ namespace client
bool just_boolean_expression = false;
std::string error_message;
+ // Table to translate symbol tag to a human readable error message.
+ static std::map<std::string, std::string> tag_to_error_message;
+
static void evaluate_full_macro(const MyContext *ctx, bool &result) { result = ! ctx->just_boolean_expression; }
const ConfigOption* resolve_symbol(const std::string &opt_key) const
@@ -707,9 +711,16 @@ namespace client
msg += ": ";
msg += info.tag.substr(1);
} else {
- // A generic error report based on the nonterminal or terminal symbol name.
- msg += ". Expecting tag ";
- msg += info.tag;
+ auto it = tag_to_error_message.find(info.tag);
+ if (it == tag_to_error_message.end()) {
+ // A generic error report based on the nonterminal or terminal symbol name.
+ msg += ". Expecting tag ";
+ msg += info.tag;
+ } else {
+ // Use the human readable error message.
+ msg += ". ";
+ msg + it->second;
+ }
}
msg += '\n';
msg += error_line;
@@ -720,6 +731,31 @@ namespace client
}
};
+ // Table to translate symbol tag to a human readable error message.
+ std::map<std::string, std::string> MyContext::tag_to_error_message = {
+ { "eoi", "Unknown syntax error" },
+ { "start", "Unknown syntax error" },
+ { "text", "Invalid text." },
+ { "text_block", "Invalid text block." },
+ { "macro", "Invalid macro." },
+ { "if_else_output", "Not an {if}{else}{endif} macro." },
+ { "switch_output", "Not a {switch} macro." },
+ { "legacy_variable_expansion", "Expecting a legacy variable expansion format" },
+ { "identifier", "Expecting an identifier." },
+ { "conditional_expression", "Expecting a conditional expression." },
+ { "logical_or_expression", "Expecting a boolean expression." },
+ { "logical_and_expression", "Expecting a boolean expression." },
+ { "equality_expression", "Expecting an expression." },
+ { "bool_expr_eval", "Expecting a boolean expression."},
+ { "relational_expression", "Expecting an expression." },
+ { "additive_expression", "Expecting an expression." },
+ { "multiplicative_expression", "Expecting an expression." },
+ { "unary_expression", "Expecting an expression." },
+ { "scalar_variable_reference", "Expecting a scalar variable reference."},
+ { "variable_reference", "Expecting a variable reference."},
+ { "regular_expression", "Expecting a regular expression."}
+ };
+
// For debugging the boost::spirit parsers. Print out the string enclosed in it_range.
template<typename Iterator>
std::ostream& operator<<(std::ostream& os, const boost::iterator_range<Iterator> &it_range)
@@ -822,7 +858,8 @@ namespace client
spirit::int_type int_;
spirit::double_type double_;
spirit::ascii::string_type string;
- spirit::repository::qi::iter_pos_type iter_pos;
+ spirit::eoi_type eoi;
+ spirit::repository::qi::iter_pos_type iter_pos;
auto kw = spirit::repository::qi::distinct(qi::copy(alnum | '_'));
qi::_val_type _val;
@@ -843,7 +880,7 @@ namespace client
start = eps[px::bind(&MyContext::evaluate_full_macro, _r1, _a)] >
( eps(_a==true) > text_block(_r1) [_val=_1]
| conditional_expression(_r1) [ px::bind(&expr<Iterator>::evaluate_boolean_to_string, _1, _val) ]
- );
+ ) > eoi;
start.name("start");
qi::on_error<qi::fail>(start, px::bind(&MyContext::process_error_message<Iterator>, _r1, _4, _1, _2, _3));
@@ -866,7 +903,7 @@ namespace client
// The macro expansion may contain numeric or string expressions, ifs and cases.
macro =
(kw["if"] > if_else_output(_r1) [_val = _1])
- | (kw["switch"] > switch_output(_r1) [_val = _1])
+// | (kw["switch"] > switch_output(_r1) [_val = _1])
| additive_expression(_r1) [ px::bind(&expr<Iterator>::to_string2, _1, _val) ];
macro.name("macro");
@@ -908,14 +945,17 @@ namespace client
conditional_expression =
logical_or_expression(_r1) [_val = _1]
>> -('?' > conditional_expression(_r1) > ':' > conditional_expression(_r1)) [px::bind(&expr<Iterator>::ternary_op, _val, _1, _2)];
+ conditional_expression.name("conditional_expression");
logical_or_expression =
logical_and_expression(_r1) [_val = _1]
>> *( ((kw["or"] | "||") > logical_and_expression(_r1) ) [px::bind(&expr<Iterator>::logical_or, _val, _1)] );
+ logical_or_expression.name("logical_or_expression");
logical_and_expression =
equality_expression(_r1) [_val = _1]
>> *( ((kw["and"] | "&&") > equality_expression(_r1) ) [px::bind(&expr<Iterator>::logical_and, _val, _1)] );
+ logical_and_expression.name("logical_and_expression");
equality_expression =
relational_expression(_r1) [_val = _1]
@@ -939,6 +979,7 @@ namespace client
| ("<=" > additive_expression(_r1) ) [px::bind(&expr<Iterator>::leq, _val, _1)]
| (">=" > additive_expression(_r1) ) [px::bind(&expr<Iterator>::geq, _val, _1)]
);
+ relational_expression.name("relational_expression");
additive_expression =
multiplicative_expression(_r1) [_val = _1]
@@ -1020,7 +1061,7 @@ namespace client
debug(text_block);
debug(macro);
debug(if_else_output);
- debug(switch_output);
+// debug(switch_output);
debug(legacy_variable_expansion);
debug(identifier);
debug(conditional_expression);
@@ -1079,7 +1120,7 @@ namespace client
qi::rule<Iterator, OptWithPos<Iterator>(const MyContext*), spirit::ascii::space_type> variable_reference;
qi::rule<Iterator, std::string(const MyContext*), qi::locals<bool, bool>, spirit::ascii::space_type> if_else_output;
- qi::rule<Iterator, std::string(const MyContext*), qi::locals<expr<Iterator>, bool, std::string>, spirit::ascii::space_type> switch_output;
+// qi::rule<Iterator, std::string(const MyContext*), qi::locals<expr<Iterator>, bool, std::string>, spirit::ascii::space_type> switch_output;
qi::symbols<char> keywords;
};
@@ -1102,7 +1143,7 @@ static std::string process_macro(const std::string &templ, client::MyContext &co
// Accumulator for the processed template.
std::string output;
bool res = phrase_parse(iter, end, macro_processor_instance(&context), space, output);
- if (! context.error_message.empty()) {
+ if (!context.error_message.empty()) {
if (context.error_message.back() != '\n' && context.error_message.back() != '\r')
context.error_message += '\n';
throw std::runtime_error(context.error_message);