Index: tools/testing/dart/status_expression.dart |
diff --git a/tools/testing/dart/status_expression.dart b/tools/testing/dart/status_expression.dart |
deleted file mode 100644 |
index e4713ba7c2a7f38247e576649bc2aff3b0ed27af..0000000000000000000000000000000000000000 |
--- a/tools/testing/dart/status_expression.dart |
+++ /dev/null |
@@ -1,292 +0,0 @@ |
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-import 'environment.dart'; |
- |
-/// A parsed Boolean expression AST. |
-abstract class Expression { |
- /// Parses Boolean expressions in a .status file for Dart. |
- /// |
- /// The grammar is: |
- /// |
- /// expression := or |
- /// or := and ( "||" and )* |
- /// and := primary ( "&&" primary )* |
- /// primary := "$" identifier ( "==" | "!=" ) identifier | |
- /// "!"? "$" identifier | |
- /// "(" expression ")" |
- /// identifier := regex "\w+" |
- /// |
- /// Expressions evaluate as expected, with values of variables found in an |
- /// environment passed to the evaluator. |
- static Expression parse(String expression) => |
- new _ExpressionParser(expression).parse(); |
- |
- /// Validates that this expression does not contain any invalid uses of |
- /// variables. |
- /// |
- /// Ensures that any variable names are known and that any literal values are |
- /// allowed for their corresponding variable. If an invalid variable or value |
- /// is found, adds appropriate error messages to [errors]. |
- void validate(List<String> errors); |
- |
- /// Evaluates the expression where all variables are defined by the given |
- /// [environment]. |
- bool evaluate(Environment environment); |
-} |
- |
-/// Keyword token strings. |
-class _Token { |
- static const leftParen = "("; |
- static const rightParen = ")"; |
- static const dollar = r"$"; |
- static const equals = "=="; |
- static const notEqual = "!="; |
- static const and = "&&"; |
- static const or = "||"; |
- static const not = "!"; |
-} |
- |
-/// A reference to a variable. |
-class _Variable { |
- final String name; |
- |
- _Variable(this.name); |
- |
- String lookup(Environment environment) { |
- var value = environment.lookUp(name); |
- if (value == null) { |
- throw new Exception("Could not find '$name' in environment " |
- "while evaluating status file expression."); |
- } |
- |
- // Explicitly stringify all values so that things like: |
- // |
- // $strong == true |
- // |
- // work correctly even though "true" is treated as a string here. |
- // TODO(rnystrom): Is there a cleaner/safer way to do this? |
- return value.toString(); |
- } |
-} |
- |
-/// Tests whether a given variable is or is not equal some literal value, as in: |
-/// ``` |
-/// $variable == someValue |
-/// ``` |
-/// Negate the result if [negate] is true. |
-class _ComparisonExpression implements Expression { |
- final _Variable left; |
- final String right; |
- final bool negate; |
- |
- _ComparisonExpression(this.left, this.right, this.negate); |
- |
- void validate(List<String> errors) { |
- Environment.validate(left.name, right, errors); |
- } |
- |
- bool evaluate(Environment environment) { |
- return negate != (left.lookup(environment) == right); |
- } |
- |
- String toString() => "(\$${left.name} ${negate ? '!=' : '=='} $right)"; |
-} |
- |
-/// A reference to a variable defined in the environment. The expression |
-/// evaluates to true if the variable's stringified value is "true". |
-/// ``` |
-/// $variable |
-/// ``` |
-/// is equivalent to |
-/// ``` |
-/// $variable == true |
-/// ``` |
-/// Negates result if [negate] is true, so |
-/// ``` |
-/// !$variable |
-/// ``` |
-/// is equivalent to |
-/// ``` |
-/// $variable != true |
-/// ``` |
-class _VariableExpression implements Expression { |
- final _Variable variable; |
- final bool negate; |
- |
- _VariableExpression(this.variable, {this.negate = false}); |
- |
- void validate(List<String> errors) { |
- // It must be a Boolean, so it should allow either Boolean value. |
- Environment.validate(variable.name, "true", errors); |
- } |
- |
- bool evaluate(Environment environment) => |
- negate != (variable.lookup(environment) == "true"); |
- |
- String toString() => "(bool ${negate ? "! " : ""}\$${variable.name})"; |
-} |
- |
-/// A logical `||` or `&&` expression. |
-class _LogicExpression implements Expression { |
- /// The operator, `||` or `&&`. |
- final String op; |
- |
- final Expression left; |
- final Expression right; |
- |
- _LogicExpression(this.op, this.left, this.right); |
- |
- void validate(List<String> errors) { |
- left.validate(errors); |
- right.validate(errors); |
- } |
- |
- bool evaluate(Environment environment) => (op == _Token.and) |
- ? left.evaluate(environment) && right.evaluate(environment) |
- : left.evaluate(environment) || right.evaluate(environment); |
- |
- String toString() => "($left $op $right)"; |
-} |
- |
-/// Parser for Boolean expressions in a .status file for Dart. |
-class _ExpressionParser { |
- final _Scanner _scanner; |
- |
- _ExpressionParser(String expression) : _scanner = new _Scanner(expression); |
- |
- Expression parse() { |
- var expression = _parseOr(); |
- |
- // Should consume entire string. |
- if (_scanner.hasMore) { |
- throw new FormatException("Unexpected input after expression"); |
- } |
- |
- return expression; |
- } |
- |
- Expression _parseOr() { |
- var left = _parseAnd(); |
- while (_scanner.match(_Token.or)) { |
- var right = _parseAnd(); |
- left = new _LogicExpression(_Token.or, left, right); |
- } |
- |
- return left; |
- } |
- |
- Expression _parseAnd() { |
- var left = _parsePrimary(); |
- while (_scanner.match(_Token.and)) { |
- var right = _parsePrimary(); |
- left = new _LogicExpression(_Token.and, left, right); |
- } |
- |
- return left; |
- } |
- |
- Expression _parsePrimary() { |
- if (_scanner.match(_Token.leftParen)) { |
- var value = _parseOr(); |
- if (!_scanner.match(_Token.rightParen)) { |
- throw new FormatException("Missing right parenthesis in expression"); |
- } |
- |
- return value; |
- } |
- |
- var negate = false; |
- if (_scanner.match(_Token.not)) { |
- negate = true; |
- } |
- |
- // The only atomic booleans are of the form $variable == value or |
- // of the form $variable. |
- if (!_scanner.match(_Token.dollar)) { |
- throw new FormatException( |
- "Expected \$ in expression, got ${_scanner.current}"); |
- } |
- |
- if (!_scanner.isIdentifier) { |
- throw new FormatException( |
- "Expected identifier in expression, got ${_scanner.current}"); |
- } |
- |
- var left = new _Variable(_scanner.current); |
- _scanner.advance(); |
- |
- if (!negate && |
- (_scanner.current == _Token.equals || |
- _scanner.current == _Token.notEqual)) { |
- var isNotEquals = _scanner.advance() == _Token.notEqual; |
- |
- if (!_scanner.isIdentifier) { |
- throw new FormatException( |
- "Expected value in expression, got ${_scanner.current}"); |
- } |
- |
- var right = _scanner.advance(); |
- return new _ComparisonExpression(left, right, isNotEquals); |
- } else { |
- return new _VariableExpression(left, negate: negate); |
- } |
- } |
-} |
- |
-/// An iterator that allows peeking at the current token. |
-class _Scanner { |
- /// Tokens are "(", ")", "$", "&&", "||", "!", ==", "!=", and (maximal) \w+. |
- static final _testPattern = new RegExp(r"^(?:[()$\w\s]|&&|\|\||==|!=?)+$"); |
- static final _tokenPattern = new RegExp(r"[()$]|&&|\|\||==|!=?|\w+"); |
- |
- /// Pattern that recognizes identifier tokens. |
- /// |
- /// Only checks the first character, since no non-identifier token can start |
- /// with a word character. |
- static final _identifierPattern = new RegExp(r"^\w"); |
- |
- /// The token strings being iterated. |
- final Iterator<String> tokenIterator; |
- |
- String current; |
- |
- _Scanner(String expression) : tokenIterator = tokenize(expression).iterator { |
- advance(); |
- } |
- |
- static List<String> tokenize(String expression) { |
- if (!_testPattern.hasMatch(expression)) { |
- throw new FormatException("Syntax error in '$expression'"); |
- } |
- |
- return _tokenPattern |
- .allMatches(expression) |
- .map((match) => match[0]) |
- .toList(); |
- } |
- |
- bool get hasMore => current != null; |
- |
- /// Returns `true` if the current token is an identifier. |
- // All non-identifier tokens are one or two characters, |
- // so a longer token must be an identifier. |
- bool get isIdentifier => |
- current.length > 2 || _identifierPattern.hasMatch(current); |
- |
- /// If the current token is [token], consumes it and returns `true`. |
- bool match(String token) { |
- if (!hasMore || current != token) return false; |
- |
- advance(); |
- return true; |
- } |
- |
- /// Consumes the current token and returns it. |
- String advance() { |
- var previous = current; |
- current = tokenIterator.moveNext() ? tokenIterator.current : null; |
- return previous; |
- } |
-} |