lib/MissMatch.js
function parseProperty(node,proto) {
    consume(); // '.'
    var name = [], property, first = once(true);

    while(hasNext() && validChar(peek(), first())) {      
      name[name.length] = next();
    }

    if(name.length > 0) {
      property = newNode(proto ? ':' : '.', node.nodes);
      property.name = name.join('');

      /**
       * Properties may have type specifiers. This is the way to go
       * to match nested objects.
       *
       * e.g. 'o(.coord:o(.x, .y))' matches objects like
       *  '{coord: {x: 5, y: 7} }'
       */
      if(hasNext() && peek() === ':') {
        consume(); // '('
        stage1(property.nodes);
      }

      // The property value might be bound to a name
      if(hasNext() && peek() === '@') {
        parseBinding(property);
      }
    } else {
      throw "No property name given at " + index + " for " + node.type;
    }
  }
function parseProperty(node,proto) {
    consume(); // '.'
    var name = [], property, first = once(true);

    while(hasNext() && validChar(peek(), first())) {      
      name[name.length] = next();
    }

    if(name.length > 0) {
      property = newNode(proto ? ':' : '.', node.nodes);
      property.name = name.join('');

      /**
       * Properties may have type specifiers. This is the way to go
       * to match nested objects.
       *
       * e.g. 'o(.coord:o(.x, .y))' matches objects like
       *  '{coord: {x: 5, y: 7} }'
       */
      if(hasNext() && peek() === ':') {
        consume(); // '('
        stage1(property.nodes);
      }

      // The property value might be bound to a name
      if(hasNext() && peek() === '@') {
        parseBinding(property);
      }
    } else {
      throw "No property name given at " + index + " for " + node.type;
    }
  }
Parse a single property. Valid property names can contain
upper- and lowercase letters, _, $ and numbers.