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

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

Issue 8394043: Start adding files for Dart version of test script test.py. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 2 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
Index: tools/testing/dart/status_expressions_lib.dart
diff --git a/tools/testing/dart/status_expressions_lib.dart b/tools/testing/dart/status_expressions_lib.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0bd31d2191e82807ad4f657d65c08fa402ce9897
--- /dev/null
+++ b/tools/testing/dart/status_expressions_lib.dart
@@ -0,0 +1,264 @@
+// 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.
+
+#library("status_expressions");
+
+/**
+ * Parse and evaluate expressions in a .status file for Dart and V8.
ngeoffray 2011/10/26 12:01:37 Extra space.
+ * There are set expressions and Boolean expressions in a .status file.
+ * The grammar is:
+ * BooleanExpression := $variable_name == value |
+ * (BooleanExpression) |
+ * BooleanExpression && BooleanExpression |
+ * BooleanExpression || BooleanExpression
+ *
+ * SetExpression := value | (SetExpression) |
+ * SetExpression || SetExpression |
+ * SetExpression if BooleanExpression |
+ * SetExpression , SetExpression
+ *
+ * Production are listed in order of precedence, and the || and , operators
Mads Ager (google) 2011/10/26 12:37:47 Remove the extra leading space starting from here
+ * both evaluate to set union, but with different precedence.
+ *
+ * Values and names are non-empty strings of word characters, matching
+ * the RegExp \w+.
+ *
+ * Expressions evaluate as expected, with values of variables found in
+ * an environment passed to the evaluator. The SetExpression "value"
+ * evaluates to a singleton set containing that value. "A if B" evaluates
+ * to A if B is true, and to the empty set if B is false.
+ */
+
+class Tokenizer {
+ String expression;
+ List<String> tokens;
+
+ Tokenizer(String this.expression)
Søren Gjesse 2011/10/26 13:36:24 Fit on one line?
+ : tokens = new List<String>();
+
+ /**
+ * Tokens are : "&&", "||", "==", "$", "(", ")", ",", and (maximal) \w+.
Søren Gjesse 2011/10/26 13:36:24 Maybe list the tokens in the same order as they ar
+ */
+ static final test_regexp =
+ const RegExp(@"^([()$\w\s,]|(\&\&)|(\|\|)|(\=\=))+$");
+ static final regexp = const RegExp(@"[()$,]|(\&\&)|(\|\|)|(\=\=)|\w+");
+
+ void tokenize() {
+ if (!test_regexp.hasMatch(expression)) {
+ throw new ExpectException("Syntax error in '" + expression + '"');
+ }
+ for (Match match in regexp.allMatches(expression)) tokens.add(match[0]);
+ }
+}
+
+
+interface BooleanExpression {
+ bool evaluate(Map<String, String> environment);
+}
+
+
+interface SetExpression {
+ // A set of test outcomes.
Mads Ager (google) 2011/10/26 12:37:47 Please update the comment here to actually describ
+ Set<String> evaluate(Map<String, String> environment);
+}
+
+
+class Comparison implements BooleanExpression {
+ Variable left;
+ TermConstant right;
+
+ Comparison(this.left, this.right);
+
+ bool evaluate(environment) => left.termValue() == right.termValue();
+ String toString() => "==(\$${left.name}, ${right.value})";
Mads Ager (google) 2011/10/26 12:37:47 Why not just "(\$${left.name} == ${right.value})"?
+}
+
+class Variable {
+ String name;
+ Variable(String this.name);
+
+ String termValue(environment) => environment[name];
+}
+
+class TermConstant {
+ String value;
+ TermConstant(String this.value);
+
+ String termValue(environment) => value;
+}
+
+
+class BooleanOperation implements BooleanExpression {
+ String op;
+ BooleanExpression left;
+ BooleanExpression right;
+
+ BooleanOperation(this.op, this.left, this.right);
+
+ bool evaluate(environment) => (op == "&&") ?
+ left.evaluate(environment) && right.evaluate(environment) :
+ left.evaluate(environment) || right.evaluate(environment);
+ String toString() => "$op(${left.toString()},${right.toString()})";
Mads Ager (google) 2011/10/26 12:37:47 I would go for infix here and in the rest.
+}
+
+class SetUnion implements SetExpression {
+ SetExpression left;
+ SetExpression right;
+
+ SetUnion(this.left, this.right);
+
+ // Overwrites left.evaluate(env).
+ Set<String> evaluate(environment) =>
+ left.evaluate(environment).addAll(right.evaluate(environment));
+ String toString() => "||(${left.toString()},${right.toString()})";
+}
+
+class SetIf implements SetExpression {
+ SetExpression left;
+ BooleanExpression right;
+
+ SetIf(this.left, this.right);
+
+ Set<String> evaluate(environment) => right.evaluate(environment) ?
+ left.evaluate(environment) : new Set<String>();
+ String toString() => "if(${left.toString()},${right.toString()})";
+}
+
+
+class SetConstant implements SetExpression {
+ String value;
+
+ SetConstant(this.value);
+
+ Set<String> evaluate(environment) => new Set<string>().add(value);
+ String toString() => value;
+}
+
+
+/* An iterator that provides peeking at the current token. */
Mads Ager (google) 2011/10/26 12:37:47 I think you should either make this a doc comment
William Hesse 2011/10/26 15:15:03 Done.
+class Scanner {
Søren Gjesse 2011/10/26 13:36:24 Should we have token constants? class Token { f
William Hesse 2011/10/26 15:15:03 Done.
+ List<String> tokens;
+ Iterator token_iterator;
+ String current;
+
+ Scanner(this.tokens) {
+ //print(tokens[0] + tokens[1]);
Mads Ager (google) 2011/10/26 12:37:47 remove.
William Hesse 2011/10/26 15:15:03 Done.
+ token_iterator = tokens.iterator();
+ current = token_iterator.next();
Mads Ager (google) 2011/10/26 12:37:47 Shouldn't this just call advance?
William Hesse 2011/10/26 15:15:03 Done.
+ //print(current);
Mads Ager (google) 2011/10/26 12:37:47 remove.
William Hesse 2011/10/26 15:15:03 Done.
+ }
+
+ bool hasMore() => current != null;
+
+ void advance() {
+ current = token_iterator.hasNext() ? token_iterator.next() : null;
+ print(current);
Mads Ager (google) 2011/10/26 12:37:47 remove
William Hesse 2011/10/26 15:15:03 Done.
+ }
+}
+
+class ExpressionParser {
+ Scanner scanner;
Søren Gjesse 2011/10/26 13:36:24 Empty line before the constructor.
William Hesse 2011/10/26 15:15:03 Done.
+ ExpressionParser(this.scanner);
+
+ SetExpression parseSetExpression() => parseSetUnion();
+
+ SetExpression parseSetUnion() {
+ SetExpression left = parseSetIf();
+ while (scanner.hasMore() && scanner.current == ","){
+ scanner.advance();
+ SetExpression right = parseSetIf();
+ left = new SetUnion(left, right);
+ }
+ return left;
+ }
+
+ SetExpression parseSetIf() {
+ SetExpression left = parseSetOr();
+ while (scanner.hasMore() && scanner.current == "if") {
+ scanner.advance();
+ BooleanExpression right = parseBooleanExpression();
+ left = new SetIf(left, right);
+ }
+ return left;
+ }
+
+ SetExpression parseSetOr() {
+ SetExpression left = parseSetAtomic();
+ while (scanner.hasMore() && scanner.current == "||"){
+ scanner.advance();
+ SetExpression right = parseSetIf();
+ left = new SetUnion(left, right);
+ }
+ return left;
+ }
+
+
+ SetExpression parseSetAtomic() {
+ if (scanner.current == "(") {
+ scanner.advance();
+ SetExpression value = parseSetUnion();
+ Expect.equals(scanner.current, ")",
+ "Missing right parenthesis in expression");
Mads Ager (google) 2011/10/26 12:37:47 Please align with first parameter.
William Hesse 2011/10/26 15:15:03 Done.
+ scanner.advance();
+ return value;
+ }
+ Expect.isTrue(const RegExp(@"^\w+$").hasMatch(scanner.current),
+ "Expected identifier in expression, got " + scanner.current);
Mads Ager (google) 2011/10/26 12:37:47 Please align with first parameter or move both to
William Hesse 2011/10/26 15:15:03 Done.
+ SetExpression value = new SetConstant(scanner.current);
+ scanner.advance();
+ return value;
+ }
+
+ BooleanExpression parseBooleanExpression() => parseBooleanOr();
+
+ BooleanExpression parseBooleanOr() {
+ BooleanExpression left = parseBooleanAnd();
+ while (scanner.hasMore() && scanner.current == "||") {
+ scanner.advance();
+ BooleanExpression right = parseBooleanAnd();
+ left = new BooleanOperation("||", left, right);
+ }
+ return left;
+ }
+
+
+ BooleanExpression parseBooleanAnd() {
+ BooleanExpression left = parseBooleanAtomic();
+ while (scanner.hasMore() && scanner.current == "&&") {
+ scanner.advance();
+ BooleanExpression right = parseBooleanAtomic();
+ left = new BooleanOperation("&&", left, right);
+ }
+ return left;
+ }
+
+ BooleanExpression parseBooleanAtomic() {
+ if (scanner.current == "(") {
+ scanner.advance();
+ SetExpression value = parseBooleanExpression();
+ Expect.equals(scanner.current, ")",
+ "Missing right parenthesis in expression");
Mads Ager (google) 2011/10/26 12:37:47 align
William Hesse 2011/10/26 15:15:03 Done.
+ scanner.advance();
+ return value;
+ }
+
+ // The only atomic booleans are of the form $variable == value.
+ Expect.equals(scanner.current, @"$",
+ @"Expected $identifier in expression, got " + scanner.current);
Mads Ager (google) 2011/10/26 12:37:47 $identifier -> $
William Hesse 2011/10/26 15:15:03 Done.
+ scanner.advance();
+ Expect.isTrue(const RegExp(@"^\w+$").hasMatch(scanner.current),
+ @"Expected $identifier in expression, got " + scanner.current);
+ Variable left = new Variable(scanner.current);
+ scanner.advance();
+ Expect.equals(scanner.current, "==",
+ "Expected == in expression, got " + scanner.current);
+ scanner.advance();
+ Expect.isTrue(const RegExp(@"^\w+$").hasMatch(scanner.current),
+ @"Expected identifier in expression, got " + scanner.current);
Søren Gjesse 2011/10/26 13:36:24 No need for @ here.
William Hesse 2011/10/26 15:15:03 Done.
+ TermConstant right = new TermConstant(scanner.current);
+ scanner.advance();
+ return new Comparison(left, right);
+ }
+}
+
« no previous file with comments | « no previous file | tools/testing/dart/test_status_expressions.dart » ('j') | tools/testing/dart/test_status_expressions.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698