Index: packages/petitparser/lib/src/petitparser/expression.dart |
diff --git a/petitparser/lib/src/core/expression.dart b/packages/petitparser/lib/src/petitparser/expression.dart |
similarity index 51% |
rename from petitparser/lib/src/core/expression.dart |
rename to packages/petitparser/lib/src/petitparser/expression.dart |
index e71de7e7911adacc2f92f11aceb6fded81b9fb22..80b4f06915731201dc92eb4a146f7df1b1dbe414 100644 |
--- a/petitparser/lib/src/core/expression.dart |
+++ b/packages/petitparser/lib/src/petitparser/expression.dart |
@@ -1,96 +1,84 @@ |
part of petitparser; |
-/** |
- * A builder that allows the simple definition of expression grammars with |
- * prefix, postfix, and left- and right-associative infix operators. |
- * |
- * The following code creates the empty expression builder: |
- * |
- * var builder = new ExpressionBuilder(); |
- * |
- * Then we define the operator-groups in descending precedence. The highest |
- * precedence have the literal numbers themselves: |
- * |
- * builder.group() |
- * ..primitive(digit().plus() |
- * .seq(char('.').seq(digit().plus()).optional()) |
- * .flatten().trim().map((a) => double.parse(a))); |
- * |
- * Then come the normal arithmetic operators. Note, that the action blocks receive |
- * both, the terms and the parsed operator in the order they appear in the parsed |
- * input. |
- * |
- * // negation is a prefix operator |
- * builder.group() |
- * ..prefix(char('-').trim(), (op, a) => -a); |
- * |
- * // power is right-associative |
- * builder.group() |
- * ..right(char('^').trim(), (a, op, b) => math.pow(a, b)); |
- * |
- * // multiplication and addition is left-associative |
- * builder.group() |
- * ..left(char('*').trim(), (a, op, b) => a * b) |
- * ..left(char('/').trim(), (a, op, b) => a / b); |
- * builder.group() |
- * ..left(char('+').trim(), (a, op, b) => a + b) |
- * ..left(char('-').trim(), (a, op, b) => a - b); |
- * |
- * Finally we can build the parser: |
- * |
- * var parser = builder.build(); |
- * |
- * After executing the above code we get an efficient parser that correctly |
- * evaluates expressions like: |
- * |
- * parser.parse('-8'); // -8 |
- * parser.parse('1+2*3'); // 7 |
- * parser.parse('1*2+3'); // 5 |
- * parser.parse('8/4/2'); // 2 |
- * parser.parse('2^2^3'); // 256 |
- */ |
+/// A builder that allows the simple definition of expression grammars with |
+/// prefix, postfix, and left- and right-associative infix operators. |
+/// |
+/// The following code creates the empty expression builder: |
+/// |
+/// var builder = new ExpressionBuilder(); |
+/// |
+/// Then we define the operator-groups in descending precedence. The highest |
+/// precedence have the literal numbers themselves: |
+/// |
+/// builder.group() |
+/// ..primitive(digit().plus() |
+/// .seq(char('.').seq(digit().plus()).optional()) |
+/// .flatten().trim().map((a) => double.parse(a))); |
+/// |
+/// Then come the normal arithmetic operators. Note, that the action blocks receive |
+/// both, the terms and the parsed operator in the order they appear in the parsed |
+/// input. |
+/// |
+/// // negation is a prefix operator |
+/// builder.group() |
+/// ..prefix(char('-').trim(), (op, a) => -a); |
+/// |
+/// // power is right-associative |
+/// builder.group() |
+/// ..right(char('^').trim(), (a, op, b) => math.pow(a, b)); |
+/// |
+/// // multiplication and addition is left-associative |
+/// builder.group() |
+/// ..left(char('*').trim(), (a, op, b) => a * b) |
+/// ..left(char('/').trim(), (a, op, b) => a / b); |
+/// builder.group() |
+/// ..left(char('+').trim(), (a, op, b) => a + b) |
+/// ..left(char('-').trim(), (a, op, b) => a - b); |
+/// |
+/// Finally we can build the parser: |
+/// |
+/// var parser = builder.build(); |
+/// |
+/// After executing the above code we get an efficient parser that correctly |
+/// evaluates expressions like: |
+/// |
+/// parser.parse('-8'); // -8 |
+/// parser.parse('1+2*3'); // 7 |
+/// parser.parse('1*2+3'); // 5 |
+/// parser.parse('8/4/2'); // 2 |
+/// parser.parse('2^2^3'); // 256 |
class ExpressionBuilder { |
final List<ExpressionGroup> _groups = new List(); |
- /** |
- * Creates a new group of operators that share the same priority. |
- */ |
+ /// Creates a new group of operators that share the same priority. |
ExpressionGroup group() { |
var group = new ExpressionGroup(); |
_groups.add(group); |
return group; |
} |
- /** |
- * Builds the expression parser. |
- */ |
+ /// Builds the expression parser. |
Parser build() => _groups.fold( |
failure('Highest priority group should define a primitive parser.'), |
(a, b) => b._build(a)); |
} |
-/** |
- * Models a group of operators of the same precedence. |
- */ |
+/// Models a group of operators of the same precedence. |
class ExpressionGroup { |
- /** |
- * Defines a new primitive or literal [parser]. |
- */ |
+ /// Defines a new primitive or literal [parser]. |
void primitive(Parser parser) { |
_primitives.add(parser); |
} |
- Parser _build_primitive(Parser inner) { |
- return _build_choice(_primitives, inner); |
+ Parser _buildPrimitive(Parser inner) { |
+ return _buildChoice(_primitives, inner); |
} |
final List<Parser> _primitives = new List(); |
- /** |
- * Adds a prefix operator [parser]. Evaluates the optional [action] with the |
- * parsed `operator` and `value`. |
- */ |
+ /// Adds a prefix operator [parser]. Evaluates the optional [action] with the |
+ /// parsed `operator` and `value`. |
void prefix(Parser parser, [action(operator, value)]) { |
if (action == null) { |
action = (operator, value) => [operator, value]; |
@@ -98,11 +86,11 @@ class ExpressionGroup { |
_prefix.add(parser.map((operator) => new _ExpressionResult(operator, action))); |
} |
- Parser _build_prefix(Parser inner) { |
+ Parser _buildPrefix(Parser inner) { |
if (_prefix.isEmpty) { |
return inner; |
} else { |
- return new SequenceParser([_build_choice(_prefix).star(), inner]).map( |
+ return new SequenceParser([_buildChoice(_prefix).star(), inner]).map( |
(tuple) { |
return tuple.first.reversed.fold(tuple.last, (value, result) { |
return result.action(result.operator, value); |
@@ -113,10 +101,8 @@ class ExpressionGroup { |
final List<Parser> _prefix = new List(); |
- /** |
- * Adds a postfix operator [parser]. Evaluates the optional [action] with the |
- * parsed `value` and `operator`. |
- */ |
+ /// Adds a postfix operator [parser]. Evaluates the optional [action] with the |
+ /// parsed `value` and `operator`. |
void postfix(Parser parser, [action(value, operator)]) { |
if (action == null) { |
action = (value, operator) => [value, operator]; |
@@ -124,11 +110,11 @@ class ExpressionGroup { |
_postfix.add(parser.map((operator) => new _ExpressionResult(operator, action))); |
} |
- Parser _build_postfix(Parser inner) { |
+ Parser _buildPostfix(Parser inner) { |
if (_postfix.isEmpty) { |
return inner; |
} else { |
- return new SequenceParser([inner, _build_choice(_postfix).star()]).map( |
+ return new SequenceParser([inner, _buildChoice(_postfix).star()]).map( |
(tuple) { |
return tuple.last.fold(tuple.first, (value, result) { |
return result.action(value, result.operator); |
@@ -139,10 +125,8 @@ class ExpressionGroup { |
final List<Parser> _postfix = new List(); |
- /** |
- * Adds a right-associative operator [parser]. Evaluates the optional [action] with |
- * the parsed `left` term, `operator`, and `right` term. |
- */ |
+ /// Adds a right-associative operator [parser]. Evaluates the optional [action] with |
+ /// the parsed `left` term, `operator`, and `right` term. |
void right(Parser parser, [action(left, operator, right)]) { |
if (action == null) { |
action = (left, operator, right) => [left, operator, right]; |
@@ -150,11 +134,11 @@ class ExpressionGroup { |
_right.add(parser.map((operator) => new _ExpressionResult(operator, action))); |
} |
- Parser _build_right(Parser inner) { |
+ Parser _buildRight(Parser inner) { |
if (_right.isEmpty) { |
return inner; |
} else { |
- return inner.separatedBy(_build_choice(_right)).map((sequence) { |
+ return inner.separatedBy(_buildChoice(_right)).map((sequence) { |
var result = sequence.last; |
for (var i = sequence.length - 2; i > 0; i -= 2) { |
result = |
@@ -167,10 +151,8 @@ class ExpressionGroup { |
final List<Parser> _right = new List(); |
- /** |
- * Adds a left-associative operator [parser]. Evaluates the optional [action] with |
- * the parsed `left` term, `operator`, and `right` term. |
- */ |
+ /// Adds a left-associative operator [parser]. Evaluates the optional [action] with |
+ /// the parsed `left` term, `operator`, and `right` term. |
void left(Parser parser, [action(left, operator, right)]) { |
if (action == null) { |
action = (left, operator, right) => [left, operator, right]; |
@@ -178,11 +160,11 @@ class ExpressionGroup { |
_left.add(parser.map((operator) => new _ExpressionResult(operator, action))); |
} |
- Parser _build_left(Parser inner) { |
+ Parser _buildLeft(Parser inner) { |
if (_left.isEmpty) { |
return inner; |
} else { |
- return inner.separatedBy(_build_choice(_left)).map((sequence) { |
+ return inner.separatedBy(_buildChoice(_left)).map((sequence) { |
var result = sequence.first; |
for (var i = 1; i < sequence.length; i += 2) { |
result = |
@@ -196,7 +178,7 @@ class ExpressionGroup { |
final List<Parser> _left = new List(); |
// helper to build an optimal choice parser |
- Parser _build_choice(List<Parser> parsers, [Parser otherwise]) { |
+ Parser _buildChoice(List<Parser> parsers, [Parser otherwise]) { |
if (parsers.isEmpty) { |
return otherwise; |
} else if (parsers.length == 1) { |
@@ -208,7 +190,7 @@ class ExpressionGroup { |
// helper to build the group of parsers |
Parser _build(Parser inner) { |
- return _build_left(_build_right(_build_postfix(_build_prefix(_build_primitive(inner))))); |
+ return _buildLeft(_buildRight(_buildPostfix(_buildPrefix(_buildPrimitive(inner))))); |
} |
} |