if (state.inhibitExpectedTrackingDepth == 0) {
// Track position for possible error messaging
if (pos > state.max_pos) {
// Store position and the rule.
state.max_pos = pos;
if (this is _Expectable) {
state.max_rule = [this];
} else {
state.max_rule = [];
}
} else if (pos == state.max_pos) {
if (this is _Expectable) {
state.max_rule.add(this);
}
}
}
// Delegate the matching logic to the specialized function.
return _match(state, pos);
}
// Overridden in subclasses to match the rule.
_match(_ParserState state, int pos) => null;
// Does the rule generate a value (AST) with the match?
bool get generatesValue => false;
get defaultValue => null;
}
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;
state.inWhitespaceMode = true;
state.inhibitExpectedTrackingDepth++;
while (true) {
var match = state.whitespaceRule.match(state, pos);
if (match == null) break;
pos = match[0];
}
state.inWhitespaceMode = false;
state.inhibitExpectedTrackingDepth--;
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 List) {
return _compileMultiRule(
rule,
true,
(compiledRules, valueCount, reducer) =>
new _SequenceRule(compiledRules, valueCount, reducer));
}
throw new Exception('Cannot compile rule: $rule');
}
class _EndOfInputRule extends _Rule {
_match(_ParserState state, int pos) {
if (pos == state._end) return [pos, null];
return null;
}
toString() => 'END';
}
class _ErrorRule extends _Rule {
String message;
_ErrorRule(String this.message);
_match(_ParserState state, int pos) {
throw new ParseError(message);
}
toString() => 'ERROR($message)';
}
class _CharCodeRule extends _Rule {
Function _predicate;
var _name;
_CharCodeRule(this._predicate, this._name);
_match(_ParserState state, int pos) {
if (pos == state._end) return null;
int code = state._text.codeUnitAt(pos);
if (_predicate(code)) return [pos + 1, null];
return null;
}
toString() => _name == null ? 'CHARCODE($_predicate)' : 'CHARCODE($_name)';
}
class _AnyCharRule extends _Rule {
const _AnyCharRule();
_match(_ParserState state, int pos) {
if (pos == state._end) return null;
return [pos + 1, null];
}
toString() => 'CHAR()';
}
class _SymbolRule extends _Rule {
final Symbol _symbol;
_SymbolRule(Symbol this._symbol);
_match(_ParserState state, int pos) {
if (_symbol._rule == null)
throw new Exception("Symbol '${_symbol.name}' is undefined");
return _symbol._rule.match(state, pos);
}
Do'stlaringiz bilan baham: |