summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-01-05 13:43:39 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-10-11 17:14:45 -0500
commit785eb144322f8d77c3697ccc30cf98fc231ed239 (patch)
treeadbf921b4aec6f71467ae21d33033110bd65f06b /Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
parentfa75ab404f065670671a614c7839a3f963ef352b (diff)
ExpressionParser: Clean up string lexing and support numeric literals without tick delimiter: e.g. 0.75
Diffstat (limited to 'Source/Core/InputCommon/ControlReference/ExpressionParser.cpp')
-rw-r--r--Source/Core/InputCommon/ControlReference/ExpressionParser.cpp75
1 files changed, 34 insertions, 41 deletions
diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
index a5c4036167..af3b9c6fd3 100644
--- a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
+++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
@@ -7,6 +7,7 @@
#include <chrono>
#include <cmath>
#include <iostream>
+#include <locale>
#include <map>
#include <memory>
#include <regex>
@@ -155,72 +156,62 @@ public:
Lexer(const std::string& expr_) : expr(expr_) { it = expr.begin(); }
- bool FetchDelimString(std::string& value, char delim)
+ template <typename F>
+ std::string FetchCharsWhile(F&& func)
{
- value = "";
- while (it != expr.end())
+ std::string value;
+ while (it != expr.end() && func(*it))
{
- char c = *it;
+ value += *it;
++it;
- if (c == delim)
- return true;
- value += c;
}
- return false;
+ return value;
}
- std::string FetchWordChars()
+ std::string FetchDelimString(char delim)
{
- std::string word;
-
- std::regex valid_name_char("[a-z0-9_]", std::regex_constants::icase);
+ const std::string result = FetchCharsWhile([delim](char c) { return c != delim; });
+ ++it;
+ return result;
+ }
- while (it != expr.end() && std::regex_match(std::string(1, *it), valid_name_char))
- {
- word += *it;
- ++it;
- }
+ std::string FetchWordChars()
+ {
+ // Valid word characters:
+ std::regex rx("[a-z0-9_]", std::regex_constants::icase);
- return word;
+ return FetchCharsWhile([&rx](char c) { return std::regex_match(std::string(1, c), rx); });
}
Token GetUnaryFunction() { return Token(TOK_UNARY, FetchWordChars()); }
- Token GetLiteral()
- {
- std::string value;
- FetchDelimString(value, '\'');
- return Token(TOK_LITERAL, value);
- }
+ Token GetDelimitedLiteral() { return Token(TOK_LITERAL, FetchDelimString('\'')); }
Token GetVariable() { return Token(TOK_VARIABLE, FetchWordChars()); }
- Token GetFullyQualifiedControl()
- {
- std::string value;
- FetchDelimString(value, '`');
- return Token(TOK_CONTROL, value);
- }
+ Token GetFullyQualifiedControl() { return Token(TOK_CONTROL, FetchDelimString('`')); }
Token GetBarewordsControl(char c)
{
std::string name;
name += c;
-
- while (it != expr.end())
- {
- c = *it;
- if (!isalpha(c))
- break;
- name += c;
- ++it;
- }
+ name += FetchCharsWhile([](char c) { return std::isalpha(c, std::locale::classic()); });
ControlQualifier qualifier;
qualifier.control_name = name;
return Token(TOK_CONTROL, qualifier);
}
+ Token GetRealLiteral(char c)
+ {
+ std::string value;
+ value += c;
+ value +=
+ FetchCharsWhile([](char c) { return isdigit(c, std::locale::classic()) || ('.' == c); });
+
+ return Token(TOK_LITERAL, value);
+ }
+
Token NextToken()
{
if (it == expr.end())
@@ -265,14 +256,16 @@ public:
case ',':
return Token(TOK_COMMA);
case '\'':
- return GetLiteral();
+ return GetDelimitedLiteral();
case '$':
return GetVariable();
case '`':
return GetFullyQualifiedControl();
default:
- if (isalpha(c))
+ if (isalpha(c, std::locale::classic()))
return GetBarewordsControl(c);
+ else if (isdigit(c, std::locale::classic()))
+ return GetRealLiteral(c);
else
return Token(TOK_INVALID);
}