MCPcopy Create free account
hub / github.com/boutproject/BOUT-dev / parseIdentifierExpr

Method parseIdentifierExpr

src/sys/expressionparser.cxx:308–435  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

306}
307
308FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo& lex) const {
309 // Make a nice error message if we couldn't find the identifier
310 const auto generatorNotFoundErrorMessage = [&](const std::string& name) -> std::string {
311 const std::string message_template = _(
312 R"(Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so you
313may need to change your input file.
314{})");
315
316 // Start position of the current identifier: by this point, we've either
317 // moved one character past the token, or we're still at the start
318 const auto start =
319 std::max(std::stringstream::off_type{0},
320 lex.ss.tellg() - std::stringstream::pos_type(lex.curident.length() + 1));
321
322 // Try to put a nice little '^~~~~' underlining the problem
323 // identifier. NOTE: this will be longer than required for multibyte UTF-8
324 // characters, but will still point to the start of the identifier
325 const std::string problem_bit =
326 fmt::format(" {0}\n {1: >{2}}{3:~^{4}}", lex.ss.str(), "^", start, "",
327 lex.curident.length() - 1);
328
329 auto possible_matches = fuzzyFind(name);
330 // Remove exact matches -- not helpful
331 bout::utils::erase_if(possible_matches,
332 [](const auto& match) -> bool { return match.distance == 0; });
333
334 // No matches, just point out the error
335 if (possible_matches.empty()) {
336 return fmt::format(message_template, name, problem_bit);
337 }
338
339 // Give the first suggestion as a possible alternative
340 std::string error_message = fmt::format(message_template, name, problem_bit);
341 error_message += fmt::format(_("\n {1: ^{2}}{0}\n Did you mean '{0}'?"),
342 possible_matches.begin()->name, "", start);
343 return error_message;
344 };
345
346 string name = lex.curident;
347 lex.nextToken();
348
349 // sum(symbol, count, expr)
350 // e.g. sum(i, 10, {i}^2) -> 0 + 1^2 + 2^2 + 3^2 + ... + 9^2
351 if (name == "sum") {
352 if (lex.curtok != '(') {
353 throw ParseException("Expecting '(' after 'sum' in 'sum(symbol, count, expr)'");
354 }
355 lex.nextToken();
356
357 if ((lex.curtok != -2) && (lex.curtok != -3)) {
358 throw ParseException("Expecting symbol in 'sum(symbol, count, expr)'");
359 }
360 string sym = lex.curident;
361 lex.nextToken();
362
363 if (lex.curtok != ',') {
364 throw ParseException("Expecting , after symbol {:s} in 'sum(symbol, count, expr)'",
365 sym);

Callers

nothing calls this directly

Calls 4

parseExpressionFunction · 0.85
nextTokenMethod · 0.80
strMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected