// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#if NET_2_0
-
using System;
using System.Collections;
using System.Collections.Generic;
internal class ConditionParser {
ConditionTokenizer tokenizer;
+ string conditionStr;
ConditionParser (string condition)
{
tokenizer = new ConditionTokenizer ();
tokenizer.Tokenize (condition);
+ conditionStr = condition;
}
public static bool ParseAndEvaluate (string condition, Project context)
if (String.IsNullOrEmpty (condition))
return true;
- ConditionExpression ce = ParseCondition (condition);
+ try {
+ ConditionExpression ce = ParseCondition (condition);
- if (!ce.CanEvaluateToBool (context))
- throw new InvalidProjectFileException (String.Format ("Can not evaluate \"{0}\" to bool.", condition));
+ if (!ce.CanEvaluateToBool (context))
+ throw new InvalidProjectFileException (String.Format ("Can not evaluate \"{0}\" to bool.", condition));
- return ce.BoolEvaluate (context);
+ return ce.BoolEvaluate (context);
+ } catch (ExpressionParseException epe) {
+ throw new InvalidProjectFileException (
+ String.Format ("Unable to parse condition \"{0}\" : {1}", condition, epe.Message),
+ epe);
+ } catch (ExpressionEvaluationException epe) {
+ throw new InvalidProjectFileException (
+ String.Format ("Unable to evaluate condition \"{0}\" : {1}", condition, epe.Message),
+ epe);
+ }
}
public static ConditionExpression ParseCondition (string condition)
ConditionExpression e = parser.ParseExpression ();
if (!parser.tokenizer.IsEOF ())
- throw new ExpressionParseException (String.Format ("Unexpected token at end of condition: \"{0}\"", parser.tokenizer.Token.Value));
+ throw new ExpressionParseException (String.Format ("Unexpected token found, {0}, in condition \"{1}\"", parser.tokenizer.Token, condition));
return e;
}
{
return ParseBooleanAnd ();
}
+
+ public static string And (string a, string b)
+ {
+ return a + " and " + b;
+ }
ConditionExpression ParseBooleanAnd ()
{
e = new ConditionFactorExpression (token);
} else if (token.Type == TokenType.Number) {
e = new ConditionFactorExpression (token);
- } else if (token.Type == TokenType.Item) {
- throw new NotImplementedException ();
- } else if (token.Type == TokenType.Property) {
- throw new NotImplementedException ();
+ } else if (token.Type == TokenType.Item || token.Type == TokenType.Property
+ || token.Type == TokenType.Metadata) {
+ e = ParseReferenceExpression (token.Value);
} else if (token.Type == TokenType.Not) {
e = ParseNotExpression ();
} else
- throw new ExpressionParseException (String.Format ("Unexpected token type {0}.", token.Type));
+ throw new ExpressionParseException (String.Format ("Unexpected token {0}, while parsing condition \"{1}\"", token, conditionStr));
return e;
}
return list;
}
+
+ //@prefix: @ or $
+ ConditionExpression ParseReferenceExpression (string prefix)
+ {
+ StringBuilder sb = new StringBuilder ();
+
+ string ref_type = prefix [0] == '$' ? "a property" : "an item list";
+ int token_pos = tokenizer.Token.Position;
+ IsAtToken (TokenType.LeftParen, String.Format (
+ "Expected {0} at position {1} in condition \"{2}\". Missing opening parantheses after the '{3}'.",
+ ref_type, token_pos, conditionStr, prefix));
+ tokenizer.GetNextToken ();
+
+ sb.AppendFormat ("{0}({1}", prefix, tokenizer.Token.Value);
+
+ tokenizer.GetNextToken ();
+ if (prefix == "@" && tokenizer.Token.Type == TokenType.Transform) {
+ tokenizer.GetNextToken ();
+ sb.AppendFormat ("->'{0}'", tokenizer.Token.Value);
+
+ tokenizer.GetNextToken ();
+ if (tokenizer.Token.Type == TokenType.Comma) {
+ tokenizer.GetNextToken ();
+ sb.AppendFormat (", '{0}'", tokenizer.Token.Value);
+ tokenizer.GetNextToken ();
+ }
+ }
+
+ IsAtToken (TokenType.RightParen, String.Format (
+ "Expected {0} at position {1} in condition \"{2}\". Missing closing parantheses'.",
+ ref_type, token_pos, conditionStr, prefix));
+ tokenizer.GetNextToken ();
+
+ sb.Append (")");
+
+ //FIXME: HACKY!
+ return new ConditionFactorExpression (new Token (sb.ToString (), TokenType.String, token_pos));
+ }
+
+ // used to check current token type
+ void IsAtToken (TokenType type, string error_msg)
+ {
+ if (tokenizer.Token.Type != type) {
+ if (!String.IsNullOrEmpty (error_msg))
+ throw new ExpressionParseException (error_msg);
+
+ if (tokenizer.Token.Type == TokenType.EOF)
+ throw new ExpressionParseException (String.Format (
+ "Expected a \"{0}\" but the condition ended abruptly, while parsing condition \"{1}\"",
+ Token.TypeAsString (type), conditionStr));
+
+ throw new ExpressionParseException (String.Format (
+ "Expected \"{0}\" token, but got {1}, while parsing \"{2}\"",
+ Token.TypeAsString (type), tokenizer.Token, conditionStr));
+ }
+ }
}
}
-
-#endif