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

/**
 * A simple recursive descent parser for CSS.
 */
class Parser {
  Tokenizer tokenizer;

  var _fs;                        // If non-null filesystem to read files.
  String _basePath;               // Base path of CSS file.

  final SourceFile source;

  Token _previousToken;
  Token _peekToken;

// Communicating errors back to template parser.
// TODO(terry): Need a better mechanism (e.g., common World).
  var _erroMsgRedirector;

  Parser(this.source, [int start = 0, this._fs = null, this._basePath = null]) {
    tokenizer = new Tokenizer(source, true, start);
    _peekToken = tokenizer.next();
    _previousToken = null;
  }

  // Main entry point for parsing an entire CSS file.
  // If nestedCSS is true when we're back at processing directives from top and
  // we encounter a } then stop we're inside of a template e.g.,
  //
  //       template ... {
  //          css {
  //            .item {
  //               left: 10px;
  //            }
  //          }
  //          <div>...</div>
  //       }
  //
  Stylesheet parse([bool nestedCSS = false, var erroMsgRedirector = null]) {
    // TODO(terry): Hack for migrating CSS errors back to template errors.
    _erroMsgRedirector = erroMsgRedirector;

    List<ASTNode> productions = [];

    int start = _peekToken.start;
    while (!_maybeEat(TokenKind.END_OF_FILE) &&
           (!nestedCSS && !_peekKind(TokenKind.RBRACE))) {
      // TODO(terry): Need to handle charset, import, media and page.
      var directive = processDirective();
      if (directive != null) {
        productions.add(directive);
      } else {
        RuleSet ruleset = processRuleSet();
        if (ruleset != null) {
          productions.add(ruleset);
        } else {
          break;
        }
      }
    }

    return new Stylesheet(productions, _makeSpan(start));
  }

  /** Generate an error if [source] has not been completely consumed. */
  void checkEndOfFile() {
    _eat(TokenKind.END_OF_FILE);
  }

  /** Guard to break out of parser when an unexpected end of file is found. */
  // TODO(jimhug): Failure to call this method can lead to inifinite parser
  //   loops.  Consider embracing exceptions for more errors to reduce
  //   the danger here.
  bool isPrematureEndOfFile() {
    if (_maybeEat(TokenKind.END_OF_FILE)) {
      _error('unexpected end of file', _peekToken.span);
      return true;
    } else {
      return false;
    }
  }

  ///////////////////////////////////////////////////////////////////
  // Basic support methods
  ///////////////////////////////////////////////////////////////////
  int _peek() {
    return _peekToken.kind;
  }

  Token _next() {
    _previousToken = _peekToken;
    _peekToken = tokenizer.next();
    return _previousToken;
  }

  bool _peekKind(int kind) {
    return _peekToken.kind == kind;
  }

  /* Is the next token a legal identifier?  This includes pseudo-keywords. */
  bool _peekIdentifier() {
    return TokenKind.isIdentifier(_peekToken.kind);
  }

  bool _maybeEat(int kind) {
    if (_peekToken.kind == kind) {
      _previousToken = _peekToken;
      _peekToken = tokenizer.next();
      return true;
    } else {
      return false;
    }
  }

  void _eat(int kind) {
    if (!_maybeEat(kind)) {
      _errorExpected(TokenKind.kindToString(kind));
    }
  }

  void _eatSemicolon() {
    _eat(TokenKind.SEMICOLON);
  }

  void _errorExpected(String expected) {
    var tok = _next();
    var message;
    try {
      message = 'expected $expected, but found $tok';
    } catch (e) {
      message = 'parsing error expected $expected';
    }
    _error(message, tok.span);
  }

  void _error(String message, [SourceSpan location=null]) {
    if (location == null) {
      location = _peekToken.span;
    }

    if (_erroMsgRedirector == null) {
       world.fatal(message, location);    // syntax errors are fatal for now
    } else {
      String text = "";
      if (location != null) {
        text = location.toMessageString("");
      }
      _erroMsgRedirector.displayError("CSS error: \r${text}\r${message}");
    }
  }

  void _warning(String message, [SourceSpan location=null]) {
    if (location == null) {
      location = _peekToken.span;
    }

    world.warning(message, location);
  }

  SourceSpan _makeSpan(int start) {
    return new SourceSpan(source, start, _previousToken.end);
  }

  ///////////////////////////////////////////////////////////////////
  // Top level productions
  ///////////////////////////////////////////////////////////////////

  // Templates are @{selectors} single line nothing else.
  SelectorGroup parseTemplate() {
    SelectorGroup selectorGroup = null;
    if (!isPrematureEndOfFile()) {
      selectorGroup = templateExpression();
    }

    return selectorGroup;
  }

  /*
   * Expect @{css_expression}
   */
  templateExpression() {
    List<Selector> selectors = [];

    int start = _peekToken.start;

    _eat(TokenKind.AT);
    _eat(TokenKind.LBRACE);

    selectors.add(processSelector());
    SelectorGroup group = new SelectorGroup(selectors, _makeSpan(start));

    _eat(TokenKind.RBRACE);

    return group;
  }

  ///////////////////////////////////////////////////////////////////
  // Productions
  ///////////////////////////////////////////////////////////////////

  processMedia([bool oneRequired = false]) {
    List<String> media = [];

    while (_peekIdentifier()) {
      // We have some media types.
      var medium = identifier();   // Medium ident.
      media.add(medium);
      if (!_maybeEat(TokenKind.COMMA)) {
        // No more media types exit now.
        break;
      }
    }

    if (oneRequired && media.length == 0) {
      _error('at least one media type required', _peekToken.span);
    }

    return media;
  }

  //  Directive grammar:
  //
  //  import:       '@import' [string | URI] media_list?
  //  media:        '@media' media_list '{' ruleset '}'
  //  page:         '@page' [':' IDENT]? '{' declarations '}'
  //  include:      '@include' [string | URI]
  //  stylet:       '@stylet' IDENT '{' ruleset '}'
  //  media_list:   IDENT [',' IDENT]
  //  keyframes:    '@-webkit-keyframes ...' (see grammar below).
  //  font_face:    '@font-face' '{' declarations '}'
  //
  processDirective() {
    int start = _peekToken.start;

    if (_maybeEat(TokenKind.AT)) {
      switch (_peek()) {
      case TokenKind.DIRECTIVE_IMPORT:
        _next();

        String importStr;
        if (_peekIdentifier()) {
          var func = processFunction(identifier());
          if (func is UriTerm) {
            importStr = func.text;
          }
        } else {
          importStr = processQuotedString(false);
        }

        // Any medias?
        List<String> medias = processMedia();

        if (importStr == null) {
          _error('missing import string', _peekToken.span);
        }
        return new ImportDirective(importStr, medias, _makeSpan(start));
      case TokenKind.DIRECTIVE_MEDIA:
        _next();

        // Any medias?
        List<String> media = processMedia(true);
        RuleSet ruleset;

        if (_maybeEat(TokenKind.LBRACE)) {
          ruleset = processRuleSet();
          if (!_maybeEat(TokenKind.RBRACE)) {
            _error('expected } after ruleset for @media', _peekToken.span);
          }
        } else {
          _error('expected { after media before ruleset', _peekToken.span);
        }
        return new MediaDirective(media, ruleset, _makeSpan(start));
      case TokenKind.DIRECTIVE_PAGE:
        _next();

        // Any pseudo page?
        var pseudoPage;
        if (_maybeEat(TokenKind.COLON)) {
          if (_peekIdentifier()) {
            pseudoPage = identifier();
          }
        }
        return new PageDirective(pseudoPage, processDeclarations(),
            _makeSpan(start));
      case TokenKind.DIRECTIVE_KEYFRAMES:
        /*  Key frames grammar:
         *
         *  @-webkit-keyframes [IDENT|STRING] '{' keyframes-blocks '}';
         *
         *  keyframes-blocks:
         *    [keyframe-selectors '{' declarations '}']* ;
         *
         *  keyframe-selectors:
         *    ['from'|'to'|PERCENTAGE] [',' ['from'|'to'|PERCENTAGE] ]* ;
         */
        _next();

        var name;
        if (_peekIdentifier()) {
          name = identifier();
        }

        _eat(TokenKind.LBRACE);

        KeyFrameDirective kf = new KeyFrameDirective(name, _makeSpan(start));

        do {
          Expressions selectors = new Expressions(_makeSpan(start));

          do {
            var term = processTerm();

            // TODO(terry): Only allow from, to and PERCENTAGE ...

            selectors.add(term);
          } while (_maybeEat(TokenKind.COMMA));

          kf.add(new KeyFrameBlock(selectors, processDeclarations(),
              _makeSpan(start)));

        } while (!_maybeEat(TokenKind.RBRACE));

        return kf;
      case TokenKind.DIRECTIVE_FONTFACE:
        _next();

        List<Declaration> decls = [];

        // TODO(terry): To Be Implemented

        return new FontFaceDirective(decls, _makeSpan(start));
      case TokenKind.DIRECTIVE_INCLUDE:
        _next();
        String filename = processQuotedString(false);
        if (_fs != null) {
          // Does CSS file exist?
          if (_fs.fileExists('${_basePath}${filename}')) {
            String basePath = "";
            int idx = filename.lastIndexOf('/');
            if (idx >= 0) {
              basePath = filename.substring(0, idx + 1);
            }
            basePath = '${_basePath}${basePath}';
            // Yes, let's parse this file as well.
            String fullFN = '${basePath}${filename}';
            String contents = _fs.readAll(fullFN);
            Parser parser = new Parser(new SourceFile(fullFN, contents), 0,
                _fs, basePath);
            Stylesheet stylesheet = parser.parse();
            return new IncludeDirective(filename, stylesheet, _makeSpan(start));
          }

          _error('file doesn\'t exist ${filename}', _peekToken.span);
        }

        print("WARNING: @include doesn't work for uitest");
        return new IncludeDirective(filename, null, _makeSpan(start));
      case TokenKind.DIRECTIVE_STYLET:
        /* Stylet grammar:
        *
        *  @stylet IDENT '{'
        *    ruleset
        *  '}'
        */
        _next();

        var name;
        if (_peekIdentifier()) {
          name = identifier();
        }

        _eat(TokenKind.LBRACE);

        List<ASTNode> productions = [];

        start = _peekToken.start;
        while (!_maybeEat(TokenKind.END_OF_FILE)) {
          RuleSet ruleset = processRuleSet();
          if (ruleset == null) {
            break;
          }
          productions.add(ruleset);
        }

        _eat(TokenKind.RBRACE);

        return new StyletDirective(name, productions, _makeSpan(start));
      default:
        _error('unknown directive, found $_peekToken', _peekToken.span);
      }
    }
  }

  RuleSet processRuleSet() {
    int start = _peekToken.start;

    SelectorGroup selGroup = processSelectorGroup();
    if (selGroup != null) {
      return new RuleSet(selGroup, processDeclarations(), _makeSpan(start));
    }
  }

  DeclarationGroup processDeclarations() {
    int start = _peekToken.start;

    _eat(TokenKind.LBRACE);

    List<Declaration> decls = [];
    do {
      Declaration decl = processDeclaration();
      if (decl != null) {
        decls.add(decl);
      }
    } while (_maybeEat(TokenKind.SEMICOLON));

    _eat(TokenKind.RBRACE);

    return new DeclarationGroup(decls, _makeSpan(start));
  }

  SelectorGroup processSelectorGroup() {
    List<Selector> selectors = [];
    int start = _peekToken.start;
    do {
      Selector selector = processSelector();
      if (selector != null) {
        selectors.add(selector);
      }
    } while (_maybeEat(TokenKind.COMMA));

    if (selectors.length > 0) {
      return new SelectorGroup(selectors, _makeSpan(start));
    }
  }

  /* Return list of selectors
   *
   */
  processSelector() {
    List<SimpleSelectorSequence> simpleSequences = [];
    int start = _peekToken.start;
    while (true) {
      // First item is never descendant make sure it's COMBINATOR_NONE.
      var selectorItem = simpleSelectorSequence(simpleSequences.length == 0);
      if (selectorItem != null) {
        simpleSequences.add(selectorItem);
      } else {
        break;
      }
    }

    if (simpleSequences.length > 0) {
      return new Selector(simpleSequences, _makeSpan(start));
    }
  }

  simpleSelectorSequence(bool forceCombinatorNone) {
    int start = _peekToken.start;
    int combinatorType = TokenKind.COMBINATOR_NONE;

    switch (_peek()) {
      case TokenKind.PLUS:
        _eat(TokenKind.PLUS);
        combinatorType = TokenKind.COMBINATOR_PLUS;
        break;
      case TokenKind.GREATER:
        _eat(TokenKind.GREATER);
        combinatorType = TokenKind.COMBINATOR_GREATER;
        break;
      case TokenKind.TILDE:
        _eat(TokenKind.TILDE);
        combinatorType = TokenKind.COMBINATOR_TILDE;
        break;
    }

    // Check if WHITESPACE existed between tokens if so we're descendent.
    if (combinatorType == TokenKind.COMBINATOR_NONE && !forceCombinatorNone) {
      if (this._previousToken != null &&
          this._previousToken.end != this._peekToken.start) {
        combinatorType = TokenKind.COMBINATOR_DESCENDANT;
      }
    }

    var simpleSel = simpleSelector();
    if (simpleSel != null) {
      return new SimpleSelectorSequence(simpleSel, _makeSpan(start),
          combinatorType);
    }
  }

  /**
   * Simple selector grammar:
   *
   *    simple_selector_sequence
   *       : [ type_selector | universal ]
   *         [ HASH | class | attrib | pseudo | negation ]*
   *       | [ HASH | class | attrib | pseudo | negation ]+
   *    type_selector
   *       : [ namespace_prefix ]? element_name
   *    namespace_prefix
   *       : [ IDENT | '*' ]? '|'
   *    element_name
   *       : IDENT
   *    universal
   *       : [ namespace_prefix ]? '*'
   *    class
   *       : '.' IDENT
   */
  simpleSelector() {
    // TODO(terry): Nathan makes a good point parsing of namespace and element
    //              are essentially the same (asterisk or identifier) other
    //              than the error message for element.  Should consolidate the
    //              code.
    // TODO(terry): Need to handle attribute namespace too.
    var first;
    int start = _peekToken.start;
    switch (_peek()) {
      case TokenKind.ASTERISK:
        // Mark as universal namespace.
        var tok = _next();
        first = new Wildcard(_makeSpan(tok.start));
        break;
      case TokenKind.IDENTIFIER:
        int startIdent = _peekToken.start;
        first = identifier();
        break;
    }

    if (_maybeEat(TokenKind.NAMESPACE)) {
      var element;
      switch (_peek()) {
        case TokenKind.ASTERISK:
          // Mark as universal element
          var tok = _next();
          element = new Wildcard(_makeSpan(tok.start));
          break;
        case TokenKind.IDENTIFIER:
          element = identifier();
          break;
        default:
          _error('expected element name or universal(*), but found $_peekToken',
              _peekToken.span);
      }

      return new NamespaceSelector(first,
          new ElementSelector(element, element.span), _makeSpan(start));
    } else if (first != null) {
      return new ElementSelector(first, _makeSpan(start));
    } else {
      // Check for HASH | class | attrib | pseudo | negation
      return simpleSelectorTail();
    }
  }

  simpleSelectorTail() {
    // Check for HASH | class | attrib | pseudo | negation
    int start = _peekToken.start;
    switch (_peek()) {
      case TokenKind.HASH:
        _eat(TokenKind.HASH);
        return new IdSelector(identifier(), _makeSpan(start));
      case TokenKind.DOT:
        _eat(TokenKind.DOT);
        return new ClassSelector(identifier(), _makeSpan(start));
      case TokenKind.COLON:
        // :pseudo-class ::pseudo-element
        // TODO(terry): '::' should be token.
        _eat(TokenKind.COLON);
        bool pseudoElement = _maybeEat(TokenKind.COLON);
        var name = identifier();
        // TODO(terry): Need to handle specific pseudo class/element name and
        // backward compatible names that are : as well as :: as well as
        // parameters.
        return pseudoElement ?
            new PseudoElementSelector(name, _makeSpan(start)) :
            new PseudoClassSelector(name, _makeSpan(start));
      case TokenKind.LBRACK:
        return processAttribute();
    }
  }

  //  Attribute grammar:
  //
  //  attributes :
  //    '[' S* IDENT S* [ ATTRIB_MATCHES S* [ IDENT | STRING ] S* ]? ']'
  //
  //  ATTRIB_MATCHES :
  //    [ '=' | INCLUDES | DASHMATCH | PREFIXMATCH | SUFFIXMATCH | SUBSTRMATCH ]
  //
  //  INCLUDES:         '~='
  //
  //  DASHMATCH:        '|='
  //
  //  PREFIXMATCH:      '^='
  //
  //  SUFFIXMATCH:      '$='
  //
  //  SUBSTRMATCH:      '*='
  //
  //
  processAttribute() {
    int start = _peekToken.start;

    if (_maybeEat(TokenKind.LBRACK)) {
      var attrName = identifier();

      int op = TokenKind.NO_MATCH;
      switch (_peek()) {
      case TokenKind.EQUALS:
      case TokenKind.INCLUDES:        // ~=
      case TokenKind.DASH_MATCH:      // |=
      case TokenKind.PREFIX_MATCH:    // ^=
      case TokenKind.SUFFIX_MATCH:    // $=
      case TokenKind.SUBSTRING_MATCH: // *=
        op = _peek();
        _next();
        break;
      }

      String value;
      if (op != TokenKind.NO_MATCH) {
        // Operator hit so we require a value too.
        if (_peekIdentifier()) {
          value = identifier();
        } else {
          value = processQuotedString(false);
        }

        if (value == null) {
          _error('expected attribute value string or ident', _peekToken.span);
        }
      }

      _eat(TokenKind.RBRACK);

      return new AttributeSelector(attrName, op, value, _makeSpan(start));
    }
  }

  //  Declaration grammar:
  //
  //  declaration:  property ':' expr prio?
  //
  //  property:  IDENT
  //  prio:      !important
  //  expr:      (see processExpr)
  //
  processDeclaration() {
    Declaration decl;

    int start = _peekToken.start;

    // IDENT ':' expr '!important'?
    if (TokenKind.isIdentifier(_peekToken.kind)) {
      var propertyIdent = identifier();
      _eat(TokenKind.COLON);

      decl = new Declaration(propertyIdent, processExpr(), _makeSpan(start));

      // Handle !important (prio)
      decl.important = _maybeEat(TokenKind.IMPORTANT);
    }

    return decl;
  }

  //  Expression grammar:
  //
  //  expression:   term [ operator? term]*
  //
  //  operator:     '/' | ','
  //  term:         (see processTerm)
  //
  processExpr() {
    int start = _peekToken.start;
    Expressions expressions = new Expressions(_makeSpan(start));

    bool keepGoing = true;
    var expr;
    while (keepGoing && (expr = processTerm()) != null) {
      var op;

      int opStart = _peekToken.start;

      switch (_peek()) {
      case TokenKind.SLASH:
        op = new OperatorSlash(_makeSpan(opStart));
        break;
      case TokenKind.COMMA:
        op = new OperatorComma(_makeSpan(opStart));
        break;
      }

      if (expr != null) {
        expressions.add(expr);
      } else {
        keepGoing = false;
      }

      if (op != null) {
        expressions.add(op);
        _next();
      }
    }

    return expressions;
  }

  //  Term grammar:
  //
  //  term:
  //    unary_operator?
  //    [ term_value ]
  //    | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
  //
  //  term_value:
  //    NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
  //    TIME S* | FREQ S* | function
  //
  //  NUMBER:       {num}
  //  PERCENTAGE:   {num}%
  //  LENGTH:       {num}['px' | 'cm' | 'mm' | 'in' | 'pt' | 'pc']
  //  EMS:          {num}'em'
  //  EXS:          {num}'ex'
  //  ANGLE:        {num}['deg' | 'rad' | 'grad']
  //  TIME:         {num}['ms' | 's']
  //  FREQ:         {num}['hz' | 'khz']
  //  function:     IDENT '(' expr ')'
  //
  processTerm() {
    int start = _peekToken.start;
    Token t;             // token for term's value
    var value;                // value of term (numeric values)

    var unary = "";

    switch (_peek()) {
    case TokenKind.HASH:
      this._eat(TokenKind.HASH);
      String hexText;
      if (_peekKind(TokenKind.INTEGER)) {
        String hexText1 = _peekToken.text;
        _next();
        if (_peekIdentifier()) {
          hexText = '${hexText1}${identifier().name}';
        } else {
          hexText = hexText1;
        }
      } else if (_peekIdentifier()) {
        hexText = identifier().name;
      } else {
        _errorExpected("hex number");
      }

      try {
        int hexValue = parseHex(hexText);
        return new HexColorTerm(hexValue, hexText, _makeSpan(start));
      } on HexNumberException catch (hne) {
        _error('Bad hex number', _makeSpan(start));
      }
      break;
    case TokenKind.INTEGER:
      t = _next();
      value = int.parse("${unary}${t.text}");
      break;
    case TokenKind.DOUBLE:
      t = _next();
      value = double.parse("${unary}${t.text}");
      break;
    case TokenKind.SINGLE_QUOTE:
    case TokenKind.DOUBLE_QUOTE:
      value = processQuotedString(false);
      value = '"${value}"';
      return new LiteralTerm(value, value, _makeSpan(start));
    case TokenKind.LPAREN:
      _next();

      GroupTerm group = new GroupTerm(_makeSpan(start));

      do {
        var term = processTerm();
        if (term != null && term is LiteralTerm) {
          group.add(term);
        }
      } while (!_maybeEat(TokenKind.RPAREN));

      return group;
    case TokenKind.LBRACK:
      _next();

      var term = processTerm();
      if (!(term is NumberTerm)) {
        _error('Expecting a positive number', _makeSpan(start));
      }

      _eat(TokenKind.RBRACK);

      return new ItemTerm(term.value, term.text, _makeSpan(start));
    case TokenKind.IDENTIFIER:
      var nameValue = identifier();   // Snarf up the ident we'll remap, maybe.

      if (_maybeEat(TokenKind.LPAREN)) {
        // FUNCTION
        return processFunction(nameValue);
      } else {
        // TODO(terry): Need to have a list of known identifiers today only
        //              'from' is special.
        if (nameValue.name == 'from') {
          return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
        }

        // What kind of identifier is it?
        try {
          // Named color?
          int colorValue = TokenKind.matchColorName(nameValue.name);

          // Yes, process the color as an RGB value.
          String rgbColor = TokenKind.decimalToHex(colorValue, 3);
          try {
            colorValue = parseHex(rgbColor);
          } on HexNumberException catch (hne) {
            _error('Bad hex number', _makeSpan(start));
          }
          return new HexColorTerm(colorValue, rgbColor, _makeSpan(start));
        } catch (error) {
          if (error is NoColorMatchException) {
            // TODO(terry): Other named things to match with validator?

            // TODO(terry): Disable call to _warning need one World class for
            //              both CSS parser and other parser (e.g., template)
            //              so all warnings, errors, options, etc. are driven
            //              from the one World.
//          _warning('Unknown property value ${error.name}', _makeSpan(start));
            return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
          }
        }
      }
    }

    var term;
    var unitType = this._peek();

    switch (unitType) {
    case TokenKind.UNIT_EM:
      term = new EmTerm(value, t.text, _makeSpan(start));
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_EX:
      term = new ExTerm(value, t.text, _makeSpan(start));
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_LENGTH_PX:
    case TokenKind.UNIT_LENGTH_CM:
    case TokenKind.UNIT_LENGTH_MM:
    case TokenKind.UNIT_LENGTH_IN:
    case TokenKind.UNIT_LENGTH_PT:
    case TokenKind.UNIT_LENGTH_PC:
      term = new LengthTerm(value, t.text, _makeSpan(start), unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_ANGLE_DEG:
    case TokenKind.UNIT_ANGLE_RAD:
    case TokenKind.UNIT_ANGLE_GRAD:
      term = new AngleTerm(value, t.text, _makeSpan(start), unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_TIME_MS:
    case TokenKind.UNIT_TIME_S:
      term = new TimeTerm(value, t.text, _makeSpan(start), unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_FREQ_HZ:
    case TokenKind.UNIT_FREQ_KHZ:
      term = new FreqTerm(value, t.text, _makeSpan(start), unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.PERCENT:
      term = new PercentageTerm(value, t.text, _makeSpan(start));
      _next();    // Skip the %
      break;
    case TokenKind.UNIT_FRACTION:
      term = new FractionTerm(value, t.text, _makeSpan(start));
      _next();     // Skip the unit
      break;
    default:
      if (value != null) {
        term = new NumberTerm(value, t.text, _makeSpan(start));
      }
    }

    return term;
  }

  processQuotedString([bool urlString = false]) {
    int start = _peekToken.start;

    // URI term sucks up everything inside of quotes(' or ") or between parens
    int stopToken = urlString ? TokenKind.RPAREN : -1;
    switch (_peek()) {
    case TokenKind.SINGLE_QUOTE:
      stopToken = TokenKind.SINGLE_QUOTE;
      _next();    // Skip the SINGLE_QUOTE.
      break;
    case TokenKind.DOUBLE_QUOTE:
      stopToken = TokenKind.DOUBLE_QUOTE;
      _next();    // Skip the DOUBLE_QUOTE.
      break;
    default:
      if (urlString) {
        if (_peek() == TokenKind.LPAREN) {
          _next();    // Skip the LPAREN.
        }
        stopToken = TokenKind.RPAREN;
      } else {
        _error('unexpected string', _makeSpan(start));
      }
    }

    StringBuffer stringValue = new StringBuffer();

    // Gobble up everything until we hit our stop token.
    int runningStart = _peekToken.start;
    while (_peek() != stopToken && _peek() != TokenKind.END_OF_FILE) {
      var tok = _next();
      stringValue.write(tok.text);
    }

    if (stopToken != TokenKind.RPAREN) {
      _next();    // Skip the SINGLE_QUOTE or DOUBLE_QUOTE;
    }

    return stringValue.toString();
  }

  //  Function grammar:
  //
  //  function:     IDENT '(' expr ')'
  //
  processFunction(Identifier func) {
    int start = _peekToken.start;

    String name = func.name;

    switch (name) {
    case 'url':
      // URI term sucks up everything inside of quotes(' or ") or between parens
      String urlParam = processQuotedString(true);

      // TODO(terry): Better error messge and checking for mismatched quotes.
      if (_peek() == TokenKind.END_OF_FILE) {
        _error("problem parsing URI", _peekToken.span);
      }

      if (_peek() == TokenKind.RPAREN) {
        _next();
      }

      return new UriTerm(urlParam, _makeSpan(start));
    case 'calc':
      // TODO(terry): Implement expression handling...
      break;
    default:
      var expr = processExpr();
      if (!_maybeEat(TokenKind.RPAREN)) {
        _error("problem parsing function expected ), ", _peekToken.span);
      }

      return new FunctionTerm(name, name, expr, _makeSpan(start));
    }

    return null;
  }

  identifier() {
    var tok = _next();
    if (!TokenKind.isIdentifier(tok.kind)) {
      _error('expected identifier, but found $tok', tok.span);
    }

    return new Identifier(tok.text, _makeSpan(tok.start));
  }

  // TODO(terry): Move this to base <= 36 and into shared code.
  static int _hexDigit(int c) {
    if(c >= 48/*0*/ && c <= 57/*9*/) {
      return c - 48;
    } else if (c >= 97/*a*/ && c <= 102/*f*/) {
      return c - 87;
    } else if (c >= 65/*A*/ && c <= 70/*F*/) {
      return c - 55;
    } else {
      return -1;
    }
  }

  static int parseHex(String hex) {
    var result = 0;

    for (int i = 0; i < hex.length; i++) {
      var digit = _hexDigit(hex.codeUnitAt(i));
      if (digit < 0) {
        throw new HexNumberException();
      }
      result = (result << 4) + digit;
    }

    return result;
  }
}

/** Not a hex number. */
class HexNumberException implements Exception {
  HexNumberException();
}

