// 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 PegParser;

/*
 * The following functions are combinators for building Rules.
 *
 * A rule is one of the following
 * - A String which matches the string literally.
 * - A Symbol which matches the symbol's definition.
 * - A list of rules with an optional reducing function, which matches a sequence.
 * - The result of calling one of the combinators.
 *
 * Some rules are 'value-generating' rules, they return an 'abstract syntax
 * tree' with the match.  If a rule is not value-generating [:null:] is the
 * value.
 *
 * A Symbol is always a value-generating rule. If the value is not required, use
 * [:SKIP(aSymbol):] in place of [:aSymbol:].
 *
 * A String is not a value-generating rule but can be converted into one by
 * using [:TEXT('string'):] in place of [:'string':].
 *
 * A list or sequence is value-generating depending on the subrules.  The
 * sequence is value-generating if any of the subrules are value-generating or
 * if there is a reducing function.  If no reducing function is given, the value
 * returned depends on the number of value-generating subrules.  If there is
 * only one value generating subrule, that provideds the value for the sequence.
 * If there are more, then the value is a list of the values of the
 * value-generating subrules.
 */

/**
 * Matches one character by a predicate on the character code.
 * If [spec] is an int, that character is matched.
 * If [spec] is a function it is used
 *
 * Example [: CHARCODE((code) => 48 <= code && code <= 57) :] recognizes an
 * ASCII digit.
 *
 * CHARCODE does not generate a value.
 */
_Rule CHARCODE(spec, [name]) {
  if (spec is int)
    return new _CharCodeRule((code) => code == spec, name);
  else
    return new _CharCodeRule(spec, name);
}

/**
 * Matches one of the [characters].
 *
 * CHAR does not generate a value.
 */
_Rule CHAR([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.
  List<int> codes = characters.codeUnits.toList();
  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);
  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;

  return CHARCODE((code) => code >= lo && code <= hi && flags[code - lo]);
}

/**
 * Matches the end of the input.
 *
 * END does not generate a value.
 */
_Rule get END => new _EndOfInputRule();

/**
 * Throws an exception.
 */
_Rule ERROR(String message) => new _ErrorRule(message);

/**
 * Matches [rule] but does not consume the input.  Useful for matching a right
 * context.
 *
 * AT does not generate a value.
 */
_Rule AT(rule) => new _ContextRule(_compile(rule));

/**
 * Matches when [rule] does not match.  No input is consumed.
 *
 * NOT does not generate a value.
 */
_Rule NOT(rule) => new _NegativeContextRule(_compile(rule));

/**
 * Matches [rule] but generates no value even if [rule] generates a value.
 *
 * SKIP never generates a value.
 */
_Rule SKIP(rule) => new _SkipRule(_compile(rule));

/**
 * Matches [rule] in a lexical context where whitespace is not automatically
 * skipped.  Useful for matching what would normally be considered to be tokens.
 * [name] is a user-friendly description of what is being matched and is used in
 * error messages.
 *
 * LEX(rule)
 * LEX(name, rule)
 *
 * LEX does not generate a value.  If a value is required, wrap LEX with TEXT.
 */
_Rule LEX(arg1, [arg2]) {
  if (arg2 == null)
    return new _LexicalRule(arg1 is String ? arg1 : null, _compile(arg1));
  else
    return new _LexicalRule(arg1, _compile(arg2));
}

/**
 * Matches [rule] and generates a value from the matched text. If the [rule]
 * matches, then TEXT(rule) matches and has a value derived from the string
 * fragment that was matched.  The default derived value is the string fragment.
 *
 * TEXT always generates a value.
 */
_Rule TEXT(rule, [extractor]) =>
  new _TextValueRule(_compile(rule),
                     extractor == null
                     ? (string, start, end) => string.substring(start, end)
                     : extractor);

/**
 * Matches an optional rule.
 *
 * MAYBE is a value generating matcher.
 *
 * If [rule] is value generating then the value is the value generated by [rule]
 * if it matches, and [:null:] if it does not.
 *
 * If [rule] is not value generatinge then the value is [:true:] if [rule]
 * matches and [:false:] if it does not.
 */
_Rule MAYBE(rule) => new _OptionalRule(_compile(rule));

/**
 * MANY(rule) matches [rule] [min] or more times.
 * [min] must be 0 or 1.
 * If [separator] is provided it is used to match a separator between matches of
 * [rule].
 *
 * MANY is a value generating matcher.  The value is a list of the matches of
 * [rule].  The list may be empty if [:min == 0:].
 */
_Rule MANY(rule, {separator: null, int min: 1}) {
  assert(0 <= min && min <= 1);
  return new _RepeatRule(_compile(rule), _compileOptional(separator), min);
}

/**
 * Matches [rule] zero or more times.  Shorthand for [:MANY(rule, min:0):]
 * TODO: retire min: parameter?
 *
 * MANY0 is a value generating matcher.
 */
_Rule MANY0(rule, [separator = null]) {
  return new _RepeatRule(_compile(rule), _compileOptional(separator), 0);
}

/**
 * Matches [rules] in order until one succeeds.
 *
 * 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]) =>
    _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),
        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));

/**
 * Matches [rule]
 */
_Rule MEMO(rule) => new _MemoRule(_compile(rule));

_Rule TAG(tag, rule) => _compile([rule, (ast) => [tag, ast]]);


class ParseError implements Exception {
  const ParseError(String this._message);
  String toString() => _message;
  final String _message;
}

/**
 * A grammar is a collection of symbols and rules that may be used to parse an
 * input.
 */
class Grammar {
  Map<String, Symbol> _symbols;

  /** This rule may be set by the user to define whitespace. */
  _Rule _whitespace;

  _Rule get whitespace => _whitespace;
  void set whitespace(rule) { _whitespace = _compile(rule); }

  Grammar() {
    _symbols = new Map<String, Symbol>();
    whitespace = CHAR(' \t\r\n');
  }

  /**
   * operator [] is used to find or create symbols. Symbols may appear in rules
   * to define recursive rules.
   */
  Symbol operator [](String name) {
    if (_symbols.containsKey(name))
      return _symbols[name];
    Symbol s = new Symbol(name, this);
    _symbols[name] = s;
    return s;
  }

  /**
   * Parses the input string and returns the parsed AST, or throws an exception
   * if the input can't be parsed.
   */
  parse(root, String text) {
    for (var symbol in _symbols.values)
      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);
    var pos = match[0];
    pos = _skip_whitespace(state, pos);
    if (pos == state._end)
      return match[1];
    // TODO: Make this complain about expecting end of file.
    return diagnose(state);
  }

  diagnose(state) {
    var message = 'unexpected error';
    if (!state.max_rule.isEmpty) {
      var s = new Set();
      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);
      var expected = tokens.join(' or ');
      var found = state.max_pos == state._end ? 'end of file'
          : "'${state._text[state.max_pos]}'";
      message = 'Expected $expected but found $found';
    }
    int start = state.max_pos;
    int end = start;
    while (start >= 1 && state._text[start - 1] != '\n') --start;
    while (end < state._text.length && state._text[end] != '\n') ++end;
    var line = state._text.substring(start, end);
    var indicator = '';
    for (var i = 0; i < line.length && start + i < state.max_pos; i++)
      indicator = ' $indicator';
    indicator = '$indicator^';
    // TODO: Convert to an exception.
    print(message);
    print(line);
    print(indicator);
    return null;
  }
}

class Symbol {
  final String name;
  final Grammar grammar;
  _Rule _rule;

  Symbol(this.name, this.grammar);

  void set def(rule) {
    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;
    whitespaceRule = whitespace;
    max_rule = [];
  }

  String _text;
  int _end;

  //
  bool inWhitespaceMode = false;
  _Rule whitespaceRule = null;

  // Used for constructing an error message.
  int inhibitExpectedTrackingDepth = 0;
  int max_pos = 0;
  var max_rule;
}

/**
 * An interface tag for rules. If this tag is on a rule, then the description()
 * of the rule is something sensible to put in a message.
 */
abstract class _Expectable {
  String description();
}

class _Rule {
  const _Rule();
  // Returns null for a match failure or [pos, ast] for success.
  match(_ParserState state, int pos) {
    if (! state.inWhitespaceMode) {
      pos = _skip_whitespace(state, pos);
    }
    return matchAfterWS(state, pos);
  }

  // Faster entry point for matching a sub-rule that is matched to the start
  // position of the super-rule.  Whitespace has already been skipped so no need
  // to try to skip it again.
  matchAfterWS(_ParserState state, int pos) {
    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 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);
  }

  bool get generatesValue => true;

  toString() => '<${_symbol.name}>';
}

class _SkipRule extends _Rule {
  // A rule that has no value.
  _Rule _rule;
  _SkipRule(_Rule this._rule);
  _match(_ParserState state, int pos) {
    var match = _rule.matchAfterWS(state, pos);
    if (match == null)
      return null;
    return [match[0], null];
  }

  toString() => 'TOKEN($_rule)';
}

class _StringRule extends _Rule implements _Expectable {
  final String _string;
  int _len;
  _StringRule(this._string) {
    _len = _string.length;
  }

  _match(_ParserState state, int pos) {
    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;
    }
    return [pos + _len, null];
  }

  //get defaultValue => _string;

  toString() => '"$_string"';

  description() => "'$_string'";
}

class _RegExpRule extends _Rule {
  RegExp _re;
  _RegExpRule(this._re) {
    // There is no convenient way to match an anchored substring.
    throw new Exception('RegExp matching not supported');
  }

  toString() => '"$_re"';
}

class _LexicalRule extends _Rule implements _Expectable {
  final String _name;
  final _Rule _rule;

  _LexicalRule(String this._name, _Rule this._rule);

  _match(_ParserState state, int pos) {
    state.inWhitespaceMode = true;
    state.inhibitExpectedTrackingDepth++;
    var match = _rule.matchAfterWS(state, pos);
    state.inhibitExpectedTrackingDepth--;
    state.inWhitespaceMode = false;
    return match;
  }

  toString() => _name;

  description() => _name == null ? '?' : _name;
}

class _TextValueRule extends _Rule {
  final _Rule _rule;
  final _extract;  // Function

  _TextValueRule(_Rule this._rule, Function this._extract);

  _match(_ParserState state, int pos) {
    var match = _rule.matchAfterWS(state, pos);
    if (match == null) {
      return null;
    }
    var endPos = match[0];
    return [endPos, _extract(state._text, pos, endPos)];
  }

  bool get generatesValue => true;

  toString() => 'TEXT($_rule)';
}

_Rule _compileMultiRule(List rules,
                        bool allowReducer,
                        finish(compiledRules, valueCount, reducer)) {
  int valueCount = 0;
  List compiledRules = new List<_Rule>();
  Function reducer;
  for (var rule in rules) {
    if (reducer != null)
      throw new Exception('Reducer must be last in sequence: $rule');
    if (rule is Function) {
      if (allowReducer)
        reducer = rule;
      else
        throw new Exception('Bad rule: "$rule"');
    } else {
      _Rule compiledRule = _compile(rule);
      if (compiledRule.generatesValue)
        ++valueCount;
      compiledRules.add(compiledRule);
    }
  }
  return finish(compiledRules, valueCount, reducer);
}

String _formatMultiRule(String functor, List rules) {
  var sb = new StringBuffer(functor);
  sb.write('(');
  var separator = '';
  for (var rule in rules) {
    sb.write(separator);
    sb.write(rule);
    separator = ',';
  }
  sb.write(')');
  return sb.toString();
}

class _SequenceRule extends _Rule {
  // This rule matches the component rules in order.
  final List<_Rule> _rules;
  final int _generatingSubRules;
  final Function _reducer;
  bool _generatesValue;
  _SequenceRule(List<_Rule> this._rules,
                int this._generatingSubRules,
                Function this._reducer) {
    _generatesValue = _generatingSubRules > 0 || _reducer != null;
  }

  _match(state, pos) {
    var sequence = [];
    for (var rule in _rules) {
      var match = rule.match(state, pos);
      if (match == null)
        return null;
      if (rule.generatesValue) {
        var ast = match[1];
        sequence.add(ast);
      }
      pos = match[0];
    }
    if (_reducer == null) {
      if (_generatingSubRules == 0)
        return [pos, null];
      if (_generatingSubRules == 1)
        return [pos, sequence[0]];
      return [pos, sequence];
    } else {
      return [pos, _apply(_reducer, sequence)];
    }
  }

  bool get generatesValue => _generatesValue;

  toString() => _formatMultiRule('SEQ', _rules);
}

class _ChoiceRule extends _Rule {
  // This rule matches the first component rule that matches.
  List<_Rule> _rules;
  _ChoiceRule(List<_Rule> this._rules);

  _match(state, pos) {
    for (var rule in _rules) {
      var match = rule.match(state, pos);
      if (match != null) {
        /*
        if (!rule.generatesValue) {
          var value = rule.defaultValue;
          if (value != null)
            return [match[0], value];
        }
        */
        return match;
      }
    }
    return null;
  }

  bool get generatesValue => true;

  toString() => _formatMultiRule('OR', _rules);
}

class _OptionalRule extends _Rule {
  _Rule _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];
  }

  bool get generatesValue => true;

  toString() => 'MAYBE($_rule)';
}

class _ContextRule extends _Rule {
  _Rule _rule;
  _ContextRule(_Rule this._rule);
  _match(_ParserState state, int pos) {
    // TODO: protect error state.
    var match = _rule._match(state, pos);
    if (match == null)
      return null;
    return [pos, null];
  }

  toString() => 'AT($_rule)';
}

class _NegativeContextRule extends _Rule {
  _Rule _rule;
  _NegativeContextRule(_Rule this._rule);
  _match(_ParserState state, int pos) {
    // TODO: protect error state.
    var match = _rule._match(state, pos);
    if (match == null)
      return [pos, null];
    return null;
  }

  toString() => 'NOT($_rule)';
}

class _RepeatRule extends _Rule {
  // Matches zero, one or more items.
  _Rule _rule;
  _Rule _separator;
  int _min;

  _RepeatRule(this._rule, this._separator, this._min);

  _match(state, pos) {
    // First match.
    var match = _rule.match(state, pos);
    if (match == null)
      if (_min == 0)
        return [pos, []];
      else
        return null;
    pos = match[0];
    var result = [match[1]];

    // Subsequent matches:
    while (true)  {
      var newPos = pos;
      if (_separator != null) {
        match = _separator.match(state, pos);
        if (match == null)
          return [pos, result];
        newPos = match[0];
      }
      match = _rule.match(state, newPos);
      if (match == null)
        return [pos, result];
      pos = match[0];
      result.add(match[1]);
    }
  }

  bool get generatesValue => true;

  toString() => 'MANY(min:$_min, $_rule${_separator==null?'':", sep: $_separator"})';
}

class _MemoRule extends _Rule {
  final _Rule _rule;

  var parseInstance;

  // 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;

  _MemoRule(this._rule);

  _match(state, pos) {
    // 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>();
      parseInstance = state._text;
    }
    // TODO: does this have to check or preserve parse state (like
    // inWhitespaceMode, error position info etc?)
    // Stored result can be null (memoized failure).
    if (map.containsKey(pos)) {
      return map[pos];
    }
    var match = _rule.match(state, pos);
    map[pos] = match;
    return match;
  }

  bool get generatesValue => _rule.generatesValue;

  toString() => 'MEMO($_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]);

    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 list = new List();
  add(element) { if (element != null) list.add(element); }
  add(a);
  add(b);
  add(c);
  add(d);
  add(e);
  add(f);
  add(g);
  add(h);
  add(i);
  add(j);
  add(k);
  add(l);
  add(m);
  add(n);
  add(o);
  add(p);
  add(q);
  add(r);
  add(s);
  add(t);
  add(u);
  add(v);
  add(w);
  add(x);
  add(y);
  add(z);
  return list;
}
