Skip to content
Permalink
Browse files

ExpressionParser: Clean up string lexing and support numeric literals…

… without tick delimiter: e.g. 0.75
  • Loading branch information...
jordan-woyak committed Jan 5, 2019
1 parent fa75ab4 commit 785eb144322f8d77c3697ccc30cf98fc231ed239
Showing with 34 additions and 41 deletions.
  1. +34 −41 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 @@ class Lexer

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 @@ class Lexer
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);
}

0 comments on commit 785eb14

Please sign in to comment.
You can’t perform that action at this time.