summaryrefslogtreecommitdiffstats
path: root/src/util/expression-evaluator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/expression-evaluator.h')
-rw-r--r--src/util/expression-evaluator.h86
1 files changed, 71 insertions, 15 deletions
diff --git a/src/util/expression-evaluator.h b/src/util/expression-evaluator.h
index 4b1065268..b9566e722 100644
--- a/src/util/expression-evaluator.h
+++ b/src/util/expression-evaluator.h
@@ -6,6 +6,7 @@
* Copyright (C) 2008-2009 Martin Nordholts <martinn@svn.gnome.org>
* Modified for Inkscape by Johan Engelen
* Copyright (C) 2011 Johan Engelen
+ * Copyright (C) 2013 Matthew Petroff
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,8 +23,8 @@
* <http://www.gnu.org/licenses/>.
*/
-#ifndef SEEN_GIMP_EEVL_H
-#define SEEN_GIMP_EEVL_H
+#ifndef INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H
+#define INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H
#include "util/units.h"
@@ -79,37 +80,92 @@ namespace Util {
class Unit;
/**
-* GimpEevlQuantity:
+* EvaluatorQuantity:
* @value: In reference units.
-* @dimension: in has a dimension of 1, in^2 has a dimension of 2 etc
+* @dimension: mm has a dimension of 1, mm^2 has a dimension of 2, etc.
*/
-typedef struct
+class EvaluatorQuantity
{
+public:
+ EvaluatorQuantity(double value = 0, unsigned int dimension = 0);
+
double value;
- gint dimension;
-} GimpEevlQuantity;
+ unsigned int dimension;
+};
-typedef bool (* GimpEevlUnitResolverProc) (const gchar *identifier,
- GimpEevlQuantity *result,
- Unit* unit);
+enum {
+ TOKEN_NUM = 30000,
+ TOKEN_IDENTIFIER = 30001,
+ TOKEN_ANY = 40000,
+ TOKEN_END = 50000
+};
+typedef int TokenType;
-GimpEevlQuantity gimp_eevl_evaluate (const gchar* string, Unit* unit = NULL);
+class EvaluatorToken
+{
+public:
+ EvaluatorToken();
+
+ TokenType type;
+
+ union {
+ double fl;
+ struct {
+ const char *c;
+ int size;
+ };
+ } value;
+};
+
+class ExpressionEvaluator
+{
+public:
+ ExpressionEvaluator(const char *string, Unit *unit = NULL);
+
+ EvaluatorQuantity evaluate();
+
+private:
+ const char *string;
+ Unit *unit;
+
+ EvaluatorToken current_token;
+ const char *start_of_current_token;
+
+ EvaluatorQuantity evaluateExpression();
+ EvaluatorQuantity evaluateTerm();
+ EvaluatorQuantity evaluateSignedFactor();
+ EvaluatorQuantity evaluateFactor();
+
+ bool acceptToken(TokenType token_type, EvaluatorToken *consumed_token);
+ void parseNextToken();
+ void acceptTokenCount(int count, TokenType token_type);
+ void isExpected(TokenType token_type, EvaluatorToken *value);
+
+ void movePastWhiteSpace();
+
+ static bool isUnitIdentifierStart(gunichar c);
+ static int getIdentifierSize(const char *s, int start);
+
+ static bool resolveUnit(const char *identifier, EvaluatorQuantity *result, Unit *unit);
+
+ void throwError(const char *msg);
+};
/**
* Special exception class for the expression evaluator.
*/
class EvaluatorException : public std::exception {
public:
- EvaluatorException(const char * message, const char *at_position) {
+ EvaluatorException(const char *message, const char *at_position) {
std::ostringstream os;
- const char* token = at_position ? at_position : "<End of input>";
+ const char *token = at_position ? at_position : "<End of input>";
os << "Expression evaluator error: " << message << " at '" << token << "'";
msgstr = os.str();
}
virtual ~EvaluatorException() throw() {} // necessary to destroy the string object!!!
- virtual const char* what() const throw () {
+ virtual const char *what() const throw () {
return msgstr.c_str();
}
protected:
@@ -119,4 +175,4 @@ protected:
}
}
-#endif // SEEN_GIMP_EEVL_H
+#endif // INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H