diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2019-01-05 13:43:39 -0600 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2019-10-11 17:14:45 -0500 |
| commit | 785eb144322f8d77c3697ccc30cf98fc231ed239 (patch) | |
| tree | adbf921b4aec6f71467ae21d33033110bd65f06b /Source/Core/InputCommon/ControlReference/ExpressionParser.cpp | |
| parent | fa75ab404f065670671a614c7839a3f963ef352b (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.cpp | 75 |
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); } |
