Chromium Code Reviews| Index: utils/peg/pegparser.dart |
| diff --git a/utils/peg/pegparser.dart b/utils/peg/pegparser.dart |
| index 9c58dea1c00255f12020edfcec2be4932c847dc5..69292b6002be6593f2e0d83dfce26168483bc43e 100644 |
| --- a/utils/peg/pegparser.dart |
| +++ b/utils/peg/pegparser.dart |
| @@ -55,10 +55,8 @@ _Rule CHARCODE(spec, [name]) { |
| * CHAR does not generate a value. |
| */ |
| _Rule CHAR([characters]) { |
| - if (characters == null) |
| - return const _AnyCharRule(); |
| - if (characters is int) |
| - return CHARCODE(characters); |
| + if (characters == null) return const _AnyCharRule(); |
| + if (characters is int) return CHARCODE(characters); |
| // Find the range of character codes and construct an array of flags for codes |
| // within the range. |
| @@ -66,14 +64,11 @@ _Rule CHAR([characters]) { |
| codes.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); |
| int lo = codes[0]; |
| int hi = codes[codes.length - 1]; |
| - if (lo == hi) |
| - return CHARCODE(lo); |
| + if (lo == hi) return CHARCODE(lo); |
| int len = hi - lo + 1; |
| var flags = new List<bool>(len); |
| - for (int i = 0; i < len; ++i) |
| - flags[i] = false; |
| - for (int code in codes) |
| - flags[code - lo] = true; |
| + for (int i = 0; i < len; ++i) flags[i] = false; |
| + for (int code in codes) flags[code - lo] = true; |
| return CHARCODE((code) => code >= lo && code <= hi && flags[code - lo]); |
| } |
| @@ -137,11 +132,11 @@ _Rule LEX(arg1, [arg2]) { |
| * |
| * TEXT always generates a value. |
| */ |
| -_Rule TEXT(rule, [extractor]) => |
| - new _TextValueRule(_compile(rule), |
| - extractor == null |
| - ? (string, start, end) => string.substring(start, end) |
| - : extractor); |
| +_Rule TEXT(rule, [extractor]) => new _TextValueRule( |
| + _compile(rule), |
| + extractor == null |
| + ? (string, start, end) => string.substring(start, end) |
| + : extractor); |
| /** |
| * Matches an optional rule. |
| @@ -185,27 +180,80 @@ _Rule MANY0(rule, [separator = null]) { |
| * |
| * OR is value-generating. |
| */ |
| -_Rule OR([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]) => |
| +_Rule OR( |
| + [a, |
| + b, |
| + c, |
| + d, |
| + e, |
| + f, |
| + g, |
| + h, |
| + i, |
| + j, |
| + k, |
| + l, |
| + m, |
| + n, |
| + o, |
| + p, |
| + q, |
| + r, |
| + s, |
| + t, |
| + u, |
| + v, |
| + w, |
| + x, |
| + y, |
|
terry
2017/04/20 13:16:36
Ugh!, not as pretty - but I guess that's life...
Jacob
2017/04/20 15:33:14
agreed that this is really ugly. Unfortunately I c
|
| + z]) => |
| _compileMultiRule( |
| - (a is List && b == null) // Backward compat. OR([a, b]) => OR(a, b). |
| - ? a |
| - : _unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z), |
| + (a is List && b == null) // Backward compat. OR([a, b]) => OR(a, b). |
| + ? a |
| + : _unspread(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, |
| + t, u, v, w, x, y, z), |
| false, |
| - (compiledRules, valueCount, reducer) => |
| - new _ChoiceRule(compiledRules)); |
| - |
| - |
| - |
| -_Rule SEQ([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]) => |
| - _compile(_unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)); |
| + (compiledRules, valueCount, reducer) => new _ChoiceRule(compiledRules)); |
| + |
| +_Rule SEQ( |
| + [a, |
| + b, |
| + c, |
| + d, |
| + e, |
| + f, |
| + g, |
| + h, |
| + i, |
| + j, |
| + k, |
| + l, |
| + m, |
| + n, |
| + o, |
| + p, |
| + q, |
| + r, |
| + s, |
| + t, |
| + u, |
| + v, |
| + w, |
| + x, |
| + y, |
| + z]) => |
| + _compile(_unspread(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, |
| + t, u, v, w, x, y, z)); |
| /** |
| * Matches [rule] |
| */ |
| _Rule MEMO(rule) => new _MemoRule(_compile(rule)); |
| -_Rule TAG(tag, rule) => _compile([rule, (ast) => [tag, ast]]); |
| - |
| +_Rule TAG(tag, rule) => _compile([ |
| + rule, |
| + (ast) => [tag, ast] |
| + ]); |
| class ParseError implements Exception { |
| const ParseError(String this._message); |
| @@ -224,7 +272,9 @@ class Grammar { |
| _Rule _whitespace; |
| _Rule get whitespace => _whitespace; |
| - void set whitespace(rule) { _whitespace = _compile(rule); } |
| + void set whitespace(rule) { |
| + _whitespace = _compile(rule); |
| + } |
| Grammar() { |
| _symbols = new Map<String, Symbol>(); |
| @@ -236,8 +286,7 @@ class Grammar { |
| * to define recursive rules. |
| */ |
| Symbol operator [](String name) { |
| - if (_symbols.containsKey(name)) |
| - return _symbols[name]; |
| + if (_symbols.containsKey(name)) return _symbols[name]; |
| Symbol s = new Symbol(name, this); |
| _symbols[name] = s; |
| return s; |
| @@ -249,17 +298,14 @@ class Grammar { |
| */ |
| parse(root, String text) { |
| for (var symbol in _symbols.values) |
| - if (symbol._rule == null) |
| - print('${symbol.name} is undefined'); |
| + if (symbol._rule == null) print('${symbol.name} is undefined'); |
| var state = new _ParserState(text, whitespace: whitespace); |
| var match = _compile(root).match(state, 0); |
| - if (match == null) |
| - return diagnose(state); |
| + if (match == null) return diagnose(state); |
| var pos = match[0]; |
| pos = _skip_whitespace(state, pos); |
| - if (pos == state._end) |
| - return match[1]; |
| + if (pos == state._end) return match[1]; |
| // TODO: Make this complain about expecting end of file. |
| return diagnose(state); |
| } |
| @@ -268,15 +314,14 @@ class Grammar { |
| var message = 'unexpected error'; |
| if (!state.max_rule.isEmpty) { |
| var s = new Set(); |
| - for (var rule in state.max_rule) |
| - s.add(rule.description()); |
| + for (var rule in state.max_rule) s.add(rule.description()); |
| var tokens = new List<String>.from(s); |
| - tokens.sort((a, b) => |
| - a.startsWith("'") == b.startsWith("'") |
| - ? a.compareTo(b) |
| - : a.startsWith("'") ? 1 : -1); |
| + tokens.sort((a, b) => a.startsWith("'") == b.startsWith("'") |
| + ? a.compareTo(b) |
| + : a.startsWith("'") ? 1 : -1); |
| var expected = tokens.join(' or '); |
| - var found = state.max_pos == state._end ? 'end of file' |
| + var found = state.max_pos == state._end |
| + ? 'end of file' |
| : "'${state._text[state.max_pos]}'"; |
| message = 'Expected $expected but found $found'; |
| } |
| @@ -305,14 +350,13 @@ class Symbol { |
| Symbol(this.name, this.grammar); |
| void set def(rule) { |
| - assert(_rule == null); // Assign once. |
| + assert(_rule == null); // Assign once. |
| _rule = _compile(rule); |
| } |
| toString() => _rule == null ? '<$name>' : '<$name = $_rule>'; |
| } |
| - |
| class _ParserState { |
| _ParserState(this._text, {_Rule whitespace}) { |
| _end = this._text.length; |
| @@ -345,7 +389,7 @@ class _Rule { |
| const _Rule(); |
| // Returns null for a match failure or [pos, ast] for success. |
| match(_ParserState state, int pos) { |
| - if (! state.inWhitespaceMode) { |
| + if (!state.inWhitespaceMode) { |
| pos = _skip_whitespace(state, pos); |
| } |
| return matchAfterWS(state, pos); |
| @@ -387,14 +431,12 @@ class _Rule { |
| int _skip_whitespace(state, pos) { |
| // Returns the next non-whitespace position. |
| // This is done by matching the optional whitespaceRule with the current text. |
| - if (state.whitespaceRule == null) |
| - return pos; |
| + if (state.whitespaceRule == null) return pos; |
| state.inWhitespaceMode = true; |
| state.inhibitExpectedTrackingDepth++; |
| while (true) { |
| var match = state.whitespaceRule.match(state, pos); |
| - if (match == null) |
| - break; |
| + if (match == null) break; |
| pos = match[0]; |
| } |
| state.inWhitespaceMode = false; |
| @@ -402,23 +444,19 @@ int _skip_whitespace(state, pos) { |
| return pos; |
| } |
| - |
| _Rule _compileOptional(rule) { |
| return rule == null ? null : _compile(rule); |
| } |
| _Rule _compile(rule) { |
| - if (rule is _Rule) |
| - return rule; |
| - if (rule is String) |
| - return new _StringRule(rule); |
| - if (rule is Symbol) |
| - return new _SymbolRule(rule); |
| - if (rule is RegExp) |
| - return new _RegExpRule(rule); |
| + if (rule is _Rule) return rule; |
| + if (rule is String) return new _StringRule(rule); |
| + if (rule is Symbol) return new _SymbolRule(rule); |
| + if (rule is RegExp) return new _RegExpRule(rule); |
| if (rule is List) { |
| return _compileMultiRule( |
| - rule, true, |
| + rule, |
| + true, |
| (compiledRules, valueCount, reducer) => |
| new _SequenceRule(compiledRules, valueCount, reducer)); |
| } |
| @@ -427,8 +465,7 @@ _Rule _compile(rule) { |
| class _EndOfInputRule extends _Rule { |
| _match(_ParserState state, int pos) { |
| - if (pos == state._end) |
| - return [pos, null]; |
| + if (pos == state._end) return [pos, null]; |
| return null; |
| } |
| @@ -450,11 +487,9 @@ class _CharCodeRule extends _Rule { |
| var _name; |
| _CharCodeRule(this._predicate, this._name); |
| _match(_ParserState state, int pos) { |
| - if (pos == state._end) |
| - return null; |
| + if (pos == state._end) return null; |
| int code = state._text.codeUnitAt(pos); |
| - if (_predicate(code)) |
| - return [pos + 1, null]; |
| + if (_predicate(code)) return [pos + 1, null]; |
| return null; |
| } |
| @@ -464,8 +499,7 @@ class _CharCodeRule extends _Rule { |
| class _AnyCharRule extends _Rule { |
| const _AnyCharRule(); |
| _match(_ParserState state, int pos) { |
| - if (pos == state._end) |
| - return null; |
| + if (pos == state._end) return null; |
| return [pos + 1, null]; |
| } |
| @@ -492,8 +526,7 @@ class _SkipRule extends _Rule { |
| _SkipRule(_Rule this._rule); |
| _match(_ParserState state, int pos) { |
| var match = _rule.matchAfterWS(state, pos); |
| - if (match == null) |
| - return null; |
| + if (match == null) return null; |
| return [match[0], null]; |
| } |
| @@ -508,11 +541,9 @@ class _StringRule extends _Rule implements _Expectable { |
| } |
| _match(_ParserState state, int pos) { |
| - if (pos + _len > state._end) |
| - return null; |
| + if (pos + _len > state._end) return null; |
| for (int i = 0; i < _len; i++) { |
| - if (state._text.codeUnitAt(pos + i) != _string.codeUnitAt(i)) |
| - return null; |
| + if (state._text.codeUnitAt(pos + i) != _string.codeUnitAt(i)) return null; |
| } |
| return [pos + _len, null]; |
| } |
| @@ -556,7 +587,7 @@ class _LexicalRule extends _Rule implements _Expectable { |
| class _TextValueRule extends _Rule { |
| final _Rule _rule; |
| - final _extract; // Function |
| + final _extract; // Function |
| _TextValueRule(_Rule this._rule, Function this._extract); |
| @@ -574,9 +605,8 @@ class _TextValueRule extends _Rule { |
| toString() => 'TEXT($_rule)'; |
| } |
| -_Rule _compileMultiRule(List rules, |
| - bool allowReducer, |
| - finish(compiledRules, valueCount, reducer)) { |
| +_Rule _compileMultiRule( |
| + List rules, bool allowReducer, finish(compiledRules, valueCount, reducer)) { |
| int valueCount = 0; |
| List compiledRules = new List<_Rule>(); |
| Function reducer; |
| @@ -590,8 +620,7 @@ _Rule _compileMultiRule(List rules, |
| throw new Exception('Bad rule: "$rule"'); |
| } else { |
| _Rule compiledRule = _compile(rule); |
| - if (compiledRule.generatesValue) |
| - ++valueCount; |
| + if (compiledRule.generatesValue) ++valueCount; |
| compiledRules.add(compiledRule); |
| } |
| } |
| @@ -617,9 +646,8 @@ class _SequenceRule extends _Rule { |
| final int _generatingSubRules; |
| final Function _reducer; |
| bool _generatesValue; |
| - _SequenceRule(List<_Rule> this._rules, |
| - int this._generatingSubRules, |
| - Function this._reducer) { |
| + _SequenceRule(List<_Rule> this._rules, int this._generatingSubRules, |
| + Function this._reducer) { |
| _generatesValue = _generatingSubRules > 0 || _reducer != null; |
| } |
| @@ -627,8 +655,7 @@ class _SequenceRule extends _Rule { |
| var sequence = []; |
| for (var rule in _rules) { |
| var match = rule.match(state, pos); |
| - if (match == null) |
| - return null; |
| + if (match == null) return null; |
| if (rule.generatesValue) { |
| var ast = match[1]; |
| sequence.add(ast); |
| @@ -636,10 +663,8 @@ class _SequenceRule extends _Rule { |
| pos = match[0]; |
| } |
| if (_reducer == null) { |
| - if (_generatingSubRules == 0) |
| - return [pos, null]; |
| - if (_generatingSubRules == 1) |
| - return [pos, sequence[0]]; |
| + if (_generatingSubRules == 0) return [pos, null]; |
| + if (_generatingSubRules == 1) return [pos, sequence[0]]; |
| return [pos, sequence]; |
| } else { |
| return [pos, _apply(_reducer, sequence)]; |
| @@ -683,13 +708,8 @@ class _OptionalRule extends _Rule { |
| _OptionalRule(_Rule this._rule); |
| _match(_ParserState state, int pos) { |
| var match = _rule.match(state, pos); |
| - if (_rule.generatesValue) |
| - return match == null |
| - ? [pos, null] |
| - : match; |
| - return match == null |
| - ? [pos, false] |
| - : [match[0], true]; |
| + if (_rule.generatesValue) return match == null ? [pos, null] : match; |
| + return match == null ? [pos, false] : [match[0], true]; |
| } |
| bool get generatesValue => true; |
| @@ -703,8 +723,7 @@ class _ContextRule extends _Rule { |
| _match(_ParserState state, int pos) { |
| // TODO: protect error state. |
| var match = _rule._match(state, pos); |
| - if (match == null) |
| - return null; |
| + if (match == null) return null; |
| return [pos, null]; |
| } |
| @@ -717,8 +736,7 @@ class _NegativeContextRule extends _Rule { |
| _match(_ParserState state, int pos) { |
| // TODO: protect error state. |
| var match = _rule._match(state, pos); |
| - if (match == null) |
| - return [pos, null]; |
| + if (match == null) return [pos, null]; |
| return null; |
| } |
| @@ -736,26 +754,23 @@ class _RepeatRule extends _Rule { |
| _match(state, pos) { |
| // First match. |
| var match = _rule.match(state, pos); |
| - if (match == null) |
| - if (_min == 0) |
| - return [pos, []]; |
| - else |
| - return null; |
| + if (match == null) if (_min == 0) |
| + return [pos, []]; |
| + else |
| + return null; |
| pos = match[0]; |
| var result = [match[1]]; |
| // Subsequent matches: |
| - while (true) { |
| + while (true) { |
| var newPos = pos; |
| if (_separator != null) { |
| match = _separator.match(state, pos); |
| - if (match == null) |
| - return [pos, result]; |
| + if (match == null) return [pos, result]; |
| newPos = match[0]; |
| } |
| match = _rule.match(state, newPos); |
| - if (match == null) |
| - return [pos, result]; |
| + if (match == null) return [pos, result]; |
| pos = match[0]; |
| result.add(match[1]); |
| } |
| @@ -763,7 +778,8 @@ class _RepeatRule extends _Rule { |
| bool get generatesValue => true; |
| - toString() => 'MANY(min:$_min, $_rule${_separator==null?'':", sep: $_separator"})'; |
| + toString() => |
| + 'MANY(min:$_min, $_rule${_separator==null?'':", sep: $_separator"})'; |
| } |
| class _MemoRule extends _Rule { |
| @@ -774,7 +790,7 @@ class _MemoRule extends _Rule { |
| // A map from position to result. Can this be replaced with something |
| // smaller? |
| // TODO: figure out how to discard the map and parseInstance after parsing. |
| - Map<int,Object> map; |
| + Map<int, Object> map; |
| _MemoRule(this._rule); |
| @@ -782,7 +798,7 @@ class _MemoRule extends _Rule { |
| // See if we are still parsing the same input. Relies on the fact that the |
| // input is a string and strings are immutable. |
| if (!identical(parseInstance, state._text)) { |
| - map = new Map<int,Object>(); |
| + map = new Map<int, Object>(); |
| parseInstance = state._text; |
| } |
| // TODO: does this have to check or preserve parse state (like |
| @@ -803,31 +819,44 @@ class _MemoRule extends _Rule { |
| _apply(fn, List args) { |
| switch (args.length) { |
| - case 0: return fn(); |
| - case 1: return fn(args[0]); |
| - case 2: return fn(args[0], args[1]); |
| - case 3: return fn(args[0], args[1], args[2]); |
| - case 4: return fn(args[0], args[1], args[2], args[3]); |
| - case 5: return fn(args[0], args[1], args[2], args[3], args[4]); |
| - case 6: return fn(args[0], args[1], args[2], args[3], args[4], |
| - args[5]); |
| - case 7: return fn(args[0], args[1], args[2], args[3], args[4], |
| - args[5], args[6]); |
| - case 8: return fn(args[0], args[1], args[2], args[3], args[4], |
| - args[5], args[6], args[7]); |
| - case 9: return fn(args[0], args[1], args[2], args[3], args[4], |
| - args[5], args[6], args[7], args[8]); |
| - case 10: return fn(args[0], args[1], args[2], args[3], args[4], |
| - args[5], args[6], args[7], args[8], args[9]); |
| + case 0: |
| + return fn(); |
| + case 1: |
| + return fn(args[0]); |
| + case 2: |
| + return fn(args[0], args[1]); |
| + case 3: |
| + return fn(args[0], args[1], args[2]); |
| + case 4: |
| + return fn(args[0], args[1], args[2], args[3]); |
| + case 5: |
| + return fn(args[0], args[1], args[2], args[3], args[4]); |
| + case 6: |
| + return fn(args[0], args[1], args[2], args[3], args[4], args[5]); |
| + case 7: |
| + return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); |
| + case 8: |
| + return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], |
| + args[7]); |
| + case 9: |
| + return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], |
| + args[7], args[8]); |
| + case 10: |
| + return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], |
| + args[7], args[8], args[9]); |
| default: |
| throw new Exception('Too many arguments in _apply: $args'); |
| } |
| } |
| -List _unspread(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) { |
| +List _unspread(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, |
| + w, x, y, z) { |
| List list = new List(); |
| - add(element) { if (element != null) list.add(element); } |
| + add(element) { |
| + if (element != null) list.add(element); |
| + } |
| + |
| add(a); |
| add(b); |
| add(c); |