mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 19:33:01 +02:00
Changed grammar to support boolean and and or.
This commit is contained in:
parent
2b0ed55077
commit
22756d168b
3 changed files with 39 additions and 43 deletions
|
@ -78,7 +78,15 @@ AnimExpression::Token AnimExpression::consumeIdentifier(const QString& str, QStr
|
||||||
}
|
}
|
||||||
int pos = (int)(begin - str.begin());
|
int pos = (int)(begin - str.begin());
|
||||||
int len = (int)(iter - begin);
|
int len = (int)(iter - begin);
|
||||||
return Token(QStringRef(const_cast<const QString*>(&str), pos, len));
|
|
||||||
|
QStringRef stringRef(const_cast<const QString*>(&str), pos, len);
|
||||||
|
if (stringRef == "true") {
|
||||||
|
return Token(true);
|
||||||
|
} else if (stringRef == "false") {
|
||||||
|
return Token(false);
|
||||||
|
} else {
|
||||||
|
return Token(stringRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: not very efficient or accruate, but it's close enough for now.
|
// TODO: not very efficient or accruate, but it's close enough for now.
|
||||||
|
@ -198,19 +206,19 @@ AnimExpression::Token AnimExpression::consumeNot(const QString& str, QString::co
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Expr → Term Expr'
|
Expr → Term Expr'
|
||||||
Expr' → + Term Expr'
|
Expr' → '||' Term Expr'
|
||||||
| – Term Expr'
|
|
||||||
| ε
|
| ε
|
||||||
Term → Factor Term'
|
Term → Factor Term'
|
||||||
Term' → * Term'
|
Term' → '&&' Term'
|
||||||
| / Term'
|
|
||||||
| ε
|
| ε
|
||||||
Factor → INT
|
Factor → INT
|
||||||
|
| BOOL
|
||||||
| FLOAT
|
| FLOAT
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
| (Expr)
|
| '(' Expr ')'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Expr → Term Expr'
|
||||||
bool AnimExpression::parseExpr(const QString& str, QString::const_iterator& iter) {
|
bool AnimExpression::parseExpr(const QString& str, QString::const_iterator& iter) {
|
||||||
if (!parseTerm(str, iter)) {
|
if (!parseTerm(str, iter)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -221,9 +229,10 @@ bool AnimExpression::parseExpr(const QString& str, QString::const_iterator& iter
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expr' → '||' Term Expr' | ε
|
||||||
bool AnimExpression::parseExprPrime(const QString& str, QString::const_iterator& iter) {
|
bool AnimExpression::parseExprPrime(const QString& str, QString::const_iterator& iter) {
|
||||||
auto token = consumeToken(str, iter);
|
auto token = consumeToken(str, iter);
|
||||||
if (token.type == Token::Plus) {
|
if (token.type == Token::Or) {
|
||||||
if (!parseTerm(str, iter)) {
|
if (!parseTerm(str, iter)) {
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
return false;
|
return false;
|
||||||
|
@ -232,18 +241,7 @@ bool AnimExpression::parseExprPrime(const QString& str, QString::const_iterator&
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_opCodes.push_back(OpCode {OpCode::Add});
|
_opCodes.push_back(OpCode {OpCode::Or});
|
||||||
return true;
|
|
||||||
} else if (token.type == Token::Minus) {
|
|
||||||
if (!parseTerm(str, iter)) {
|
|
||||||
unconsumeToken(token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!parseExprPrime(str, iter)) {
|
|
||||||
unconsumeToken(token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_opCodes.push_back(OpCode {OpCode::Subtract});
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
|
@ -251,6 +249,7 @@ bool AnimExpression::parseExprPrime(const QString& str, QString::const_iterator&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Term → Factor Term'
|
||||||
bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter) {
|
bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter) {
|
||||||
if (!parseFactor(str, iter)) {
|
if (!parseFactor(str, iter)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -261,9 +260,10 @@ bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Term' → '&&' Term' | ε
|
||||||
bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator& iter) {
|
bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator& iter) {
|
||||||
auto token = consumeToken(str, iter);
|
auto token = consumeToken(str, iter);
|
||||||
if (token.type == Token::Multiply) {
|
if (token.type == Token::And) {
|
||||||
if (!parseTerm(str, iter)) {
|
if (!parseTerm(str, iter)) {
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
return false;
|
return false;
|
||||||
|
@ -272,18 +272,7 @@ bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator&
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_opCodes.push_back(OpCode {OpCode::Multiply});
|
_opCodes.push_back(OpCode {OpCode::And});
|
||||||
return true;
|
|
||||||
} else if (token.type == Token::Divide) {
|
|
||||||
if (!parseTerm(str, iter)) {
|
|
||||||
unconsumeToken(token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!parseTermPrime(str, iter)) {
|
|
||||||
unconsumeToken(token);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_opCodes.push_back(OpCode {OpCode::Divide});
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
unconsumeToken(token);
|
unconsumeToken(token);
|
||||||
|
@ -291,11 +280,15 @@ bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Factor → INT | BOOL | FLOAT | IDENTIFIER | '(' Expr ')'
|
||||||
bool AnimExpression::parseFactor(const QString& str, QString::const_iterator& iter) {
|
bool AnimExpression::parseFactor(const QString& str, QString::const_iterator& iter) {
|
||||||
auto token = consumeToken(str, iter);
|
auto token = consumeToken(str, iter);
|
||||||
if (token.type == Token::Int) {
|
if (token.type == Token::Int) {
|
||||||
_opCodes.push_back(OpCode {token.intVal});
|
_opCodes.push_back(OpCode {token.intVal});
|
||||||
return true;
|
return true;
|
||||||
|
} else if (token.type == Token::Bool) {
|
||||||
|
_opCodes.push_back(OpCode {(bool)token.intVal});
|
||||||
|
return true;
|
||||||
} else if (token.type == Token::Float) {
|
} else if (token.type == Token::Float) {
|
||||||
_opCodes.push_back(OpCode {token.floatVal});
|
_opCodes.push_back(OpCode {token.floatVal});
|
||||||
return true;
|
return true;
|
||||||
|
@ -351,7 +344,7 @@ AnimExpression::OpCode AnimExpression::evaluate(const AnimVariantMap& map) const
|
||||||
case OpCode::UnaryMinus: evalUnaryMinus(map, stack); break;
|
case OpCode::UnaryMinus: evalUnaryMinus(map, stack); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack.top();
|
return coerseToValue(map, stack.top());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define POP_BOOL(NAME) \
|
#define POP_BOOL(NAME) \
|
||||||
|
@ -602,8 +595,7 @@ AnimExpression::OpCode AnimExpression::coerseToValue(const AnimVariantMap& map,
|
||||||
const AnimVariant& var = map.get(opCode.strVal);
|
const AnimVariant& var = map.get(opCode.strVal);
|
||||||
switch (var.getType()) {
|
switch (var.getType()) {
|
||||||
case AnimVariant::Type::Bool:
|
case AnimVariant::Type::Bool:
|
||||||
qCWarning(animation) << "AnimExpression: type missmatch, expected a number not a bool";
|
return OpCode((bool)var.getBool());
|
||||||
return OpCode(0);
|
|
||||||
break;
|
break;
|
||||||
case AnimVariant::Type::Int:
|
case AnimVariant::Type::Int:
|
||||||
return OpCode(var.getInt());
|
return OpCode(var.getInt());
|
||||||
|
@ -631,6 +623,7 @@ AnimExpression::OpCode AnimExpression::coerseToValue(const AnimVariantMap& map,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
void AnimExpression::dumpOpCodes() const {
|
void AnimExpression::dumpOpCodes() const {
|
||||||
QString tmp;
|
QString tmp;
|
||||||
for (auto& op : _opCodes) {
|
for (auto& op : _opCodes) {
|
||||||
|
@ -660,3 +653,4 @@ void AnimExpression::dumpOpCodes() const {
|
||||||
qCDebug(animation).nospace().noquote() << "opCodes =" << tmp;
|
qCDebug(animation).nospace().noquote() << "opCodes =" << tmp;
|
||||||
qCDebug(animation).resetFormat();
|
qCDebug(animation).resetFormat();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@ protected:
|
||||||
enum Type {
|
enum Type {
|
||||||
End = 0,
|
End = 0,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
Bool,
|
||||||
Int,
|
Int,
|
||||||
Float,
|
Float,
|
||||||
And,
|
And,
|
||||||
|
@ -50,8 +51,9 @@ protected:
|
||||||
};
|
};
|
||||||
Token(Type type) : type {type} {}
|
Token(Type type) : type {type} {}
|
||||||
Token(const QStringRef& strRef) : type {Type::Identifier}, strVal {strRef.toString()} {}
|
Token(const QStringRef& strRef) : type {Type::Identifier}, strVal {strRef.toString()} {}
|
||||||
Token(int val) : type {Type::Int}, intVal {val} {}
|
explicit Token(int val) : type {Type::Int}, intVal {val} {}
|
||||||
Token(float val) : type {Type::Float}, floatVal {val} {}
|
explicit Token(bool val) : type {Type::Bool}, intVal {val} {}
|
||||||
|
explicit Token(float val) : type {Type::Float}, floatVal {val} {}
|
||||||
Type type {End};
|
Type type {End};
|
||||||
QString strVal;
|
QString strVal;
|
||||||
int intVal {0};
|
int intVal {0};
|
||||||
|
@ -81,11 +83,11 @@ protected:
|
||||||
UnaryMinus
|
UnaryMinus
|
||||||
};
|
};
|
||||||
OpCode(Type type) : type {type} {}
|
OpCode(Type type) : type {type} {}
|
||||||
OpCode(const QStringRef& strRef) : type {Type::Identifier}, strVal {strRef.toString()} {}
|
explicit OpCode(const QStringRef& strRef) : type {Type::Identifier}, strVal {strRef.toString()} {}
|
||||||
OpCode(const QString& str) : type {Type::Identifier}, strVal {str} {}
|
explicit OpCode(const QString& str) : type {Type::Identifier}, strVal {str} {}
|
||||||
OpCode(int val) : type {Type::Int}, intVal {val} {}
|
explicit OpCode(int val) : type {Type::Int}, intVal {val} {}
|
||||||
OpCode(bool val) : type {Type::Bool}, intVal {(int)val} {}
|
explicit OpCode(bool val) : type {Type::Bool}, intVal {(int)val} {}
|
||||||
OpCode(float val) : type {Type::Float}, floatVal {val} {}
|
explicit OpCode(float val) : type {Type::Float}, floatVal {val} {}
|
||||||
|
|
||||||
bool coerceBool(const AnimVariantMap& map) const {
|
bool coerceBool(const AnimVariantMap& map) const {
|
||||||
if (type == Int || type == Bool) {
|
if (type == Int || type == Bool) {
|
||||||
|
|
|
@ -274,7 +274,7 @@ struct ByteData {
|
||||||
|
|
||||||
QTextStream & operator << (QTextStream& stream, const ByteData & wrapper) {
|
QTextStream & operator << (QTextStream& stream, const ByteData & wrapper) {
|
||||||
// Print bytes as hex
|
// Print bytes as hex
|
||||||
stream << QByteArray::fromRawData(wrapper.data, wrapper.length).toHex();
|
stream << QByteArray::fromRawData(wrapper.data, (int)wrapper.length).toHex();
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue