Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Unified Diff: tools/testing/dart/status_expression.dart

Issue 2984203002: Move the status file parser into its own package. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/testing/dart/expectation_set.dart ('k') | tools/testing/dart/status_file.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
- }
-}
« no previous file with comments | « tools/testing/dart/expectation_set.dart ('k') | tools/testing/dart/status_file.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698