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, |
+ 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); |