<commit_before>
/*!
 * CSS - Parser
 * Copyright(c) 2010 LearnBoost <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Lexer = require('./lexer')
  , nodes = require('./nodes')
  , inspect = require('sys').inspect;

/**
 * Initialize a new `Parser` with the given `str` and `options`.
 *
 * @param {String} str
 * @param {Object} options
 * @api private
 */

var Parser = module.exports = function Parser(str, options) {
  options = options || {};
  this.str = str;
  this.filename = options.filename || 'css';
  this.lexer = new Lexer(str, options);
  this.lexer.isSelector = true;
};

/**
 * Parser prototype.
 */

Parser.prototype = {
  
  /**
   * Parse the input, then return the root node.
   *
   * @return {Node}
   * @api private
   */
  
  parse: function(){
    var block = this.root = new nodes.Root;
    while ('eos' != this.peek.type) {
      if (this.accept('newline')) continue;
      block.push(this.statement);
    }
    return block;
  },
  
  /**
   * Accept the given token `type`, and return it,
   * otherwise return `undefined`.
   *
   * @param {String} type
   * @return {Token}
   * @api private
   */

  accept: function(type){
    if (type == this.peek.type) {
      return this.next;
    }
  },

  /**
   * Expect token `type` and return it, throw otherwise.
   *
   * @param {String} type
   * @return {Token}
   * @api private
   */

  expect: function(type){
    if (type != this.peek.type) {
      throw new Error('expected ' + type + ', got ' + this.peek.type);
    }
    return this.next;
  },
  
  /**
   * Get the next token.
   *
   * @return {Token}
   * @api private
   */
  
  get next() {
    return this.lexer.next;
  },
  
  /**
   * Peek with lookahead(1).
   *
   * @return {Token}
   * @api private
   */
  
  get peek() {
    return this.lexer.peek;
  },
  
  /**
   *    variable
   *  | property
   *  | selector
   */
  
  get statement() {
    var type = this.peek.type;
    switch (type) {
      case 'variable':
      case 'property':
      case 'selector':
        return this[type];
      default:
        // TODO: refactor
        throw new Error('invalid token "' + type + '" ' + inspect(this.peek.val));
    }
  },
  
  /**
   * indent (!outdent)+ outdent
   */

  get block() {
    var block = new nodes.Block;
    this.expect('indent');
    while ('outdent' != this.peek.type) {
      if (this.accept('newline')) continue;
      block.push(this.statement);
    }
    this.expect('outdent');
    return block;
  },
  
  /**
   * property (unit | color)
   */

  get property() {
    var tok
      , prop = this.expect('property').val
      , val = this.next;
    switch (val.type) {
      case 'unit':
      case 'color':
        var prop = new nodes.Property(prop, val.val);
        prop.push(val.val);<commit_msg>Misc refactoring<commit_after>
/*!
 * CSS - Parser
 * Copyright(c) 2010 LearnBoost <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Lexer = require('./lexer')
  , nodes = require('./nodes')
  , inspect = require('sys').inspect;

/**
 * Initialize a new `Parser` with the given `str` and `options`.
 *
 * @param {String} str
 * @param {Object} options
 * @api private
 */

var Parser = module.exports = function Parser(str, options) {
  options = options || {};
  this.str = str;
  this.filename = options.filename || 'css';
  this.lexer = new Lexer(str, options);
  this.lexer.isSelector = true;
};

/**
 * Parser prototype.
 */

Parser.prototype = {
  
  /**
   * Parse the input, then return the root node.
   *
   * @return {Node}
   * @api private
   */
  
  parse: function(){
    var block = this.root = new nodes.Root;
    while ('eos' != this.peek.type) {
      if (this.accept('newline')) continue;
      block.push(this.statement);
    }
    return block;
  },
  
  /**
   * Accept the given token `type`, and return it,
   * otherwise return `undefined`.
   *
   * @param {String} type
   * @return {Token}
   * @api private
   */

  accept: function(type){
    if (type == this.peek.type) {
      return this.next;
    }
  },

  /**
   * Expect token `type` and return it, throw otherwise.
   *
   * @param {String} type
   * @return {Token}
   * @api private
   */

  expect: function(type){
    if (type != this.peek.type) {
      throw new Error('expected ' + type + ', got ' + this.peek.type);
    }
    return this.next;
  },
  
  /**
   * Get the next token.
   *
   * @return {Token}
   * @api private
   */
  
  get next() {
    return this.lexer.next;
  },
  
  /**
   * Peek with lookahead(1).
   *
   * @return {Token}
   * @api private
   */
  
  get peek() {
    return this.lexer.peek;
  },
  
  /**
   *    variable
   *  | property
   *  | selector
   */
  
  get statement() {
    var type = this.peek.type;
    switch (type) {
      case 'variable':
      case 'property':
      case 'selector':
        return this[type];
      default:
        // TODO: refactor
        throw new Error('invalid token "' + type + '" ' + inspect(this.peek.val));
    }
  },
  
  /**
   * indent (!outdent)+ outdent
   */

  get block() {
    var block = new nodes.Block;
    this.expect('indent');
    while ('outdent' != this.peek.type) {
      if (this.accept('newline')) continue;
      block.push(this.statement);
    }
    this.expect('outdent');
    return block;
  },
  
  /**
   * property (unit | color)
   */

  get property() {
    var tok
      , name = this.expect('property').val
      , val = this.next;
    switch (val.type) {
      case 'unit':
      case 'color':
        var prop = new nodes.Property(name, val.val);
        prop.push(val.val);
{'fraction_non_alphanumeric': 0.1646090534979424, 'fraction_numerical': 0.001789228842368939, 'mean_word_length': 2.119419642857143, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4762213', 'n_tokens_mistral': 1933, 'n_tokens_neox': 1902, 'n_words': 464}